mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
351 lines
14 KiB
Ruby
351 lines
14 KiB
Ruby
class PokeBattle_Move
|
|
#=============================================================================
|
|
# Effect methods per move usage
|
|
#=============================================================================
|
|
def pbCanChooseMove?(user,commandPhase,showMessages); return true; end # For Belch
|
|
def pbDisplayChargeMessage(user); end # For Focus Punch/shell Trap/Beak Blast
|
|
def pbOnStartUse(user,targets); end
|
|
def pbAddTarget(targets,user); end # For Counter, etc. and Bide
|
|
|
|
# Reset move usage counters (child classes can increment them).
|
|
def pbChangeUsageCounters(user,specialUsage)
|
|
user.effects[PBEffects::FuryCutter] = 0
|
|
user.effects[PBEffects::ParentalBond] = 0
|
|
user.effects[PBEffects::ProtectRate] = 1
|
|
@battle.field.effects[PBEffects::FusionBolt] = false
|
|
@battle.field.effects[PBEffects::FusionFlare] = false
|
|
end
|
|
|
|
def pbDisplayUseMessage(user)
|
|
@battle.pbDisplayBrief(_INTL("{1} used {2}!",user.pbThis,@name))
|
|
end
|
|
|
|
def pbMissMessage(user,target); return false; end
|
|
|
|
#=============================================================================
|
|
#
|
|
#=============================================================================
|
|
# Whether the move is currently in the "charging" turn of a two turn attack.
|
|
# Is false if Power Herb or another effect lets a two turn move charge and
|
|
# attack in the same turn.
|
|
# user.effects[PBEffects::TwoTurnAttack] is set to the move's ID during the
|
|
# charging turn, and is 0 during the attack turn.
|
|
def pbIsChargingTurn?(user); return false; end
|
|
def pbDamagingMove?; return damagingMove?; end
|
|
|
|
def pbContactMove?(user)
|
|
return false if user.hasActiveAbility?(:LONGREACH)
|
|
return contactMove?
|
|
end
|
|
|
|
# The maximum number of hits in a round this move will actually perform. This
|
|
# can be 1 for Beat Up, and can be 2 for any moves affected by Parental Bond.
|
|
def pbNumHits(user,targets)
|
|
if user.hasActiveAbility?(:PARENTALBOND) && pbDamagingMove? &&
|
|
!chargingTurnMove? && targets.length==1
|
|
# Record that Parental Bond applies, to weaken the second attack
|
|
user.effects[PBEffects::ParentalBond] = 3
|
|
return 2
|
|
end
|
|
return 1
|
|
end
|
|
|
|
#=============================================================================
|
|
# Effect methods per hit
|
|
#=============================================================================
|
|
def pbOverrideSuccessCheckPerHit(user,target); return false; end
|
|
def pbCrashDamage(user); end
|
|
def pbInitialEffect(user,targets,hitNum); end
|
|
|
|
def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true)
|
|
return if !showAnimation
|
|
if user.effects[PBEffects::ParentalBond]==1
|
|
@battle.pbCommonAnimation("ParentalBond",user,targets)
|
|
else
|
|
@battle.pbAnimation(id,user,targets,hitNum)
|
|
end
|
|
end
|
|
|
|
def pbSelfKO(user); end
|
|
def pbEffectWhenDealingDamage(user,target); end
|
|
def pbEffectAgainstTarget(user,target); end
|
|
def pbEffectGeneral(user); end
|
|
def pbAdditionalEffect(user,target); end
|
|
def pbEffectAfterAllHits(user,target); end # Move effects that occur after all hits
|
|
def pbSwitchOutTargetsEffect(user,targets,numHits,switchedBattlers); end
|
|
def pbEndOfMoveUsageEffect(user,targets,numHits,switchedBattlers); end
|
|
|
|
#=============================================================================
|
|
# Check if target is immune to the move because of its ability
|
|
#=============================================================================
|
|
def pbImmunityByAbility(user,target)
|
|
return false if @battle.moldBreaker
|
|
ret = false
|
|
if target.abilityActive?
|
|
ret = BattleHandlers.triggerMoveImmunityTargetAbility(target.ability,
|
|
user,target,self,@calcType,@battle)
|
|
end
|
|
return ret
|
|
end
|
|
|
|
#=============================================================================
|
|
# Move failure checks
|
|
#=============================================================================
|
|
# Check whether the move fails completely due to move-specific requirements.
|
|
def pbMoveFailed?(user,targets); return false; end
|
|
# Checks whether the move will be ineffective against the target.
|
|
def pbFailsAgainstTarget?(user,target); return false; end
|
|
|
|
def pbMoveFailedLastInRound?(user)
|
|
unmoved = false
|
|
@battle.eachBattler do |b|
|
|
next if b.index==user.index
|
|
next if @battle.choices[b.index][0]!=:UseMove && @battle.choices[b.index][0]!=:Shift
|
|
next if b.movedThisRound?
|
|
unmoved = true
|
|
break
|
|
end
|
|
if !unmoved
|
|
@battle.pbDisplay(_INTL("But it failed!"))
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
def pbMoveFailedTargetAlreadyMoved?(target)
|
|
if (@battle.choices[target.index][0]!=:UseMove &&
|
|
@battle.choices[target.index][0]!=:Shift) || target.movedThisRound?
|
|
@battle.pbDisplay(_INTL("But it failed!"))
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
def pbMoveFailedAromaVeil?(user,target,showMessage=true)
|
|
return false if @battle.moldBreaker
|
|
if target.hasActiveAbility?(:AROMAVEIL)
|
|
if showMessage
|
|
@battle.pbShowAbilitySplash(target)
|
|
if PokeBattle_SceneConstants::USE_ABILITY_SPLASH
|
|
@battle.pbDisplay(_INTL("{1} is unaffected!",target.pbThis))
|
|
else
|
|
@battle.pbDisplay(_INTL("{1} is unaffected because of its {2}!",
|
|
target.pbThis,target.abilityName))
|
|
end
|
|
@battle.pbHideAbilitySplash(target)
|
|
end
|
|
return true
|
|
end
|
|
target.eachAlly do |b|
|
|
next if !b.hasActiveAbility?(:AROMAVEIL)
|
|
if showMessage
|
|
@battle.pbShowAbilitySplash(target)
|
|
if PokeBattle_SceneConstants::USE_ABILITY_SPLASH
|
|
@battle.pbDisplay(_INTL("{1} is unaffected!",target.pbThis))
|
|
else
|
|
@battle.pbDisplay(_INTL("{1} is unaffected because of {2}'s {3}!",
|
|
target.pbThis,b.pbThis(true),b.abilityName))
|
|
end
|
|
@battle.pbHideAbilitySplash(target)
|
|
end
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
#=============================================================================
|
|
# Weaken the damage dealt (doesn't actually change a battler's HP)
|
|
#=============================================================================
|
|
def pbCheckDamageAbsorption(user,target)
|
|
# Substitute will take the damage
|
|
if target.effects[PBEffects::Substitute]>0 && !ignoresSubstitute?(user) &&
|
|
(!user || user.index!=target.index)
|
|
target.damageState.substitute = true
|
|
return
|
|
end
|
|
# Disguise will take the damage
|
|
if !@battle.moldBreaker && target.isSpecies?(:MIMIKYU) &&
|
|
target.form==0 && target.ability == :DISGUISE
|
|
target.damageState.disguise = true
|
|
return
|
|
end
|
|
end
|
|
|
|
def pbReduceDamage(user,target)
|
|
damage = target.damageState.calcDamage
|
|
# Substitute takes the damage
|
|
if target.damageState.substitute
|
|
damage = target.effects[PBEffects::Substitute] if damage>target.effects[PBEffects::Substitute]
|
|
target.damageState.hpLost = damage
|
|
target.damageState.totalHPLost += damage
|
|
return
|
|
end
|
|
# Disguise takes the damage
|
|
return if target.damageState.disguise
|
|
# Target takes the damage
|
|
if damage>=target.hp
|
|
damage = target.hp
|
|
# Survive a lethal hit with 1 HP effects
|
|
if nonLethal?(user,target)
|
|
damage -= 1
|
|
elsif target.effects[PBEffects::Endure]
|
|
target.damageState.endured = true
|
|
damage -= 1
|
|
elsif damage==target.totalhp
|
|
if target.hasActiveAbility?(:STURDY) && !@battle.moldBreaker
|
|
target.damageState.sturdy = true
|
|
damage -= 1
|
|
elsif target.hasActiveItem?(:FOCUSSASH) && target.hp==target.totalhp
|
|
target.damageState.focusSash = true
|
|
damage -= 1
|
|
elsif target.hasActiveItem?(:FOCUSBAND) && @battle.pbRandom(100)<10
|
|
target.damageState.focusBand = true
|
|
damage -= 1
|
|
end
|
|
end
|
|
end
|
|
damage = 0 if damage<0
|
|
target.damageState.hpLost = damage
|
|
target.damageState.totalHPLost += damage
|
|
end
|
|
|
|
#=============================================================================
|
|
# Change the target's HP by the amount calculated above
|
|
#=============================================================================
|
|
def pbInflictHPDamage(target)
|
|
if target.damageState.substitute
|
|
target.effects[PBEffects::Substitute] -= target.damageState.hpLost
|
|
else
|
|
target.hp -= target.damageState.hpLost
|
|
end
|
|
end
|
|
|
|
#=============================================================================
|
|
# Animate the damage dealt, including lowering the HP
|
|
#=============================================================================
|
|
# Animate being damaged and losing HP (by a move)
|
|
def pbAnimateHitAndHPLost(user,targets)
|
|
# Animate allies first, then foes
|
|
animArray = []
|
|
for side in 0...2 # side here means "allies first, then foes"
|
|
targets.each do |b|
|
|
next if b.damageState.unaffected || b.damageState.hpLost==0
|
|
next if (side==0 && b.opposes?(user)) || (side==1 && !b.opposes?(user))
|
|
oldHP = b.hp+b.damageState.hpLost
|
|
PBDebug.log("[Move damage] #{b.pbThis} lost #{b.damageState.hpLost} HP (#{oldHP}=>#{b.hp})")
|
|
effectiveness = 0
|
|
if PBTypes.resistant?(b.damageState.typeMod); effectiveness = 1
|
|
elsif PBTypes.superEffective?(b.damageState.typeMod); effectiveness = 2
|
|
end
|
|
animArray.push([b,oldHP,effectiveness])
|
|
end
|
|
if animArray.length>0
|
|
@battle.scene.pbHitAndHPLossAnimation(animArray)
|
|
animArray.clear
|
|
end
|
|
end
|
|
end
|
|
|
|
#=============================================================================
|
|
# Messages upon being hit
|
|
#=============================================================================
|
|
def pbEffectivenessMessage(user,target,numTargets=1)
|
|
return if target.damageState.disguise
|
|
if PBTypes.superEffective?(target.damageState.typeMod)
|
|
if numTargets>1
|
|
@battle.pbDisplay(_INTL("It's super effective on {1}!",target.pbThis(true)))
|
|
else
|
|
@battle.pbDisplay(_INTL("It's super effective!"))
|
|
end
|
|
elsif PBTypes.notVeryEffective?(target.damageState.typeMod)
|
|
if numTargets>1
|
|
@battle.pbDisplay(_INTL("It's not very effective on {1}...",target.pbThis(true)))
|
|
else
|
|
@battle.pbDisplay(_INTL("It's not very effective..."))
|
|
end
|
|
end
|
|
end
|
|
|
|
def pbHitEffectivenessMessages(user,target,numTargets=1)
|
|
return if target.damageState.disguise
|
|
if target.damageState.substitute
|
|
@battle.pbDisplay(_INTL("The substitute took damage for {1}!",target.pbThis(true)))
|
|
end
|
|
if target.damageState.critical
|
|
if numTargets>1
|
|
@battle.pbDisplay(_INTL("A critical hit on {1}!",target.pbThis(true)))
|
|
else
|
|
@battle.pbDisplay(_INTL("A critical hit!"))
|
|
end
|
|
end
|
|
# Effectiveness message, for moves with 1 hit
|
|
if !multiHitMove? && user.effects[PBEffects::ParentalBond]==0
|
|
pbEffectivenessMessage(user,target,numTargets)
|
|
end
|
|
if target.damageState.substitute && target.effects[PBEffects::Substitute]==0
|
|
target.effects[PBEffects::Substitute] = 0
|
|
@battle.pbDisplay(_INTL("{1}'s substitute faded!",target.pbThis))
|
|
end
|
|
end
|
|
|
|
def pbEndureKOMessage(target)
|
|
if target.damageState.disguise
|
|
@battle.pbShowAbilitySplash(target)
|
|
if PokeBattle_SceneConstants::USE_ABILITY_SPLASH
|
|
@battle.pbDisplay(_INTL("Its disguise served it as a decoy!"))
|
|
else
|
|
@battle.pbDisplay(_INTL("{1}'s disguise served it as a decoy!",target.pbThis))
|
|
end
|
|
@battle.pbHideAbilitySplash(target)
|
|
target.pbChangeForm(1,_INTL("{1}'s disguise was busted!",target.pbThis))
|
|
elsif target.damageState.endured
|
|
@battle.pbDisplay(_INTL("{1} endured the hit!",target.pbThis))
|
|
elsif target.damageState.sturdy
|
|
@battle.pbShowAbilitySplash(target)
|
|
if PokeBattle_SceneConstants::USE_ABILITY_SPLASH
|
|
@battle.pbDisplay(_INTL("{1} endured the hit!",target.pbThis))
|
|
else
|
|
@battle.pbDisplay(_INTL("{1} hung on with Sturdy!",target.pbThis))
|
|
end
|
|
@battle.pbHideAbilitySplash(target)
|
|
elsif target.damageState.focusSash
|
|
@battle.pbCommonAnimation("UseItem",target)
|
|
@battle.pbDisplay(_INTL("{1} hung on using its Focus Sash!",target.pbThis))
|
|
target.pbConsumeItem
|
|
elsif target.damageState.focusBand
|
|
@battle.pbCommonAnimation("UseItem",target)
|
|
@battle.pbDisplay(_INTL("{1} hung on using its Focus Band!",target.pbThis))
|
|
end
|
|
end
|
|
|
|
# Used by Counter/Mirror Coat/Metal Burst/Revenge/Focus Punch/Bide/Assurance.
|
|
def pbRecordDamageLost(user,target)
|
|
damage = target.damageState.hpLost
|
|
# NOTE: In Gen 3 where a move's category depends on its type, Hidden Power
|
|
# is for some reason countered by Counter rather than Mirror Coat,
|
|
# regardless of its calculated type. Hence the following two lines of
|
|
# code.
|
|
moveType = nil
|
|
moveType = getID(PBTypes,:NORMAL) if @function=="090" # Hidden Power
|
|
if physicalMove?(moveType)
|
|
target.effects[PBEffects::Counter] = damage
|
|
target.effects[PBEffects::CounterTarget] = user.index
|
|
elsif specialMove?(moveType)
|
|
target.effects[PBEffects::MirrorCoat] = damage
|
|
target.effects[PBEffects::MirrorCoatTarget] = user.index
|
|
end
|
|
if target.effects[PBEffects::Bide]>0
|
|
target.effects[PBEffects::BideDamage] += damage
|
|
target.effects[PBEffects::BideTarget] = user.index
|
|
end
|
|
target.damageState.fainted = true if target.fainted?
|
|
target.lastHPLost = damage # For Focus Punch
|
|
target.tookDamage = true if damage>0 # For Assurance
|
|
target.lastAttacker.push(user.index) # For Revenge
|
|
if target.opposes?(user)
|
|
target.lastHPLostFromFoe = damage # For Metal Burst
|
|
target.lastFoeAttacker.push(user.index) # For Metal Burst
|
|
end
|
|
end
|
|
end
|