|
|
|
|
@@ -4,14 +4,20 @@
|
|
|
|
|
class Battle::Scene::PokemonDataBox < Sprite
|
|
|
|
|
attr_reader :battler
|
|
|
|
|
attr_accessor :selected
|
|
|
|
|
attr_reader :animatingHP
|
|
|
|
|
attr_reader :animatingExp
|
|
|
|
|
|
|
|
|
|
# Time in seconds to fully fill the Exp bar (from empty).
|
|
|
|
|
EXP_BAR_FILL_TIME = 1.75
|
|
|
|
|
# Time in seconds for this data box to flash when the Exp fully fills.
|
|
|
|
|
EXP_FULL_FLASH_DURATION = 0.2
|
|
|
|
|
# Maximum time in seconds to make a change to the HP bar.
|
|
|
|
|
HP_BAR_CHANGE_TIME = 1.0
|
|
|
|
|
# Time (in seconds) for one complete sprite bob cycle (up and down) while
|
|
|
|
|
# choosing a command for this battler or when this battler is being chosen as
|
|
|
|
|
# a target. Set to nil to prevent bobbing.
|
|
|
|
|
BOBBING_DURATION = 0.6
|
|
|
|
|
# Height in pixels of a status icon
|
|
|
|
|
STATUS_ICON_HEIGHT = 16
|
|
|
|
|
# Text colors
|
|
|
|
|
NAME_BASE_COLOR = Color.new(72, 72, 72)
|
|
|
|
|
NAME_SHADOW_COLOR = Color.new(184, 184, 184)
|
|
|
|
|
MALE_BASE_COLOR = Color.new(48, 96, 216)
|
|
|
|
|
@@ -21,18 +27,14 @@ class Battle::Scene::PokemonDataBox < Sprite
|
|
|
|
|
|
|
|
|
|
def initialize(battler, sideSize, viewport = nil)
|
|
|
|
|
super(viewport)
|
|
|
|
|
@battler = battler
|
|
|
|
|
@sprites = {}
|
|
|
|
|
@spriteX = 0
|
|
|
|
|
@spriteY = 0
|
|
|
|
|
@spriteBaseX = 0
|
|
|
|
|
@selected = 0
|
|
|
|
|
@frame = 0
|
|
|
|
|
@showHP = false # Specifically, show the HP numbers
|
|
|
|
|
@animatingHP = false
|
|
|
|
|
@showExp = false # Specifically, show the Exp bar
|
|
|
|
|
@animatingExp = false
|
|
|
|
|
@expFlash = 0
|
|
|
|
|
@battler = battler
|
|
|
|
|
@sprites = {}
|
|
|
|
|
@spriteX = 0
|
|
|
|
|
@spriteY = 0
|
|
|
|
|
@spriteBaseX = 0
|
|
|
|
|
@selected = 0
|
|
|
|
|
@show_hp_numbers = false
|
|
|
|
|
@show_exp_bar = false
|
|
|
|
|
initializeDataBoxGraphic(sideSize)
|
|
|
|
|
initializeOtherGraphics(viewport)
|
|
|
|
|
refresh
|
|
|
|
|
@@ -45,8 +47,8 @@ class Battle::Scene::PokemonDataBox < Sprite
|
|
|
|
|
bgFilename = ["Graphics/UI/Battle/databox_normal",
|
|
|
|
|
"Graphics/UI/Battle/databox_normal_foe"][@battler.index % 2]
|
|
|
|
|
if onPlayerSide
|
|
|
|
|
@showHP = true
|
|
|
|
|
@showExp = true
|
|
|
|
|
@show_hp_numbers = true
|
|
|
|
|
@show_exp_bar = true
|
|
|
|
|
end
|
|
|
|
|
else # Multiple Pokémon on side, use the thin dara box BG
|
|
|
|
|
bgFilename = ["Graphics/UI/Battle/databox_thin",
|
|
|
|
|
@@ -143,7 +145,7 @@ class Battle::Scene::PokemonDataBox < Sprite
|
|
|
|
|
@sprites.each do |i|
|
|
|
|
|
i[1].visible = value if !i[1].disposed?
|
|
|
|
|
end
|
|
|
|
|
@expBar.visible = (value && @showExp)
|
|
|
|
|
@expBar.visible = (value && @show_exp_bar)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def color=(value)
|
|
|
|
|
@@ -159,38 +161,46 @@ class Battle::Scene::PokemonDataBox < Sprite
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def hp
|
|
|
|
|
return (@animatingHP) ? @currentHP : @battler.hp
|
|
|
|
|
return (animating_hp?) ? @anim_hp_current : @battler.hp
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def exp_fraction
|
|
|
|
|
return 0.0 if @rangeExp == 0
|
|
|
|
|
return (@animatingExp) ? @currentExp.to_f / @rangeExp : @battler.pokemon.exp_fraction
|
|
|
|
|
if animating_exp?
|
|
|
|
|
return 0.0 if @anim_exp_range == 0
|
|
|
|
|
return @anim_exp_current.to_f / @anim_exp_range
|
|
|
|
|
end
|
|
|
|
|
return @battler.pokemon.exp_fraction
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def animateHP(oldHP, newHP, rangeHP)
|
|
|
|
|
@currentHP = oldHP
|
|
|
|
|
@endHP = newHP
|
|
|
|
|
@rangeHP = rangeHP
|
|
|
|
|
# NOTE: A change in HP takes the same amount of time to animate, no matter
|
|
|
|
|
# how big a change it is.
|
|
|
|
|
@hpIncPerFrame = (newHP - oldHP).abs / (HP_BAR_CHANGE_TIME * Graphics.frame_rate)
|
|
|
|
|
# minInc is the smallest amount that HP is allowed to change per frame.
|
|
|
|
|
# This avoids a tiny change in HP still taking HP_BAR_CHANGE_TIME seconds.
|
|
|
|
|
minInc = (rangeHP * 4) / (@hpBarBitmap.width * HP_BAR_CHANGE_TIME * Graphics.frame_rate)
|
|
|
|
|
@hpIncPerFrame = minInc if @hpIncPerFrame < minInc
|
|
|
|
|
@animatingHP = true
|
|
|
|
|
# NOTE: A change in HP takes the same amount of time to animate, no matter how
|
|
|
|
|
# big a change it is.
|
|
|
|
|
def animate_hp(old_val, new_val)
|
|
|
|
|
return if old_val == new_val
|
|
|
|
|
@anim_hp_start = old_val
|
|
|
|
|
@anim_hp_end = new_val
|
|
|
|
|
@anim_hp_current = old_val
|
|
|
|
|
@anim_hp_timer_start = System.uptime
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def animateExp(oldExp, newExp, rangeExp)
|
|
|
|
|
return if rangeExp == 0
|
|
|
|
|
@currentExp = oldExp
|
|
|
|
|
@endExp = newExp
|
|
|
|
|
@rangeExp = rangeExp
|
|
|
|
|
# NOTE: Filling the Exp bar from empty to full takes EXP_BAR_FILL_TIME
|
|
|
|
|
# seconds no matter what. Filling half of it takes half as long, etc.
|
|
|
|
|
@expIncPerFrame = rangeExp / (EXP_BAR_FILL_TIME * Graphics.frame_rate)
|
|
|
|
|
@animatingExp = true
|
|
|
|
|
pbSEPlay("Pkmn exp gain") if @showExp
|
|
|
|
|
def animating_hp?
|
|
|
|
|
return @anim_hp_timer_start != nil
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# NOTE: Filling the Exp bar from empty to full takes EXP_BAR_FILL_TIME seconds
|
|
|
|
|
# no matter what. Filling half of it takes half as long, etc.
|
|
|
|
|
def animate_exp(old_val, new_val, range)
|
|
|
|
|
return if old_val == new_val || range == 0 || !@show_exp_bar
|
|
|
|
|
@anim_exp_start = old_val
|
|
|
|
|
@anim_exp_end = new_val
|
|
|
|
|
@anim_exp_range = range
|
|
|
|
|
@anim_exp_duration_mult = (new_val - old_val).abs / range.to_f
|
|
|
|
|
@anim_exp_current = old_val
|
|
|
|
|
@anim_exp_timer_start = System.uptime
|
|
|
|
|
pbSEPlay("Pkmn exp gain") if @show_exp_bar
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def animating_exp?
|
|
|
|
|
return @anim_exp_timer_start != nil
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def pbDrawNumber(number, btmp, startX, startY, align = 0)
|
|
|
|
|
@@ -284,15 +294,15 @@ class Battle::Scene::PokemonDataBox < Sprite
|
|
|
|
|
draw_shiny_icon
|
|
|
|
|
draw_special_form_icon
|
|
|
|
|
draw_owned_icon
|
|
|
|
|
refreshHP
|
|
|
|
|
refreshExp
|
|
|
|
|
refresh_hp
|
|
|
|
|
refresh_exp
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def refreshHP
|
|
|
|
|
def refresh_hp
|
|
|
|
|
@hpNumbers.bitmap.clear
|
|
|
|
|
return if !@battler.pokemon
|
|
|
|
|
# Show HP numbers
|
|
|
|
|
if @showHP
|
|
|
|
|
if @show_hp_numbers
|
|
|
|
|
pbDrawNumber(self.hp, @hpNumbers.bitmap, 54, 2, 1)
|
|
|
|
|
pbDrawNumber(-1, @hpNumbers.bitmap, 54, 2) # / char
|
|
|
|
|
pbDrawNumber(@battler.totalhp, @hpNumbers.bitmap, 70, 2)
|
|
|
|
|
@@ -307,14 +317,14 @@ class Battle::Scene::PokemonDataBox < Sprite
|
|
|
|
|
w = ((w / 2.0).round) * 2
|
|
|
|
|
end
|
|
|
|
|
@hpBar.src_rect.width = w
|
|
|
|
|
hpColor = 0 # Green bar
|
|
|
|
|
hpColor = 0 # Green bar
|
|
|
|
|
hpColor = 1 if self.hp <= @battler.totalhp / 2 # Yellow bar
|
|
|
|
|
hpColor = 2 if self.hp <= @battler.totalhp / 4 # Red bar
|
|
|
|
|
@hpBar.src_rect.y = hpColor * @hpBarBitmap.height / 3
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def refreshExp
|
|
|
|
|
return if !@showExp
|
|
|
|
|
def refresh_exp
|
|
|
|
|
return if !@show_exp_bar
|
|
|
|
|
w = exp_fraction * @expBarBitmap.width
|
|
|
|
|
# NOTE: The line below snaps the bar's width to the nearest 2 pixels, to
|
|
|
|
|
# fit in with the rest of the graphics which are doubled in size.
|
|
|
|
|
@@ -322,80 +332,82 @@ class Battle::Scene::PokemonDataBox < Sprite
|
|
|
|
|
@expBar.src_rect.width = w
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def updateHPAnimation
|
|
|
|
|
return if !@animatingHP
|
|
|
|
|
if @currentHP < @endHP # Gaining HP
|
|
|
|
|
@currentHP += @hpIncPerFrame
|
|
|
|
|
@currentHP = @endHP if @currentHP >= @endHP
|
|
|
|
|
elsif @currentHP > @endHP # Losing HP
|
|
|
|
|
@currentHP -= @hpIncPerFrame
|
|
|
|
|
@currentHP = @endHP if @currentHP <= @endHP
|
|
|
|
|
end
|
|
|
|
|
def update_hp_animation
|
|
|
|
|
return if !animating_hp?
|
|
|
|
|
@anim_hp_current = lerp(@anim_hp_start, @anim_hp_end, HP_BAR_CHANGE_TIME,
|
|
|
|
|
@anim_hp_timer_start, System.uptime)
|
|
|
|
|
# Refresh the HP bar/numbers
|
|
|
|
|
refreshHP
|
|
|
|
|
@animatingHP = false if @currentHP == @endHP
|
|
|
|
|
refresh_hp
|
|
|
|
|
# End the HP bar filling animation
|
|
|
|
|
if @anim_hp_current == @anim_hp_end
|
|
|
|
|
@anim_hp_start = nil
|
|
|
|
|
@anim_hp_end = nil
|
|
|
|
|
@anim_hp_timer_start = nil
|
|
|
|
|
@anim_hp_current = nil
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def updateExpAnimation
|
|
|
|
|
return if !@animatingExp
|
|
|
|
|
if !@showExp # Not showing the Exp bar, no need to waste time animating it
|
|
|
|
|
@currentExp = @endExp
|
|
|
|
|
@animatingExp = false
|
|
|
|
|
def update_exp_animation
|
|
|
|
|
return if !animating_exp?
|
|
|
|
|
if !@show_exp_bar # Not showing the Exp bar, no need to waste time animating it
|
|
|
|
|
@anim_exp_timer_start = nil
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
if @currentExp < @endExp # Gaining Exp
|
|
|
|
|
@currentExp += @expIncPerFrame
|
|
|
|
|
@currentExp = @endExp if @currentExp >= @endExp
|
|
|
|
|
elsif @currentExp > @endExp # Losing Exp
|
|
|
|
|
@currentExp -= @expIncPerFrame
|
|
|
|
|
@currentExp = @endExp if @currentExp <= @endExp
|
|
|
|
|
end
|
|
|
|
|
duration = EXP_BAR_FILL_TIME * @anim_exp_duration_mult
|
|
|
|
|
@anim_exp_current = lerp(@anim_exp_start, @anim_exp_end, duration,
|
|
|
|
|
@anim_exp_timer_start, System.uptime)
|
|
|
|
|
# Refresh the Exp bar
|
|
|
|
|
refreshExp
|
|
|
|
|
return if @currentExp != @endExp # Exp bar still has more to animate
|
|
|
|
|
# Exp bar is completely filled, level up with a flash and sound effect
|
|
|
|
|
if @currentExp >= @rangeExp
|
|
|
|
|
if @expFlash == 0
|
|
|
|
|
pbSEStop
|
|
|
|
|
@expFlash = Graphics.frame_rate / 5
|
|
|
|
|
pbSEPlay("Pkmn exp full")
|
|
|
|
|
self.flash(Color.new(64, 200, 248, 192), @expFlash)
|
|
|
|
|
@sprites.each do |i|
|
|
|
|
|
i[1].flash(Color.new(64, 200, 248, 192), @expFlash) if !i[1].disposed?
|
|
|
|
|
end
|
|
|
|
|
refresh_exp
|
|
|
|
|
return if @anim_exp_current != @anim_exp_end # Exp bar still has more to animate
|
|
|
|
|
# End the Exp bar filling animation
|
|
|
|
|
if @anim_exp_current >= @anim_exp_range
|
|
|
|
|
if @anim_exp_flash_timer_start
|
|
|
|
|
# Waiting for Exp full flash to finish
|
|
|
|
|
return if System.uptime - @anim_exp_flash_timer_start < EXP_FULL_FLASH_DURATION
|
|
|
|
|
else
|
|
|
|
|
@expFlash -= 1
|
|
|
|
|
@animatingExp = false if @expFlash == 0
|
|
|
|
|
# Show the Exp full flash
|
|
|
|
|
@anim_exp_flash_timer_start = System.uptime
|
|
|
|
|
pbSEStop
|
|
|
|
|
pbSEPlay("Pkmn exp full")
|
|
|
|
|
flash_duration = EXP_FULL_FLASH_DURATION * Graphics.frame_rate # Must be in frames, not seconds
|
|
|
|
|
self.flash(Color.new(64, 200, 248, 192), flash_duration)
|
|
|
|
|
@sprites.each do |i|
|
|
|
|
|
i[1].flash(Color.new(64, 200, 248, 192), flash_duration) if !i[1].disposed?
|
|
|
|
|
end
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
pbSEStop
|
|
|
|
|
# Exp bar has finished filling, end animation
|
|
|
|
|
@animatingExp = false
|
|
|
|
|
end
|
|
|
|
|
pbSEStop if !@anim_exp_flash_timer_start
|
|
|
|
|
@anim_exp_start = nil
|
|
|
|
|
@anim_exp_end = nil
|
|
|
|
|
@anim_exp_duration_mult = nil
|
|
|
|
|
@anim_exp_current = nil
|
|
|
|
|
@anim_exp_timer_start = nil
|
|
|
|
|
@anim_exp_flash_timer_start = nil
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
QUARTER_ANIM_PERIOD = Graphics.frame_rate * 3 / 20
|
|
|
|
|
|
|
|
|
|
def updatePositions(frameCounter)
|
|
|
|
|
def update_positions
|
|
|
|
|
self.x = @spriteX
|
|
|
|
|
self.y = @spriteY
|
|
|
|
|
# Data box bobbing while Pokémon is selected
|
|
|
|
|
if @selected == 1 || @selected == 2 # Choosing commands/targeted or damaged
|
|
|
|
|
case (frameCounter / QUARTER_ANIM_PERIOD).floor
|
|
|
|
|
if (@selected == 1 || @selected == 2) && BOBBING_DURATION # Choosing commands/targeted
|
|
|
|
|
bob_delta = System.uptime % BOBBING_DURATION # 0-BOBBING_DURATION
|
|
|
|
|
bob_frame = (4 * bob_delta / BOBBING_DURATION).floor
|
|
|
|
|
case bob_frame
|
|
|
|
|
when 1 then self.y = @spriteY - 2
|
|
|
|
|
when 3 then self.y = @spriteY + 2
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def update(frameCounter = 0)
|
|
|
|
|
super()
|
|
|
|
|
def update
|
|
|
|
|
super
|
|
|
|
|
# Animate HP bar
|
|
|
|
|
updateHPAnimation
|
|
|
|
|
update_hp_animation
|
|
|
|
|
# Animate Exp bar
|
|
|
|
|
updateExpAnimation
|
|
|
|
|
update_exp_animation
|
|
|
|
|
# Update coordinates of the data box
|
|
|
|
|
updatePositions(frameCounter)
|
|
|
|
|
update_positions
|
|
|
|
|
pbUpdateSpriteHash(@sprites)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
@@ -502,6 +514,13 @@ class Battle::Scene::BattlerSprite < RPG::Sprite
|
|
|
|
|
attr_accessor :selected
|
|
|
|
|
attr_reader :sideSize
|
|
|
|
|
|
|
|
|
|
# Time (in seconds) for one complete sprite bob cycle (up and down) while
|
|
|
|
|
# choosing a command for this battler. Set to nil to prevent bobbing.
|
|
|
|
|
COMMAND_BOBBING_DURATION = 0.6
|
|
|
|
|
# Time (in seconds) for one complete blinking cycle while this battler is
|
|
|
|
|
# being chosen as a target. Set to nil to prevent blinking.
|
|
|
|
|
TARGET_BLINKING_DURATION = 0.3
|
|
|
|
|
|
|
|
|
|
def initialize(viewport, sideSize, index, battleAnimations)
|
|
|
|
|
super(viewport)
|
|
|
|
|
@pkmn = nil
|
|
|
|
|
@@ -511,7 +530,6 @@ class Battle::Scene::BattlerSprite < RPG::Sprite
|
|
|
|
|
# @selected: 0 = not selected, 1 = choosing action bobbing for this Pokémon,
|
|
|
|
|
# 2 = flashing when targeted
|
|
|
|
|
@selected = 0
|
|
|
|
|
@frame = 0
|
|
|
|
|
@updating = false
|
|
|
|
|
@spriteX = 0 # Actual x coordinate
|
|
|
|
|
@spriteY = 0 # Actual y coordinate
|
|
|
|
|
@@ -588,10 +606,7 @@ class Battle::Scene::BattlerSprite < RPG::Sprite
|
|
|
|
|
@pkmn&.play_cry
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
QUARTER_ANIM_PERIOD = Graphics.frame_rate * 3 / 20
|
|
|
|
|
SIXTH_ANIM_PERIOD = Graphics.frame_rate * 2 / 20
|
|
|
|
|
|
|
|
|
|
def update(frameCounter = 0)
|
|
|
|
|
def update
|
|
|
|
|
return if !@_iconBitmap
|
|
|
|
|
@updating = true
|
|
|
|
|
# Update bitmap
|
|
|
|
|
@@ -599,8 +614,10 @@ class Battle::Scene::BattlerSprite < RPG::Sprite
|
|
|
|
|
self.bitmap = @_iconBitmap.bitmap
|
|
|
|
|
# Pokémon sprite bobbing while Pokémon is selected
|
|
|
|
|
@spriteYExtra = 0
|
|
|
|
|
if @selected == 1 # When choosing commands for this Pokémon
|
|
|
|
|
case (frameCounter / QUARTER_ANIM_PERIOD).floor
|
|
|
|
|
if @selected == 1 && COMMAND_BOBBING_DURATION # When choosing commands for this Pokémon
|
|
|
|
|
bob_delta = System.uptime % COMMAND_BOBBING_DURATION # 0-COMMAND_BOBBING_DURATION
|
|
|
|
|
bob_frame = (4 * bob_delta / COMMAND_BOBBING_DURATION).floor
|
|
|
|
|
case bob_frame
|
|
|
|
|
when 1 then @spriteYExtra = 2
|
|
|
|
|
when 3 then @spriteYExtra = -2
|
|
|
|
|
end
|
|
|
|
|
@@ -609,11 +626,10 @@ class Battle::Scene::BattlerSprite < RPG::Sprite
|
|
|
|
|
self.y = self.y
|
|
|
|
|
self.visible = @spriteVisible
|
|
|
|
|
# Pokémon sprite blinking when targeted
|
|
|
|
|
if @selected == 2 && @spriteVisible
|
|
|
|
|
case (frameCounter / SIXTH_ANIM_PERIOD).floor
|
|
|
|
|
when 2, 5 then self.visible = false
|
|
|
|
|
else self.visible = true
|
|
|
|
|
end
|
|
|
|
|
if @selected == 2 && @spriteVisible && TARGET_BLINKING_DURATION
|
|
|
|
|
blink_delta = System.uptime % TARGET_BLINKING_DURATION # 0-TARGET_BLINKING_DURATION
|
|
|
|
|
blink_frame = (3 * blink_delta / TARGET_BLINKING_DURATION).floor
|
|
|
|
|
self.visible = (blink_frame != 0)
|
|
|
|
|
end
|
|
|
|
|
@updating = false
|
|
|
|
|
end
|
|
|
|
|
@@ -673,7 +689,7 @@ class Battle::Scene::BattlerShadowSprite < RPG::Sprite
|
|
|
|
|
pbSetPosition
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def update(frameCounter = 0)
|
|
|
|
|
def update
|
|
|
|
|
return if !@_iconBitmap
|
|
|
|
|
# Update bitmap
|
|
|
|
|
@_iconBitmap.update
|
|
|
|
|
|