module RPG
class Sprite
# whether to use the cool damage (set it to false if you never wanted this
# script)
COOL_DAMAGE = true
# the font name of the damage text
DAMAGE_FONT_NAME = "Times New Roman"
# the font size of the damage text
DAMAGE_FONT_SIZE = 32
# whether to make the damage text bold
DAMAGE_FONT_BOLD = true
# whether to make the damage text italic
DAMAGE_FONT_ITALIC = true
# the colors for the damage text
# directions for setup will be found in the script topic on Chaos Project
DAMAGE_COLORS = [
[proc { |val, crit| val.is_a?(Numeric) and val < 0 }, Color.new(176, 255, 144)],
[proc { |val, crit| crit }, Color.new(255, 0, 0)]
]
# the horizontal and vertical distance between the letters at the end of
# their movement
LETTER_SEPARATION = [0, 5]
# how much the damage's actual position can differ from the normal position
# (can help with scripts that show multiple damage numbers in quick
# succession)
POSITION_VARIANCE = [0..0, 0..0]
# the duration of the appearance of the damage
APPEAR_DURATION = 20
# the duration of the fading in of the damage
# note - should be less than APPEAR_DURATION
APPEAR_FADE_DURATION = 5
# the amount of frames of movement between each letter
APPEAR_OFFSET = 5
# the amplitude of the letters' movement
# suggested values
# modes 0 and 1
# 5 - 15
# modes 2, 4
# -0.5 - 0 or 0.0 - 2
# mode 3
# 0.5 - 1.5
# mode 4
# 0.5 - 2.0
# mode 5
# Color.new(FLASH_RED, FLASH_GREEN, FLASH_BLUE, FLASH_AMOUNT)
APPEAR_AMP = 10
# how far the letters should rotate when appearing (degrees)
APPEAR_ANGLE = 0
# the appearance mode
# letter animations:
# 0 - float
# 1 - bounce
# 2 - sink in
# 3 - 3d-spin
# non-letter animations:
# 4 - sink in
# 5 - flash (can be used with a color with an alpha of 0 to achieve some
# cool effects by setting APPEAR_ANGLE)
APPEAR_MODE = 0
# whether to have the letters enter in a random order
# note - no effect on non-letter animations
APPEAR_RANDOM = false
# how long to show the letters before they begin to disappear
WAIT_DURATION = 10
# the duration of the disappearance of the damage
DISAPPEAR_DURATION = 15
# the duration of the fading out of the damage
# note - should be less than DISAPPEAR_DURATION
DISAPPEAR_FADE_DURATION = 12
# the amount of frames of movement between each letter
DISAPPEAR_OFFSET = 2
# the amplitude of the letters' movement
# suggested values
# modes 0 and 1
# 5 - 15
# mode 2
# 1 - 2
# mode 3
# 0.5 - 1.5
DISAPPEAR_AMP = 1.5
# how far the letters should rotate when disappearing (degrees)
DISAPPEAR_ANGLE = 100
# which way to have the letters disappear
# letter animations:
# 0 - float
# 1 - bounce
# 2 - fall away
# 3 - 3d-spin
DISAPPEAR_MODE = 2
# whether to have the letters exit in a random order
DISAPPEAR_RANDOM = false
alias tdks_dmg_txt_init initialize
def initialize(viewport = nil)
tdks_dmg_txt_init(viewport)
@_cdamage_duration = 0
end
alias tdks_dmg_txt_dmg damage
def damage(value, critical)
unless RPG::Sprite::COOL_DAMAGE
return tdks_dmg_txt_dmg(value, critical)
end
dispose_damage
if value.is_a?(Numeric)
damage_string = value.abs.to_s
else
damage_string = value.to_s
end
obmp = bitmap
bmp = Bitmap.new(1, 1)
bmp.font.name = RPG::Sprite::DAMAGE_FONT_NAME
bmp.font.size = RPG::Sprite::DAMAGE_FONT_SIZE
bmp.font.bold = RPG::Sprite::DAMAGE_FONT_BOLD
bmp.font.italic = RPG::Sprite::DAMAGE_FONT_ITALIC
bmp.font.color.set(0, 0, 0)
@_cdamage_sprites = []
size = bmp.text_size(damage_string)
usep_bmp = Bitmap.new(size.width + 2 + RPG::Sprite::LETTER_SEPARATION[0] * (damage_string.length - 1), size.height + 2 + RPG::Sprite::LETTER_SEPARATION[1] * (damage_string.length - 1))
x = 0
y = 0
rx = (160 - size.width) / 2 - 80
pv = RPG::Sprite::POSITION_VARIANCE.map { |i| i.first + rand(i.last - i.first + 1) }
damage_string = damage_string.split('')
ofsx = damage_string.length * RPG::Sprite::LETTER_SEPARATION[0] / 2
ofsy = damage_string.length * RPG::Sprite::LETTER_SEPARATION[1] / 2
damage_string.each_with_index { |i, ind|
r = bmp.text_size(i)
r.x += 1
r.y += 1
bitmap = Bitmap.new(r.width+2, r.height+2)
bitmap.font = bmp.font
usep_bmp.font = bmp.font
(-1..1).each{|v|
next if v==0
bitmap.draw_text(r.x + v, r.y, r.width, r.height, i, 1)
bitmap.draw_text(r.x, r.y + v, r.width, r.height, i, 1)
usep_bmp.draw_text(x + RPG::Sprite::LETTER_SEPARATION[0] * ind + 1 + v, RPG::Sprite::LETTER_SEPARATION[1] * ind + 1, r.width, r.height, i, 1)
usep_bmp.draw_text(x + RPG::Sprite::LETTER_SEPARATION[0] * ind + 1, RPG::Sprite::LETTER_SEPARATION[1] * ind + 1 + v, r.width, r.height, i, 1)
}
bitmap.font.color.set(255, 255, 255)
usep_bmp.font.color.set(255, 255, 255)
RPG::Sprite::DAMAGE_COLORS.each { |col|
if col[0].call(value, critical)
bitmap.font.color = col[1]
usep_bmp.font.color = col[1]
end
}
bitmap.draw_text(r, i, 1)
usep_bmp.draw_text(x + RPG::Sprite::LETTER_SEPARATION[0] * ind + 1, RPG::Sprite::LETTER_SEPARATION[1] * ind + 1, r.width, r.height, i, 1)
sprite = ::Sprite.new(self.viewport)
sprite.z = 3000
sprite.bitmap = bitmap
case RPG::Sprite::APPEAR_MODE
when 0,1, 3:
sprite.ox = bitmap.width / 2
sprite.oy = bitmap.height / 2
when 2:
sprite.ox = 0
sprite.oy = bitmap.height
end
sprite.x = self.x + rx + x + sprite.ox + RPG::Sprite::LETTER_SEPARATION[0] * ind - ofsx + pv[0]
sprite.y = self.y - self.oy / 2 - 20 + 12 + sprite.oy + RPG::Sprite::LETTER_SEPARATION[1] * ind - ofsy + pv[1]
sprite.opacity = 0
x += r.width
@_cdamage_sprites.push(sprite)
}
sprite = Sprite.new(self.viewport)
sprite.bitmap = usep_bmp
case RPG::Sprite::APPEAR_MODE
when 4:
sprite.ox = sprite.bitmap.width / 2
sprite.oy = sprite.bitmap.height / 2
end
sprite.x = self.x + rx - ofsx + sprite.ox + pv[0]
sprite.y = self.y - self.oy / 2 - 20 + 12 - ofsy + sprite.oy + pv[1]
sprite.opacity = 0
sprite.z = 3000
if RPG::Sprite::APPEAR_MODE.between?(0, 3)
sprite.visible = false
else
@_cdamage_sprites.each{|i|i.visible=false}
end
@_cdamage_sprites.push(sprite)
l = @_cdamage_sprites.length
tmp = Array.new(l) { |i| i }
@_cdamage_rind = Array.new(l) { v=tmp[rand(tmp.length)];tmp.delete(v);v }
@_cdamage_spos = @_cdamage_sprites.map { |i| [i.x, i.y] }
@_cdamage_duration = RPG::Sprite::APPEAR_DURATION + RPG::Sprite::WAIT_DURATION + RPG::Sprite::DISAPPEAR_DURATION + (l - 1) * ((RPG::Sprite::DISAPPEAR_MODE.between?(0, 3) ? RPG::Sprite::DISAPPEAR_OFFSET : 0) + (RPG::Sprite::APPEAR_MODE.between?(0, 3) ? RPG::Sprite::APPEAR_OFFSET : 0))
@_damage_duration = 0
end
alias tdks_dmg_txt_effect? effect?
def effect?
return tdks_dmg_txt_effect?() || @_cdamage_duration > 0
end
alias tdks_dmg_txt_updt update
def update
tdks_dmg_txt_updt
if @_cdamage_duration > 0
@_cdamage_duration -= 1
amnt = 50
ofs = RPG::Sprite::APPEAR_OFFSET
ofs2 = RPG::Sprite::DISAPPEAR_OFFSET
l = @_cdamage_sprites.length - 1
if @_cdamage_duration > RPG::Sprite::DISAPPEAR_DURATION + RPG::Sprite::WAIT_DURATION + (l - 1) * (RPG::Sprite::DISAPPEAR_MODE.between?(0, 3) ? ofs2 : 0)
frames = @_cdamage_duration - RPG::Sprite::DISAPPEAR_DURATION - RPG::Sprite::WAIT_DURATION - (l - 1) * (RPG::Sprite::DISAPPEAR_MODE.between?(0, 3) ? ofs2 : 0)
if RPG::Sprite::APPEAR_MODE.between?(0, 3)
@_cdamage_sprites[0...l].each_with_index { |i, ind|
rind = ind
ind = @_cdamage_rind[ind] if RPG::Sprite::APPEAR_RANDOM
if RPG::Sprite::APPEAR_DURATION + (l - 1) * ofs - frames - ind * ofs > 0 and (l - 1 - ind) * ofs - frames < 0
fadedur = [RPG::Sprite::APPEAR_FADE_DURATION, RPG::Sprite::APPEAR_DURATION].min
if RPG::Sprite::APPEAR_DURATION + (l - 1) * ofs - frames - ind * ofs <= fadedur - 1
i.opacity = 255 * (RPG::Sprite::APPEAR_DURATION + (l - 1) * ofs - frames - ind * ofs + 1) / fadedur
end
case RPG::Sprite::APPEAR_MODE
when 0:
s = 0-Math.cos(Math::PI * 3 * (RPG::Sprite::APPEAR_DURATION + (l - 1) * ofs - frames - ind * ofs) / (RPG::Sprite::APPEAR_DURATION - 1) / 2)
i.y = @_cdamage_spos[rind][1] - RPG::Sprite::APPEAR_AMP * s
when 1:
s = 2 * Math.cos(Math::PI * 4 * (RPG::Sprite::APPEAR_DURATION + (l - 1) * ofs - frames - ind * ofs) / (RPG::Sprite::APPEAR_DURATION - 1) / 3).abs - 1
i.y = @_cdamage_spos[rind][1] - RPG::Sprite::APPEAR_AMP * s
when 2:
i.zoom_x = i.zoom_y = RPG::Sprite::APPEAR_AMP - (RPG::Sprite::APPEAR_AMP - 1) * (RPG::Sprite::APPEAR_DURATION + (l - 1) * ofs - frames - ind * ofs).to_f / (RPG::Sprite::APPEAR_DURATION - 1)
when 3:
angle = (360 * RPG::Sprite::APPEAR_AMP * (RPG::Sprite::APPEAR_DURATION + (l - 1) * ofs - frames - ind * ofs).to_f / (RPG::Sprite::APPEAR_DURATION - 1) - RPG::Sprite::APPEAR_AMP * 360) % 360
while angle < 0;angle += 360;end
if angle < 90
i.mirror = false
i.zoom_x = Math.sin((90 - angle) * Math::PI / 180)
elsif angle < 180
i.mirror = true
i.zoom_x = Math.sin((angle - 90) * Math::PI / 180)
elsif angle < 270
i.mirror = true
i.zoom_x = Math.sin((270 - angle) * Math::PI / 180)
else
i.mirror = false
i.zoom_x = Math.sin((angle - 270) * Math::PI / 180)
end
end
i.angle = (RPG::Sprite::APPEAR_ANGLE) * (RPG::Sprite::APPEAR_DURATION + (l - 1) * ofs - frames - ind * ofs) / (RPG::Sprite::APPEAR_DURATION - 1) - RPG::Sprite::APPEAR_ANGLE
end
}
else
sprite = @_cdamage_sprites[-1]
sprite.angle = (RPG::Sprite::APPEAR_ANGLE) * (RPG::Sprite::APPEAR_DURATION - frames) / (RPG::Sprite::APPEAR_DURATION - 1) - RPG::Sprite::APPEAR_ANGLE
fadedur = [RPG::Sprite::APPEAR_FADE_DURATION, RPG::Sprite::APPEAR_DURATION].min
if RPG::Sprite::APPEAR_DURATION - frames <= fadedur - 1
sprite.opacity = 255 * (RPG::Sprite::APPEAR_DURATION - frames + 1) / fadedur
end
case RPG::Sprite::APPEAR_MODE
when 4:
sprite.zoom_x = sprite.zoom_y = 1.0 + RPG::Sprite::APPEAR_AMP.to_f * (frames - 1) / RPG::Sprite::APPEAR_DURATION
when 5:
col = RPG::Sprite::APPEAR_AMP.clone
col.alpha *= 1-(2 * (RPG::Sprite::APPEAR_DURATION + 1.0 - frames) / RPG::Sprite::APPEAR_DURATION - 1).abs
sprite.color = col
end
end
if @_cdamage_duration == RPG::Sprite::DISAPPEAR_DURATION + RPG::Sprite::WAIT_DURATION + (l - 1) * ofs2 + 1
tmp = Array.new(l) { |e| e }
@_cdamage_rind = Array.new(l) { v=tmp[rand(tmp.length)];tmp.delete(v);v }
@_cdamage_sprites.each_with_index { |e, tind|
oox = e.ox
ooy = e.oy
case RPG::Sprite::DISAPPEAR_MODE
when 0,1,2:
e.ox = 0
e.oy = e.bitmap.height
when 3:
e.ox = e.bitmap.width / 2
e.oy = e.bitmap.height / 2
end
e.x += e.ox - oox
e.y += e.oy - ooy
@_cdamage_spos[tind] = [e.x, e.y]
}
if RPG::Sprite::DISAPPEAR_MODE.between?(0, 3)
@_cdamage_sprites[-1].visible = false
@_cdamage_sprites[0...l].each { |i| i.visible = true;i.opacity = 255 }
else
@_cdamage_sprites[-1].visible = true
@_cdamage_sprites[-1].opacity = 255
@_cdamage_sprites[0...l].each { |i| i.visible = false }
end
end
elsif @_cdamage_duration.between?(1, RPG::Sprite::DISAPPEAR_DURATION + (l - 1) * ofs2)
@_cdamage_sprites[0...l].each_with_index { |i, ind|
rind = ind
ind = @_cdamage_rind[ind] if RPG::Sprite::DISAPPEAR_RANDOM
frames = @_cdamage_duration
if RPG::Sprite::DISAPPEAR_DURATION + (l - 1) * ofs2 - frames - ind * ofs2 > 0 and RPG::Sprite::DISAPPEAR_DURATION + (l - 1) * ofs2 - frames - ind * ofs2 < RPG::Sprite::DISAPPEAR_DURATION
case RPG::Sprite::DISAPPEAR_MODE
when 0:
s = Math.sin(Math::PI * 2 * (RPG::Sprite::DISAPPEAR_DURATION + (l - 1) * ofs2 - frames - ind * ofs2) / (RPG::Sprite::DISAPPEAR_DURATION - 1) / 3)
i.y = @_cdamage_spos[rind][1] - RPG::Sprite::DISAPPEAR_AMP * s
when 1:
s = Math.sin(Math::PI * (RPG::Sprite::DISAPPEAR_DURATION + (l - 1) * ofs2 - frames - ind * ofs2) / (RPG::Sprite::DISAPPEAR_DURATION - 1)).abs
i.y = @_cdamage_spos[rind][1] + RPG::Sprite::DISAPPEAR_AMP * s
when 2:
i.y += RPG::Sprite::DISAPPEAR_AMP * 1.2 ** ((RPG::Sprite::DISAPPEAR_DURATION + (l - 1) * ofs2 - frames - ind * ofs2) / (RPG::Sprite::DISAPPEAR_DURATION - 1))
when 3:
angle = (360 * RPG::Sprite::DISAPPEAR_AMP * (RPG::Sprite::DISAPPEAR_DURATION + (l - 1) * ofs2 - frames - ind * ofs2).to_f / (RPG::Sprite::DISAPPEAR_DURATION - 1)) % 360
while angle < 0;angle += 360;end
if angle < 90
i.mirror = false
i.zoom_x = Math.sin((90 - angle) * Math::PI / 180)
elsif angle < 180
i.mirror = true
i.zoom_x = Math.sin((angle - 90) * Math::PI / 180)
elsif angle < 270
i.mirror = true
i.zoom_x = Math.sin((270 - angle) * Math::PI / 180)
else
i.mirror = false
i.zoom_x = Math.sin((angle - 270) * Math::PI / 180)
end
end
i.angle = (RPG::Sprite::DISAPPEAR_ANGLE) * (RPG::Sprite::DISAPPEAR_DURATION + (l - 1) * ofs2 - frames - ind * ofs2) / (RPG::Sprite::DISAPPEAR_DURATION - 1)
end
fadedur = [RPG::Sprite::DISAPPEAR_FADE_DURATION, RPG::Sprite::DISAPPEAR_DURATION].min
if frames - (l - 1 - ind) * ofs2 < fadedur
i.opacity = 255 * (frames - (l - 1 - ind) * ofs2) / fadedur
end
}
end
if @_cdamage_duration == 0
@_cdamage_sprites.each{|i|i.bitmap.dispose;i.dispose}
end
end
end
end
end