Files
infinitefusion-e18/Data/Scripts/053_PIF_Hoenn/Contests/Pokemon Contests/011_Animations.rb
T
2026-07-10 15:42:06 -04:00

477 lines
17 KiB
Ruby

#====================================================================================
# DO NOT MAKE EDITS HERE
#====================================================================================
#====================================================================================
# Animations
#====================================================================================
class PokemonContestTalent_Scene
def pbDisplayPokemon(position)
# Always dispose and recreate, since round order may have changed
if @sprites["trainersprite#{position}"]
@sprites["trainersprite#{position}"].dispose
@sprites.delete("trainersprite#{position}")
end
pokemon = @contest.roundOrder[position - 1]
if pokemon == @contest.pokemonOne
original_index = 0
elsif pokemon == @contest.pokemonTwo
original_index = 1
elsif pokemon == @contest.pokemonThree
original_index = 2
else
original_index = nil
end
if original_index
appearance = @contest.contestTrainerAppearances[original_index]
bitmap = generate_front_trainer_sprite_bitmap_from_appearance(appearance)
else
bitmap = generate_front_trainer_sprite_bitmap
end
@sprites["trainersprite#{position}"] = IconSprite.new(0, 0, @viewport)
@sprites["trainersprite#{position}"].setBitmapDirectly(bitmap)
@sprites["trainersprite#{position}"].x = -140
@sprites["trainersprite#{position}"].y = 24
@sprites["trainersprite#{position}"].mirror = true
@sprites["trainersprite#{position}"].z = 50
@sprites["pokemonsprite#{position}"] = PokemonSprite.new(@viewport)
@sprites["pokemonsprite#{position}"].setPokemonBitmap(@contest.roundOrder[position-1], true)
@sprites["pokemonsprite#{position}"].setOffset
@sprites["pokemonsprite#{position}"].mirror = true
@sprites["pokemonsprite#{position}"].z = 50
xPos = ContestSettings::FOCUSUSER_X
yPos = ContestSettings::FOCUSUSER_Y
@sprites["pokemonsprite#{position}"].x = xPos
@sprites["pokemonsprite#{position}"].y = yPos
10.times {
@sprites["pokemonsprite#{position}"].x -= 20
@sprites["trainersprite#{position}"].x += 10
Graphics.update
Input.update
pbUpdateSpriteHash(@sprites)
}
end
def pbDismissPokemon(position)
10.times {
@sprites["pokemonsprite#{position}"].x += 20
@sprites["trainersprite#{position}"].x -= 10
Graphics.update
Input.update
pbUpdateSpriteHash(@sprites)
}
@sprites["pokemonsprite#{position}"].dispose
@sprites.delete("pokemonsprite#{position}")
end
#=============================================================================
# Plays a move/common animation
#=============================================================================
def pbPlayAnimation(moveID, atself = false, hitNum=0)
# animID = find_animation(moveID, 0, hitNum)
animID = pbFindMoveAnimation(moveID, 0, hitNum)
return if !animID
anim = animID[0]
animations = pbLoadBattleAnimations
return if !animations
pbAnimationCore(animations[anim], atself)
end
def pbAnimationCore(animation, atself)
return if !animation
@briefMessage = false
userSprite = @sprites["pokemonsprite#{@currentPosition}"]
targetSprite = atself ? userSprite : @sprites["opponent"]
# Remember the original positions of Pokémon sprites
oldUserX = userSprite.x
oldUserY = userSprite.y
oldTargetX = atself ? oldUserX : targetSprite.x
oldTargetY = atself ? oldUserY : targetSprite.y
oldUserOx = userSprite.ox
oldUserOy = userSprite.oy
oldTargetOx = atself ? oldUserOx : targetSprite.ox
oldTargetOy = atself ? oldUserOy : targetSprite.oy
# Create the animation player
animPlayer = AnimationPlayerXContest.new(animation, userSprite, targetSprite, @viewport, self)
#animPlayer = PBAnimationPlayerX.new(animation, user, target, self, oppMove)
# Apply a transformation to the animation based on where the user and target
# actually are. Get the centres of each sprite.
userHeight = (userSprite&.bitmap && !userSprite.bitmap.disposed?) ? userSprite.bitmap.height : 128
if targetSprite
targetHeight = (targetSprite.bitmap && !targetSprite.bitmap.disposed?) ? targetSprite.bitmap.height : 128
else
targetHeight = userHeight
end
animPlayer.setLineTransform(
#Battle::Scene::FOCUSUSER_X, Battle::Scene::FOCUSUSER_Y, Battle::Scene::FOCUSTARGET_X, Battle::Scene::FOCUSTARGET_Y,
ContestSettings::FOCUSUSER_X, ContestSettings::FOCUSUSER_Y, ContestSettings::FOCUSTARGET_X, ContestSettings::FOCUSTARGET_Y,
oldUserX, oldUserY - (userHeight / 2) + 80, oldTargetX, oldTargetY - (targetHeight / 2) + 80
)
# Play the animation
animPlayer.start
loop do
animPlayer.update
Graphics.update
Input.update
pbUpdateSpriteHash(@sprites)
break if animPlayer.animDone?
end
animPlayer.dispose
# Return Pokémon sprites to their original positions
if userSprite
userSprite.x = oldUserX
userSprite.y = oldUserY
userSprite.ox = oldUserOx
userSprite.oy = oldUserOy
end
if targetSprite
targetSprite.x = oldTargetX
targetSprite.y = oldTargetY
targetSprite.ox = oldTargetOx
targetSprite.oy = oldTargetOy
end
end
#copied directly from Scene_PlayAnimaitons
# Returns the animation ID to use for a given move/user. Returns nil if that
# move has no animations defined for it.
def pbFindMoveAnimDetails(move2anim, moveID, idxUser, hitNum = 0)
id_number = GameData::Move.get(moveID).id_number
noFlip = false
if (idxUser & 1) == 0
anim = move2anim[0][id_number]
else
anim = move2anim[1][id_number]
noFlip = true if anim
anim = move2anim[0][id_number] if !anim
end
return [anim + hitNum, noFlip] if anim
return nil
end
# Returns the animation ID to use for a given move. If the move has no
# animations, tries to use a default move animation depending on the move's
# type. If that default move animation doesn't exist, trues to use Tackle's
# move animation. Returns nil if it can't find any of these animations to use.
def pbFindMoveAnimation(moveID, idxUser, hitNum)
begin
move2anim = pbLoadMoveToAnim
# Find actual animation requested (an opponent using the animation first
# looks for an OppMove version then a Move version)
anim = pbFindMoveAnimDetails(move2anim, moveID, idxUser, hitNum)
return anim if anim
# Actual animation not found, get the default animation for the move's type
moveData = GameData::Move.get(moveID)
target_data = GameData::Target.get(moveData.target)
moveType = moveData.type
moveKind = moveData.category
moveKind += 3 if target_data.num_targets > 1 || target_data.affects_foe_side
moveKind += 3 if moveKind == 2 && target_data.num_targets > 0
# [one target physical, one target special, user status,
# multiple targets physical, multiple targets special, non-user status]
typeDefaultAnim = {
:NORMAL => [:TACKLE, :SONICBOOM, :DEFENSECURL, :EXPLOSION, :SWIFT, :TAILWHIP],
:FIGHTING => [:MACHPUNCH, :AURASPHERE, :DETECT, nil, nil, nil],
:FLYING => [:WINGATTACK, :GUST, :ROOST, nil, :AIRCUTTER, :FEATHERDANCE],
:POISON => [:POISONSTING, :SLUDGE, :ACIDARMOR, nil, :ACID, :POISONPOWDER],
:GROUND => [:SANDTOMB, :MUDSLAP, nil, :EARTHQUAKE, :EARTHPOWER, :MUDSPORT],
:ROCK => [:ROCKTHROW, :POWERGEM, :ROCKPOLISH, :ROCKSLIDE, nil, :SANDSTORM],
:BUG => [:TWINEEDLE, :BUGBUZZ, :QUIVERDANCE, nil, :STRUGGLEBUG, :STRINGSHOT],
:GHOST => [:LICK, :SHADOWBALL, :GRUDGE, nil, nil, :CONFUSERAY],
:STEEL => [:IRONHEAD, :MIRRORSHOT, :IRONDEFENSE, nil, nil, :METALSOUND],
:FIRE => [:FIREPUNCH, :EMBER, :SUNNYDAY, nil, :INCINERATE, :WILLOWISP],
:WATER => [:CRABHAMMER, :WATERGUN, :AQUARING, nil, :SURF, :WATERSPORT],
:GRASS => [:VINEWHIP, :MEGADRAIN, :COTTONGUARD, :RAZORLEAF, nil, :SPORE],
:ELECTRIC => [:THUNDERPUNCH, :THUNDERSHOCK, :CHARGE, nil, :DISCHARGE, :THUNDERWAVE],
:PSYCHIC => [:ZENHEADBUTT, :CONFUSION, :CALMMIND, nil, :SYNCHRONOISE, :MIRACLEEYE],
:ICE => [:ICEPUNCH, :ICEBEAM, :MIST, nil, :POWDERSNOW, :HAIL],
:DRAGON => [:DRAGONCLAW, :DRAGONRAGE, :DRAGONDANCE, nil, :TWISTER, nil],
:DARK => [:PURSUIT, :DARKPULSE, :HONECLAWS, nil, :SNARL, :EMBARGO],
:FAIRY => [:TACKLE, :FAIRYWIND, :MOONLIGHT, nil, :SWIFT, :SWEETKISS]
}
if typeDefaultAnim[moveType]
anims = typeDefaultAnim[moveType]
if GameData::Move.exists?(anims[moveKind])
anim = pbFindMoveAnimDetails(move2anim, anims[moveKind], idxUser)
end
if !anim && moveKind >= 3 && GameData::Move.exists?(anims[moveKind - 3])
anim = pbFindMoveAnimDetails(move2anim, anims[moveKind - 3], idxUser)
end
if !anim && GameData::Move.exists?(anims[2])
anim = pbFindMoveAnimDetails(move2anim, anims[2], idxUser)
end
end
return anim if anim
# Default animation for the move's type not found, use Tackle's animation
if GameData::Move.exists?(:TACKLE)
return pbFindMoveAnimDetails(move2anim, :TACKLE, idxUser)
end
rescue
end
return nil
end
end
class AnimationPlayerXContest
attr_accessor :looping
MAX_SPRITES = 60
def initialize(animation,usersprite,targetsprite,vp,scene=nil,oppMove=false,inEditor=false)
#targetsprite = usersprite if usersprite && !targetsprite #TDW Added
@animation = animation
@user = nil
@usersprite = usersprite
@targetsprite = targetsprite
@userbitmap = (@usersprite && @usersprite.bitmap) ? @usersprite.bitmap : nil # not to be disposed
@targetbitmap = (@targetsprite && @targetsprite.bitmap) ? @targetsprite.bitmap : nil # not to be disposed
@scene = scene
@viewport = vp
@inEditor = inEditor
@looping = false
@animbitmap = nil # Animation sheet graphic
@frame = -1
@framesPerTick = [Graphics.frame_rate/20,1].max # 20 ticks per second
@srcLine = nil
@dstLine = nil
@userOrig = getSpriteCenter(@usersprite)
@targetOrig = getSpriteCenter(@targetsprite)
@oldbg = []
@oldfo = []
initializeSprites
end
def initializeSprites
# Create animation sprites (0=user's sprite, 1=target's sprite)
@animsprites = []
@animsprites[0] = @usersprite
@animsprites[1] = @targetsprite
(2...MAX_SPRITES).each do |i|
@animsprites[i] = Sprite.new(@viewport)
@animsprites[i].bitmap = nil
@animsprites[i].visible = false
end
# Create background colour sprite
@bgColor = ColoredPlane.new(Color.new(0, 0, 0), @viewport)
@bgColor.z = 5
@bgColor.opacity = 0
@bgColor.refresh
# Create background graphic sprite
@bgGraphic = AnimatedPlane.new(@viewport)
@bgGraphic.setBitmap(nil)
@bgGraphic.z = 5
@bgGraphic.opacity = 0
@bgGraphic.refresh
# Create foreground colour sprite
@foColor = ColoredPlane.new(Color.new(0, 0, 0), @viewport)
@foColor.z = 85
@foColor.opacity = 0
@foColor.refresh
# Create foreground graphic sprite
@foGraphic = AnimatedPlane.new(@viewport)
@foGraphic.setBitmap(nil)
@foGraphic.z = 85
@foGraphic.opacity = 0
@foGraphic.refresh
end
def dispose
@animbitmap&.dispose
(2...MAX_SPRITES).each do |i|
@animsprites[i]&.dispose
end
@bgGraphic.dispose
@bgColor.dispose
@foGraphic.dispose
@foColor.dispose
end
def start
@frame = 0
end
def animDone?
return @frame<0
end
def setLineTransform(x1,y1,x2,y2,x3,y3,x4,y4)
@srcLine = [x1,y1,x2,y2]
@dstLine = [x3,y3,x4,y4]
end
def update
return if @frame < 0
animFrame = @frame / @framesPerTick
# Loop or end the animation if the animation has reached the end
if animFrame >= @animation.length
@frame = (@looping) ? 0 : -1
if @frame < 0
@animbitmap&.dispose
@animbitmap = nil
return
end
end
# Load the animation's spritesheet and assign it to all the sprites.
if !@animbitmap || @animbitmap.disposed?
@animbitmap = AnimatedBitmap.new("Graphics/Animations/" + @animation.graphic,
@animation.hue).deanimate
MAX_SPRITES.times do |i|
@animsprites[i].bitmap = @animbitmap if @animsprites[i]
end
end
# Update background and foreground graphics
@bgGraphic.update
@bgColor.update
@foGraphic.update
@foColor.update
# Update all the sprites to depict the animation's next frame
if @framesPerTick == 1 || (@frame % @framesPerTick) == 0
thisframe = @animation[animFrame]
# Make all cel sprites invisible
MAX_SPRITES.times do |i|
@animsprites[i].visible = false if @animsprites[i]
end
# Set each cel sprite acoordingly
thisframe.length.times do |i|
cel = thisframe[i]
next if !cel
sprite = @animsprites[i]
next if !sprite
# Set cel sprite's graphic
case cel[AnimFrame::PATTERN]
when -1
sprite.bitmap = @userbitmap
when -2
sprite.bitmap = @targetbitmap
else
sprite.bitmap = @animbitmap
end
cel[AnimFrame::MIRROR] = 1
# Apply settings to the cel sprite
pbSpriteSetAnimFrame(sprite, cel, @usersprite, @targetsprite)
case cel[AnimFrame::FOCUS]
# when 1 # Focused on target
# sprite.x = cel[AnimFrame::X] - 304
# sprite.y = cel[AnimFrame::Y] - 16
# when 2 # Focused on user
# sprite.x = cel[AnimFrame::X] + 139
# sprite.y = cel[AnimFrame::Y] - 48
when 1 # Focused on target
sprite.x = cel[AnimFrame::X] + @targetOrig[0] - ContestSettings::FOCUSTARGET_X #+ ContestSettings::FOCUSTARGET_X
sprite.y = cel[AnimFrame::Y] + @targetOrig[1] - ContestSettings::FOCUSTARGET_Y #+ ContestSettings::FOCUSTARGET_Y
when 2 # Focused on user
sprite.x = cel[AnimFrame::X] + @userOrig[0] - ContestSettings::FOCUSUSER_X #+ ContestSettings::FOCUSUSER_X
sprite.y = cel[AnimFrame::Y] + @userOrig[1] - ContestSettings::FOCUSUSER_Y #+ ContestSettings::FOCUSUSER_Y
when 3 # Focused on user and target
next if !@srcLine || !@dstLine
point = transformPoint(@srcLine[0], @srcLine[1], @srcLine[2], @srcLine[3],
@dstLine[0], @dstLine[1], @dstLine[2], @dstLine[3],
sprite.x, sprite.y)
sprite.x = point[0]
sprite.y = point[1]
if isReversed(@srcLine[0], @srcLine[2], @dstLine[0], @dstLine[2]) &&
cel[AnimFrame::PATTERN] >= 0
# Reverse direction
sprite.mirror = !sprite.mirror
end
end
sprite.x += 64 if @inEditor
sprite.y += 64 if @inEditor
# For things that move the sprite, make it so it gets mirrored (like for Take Down or Protect)
if cel[AnimFrame::FOCUS] == 1 || cel[AnimFrame::FOCUS] == 2
origDistance = sprite.x - (cel[AnimFrame::FOCUS] == 1 ? @targetOrig[0] : @userOrig[0])
sprite.x -= origDistance*2
end
end
# Play timings
@animation.playTiming(animFrame, @bgGraphic, @bgColor, @foGraphic, @foColor, @oldbg, @oldfo, @user)
end
@frame += 1
end
end
# def pbSpriteSetAnimFrameContest(sprite, frame, user = nil, target = nil, inEditor = false)
# return if !sprite
# if !frame
# sprite.visible = false
# sprite.src_rect = Rect.new(0, 0, 1, 1)
# return
# end
# sprite.blend_type = frame[AnimFrame::BLENDTYPE]
# sprite.angle = frame[AnimFrame::ANGLE]
# sprite.mirror = (frame[AnimFrame::MIRROR] > 0)
# sprite.opacity = frame[AnimFrame::OPACITY]
# sprite.visible = true
# if !frame[AnimFrame::VISIBLE] == 1 && inEditor
# sprite.opacity /= 2
# else
# sprite.visible = (frame[AnimFrame::VISIBLE] == 1)
# end
# pattern = frame[AnimFrame::PATTERN]
# if pattern >= 0
# animwidth = 192
# sprite.src_rect.set((pattern % 5) * animwidth, (pattern / 5) * animwidth,
# animwidth, animwidth)
# else
# sprite.src_rect.set(0, 0,
# (sprite.bitmap) ? sprite.bitmap.width : 128,
# (sprite.bitmap) ? sprite.bitmap.height : 128)
# end
# sprite.zoom_x = frame[AnimFrame::ZOOMX] / 100.0
# sprite.zoom_y = frame[AnimFrame::ZOOMY] / 100.0
# sprite.color.set(
# frame[AnimFrame::COLORRED],
# frame[AnimFrame::COLORGREEN],
# frame[AnimFrame::COLORBLUE],
# frame[AnimFrame::COLORALPHA]
# )
# sprite.tone.set(
# frame[AnimFrame::TONERED],
# frame[AnimFrame::TONEGREEN],
# frame[AnimFrame::TONEBLUE],
# frame[AnimFrame::TONEGRAY]
# )
# sprite.ox = sprite.src_rect.width / 2
# sprite.oy = sprite.src_rect.height / 2
# sprite.x = frame[AnimFrame::X]
# sprite.y = frame[AnimFrame::Y]
# if sprite != user && sprite != target
# case frame[AnimFrame::PRIORITY]
# when 0 # Behind everything
# sprite.z = 10
# when 1 # In front of everything
# sprite.z = 80
# when 2 # Just behind focus
# case frame[AnimFrame::FOCUS]
# when 1 # Focused on target
# sprite.z = (target) ? target.z - 1 : 20
# when 2 # Focused on user
# sprite.z = (user) ? user.z - 1 : 20
# else # Focused on user and target, or screen
# sprite.z = 20
# end
# when 3 # Just in front of focus
# case frame[AnimFrame::FOCUS]
# when 1 # Focused on target
# sprite.z = (target) ? target.z + 1 : 80
# when 2 # Focused on user
# sprite.z = (user) ? user.z + 1 : 80
# else # Focused on user and target, or screen
# sprite.z = 80
# end
# else
# sprite.z = 80
# end
# end
# end