Renamed all battle-related classes and modules

This commit is contained in:
Maruno17
2021-11-16 23:05:16 +00:00
parent 6dacd6a139
commit 1c4819e5f0
79 changed files with 1270 additions and 1310 deletions

View File

@@ -0,0 +1,179 @@
module PBEffects
#===========================================================================
# These effects apply to a battler
#===========================================================================
AquaRing = 0
Attract = 1
BanefulBunker = 2
BeakBlast = 3
Bide = 4
BideDamage = 5
BideTarget = 6
BurnUp = 7
Charge = 8
ChoiceBand = 9
Confusion = 10
Counter = 11
CounterTarget = 12
Curse = 13
Dancer = 14
DefenseCurl = 15
DestinyBond = 16
DestinyBondPrevious = 17
DestinyBondTarget = 18
Disable = 19
DisableMove = 20
Electrify = 21
Embargo = 22
Encore = 23
EncoreMove = 24
Endure = 25
FirstPledge = 26
FlashFire = 27
Flinch = 28
FocusEnergy = 29
FocusPunch = 30
FollowMe = 31
Foresight = 32
FuryCutter = 33
GastroAcid = 34
GemConsumed = 35
Grudge = 36
HealBlock = 37
HelpingHand = 38
HyperBeam = 39
Illusion = 40
Imprison = 41
Ingrain = 42
Instruct = 43
Instructed = 44
JawLock = 994
KingsShield = 45
LaserFocus = 46
LeechSeed = 47
LockOn = 48
LockOnPos = 49
MagicBounce = 50
MagicCoat = 51
MagnetRise = 52
MeanLook = 53
MeFirst = 54
Metronome = 55
MicleBerry = 56
Minimize = 57
MiracleEye = 58
MirrorCoat = 59
MirrorCoatTarget = 60
MoveNext = 61
MudSport = 62
Nightmare = 63
NoRetreat = 990
Obstruct = 992
Octolock = 993
Outrage = 64
ParentalBond = 65
PerishSong = 66
PerishSongUser = 67
PickupItem = 68
PickupUse = 69
Pinch = 70 # Battle Palace only
Powder = 71
PowerTrick = 72
Prankster = 73
PriorityAbility = 74
PriorityItem = 75
Protect = 76
ProtectRate = 77
Pursuit = 78
Quash = 79
Rage = 80
RagePowder = 81 # Used along with FollowMe
Rollout = 82
Roost = 83
ShellTrap = 84
SkyDrop = 85
SlowStart = 86
SmackDown = 87
Snatch = 88
SpikyShield = 89
Spotlight = 90
Stockpile = 91
StockpileDef = 92
StockpileSpDef = 93
Substitute = 94
TarShot = 991
Taunt = 95
Telekinesis = 96
ThroatChop = 97
Torment = 98
Toxic = 99
Transform = 100
TransformSpecies = 101
Trapping = 102 # Trapping move
TrappingMove = 103
TrappingUser = 104
Truant = 105
TwoTurnAttack = 106
Type3 = 107
Unburden = 108
Uproar = 109
WaterSport = 110
WeightChange = 111
Yawn = 112
#=============================================================================
# These effects apply to a battler position
#=============================================================================
FutureSightCounter = 0
FutureSightMove = 1
FutureSightUserIndex = 2
FutureSightUserPartyIndex = 3
HealingWish = 4
LunarDance = 5
Wish = 6
WishAmount = 7
WishMaker = 8
#=============================================================================
# These effects apply to a side
#=============================================================================
AuroraVeil = 0
CraftyShield = 1
EchoedVoiceCounter = 2
EchoedVoiceUsed = 3
LastRoundFainted = 4
LightScreen = 5
LuckyChant = 6
MatBlock = 7
Mist = 8
QuickGuard = 9
Rainbow = 10
Reflect = 11
Round = 12
Safeguard = 13
SeaOfFire = 14
Spikes = 15
StealthRock = 16
StickyWeb = 17
Swamp = 18
Tailwind = 19
ToxicSpikes = 20
WideGuard = 21
#=============================================================================
# These effects apply to the battle (i.e. both sides)
#=============================================================================
AmuletCoin = 0
FairyLock = 1
FusionBolt = 2
FusionFlare = 3
Gravity = 4
HappyHour = 5
IonDeluge = 6
MagicRoom = 7
MudSportField = 8
PayDay = 9
TrickRoom = 10
WaterSportField = 11
WonderRoom = 12
end

View File

@@ -0,0 +1,88 @@
#===============================================================================
#
#===============================================================================
class Battle::ActiveField
attr_accessor :effects
attr_accessor :defaultWeather
attr_accessor :weather
attr_accessor :weatherDuration
attr_accessor :defaultTerrain
attr_accessor :terrain
attr_accessor :terrainDuration
def initialize
@effects = []
@effects[PBEffects::AmuletCoin] = false
@effects[PBEffects::FairyLock] = 0
@effects[PBEffects::FusionBolt] = false
@effects[PBEffects::FusionFlare] = false
@effects[PBEffects::Gravity] = 0
@effects[PBEffects::HappyHour] = false
@effects[PBEffects::IonDeluge] = false
@effects[PBEffects::MagicRoom] = 0
@effects[PBEffects::MudSportField] = 0
@effects[PBEffects::PayDay] = 0
@effects[PBEffects::TrickRoom] = 0
@effects[PBEffects::WaterSportField] = 0
@effects[PBEffects::WonderRoom] = 0
@defaultWeather = :None
@weather = :None
@weatherDuration = 0
@defaultTerrain = :None
@terrain = :None
@terrainDuration = 0
end
end
#===============================================================================
#
#===============================================================================
class Battle::ActiveSide
attr_accessor :effects
def initialize
@effects = []
@effects[PBEffects::AuroraVeil] = 0
@effects[PBEffects::CraftyShield] = false
@effects[PBEffects::EchoedVoiceCounter] = 0
@effects[PBEffects::EchoedVoiceUsed] = false
@effects[PBEffects::LastRoundFainted] = -1
@effects[PBEffects::LightScreen] = 0
@effects[PBEffects::LuckyChant] = 0
@effects[PBEffects::MatBlock] = false
@effects[PBEffects::Mist] = 0
@effects[PBEffects::QuickGuard] = false
@effects[PBEffects::Rainbow] = 0
@effects[PBEffects::Reflect] = 0
@effects[PBEffects::Round] = false
@effects[PBEffects::Safeguard] = 0
@effects[PBEffects::SeaOfFire] = 0
@effects[PBEffects::Spikes] = 0
@effects[PBEffects::StealthRock] = false
@effects[PBEffects::StickyWeb] = false
@effects[PBEffects::Swamp] = 0
@effects[PBEffects::Tailwind] = 0
@effects[PBEffects::ToxicSpikes] = 0
@effects[PBEffects::WideGuard] = false
end
end
#===============================================================================
#
#===============================================================================
class Battle::ActivePosition
attr_accessor :effects
def initialize
@effects = []
@effects[PBEffects::FutureSightCounter] = 0
@effects[PBEffects::FutureSightMove] = nil
@effects[PBEffects::FutureSightUserIndex] = -1
@effects[PBEffects::FutureSightUserPartyIndex] = -1
@effects[PBEffects::HealingWish] = false
@effects[PBEffects::LunarDance] = false
@effects[PBEffects::Wish] = 0
@effects[PBEffects::WishAmount] = 0
@effects[PBEffects::WishMaker] = -1
end
end

View File

@@ -0,0 +1,61 @@
#===============================================================================
#
#===============================================================================
class Battle::DamageState
attr_accessor :typeMod # Type effectiveness
attr_accessor :unaffected
attr_accessor :protected
attr_accessor :magicCoat
attr_accessor :magicBounce
attr_accessor :totalHPLost # Like hpLost, but cumulative over all hits
attr_accessor :fainted # Whether battler was knocked out by the move
attr_accessor :missed # Whether the move failed the accuracy check
attr_accessor :affection_missed
attr_accessor :invulnerable # If the move missed due to two turn move invulnerability
attr_accessor :calcDamage # Calculated damage
attr_accessor :hpLost # HP lost by opponent, inc. HP lost by a substitute
attr_accessor :critical # Critical hit flag
attr_accessor :affection_critical
attr_accessor :substitute # Whether a substitute took the damage
attr_accessor :focusBand # Focus Band used
attr_accessor :focusSash # Focus Sash used
attr_accessor :sturdy # Sturdy ability used
attr_accessor :disguise # Disguise ability used
attr_accessor :iceFace # Ice Face ability used
attr_accessor :endured # Damage was endured
attr_accessor :affection_endured
attr_accessor :berryWeakened # Whether a type-resisting berry was used
def initialize; reset; end
def reset
@typeMod = Effectiveness::INEFFECTIVE
@unaffected = false
@protected = false
@missed = false
@affection_missed = false
@invulnerable = false
@magicCoat = false
@magicBounce = false
@totalHPLost = 0
@fainted = false
resetPerHit
end
def resetPerHit
@calcDamage = 0
@hpLost = 0
@critical = false
@affection_critical = false
@substitute = false
@focusBand = false
@focusSash = false
@sturdy = false
@disguise = false
@iceFace = false
@endured = false
@affection_endured = false
@berryWeakened = false
end
end

View File

@@ -0,0 +1,71 @@
#===============================================================================
#
#===============================================================================
class Battle::Peer
def pbStorePokemon(player,pkmn)
if !player.party_full?
player.party[player.party.length] = pkmn
return -1
end
if Settings::HEAL_STORED_POKEMON
old_ready_evo = pkmn.ready_to_evolve
pkmn.heal
pkmn.ready_to_evolve = old_ready_evo
end
oldCurBox = pbCurrentBox
storedBox = $PokemonStorage.pbStoreCaught(pkmn)
if storedBox<0
# NOTE: Poké Balls can't be used if storage is full, so you shouldn't ever
# see this message.
pbDisplayPaused(_INTL("Can't catch any more..."))
return oldCurBox
end
return storedBox
end
def pbGetStorageCreatorName
return pbGetStorageCreator if $player.seen_storage_creator
return nil
end
def pbCurrentBox
return $PokemonStorage.currentBox
end
def pbBoxName(box)
return (box<0) ? "" : $PokemonStorage[box].name
end
def pbOnEnteringBattle(battle, battler, pkmn, wild = false)
f = MultipleForms.call("getFormOnEnteringBattle",pkmn,wild)
pkmn.form = f if f
battler.form = pkmn.form if battler.form != pkmn.form
MultipleForms.call("changePokemonOnEnteringBattle", battler, pkmn, battle)
end
# For switching out, including due to fainting, and for the end of battle
def pbOnLeavingBattle(battle,pkmn,usedInBattle,endBattle=false)
return if !pkmn
f = MultipleForms.call("getFormOnLeavingBattle",pkmn,battle,usedInBattle,endBattle)
pkmn.form = f if f && pkmn.form!=f
pkmn.hp = pkmn.totalhp if pkmn.hp>pkmn.totalhp
MultipleForms.call("changePokemonOnLeavingBattle", pkmn, battle, usedInBattle, endBattle)
end
end
#===============================================================================
# Unused class.
#===============================================================================
class Battle::NullPeer
def pbOnEnteringBattle(battle, battler, pkmn, wild = false); end
def pbOnLeavingBattle(battle,pkmn,usedInBattle,endBattle=false); end
def pbStorePokemon(player,pkmn)
player.party[player.party.length] = pkmn if !player.party_full?
return -1
end
def pbGetStorageCreatorName; return nil; end
def pbCurrentBox; return -1; end
def pbBoxName(box); return ""; end
end

View File

@@ -0,0 +1,275 @@
#===============================================================================
# This script modifies the battle system to implement battle rules
#===============================================================================
class Battle
unless @__clauses__aliased
alias __clauses__pbDecisionOnDraw pbDecisionOnDraw
alias __clauses__pbEndOfRoundPhase pbEndOfRoundPhase
@__clauses__aliased = true
end
def pbDecisionOnDraw
if @rules["selfkoclause"]
if self.lastMoveUser<0
# in extreme cases there may be no last move user
return 5 # game is a draw
elsif opposes?(self.lastMoveUser)
return 2 # loss
else
return 1 # win
end
end
return __clauses__pbDecisionOnDraw
end
def pbJudgeCheckpoint(user,move=nil)
if pbAllFainted?(0) && pbAllFainted?(1)
if @rules["drawclause"] # NOTE: Also includes Life Orb (not implemented)
if !(move && move.function=="HealUserByHalfOfDamageDone")
# Not a draw if fainting occurred due to Liquid Ooze
@decision = (user.opposes?) ? 1 : 2 # win / loss
end
elsif @rules["modifiedselfdestructclause"]
if move && move.function=="UserFaintsExplosive" # Self-Destruct
@decision = (user.opposes?) ? 1 : 2 # win / loss
end
end
end
end
def pbEndOfRoundPhase
__clauses__pbEndOfRoundPhase
if @rules["suddendeath"] && @decision==0
p1able = pbAbleCount(0)
p2able = pbAbleCount(1)
if p1able>p2able
@decision = 1 # loss
elsif p1able<p2able
@decision = 2 # win
end
end
end
end
class Battle::Battler
unless @__clauses__aliased
alias __clauses__pbCanSleep? pbCanSleep?
alias __clauses__pbCanSleepYawn? pbCanSleepYawn?
alias __clauses__pbCanFreeze? pbCanFreeze?
alias __clauses__pbUseMove pbUseMove
@__clauses__aliased = true
end
def pbCanSleep?(user,showMessages,move=nil,ignoreStatus=false)
selfsleep = (user && user.index==@index)
if ((@battle.rules["modifiedsleepclause"]) || (!selfsleep && @battle.rules["sleepclause"])) &&
pbHasStatusPokemon?(:SLEEP)
if showMessages
@battle.pbDisplay(_INTL("But {1} couldn't sleep!",pbThis(true)))
end
return false
end
return __clauses__pbCanSleep?(user,showMessages,move,ignoreStatus)
end
def pbCanSleepYawn?
if (@battle.rules["sleepclause"] || @battle.rules["modifiedsleepclause"]) &&
pbHasStatusPokemon?(:SLEEP)
return false
end
return __clauses__pbCanSleepYawn?
end
def pbCanFreeze?(*arg)
if @battle.rules["freezeclause"] && pbHasStatusPokemon?(:FROZEN)
return false
end
return __clauses__pbCanFreeze?(*arg)
end
def pbHasStatusPokemon?(status)
count = 0
@battle.pbParty(@index).each do |pkmn|
next if !pkmn || pkmn.egg?
next if pkmn.status!=status
count += 1
end
return count>0
end
end
class Battle::Move::RaiseUserEvasion1 # Double Team
alias __clauses__pbMoveFailed? pbMoveFailed?
def pbMoveFailed?(user,targets)
if !damagingMove? && @battle.rules["evasionclause"]
@battle.pbDisplay(_INTL("But it failed!"))
return true
end
return __clauses__pbMoveFailed?(user,targets)
end
end
class Battle::Move::RaiseUserEvasion2MinimizeUser # Minimize
alias __clauses__pbMoveFailed? pbMoveFailed?
def pbMoveFailed?(user,targets)
if !damagingMove? && @battle.rules["evasionclause"]
@battle.pbDisplay(_INTL("But it failed!"))
return true
end
return __clauses__pbMoveFailed?(user,targets)
end
end
class Battle::Move::UserTargetSwapAbilities # Skill Swap
alias __clauses__pbFailsAgainstTarget? pbFailsAgainstTarget?
def pbFailsAgainstTarget?(user, target, show_message)
if @battle.rules["skillswapclause"]
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
return __clauses__pbFailsAgainstTarget?(user, target, show_message)
end
end
class Battle::Move::FixedDamage20 # Sonic Boom
alias __clauses__pbFailsAgainstTarget? pbFailsAgainstTarget?
def pbFailsAgainstTarget?(user, target, show_message)
if @battle.rules["sonicboomclause"]
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
return __clauses__pbFailsAgainstTarget?(user, target, show_message)
end
end
class Battle::Move::FixedDamage40 # Dragon Rage
alias __clauses__pbFailsAgainstTarget? pbFailsAgainstTarget?
def pbFailsAgainstTarget?(user, target, show_message)
if @battle.rules["sonicboomclause"]
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
return __clauses__pbFailsAgainstTarget?(user, target, show_message)
end
end
class Battle::Move::OHKO
alias __clauses__pbFailsAgainstTarget? pbFailsAgainstTarget?
def pbFailsAgainstTarget?(user, target, show_message)
if @battle.rules["ohkoclause"]
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
return __clauses__pbFailsAgainstTarget?(user, target, show_message)
end
end
class Battle::Move::OHKOIce
alias __clauses__pbFailsAgainstTarget? pbFailsAgainstTarget?
def pbFailsAgainstTarget?(user, target, show_message)
if @battle.rules["ohkoclause"]
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
return __clauses__pbFailsAgainstTarget?(user, target, show_message)
end
end
class Battle::Move::OHKOHitsUndergroundTarget
alias __clauses__pbFailsAgainstTarget? pbFailsAgainstTarget?
def pbFailsAgainstTarget?(user, target, show_message)
if @battle.rules["ohkoclause"]
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
return __clauses__pbFailsAgainstTarget?(user, target, show_message)
end
end
class Battle::Move::UserFaintsExplosive # Self-Destruct
unless @__clauses__aliased
alias __clauses__pbMoveFailed? pbMoveFailed?
@__clauses__aliased = true
end
def pbMoveFailed?(user,targets)
if @battle.rules["selfkoclause"]
# Check whether no unfainted Pokemon remain in either party
count = @battle.pbAbleNonActiveCount(user.idxOwnSide)
count += @battle.pbAbleNonActiveCount(user.idxOpposingSide)
if count==0
@battle.pbDisplay("But it failed!")
return false
end
end
if @battle.rules["selfdestructclause"]
# Check whether no unfainted Pokemon remain in either party
count = @battle.pbAbleNonActiveCount(user.idxOwnSide)
count += @battle.pbAbleNonActiveCount(user.idxOpposingSide)
if count==0
@battle.pbDisplay(_INTL("{1}'s team was disqualified!",user.pbThis))
@battle.decision = (user.opposes?) ? 1 : 2
return false
end
end
return __clauses__pbMoveFailed?(user,targets)
end
end
class Battle::Move::StartPerishCountsForAllBattlers # Perish Song
alias __clauses__pbFailsAgainstTarget? pbFailsAgainstTarget?
def pbFailsAgainstTarget?(user, target, show_message)
if @battle.rules["perishsongclause"] &&
@battle.pbAbleNonActiveCount(user.idxOwnSide)==0
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
return __clauses__pbFailsAgainstTarget?(user, target, show_message)
end
end
class Battle::Move::AttackerFaintsIfUserFaints # Destiny Bond
alias __clauses__pbFailsAgainstTarget? pbFailsAgainstTarget?
def pbFailsAgainstTarget?(user, target, show_message)
if @battle.rules["perishsongclause"] &&
@battle.pbAbleNonActiveCount(user.idxOwnSide)==0
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
return __clauses__pbFailsAgainstTarget?(user, target, show_message)
end
end

View File

@@ -0,0 +1,872 @@
#===============================================================================
#
#===============================================================================
class AnimFrame
X = 0
Y = 1
ZOOMX = 2
ANGLE = 3
MIRROR = 4
BLENDTYPE = 5
VISIBLE = 6
PATTERN = 7
OPACITY = 8
ZOOMY = 11
COLORRED = 12
COLORGREEN = 13
COLORBLUE = 14
COLORALPHA = 15
TONERED = 16
TONEGREEN = 17
TONEBLUE = 18
TONEGRAY = 19
LOCKED = 20
FLASHRED = 21
FLASHGREEN = 22
FLASHBLUE = 23
FLASHALPHA = 24
PRIORITY = 25
FOCUS = 26
end
#===============================================================================
#
#===============================================================================
def yaxisIntersect(x1,y1,x2,y2,px,py)
dx = x2-x1
dy = y2-y1
x = (dx==0) ? 0.0 : (px-x1).to_f/dx
y = (dy==0) ? 0.0 : (py-y1).to_f/dy
return [x,y]
end
def repositionY(x1,y1,x2,y2,tx,ty)
dx = x2-x1
dy = y2-y1
x = x1+tx*dx.to_f
y = y1+ty*dy.to_f
return [x,y]
end
def transformPoint(x1,y1,x2,y2, # Source line
x3,y3,x4,y4, # Destination line
px,py) # Source point
ret = yaxisIntersect(x1,y1,x2,y2,px,py)
ret2 = repositionY(x3,y3,x4,y4,ret[0],ret[1])
return ret2
end
def getSpriteCenter(sprite)
return [0,0] if !sprite || sprite.disposed?
return [sprite.x,sprite.y] if !sprite.bitmap || sprite.bitmap.disposed?
centerX = sprite.src_rect.width/2
centerY = sprite.src_rect.height/2
offsetX = (centerX-sprite.ox)*sprite.zoom_x
offsetY = (centerY-sprite.oy)*sprite.zoom_y
return [sprite.x+offsetX,sprite.y+offsetY]
end
def isReversed(src0,src1,dst0,dst1)
return false if src0==src1
return (dst0>dst1) if src0<src1
return (dst0<dst1)
end
def pbCreateCel(x,y,pattern,focus=4)
frame = []
frame[AnimFrame::X] = x
frame[AnimFrame::Y] = y
frame[AnimFrame::PATTERN] = pattern
frame[AnimFrame::FOCUS] = focus # 1=target, 2=user, 3=user and target, 4=screen
frame[AnimFrame::LOCKED] = 0
pbResetCel(frame)
return frame
end
def pbResetCel(frame)
return if !frame
frame[AnimFrame::ZOOMX] = 100
frame[AnimFrame::ZOOMY] = 100
frame[AnimFrame::BLENDTYPE] = 0
frame[AnimFrame::VISIBLE] = 1
frame[AnimFrame::ANGLE] = 0
frame[AnimFrame::MIRROR] = 0
frame[AnimFrame::OPACITY] = 255
frame[AnimFrame::COLORRED] = 0
frame[AnimFrame::COLORGREEN] = 0
frame[AnimFrame::COLORBLUE] = 0
frame[AnimFrame::COLORALPHA] = 0
frame[AnimFrame::TONERED] = 0
frame[AnimFrame::TONEGREEN] = 0
frame[AnimFrame::TONEBLUE] = 0
frame[AnimFrame::TONEGRAY] = 0
frame[AnimFrame::FLASHRED] = 0
frame[AnimFrame::FLASHGREEN] = 0
frame[AnimFrame::FLASHBLUE] = 0
frame[AnimFrame::FLASHALPHA] = 0
frame[AnimFrame::PRIORITY] = 1 # 0=back, 1=front, 2=behind focus, 3=before focus
end
#===============================================================================
#
#===============================================================================
def pbConvertRPGAnimation(animation)
pbAnim = PBAnimation.new
pbAnim.id = animation.id
pbAnim.name = animation.name.clone
pbAnim.graphic = animation.animation_name
pbAnim.hue = animation.animation_hue
pbAnim.array.clear
yOffset = 0
pbAnim.position = animation.position
yOffset = -64 if animation.position==0
yOffset = 64 if animation.position==2
for i in 0...animation.frames.length
frame = pbAnim.addFrame
animFrame = animation.frames[i]
for j in 0...animFrame.cell_max
data = animFrame.cell_data
if data[j,0]==-1
frame.push(nil)
next
end
if animation.position==3 # Screen
point = transformPoint(
-160,80,160,-80,
Battle::Scene::FOCUSUSER_X,Battle::Scene::FOCUSUSER_Y,
Battle::Scene::FOCUSTARGET_X,Battle::Scene::FOCUSTARGET_Y,
data[j,1],data[j,2]
)
cel = pbCreateCel(point[0],point[1],data[j,0])
else
cel = pbCreateCel(data[j,1],data[j,2]+yOffset,data[j,0])
end
cel[AnimFrame::ZOOMX] = data[j,3]
cel[AnimFrame::ZOOMY] = data[j,3]
cel[AnimFrame::ANGLE] = data[j,4]
cel[AnimFrame::MIRROR] = data[j,5]
cel[AnimFrame::OPACITY] = data[j,6]
cel[AnimFrame::BLENDTYPE] = 0
frame.push(cel)
end
end
for i in 0...animation.timings.length
timing = animation.timings[i]
newTiming = PBAnimTiming.new
newTiming.frame = timing.frame
newTiming.name = timing.se.name
newTiming.volume = timing.se.volume
newTiming.pitch = timing.se.pitch
newTiming.flashScope = timing.flash_scope
newTiming.flashColor = timing.flash_color.clone
newTiming.flashDuration = timing.flash_duration
pbAnim.timing.push(newTiming)
end
return pbAnim
end
#===============================================================================
#
#===============================================================================
class RPG::Animation
def self.fromOther(otherAnim,id)
ret = RPG::Animation.new
ret.id = id
ret.name = otherAnim.name.clone
ret.animation_name = otherAnim.animation_name.clone
ret.animation_hue = otherAnim.animation_hue
ret.position = otherAnim.position
return ret
end
def addSound(frame,se)
timing = RPG::Animation::Timing.new
timing.frame = frame
timing.se = RPG::AudioFile.new(se,100)
self.timings.push(timing)
end
def addAnimation(otherAnim,frame,x,y) # frame is zero-based
if frame+otherAnim.frames.length>=self.frames.length
totalframes = frame+otherAnim.frames.length+1
for i in self.frames.length...totalframes
self.frames.push(RPG::Animation::Frame.new)
end
end
self.frame_max = self.frames.length
for i in 0...otherAnim.frame_max
thisframe = self.frames[frame+i]
otherframe = otherAnim.frames[i]
cellStart = thisframe.cell_max
thisframe.cell_max += otherframe.cell_max
thisframe.cell_data.resize(thisframe.cell_max,8)
for j in 0...otherframe.cell_max
thisframe.cell_data[cellStart+j,0] = otherframe.cell_data[j,0]
thisframe.cell_data[cellStart+j,1] = otherframe.cell_data[j,1]+x
thisframe.cell_data[cellStart+j,2] = otherframe.cell_data[j,2]+y
thisframe.cell_data[cellStart+j,3] = otherframe.cell_data[j,3]
thisframe.cell_data[cellStart+j,4] = otherframe.cell_data[j,4]
thisframe.cell_data[cellStart+j,5] = otherframe.cell_data[j,5]
thisframe.cell_data[cellStart+j,6] = otherframe.cell_data[j,6]
thisframe.cell_data[cellStart+j,7] = otherframe.cell_data[j,7]
end
end
for i in 0...otherAnim.timings.length
timing = RPG::Animation::Timing.new
othertiming = otherAnim.timings[i]
timing.frame = frame+othertiming.frame
timing.se = RPG::AudioFile.new(
othertiming.se.name.clone,
othertiming.se.volume,
othertiming.se.pitch)
timing.flash_scope = othertiming.flash_scope
timing.flash_color = othertiming.flash_color.clone
timing.flash_duration = othertiming.flash_duration
timing.condition = othertiming.condition
self.timings.push(timing)
end
self.timings.sort! { |a,b| a.frame<=>b.frame }
end
end
#===============================================================================
#
#===============================================================================
class PBAnimTiming
attr_accessor :frame
attr_writer :timingType # 0=play SE, 1=set bg, 2=bg mod
attr_accessor :name # Name of SE file or BG file
attr_accessor :volume
attr_accessor :pitch
attr_accessor :bgX # x coordinate of bg (or to move bg to)
attr_accessor :bgY # y coordinate of bg (or to move bg to)
attr_accessor :opacity # Opacity of bg (or to change bg to)
attr_accessor :colorRed # Color of bg (or to change bg to)
attr_accessor :colorGreen # Color of bg (or to change bg to)
attr_accessor :colorBlue # Color of bg (or to change bg to)
attr_accessor :colorAlpha # Color of bg (or to change bg to)
attr_writer :duration # How long to spend changing to the new bg coords/color
attr_accessor :flashScope
attr_accessor :flashColor
attr_accessor :flashDuration
def initialize(type=0)
@frame = 0
@timingType = type
@name = ""
@volume = 80
@pitch = 100
@bgX = nil
@bgY = nil
@opacity = nil
@colorRed = nil
@colorGreen = nil
@colorBlue = nil
@colorAlpha = nil
@duration = 5
@flashScope = 0
@flashColor = Color.new(255,255,255,255)
@flashDuration = 5
end
def timingType
return @timingType || 0
end
def duration
return @duration || 5
end
def to_s
case self.timingType
when 0
return "[#{@frame+1}] Play SE: #{name} (volume #{@volume}, pitch #{@pitch})"
when 1
text = sprintf("[%d] Set BG: \"%s\"",@frame+1,name)
text += sprintf(" (color=%s,%s,%s,%s)",
(@colorRed!=nil) ? @colorRed.to_i : "-",
(@colorGreen!=nil) ? @colorGreen.to_i : "-",
(@colorBlue!=nil) ? @colorBlue.to_i : "-",
(@colorAlpha!=nil) ? @colorAlpha.to_i : "-")
text += sprintf(" (opacity=%s)",@opacity.to_i)
text += sprintf(" (coords=%s,%s)",
(@bgX!=nil) ? @bgX : "-",
(@bgY!=nil) ? @bgY : "-")
return text
when 2
text = sprintf("[%d] Change BG: @%d",@frame+1,duration)
if @colorRed!=nil || @colorGreen!=nil || @colorBlue!=nil || @colorAlpha!=nil
text += sprintf(" (color=%s,%s,%s,%s)",
(@colorRed!=nil) ? @colorRed.to_i : "-",
(@colorGreen!=nil) ? @colorGreen.to_i : "-",
(@colorBlue!=nil) ? @colorBlue.to_i : "-",
(@colorAlpha!=nil) ? @colorAlpha.to_i : "-")
end
text += sprintf(" (opacity=%s)",@opacity.to_i) if @opacity!=nil
if @bgX!=nil || @bgY!=nil
text += sprintf(" (coords=%s,%s)",
(@bgX!=nil) ? @bgX : "-",
(@bgY!=nil) ? @bgY : "-")
end
return text
when 3
text = sprintf("[%d] Set FG: \"%s\"",@frame+1,name)
text += sprintf(" (color=%s,%s,%s,%s)",
(@colorRed!=nil) ? @colorRed.to_i : "-",
(@colorGreen!=nil) ? @colorGreen.to_i : "-",
(@colorBlue!=nil) ? @colorBlue.to_i : "-",
(@colorAlpha!=nil) ? @colorAlpha.to_i : "-")
text += sprintf(" (opacity=%s)",@opacity.to_i)
text += sprintf(" (coords=%s,%s)",
(@bgX!=nil) ? @bgX : "-",
(@bgY!=nil) ? @bgY : "-")
return text
when 4
text = sprintf("[%d] Change FG: @%d",@frame+1,duration)
if @colorRed!=nil || @colorGreen!=nil || @colorBlue!=nil || @colorAlpha!=nil
text += sprintf(" (color=%s,%s,%s,%s)",
(@colorRed!=nil) ? @colorRed.to_i : "-",
(@colorGreen!=nil) ? @colorGreen.to_i : "-",
(@colorBlue!=nil) ? @colorBlue.to_i : "-",
(@colorAlpha!=nil) ? @colorAlpha.to_i : "-")
end
text += sprintf(" (opacity=%s)",@opacity.to_i) if @opacity!=nil
if @bgX!=nil || @bgY!=nil
text += sprintf(" (coords=%s,%s)",
(@bgX!=nil) ? @bgX : "-",
(@bgY!=nil) ? @bgY : "-")
end
return text
end
return ""
end
end
#===============================================================================
#
#===============================================================================
class PBAnimations < Array
include Enumerable
attr_reader :array
attr_accessor :selected
def initialize(size=1)
@array = []
@selected = 0
size = 1 if size<1 # Always create at least one animation
size.times do
@array.push(PBAnimation.new)
end
end
def length
return @array.length
end
def each
@array.each { |i| yield i }
end
def [](i)
return @array[i]
end
def []=(i,value)
@array[i] = value
end
def compact
@array.compact!
end
def insert(index,val)
@array.insert(index,val)
end
def delete_at(index)
@array.delete_at(index)
end
def resize(len)
idxStart = @array.length
idxEnd = len
if idxStart>idxEnd
for i in idxEnd...idxStart
@array.pop
end
else
for i in idxStart...idxEnd
@array.push(PBAnimation.new)
end
end
self.selected = len if self.selected>=len
end
end
#===============================================================================
#
#===============================================================================
class PBAnimation < Array
include Enumerable
attr_accessor :id
attr_accessor :name
attr_accessor :graphic
attr_accessor :hue
attr_accessor :position
attr_writer :speed
attr_reader :array
attr_reader :timing
MAX_SPRITES = 60
def speed
return @speed || 20
end
def initialize(size=1)
@id = -1
@name = ""
@graphic = ""
@hue = 0
@position = 4 # 1=target, 2=user, 3=user and target, 4=screen
@array = []
size = 1 if size<1 # Always create at least one frame
size.times { addFrame }
@timing = []
@scope = 0
end
def length
return @array.length
end
def each
@array.each { |i| yield i }
end
def [](i)
return @array[i]
end
def []=(i,value)
@array[i] = value
end
def insert(*arg)
return @array.insert(*arg)
end
def delete_at(*arg)
return @array.delete_at(*arg)
end
def resize(len)
if len<@array.length
@array[len,@array.length-len] = []
elsif len>@array.length
(len-@array.length).times do
addFrame
end
end
end
def addFrame
pos = @array.length
@array[pos] = []
# Move's user
@array[pos][0] = pbCreateCel(Battle::Scene::FOCUSUSER_X, Battle::Scene::FOCUSUSER_Y,-1)
@array[pos][0][AnimFrame::FOCUS] = 2
@array[pos][0][AnimFrame::LOCKED] = 1
# Move's target
@array[pos][1] = pbCreateCel(Battle::Scene::FOCUSTARGET_X, Battle::Scene::FOCUSTARGET_Y,-2)
@array[pos][1][AnimFrame::FOCUS] = 1
@array[pos][1][AnimFrame::LOCKED] = 1
return @array[pos]
end
def playTiming(frame,bgGraphic,bgColor,foGraphic,foColor,oldbg=[],oldfo=[],user=nil)
for i in @timing
next if i.frame!=frame
case i.timingType
when 0 # Play SE
if i.name && i.name!=""
pbSEPlay("Anim/"+i.name,i.volume,i.pitch)
elsif user && user.pokemon
name = GameData::Species.cry_filename_from_pokemon(user.pokemon)
pbSEPlay(name,i.volume,i.pitch) if name
end
# if sprite
# sprite.flash(i.flashColor,i.flashDuration*2) if i.flashScope==1
# sprite.flash(nil,i.flashDuration*2) if i.flashScope==3
# end
when 1 # Set background graphic (immediate)
if i.name && i.name!=""
bgGraphic.setBitmap("Graphics/Animations/"+i.name)
bgGraphic.ox = -i.bgX || 0
bgGraphic.oy = -i.bgY || 0
bgGraphic.color = Color.new(i.colorRed || 0,i.colorGreen || 0,i.colorBlue || 0,i.colorAlpha || 0)
bgGraphic.opacity = i.opacity || 0
bgColor.opacity = 0
else
bgGraphic.setBitmap(nil)
bgGraphic.opacity = 0
bgColor.color = Color.new(i.colorRed || 0,i.colorGreen || 0,i.colorBlue || 0,i.colorAlpha || 0)
bgColor.opacity = i.opacity || 0
end
when 2 # Move/recolour background graphic
if bgGraphic.bitmap!=nil
oldbg[0] = bgGraphic.ox || 0
oldbg[1] = bgGraphic.oy || 0
oldbg[2] = bgGraphic.opacity || 0
oldbg[3] = bgGraphic.color.clone || Color.new(0,0,0,0)
else
oldbg[0] = 0
oldbg[1] = 0
oldbg[2] = bgColor.opacity || 0
oldbg[3] = bgColor.color.clone || Color.new(0,0,0,0)
end
when 3 # Set foreground graphic (immediate)
if i.name && i.name!=""
foGraphic.setBitmap("Graphics/Animations/"+i.name)
foGraphic.ox = -i.bgX || 0
foGraphic.oy = -i.bgY || 0
foGraphic.color = Color.new(i.colorRed || 0,i.colorGreen || 0,i.colorBlue || 0,i.colorAlpha || 0)
foGraphic.opacity = i.opacity || 0
foColor.opacity = 0
else
foGraphic.setBitmap(nil)
foGraphic.opacity = 0
foColor.color = Color.new(i.colorRed || 0,i.colorGreen || 0,i.colorBlue || 0,i.colorAlpha || 0)
foColor.opacity = i.opacity || 0
end
when 4 # Move/recolour foreground graphic
if foGraphic.bitmap!=nil
oldfo[0] = foGraphic.ox || 0
oldfo[1] = foGraphic.oy || 0
oldfo[2] = foGraphic.opacity || 0
oldfo[3] = foGraphic.color.clone || Color.new(0,0,0,0)
else
oldfo[0] = 0
oldfo[1] = 0
oldfo[2] = foColor.opacity || 0
oldfo[3] = foColor.color.clone || Color.new(0,0,0,0)
end
end
end
for i in @timing
case i.timingType
when 2
next if !i.duration || i.duration<=0
next if frame<i.frame || frame>i.frame+i.duration
fraction = (frame-i.frame).to_f/i.duration
if bgGraphic.bitmap!=nil
bgGraphic.ox = oldbg[0]-(i.bgX-oldbg[0])*fraction if i.bgX!=nil
bgGraphic.oy = oldbg[1]-(i.bgY-oldbg[1])*fraction if i.bgY!=nil
bgGraphic.opacity = oldbg[2]+(i.opacity-oldbg[2])*fraction if i.opacity!=nil
cr = (i.colorRed!=nil) ? oldbg[3].red+(i.colorRed-oldbg[3].red)*fraction : oldbg[3].red
cg = (i.colorGreen!=nil) ? oldbg[3].green+(i.colorGreen-oldbg[3].green)*fraction : oldbg[3].green
cb = (i.colorBlue!=nil) ? oldbg[3].blue+(i.colorBlue-oldbg[3].blue)*fraction : oldbg[3].blue
ca = (i.colorAlpha!=nil) ? oldbg[3].alpha+(i.colorAlpha-oldbg[3].alpha)*fraction : oldbg[3].alpha
bgGraphic.color = Color.new(cr,cg,cb,ca)
else
bgColor.opacity = oldbg[2]+(i.opacity-oldbg[2])*fraction if i.opacity!=nil
cr = (i.colorRed!=nil) ? oldbg[3].red+(i.colorRed-oldbg[3].red)*fraction : oldbg[3].red
cg = (i.colorGreen!=nil) ? oldbg[3].green+(i.colorGreen-oldbg[3].green)*fraction : oldbg[3].green
cb = (i.colorBlue!=nil) ? oldbg[3].blue+(i.colorBlue-oldbg[3].blue)*fraction : oldbg[3].blue
ca = (i.colorAlpha!=nil) ? oldbg[3].alpha+(i.colorAlpha-oldbg[3].alpha)*fraction : oldbg[3].alpha
bgColor.color = Color.new(cr,cg,cb,ca)
end
when 4
next if !i.duration || i.duration<=0
next if frame<i.frame || frame>i.frame+i.duration
fraction = (frame-i.frame).to_f/i.duration
if foGraphic.bitmap!=nil
foGraphic.ox = oldfo[0]-(i.bgX-oldfo[0])*fraction if i.bgX!=nil
foGraphic.oy = oldfo[1]-(i.bgY-oldfo[1])*fraction if i.bgY!=nil
foGraphic.opacity = oldfo[2]+(i.opacity-oldfo[2])*fraction if i.opacity!=nil
cr = (i.colorRed!=nil) ? oldfo[3].red+(i.colorRed-oldfo[3].red)*fraction : oldfo[3].red
cg = (i.colorGreen!=nil) ? oldfo[3].green+(i.colorGreen-oldfo[3].green)*fraction : oldfo[3].green
cb = (i.colorBlue!=nil) ? oldfo[3].blue+(i.colorBlue-oldfo[3].blue)*fraction : oldfo[3].blue
ca = (i.colorAlpha!=nil) ? oldfo[3].alpha+(i.colorAlpha-oldfo[3].alpha)*fraction : oldfo[3].alpha
foGraphic.color = Color.new(cr,cg,cb,ca)
else
foColor.opacity = oldfo[2]+(i.opacity-oldfo[2])*fraction if i.opacity!=nil
cr = (i.colorRed!=nil) ? oldfo[3].red+(i.colorRed-oldfo[3].red)*fraction : oldfo[3].red
cg = (i.colorGreen!=nil) ? oldfo[3].green+(i.colorGreen-oldfo[3].green)*fraction : oldfo[3].green
cb = (i.colorBlue!=nil) ? oldfo[3].blue+(i.colorBlue-oldfo[3].blue)*fraction : oldfo[3].blue
ca = (i.colorAlpha!=nil) ? oldfo[3].alpha+(i.colorAlpha-oldfo[3].alpha)*fraction : oldfo[3].alpha
foColor.color = Color.new(cr,cg,cb,ca)
end
end
end
end
end
#===============================================================================
#
#===============================================================================
def pbSpriteSetAnimFrame(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
#===============================================================================
# Animation player
#===============================================================================
class PBAnimationPlayerX
attr_accessor :looping
MAX_SPRITES = 60
def initialize(animation,user,target,scene=nil,oppMove=false,inEditor=false)
@animation = animation
@user = (oppMove) ? target : user # Just used for playing user's cry
@usersprite = (user) ? scene.sprites["pokemon_#{user.index}"] : nil
@targetsprite = (target) ? scene.sprites["pokemon_#{target.index}"] : nil
@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 = (scene) ? scene.viewport : nil
@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
for i in 2...MAX_SPRITES
@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.borderX = 64 if @inEditor
@bgColor.borderY = 64 if @inEditor
@bgColor.z = 5
@bgColor.opacity = 0
@bgColor.refresh
# Create background graphic sprite
@bgGraphic = AnimatedPlane.new(@viewport)
@bgGraphic.setBitmap(nil)
@bgGraphic.borderX = 64 if @inEditor
@bgGraphic.borderY = 64 if @inEditor
@bgGraphic.z = 5
@bgGraphic.opacity = 0
@bgGraphic.refresh
# Create foreground colour sprite
@foColor = ColoredPlane.new(Color.new(0,0,0),@viewport)
@foColor.borderX = 64 if @inEditor
@foColor.borderY = 64 if @inEditor
@foColor.z = 85
@foColor.opacity = 0
@foColor.refresh
# Create foreground graphic sprite
@foGraphic = AnimatedPlane.new(@viewport)
@foGraphic.setBitmap(nil)
@foGraphic.borderX = 64 if @inEditor
@foGraphic.borderY = 64 if @inEditor
@foGraphic.z = 85
@foGraphic.opacity = 0
@foGraphic.refresh
end
def dispose
@animbitmap.dispose if @animbitmap
for i in 2...MAX_SPRITES
@animsprites[i].dispose if @animsprites[i]
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 if @animbitmap
@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
for i in 0...MAX_SPRITES
@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
for i in 0...MAX_SPRITES
@animsprites[i].visible = false if @animsprites[i]
end
# Set each cel sprite acoordingly
for i in 0...thisframe.length
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
# 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] + @targetOrig[0] - Battle::Scene::FOCUSTARGET_X
sprite.y = cel[AnimFrame::Y] + @targetOrig[1] - Battle::Scene::FOCUSTARGET_Y
when 2 # Focused on user
sprite.x = cel[AnimFrame::X] + @userOrig[0] - Battle::Scene::FOCUSUSER_X
sprite.y = cel[AnimFrame::Y] + @userOrig[1] - Battle::Scene::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
end
# Play timings
@animation.playTiming(animFrame,@bgGraphic,@bgColor,@foGraphic,@foColor,@oldbg,@oldfo,@user)
end
@frame += 1
end
end

View File

@@ -0,0 +1,657 @@
module BattleHandlers
# Battler's speed calculation
SpeedCalcAbility = AbilityHandlerHash.new
SpeedCalcItem = ItemHandlerHash.new
# Battler's weight calculation
WeightCalcAbility = AbilityHandlerHash.new
WeightCalcItem = ItemHandlerHash.new # Float Stone
# Battler's HP/stat changed
HPHealItem = ItemHandlerHash.new
AbilityOnHPDroppedBelowHalf = AbilityHandlerHash.new
ItemOnStatDropped = ItemHandlerHash.new
# Battler's status problem
StatusCheckAbilityNonIgnorable = AbilityHandlerHash.new # Comatose
StatusImmunityAbility = AbilityHandlerHash.new
StatusImmunityAbilityNonIgnorable = AbilityHandlerHash.new
StatusImmunityAllyAbility = AbilityHandlerHash.new
AbilityOnStatusInflicted = AbilityHandlerHash.new # Synchronize
StatusCureItem = ItemHandlerHash.new
StatusCureAbility = AbilityHandlerHash.new
# Battler's stat stages
StatLossImmunityAbility = AbilityHandlerHash.new
StatLossImmunityAbilityNonIgnorable = AbilityHandlerHash.new # Full Metal Body
StatLossImmunityAllyAbility = AbilityHandlerHash.new # Flower Veil
AbilityOnStatGain = AbilityHandlerHash.new # None!
AbilityOnStatLoss = AbilityHandlerHash.new
# Priority and turn order
PriorityChangeAbility = AbilityHandlerHash.new
PriorityBracketChangeAbility = AbilityHandlerHash.new # Stall
PriorityBracketChangeItem = ItemHandlerHash.new
PriorityBracketUseAbility = AbilityHandlerHash.new # None!
PriorityBracketUseItem = ItemHandlerHash.new
# Move usage failures
AbilityOnFlinch = AbilityHandlerHash.new # Steadfast
MoveBlockingAbility = AbilityHandlerHash.new
MoveImmunityTargetAbility = AbilityHandlerHash.new
UserItemOnMissing = ItemHandlerHash.new # Blunder Policy
# Move usage
MoveBaseTypeModifierAbility = AbilityHandlerHash.new
# Accuracy calculation
AccuracyCalcUserAbility = AbilityHandlerHash.new
AccuracyCalcUserAllyAbility = AbilityHandlerHash.new # Victory Star
AccuracyCalcTargetAbility = AbilityHandlerHash.new
AccuracyCalcUserItem = ItemHandlerHash.new
AccuracyCalcTargetItem = ItemHandlerHash.new
# Damage calculation
DamageCalcUserAbility = AbilityHandlerHash.new
DamageCalcUserAllyAbility = AbilityHandlerHash.new
DamageCalcTargetAbility = AbilityHandlerHash.new
DamageCalcTargetAbilityNonIgnorable = AbilityHandlerHash.new
DamageCalcTargetAllyAbility = AbilityHandlerHash.new
DamageCalcUserItem = ItemHandlerHash.new
DamageCalcTargetItem = ItemHandlerHash.new
# Critical hit calculation
CriticalCalcUserAbility = AbilityHandlerHash.new
CriticalCalcTargetAbility = AbilityHandlerHash.new
CriticalCalcUserItem = ItemHandlerHash.new
CriticalCalcTargetItem = ItemHandlerHash.new # None!
# Upon a move hitting a target
TargetAbilityOnHit = AbilityHandlerHash.new
UserAbilityOnHit = AbilityHandlerHash.new # Poison Touch
TargetItemOnHit = ItemHandlerHash.new
TargetItemOnHitPositiveBerry = ItemHandlerHash.new
# Abilities/items that trigger at the end of using a move
UserAbilityEndOfMove = AbilityHandlerHash.new
TargetItemAfterMoveUse = ItemHandlerHash.new
UserItemAfterMoveUse = ItemHandlerHash.new
TargetAbilityAfterMoveUse = AbilityHandlerHash.new
EndOfMoveItem = ItemHandlerHash.new # Leppa Berry
EndOfMoveStatRestoreItem = ItemHandlerHash.new # White Herb
# Experience and EV gain
ExpGainModifierItem = ItemHandlerHash.new # Lucky Egg
EVGainModifierItem = ItemHandlerHash.new
# Weather and terrin
WeatherExtenderItem = ItemHandlerHash.new
TerrainExtenderItem = ItemHandlerHash.new # Terrain Extender
TerrainStatBoostItem = ItemHandlerHash.new
# End Of Round
EORWeatherAbility = AbilityHandlerHash.new
EORHealingAbility = AbilityHandlerHash.new
EORHealingItem = ItemHandlerHash.new
EOREffectAbility = AbilityHandlerHash.new
EOREffectItem = ItemHandlerHash.new
EORGainItemAbility = AbilityHandlerHash.new
# Switching and fainting
CertainSwitchingUserAbility = AbilityHandlerHash.new # None!
CertainSwitchingUserItem = ItemHandlerHash.new # Shed Shell
TrappingTargetAbility = AbilityHandlerHash.new
TrappingTargetItem = ItemHandlerHash.new # None!
AbilityOnSwitchIn = AbilityHandlerHash.new
ItemOnSwitchIn = ItemHandlerHash.new # Air Balloon
ItemOnIntimidated = ItemHandlerHash.new # Adrenaline Orb
AbilityOnSwitchOut = AbilityHandlerHash.new
AbilityChangeOnBattlerFainting = AbilityHandlerHash.new
AbilityOnBattlerFainting = AbilityHandlerHash.new # Soul-Heart
AbilityOnTerrainChange = AbilityHandlerHash.new # Mimicry
AbilityOnIntimidated = AbilityHandlerHash.new # Rattled (Gen 8)
# Running from battle
RunFromBattleAbility = AbilityHandlerHash.new # Run Away
RunFromBattleItem = ItemHandlerHash.new # Smoke Ball
#=============================================================================
def self.triggerSpeedCalcAbility(ability,battler,mult)
ret = SpeedCalcAbility.trigger(ability,battler,mult)
return (ret!=nil) ? ret : mult
end
def self.triggerSpeedCalcItem(item,battler,mult)
ret = SpeedCalcItem.trigger(item,battler,mult)
return (ret!=nil) ? ret : mult
end
#=============================================================================
def self.triggerWeightCalcAbility(ability,battler,w)
ret = WeightCalcAbility.trigger(ability,battler,w)
return (ret!=nil) ? ret : w
end
def self.triggerWeightCalcItem(item,battler,w)
ret = WeightCalcItem.trigger(item,battler,w)
return (ret!=nil) ? ret : w
end
#=============================================================================
def self.triggerHPHealItem(item,battler,battle,forced)
ret = HPHealItem.trigger(item,battler,battle,forced)
return (ret!=nil) ? ret : false
end
def self.triggerAbilityOnHPDroppedBelowHalf(ability, user, move_user, battle)
ret = AbilityOnHPDroppedBelowHalf.trigger(ability, user, move_user, battle)
return (ret!=nil) ? ret : false
end
def self.triggerItemOnStatDropped(item, user, move_user, battle)
ret = ItemOnStatDropped.trigger(item, user, move_user, battle)
return (ret != nil) ? ret : false
end
#=============================================================================
def self.triggerStatusCheckAbilityNonIgnorable(ability,battler,status)
ret = StatusCheckAbilityNonIgnorable.trigger(ability,battler,status)
return (ret!=nil) ? ret : false
end
def self.triggerStatusImmunityAbility(ability,battler,status)
ret = StatusImmunityAbility.trigger(ability,battler,status)
return (ret!=nil) ? ret : false
end
def self.triggerStatusImmunityAbilityNonIgnorable(ability,battler,status)
ret = StatusImmunityAbilityNonIgnorable.trigger(ability,battler,status)
return (ret!=nil) ? ret : false
end
def self.triggerStatusImmunityAllyAbility(ability,battler,status)
ret = StatusImmunityAllyAbility.trigger(ability,battler,status)
return (ret!=nil) ? ret : false
end
def self.triggerAbilityOnStatusInflicted(ability,battler,user,status)
AbilityOnStatusInflicted.trigger(ability,battler,user,status)
end
def self.triggerStatusCureItem(item,battler,battle,forced)
ret = StatusCureItem.trigger(item,battler,battle,forced)
return (ret!=nil) ? ret : false
end
def self.triggerStatusCureAbility(ability,battler)
ret = StatusCureAbility.trigger(ability,battler)
return (ret!=nil) ? ret : false
end
#=============================================================================
def self.triggerStatLossImmunityAbility(ability,battler,stat,battle,showMessages)
ret = StatLossImmunityAbility.trigger(ability,battler,stat,battle,showMessages)
return (ret!=nil) ? ret : false
end
def self.triggerStatLossImmunityAbilityNonIgnorable(ability,battler,stat,battle,showMessages)
ret = StatLossImmunityAbilityNonIgnorable.trigger(ability,battler,stat,battle,showMessages)
return (ret!=nil) ? ret : false
end
def self.triggerStatLossImmunityAllyAbility(ability,bearer,battler,stat,battle,showMessages)
ret = StatLossImmunityAllyAbility.trigger(ability,bearer,battler,stat,battle,showMessages)
return (ret!=nil) ? ret : false
end
def self.triggerAbilityOnStatGain(ability,battler,stat,user)
AbilityOnStatGain.trigger(ability,battler,stat,user)
end
def self.triggerAbilityOnStatLoss(ability,battler,stat,user)
AbilityOnStatLoss.trigger(ability,battler,stat,user)
end
#=============================================================================
def self.triggerPriorityChangeAbility(ability,battler,move,pri)
ret = PriorityChangeAbility.trigger(ability,battler,move,pri)
return (ret!=nil) ? ret : pri
end
def self.triggerPriorityBracketChangeAbility(ability,battler,subPri,battle)
ret = PriorityBracketChangeAbility.trigger(ability,battler,subPri,battle)
return (ret!=nil) ? ret : subPri
end
def self.triggerPriorityBracketChangeItem(item,battler,subPri,battle)
ret = PriorityBracketChangeItem.trigger(item,battler,subPri,battle)
return (ret!=nil) ? ret : subPri
end
def self.triggerPriorityBracketUseAbility(ability,battler,battle)
PriorityBracketUseAbility.trigger(ability,battler,battle)
end
def self.triggerPriorityBracketUseItem(item,battler,battle)
PriorityBracketUseItem.trigger(item,battler,battle)
end
#=============================================================================
def self.triggerAbilityOnFlinch(ability,battler,battle)
AbilityOnFlinch.trigger(ability,battler,battle)
end
def self.triggerMoveBlockingAbility(ability,bearer,user,targets,move,battle)
ret = MoveBlockingAbility.trigger(ability,bearer,user,targets,move,battle)
return (ret!=nil) ? ret : false
end
def self.triggerMoveImmunityTargetAbility(ability, user, target, move, type, battle, show_message)
ret = MoveImmunityTargetAbility.trigger(ability, user, target, move, type, battle, show_message)
return (ret!=nil) ? ret : false
end
def self.triggerUserItemOnMissing(item, user, target, move, hit_num, battle)
UserItemOnMissing.trigger(item, user, target, move, hit_num, battle)
end
#=============================================================================
def self.triggerMoveBaseTypeModifierAbility(ability,user,move,type)
ret = MoveBaseTypeModifierAbility.trigger(ability,user,move,type)
return (ret!=nil) ? ret : type
end
#=============================================================================
def self.triggerAccuracyCalcUserAbility(ability,mods,user,target,move,type)
AccuracyCalcUserAbility.trigger(ability,mods,user,target,move,type)
end
def self.triggerAccuracyCalcUserAllyAbility(ability,mods,user,target,move,type)
AccuracyCalcUserAllyAbility.trigger(ability,mods,user,target,move,type)
end
def self.triggerAccuracyCalcTargetAbility(ability,mods,user,target,move,type)
AccuracyCalcTargetAbility.trigger(ability,mods,user,target,move,type)
end
def self.triggerAccuracyCalcUserItem(item,mods,user,target,move,type)
AccuracyCalcUserItem.trigger(item,mods,user,target,move,type)
end
def self.triggerAccuracyCalcTargetItem(item,mods,user,target,move,type)
AccuracyCalcTargetItem.trigger(item,mods,user,target,move,type)
end
#=============================================================================
def self.triggerDamageCalcUserAbility(ability,user,target,move,mults,baseDmg,type)
DamageCalcUserAbility.trigger(ability,user,target,move,mults,baseDmg,type)
end
def self.triggerDamageCalcUserAllyAbility(ability,user,target,move,mults,baseDmg,type)
DamageCalcUserAllyAbility.trigger(ability,user,target,move,mults,baseDmg,type)
end
def self.triggerDamageCalcTargetAbility(ability,user,target,move,mults,baseDmg,type)
DamageCalcTargetAbility.trigger(ability,user,target,move,mults,baseDmg,type)
end
def self.triggerDamageCalcTargetAbilityNonIgnorable(ability,user,target,move,mults,baseDmg,type)
DamageCalcTargetAbilityNonIgnorable.trigger(ability,user,target,move,mults,baseDmg,type)
end
def self.triggerDamageCalcTargetAllyAbility(ability,user,target,move,mults,baseDmg,type)
DamageCalcTargetAllyAbility.trigger(ability,user,target,move,mults,baseDmg,type)
end
def self.triggerDamageCalcUserItem(item,user,target,move,mults,baseDmg,type)
DamageCalcUserItem.trigger(item,user,target,move,mults,baseDmg,type)
end
def self.triggerDamageCalcTargetItem(item,user,target,move,mults,baseDmg,type)
DamageCalcTargetItem.trigger(item,user,target,move,mults,baseDmg,type)
end
#=============================================================================
def self.triggerCriticalCalcUserAbility(ability,user,target,c)
ret = CriticalCalcUserAbility.trigger(ability,user,target,c)
return (ret!=nil) ? ret : c
end
def self.triggerCriticalCalcTargetAbility(ability,user,target,c)
ret = CriticalCalcTargetAbility.trigger(ability,user,target,c)
return (ret!=nil) ? ret : c
end
def self.triggerCriticalCalcUserItem(item,user,target,c)
ret = CriticalCalcUserItem.trigger(item,user,target,c)
return (ret!=nil) ? ret : c
end
def self.triggerCriticalCalcTargetItem(item,user,target,c)
ret = CriticalCalcTargetItem.trigger(item,user,target,c)
return (ret!=nil) ? ret : c
end
#=============================================================================
def self.triggerTargetAbilityOnHit(ability,user,target,move,battle)
TargetAbilityOnHit.trigger(ability,user,target,move,battle)
end
def self.triggerUserAbilityOnHit(ability,user,target,move,battle)
UserAbilityOnHit.trigger(ability,user,target,move,battle)
end
def self.triggerTargetItemOnHit(item,user,target,move,battle)
TargetItemOnHit.trigger(item,user,target,move,battle)
end
def self.triggerTargetItemOnHitPositiveBerry(item,battler,battle,forced)
ret = TargetItemOnHitPositiveBerry.trigger(item,battler,battle,forced)
return (ret!=nil) ? ret : false
end
#=============================================================================
def self.triggerUserAbilityEndOfMove(ability,user,targets,move,battle)
UserAbilityEndOfMove.trigger(ability,user,targets,move,battle)
end
def self.triggerTargetItemAfterMoveUse(item, battler, user, move, switched_battlers, battle)
TargetItemAfterMoveUse.trigger(item, battler, user, move, switched_battlers, battle)
end
def self.triggerUserItemAfterMoveUse(item,user,targets,move,numHits,battle)
UserItemAfterMoveUse.trigger(item,user,targets,move,numHits,battle)
end
def self.triggerTargetAbilityAfterMoveUse(ability, target, user, move, switched_battlers, battle)
TargetAbilityAfterMoveUse.trigger(ability, target, user, move, switched_battlers, battle)
end
def self.triggerEndOfMoveItem(item,battler,battle,forced)
ret = EndOfMoveItem.trigger(item,battler,battle,forced)
return (ret!=nil) ? ret : false
end
def self.triggerEndOfMoveStatRestoreItem(item,battler,battle,forced)
ret = EndOfMoveStatRestoreItem.trigger(item,battler,battle,forced)
return (ret!=nil) ? ret : false
end
#=============================================================================
def self.triggerExpGainModifierItem(item,battler,exp)
ret = ExpGainModifierItem.trigger(item,battler,exp)
return (ret!=nil) ? ret : -1
end
def self.triggerEVGainModifierItem(item,battler,evarray)
return false if !EVGainModifierItem[item]
EVGainModifierItem.trigger(item,battler,evarray)
return true
end
#=============================================================================
def self.triggerWeatherExtenderItem(item,weather,duration,battler,battle)
ret = WeatherExtenderItem.trigger(item,weather,duration,battler,battle)
return (ret!=nil) ? ret : duration
end
def self.triggerTerrainExtenderItem(item,terrain,duration,battler,battle)
ret = TerrainExtenderItem.trigger(item,terrain,duration,battler,battle)
return (ret!=nil) ? ret : duration
end
def self.triggerTerrainStatBoostItem(item,battler,battle)
ret = TerrainStatBoostItem.trigger(item,battler,battle)
return (ret!=nil) ? ret : false
end
#=============================================================================
def self.triggerEORWeatherAbility(ability,weather,battler,battle)
EORWeatherAbility.trigger(ability,weather,battler,battle)
end
def self.triggerEORHealingAbility(ability,battler,battle)
EORHealingAbility.trigger(ability,battler,battle)
end
def self.triggerEORHealingItem(item,battler,battle)
EORHealingItem.trigger(item,battler,battle)
end
def self.triggerEOREffectAbility(ability,battler,battle)
EOREffectAbility.trigger(ability,battler,battle)
end
def self.triggerEOREffectItem(item,battler,battle)
EOREffectItem.trigger(item,battler,battle)
end
def self.triggerEORGainItemAbility(ability,battler,battle)
EORGainItemAbility.trigger(ability,battler,battle)
end
#=============================================================================
def self.triggerCertainSwitchingUserAbility(ability,switcher,battle)
ret = CertainSwitchingUserAbility.trigger(ability,switcher,battle)
return (ret!=nil) ? ret : false
end
def self.triggerCertainSwitchingUserItem(item,switcher,battle)
ret = CertainSwitchingUserItem.trigger(item,switcher,battle)
return (ret!=nil) ? ret : false
end
def self.triggerTrappingTargetAbility(ability,switcher,bearer,battle)
ret = TrappingTargetAbility.trigger(ability,switcher,bearer,battle)
return (ret!=nil) ? ret : false
end
def self.triggerTrappingTargetItem(item,switcher,bearer,battle)
ret = TrappingTargetItem.trigger(item,switcher,bearer,battle)
return (ret!=nil) ? ret : false
end
def self.triggerAbilityOnSwitchIn(ability,battler,battle)
AbilityOnSwitchIn.trigger(ability,battler,battle)
end
def self.triggerItemOnSwitchIn(item,battler,battle)
ItemOnSwitchIn.trigger(item,battler,battle)
end
def self.triggerItemOnIntimidated(item,battler,battle)
ret = ItemOnIntimidated.trigger(item,battler,battle)
return (ret!=nil) ? ret : false
end
def self.triggerAbilityOnSwitchOut(ability,battler,endOfBattle)
AbilityOnSwitchOut.trigger(ability,battler,endOfBattle)
end
def self.triggerAbilityChangeOnBattlerFainting(ability,battler,fainted,battle)
AbilityChangeOnBattlerFainting.trigger(ability,battler,fainted,battle)
end
def self.triggerAbilityOnBattlerFainting(ability,battler,fainted,battle)
AbilityOnBattlerFainting.trigger(ability,battler,fainted,battle)
end
def self.triggerAbilityOnTerrainChange(ability, battler, battle, ability_changed)
AbilityOnTerrainChange.trigger(ability, battler, battle, ability_changed)
end
def self.triggerAbilityOnIntimidated(ability,battler,battle)
AbilityOnIntimidated.trigger(ability,battler,battle)
end
#=============================================================================
def self.triggerRunFromBattleAbility(ability,battler)
ret = RunFromBattleAbility.trigger(ability,battler)
return (ret!=nil) ? ret : false
end
def self.triggerRunFromBattleItem(item,battler)
ret = RunFromBattleItem.trigger(item,battler)
return (ret!=nil) ? ret : false
end
end
def pbBattleConfusionBerry(battler,battle,item,forced,flavor,confuseMsg)
return false if !forced && !battler.canHeal?
return false if !forced && !battler.canConsumePinchBerry?(Settings::MECHANICS_GENERATION >= 7)
itemName = GameData::Item.get(item).name
fraction_to_heal = 8 # Gens 6 and lower
if Settings::MECHANICS_GENERATION == 7
fraction_to_heal = 2
elsif Settings::MECHANICS_GENERATION >= 8
fraction_to_heal = 3
end
amt = battler.totalhp / fraction_to_heal
ripening = false
if battler.hasActiveAbility?(:RIPEN)
battle.pbShowAbilitySplash(battler, forced)
amt *= 2
ripening = true
end
battle.pbCommonAnimation("EatBerry", battler) if !forced
battle.pbHideAbilitySplash(battler) if ripening
amt = battler.pbRecoverHP(amt)
if amt>0
if forced
PBDebug.log("[Item triggered] Forced consuming of #{itemName}")
battle.pbDisplay(_INTL("{1}'s HP was restored.",battler.pbThis))
else
battle.pbDisplay(_INTL("{1} restored its health using its {2}!",battler.pbThis,itemName))
end
end
flavor_stat = [:ATTACK, :DEFENSE, :SPEED, :SPECIAL_ATTACK, :SPECIAL_DEFENSE][flavor]
battler.nature.stat_changes.each do |change|
next if change[1] > 0 || change[0] != flavor_stat
battle.pbDisplay(confuseMsg)
battler.pbConfuse if battler.pbCanConfuseSelf?(false)
break
end
return true
end
def pbBattleStatIncreasingBerry(battler,battle,item,forced,stat,increment=1)
return false if !forced && !battler.canConsumePinchBerry?
return false if !battler.pbCanRaiseStatStage?(stat,battler)
itemName = GameData::Item.get(item).name
ripening = false
if battler.hasActiveAbility?(:RIPEN)
battle.pbShowAbilitySplash(battler, forced)
increment *= 2
ripening = true
end
battle.pbCommonAnimation("EatBerry", battler) if !forced
battle.pbHideAbilitySplash(battler) if ripening
return battler.pbRaiseStatStageByCause(stat, increment, battler, itemName) if !forced
PBDebug.log("[Item triggered] Forced consuming of #{itemName}")
return battler.pbRaiseStatStage(stat, increment, battler)
end
# For abilities that grant immunity to moves of a particular type, and raises
# one of the ability's bearer's stats instead.
def pbBattleMoveImmunityStatAbility(user, target, move, moveType, immuneType,
stat, increment, battle, show_message)
return false if user.index==target.index
return false if moveType != immuneType
# NOTE: If show_message is false (Dragon Darts only), the stat will not be
# raised. This is not how the official games work, but I'm considering
# that a bug because Dragon Darts won't be fired at target in the first
# place if it's immune, so why would this ability be triggered by them?
if show_message
battle.pbShowAbilitySplash(target)
if target.pbCanRaiseStatStage?(stat, target)
if Battle::Scene::USE_ABILITY_SPLASH
target.pbRaiseStatStage(stat, increment, target)
else
target.pbRaiseStatStageByCause(stat, increment, target, target.abilityName)
end
else
if Battle::Scene::USE_ABILITY_SPLASH
battle.pbDisplay(_INTL("It doesn't affect {1}...", target.pbThis(true)))
else
battle.pbDisplay(_INTL("{1}'s {2} made {3} ineffective!",
target.pbThis, target.abilityName, move.name))
end
end
battle.pbHideAbilitySplash(target)
end
return true
end
# For abilities that grant immunity to moves of a particular type, and heals the
# ability's bearer by 1/4 of its total HP instead.
def pbBattleMoveImmunityHealAbility(user, target, move, moveType, immuneType, battle, show_message)
return false if user.index==target.index
return false if moveType != immuneType
# NOTE: If show_message is false (Dragon Darts only), HP will not be healed.
# This is not how the official games work, but I'm considering that a
# bug because Dragon Darts won't be fired at target in the first place
# if it's immune, so why would this ability be triggered by them?
if show_message
battle.pbShowAbilitySplash(target)
if target.canHeal? && target.pbRecoverHP(target.totalhp / 4) > 0
if Battle::Scene::USE_ABILITY_SPLASH
battle.pbDisplay(_INTL("{1}'s HP was restored.", target.pbThis))
else
battle.pbDisplay(_INTL("{1}'s {2} restored its HP.", target.pbThis, target.abilityName))
end
else
if Battle::Scene::USE_ABILITY_SPLASH
battle.pbDisplay(_INTL("It doesn't affect {1}...", target.pbThis(true)))
else
battle.pbDisplay(_INTL("{1}'s {2} made {3} ineffective!",
target.pbThis, target.abilityName, move.name))
end
end
battle.pbHideAbilitySplash(target)
end
return true
end
def pbBattleGem(user,type,move,mults,moveType)
# Pledge moves never consume Gems
return if move.is_a?(Battle::Move::PledgeMove)
return if moveType != type
user.effects[PBEffects::GemConsumed] = user.item_id
if Settings::MECHANICS_GENERATION >= 6
mults[:base_damage_multiplier] *= 1.3
else
mults[:base_damage_multiplier] *= 1.5
end
end
def pbBattleTypeWeakingBerry(type,moveType,target,mults)
return if moveType != type
return if !Effectiveness.super_effective?(target.damageState.typeMod) && moveType != :NORMAL
mults[:final_damage_multiplier] /= 2
target.damageState.berryWeakened = true
ripening = false
if target.hasActiveAbility?(:RIPEN)
target.battle.pbShowAbilitySplash(target)
mults[:final_damage_multiplier] /= 2
ripening = true
end
target.battle.pbCommonAnimation("EatBerry",target)
target.battle.pbHideAbilitySplash(target) if ripening
end
def pbBattleWeatherAbility(weather,battler,battle,ignorePrimal=false)
return if !ignorePrimal && [:HarshSun, :HeavyRain, :StrongWinds].include?(battle.field.weather)
return if battle.field.weather==weather
battle.pbShowAbilitySplash(battler)
if !Battle::Scene::USE_ABILITY_SPLASH
battle.pbDisplay(_INTL("{1}'s {2} activated!",battler.pbThis,battler.abilityName))
end
fixedDuration = false
fixedDuration = true if Settings::FIXED_DURATION_WEATHER_FROM_ABILITY &&
![:HarshSun, :HeavyRain, :StrongWinds].include?(weather)
battle.pbStartWeather(battler,weather,fixedDuration)
# NOTE: The ability splash is hidden again in def pbStartWeather.
end

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,198 @@
#===============================================================================
#
#===============================================================================
module BallHandlers
IsUnconditional = ItemHandlerHash.new
ModifyCatchRate = ItemHandlerHash.new
OnCatch = ItemHandlerHash.new
OnFailCatch = ItemHandlerHash.new
def self.isUnconditional?(ball,battle,battler)
ret = IsUnconditional.trigger(ball,battle,battler)
return (ret!=nil) ? ret : false
end
def self.modifyCatchRate(ball,catchRate,battle,battler,ultraBeast)
ret = ModifyCatchRate.trigger(ball,catchRate,battle,battler,ultraBeast)
return (ret!=nil) ? ret : catchRate
end
def self.onCatch(ball,battle,pkmn)
OnCatch.trigger(ball,battle,pkmn)
end
def self.onFailCatch(ball,battle,battler)
$stats.failed_poke_ball_count += 1
OnFailCatch.trigger(ball,battle,battler)
end
end
#===============================================================================
# IsUnconditional
#===============================================================================
BallHandlers::IsUnconditional.add(:MASTERBALL,proc { |ball,battle,battler|
next true
})
#===============================================================================
# ModifyCatchRate
# NOTE: This code is not called if the battler is an Ultra Beast (except if the
# Ball is a Beast Ball). In this case, all Balls' catch rates are set
# elsewhere to 0.1x.
#===============================================================================
BallHandlers::ModifyCatchRate.add(:GREATBALL,proc { |ball,catchRate,battle,battler,ultraBeast|
next catchRate*1.5
})
BallHandlers::ModifyCatchRate.add(:ULTRABALL,proc { |ball,catchRate,battle,battler,ultraBeast|
next catchRate*2
})
BallHandlers::ModifyCatchRate.add(:SAFARIBALL,proc { |ball,catchRate,battle,battler,ultraBeast|
next catchRate*1.5
})
BallHandlers::ModifyCatchRate.add(:NETBALL,proc { |ball,catchRate,battle,battler,ultraBeast|
multiplier = (Settings::NEW_POKE_BALL_CATCH_RATES) ? 3.5 : 3
catchRate *= multiplier if battler.pbHasType?(:BUG) || battler.pbHasType?(:WATER)
next catchRate
})
BallHandlers::ModifyCatchRate.add(:DIVEBALL,proc { |ball,catchRate,battle,battler,ultraBeast|
catchRate *= 3.5 if battle.environment == :Underwater
next catchRate
})
BallHandlers::ModifyCatchRate.add(:NESTBALL,proc { |ball,catchRate,battle,battler,ultraBeast|
if battler.level <= 30
catchRate *= [(41 - battler.level) / 10.0, 1].max
end
next catchRate
})
BallHandlers::ModifyCatchRate.add(:REPEATBALL,proc { |ball,catchRate,battle,battler,ultraBeast|
multiplier = (Settings::NEW_POKE_BALL_CATCH_RATES) ? 3.5 : 3
catchRate *= multiplier if battle.pbPlayer.owned?(battler.species)
next catchRate
})
BallHandlers::ModifyCatchRate.add(:TIMERBALL,proc { |ball,catchRate,battle,battler,ultraBeast|
multiplier = [1+(0.3*battle.turnCount),4].min
catchRate *= multiplier
next catchRate
})
BallHandlers::ModifyCatchRate.add(:DUSKBALL,proc { |ball,catchRate,battle,battler,ultraBeast|
multiplier = (Settings::NEW_POKE_BALL_CATCH_RATES) ? 3 : 3.5
catchRate *= multiplier if battle.time==2
next catchRate
})
BallHandlers::ModifyCatchRate.add(:QUICKBALL,proc { |ball,catchRate,battle,battler,ultraBeast|
catchRate *= 5 if battle.turnCount==0
next catchRate
})
BallHandlers::ModifyCatchRate.add(:FASTBALL,proc { |ball,catchRate,battle,battler,ultraBeast|
baseStats = battler.pokemon.baseStats
baseSpeed = baseStats[:SPEED]
catchRate *= 4 if baseSpeed >= 100
next [catchRate, 255].min
})
BallHandlers::ModifyCatchRate.add(:LEVELBALL,proc { |ball,catchRate,battle,battler,ultraBeast|
maxlevel = 0
battle.allSameSideBattlers.each { |b| maxlevel = b.level if b.level > maxlevel }
if maxlevel >= battler.level * 4
catchRate *= 8
elsif maxlevel >= battler.level * 2
catchRate *= 4
elsif maxlevel > battler.level
catchRate *= 2
end
next [catchRate,255].min
})
BallHandlers::ModifyCatchRate.add(:LUREBALL,proc { |ball,catchRate,battle,battler,ultraBeast|
multiplier = (Settings::NEW_POKE_BALL_CATCH_RATES) ? 5 : 3
catchRate *= multiplier if GameData::EncounterType.get($game_temp.encounter_type).type == :fishing
next [catchRate,255].min
})
BallHandlers::ModifyCatchRate.add(:HEAVYBALL,proc { |ball,catchRate,battle,battler,ultraBeast|
next 0 if catchRate==0
weight = battler.pokemon.species_data.base_stats[:SPEED]
if Settings::NEW_POKE_BALL_CATCH_RATES
if weight >= 3000
catchRate += 30
elsif weight >= 2000
catchRate += 20
elsif weight < 1000
catchRate -= 20
end
else
if weight >= 4096
catchRate += 40
elsif weight >= 3072
catchRate += 30
elsif weight >= 2048
catchRate += 20
else
catchRate -= 20
end
end
catchRate = [catchRate,1].max
next [catchRate,255].min
})
BallHandlers::ModifyCatchRate.add(:LOVEBALL,proc { |ball,catchRate,battle,battler,ultraBeast|
battle.allSameSideBattlers.each do |b|
next if b.species!=battler.species
next if b.gender==battler.gender || b.gender==2 || battler.gender==2
catchRate *= 8
break
end
next [catchRate,255].min
})
BallHandlers::ModifyCatchRate.add(:MOONBALL,proc { |ball,catchRate,battle,battler,ultraBeast|
# NOTE: Moon Ball cares about whether any species in the target's evolutionary
# family can evolve with the Moon Stone, not whether the target itself
# can immediately evolve with the Moon Stone.
moon_stone = GameData::Item.try_get(:MOONSTONE)
if moon_stone && battler.pokemon.species_data.family_item_evolutions_use_item?(moon_stone.id)
catchRate *= 4
end
next [catchRate, 255].min
})
BallHandlers::ModifyCatchRate.add(:SPORTBALL,proc { |ball,catchRate,battle,battler,ultraBeast|
next catchRate*1.5
})
BallHandlers::ModifyCatchRate.add(:DREAMBALL,proc { |ball,catchRate,battle,battler,ultraBeast|
catchRate *= 4 if battler.asleep?
next catchRate
})
BallHandlers::ModifyCatchRate.add(:BEASTBALL,proc { |ball,catchRate,battle,battler,ultraBeast|
if ultraBeast
catchRate *= 5
else
catchRate /= 10
end
next catchRate
})
#===============================================================================
# OnCatch
#===============================================================================
BallHandlers::OnCatch.add(:HEALBALL,proc { |ball,battle,pkmn|
pkmn.heal
})
BallHandlers::OnCatch.add(:FRIENDBALL,proc { |ball,battle,pkmn|
pkmn.happiness = 200
})