module DesignHUD
# This HUD uses an easy to use format for configuration much like html
# it has many types of tags, each inserting different information into the
# HUD, such as icons, hp/sp/xp bars, and different information about the
# actors.
#
# Tags:
#
# Formatting Elements:
# * <i></i>
# - italicizes text
# * <b></b>
# - bolds text
# * <c=R:G:B[:A]></c>
# - changes the color to Color.new(R, G, B, A) (A is unnecessary)
# * <font=NAME:SIZE></font>
# - changes the font to NAME and the font size to SIZE
# Graphical Elements:
# * <ico=FILENAME>
# - inserts the icon named FILENAME
# * <pic=FILENAME>
# - inserts the picture named FILENAME
# * <bar style=STYLE type=TYPE cstyle=COLORSTYLE1:COLORSTYLE2... text=TEXT
# neaten=NEATEN lines=LINES shape=SHAPE dimensions=WIDTH:HEIGHT>
# - inserts a gradient bar with certain parameters that you can customize
# - types: :hp, :mp, :exp, :lvl
# - styles: 0 - 34
# 0-6 - Linear top-to-bottom
# some are ease in or ease out or bilinear (starts from center)
# 7-13 - Linear top-to-bottom stripes
# same as 0-6 except it uses stripes defined by four color styles
# instead of 2
# 14-34 - Linear left-to-right
# some are ease in or ease out or bilinear or fade out on the top
# and bottom
# - shapes: 0 - 3
# 0 - Rectangular
# 1 - Slant Left
# 2 - Rounded
# 3 - Slant Right
# - color styles: 0 - 12
# color styles define the two endpoints of the gradient's colors
# for styles 7 - 13 use four color styles
# main two colors defined by the type
# :hp - Red and Green
# :mp - Red and Blue
# :exp - Orange and Yellow
# :lvl - Blue and Purple
# two mixed colors are defined by the percentage of the bar remaining
# Mixed1 - At 0% full, Color1, at 100% full, Color2
# Mixed2 - At 0% full, Color2, at 100% full, Color1
# real colors defined by color style
# 0 - Color1
# 1 - Color2
# 2 - Black
# 3 - Mixed1
# 4 - Mixed2
# 5 - Highlight of Color1
# 6 - Highlight of Color2
# 7 - Highlight of Mixed1
# 8 - Highlight of Mixed2
# 9 - Shadow of Color1
# 10 - Shadow of Color2
# 11 - Shadow of Mixed1
# 12 - Shadow of Mixed2
# Positioning Elements:
# * <pos x=VALX y=VALY></pos>
# - positions the contents at an x position of VALX and
# at a y position of VALY
# * <offset x=VALX y=VALY></offset>
# - adds VALX and VALY to the position of the contents
# * <table></table>
# - starts a table
# * <tr></tr>
# - adds a row to a table
# * <td></td>
# - adds a cell to a row of a table
# * <left></left>
# - aligns the contents to the left
# * <center></center>
# - aligns the contents in the center
# * <right></right>
# - aligns the contents to the right
# * <ln></ln>
# - denotes one line in the HUD
# * <width=VAL></width>
# - sets the width of the contents to VAL
# * <height=VAL></height>
# - sets the height of the contents to VAL
# HUD Properties:
# * <hud>
# - this tag has many properties, listed below
# * windowskin='FILENAME'
# - sets the windowskin of the HUD to the windowskin named FILENAME
# * bg='FILENAME'
# - sets the background image of the HUD to the picture named FILENAME
# * align=ALIGN
# - sets the align of the HUD to ALIGN
# - possible aligns: TL, TC, TR, ML, MC, MR, BL, BC, BR (top-left,
# top-center, top-right, middle-left, middle-center, middle-right,
# bottom-left, bottom-center, bottom-right)
# * offsetx=VAL
# - sets the xoffset of the HUD to VAL
# * offsety=VAL
# - and the yoffset of the HUD to VAL
# * width=VAL
# - sets the width of the HUD to VAL
# * height=VAL
# - sets the height of the HUD to VAL
# * back_opacity=VAL
# - sets the back opacity of the HUD to VAL
# * contents_opacity=VAL
# - sets the contents opacity of the HUD to VAL
# * opacity=VAL
# - sets the opacity of the HUD to VAL
HUD = <<-HUD
<hud width=220 align=TL offsetx=16 offsety=16 opacity=0>
<ln><center><var=name></center></ln>
<ln>HP: <right><bar neaten=true lines=true text=false style=20 cstyle=0:3 shape=2></right></ln>
<ln>SP: <right><bar type=:mp neaten=true lines=true text=false style=20 cstyle=0:3 shape=2></right></ln>
<ln>EXP: <right><bar type=:exp neaten=true lines=true text=false style=20 cstyle=0:3 shape=2></right></ln>
<ln>Level: <right><bar type=:lvl neaten=true lines=true text=false style=20 cstyle=0:3 shape=2></right></ln>
HUD
NO_END = ['ico', 'pic', 'hud', 'var', 'bar', 'shape']
BLOCK_ELS = ['ln']
def self.var_expression(name)
case name
when 'gold' then return proc { $game_party.gold }
when 'name' then return proc { $game_party.actors[0].name }
else return proc {}
end
end
SPATTERN = /<([\w\-]+)(?:\s*=\s*([\w\"\'\-\_\:\$\.\s\+]+))?((?:\s*\w+\s*=\s*[\w\"\'\-\_\:\$\.\s\+]+)*)>/
end
class HUD < Window_Base
attr_accessor :tmp_attrs
def initialize(text)
super(0, 0, 33, 33)
self.contents = Bitmap.new(1, 1)
self.visible = false
@align = 'TL'
@xoffset, @yoffset = 0, 0
@tmp_attrs = {}
@text = text
Element.reset_id
parse_text
setup_hud
setup_align
@dom.delete_if { |el| el.el_type == 'hud' }
self.width = [self.width, 33].max
self.height = [self.height, 33].max
self.contents = Bitmap.new(width - 32, height - 32)
tmp = self.contents
render_hud
end
def update
redim = []
vars = []
redraw = []
@var_nodes.each { |el|
val = el.val
if val != el.attrs[:val]
vars.push(el)
redim |= [el.last_line]
pos = el.attrs[:pos]
rect = el.attrs[:size]
rect.x, rect.y = *pos
rect.x += el.attrs[:ox]
rect.y += el.attrs[:oy]
self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
el.attrs[:val] = val
end
}
@dom.each { |el|
comp = false
el.each_child_ex2(proc { |child|
comp = false
}) { |child|
if child.attrs[:size] and !comp
pos = child.attrs[:pos]
rect = child.attrs[:size]
rect.x, rect.y = *pos
rect.x += child.attrs[:ox] if child.attrs[:ox]
rect.y += child.attrs[:oy] if child.attrs[:oy]
if vars.select { |el|
pos = el.attrs[:pos]
tmp = el.attrs[:size]
tmp.x, tmp.y = *pos
tmp.x += el.attrs[:ox] if el.attrs[:ox]
tmp.y += el.attrs[:oy] if el.attrs[:oy]
tmp.intersect?(rect)
}.length > 0
redraw.push(child)
self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
comp = true
end
end
}
}
redraw ||= vars
if redim.length > 0
redetermine_size(redim)
setup_align
end
if redraw.length > 0
redraw_hud(redraw)
end
end
def redetermine_size(els)
@tmp_attrs[:ox] = 0
@tmp_attrs[:oy] = 0
pos = [0, 0]
@dom.each { |el|
ln_height = ln_width = 0
if els.include?(el)
pos = el.attrs[:pos].clone unless @tmp_attrs[:tmp]
if @tmp_attrs[:tmp]
@tmp_attrs[:tmp].push(true)
else
@tmp_attrs[:tmp] = [true]
end
end
case el.el_type
when 'ln'
el.each_child_ex(proc { |child|
if @tmp_attrs[:tmp]
unless child.attrs[:size].nil?
rect = child.attrs[:size]
rect.x, rect.y = *child.attrs[:pos]
self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
end
if @tmp_attrs[:abs_pos]
child.attrs[:pos] = [@tmp_attrs[:abs_pos].last[0], @tmp_attrs[:abs_pos].last[1]]
else
child.attrs[:pos] = [pos[0], pos[1]]
end
child.attrs[:ox], child.attrs[:oy] = @tmp_attrs[:ox], @tmp_attrs[:oy]
end
if els.include?(child)
pos = child.attrs[:pos].clone unless @tmp_attrs[:tmp]
if @tmp_attrs[:tmp]
@tmp_attrs[:tmp].push(true)
else
@tmp_attrs[:tmp] = [true]
end
end
case child
when FormatNode
tmp = child.attrs[:start].call(child, self)
child.attrs = tmp if tmp and tmp.is_a?(Hash)
end
},
proc { |child|
case child
when FormatNode
tmp = child.attrs[:finish].call(child, self)
child.attrs = tmp if tmp and tmp.is_a?(Hash)
end
if @tmp_attrs[:tmp]
if els.include?(child)
@tmp_attrs[:tmp].pop
@tmp_attrs.delete(:tmp) if @tmp_attrs[:tmp].length == 0
end
end
unless child.children.empty?
resize(child)
end
}) { |child|
if @tmp_attrs[:tmp]
case child
when TextNode
size = self.contents.text_size(child.attrs[:val])
child.attrs[:size] = size
ln_height = [size.height, ln_height].max
if @tmp_attrs[:abs_pos]
tmp = @tmp_attrs[:abs_pos]
ln_width = [tmp.last[0] + @tmp_attrs[:ox] + size.width, ln_width].max
@tmp_attrs[:abs_pos][tmp.length - 1][0] += size.width
else
ln_width = [pos[0] + @tmp_attrs[:ox] + size.width, ln_width].max
pos[0] += size.width
end
when VariableNode
size = self.contents.text_size(child.val.to_s)
child.attrs[:size] = size
ln_height = [size.height, ln_height].max
if @tmp_attrs[:abs_pos]
tmp = @tmp_attrs[:abs_pos]
ln_width = [tmp.last[0] + @tmp_attrs[:ox] + size.width, ln_width].max
@tmp_attrs[:abs_pos][tmp.length - 1][0] += size.width
else
ln_width = [pos[0] + @tmp_attrs[:ox] + size.width, ln_width].max
pos[0] += size.width
end
when IconNode, PictureNode, ShapeNode
size = child.attrs[:bitmap].rect
child.attrs[:size] = size
ln_height = [size.height, ln_height].max
if @tmp_attrs[:abs_pos]
tmp = @tmp_attrs[:abs_pos]
ln_width = [tmp.last[0] + @tmp_attrs[:ox] + size.width, ln_width].max
@tmp_attrs[:abs_pos][tmp.length - 1][0] += size.width
else
ln_width = [pos[0] + @tmp_attrs[:ox] + size.width, ln_width].max
pos[0] += size.width
end
when BarNode
size = Rect.new(0,0,*child.attrs[:dimensions])
child.attrs[:size] = size
ln_height = [size.height, ln_height].max
if @tmp_attrs[:abs_pos]
tmp = @tmp_attrs[:abs_pos]
ln_width = [tmp.last[0] + @tmp_attrs[:ox] + size.width, ln_width].max
@tmp_attrs[:abs_pos][tmp.length - 1][0] += size.width
else
ln_width = [pos[0] + @tmp_attrs[:ox] + size.width, ln_width].max
pos[0] += size.width
end
end
end
}
end
if @tmp_attrs[:tmp]
if els.include?(el)
@tmp_attrs[:tmp].pop
@tmp_attrs.delete(:tmp) if @tmp_attrs[:tmp].length == 0
end
end
}
@dom.each { |child|
if child.block?
child.attrs[:size].width = self.width - 32
child.attrs[:size].height = child.attrs[:height] || child.attrs[:size].height
child.attrs[:size].width = child.attrs[:width] || child.attrs[:size].width
end
}
end
def redraw_hud(els)
@tmp_attrs = {}
@dom.each { |el|
align = 0
case el.el_type
when 'ln'
if els.include?(el)
pos = el.attrs[:pos].clone unless @tmp_attrs[:tmp]
if @tmp_attrs[:tmp]
@tmp_attrs[:tmp].push(true)
else
@tmp_attrs[:tmp] = [true]
end
end
el.each_child_ex(proc { |child|
if els.include?(child)
pos = child.attrs[:pos].clone unless @tmp_attrs[:tmp]
if @tmp_attrs[:tmp]
@tmp_attrs[:tmp].push(true)
else
@tmp_attrs[:tmp] = [true]
end
end
case child
when FormatNode
child.attrs[:start].call(child, self)
end
},
proc { |child|
case child
when FormatNode
child.attrs[:finish].call(child, self)
end
if @tmp_attrs[:tmp]
if els.include?(child)
@tmp_attrs[:tmp].pop
@tmp_attrs.delete(:tmp) if @tmp_attrs[:tmp].length == 0
end
end
}) { |child|
if @tmp_attrs[:tmp]
draw_node(child)
end
}
end
}
end
def draw_node(node)
case node
when TextNode
pos = node.attrs[:pos]
ox, oy = node.attrs[:ox], node.attrs[:oy]
text = node.attrs[:val]
size = node.attrs[:size]
self.contents.draw_text(Rect.new(pos[0] + ox, pos[1] + oy, size.width, size.height), text)
when VariableNode
pos = node.attrs[:pos]
ox, oy = node.attrs[:ox], node.attrs[:oy]
text = node.val.to_s
size = node.attrs[:size]
self.contents.draw_text(Rect.new(pos[0] + ox, pos[1] + oy, size.width, size.height), text)
when IconNode, PictureNode, ShapeNode
pos = node.attrs[:pos]
ox, oy = node.attrs[:ox], node.attrs[:oy]
bitmap = node.attrs[:bitmap]
self.contents.blt(pos[0] + ox, pos[1] + oy, bitmap, bitmap.rect)
when BarNode
ln = node.last_line
pos = node.attrs[:pos]
ox, oy = node.attrs[:ox], node.attrs[:oy]
size = node.attrs[:size]
oy += (ln.attrs[:size].height - size.height) / 2
type = node.attrs[:type]
style = node.attrs[:style]
shape = node.attrs[:shape]
cstyle = node.attrs[:cstyle]
text = node.attrs[:text]
lines = node.attrs[:lines]
neaten = node.attrs[:neaten]
actor = node.attrs[:actor]
self.contents.gradient_bar(type, style, shape, cstyle, actor, pos[0] + ox, pos[1] + oy, size.width, size.height, text, lines, neaten)
end
end
def parse_text
text = @text.clone
@dom, @var_nodes = [], []
index = 0
current_id = -1
current_el = nil
parent = nil
parent_els = []
spattern = /<([\w\-]+)(?:\s*=\s*([\w\"\'\-\_\:\$\.\s\+]+))?((?:\s*\w+\s*=\s*[\w\"\'\-\_\:\$\.\s]+)*)>/
epattern = /<\/[\w\-]+>/
while text.length != 0
s_ind = text.index(DesignHUD::SPATTERN)
if s_ind != nil
contents = nil
el_name = $1
el_val = $2 || ''
el_attrs = {}
tmp = $3.strip
tmp.gsub(/(\w+)\s+=\s+([\w\"\'\-\:\+]+)/, "\\1=\\2").split(/\s+/).each { |el| el_attrs[el.split('=')[0].to_sym] = get_val(el.split('=')[1]) }
el_val.gsub!(/[\'\"]/, '') if el_val
el_attrs[:val] = el_val
level, tmp_name, tmp_ind = 0, '', s_ind
if !DesignHUD::NO_END.include?(el_name)
loop do
text.sub!(DesignHUD::SPATTERN, '')
tmp = [text.index(/(<#{el_name}(?:=[\w\"\'\-\:]+)?(?:\s*\w+=[\w\"\'\-\:]+)*>)/, tmp_ind)]
tmp.push(text.index(/<\/#{el_name}>/, tmp_ind))
if !tmp[1]
contents = text[s_ind...text.length - 4 - el_name.length]
text = ''
elsif !tmp[0]
contents = text[s_ind...text.length - 4 - el_name.length]
text = ''
elsif tmp[1] < tmp[0]
contents = text[s_ind...tmp[1]]
text = text[tmp[1]...text.length]
else
level += 1
tmp_ind = tmp[0] + 2 + el_name.length
end
break if contents != nil
end
case el_name
when 'ln'
element = ContainerNode.new('ln', el_attrs, nil, contents)
@dom.push(element)
end
else
text.sub!(DesignHUD::SPATTERN, '')
case el_name
when 'hud'
element = HudNode.new('hud', el_attrs)
@dom.push(element)
end
end
end
end
end
def setup_hud
@bg = Sprite.new
@bg.z = self.z - 1
@bg.visible = false
@dom.each { |el|
el.each_child { |tmp|
if tmp.el_type == 'hud'
self.width = tmp.attrs[:width].to_i if tmp.attrs[:width]
self.height = tmp.attrs[:height].to_i if tmp.attrs[:height]
@align = tmp.attrs[:align] if tmp.attrs[:align]
@xoffset = tmp.attrs[:offsetx].to_i if tmp.attrs[:offsetx]
@yoffset = tmp.attrs[:offsety].to_i if tmp.attrs[:offsety]
self.opacity = tmp.attrs[:opacity].to_i if tmp.attrs[:opacity]
self.back_opacity = tmp.attrs[:back_opacity].to_i if tmp.attrs[:back_opacity]
self.contents_opacity = tmp.attrs[:contents_opacity].to_i if tmp.attrs[:contents_opacity]
begin
self.windowskin = ((tmp.attrs[:windowskin] == '') ? Bitmap.new(1, 1) : RPG::Cache.windowskin(tmp.attrs[:windowskin])) if tmp.attrs[:windowskin]
rescue
self.windowskin = Bitmap.new(1, 1)
end
if tmp.attrs[:bg]
@bg.bitmap = RPG::Cache.picture(tmp.attrs[:bg])
@bg.visible = true
end
end
}
}
tmp_width, tmp_height = get_dimensions
if self.width == 33
self.width = [tmp_width, 1].max + 32
end
if self.height == 33
self.height = [tmp_height, 1].max + 32
end
amnt = 0
@dom.each_with_index { |child, ind|
if child.block?
child.attrs[:size].width = self.width - 32
#child.attrs[:size].height = child.attrs[:height] || child.attrs[:size].height
child.attrs[:size].width = child.attrs[:width] || child.attrs[:size].width
if child.attrs[:height]
tmp = child.attrs[:size].height
amnt += child.attrs[:height] - tmp
child.attrs[:size].height = child.attrs[:height]
unless ind == @dom.length - 1
@dom[ind + 1...@dom.length].each { |i|
i.attrs[:pos][1] += child.attrs[:height] - tmp
}
end
end
end
}
self.height += amnt
@align.downcase!
xmod = (['l','c'].include?(@align[1..1]) ? 1 : -1)
ymod = (['t','m'].include?(@align[0..0]) ? 1 : -1)
xstrt = case @align[1..1]
when 'l' then 0
when 'r' then 640 - self.width
when 'c' then (640 - self.width) / 2
end
ystrt = case @align[0..0]
when 't' then 0
when 'b' then 480 - self.height
when 'm' then (480 - self.height) / 2
end
self.x = xstrt + xmod * @xoffset
self.y = ystrt + ymod * @yoffset
if @bg.visible
@bg.x = self.x + (self.width - @bg.bitmap.width) / 2
@bg.y = self.y + (self.height - @bg.bitmap.height) / 2
end
self.visible = true
end
def get_dimensions
ln_widths = []
height = 0
@tmp_attrs[:ox] = 0
@tmp_attrs[:oy] = 0
@tmp_attrs[:align] = 0
pos = [0, 0]
@dom.each { |el|
pos[0] = 0
ln_width = 0
ln_height = 0
case el.el_type
when 'ln'
el.attrs[:pos] = pos.clone
el.attrs[:align] = @tmp_attrs[:abs_pos]
el.attrs[:abs] = 0
el.each_child_ex(proc { |child| # start proc
child.attrs[:align] = (@tmp_attrs[:abs_pos] ? 0 : @tmp_attrs[:align])
if @tmp_attrs[:abs_pos]
child.attrs[:pos] = @tmp_attrs[:abs_pos].last.clone
child.attrs[:abs] = @tmp_attrs[:abs_pos].length
else
child.attrs[:pos] = pos.clone
child.attrs[:abs] = 0
end
child.attrs[:ox], child.attrs[:oy] = @tmp_attrs[:ox], @tmp_attrs[:oy]
case child
when FormatNode
tmp = child.attrs[:start].call(child, self)
child.attrs = tmp if tmp and tmp.is_a?(Hash)
end
},
proc { |child| # end proc
case child
when FormatNode
tmp = child.attrs[:finish].call(child, self)
child.attrs = tmp if tmp and tmp.is_a?(Hash)
end
if !child.children.empty?
resize(child)
elsif child.block? or ![TextNode, VariableNode, IconNode, PictureNode, BarNode, ShapeNode].include?(child.class)
child.attrs[:size] = Rect.new(0, 0, 0, 0)
end
}) { |child| # main proc
case child
when TextNode
size = self.contents.text_size(child.attrs[:val])
child.attrs[:size] = size
ln_height = [size.height, ln_height].max
if @tmp_attrs[:abs_pos]
tmp = @tmp_attrs[:abs_pos]
ln_width = [tmp.last[0] + @tmp_attrs[:ox] + size.width, ln_width].max
@tmp_attrs[:abs_pos][tmp.length - 1][0] += size.width
else
ln_width = [pos[0] + @tmp_attrs[:ox] + size.width, ln_width].max
pos[0] += size.width
end
when VariableNode
size = self.contents.text_size(child.val.to_s)
child.attrs[:size] = size
ln_height = [size.height, ln_height].max
if @tmp_attrs[:abs_pos]
tmp = @tmp_attrs[:abs_pos]
ln_width = [tmp.last[0] + @tmp_attrs[:ox] + size.width, ln_width].max
@tmp_attrs[:abs_pos][tmp.length - 1][0] += size.width
else
ln_width = [pos[0] + @tmp_attrs[:ox] + size.width, ln_width].max
pos[0] += size.width
end
@var_nodes.push(child)
when IconNode, PictureNode, ShapeNode
size = child.attrs[:bitmap].rect
child.attrs[:size] = size
ln_height = [size.height, ln_height].max
if @tmp_attrs[:abs_pos]
tmp = @tmp_attrs[:abs_pos]
ln_width = [tmp.last[0] + @tmp_attrs[:ox] + size.width, ln_width].max
@tmp_attrs[:abs_pos][tmp.length - 1][0] += size.width
else
ln_width = [pos[0] + @tmp_attrs[:ox] + size.width, ln_width].max
pos[0] += size.width
end
when BarNode
size = Rect.new(0,0,*child.attrs[:dimensions])
child.attrs[:size] = size
ln_height = [size.height, ln_height].max
if @tmp_attrs[:abs_pos]
tmp = @tmp_attrs[:abs_pos]
ln_width = [tmp.last[0] + @tmp_attrs[:ox] + size.width, ln_width].max
@tmp_attrs[:abs_pos][tmp.length - 1][0] += size.width
else
ln_width = [pos[0] + @tmp_attrs[:ox] + size.width, ln_width].max
pos[0] += size.width
end
@var_nodes.push(child)
end
}
end
pos[1] += ln_height + @tmp_attrs[:oy]
ln_widths.push(ln_width)
}
height = pos[1]
width = ln_widths.max
return width, height
end
def resize(el)
size = Rect.new(0, 0, 0, 0)
x1, y1 = 640, 480
x2 = y2 = 0
len = el.attrs[:abs]
el.children.each { |i|
next if i.attrs[:abs] > len
x, y = *i.attrs[:pos]
ns = i.attrs[:size]
x1 = [x1, x].min
y1 = [y1, y].min
x2 = [x2, x + ns.width].max
y2 = [y2, y + ns.height].max
}
size.width = x2 - x1
size.height = y2 - y1
pos = el.block? ? el.attrs[:pos] : [x1, y1]
el.attrs[:pos], el.attrs[:size] = pos, size
end
def setup_align
aligned = nil
la = 0
blocks = []
@dom.each { |el|
case el.el_type
when 'ln'
el.each_child_ex(proc{|child|},proc{|child|
if child.attrs[:tmp]
child.attrs.delete_if { |i| i[0] == :tmp }
aligned = nil
end
}) { |child|
unless child.attrs[:abs] > 0 or !aligned.nil?
aligned = true
child.attrs[:tmp] = true
la = child.attrs[:align]
blocks |= [child.last_block]
child.last_block.attrs[:aels] = (child.last_block.attrs[:aels] || []).concat([child])
end
}
end
}
blocks.each { |el|
rw = el.attrs[:aels].inject(0) { |s, n| s + (n.attrs[:align] == 2 ? n.attrs[:size].width : 0) }
cw = el.attrs[:aels].inject(0) { |s, n| s + (n.attrs[:align] == 1 ? n.attrs[:size].width : 0) }
lx = el.attrs[:pos][0]
rx = el.attrs[:pos][0] + el.attrs[:size].width - rw
cx = el.attrs[:pos][0] + (el.attrs[:size].width) / 2
el.attrs[:aels].each { |child|
case child.attrs[:align]
when 0
ox = child.attrs[:pos][0]
child.attrs[:pos][0] = lx
child.each_child_ex(proc{},proc{}) { |i|
i.attrs[:pos][0] += lx - ox
}
lx += child.attrs[:size].width
when 1
cx -= child.attrs[:size].width / 2
when 2
ox = child.attrs[:pos][0]
child.attrs[:pos][0] = rx
child.each_child_ex(proc{},proc{}) { |i|
i.attrs[:pos][0] += rx - ox
}
rx += child.attrs[:size].width
end
}
el.attrs[:aels].select { |i| i.attrs[:align] == 1 }.each { |child|
ox = child.attrs[:pos][0]
child.attrs[:pos][0] = cx
child.each_child_ex(proc{},proc{}) { |i|
i.attrs[:pos][0] += cx - ox
}
cx += child.attrs[:size].width
}
el.attrs.delete(:aels)
}
end
def render_hud
@dom.each { |el|
align = 0
case el.el_type
when 'ln'
el.each_child_ex(proc { |child|
case child
when FormatNode
child.attrs[:start].call(child, self)
end
},
proc { |child|
case child
when FormatNode
child.attrs[:finish].call(child, self)
end
}) { |child|
draw_node(child)
}
end
}
end
def get_val(str)
separators = [':', '.', ',']
val = nil
vp = []
sp = []
loop do
tmpstr = eval('str' + sp.map{|i|'['+i.to_s+']'}.join(''))
if tmpstr.nil?
sp.pop
vp.pop
if vp.length == 0
break
end
sp[-1] += 1
vp[-1] += 1
next
end
if tmpstr.index(separators[sp.length]) != nil
begin
eval('val' + vp.map{|i|'['+i.to_s+']'}.join('') + "=eval('#{tmpstr}')")
if sp.length > 0 and sp.last < eval('str' + sp[0..sp.length - 2].map{|i|'['+i.to_s+']'}.join('')).length
sp[-1] += 1
vp[-1] += 1
else
break if vp.length == 0
vp.pop
sp.pop
break if vp.length == 0
sp[-1] += 1
vp[-1] += 1
end
rescue Exception
eval('str' + sp.map{|i|'['+i.to_s+']'}.join('') + '=tmpstr.split(separators[sp.length])')
eval('val' + vp.map{|i|'['+i.to_s+']'}.join('') + '=[]')
vp.push(0)
sp.push(0)
end
else
begin
eval('val' + vp.map{|i|'['+i.to_s+']'}.join('') + "=eval('#{tmpstr}')")
rescue Exception
eval('val' + vp.map{|i|'['+i.to_s+']'}.join('') + '=tmpstr')
end
etxt = 'str'
etxt += sp[0..sp.length - 2].map{|i|'['+i.to_s+']'}.join('') if sp.length > 1
if sp.length > 0 and sp.last < eval(etxt).length
sp[-1] += 1
vp[-1] += 1
else
break if vp.length == 0
vp.pop
sp.pop
break if vp.length == 0
sp[-1] += 1
vp[-1] += 1
end
end
end
val
end
def get_el(path)
el = @dom[path[0]]
if path.length > 1
path[1..path.length - 1].each { |tmp|
el = el.children[tmp]
}
end
el
end
end
class Element
@@id = 0
attr_accessor :children, :el_type, :attrs, :el_id, :parent
def initialize(el_type, attrs, parent)
@children = []
@el_type = el_type.downcase
@attrs = attrs
@parent = parent
@contents = ''
@el_id = @@id
@@id += 1
end
def get_val(str)
separators = [':', '.', ',']
val = nil
vp = []
sp = []
loop do
tmpstr = eval('str' + sp.map{|i|'['+i.to_s+']'}.join(''))
if tmpstr.nil?
sp.pop
vp.pop
if vp.length == 0
break
end
sp[-1] += 1
vp[-1] += 1
next
end
if tmpstr.index(separators[sp.length]) != nil
begin
eval('val' + vp.map{|i|'['+i.to_s+']'}.join('') + "=eval('#{tmpstr}')")
if sp.length > 0 and sp.last < eval('str' + sp[0..sp.length - 2].map{|i|'['+i.to_s+']'}.join('')).length
sp[-1] += 1
vp[-1] += 1
else
break if vp.length == 0
vp.pop
sp.pop
break if vp.length == 0
sp[-1] += 1
vp[-1] += 1
end
rescue Exception
eval('str' + sp.map{|i|'['+i.to_s+']'}.join('') + '=tmpstr.split(separators[sp.length])')
eval('val' + vp.map{|i|'['+i.to_s+']'}.join('') + '=[]')
vp.push(0)
sp.push(0)
end
else
begin
eval('val' + vp.map{|i|'['+i.to_s+']'}.join('') + "=eval('#{tmpstr}')")
rescue Exception
eval('val' + vp.map{|i|'['+i.to_s+']'}.join('') + '=tmpstr')
end
etxt = 'str'
etxt += sp[0..sp.length - 2].map{|i|'['+i.to_s+']'}.join('') if sp.length > 1
if sp.length > 0 and sp.last < eval(etxt).length
sp[-1] += 1
vp[-1] += 1
else
break if vp.length == 0
vp.pop
sp.pop
break if vp.length == 0
sp[-1] += 1
vp[-1] += 1
end
end
end
val
end
def block?
return DesignHUD::BLOCK_ELS.include?(@el_type)
end
def inline?
return !DesignHUD::BLOCK_ELS.include?(@el_type)
end
def self.reset_id
@@id = 0
end
def parents
if @parent != nil
parents = [@parent]
parent = @parent
while parent.parent != nil
parents.push(parent.parent)
parent = parent.parent
end
return parents
else
return []
end
end
def last_block
if @parent != nil
last = self
parent = @parent
while last.inline?
last = parent
parent = parent.parent
break if parent.nil?
end
return last
else
return nil
end
end
def last_line
if @parent != nil
last = self
parent = @parent
while last.el_type != 'ln'
last = parent
parent = parent.parent
break if parent.nil?
end
return last
else
return nil
end
end
def each_child(&block)
block.call(self)
path = [0]
cur = self
loop {
child = cur.children[path.last]
if child
block.call(child)
cur = child
path.push(0)
else
cur = cur.parent
path.pop
break unless cur
path[path.length - 1] += 1
end
}
end
def each_child_ex(start, finish, &block)
path = [0]
cur = self
loop {
child = cur.children[path.last]
if child
start.call(child)
block.call(child)
cur = child
path.push(0)
else
finish.call(cur)
cur = cur.parent
path.pop
break unless cur and path.length > 0
path[path.length-1] += 1
end
}
end
def each_child_ex2(finish, &block)
block.call(self)
path = [0]
cur = self
loop {
child = cur.children[path.last]
if child
block.call(child)
cur = child
path.push(0)
else
finish.call(cur)
cur = cur.parent
path.pop
break unless cur
path[path.length - 1] += 1
end
}
end
def parse_contents(text)
@tmp_attrs = {}
spattern = /<([\w\-]+)(?:\s*=\s*([\w\"\'\-\_\:\$\.\s]+))?((?:\s*\w+\s*=\s*[\w\"\'\-\_\:\$\.\s]+)*)>/
epattern = /<\/[\w\-]+>/
while text != ''
s_ind = text.index(DesignHUD::SPATTERN)
if s_ind != nil
if s_ind > 0
contents = text[0...s_ind]
text = text[s_ind...text.length]
element = TextNode.new('', self, contents)
@children.push(element)
end
contents = nil
el_name = $1
el_val = $2 || ''
el_attrs = {}
tmp = $3.strip
tmp.gsub(/(\w+)\s+=\s+([\w\"\'\-\:]+)/, "\\1=\\2").split(/\s+/).each { |el| el_attrs[el.split('=')[0].to_sym] = get_val(el.split('=')[1]) }
el_val.gsub!(/[\'\"]/, '') if el_val
el_attrs[:val] = el_val
level, tmp_name, tmp_ind = 0, '', 0
if !DesignHUD::NO_END.include?(el_name)
text.sub!(DesignHUD::SPATTERN, '')
last_ind = nil
loop do
tmp = [text.index(/(<#{el_name}(?:=[\w\"\'\-\:]+)?(?:\s*\w+=[\w\"\'\-\:]+)*>)/, tmp_ind)]
tmp2 = tmp_ind
(level+1).times {
i = text.index(/<\/#{el_name}>/, tmp2)
tmp2 = i + 2 + el_name.length unless i.nil?
}
tmp.push(tmp2 - 2 - el_name.length)
if !tmp[1]
contents = text[0...text.length]
text = ''
elsif !tmp[0]
contents = text[0...tmp[1]]
text = text[tmp[1] + 3 + el_name.length...text.length]
level = [level - 1, 0].max
elsif tmp[1] < tmp[0]
contents = text[0...tmp[1]]
text = text[tmp[1] + 3 + el_name.length...text.length]
level = [level - 1, 0].max
else
level += 1 unless last_ind != nil and tmp[0] > last_ind[1]
tmp_ind = tmp[0] + 2 + el_name.length
end
last_ind = tmp
break if contents != nil
end
case el_name
when 'ln'
element = ContainerNode.new('ln', el_attrs, self, contents)
@children.push(element)
when 'b'
element = FormatNode.new('b', self, contents, proc { |child, hud|
if !@tmp_attrs[:tmpb]
@tmp_attrs[:tmpb] = [hud.contents.font.bold]
else
@tmp_attrs[:tmpb].push(hud.contents.font.bold)
end
hud.contents.font.bold = true
},
proc { |child, hud|
hud.contents.font.bold = @tmp_attrs[:tmpb].pop
})
@children.push(element)
when 'i'
element = FormatNode.new('i', self, contents, proc { |child, hud|
if !@tmp_attrs[:tmpi]
@tmp_attrs[:tmpi] = [hud.contents.font.italic]
else
@tmp_attrs[:tmpi].push(hud.contents.font.italic)
end
hud.contents.font.italic = true
},
proc { |child, hud|
hud.contents.font.italic = @tmp_attrs[:tmpi].pop
})
@children.push(element)
when 'c'
element = FormatNode.new('c', self, contents, proc { |child, hud|
if !hud.tmp_attrs[:tmpc]
hud.tmp_attrs[:tmpc] = [hud.contents.font.color.clone]
else
hud.tmp_attrs[:tmpc].push(hud.contents.font.color.clone)
end
hud.contents.font.color = Color.new(*child.attrs[:val].split(':').map { |i| i.to_i })
},
proc { |child, hud|
hud.contents.font.color = hud.tmp_attrs[:tmpc].pop
}, el_val)
@children.push(element)
when 'font'
element = FormatNode.new('font', self, contents, proc { |child, hud|
if !@tmp_attrs[:tmpfn]
hud.tmp_attrs[:tmpfn] = [[hud.contents.font.name.clone, hud.contents.font.size]]
else
hud.tmp_attrs[:tmpfn].push([hud.contents.font.name.clone, hud.contents.font.size])
end
if Font.exist?(child.attrs[:val].split(':')[0])
hud.contents.font.name = child.attrs[:val].split(':')[0]
hud.contents.font.size = child.attrs[:val].split(':')[1].to_i
end
},
proc { |child, hud|
hud.contents.font.name, hud.contents.font.size = *hud.tmp_attrs[:tmpfn].pop
}, el_val)
@children.push(element)
when 'pos'
element = FormatNode.new('pos', self, contents, proc { |child, hud|
if !hud.tmp_attrs[:abs_pos]
hud.tmp_attrs[:abs_pos] = [[child.attrs[:x], child.attrs[:y]]]
else
hud.tmp_attrs[:abs_pos].push([child.attrs[:x], child.attrs[:y]])
end
},
proc { |child, hud|
hud.tmp_attrs[:abs_pos].pop
hud.tmp_attrs.delete(:abs_pos) if hud.tmp_attrs[:abs_pos].length == 0
}, el_val, el_attrs)
@children.push(element)
when 'offset'
element = FormatNode.new('offset', self, contents, proc { |child, hud|
if !hud.tmp_attrs[:tmpofst]
hud.tmp_attrs[:tmpofst] = [[hud.tmp_attrs[:ox], hud.tmp_attrs[:oy]]]
else
hud.tmp_attrs[:tmpofst].push([hud.tmp_attrs[:ox], hud.tmp_attrs[:oy]])
end
hud.tmp_attrs[:ox], hud.tmp_attrs[:oy] = child.attrs[:x], child.attrs[:y]
},
proc { |child, hud|
hud.tmp_attrs[:ox], hud.tmp_attrs[:oy] = *hud.tmp_attrs[:tmpofst].pop
}, el_val, el_attrs)
@children.push(element)
when 'right'
element = FormatNode.new('right', self, contents, proc { |child, hud|
if !hud.tmp_attrs[:tmpalign]
hud.tmp_attrs[:tmpalign] = [hud.tmp_attrs[:align]]
else
hud.tmp_attrs[:tmpalign].push(hud.tmp_attrs[:align])
end
hud.tmp_attrs[:align] = 2
child.attrs[:align] = 2
},
proc { |child, hud|
hud.tmp_attrs[:align] = hud.tmp_attrs[:tmpalign].pop
}, el_val, el_attrs)
@children.push(element)
when 'center'
element = FormatNode.new('center', self, contents, proc { |child, hud|
if !hud.tmp_attrs[:tmpalign]
hud.tmp_attrs[:tmpalign] = [hud.tmp_attrs[:align]]
else
hud.tmp_attrs[:tmpalign].push(hud.tmp_attrs[:align])
end
hud.tmp_attrs[:align] = 1
child.attrs[:align] = 1
},
proc { |child, hud|
hud.tmp_attrs[:align] = hud.tmp_attrs[:tmpalign].pop
}, el_val, el_attrs)
@children.push(element)
when 'left'
element = FormatNode.new('left', self, contents, proc { |child, hud|
if !hud.tmp_attrs[:tmpalign]
hud.tmp_attrs[:tmpalign] = [hud.tmp_attrs[:align]]
else
hud.tmp_attrs[:tmpalign].push(hud.tmp_attrs[:align])
end
hud.tmp_attrs[:align] = 0
child.attrs[:align] = 0
},
proc { |child, hud|
hud.tmp_attrs[:align] = hud.tmp_attrs[:tmpalign].pop
}, el_val, el_attrs)
@children.push(element)
end
else
text.sub!(DesignHUD::SPATTERN, '')
case el_name
when 'hud'
element = HudNode.new('hud', el_attrs, self)
@children.push(element)
when 'var'
element = VariableNode.new(self, el_val)
@children.push(element)
when 'ico'
element = IconNode.new(self, el_val)
@children.push(element)
when 'pic'
element = PictureNode.new(self, el_val)
@children.push(element)
when 'bar'
element = BarNode.new(self, el_attrs)
@children.push(element)
when 'shape'
element = ShapeNode.new(self, el_attrs)
@children.push(element)
end
end
else
contents = text
text = ''
element = TextNode.new('', self, contents)
@children.push(element)
end
end
end
end
class TextNode < Element
def initialize(type, parent, text)
super(type, {}, parent)
@attrs[:val] = text
end
end
class PictureNode < Element
def initialize(parent, val)
super('pic', {}, parent)
@attrs[:bitmap] = RPG::Cache.picture(val)
end
end
class IconNode < Element
def initialize(parent, val)
super('ico', {}, parent)
@attrs[:bitmap] = RPG::Cache.icon(el_val).clone
end
end
class VariableNode < Element
def initialize(parent, name)
super('var', {}, parent)
@attrs[:expr] = DesignHUD.var_expression(name)
@attrs[:val] = @attrs[:expr].call || 0
end
def val
tmp = @attrs[:expr].call
return (tmp.nil? ? 0 : tmp)
end
end
class ShapeNode < Element
def initialize(parent, attrs)
super('shape', attrs, parent)
@attrs[:width] ||= 50
@attrs[:height] ||= 50
bitmap = Bitmap.new(@attrs[:width], @attrs[:height])
case @attrs[:type].to_s.downcase
when 'rect'
@attrs[:color] ||= [0, 0, 0]
bitmap.fill_rect(bitmap.rect, Color.new(*@attrs[:color]))
when 'hgrect'
@attrs[:color] ||= [[0, 0, 0], [255, 255, 255]]
tmp = @attrs[:color]
bitmap.width.times { |i|
r = tmp[0][0] * (bitmap.width - 1 - i) / (bitmap.width - 1) + tmp[1][0] * i / (bitmap.width - 1)
g = tmp[0][1] * (bitmap.width - 1 - i) / (bitmap.width - 1) + tmp[1][1] * i / (bitmap.width - 1)
b = tmp[0][2] * (bitmap.width - 1 - i) / (bitmap.width - 1) + tmp[1][2] * i / (bitmap.width - 1)
bitmap.fill_rect(i, 0, 1, bitmap.height, Color.new(r, g, b))
}
when 'vgrect'
@attrs[:color] ||= [[0, 0, 0], [255, 255, 255]]
tmp = @attrs[:color]
bitmap.height.times { |i|
r = tmp[0][0] * (bitmap.height - 1 - i) / (bitmap.height - 1) + tmp[1][0] * i / (bitmap.height - 1)
g = tmp[0][1] * (bitmap.height - 1 - i) / (bitmap.height - 1) + tmp[1][1] * i / (bitmap.height - 1)
b = tmp[0][2] * (bitmap.height - 1 - i) / (bitmap.height - 1) + tmp[1][2] * i / (bitmap.height - 1)
bitmap.fill_rect(0, i, bitmap.width, 1, Color.new(r, g, b))
}
end
@attrs[:bitmap] = bitmap
end
end
class BarNode < Element
def initialize(parent, attrs)
super('bar', attrs, parent)
@attrs[:type] ||= :hp
@attrs[:style] ||= 0
@attrs[:shape] ||= 0
@attrs[:cstyle] ||= [3, 2, 4, 2]
@attrs[:lines] = false if @attrs[:lines].nil?
@attrs[:neaten] = true if @attrs[:neaten].nil?
@attrs[:dimensions] ||= [120, 16]
@attrs[:text] = true if @attrs[:text].nil?
@attrs[:actor] ||= 1
@attrs[:actor] = $game_actors[@attrs[:actor]]
@attrs[:val] = val
end
def val
case @attrs[:type]
when :hp
return [@attrs[:actor].hp, @attrs[:actor].maxhp]
when :mp
return [@attrs[:actor].sp, @attrs[:actor].maxsp]
when :exp
return @attrs[:actor].exp
when :lvl
return @attrs[:actor].level
end
end
end
class HudNode < Element
def initialize(type, attrs, parent = nil)
super('hud', attrs, parent)
end
end
class ContainerNode < Element
def initialize(type, attrs, parent, contents)
super(type, attrs, parent)
parse_contents(contents)
end
end
class FormatNode < Element
def initialize(type, parent, contents, start, finish, val=nil, attrs = {})
super(type, attrs, parent)
parse_contents(contents)
@attrs[:val] = val if val
@attrs[:start] = start
@attrs[:finish] = finish
end
end
class Rect
def intersect?(rect)
return false if rect.width * rect.height == 0 or self.width * self.height == 0
return true if (self.x.between?(rect.x - 1, rect.x + rect.width) or
(self.x + self.width).between?(rect.x - 1, rect.x + rect.width)) and
(self.y.between?(rect.y - 1, rect.y + rect.height) or
(self.y + self.height).between?(rect.y - 1, rect.y + rect.height))
return false
end
end
class Bitmap
def get_colors(type, actor, cstyle)
bc = Color.new(0, 0, 0)
case type
when :hp
c1 = Color.new(200, 0, 0)
c2 = Color.new(0, 200, 0)
p = actor.hp * 100 / actor.maxhp
when :mp
c1 = Color.new(200, 0, 0)
c2 = Color.new(0, 0, 200)
p = actor.sp * 100 / actor.maxsp
when :exp
c1 = Color.new(170, 85, 0)
c2 = Color.new(150, 150, 0)
elist = actor.instance_variable_get(:@exp_list)
if elist[actor.level + 1]
nexp = elist[actor.level + 1] - elist[actor.level]
cexp = actor.exp - elist[actor.level]
p = (nexp <= 0 ? 100 : cexp * 100 / nexp)
else
p = 100
end
when :lvl
c1 = Color.new(0, 85, 170)
c2 = Color.new(150, 0, 150)
p = actor.level * 100 / (actor.respond_to?(:final_level) ? actor.final_level : $data_actors[actor.id].final_level)
end
r = c2.red * p / 100 + c1.red * (100 - p) / 100
g = c2.green * p / 100 + c1.green * (100 - p) / 100
b = c2.blue * p / 100 + c1.blue * (100 - p) / 100
pc1 = Color.new(r, g, b)
r = c1.red * p / 100 + c2.red * (100 - p) / 100
g = c1.green * p / 100 + c2.green * (100 - p) / 100
b = c1.blue * p / 100 + c2.blue * (100 - p) / 100
pc2 = Color.new(r, g, b)
c = cstyle.map { |i|
case i
when 0 then c1
when 1 then c2
when 2 then bc
when 3 then pc1
when 4 then pc2
when 5 then lcol(c1)
when 6 then lcol(c2)
when 7 then lcol(pc1)
when 8 then lcol(pc2)
when 9 then dcol(c1)
when 10 then dcol(c2)
when 11 then dcol(pc1)
when 12 then dcol(pc2)
end
}
return c, bc
end
def lcol(c)
return Color.new(c.red * 1.3, c.green * 1.3, c.blue * 1.3)
end
def dcol(c)
return Color.new(c.red * 0.7, c.green * 0.7, c.blue * 0.7)
end
def gradient_bar_back(color, shape, x, y, w, h, lines, extend = true)
rw = w
w += 10 if extend
fill_rect(x, y, w, h, color)
case shape
when 0
unless lines
fill_rect(x + 1, y + 1, rw - 2, 1, Color.new(255, 255, 255))
fill_rect(x + 1, y + h - 2, rw - 2, 1, Color.new(255, 255, 255))
fill_rect(x + 1, y + 1, 1, h - 2, Color.new(255, 255, 255))
fill_rect(x + w - 2, y + 1, 1, h - 2, Color.new(255, 255, 255))
end
when 1
h.times { |i|
fill_rect(x + i, y + i + 1, 1, h - 1 - i, Color.new(0, 0, 0, 0))
fill_rect(x + w - 1 - i, y, 1, h - 1 - i, Color.new(0, 0, 0, 0))
set_pixel(x + i + 1, y + i, Color.new(255, 255, 255)) unless i == 0 or i == h - 1
}
fill_rect(x + h, y + h - 2, rw - 2 - h, 1, Color.new(255, 255, 255))
when 2
fill_rect(x, y, w, 1, Color.new(0, 0, 0, 127))
fill_rect(x, y + h - 1, w, 1, Color.new(0, 0, 0, 127))
t = (h / 2.0).floor
h.times { |i|
v = ((t + 1) * (1 - Math.sin(Math::PI * (i + 1) / (h + 1)))).floor
unless v == 0
fill_rect(x, y + i, v, 1, Color.new(0, 0, 0, 0))
fill_rect(x + w - v, y + i, v, 1, Color.new(0, 0, 0, 0))
end
unless [0, h - 1].include?(i)
set_pixel(x + v, y + i, Color.new(0, 0, 0, 85))
set_pixel(x + w - v, y + i, Color.new(0, 0, 0, 85))
end
}
when 3
h.times { |i|
fill_rect(x + i, y, 1, h - 1 - i, Color.new(0, 0, 0, 0))
fill_rect(x + w - 1 - i, y + i + 1, 1, h - 1 - i, Color.new(0, 0, 0, 0))
set_pixel(x + h - i, y + i, Color.new(255, 255, 255)) unless i == 0 or i == h - 1
}
fill_rect(x + 2, y + h - 2, w - (extend ? 7 : 2) - h, 1, Color.new(255, 255, 255))
#w -= h - 1
end
if extend
tmp = self.clone
fill_rect(x + w - 20, y, 20, h, Color.new(0, 0, 0, 0))
20.times { |i|
blt(x + w - 20 + i, y, tmp, Rect.new(x + w - 20 + i, y, 1, h), 255 * (19 - i) / 19)
}
end
end
def gradient_bar_front(colors, bgcolor, style, shape, sx, sy, w, h, rate)
sbmap = self.clone
t = (h / 2.0).ceil
if style.between?(0, 6)
h.times { |i|
rect = Rect.new(sx, sy + i, w * rate, 1)
case shape
when 1
rect.width -= h - 1
rect.x += i
when 2
t = (h / 2.0).floor
v = ((t + 1) * (1 - Math.sin(Math::PI * (i + 1) / (h + 1)))).floor
rect.x += v
rect.width -= 2 * v
when 3
rect.width -= h - 1
rect.x += h - 1 - i
end
case style
when 0
r = colors[1].red * i / (h - 1) + colors[0].red * (h - 1 - i) / (h - 1)
g = colors[1].green * i / (h - 1) + colors[0].green * (h - 1 - i) / (h - 1)
b = colors[1].blue * i / (h - 1) + colors[0].blue * (h - 1 - i) / (h - 1)
when 1
t = (h / 2.0).ceil
if i >= t
d = i - t + (h % 2 == 1 ? 1 : 0)
else
d = t - i - 1
end
t -= 1 if h % 2 == 1
r = colors[1].red * d / (t) + colors[0].red * (t - d) / (t)
g = colors[1].green * d / (t) + colors[0].green * (t - d) / (t)
b = colors[1].blue * d / (t) + colors[0].blue * (t - d) / (t)
when 2
s = Math.sin(Math::PI * i / (h - 1) / 2)
r = colors[1].red * s + colors[0].red * (1 - s)
g = colors[1].green * s + colors[0].green * (1 - s)
b = colors[1].blue * s + colors[0].blue * (1 - s)
when 3
s = 2 * Math.sin(Math::PI * i / (h - 1) / 6)
r = colors[1].red * s + colors[0].red * (1 - s)
g = colors[1].green * s + colors[0].green * (1 - s)
b = colors[1].blue * s + colors[0].blue * (1 - s)
when 4
s = 1 - 2 * Math.sin(Math::PI * i / (h - 1) / 6)
r = colors[0].red * s + colors[1].red * (1 - s)
g = colors[0].green * s + colors[1].green * (1 - s)
b = colors[0].blue * s + colors[1].blue * (1 - s)
when 5
s = Math.sin(Math::PI * i / (h - 1))
r = colors[0].red * s + colors[1].red * (1 - s)
g = colors[0].green * s + colors[1].green * (1 - s)
b = colors[0].blue * s + colors[1].blue * (1 - s)
when 6
s = Math.sin(Math::PI / 2 + Math::PI * i / (h - 1)).abs
r = colors[1].red * s + colors[0].red * (1 - s)
g = colors[1].green * s + colors[0].green * (1 - s)
b = colors[1].blue * s + colors[0].blue * (1 - s)
end
fill_rect(rect, Color.new(r, g, b))
}
elsif style.between?(7, 13)
amnt = 8
case shape
when 1, 3
w -= h - 1
end
at = (w.to_f * rate / amnt).ceil
h.times { |i|
at.times { |e|
rect = Rect.new(sx + amnt * e, sy + i, amnt, 1)
dw = w * rate
case shape
when 0
rect.width = [rect.width, sx + dw - rect.x].min
when 1
rect.x += i
rect.width = [rect.width, sx + dw + i - rect.x].min
when 2
v = ((t + 1) * (1 - Math.sin(Math::PI * (i + 1) / (h + 1)))).floor
rect.x += v if e == 0
tmp = 0
if e == 0
rect.width -= v
tmp += v
end
if e == at - 1
rect.width -= v
tmp += v
end
rect.width = [rect.width, sx + dw - tmp - rect.x].min
when 3
rect.x += h - 1 - i
rect.width = [rect.width, sx + dw + h - 1 - i - rect.x].min
end
tmpcolors = (e % 2 == 0 ? colors[0..1] : colors[2..3])
case style
when 7
r = tmpcolors[1].red * i / (h - 1) + tmpcolors[0].red * (h - 1 - i) / (h - 1)
g = tmpcolors[1].green * i / (h - 1) + tmpcolors[0].green * (h - 1 - i) / (h - 1)
b = tmpcolors[1].blue * i / (h - 1) + tmpcolors[0].blue * (h - 1 - i) / (h - 1)
when 8
if i >= t
d = i - t + (h % 2 == 1 ? 1 : 0)
else
d = t - i - 1
end
t -= 1 if h % 2 == 1
r = tmpcolors[1].red * d / (t) + tmpcolors[0].red * (t - d) / (t)
g = tmpcolors[1].green * d / (t) + tmpcolors[0].green * (t - d) / (t)
b = tmpcolors[1].blue * d / (t) + tmpcolors[0].blue * (t - d) / (t)
when 9
s = Math.sin(Math::PI * i / (h - 1) / 2)
r = tmpcolors[1].red * s + tmpcolors[0].red * (1 - s)
g = tmpcolors[1].green * s + tmpcolors[0].green * (1 - s)
b = tmpcolors[1].blue * s + tmpcolors[0].blue * (1 - s)
when 10
s = 2 * Math.sin(Math::PI * i / (h - 1) / 6)
r = tmpcolors[1].red * s + tmpcolors[0].red * (1 - s)
g = tmpcolors[1].green * s + tmpcolors[0].green * (1 - s)
b = tmpcolors[1].blue * s + tmpcolors[0].blue * (1 - s)
when 11
s = 1 - 2 * Math.sin(Math::PI * i / (h - 1) / 6)
r = tmpcolors[0].red * s + tmpcolors[1].red * (1 - s)
g = tmpcolors[0].green * s + tmpcolors[1].green * (1 - s)
b = tmpcolors[0].blue * s + tmpcolors[1].blue * (1 - s)
when 12
s = Math.sin(Math::PI * i / (h - 1))
r = tmpcolors[0].red * s + tmpcolors[1].red * (1 - s)
g = tmpcolors[0].green * s + tmpcolors[1].green * (1 - s)
b = tmpcolors[0].blue * s + tmpcolors[1].blue * (1 - s)
when 13
s = Math.sin(Math::PI / 2 + Math::PI * i / (h - 1)).abs
r = tmpcolors[1].red * s + tmpcolors[0].red * (1 - s)
g = tmpcolors[1].green * s + tmpcolors[0].green * (1 - s)
b = tmpcolors[1].blue * s + tmpcolors[0].blue * (1 - s)
end
fill_rect(rect, Color.new(r, g, b))
}
}
elsif style.between?(14, 34)
case shape
when 2
t = (h / 2.0).floor
v = []
h.times { |i|
v.push(((t + 1) * (1 - Math.sin(Math::PI * (i + 1) / (h + 1)))).floor)
}
end
dw = (w * rate).to_i
dw.times { |i|
rect = Rect.new(sx + i, sy, 1, h)
case shape
when 1
if i < h
rect.height -= h - 1 - i
end
if i > dw - h
rect.y += i - dw + h
rect.height -= i - dw + h
end
when 2
if i <= v.max
ind = v.index(v.detect { |val| val <= i })
rect.y += ind
rect.height -= ind * 2
elsif w - 1 - i <= v.max
ind = v.index(v.detect { |val| val <= w - 1 - i })
rect.y += ind
rect.height -= ind * 2
end
when 3
if i < h
rect.y += h - 1 - i
rect.height -= h - 1 - i
end
if i > w - h
rect.height -= i - w + h
end
end
case style
when 14, 17, 20, 23, 26, 29, 32
r = colors[1].red * i / (w - 1) + colors[0].red * (w - 1 - i) / (w - 1)
g = colors[1].green * i / (w - 1) + colors[0].green * (w - 1 - i) / (w - 1)
b = colors[1].blue * i / (w - 1) + colors[0].blue * (w - 1 - i) / (w - 1)
when 15, 18, 21, 24, 27, 30, 33
s = Math.sin(Math::PI * i / (w - 1) / 2)
r = colors[1].red * s + colors[0].red * (1 - s)
g = colors[1].green * s + colors[0].green * (1 - s)
b = colors[1].blue * s + colors[0].blue * (1 - s)
when 16, 19, 22, 25, 28, 31, 34
s = 2 * Math.sin(Math::PI * i / (w - 1) / 6)
r = colors[1].red * s + colors[0].red * (1 - s)
g = colors[1].green * s + colors[0].green * (1 - s)
b = colors[1].blue * s + colors[0].blue * (1 - s)
end
fill_rect(rect, Color.new(r, g, b))
}
if style.between?(17, 34)
bmap = self.clone
h.times { |i|
case style
when 17, 18, 19
t = (h / 2.0).ceil
if i >= t
d = i - t + (h % 2 == 1 ? 1 : 0)
else
d = t - i - 1
end
t -= 1 if h % 2 == 1
a = 255 * (t - d) / t
when 20, 21, 22
s = Math.sin(Math::PI * i / (h - 1))
a = 255 * s
when 23, 24, 25
s = 1 - Math.sin(Math::PI / 2 + Math::PI * i / (h - 1)).abs
a = 255 * s
when 26, 27, 28
a = 255 * (h - 1 - i) / (h - 1)
when 29, 30, 31
s = 1 - Math.sin(Math::PI * i / (h - 1) / 2)
a = 255 * s
when 32, 33, 34
s = 1 - 2 * Math.sin(Math::PI * i / (h - 1) / 6)
a = 255 * s
end
r = Rect.new(sx, sy + i, w, 1)
blt(r.x, r.y, sbmap, r)
blt(r.x, r.y, bmap, r, a)
}
end
end
case shape
when 2
bmap = self.clone
t.times { |i|
r = Rect.new(sx + i, sy, 1, h)
blt(r.x, r.y, sbmap, r)
blt(r.x, r.y, bmap, r, 255 * i / t)
r = Rect.new(sx + w * rate - 1 - i, sy, 1, h)
blt(r.x, r.y, sbmap, r)
blt(r.x, r.y, bmap, r, 255 * i / t)
bmap = self.clone
}
end
end
def gradient_bar(type, style, shape, cstyle, actor, x, y, w, h, text = false, lines = false, fix = true)
colors, bgcolor = get_colors(type, actor, cstyle)
if fix
case shape
when 0
w = (w - (lines ? 2 : 4)) / 8 * 8 + (lines ? 2 : 4)
when 1
w = (w - 3 - h + 1)
w = w / 8 * 8
w = w + h - 1 + 3
when 2
w = (w - 4) / 8 * 8 + 4
when 3
w = (w - 2 - h + 1)
w = w / 8 * 8
w = w + h - 1 + 2
end
end
gradient_bar_back(bgcolor, shape, x, y, w, h, lines, false)
case shape
when 0
x += (lines ? 1 : 2)
y += (lines ? 1 : 2)
w -= (lines ? 2 : 4)
h -= (lines ? 2 : 4)
when 1
x += 3
y += 1
w -= 6
h -= 3
when 2
x += 2
y += 2
w -= 4
h -= 4
when 3
x += 3
y += 1
w -= 5
h -= 3
end
case type
when :hp
rate = actor.hp.to_f / actor.maxhp
str = actor.hp.to_s + '/' + actor.maxhp.to_s
when :mp
rate = actor.sp.to_f / actor.maxsp
str = actor.sp.to_s + '/' + actor.maxsp.to_s
when :exp
elist = actor.instance_variable_get(:@exp_list)
if elist[actor.level + 1]
nexp = elist[actor.level + 1] - elist[actor.level]
cexp = actor.exp - elist[actor.level]
rate = (nexp <= 0 ? 1 : cexp.to_f / nexp)
else
rate = 1
end
str = actor.exp_s + '/' + actor.next_exp_s
when :lvl
rate = actor.level.to_f / (actor.respond_to?(:final_level) ? actor.final_level : $data_actors[actor.id].final_level)
str = actor.level.to_s + '/' + (actor.respond_to?(:final_level) ? actor.final_level : $data_actors[actor.id].final_level).to_s
end
bgcolors = get_bgcolors(type, cstyle)
gradient_bar_front(bgcolors, bgcolor, style, shape, x, y, w, h, 1)
gradient_bar_front(colors, bgcolor, style, shape, x, y, w, h, rate)
draw_lines(bgcolor, shape, x, y, w, h) if lines
psize, pcol = font.size, font.color
font.size = h
font.color = Color.new(255, 255, 255)
draw_text(x, y, w, h, str, 1) if text
font.size, font.color = psize, pcol
end
def draw_lines(color, shape, x, y, w, h)
case shape
when 1, 3
w -= h - 1
when 2
t = (h / 2.0).floor
v = []
h.times { |i|
v.push(((t + 1) * (1 - Math.sin(Math::PI * (i + 1) / (h + 1)))).floor)
}
end
w.times { |i|
if [0, 7].include?(i % 8)
case shape
when 0
fill_rect(x + i, y, 1, h, color)
when 1
h.times { |e|
set_pixel(x + i + e, y + e, color)
}
when 2
if i <= v.max
ind = v.index(v.detect { |val| val <= i })
elsif w - 1 - i <= v.max
ind = v.index(v.detect { |val| val <= w - 1 - i })
else
ind = 0
end
fill_rect(x + i, y + ind, 1, h - (ind) * 2, color)
when 3
h.times { |e|
set_pixel(x + i + h - 1 - e, y + e, color)
}
end
end
}
end
def get_bgcolors(type, cstyle)
bc = Color.new(0, 0, 0)
case type
when :hp
c1 = Color.new(100, 30, 30)
c2 = Color.new(30, 100, 30)
when :mp
c1 = Color.new(100, 30, 30)
c2 = Color.new(30, 30, 100)
when :exp
c1 = Color.new(100, 47, 22)
c2 = Color.new(80, 80, 22)
when :lvl
c1 = Color.new(22, 47, 100)
c2 = Color.new(80, 22, 80)
end
c = cstyle.map { |i|
case i
when 0 then c1
when 1 then c2
when 2 then bc
when 3 then c2
when 4 then c1
when 5 then lcol(c1)
when 6 then lcol(c2)
when 7 then lcol(c2)
when 8 then lcol(c1)
when 9 then dcol(c1)
when 10 then dcol(c2)
when 11 then dcol(c2)
when 12 then dcol(c1)
end
}
return c
end
end
class Scene_Map
alias tdks_hud_main main
def main
@hud = HUD.new(DesignHUD::HUD)
tdks_hud_main
@hud.dispose
end
alias tdks_hud_updt update
def update
@hud.update
tdks_hud_updt
end
end