mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-05 21:51:46 +00:00
877 lines
32 KiB
Ruby
877 lines
32 KiB
Ruby
#===============================================================================
|
|
# Shows the battle scene fading in while elements slide around into place
|
|
#===============================================================================
|
|
class BattleIntroAnimation < PokeBattle_Animation
|
|
def initialize(sprites,viewport,battle)
|
|
@battle = battle
|
|
super(sprites,viewport)
|
|
end
|
|
|
|
def createProcesses
|
|
appearTime = 20 # This is in 1/20 seconds
|
|
# Background
|
|
if @sprites["battle_bg2"]
|
|
makeSlideSprite("battle_bg",0.5,appearTime)
|
|
makeSlideSprite("battle_bg2",0.5,appearTime)
|
|
end
|
|
# Bases
|
|
makeSlideSprite("base_0",1,appearTime,PictureOrigin::Bottom)
|
|
makeSlideSprite("base_1",-1,appearTime,PictureOrigin::Center)
|
|
# Player sprite, partner trainer sprite
|
|
@battle.player.each_with_index do |_p,i|
|
|
makeSlideSprite("player_#{i+1}",1,appearTime,PictureOrigin::Bottom)
|
|
end
|
|
# Opposing trainer sprite(s) or wild Pokémon sprite(s)
|
|
if @battle.trainerBattle?
|
|
@battle.opponent.each_with_index do |_p,i|
|
|
makeSlideSprite("trainer_#{i+1}",-1,appearTime,PictureOrigin::Bottom)
|
|
end
|
|
else # Wild battle
|
|
@battle.pbParty(1).each_with_index do |_pkmn,i|
|
|
idxBattler = 2*i+1
|
|
makeSlideSprite("pokemon_#{idxBattler}",-1,appearTime,PictureOrigin::Bottom)
|
|
end
|
|
end
|
|
# Shadows
|
|
for i in 0...@battle.battlers.length
|
|
makeSlideSprite("shadow_#{i}",((i%2)==0) ? 1 : -1,appearTime,PictureOrigin::Center)
|
|
end
|
|
# Fading blackness over whole screen
|
|
blackScreen = addNewSprite(0,0,"Graphics/Battle animations/black_screen")
|
|
blackScreen.setZ(0,999)
|
|
blackScreen.moveOpacity(0,8,0)
|
|
# Fading blackness over command bar
|
|
blackBar = addNewSprite(@sprites["cmdBar_bg"].x,@sprites["cmdBar_bg"].y,
|
|
"Graphics/Battle animations/black_bar")
|
|
blackBar.setZ(0,998)
|
|
blackBar.moveOpacity(appearTime*3/4,appearTime/4,0)
|
|
end
|
|
|
|
def makeSlideSprite(spriteName,deltaMult,appearTime,origin=nil)
|
|
# If deltaMult is positive, the sprite starts off to the right and moves
|
|
# left (for sprites on the player's side and the background).
|
|
return if !@sprites[spriteName]
|
|
s = addSprite(@sprites[spriteName],origin)
|
|
s.setDelta(0,(Graphics.width*deltaMult).floor,0)
|
|
s.moveDelta(0,appearTime,(-Graphics.width*deltaMult).floor,0)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
#===============================================================================
|
|
# Shows wild Pokémon fading back to their normal color, and triggers their intro
|
|
# animations
|
|
#===============================================================================
|
|
class BattleIntroAnimation2 < PokeBattle_Animation
|
|
def initialize(sprites,viewport,sideSize)
|
|
@sideSize = sideSize
|
|
super(sprites,viewport)
|
|
end
|
|
|
|
def createProcesses
|
|
for i in 0...@sideSize
|
|
idxBattler = 2*i+1
|
|
next if !@sprites["pokemon_#{idxBattler}"]
|
|
battler = addSprite(@sprites["pokemon_#{idxBattler}"],PictureOrigin::Bottom)
|
|
battler.moveTone(0,4,Tone.new(0,0,0,0))
|
|
battler.setCallback(10*i,[@sprites["pokemon_#{idxBattler}"],:pbPlayIntroAnimation])
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
#===============================================================================
|
|
# Makes a side's party bar and balls appear
|
|
#===============================================================================
|
|
class LineupAppearAnimation < PokeBattle_Animation
|
|
BAR_DISPLAY_WIDTH = 248
|
|
|
|
def initialize(sprites,viewport,side,party,partyStarts,fullAnim)
|
|
@side = side
|
|
@party = party
|
|
@partyStarts = partyStarts
|
|
@fullAnim = fullAnim # True at start of battle, false when switching
|
|
resetGraphics(sprites)
|
|
super(sprites,viewport)
|
|
end
|
|
|
|
def resetGraphics(sprites)
|
|
bar = sprites["partyBar_#{@side}"]
|
|
case @side
|
|
when 0 # Player's lineup
|
|
barX = Graphics.width - BAR_DISPLAY_WIDTH
|
|
barY = Graphics.height - 142
|
|
ballX = barX + 44
|
|
ballY = barY - 30
|
|
when 1 # Opposing lineup
|
|
barX = BAR_DISPLAY_WIDTH
|
|
barY = 114
|
|
ballX = barX - 44 - 30 # 30 is width of ball icon
|
|
ballY = barY - 30
|
|
barX -= bar.bitmap.width
|
|
end
|
|
ballXdiff = 32*(1-2*@side)
|
|
bar.x = barX
|
|
bar.y = barY
|
|
bar.opacity = 255
|
|
bar.visible = false
|
|
for i in 0...PokeBattle_SceneConstants::NUM_BALLS
|
|
ball = sprites["partyBall_#{@side}_#{i}"]
|
|
ball.x = ballX
|
|
ball.y = ballY
|
|
ball.opacity = 255
|
|
ball.visible = false
|
|
ballX += ballXdiff
|
|
end
|
|
end
|
|
|
|
def getPartyIndexFromBallIndex(idxBall)
|
|
# Player's lineup (just show balls for player's party)
|
|
if @side==0
|
|
return idxBall if @partyStarts.length<2
|
|
return idxBall if idxBall<@partyStarts[1]
|
|
return -1
|
|
end
|
|
# Opposing lineup
|
|
# NOTE: This doesn't work well for 4+ opposing trainers.
|
|
ballsPerTrainer = PokeBattle_SceneConstants::NUM_BALLS/@partyStarts.length # 6/3/2
|
|
startsIndex = idxBall/ballsPerTrainer
|
|
teamIndex = idxBall%ballsPerTrainer
|
|
ret = @partyStarts[startsIndex]+teamIndex
|
|
if startsIndex<@partyStarts.length-1
|
|
# There is a later trainer, don't spill over into its team
|
|
return -1 if ret>=@partyStarts[startsIndex+1]
|
|
end
|
|
return ret
|
|
end
|
|
|
|
def createProcesses
|
|
bar = addSprite(@sprites["partyBar_#{@side}"])
|
|
bar.setVisible(0,true)
|
|
dir = (@side==0) ? 1 : -1
|
|
bar.setDelta(0,dir*Graphics.width/2,0)
|
|
bar.moveDelta(0,8,-dir*Graphics.width/2,0)
|
|
delay = bar.totalDuration
|
|
for i in 0...PokeBattle_SceneConstants::NUM_BALLS
|
|
createBall(i,(@fullAnim) ? delay+i*2 : 0,dir)
|
|
end
|
|
end
|
|
|
|
def createBall(idxBall,delay,dir)
|
|
# Choose ball's graphic
|
|
idxParty = getPartyIndexFromBallIndex(idxBall)
|
|
graphicFilename = "Graphics/Pictures/Battle/icon_ball_empty"
|
|
if idxParty>=0 && idxParty<@party.length && @party[idxParty]
|
|
if !@party[idxParty].able?
|
|
graphicFilename = "Graphics/Pictures/Battle/icon_ball_faint"
|
|
elsif @party[idxParty].status != :NONE
|
|
graphicFilename = "Graphics/Pictures/Battle/icon_ball_status"
|
|
else
|
|
graphicFilename = "Graphics/Pictures/Battle/icon_ball"
|
|
end
|
|
end
|
|
# Set up ball sprite
|
|
ball = addSprite(@sprites["partyBall_#{@side}_#{idxBall}"])
|
|
ball.setVisible(delay,true)
|
|
ball.setName(delay,graphicFilename)
|
|
ball.setDelta(delay,dir*Graphics.width/2,0)
|
|
ball.moveDelta(delay,8,-dir*Graphics.width/2,0)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
#===============================================================================
|
|
# Makes a Pokémon's data box appear
|
|
#===============================================================================
|
|
class DataBoxAppearAnimation < PokeBattle_Animation
|
|
def initialize(sprites,viewport,idxBox)
|
|
@idxBox = idxBox
|
|
super(sprites,viewport)
|
|
end
|
|
|
|
def createProcesses
|
|
return if !@sprites["dataBox_#{@idxBox}"]
|
|
box = addSprite(@sprites["dataBox_#{@idxBox}"])
|
|
box.setVisible(0,true)
|
|
dir = ((@idxBox%2)==0) ? 1 : -1
|
|
box.setDelta(0,dir*Graphics.width/2,0)
|
|
box.moveDelta(0,8,-dir*Graphics.width/2,0)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
#===============================================================================
|
|
# Makes a Pokémon's data box disappear
|
|
#===============================================================================
|
|
class DataBoxDisappearAnimation < PokeBattle_Animation
|
|
def initialize(sprites,viewport,idxBox)
|
|
@idxBox = idxBox
|
|
super(sprites,viewport)
|
|
end
|
|
|
|
def createProcesses
|
|
return if !@sprites["dataBox_#{@idxBox}"] || !@sprites["dataBox_#{@idxBox}"].visible
|
|
box = addSprite(@sprites["dataBox_#{@idxBox}"])
|
|
dir = ((@idxBox%2)==0) ? 1 : -1
|
|
box.moveDelta(0,8,dir*Graphics.width/2,0)
|
|
box.setVisible(8,false)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
#===============================================================================
|
|
# Makes a Pokémon's ability bar appear
|
|
#===============================================================================
|
|
class AbilitySplashAppearAnimation < PokeBattle_Animation
|
|
def initialize(sprites,viewport,side,secondAbility=false)
|
|
@secondAbility=secondAbility
|
|
@side = side
|
|
super(sprites,viewport)
|
|
end
|
|
|
|
def createProcesses
|
|
if @secondAbility
|
|
return if !@sprites["ability2Bar_#{@side}"]
|
|
bar = addSprite(@sprites["ability2Bar_#{@side}"])
|
|
else
|
|
return if !@sprites["abilityBar_#{@side}"]
|
|
bar = addSprite(@sprites["abilityBar_#{@side}"])
|
|
end
|
|
|
|
bar.setVisible(0,true)
|
|
dir = (@side==0) ? 1 : -1
|
|
bar.moveDelta(0,8,dir*Graphics.width/2,0)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
#===============================================================================
|
|
# Makes a Pokémon's ability bar disappear
|
|
#===============================================================================
|
|
class AbilitySplashDisappearAnimation < PokeBattle_Animation
|
|
def initialize(sprites,viewport,side)
|
|
@side = side
|
|
super(sprites,viewport)
|
|
end
|
|
|
|
def createProcesses
|
|
return if !@sprites["abilityBar_#{@side}"]
|
|
bar = addSprite(@sprites["abilityBar_#{@side}"])
|
|
dir = (@side==0) ? -1 : 1
|
|
bar.moveDelta(0,8,dir*Graphics.width/2,0)
|
|
bar.setVisible(8,false)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
#===============================================================================
|
|
# Make an enemy trainer slide on-screen from the right. Makes the previous
|
|
# trainer slide off to the right first if it is on-screen.
|
|
# Used at the end of battle.
|
|
#===============================================================================
|
|
class TrainerAppearAnimation < PokeBattle_Animation
|
|
def initialize(sprites,viewport,idxTrainer)
|
|
@idxTrainer = idxTrainer
|
|
super(sprites,viewport)
|
|
end
|
|
|
|
def createProcesses
|
|
delay = 0
|
|
# Make old trainer sprite move off-screen first if necessary
|
|
if @idxTrainer>0 && @sprites["trainer_#{@idxTrainer}"].visible
|
|
oldTrainer = addSprite(@sprites["trainer_#{@idxTrainer}"],PictureOrigin::Bottom)
|
|
oldTrainer.moveDelta(delay,8,Graphics.width/4,0)
|
|
oldTrainer.setVisible(delay+8,false)
|
|
delay = oldTrainer.totalDuration
|
|
end
|
|
# Make new trainer sprite move on-screen
|
|
if @sprites["trainer_#{@idxTrainer+1}"]
|
|
trainerX, trainerY = PokeBattle_SceneConstants.pbTrainerPosition(1)
|
|
trainerX += 64+Graphics.width/4
|
|
newTrainer = addSprite(@sprites["trainer_#{@idxTrainer+1}"],PictureOrigin::Bottom)
|
|
newTrainer.setVisible(delay,true)
|
|
newTrainer.setXY(delay,trainerX,trainerY)
|
|
newTrainer.moveDelta(delay,8,-Graphics.width/4,0)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
#===============================================================================
|
|
# Shows the player (and partner) and the player party lineup sliding off screen.
|
|
# Shows the player's/partner's throwing animation (if they have one).
|
|
# Doesn't show the ball thrown or the Pokémon.
|
|
#===============================================================================
|
|
class PlayerFadeAnimation < PokeBattle_Animation
|
|
def initialize(sprites,viewport,fullAnim=false)
|
|
@fullAnim = fullAnim # True at start of battle, false when switching
|
|
super(sprites,viewport)
|
|
end
|
|
|
|
def createProcesses
|
|
# NOTE: The movement speeds of trainers/bar/balls are all different.
|
|
# Move trainer sprite(s) off-screen
|
|
spriteNameBase = "player"
|
|
i = 1
|
|
while @sprites[spriteNameBase+"_#{i}"]
|
|
pl = @sprites[spriteNameBase+"_#{i}"]
|
|
i += 1
|
|
next if !pl.visible || pl.x<0
|
|
trainer = addSprite(pl,PictureOrigin::Bottom)
|
|
trainer.moveDelta(0,16,-Graphics.width/2,0)
|
|
# Animate trainer sprite(s) if they have multiple frames
|
|
if pl.bitmap && !pl.bitmap.disposed? && pl.bitmap.width>=pl.bitmap.height*2
|
|
size = pl.src_rect.width # Width per frame
|
|
trainer.setSrc(0,size,0)
|
|
trainer.setSrc(5,size*2,0)
|
|
trainer.setSrc(7,size*3,0)
|
|
trainer.setSrc(9,size*4,0)
|
|
end
|
|
trainer.setVisible(16,false)
|
|
end
|
|
# Move and fade party bar/balls
|
|
delay = 3
|
|
if @sprites["partyBar_0"] && @sprites["partyBar_0"].visible
|
|
partyBar = addSprite(@sprites["partyBar_0"])
|
|
partyBar.moveDelta(delay,16,-Graphics.width/4,0) if @fullAnim
|
|
partyBar.moveOpacity(delay,12,0)
|
|
partyBar.setVisible(delay+12,false)
|
|
partyBar.setOpacity(delay+12,255)
|
|
end
|
|
for i in 0...PokeBattle_SceneConstants::NUM_BALLS
|
|
next if !@sprites["partyBall_0_#{i}"] || !@sprites["partyBall_0_#{i}"].visible
|
|
partyBall = addSprite(@sprites["partyBall_0_#{i}"])
|
|
partyBall.moveDelta(delay+2*i,16,-Graphics.width,0) if @fullAnim
|
|
partyBall.moveOpacity(delay,12,0)
|
|
partyBall.setVisible(delay+12,false)
|
|
partyBall.setOpacity(delay+12,255)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
#===============================================================================
|
|
# Shows the enemy trainer(s) and the enemy party lineup sliding off screen.
|
|
# Doesn't show the ball thrown or the Pokémon.
|
|
#===============================================================================
|
|
class TrainerFadeAnimation < PokeBattle_Animation
|
|
def initialize(sprites,viewport,fullAnim=false)
|
|
@fullAnim = fullAnim # True at start of battle, false when switching
|
|
super(sprites,viewport)
|
|
end
|
|
|
|
def createProcesses
|
|
# NOTE: The movement speeds of trainers/bar/balls are all different.
|
|
# Move trainer sprite(s) off-screen
|
|
spriteNameBase = "trainer"
|
|
i = 1
|
|
while @sprites[spriteNameBase+"_#{i}"]
|
|
trSprite = @sprites[spriteNameBase+"_#{i}"]
|
|
i += 1
|
|
next if !trSprite.visible || trSprite.x>Graphics.width
|
|
trainer = addSprite(trSprite,PictureOrigin::Bottom)
|
|
trainer.moveDelta(0,16,Graphics.width/2,0)
|
|
trainer.setVisible(16,false)
|
|
end
|
|
# Move and fade party bar/balls
|
|
delay = 3
|
|
if @sprites["partyBar_1"] && @sprites["partyBar_1"].visible
|
|
partyBar = addSprite(@sprites["partyBar_1"])
|
|
partyBar.moveDelta(delay,16,Graphics.width/4,0) if @fullAnim
|
|
partyBar.moveOpacity(delay,12,0)
|
|
partyBar.setVisible(delay+12,false)
|
|
partyBar.setOpacity(delay+12,255)
|
|
end
|
|
for i in 0...PokeBattle_SceneConstants::NUM_BALLS
|
|
next if !@sprites["partyBall_1_#{i}"] || !@sprites["partyBall_1_#{i}"].visible
|
|
partyBall = addSprite(@sprites["partyBall_1_#{i}"])
|
|
partyBall.moveDelta(delay+2*i,16,Graphics.width,0) if @fullAnim
|
|
partyBall.moveOpacity(delay,12,0)
|
|
partyBall.setVisible(delay+12,false)
|
|
partyBall.setOpacity(delay+12,255)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
#===============================================================================
|
|
# Shows a Pokémon being sent out on the player's side (including by a partner).
|
|
# Includes the Poké Ball being thrown.
|
|
#===============================================================================
|
|
class PokeballPlayerSendOutAnimation < PokeBattle_Animation
|
|
include PokeBattle_BallAnimationMixin
|
|
|
|
def initialize(sprites,viewport,idxTrainer,battler,startBattle,idxOrder=0)
|
|
@idxTrainer = idxTrainer
|
|
@battler = battler
|
|
@showingTrainer = startBattle
|
|
@idxOrder = idxOrder
|
|
@trainer = @battler.battle.pbGetOwnerFromBattlerIndex(@battler.index)
|
|
sprites["pokemon_#{battler.index}"].visible = false
|
|
@shadowVisible = sprites["shadow_#{battler.index}"].visible
|
|
sprites["shadow_#{battler.index}"].visible = false
|
|
super(sprites,viewport)
|
|
end
|
|
|
|
def createProcesses
|
|
batSprite = @sprites["pokemon_#{@battler.index}"]
|
|
shaSprite = @sprites["shadow_#{@battler.index}"]
|
|
traSprite = @sprites["player_#{@idxTrainer}"]
|
|
# Calculate the Poké Ball graphic to use
|
|
poke_ball = (batSprite.pkmn) ? batSprite.pkmn.poke_ball : nil
|
|
# Calculate the color to turn the battler sprite
|
|
col = getBattlerColorFromPokeBall(poke_ball)
|
|
col.alpha = 255
|
|
# Calculate start and end coordinates for battler sprite movement
|
|
ballPos = PokeBattle_SceneConstants.pbBattlerPosition(@battler.index,batSprite.sideSize)
|
|
battlerStartX = ballPos[0] # Is also where the Ball needs to end
|
|
battlerStartY = ballPos[1] # Is also where the Ball needs to end + 18
|
|
battlerEndX = batSprite.x
|
|
battlerEndY = batSprite.y
|
|
# Calculate start and end coordinates for Poké Ball sprite movement
|
|
ballStartX = -6
|
|
ballStartY = 202
|
|
ballMidX = 0 # Unused in trajectory calculation
|
|
ballMidY = battlerStartY-144
|
|
# Set up Poké Ball sprite
|
|
ball = addBallSprite(ballStartX,ballStartY,poke_ball)
|
|
ball.setZ(0,25)
|
|
ball.setVisible(0,false)
|
|
# Poké Ball tracking the player's hand animation (if trainer is visible)
|
|
if @showingTrainer && traSprite && traSprite.x>0
|
|
ball.setZ(0,traSprite.z-1)
|
|
ballStartX, ballStartY = ballTracksHand(ball,traSprite)
|
|
end
|
|
delay = ball.totalDuration # 0 or 7
|
|
# Poké Ball trajectory animation
|
|
createBallTrajectory(ball,delay,12,
|
|
ballStartX,ballStartY,ballMidX,ballMidY,battlerStartX,battlerStartY-18)
|
|
ball.setZ(9,batSprite.z-1)
|
|
delay = ball.totalDuration+4
|
|
delay += 10*@idxOrder # Stagger appearances if multiple Pokémon are sent out at once
|
|
ballOpenUp(ball,delay-2,poke_ball)
|
|
ballBurst(delay,battlerStartX,battlerStartY-18,poke_ball)
|
|
ball.moveOpacity(delay+2,2,0)
|
|
# Set up battler sprite
|
|
battler = addSprite(batSprite,PictureOrigin::Bottom)
|
|
battler.setXY(0,battlerStartX,battlerStartY)
|
|
battler.setZoom(0,0)
|
|
battler.setColor(0,col)
|
|
# Battler animation
|
|
battlerAppear(battler,delay,battlerEndX,battlerEndY,batSprite,col)
|
|
if @shadowVisible
|
|
# Set up shadow sprite
|
|
shadow = addSprite(shaSprite,PictureOrigin::Center)
|
|
shadow.setOpacity(0,0)
|
|
# Shadow animation
|
|
shadow.setVisible(delay,@shadowVisible)
|
|
shadow.moveOpacity(delay+5,10,255)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
#===============================================================================
|
|
# Shows a Pokémon being sent out on the opposing side.
|
|
# Includes the Poké Ball being "thrown" (although here the Poké Ball just
|
|
# appears in the spot where it opens up rather than being thrown to there).
|
|
#===============================================================================
|
|
class PokeballTrainerSendOutAnimation < PokeBattle_Animation
|
|
include PokeBattle_BallAnimationMixin
|
|
|
|
def initialize(sprites,viewport,idxTrainer,battler,startBattle,idxOrder)
|
|
@idxTrainer = idxTrainer
|
|
@battler = battler
|
|
@showingTrainer = startBattle
|
|
@idxOrder = idxOrder
|
|
sprites["pokemon_#{battler.index}"].visible = false
|
|
@shadowVisible = sprites["shadow_#{battler.index}"].visible
|
|
sprites["shadow_#{battler.index}"].visible = false
|
|
super(sprites,viewport)
|
|
end
|
|
|
|
def createProcesses
|
|
batSprite = @sprites["pokemon_#{@battler.index}"]
|
|
shaSprite = @sprites["shadow_#{@battler.index}"]
|
|
# Calculate the Poké Ball graphic to use
|
|
poke_ball = (batSprite.pkmn) ? batSprite.pkmn.poke_ball : nil
|
|
# Calculate the color to turn the battler sprite
|
|
col = getBattlerColorFromPokeBall(poke_ball)
|
|
col.alpha = 255
|
|
# Calculate start and end coordinates for battler sprite movement
|
|
ballPos = PokeBattle_SceneConstants.pbBattlerPosition(@battler.index,batSprite.sideSize)
|
|
battlerStartX = ballPos[0]
|
|
battlerStartY = ballPos[1]
|
|
battlerEndX = batSprite.x
|
|
battlerEndY = batSprite.y
|
|
# Set up Poké Ball sprite
|
|
ball = addBallSprite(0,0,poke_ball)
|
|
ball.setZ(0,batSprite.z-1)
|
|
# Poké Ball animation
|
|
createBallTrajectory(ball,battlerStartX,battlerStartY)
|
|
delay = ball.totalDuration+6
|
|
delay += 10 if @showingTrainer # Give time for trainer to slide off screen
|
|
delay += 10*@idxOrder # Stagger appearances if multiple Pokémon are sent out at once
|
|
ballOpenUp(ball,delay-2,poke_ball)
|
|
ballBurst(delay,battlerStartX,battlerStartY-18,poke_ball)
|
|
ball.moveOpacity(delay+2,2,0)
|
|
# Set up battler sprite
|
|
battler = addSprite(batSprite,PictureOrigin::Bottom)
|
|
battler.setXY(0,battlerStartX,battlerStartY)
|
|
battler.setZoom(0,0)
|
|
battler.setColor(0,col)
|
|
# Battler animation
|
|
battlerAppear(battler,delay,battlerEndX,battlerEndY,batSprite,col)
|
|
if @shadowVisible
|
|
# Set up shadow sprite
|
|
shadow = addSprite(shaSprite,PictureOrigin::Center)
|
|
shadow.setOpacity(0,0)
|
|
# Shadow animation
|
|
shadow.setVisible(delay,@shadowVisible)
|
|
shadow.moveOpacity(delay+5,10,255)
|
|
end
|
|
end
|
|
|
|
def createBallTrajectory(ball,destX,destY)
|
|
# NOTE: In HGSS, there isn't a Poké Ball arc under any circumstance (neither
|
|
# when throwing out the first Pokémon nor when switching/replacing a
|
|
# fainted Pokémon). This is probably worth changing.
|
|
ball.setXY(0,destX,destY-4)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
#===============================================================================
|
|
# Shows a Pokémon being recalled into its Poké Ball
|
|
#===============================================================================
|
|
class BattlerRecallAnimation < PokeBattle_Animation
|
|
include PokeBattle_BallAnimationMixin
|
|
|
|
def initialize(sprites,viewport,idxBattler)
|
|
@idxBattler = idxBattler
|
|
super(sprites,viewport)
|
|
end
|
|
|
|
def createProcesses
|
|
batSprite = @sprites["pokemon_#{@idxBattler}"]
|
|
shaSprite = @sprites["shadow_#{@idxBattler}"]
|
|
# Calculate the Poké Ball graphic to use
|
|
poke_ball = (batSprite.pkmn) ? batSprite.pkmn.poke_ball : nil
|
|
# Calculate the color to turn the battler sprite
|
|
col = getBattlerColorFromPokeBall(poke_ball)
|
|
col.alpha = 0
|
|
# Calculate end coordinates for battler sprite movement
|
|
ballPos = PokeBattle_SceneConstants.pbBattlerPosition(@idxBattler,batSprite.sideSize)
|
|
battlerEndX = ballPos[0]
|
|
battlerEndY = ballPos[1]
|
|
# Set up battler sprite
|
|
battler = addSprite(batSprite,PictureOrigin::Bottom)
|
|
battler.setVisible(0,true)
|
|
battler.setColor(0,col)
|
|
# Set up Poké Ball sprite
|
|
ball = addBallSprite(battlerEndX,battlerEndY,poke_ball)
|
|
ball.setZ(0,batSprite.z+1)
|
|
# Poké Ball animation
|
|
ballOpenUp(ball,0,poke_ball)
|
|
delay = ball.totalDuration
|
|
ballBurstRecall(delay,battlerEndX,battlerEndY,poke_ball)
|
|
ball.moveOpacity(10,2,0)
|
|
# Battler animation
|
|
battlerAbsorb(battler,delay,battlerEndX,battlerEndY,col)
|
|
if shaSprite.visible
|
|
# Set up shadow sprite
|
|
shadow = addSprite(shaSprite,PictureOrigin::Center)
|
|
# Shadow animation
|
|
shadow.moveOpacity(0,10,0)
|
|
shadow.setVisible(delay,false)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
#===============================================================================
|
|
# Shows a Pokémon flashing after taking damage
|
|
#===============================================================================
|
|
class BattlerDamageAnimation < PokeBattle_Animation
|
|
def initialize(sprites,viewport,idxBattler,effectiveness)
|
|
@idxBattler = idxBattler
|
|
@effectiveness = effectiveness
|
|
super(sprites,viewport)
|
|
end
|
|
|
|
def createProcesses
|
|
batSprite = @sprites["pokemon_#{@idxBattler}"]
|
|
shaSprite = @sprites["shadow_#{@idxBattler}"]
|
|
# Set up battler/shadow sprite
|
|
battler = addSprite(batSprite,PictureOrigin::Bottom)
|
|
shadow = addSprite(shaSprite,PictureOrigin::Center)
|
|
# Animation
|
|
delay = 0
|
|
case @effectiveness
|
|
when 0 then battler.setSE(delay, "Battle damage normal");
|
|
when 1 then battler.setSE(delay, "Battle damage weak")
|
|
when 2 then battler.setSE(delay, "Battle damage super")
|
|
end
|
|
4.times do # 4 flashes, each lasting 0.2 (4/20) seconds
|
|
battler.setVisible(delay,false)
|
|
shadow.setVisible(delay,false)
|
|
battler.setVisible(delay+2,true) if batSprite.visible
|
|
shadow.setVisible(delay+2,true) if shaSprite.visible
|
|
delay += 4
|
|
end
|
|
# Restore original battler/shadow sprites visibilities
|
|
battler.setVisible(delay,batSprite.visible)
|
|
shadow.setVisible(delay,shaSprite.visible)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
#===============================================================================
|
|
# Shows a Pokémon fainting
|
|
#===============================================================================
|
|
class BattlerFaintAnimation < PokeBattle_Animation
|
|
def initialize(sprites,viewport,idxBattler,battle)
|
|
@idxBattler = idxBattler
|
|
@battle = battle
|
|
super(sprites,viewport)
|
|
end
|
|
|
|
def createProcesses
|
|
batSprite = @sprites["pokemon_#{@idxBattler}"]
|
|
shaSprite = @sprites["shadow_#{@idxBattler}"]
|
|
# Set up battler/shadow sprite
|
|
battler = addSprite(batSprite,PictureOrigin::Bottom)
|
|
shadow = addSprite(shaSprite,PictureOrigin::Center)
|
|
# Get approx duration depending on sprite's position/size. Min 20 frames.
|
|
battlerTop = batSprite.y-batSprite.height
|
|
cropY = PokeBattle_SceneConstants.pbBattlerPosition(@idxBattler,
|
|
@battle.pbSideSize(@idxBattler))[1]
|
|
cropY += 8
|
|
duration = (cropY-battlerTop)/8
|
|
duration = 5#10 if duration<10 # Min 0.5 seconds
|
|
# Animation
|
|
# Play cry
|
|
delay = 10
|
|
cry = GameData::Species.cry_filename_from_pokemon(batSprite.pkmn)
|
|
if cry
|
|
battler.setSE(0, cry, nil, 75) # 75 is pitch
|
|
delay = GameData::Species.cry_length(batSprite.pkmn) * 20 / Graphics.frame_rate
|
|
end
|
|
# Sprite drops down
|
|
shadow.setVisible(delay,false)
|
|
battler.setSE(delay,"Pkmn faint")
|
|
battler.moveOpacity(delay,duration,0)
|
|
battler.moveDelta(delay,duration,0,cropY-battlerTop)
|
|
battler.setCropBottom(delay,cropY)
|
|
battler.setVisible(delay+duration,false)
|
|
battler.setOpacity(delay+duration,255)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
#===============================================================================
|
|
# Shows the player's Poké Ball being thrown to capture a Pokémon
|
|
#===============================================================================
|
|
class PokeballThrowCaptureAnimation < PokeBattle_Animation
|
|
include PokeBattle_BallAnimationMixin
|
|
|
|
def initialize(sprites,viewport,
|
|
poke_ball,numShakes,critCapture,battler,showingTrainer)
|
|
@poke_ball = poke_ball
|
|
@numShakes = (critCapture) ? 1 : numShakes
|
|
@critCapture = critCapture
|
|
@battler = battler
|
|
@showingTrainer = showingTrainer # Only true if a Safari Zone battle
|
|
@shadowVisible = sprites["shadow_#{battler.index}"].visible
|
|
@trainer = battler.battle.pbPlayer
|
|
super(sprites,viewport)
|
|
end
|
|
|
|
def createProcesses
|
|
# Calculate start and end coordinates for battler sprite movement
|
|
batSprite = @sprites["pokemon_#{@battler.index}"]
|
|
shaSprite = @sprites["shadow_#{@battler.index}"]
|
|
traSprite = @sprites["player_1"]
|
|
ballPos = PokeBattle_SceneConstants.pbBattlerPosition(@battler.index,batSprite.sideSize)
|
|
battlerStartX = batSprite.x
|
|
battlerStartY = batSprite.y
|
|
ballStartX = -6
|
|
ballStartY = 246
|
|
ballMidX = 0 # Unused in arc calculation
|
|
ballMidY = 78
|
|
ballEndX = ballPos[0]
|
|
ballEndY = 112
|
|
ballGroundY = ballPos[1]-4
|
|
# Set up Poké Ball sprite
|
|
ball = addBallSprite(ballStartX,ballStartY,@poke_ball)
|
|
ball.setZ(0,batSprite.z+1)
|
|
@ballSpriteIndex = (@numShakes>=4 || @critCapture) ? @tempSprites.length-1 : -1
|
|
# Set up trainer sprite (only visible in Safari Zone battles)
|
|
if @showingTrainer && traSprite
|
|
if traSprite.bitmap.width>=traSprite.bitmap.height*2
|
|
trainer = addSprite(traSprite,PictureOrigin::Bottom)
|
|
# Trainer animation
|
|
ballStartX, ballStartY = trainerThrowingFrames(ball,trainer,traSprite)
|
|
end
|
|
end
|
|
delay = ball.totalDuration # 0 or 7
|
|
# Poké Ball arc animation
|
|
ball.setSE(delay,"Battle throw")
|
|
createBallTrajectory(ball,delay,16,
|
|
ballStartX,ballStartY,ballMidX,ballMidY,ballEndX,ballEndY)
|
|
ball.setZ(9,batSprite.z+1)
|
|
ball.setSE(delay+16,"Battle ball hit")
|
|
# Poké Ball opens up
|
|
delay = ball.totalDuration+6
|
|
ballOpenUp(ball,delay,@poke_ball,true,false)
|
|
# Set up battler sprite
|
|
battler = addSprite(batSprite,PictureOrigin::Bottom)
|
|
# Poké Ball absorbs battler
|
|
delay = ball.totalDuration
|
|
ballBurstCapture(delay,ballEndX,ballEndY,@poke_ball)
|
|
delay = ball.totalDuration+4
|
|
# NOTE: The Pokémon does not change color while being absorbed into a Poké
|
|
# Ball during a capture attempt. This may be an oversight in HGSS.
|
|
battler.setSE(delay,"Battle jump to ball")
|
|
battler.moveXY(delay,5,ballEndX,ballEndY)
|
|
battler.moveZoom(delay,5,0)
|
|
battler.setVisible(delay+5,false)
|
|
if @shadowVisible
|
|
# Set up shadow sprite
|
|
shadow = addSprite(shaSprite,PictureOrigin::Center)
|
|
# Shadow animation
|
|
shadow.moveOpacity(delay,5,0)
|
|
shadow.moveZoom(delay,5,0)
|
|
shadow.setVisible(delay+5,false)
|
|
end
|
|
# Poké Ball closes
|
|
delay = battler.totalDuration
|
|
ballSetClosed(ball,delay,@poke_ball)
|
|
ball.moveTone(delay,3,Tone.new(96,64,-160,160))
|
|
ball.moveTone(delay+5,3,Tone.new(0,0,0,0))
|
|
# Poké Ball critical capture animation
|
|
delay = ball.totalDuration+3
|
|
if @critCapture
|
|
ball.setSE(delay,"Battle ball shake")
|
|
ball.moveXY(delay,1,ballEndX+4,ballEndY)
|
|
ball.moveXY(delay+1,2,ballEndX-4,ballEndY)
|
|
ball.moveXY(delay+3,2,ballEndX+4,ballEndY)
|
|
ball.setSE(delay+4,"Battle ball shake")
|
|
ball.moveXY(delay+5,2,ballEndX-4,ballEndY)
|
|
ball.moveXY(delay+7,1,ballEndX,ballEndY)
|
|
delay = ball.totalDuration+3
|
|
end
|
|
# Poké Ball drops to the ground
|
|
for i in 0...4
|
|
t = [4,4,3,2][i] # Time taken to rise or fall for each bounce
|
|
d = [1,2,4,8][i] # Fraction of the starting height each bounce rises to
|
|
delay -= t if i==0
|
|
if i>0
|
|
ball.setZoomXY(delay,100+5*(5-i),100-5*(5-i)) # Squish
|
|
ball.moveZoom(delay,2,100) # Unsquish
|
|
ball.moveXY(delay,t,ballEndX,ballGroundY-(ballGroundY-ballEndY)/d)
|
|
end
|
|
ball.moveXY(delay+t,t,ballEndX,ballGroundY)
|
|
ball.setSE(delay+2*t,"Battle ball drop",100-i*7)
|
|
delay = ball.totalDuration
|
|
end
|
|
battler.setXY(ball.totalDuration,ballEndX,ballGroundY)
|
|
# Poké Ball shakes
|
|
delay = ball.totalDuration+12
|
|
for i in 0...[@numShakes,3].min
|
|
ball.setSE(delay,"Battle ball shake")
|
|
ball.moveXY(delay,2,ballEndX-2*(4-i),ballGroundY)
|
|
ball.moveAngle(delay,2,5*(4-i)) # positive means counterclockwise
|
|
ball.moveXY(delay+2,4,ballEndX+2*(4-i),ballGroundY)
|
|
ball.moveAngle(delay+2,4,-5*(4-i)) # negative means clockwise
|
|
ball.moveXY(delay+6,2,ballEndX,ballGroundY)
|
|
ball.moveAngle(delay+6,2,0)
|
|
delay = ball.totalDuration+8
|
|
end
|
|
if @numShakes==0 || (@numShakes<4 && !@critCapture)
|
|
# Poké Ball opens
|
|
ball.setZ(delay,batSprite.z-1)
|
|
ballOpenUp(ball,delay,@poke_ball,false)
|
|
ballBurst(delay,ballEndX,ballGroundY,@poke_ball)
|
|
ball.moveOpacity(delay+2,2,0)
|
|
# Battler emerges
|
|
col = getBattlerColorFromPokeBall(@poke_ball)
|
|
col.alpha = 255
|
|
battler.setColor(delay,col)
|
|
battlerAppear(battler,delay,battlerStartX,battlerStartY,batSprite,col)
|
|
if @shadowVisible
|
|
shadow.setVisible(delay+5,true)
|
|
shadow.setZoom(delay+5,100)
|
|
shadow.moveOpacity(delay+5,10,255)
|
|
end
|
|
else
|
|
# Pokémon was caught
|
|
ballCaptureSuccess(ball,delay,ballEndX,ballGroundY)
|
|
end
|
|
end
|
|
|
|
def dispose
|
|
if @ballSpriteIndex>=0
|
|
# Capture was successful, the Poké Ball sprite should stay around after
|
|
# this animation has finished.
|
|
@sprites["captureBall"] = @tempSprites[@ballSpriteIndex]
|
|
@tempSprites[@ballSpriteIndex] = nil
|
|
end
|
|
super
|
|
end
|
|
end
|
|
|
|
|
|
|
|
#===============================================================================
|
|
# Shows the player throwing a Poké Ball and it being deflected
|
|
#===============================================================================
|
|
class PokeballThrowDeflectAnimation < PokeBattle_Animation
|
|
include PokeBattle_BallAnimationMixin
|
|
|
|
def initialize(sprites,viewport,poke_ball,battler)
|
|
@poke_ball = poke_ball
|
|
@battler = battler
|
|
super(sprites,viewport)
|
|
end
|
|
|
|
def createProcesses
|
|
# Calculate start and end coordinates for battler sprite movement
|
|
batSprite = @sprites["pokemon_#{@battler.index}"]
|
|
ballPos = PokeBattle_SceneConstants.pbBattlerPosition(@battler.index,batSprite.sideSize)
|
|
ballStartX = -6
|
|
ballStartY = 246
|
|
ballMidX = 190 # Unused in arc calculation
|
|
ballMidY = 78
|
|
ballEndX = ballPos[0]
|
|
ballEndY = 112
|
|
# Set up Poké Ball sprite
|
|
ball = addBallSprite(ballStartX,ballStartY,@poke_ball)
|
|
ball.setZ(0,90)
|
|
# Poké Ball arc animation
|
|
ball.setSE(0,"Battle throw")
|
|
createBallTrajectory(ball,0,16,
|
|
ballStartX,ballStartY,ballMidX,ballMidY,ballEndX,ballEndY)
|
|
# Poké Ball knocked back
|
|
delay = ball.totalDuration
|
|
ball.setSE(delay,"Battle ball drop")
|
|
ball.moveXY(delay,8,-32,Graphics.height-96+32) # Back to player's corner
|
|
createBallTumbling(ball,delay,8)
|
|
end
|
|
end
|