mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
3206 lines
113 KiB
Ruby
3206 lines
113 KiB
Ruby
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
module Battle::AbilityEffects
|
|
SpeedCalc = AbilityHandlerHash.new
|
|
WeightCalc = AbilityHandlerHash.new
|
|
# Battler's HP/stat changed
|
|
OnHPDroppedBelowHalf = AbilityHandlerHash.new
|
|
# Battler's status problem
|
|
StatusCheckNonIgnorable = AbilityHandlerHash.new # Comatose
|
|
StatusImmunity = AbilityHandlerHash.new
|
|
StatusImmunityNonIgnorable = AbilityHandlerHash.new
|
|
StatusImmunityFromAlly = AbilityHandlerHash.new
|
|
OnStatusInflicted = AbilityHandlerHash.new # Synchronize
|
|
StatusCure = AbilityHandlerHash.new
|
|
# Battler's stat stages
|
|
StatLossImmunity = AbilityHandlerHash.new
|
|
StatLossImmunityNonIgnorable = AbilityHandlerHash.new # Full Metal Body
|
|
StatLossImmunityFromAlly = AbilityHandlerHash.new # Flower Veil
|
|
OnStatGain = AbilityHandlerHash.new # None!
|
|
OnStatLoss = AbilityHandlerHash.new
|
|
# Priority and turn order
|
|
PriorityChange = AbilityHandlerHash.new
|
|
PriorityBracketChange = AbilityHandlerHash.new # Stall
|
|
PriorityBracketUse = AbilityHandlerHash.new # None!
|
|
# Move usage failures
|
|
OnFlinch = AbilityHandlerHash.new # Steadfast
|
|
MoveBlocking = AbilityHandlerHash.new
|
|
MoveImmunity = AbilityHandlerHash.new
|
|
# Move usage
|
|
ModifyMoveBaseType = AbilityHandlerHash.new
|
|
# Accuracy calculation
|
|
AccuracyCalcFromUser = AbilityHandlerHash.new
|
|
AccuracyCalcFromAlly = AbilityHandlerHash.new # Victory Star
|
|
AccuracyCalcFromTarget = AbilityHandlerHash.new
|
|
# Damage calculation
|
|
DamageCalcFromUser = AbilityHandlerHash.new
|
|
DamageCalcFromAlly = AbilityHandlerHash.new
|
|
DamageCalcFromTarget = AbilityHandlerHash.new
|
|
DamageCalcFromTargetNonIgnorable = AbilityHandlerHash.new
|
|
DamageCalcFromTargetAlly = AbilityHandlerHash.new
|
|
CriticalCalcFromUser = AbilityHandlerHash.new
|
|
CriticalCalcFromTarget = AbilityHandlerHash.new
|
|
# Upon a move hitting a target
|
|
OnBeingHit = AbilityHandlerHash.new
|
|
OnDealingHit = AbilityHandlerHash.new # Poison Touch
|
|
# Abilities that trigger at the end of using a move
|
|
OnEndOfUsingMove = AbilityHandlerHash.new
|
|
AfterMoveUseFromTarget = AbilityHandlerHash.new
|
|
# End Of Round
|
|
EndOfRoundWeather = AbilityHandlerHash.new
|
|
EndOfRoundHealing = AbilityHandlerHash.new
|
|
EndOfRoundEffect = AbilityHandlerHash.new
|
|
EndOfRoundGainItem = AbilityHandlerHash.new
|
|
# Switching and fainting
|
|
CertainSwitching = AbilityHandlerHash.new # None!
|
|
TrappingByTarget = AbilityHandlerHash.new
|
|
OnSwitchIn = AbilityHandlerHash.new
|
|
OnSwitchOut = AbilityHandlerHash.new
|
|
ChangeOnBattlerFainting = AbilityHandlerHash.new
|
|
OnBattlerFainting = AbilityHandlerHash.new # Soul-Heart
|
|
OnTerrainChange = AbilityHandlerHash.new # Mimicry
|
|
OnIntimidated = AbilityHandlerHash.new # Rattled (Gen 8)
|
|
# Running from battle
|
|
CertainEscapeFromBattle = AbilityHandlerHash.new # Run Away
|
|
|
|
#=============================================================================
|
|
|
|
def self.trigger(hash, *args, ret: false)
|
|
new_ret = hash.trigger(*args)
|
|
return (!new_ret.nil?) ? new_ret : ret
|
|
end
|
|
|
|
#=============================================================================
|
|
|
|
def self.triggerSpeedCalc(ability, battler, mult)
|
|
return trigger(SpeedCalc, ability, battler, mult, ret: mult)
|
|
end
|
|
|
|
def self.triggerWeightCalc(ability, battler, weight)
|
|
return trigger(WeightCalc, ability, battler, weight, ret: weight)
|
|
end
|
|
|
|
#=============================================================================
|
|
|
|
def self.triggerOnHPDroppedBelowHalf(ability, user, move_user, battle)
|
|
return trigger(OnHPDroppedBelowHalf, ability, user, move_user, battle)
|
|
end
|
|
|
|
#=============================================================================
|
|
|
|
def self.triggerStatusCheckNonIgnorable(ability, battler, status)
|
|
return trigger(StatusCheckNonIgnorable, ability, battler, status)
|
|
end
|
|
|
|
def self.triggerStatusImmunity(ability, battler, status)
|
|
return trigger(StatusImmunity, ability, battler, status)
|
|
end
|
|
|
|
def self.triggerStatusImmunityNonIgnorable(ability, battler, status)
|
|
return trigger(StatusImmunityNonIgnorable, ability, battler, status)
|
|
end
|
|
|
|
def self.triggerStatusImmunityFromAlly(ability, battler, status)
|
|
return trigger(StatusImmunityFromAlly, ability, battler, status)
|
|
end
|
|
|
|
def self.triggerOnStatusInflicted(ability, battler, user, status)
|
|
OnStatusInflicted.trigger(ability, battler, user, status)
|
|
end
|
|
|
|
def self.triggerStatusCure(ability, battler)
|
|
return trigger(StatusCure, ability, battler)
|
|
end
|
|
|
|
#=============================================================================
|
|
|
|
def self.triggerStatLossImmunity(ability, battler, stat, battle, show_messages)
|
|
return trigger(StatLossImmunity, ability, battler, stat, battle, show_messages)
|
|
end
|
|
|
|
def self.triggerStatLossImmunityNonIgnorable(ability, battler, stat, battle, show_messages)
|
|
return trigger(StatLossImmunityNonIgnorable, ability, battler, stat, battle, show_messages)
|
|
end
|
|
|
|
def self.triggerStatLossImmunityFromAlly(ability, bearer, battler, stat, battle, show_messages)
|
|
return trigger(StatLossImmunityFromAlly, ability, bearer, battler, stat, battle, show_messages)
|
|
end
|
|
|
|
def self.triggerOnStatGain(ability, battler, stat, user)
|
|
OnStatGain.trigger(ability, battler, stat, user)
|
|
end
|
|
|
|
def self.triggerOnStatLoss(ability, battler, stat, user)
|
|
OnStatLoss.trigger(ability, battler, stat, user)
|
|
end
|
|
|
|
#=============================================================================
|
|
|
|
def self.triggerPriorityChange(ability, battler, move, priority)
|
|
return trigger(PriorityChange, ability, battler, move, priority, ret: priority)
|
|
end
|
|
|
|
def self.triggerPriorityBracketChange(ability, battler, battle)
|
|
return trigger(PriorityBracketChange, ability, battler, battle, ret: 0)
|
|
end
|
|
|
|
def self.triggerPriorityBracketUse(ability, battler, battle)
|
|
PriorityBracketUse.trigger(ability, battler, battle)
|
|
end
|
|
|
|
#=============================================================================
|
|
|
|
def self.triggerOnFlinch(ability, battler, battle)
|
|
OnFlinch.trigger(ability, battler, battle)
|
|
end
|
|
|
|
def self.triggerMoveBlocking(ability, bearer, user, targets, move, battle)
|
|
return trigger(MoveBlocking, ability, bearer, user, targets, move, battle)
|
|
end
|
|
|
|
def self.triggerMoveImmunity(ability, user, target, move, type, battle, show_message)
|
|
return trigger(MoveImmunity, ability, user, target, move, type, battle, show_message)
|
|
end
|
|
|
|
#=============================================================================
|
|
|
|
def self.triggerModifyMoveBaseType(ability, user, move, type)
|
|
return trigger(ModifyMoveBaseType, ability, user, move, type, ret: type)
|
|
end
|
|
|
|
#=============================================================================
|
|
|
|
def self.triggerAccuracyCalcFromUser(ability, mods, user, target, move, type)
|
|
AccuracyCalcFromUser.trigger(ability, mods, user, target, move, type)
|
|
end
|
|
|
|
def self.triggerAccuracyCalcFromAlly(ability, mods, user, target, move, type)
|
|
AccuracyCalcFromAlly.trigger(ability, mods, user, target, move, type)
|
|
end
|
|
|
|
def self.triggerAccuracyCalcFromTarget(ability, mods, user, target, move, type)
|
|
AccuracyCalcFromTarget.trigger(ability, mods, user, target, move, type)
|
|
end
|
|
|
|
#=============================================================================
|
|
|
|
def self.triggerDamageCalcFromUser(ability, user, target, move, mults, power, type)
|
|
DamageCalcFromUser.trigger(ability, user, target, move, mults, power, type)
|
|
end
|
|
|
|
def self.triggerDamageCalcFromAlly(ability, user, target, move, mults, power, type)
|
|
DamageCalcFromAlly.trigger(ability, user, target, move, mults, power, type)
|
|
end
|
|
|
|
def self.triggerDamageCalcFromTarget(ability, user, target, move, mults, power, type)
|
|
DamageCalcFromTarget.trigger(ability, user, target, move, mults, power, type)
|
|
end
|
|
|
|
def self.triggerDamageCalcFromTargetNonIgnorable(ability, user, target, move, mults, power, type)
|
|
DamageCalcFromTargetNonIgnorable.trigger(ability, user, target, move, mults, power, type)
|
|
end
|
|
|
|
def self.triggerDamageCalcFromTargetAlly(ability, user, target, move, mults, power, type)
|
|
DamageCalcFromTargetAlly.trigger(ability, user, target, move, mults, power, type)
|
|
end
|
|
|
|
def self.triggerCriticalCalcFromUser(ability, user, target, crit_stage)
|
|
return trigger(CriticalCalcFromUser, ability, user, target, crit_stage, ret: crit_stage)
|
|
end
|
|
|
|
def self.triggerCriticalCalcFromTarget(ability, user, target, crit_stage)
|
|
return trigger(CriticalCalcFromTarget, ability, user, target, crit_stage, ret: crit_stage)
|
|
end
|
|
|
|
#=============================================================================
|
|
|
|
def self.triggerOnBeingHit(ability, user, target, move, battle)
|
|
OnBeingHit.trigger(ability, user, target, move, battle)
|
|
end
|
|
|
|
def self.triggerOnDealingHit(ability, user, target, move, battle)
|
|
OnDealingHit.trigger(ability, user, target, move, battle)
|
|
end
|
|
|
|
#=============================================================================
|
|
|
|
def self.triggerOnEndOfUsingMove(ability, user, targets, move, battle)
|
|
OnEndOfUsingMove.trigger(ability, user, targets, move, battle)
|
|
end
|
|
|
|
def self.triggerAfterMoveUseFromTarget(ability, target, user, move, switched_battlers, battle)
|
|
AfterMoveUseFromTarget.trigger(ability, target, user, move, switched_battlers, battle)
|
|
end
|
|
|
|
#=============================================================================
|
|
|
|
def self.triggerEndOfRoundWeather(ability, weather, battler, battle)
|
|
EndOfRoundWeather.trigger(ability, weather, battler, battle)
|
|
end
|
|
|
|
def self.triggerEndOfRoundHealing(ability, battler, battle)
|
|
EndOfRoundHealing.trigger(ability, battler, battle)
|
|
end
|
|
|
|
def self.triggerEndOfRoundEffect(ability, battler, battle)
|
|
EndOfRoundEffect.trigger(ability, battler, battle)
|
|
end
|
|
|
|
def self.triggerEndOfRoundGainItem(ability, battler, battle)
|
|
EndOfRoundGainItem.trigger(ability, battler, battle)
|
|
end
|
|
|
|
#=============================================================================
|
|
|
|
def self.triggerCertainSwitching(ability, switcher, battle)
|
|
return trigger(CertainSwitching, ability, switcher, battle)
|
|
end
|
|
|
|
def self.triggerTrappingByTarget(ability, switcher, bearer, battle)
|
|
return trigger(TrappingByTarget, ability, switcher, bearer, battle)
|
|
end
|
|
|
|
def self.triggerOnSwitchIn(ability, battler, battle, switch_in = false)
|
|
OnSwitchIn.trigger(ability, battler, battle, switch_in)
|
|
end
|
|
|
|
def self.triggerOnSwitchOut(ability, battler, end_of_battle)
|
|
OnSwitchOut.trigger(ability, battler, end_of_battle)
|
|
end
|
|
|
|
def self.triggerChangeOnBattlerFainting(ability, battler, fainted, battle)
|
|
ChangeOnBattlerFainting.trigger(ability, battler, fainted, battle)
|
|
end
|
|
|
|
def self.triggerOnBattlerFainting(ability, battler, fainted, battle)
|
|
OnBattlerFainting.trigger(ability, battler, fainted, battle)
|
|
end
|
|
|
|
def self.triggerOnTerrainChange(ability, battler, battle, ability_changed)
|
|
OnTerrainChange.trigger(ability, battler, battle, ability_changed)
|
|
end
|
|
|
|
def self.triggerOnIntimidated(ability, battler, battle)
|
|
OnIntimidated.trigger(ability, battler, battle)
|
|
end
|
|
|
|
#=============================================================================
|
|
|
|
def self.triggerCertainEscapeFromBattle(ability, battler)
|
|
return trigger(CertainEscapeFromBattle, ability, battler)
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
# SpeedCalc handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::SpeedCalc.add(:CHLOROPHYLL,
|
|
proc { |ability, battler, mult|
|
|
next mult * 2 if [:Sun, :HarshSun].include?(battler.effectiveWeather)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::SpeedCalc.add(:QUICKFEET,
|
|
proc { |ability, battler, mult|
|
|
next mult * 1.5 if battler.pbHasAnyStatus?
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::SpeedCalc.add(:SANDRUSH,
|
|
proc { |ability, battler, mult|
|
|
next mult * 2 if [:Sandstorm].include?(battler.effectiveWeather)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::SpeedCalc.add(:SLOWSTART,
|
|
proc { |ability, battler, mult|
|
|
next mult / 2 if battler.effects[PBEffects::SlowStart] > 0
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::SpeedCalc.add(:SLUSHRUSH,
|
|
proc { |ability, battler, mult|
|
|
next mult * 2 if [:Hail].include?(battler.effectiveWeather)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::SpeedCalc.add(:SURGESURFER,
|
|
proc { |ability, battler, mult|
|
|
next mult * 2 if battler.battle.field.terrain == :Electric
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::SpeedCalc.add(:SWIFTSWIM,
|
|
proc { |ability, battler, mult|
|
|
next mult * 2 if [:Rain, :HeavyRain].include?(battler.effectiveWeather)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::SpeedCalc.add(:UNBURDEN,
|
|
proc { |ability, battler, mult|
|
|
next mult * 2 if battler.effects[PBEffects::Unburden] && !battler.item
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# WeightCalcy handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::WeightCalc.add(:HEAVYMETAL,
|
|
proc { |ability, battler, w|
|
|
next w * 2
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::WeightCalc.add(:LIGHTMETAL,
|
|
proc { |ability, battler, w|
|
|
next [w / 2, 1].max
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# OnHPDroppedBelowHalf handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::OnHPDroppedBelowHalf.add(:EMERGENCYEXIT,
|
|
proc { |ability, battler, move_user, battle|
|
|
next false if battler.effects[PBEffects::SkyDrop] >= 0 ||
|
|
battler.inTwoTurnAttack?("TwoTurnAttackInvulnerableInSkyTargetCannotAct") # Sky Drop
|
|
# In wild battles
|
|
if battle.wildBattle?
|
|
next false if battler.opposes? && battle.pbSideBattlerCount(battler.index) > 1
|
|
next false if !battle.pbCanRun?(battler.index)
|
|
battle.pbShowAbilitySplash(battler, true)
|
|
battle.pbHideAbilitySplash(battler)
|
|
pbSEPlay("Battle flee")
|
|
battle.pbDisplay(_INTL("{1} fled from battle!", battler.pbThis))
|
|
battle.decision = 3 # Escaped
|
|
next true
|
|
end
|
|
# In trainer battles
|
|
next false if battle.pbAllFainted?(battler.idxOpposingSide)
|
|
next false if !battle.pbCanSwitchOut?(battler.index) # Battler can't switch out
|
|
next false if !battle.pbCanChooseNonActive?(battler.index) # No Pokémon can switch in
|
|
battle.pbShowAbilitySplash(battler, true)
|
|
battle.pbHideAbilitySplash(battler)
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1}'s {2} activated!", battler.pbThis, battler.abilityName))
|
|
end
|
|
battle.pbDisplay(_INTL("{1} went back to {2}!",
|
|
battler.pbThis, battle.pbGetOwnerName(battler.index)))
|
|
if battle.endOfRound # Just switch out
|
|
battle.scene.pbRecall(battler.index) if !battler.fainted?
|
|
battler.pbAbilitiesOnSwitchOut # Inc. primordial weather check
|
|
next true
|
|
end
|
|
newPkmn = battle.pbGetReplacementPokemonIndex(battler.index) # Owner chooses
|
|
next false if newPkmn < 0 # Shouldn't ever do this
|
|
battle.pbRecallAndReplace(battler.index, newPkmn)
|
|
battle.pbClearChoice(battler.index) # Replacement Pokémon does nothing this round
|
|
battle.moldBreaker = false if move_user && battler.index == move_user.index
|
|
battle.pbOnBattlerEnteringBattle(battler.index)
|
|
next true
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnHPDroppedBelowHalf.copy(:EMERGENCYEXIT, :WIMPOUT)
|
|
|
|
#===============================================================================
|
|
# StatusCheckNonIgnorable handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::StatusCheckNonIgnorable.add(:COMATOSE,
|
|
proc { |ability, battler, status|
|
|
next false if !battler.isSpecies?(:KOMALA)
|
|
next true if status.nil? || status == :SLEEP
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# StatusImmunity handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::StatusImmunity.add(:FLOWERVEIL,
|
|
proc { |ability, battler, status|
|
|
next true if battler.pbHasType?(:GRASS)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatusImmunity.add(:IMMUNITY,
|
|
proc { |ability, battler, status|
|
|
next true if status == :POISON
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatusImmunity.copy(:IMMUNITY, :PASTELVEIL)
|
|
|
|
Battle::AbilityEffects::StatusImmunity.add(:INSOMNIA,
|
|
proc { |ability, battler, status|
|
|
next true if status == :SLEEP
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatusImmunity.copy(:INSOMNIA, :SWEETVEIL, :VITALSPIRIT)
|
|
|
|
Battle::AbilityEffects::StatusImmunity.add(:LEAFGUARD,
|
|
proc { |ability, battler, status|
|
|
next true if [:Sun, :HarshSun].include?(battler.effectiveWeather)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatusImmunity.add(:LIMBER,
|
|
proc { |ability, battler, status|
|
|
next true if status == :PARALYSIS
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatusImmunity.add(:MAGMAARMOR,
|
|
proc { |ability, battler, status|
|
|
next true if status == :FROZEN
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatusImmunity.add(:WATERVEIL,
|
|
proc { |ability, battler, status|
|
|
next true if status == :BURN
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatusImmunity.copy(:WATERVEIL, :WATERBUBBLE)
|
|
|
|
#===============================================================================
|
|
# StatusImmunityNonIgnorable handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::StatusImmunityNonIgnorable.add(:COMATOSE,
|
|
proc { |ability, battler, status|
|
|
next true if battler.isSpecies?(:KOMALA)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatusImmunityNonIgnorable.add(:SHIELDSDOWN,
|
|
proc { |ability, battler, status|
|
|
next true if battler.isSpecies?(:MINIOR) && battler.form < 7
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# StatusImmunityFromAlly handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::StatusImmunityFromAlly.add(:FLOWERVEIL,
|
|
proc { |ability, battler, status|
|
|
next true if battler.pbHasType?(:GRASS)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatusImmunityFromAlly.add(:PASTELVEIL,
|
|
proc { |ability, battler, status|
|
|
next true if status == :POISON
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatusImmunityFromAlly.add(:SWEETVEIL,
|
|
proc { |ability, battler, status|
|
|
next true if status == :SLEEP
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# OnStatusInflicted handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::OnStatusInflicted.add(:SYNCHRONIZE,
|
|
proc { |ability, battler, user, status|
|
|
next if !user || user.index == battler.index
|
|
case status
|
|
when :POISON
|
|
if user.pbCanPoisonSynchronize?(battler)
|
|
battler.battle.pbShowAbilitySplash(battler)
|
|
msg = nil
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
msg = _INTL("{1}'s {2} poisoned {3}!", battler.pbThis, battler.abilityName, user.pbThis(true))
|
|
end
|
|
user.pbPoison(nil, msg, (battler.statusCount > 0))
|
|
battler.battle.pbHideAbilitySplash(battler)
|
|
end
|
|
when :BURN
|
|
if user.pbCanBurnSynchronize?(battler)
|
|
battler.battle.pbShowAbilitySplash(battler)
|
|
msg = nil
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
msg = _INTL("{1}'s {2} burned {3}!", battler.pbThis, battler.abilityName, user.pbThis(true))
|
|
end
|
|
user.pbBurn(nil, msg)
|
|
battler.battle.pbHideAbilitySplash(battler)
|
|
end
|
|
when :PARALYSIS
|
|
if user.pbCanParalyzeSynchronize?(battler)
|
|
battler.battle.pbShowAbilitySplash(battler)
|
|
msg = nil
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
msg = _INTL("{1}'s {2} paralyzed {3}! It may be unable to move!",
|
|
battler.pbThis, battler.abilityName, user.pbThis(true))
|
|
end
|
|
user.pbParalyze(nil, msg)
|
|
battler.battle.pbHideAbilitySplash(battler)
|
|
end
|
|
end
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# StatusCure handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::StatusCure.add(:IMMUNITY,
|
|
proc { |ability, battler|
|
|
next if battler.status != :POISON
|
|
battler.battle.pbShowAbilitySplash(battler)
|
|
battler.pbCureStatus(Battle::Scene::USE_ABILITY_SPLASH)
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
battler.battle.pbDisplay(_INTL("{1}'s {2} cured its poisoning!", battler.pbThis, battler.abilityName))
|
|
end
|
|
battler.battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatusCure.copy(:IMMUNITY, :PASTELVEIL)
|
|
|
|
Battle::AbilityEffects::StatusCure.add(:INSOMNIA,
|
|
proc { |ability, battler|
|
|
next if battler.status != :SLEEP
|
|
battler.battle.pbShowAbilitySplash(battler)
|
|
battler.pbCureStatus(Battle::Scene::USE_ABILITY_SPLASH)
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
battler.battle.pbDisplay(_INTL("{1}'s {2} woke it up!", battler.pbThis, battler.abilityName))
|
|
end
|
|
battler.battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatusCure.copy(:INSOMNIA, :VITALSPIRIT)
|
|
|
|
Battle::AbilityEffects::StatusCure.add(:LIMBER,
|
|
proc { |ability, battler|
|
|
next if battler.status != :PARALYSIS
|
|
battler.battle.pbShowAbilitySplash(battler)
|
|
battler.pbCureStatus(Battle::Scene::USE_ABILITY_SPLASH)
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
battler.battle.pbDisplay(_INTL("{1}'s {2} cured its paralysis!", battler.pbThis, battler.abilityName))
|
|
end
|
|
battler.battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatusCure.add(:MAGMAARMOR,
|
|
proc { |ability, battler|
|
|
next if battler.status != :FROZEN
|
|
battler.battle.pbShowAbilitySplash(battler)
|
|
battler.pbCureStatus(Battle::Scene::USE_ABILITY_SPLASH)
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
battler.battle.pbDisplay(_INTL("{1}'s {2} defrosted it!", battler.pbThis, battler.abilityName))
|
|
end
|
|
battler.battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatusCure.add(:OBLIVIOUS,
|
|
proc { |ability, battler|
|
|
next if battler.effects[PBEffects::Attract] < 0 &&
|
|
(battler.effects[PBEffects::Taunt] == 0 || Settings::MECHANICS_GENERATION <= 5)
|
|
battler.battle.pbShowAbilitySplash(battler)
|
|
if battler.effects[PBEffects::Attract] >= 0
|
|
battler.pbCureAttract
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battler.battle.pbDisplay(_INTL("{1} got over its infatuation.", battler.pbThis))
|
|
else
|
|
battler.battle.pbDisplay(_INTL("{1}'s {2} cured its infatuation status!",
|
|
battler.pbThis, battler.abilityName))
|
|
end
|
|
end
|
|
if battler.effects[PBEffects::Taunt] > 0 && Settings::MECHANICS_GENERATION >= 6
|
|
battler.effects[PBEffects::Taunt] = 0
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battler.battle.pbDisplay(_INTL("{1}'s Taunt wore off!", battler.pbThis))
|
|
else
|
|
battler.battle.pbDisplay(_INTL("{1}'s {2} made its taunt wear off!",
|
|
battler.pbThis, battler.abilityName))
|
|
end
|
|
end
|
|
battler.battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatusCure.add(:OWNTEMPO,
|
|
proc { |ability, battler|
|
|
next if battler.effects[PBEffects::Confusion] == 0
|
|
battler.battle.pbShowAbilitySplash(battler)
|
|
battler.pbCureConfusion
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battler.battle.pbDisplay(_INTL("{1} snapped out of its confusion.", battler.pbThis))
|
|
else
|
|
battler.battle.pbDisplay(_INTL("{1}'s {2} snapped it out of its confusion!",
|
|
battler.pbThis, battler.abilityName))
|
|
end
|
|
battler.battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatusCure.add(:WATERVEIL,
|
|
proc { |ability, battler|
|
|
next if battler.status != :BURN
|
|
battler.battle.pbShowAbilitySplash(battler)
|
|
battler.pbCureStatus(Battle::Scene::USE_ABILITY_SPLASH)
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
battler.battle.pbDisplay(_INTL("{1}'s {2} healed its burn!", battler.pbThis, battler.abilityName))
|
|
end
|
|
battler.battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatusCure.copy(:WATERVEIL, :WATERBUBBLE)
|
|
|
|
#===============================================================================
|
|
# StatLossImmunity handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::StatLossImmunity.add(:BIGPECKS,
|
|
proc { |ability, battler, stat, battle, showMessages|
|
|
next false if stat != :DEFENSE
|
|
if showMessages
|
|
battle.pbShowAbilitySplash(battler)
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1}'s {2} cannot be lowered!", battler.pbThis, GameData::Stat.get(stat).name))
|
|
else
|
|
battle.pbDisplay(_INTL("{1}'s {2} prevents {3} loss!", battler.pbThis,
|
|
battler.abilityName, GameData::Stat.get(stat).name))
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
end
|
|
next true
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatLossImmunity.add(:CLEARBODY,
|
|
proc { |ability, battler, stat, battle, showMessages|
|
|
if showMessages
|
|
battle.pbShowAbilitySplash(battler)
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1}'s stats cannot be lowered!", battler.pbThis))
|
|
else
|
|
battle.pbDisplay(_INTL("{1}'s {2} prevents stat loss!", battler.pbThis, battler.abilityName))
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
end
|
|
next true
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatLossImmunity.copy(:CLEARBODY, :WHITESMOKE)
|
|
|
|
Battle::AbilityEffects::StatLossImmunity.add(:FLOWERVEIL,
|
|
proc { |ability, battler, stat, battle, showMessages|
|
|
next false if !battler.pbHasType?(:GRASS)
|
|
if showMessages
|
|
battle.pbShowAbilitySplash(battler)
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1}'s stats cannot be lowered!", battler.pbThis))
|
|
else
|
|
battle.pbDisplay(_INTL("{1}'s {2} prevents stat loss!", battler.pbThis, battler.abilityName))
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
end
|
|
next true
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatLossImmunity.add(:HYPERCUTTER,
|
|
proc { |ability, battler, stat, battle, showMessages|
|
|
next false if stat != :ATTACK
|
|
if showMessages
|
|
battle.pbShowAbilitySplash(battler)
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1}'s {2} cannot be lowered!", battler.pbThis, GameData::Stat.get(stat).name))
|
|
else
|
|
battle.pbDisplay(_INTL("{1}'s {2} prevents {3} loss!", battler.pbThis,
|
|
battler.abilityName, GameData::Stat.get(stat).name))
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
end
|
|
next true
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::StatLossImmunity.add(:KEENEYE,
|
|
proc { |ability, battler, stat, battle, showMessages|
|
|
next false if stat != :ACCURACY
|
|
if showMessages
|
|
battle.pbShowAbilitySplash(battler)
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1}'s {2} cannot be lowered!", battler.pbThis, GameData::Stat.get(stat).name))
|
|
else
|
|
battle.pbDisplay(_INTL("{1}'s {2} prevents {3} loss!", battler.pbThis,
|
|
battler.abilityName, GameData::Stat.get(stat).name))
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
end
|
|
next true
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# StatLossImmunityNonIgnorable handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::StatLossImmunityNonIgnorable.add(:FULLMETALBODY,
|
|
proc { |ability, battler, stat, battle, showMessages|
|
|
if showMessages
|
|
battle.pbShowAbilitySplash(battler)
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1}'s stats cannot be lowered!", battler.pbThis))
|
|
else
|
|
battle.pbDisplay(_INTL("{1}'s {2} prevents stat loss!", battler.pbThis, battler.abilityName))
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
end
|
|
next true
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# StatLossImmunityFromAlly handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::StatLossImmunityFromAlly.add(:FLOWERVEIL,
|
|
proc { |ability, bearer, battler, stat, battle, showMessages|
|
|
next false if !battler.pbHasType?(:GRASS)
|
|
if showMessages
|
|
battle.pbShowAbilitySplash(bearer)
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1}'s stats cannot be lowered!", battler.pbThis))
|
|
else
|
|
battle.pbDisplay(_INTL("{1}'s {2} prevents {3}'s stat loss!",
|
|
bearer.pbThis, bearer.abilityName, battler.pbThis(true)))
|
|
end
|
|
battle.pbHideAbilitySplash(bearer)
|
|
end
|
|
next true
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# OnStatGain handlers
|
|
#===============================================================================
|
|
|
|
# There aren't any!
|
|
|
|
#===============================================================================
|
|
# OnStatLoss handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::OnStatLoss.add(:COMPETITIVE,
|
|
proc { |ability, battler, stat, user|
|
|
next if user && !user.opposes?(battler)
|
|
battler.pbRaiseStatStageByAbility(:SPECIAL_ATTACK, 2, battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnStatLoss.add(:DEFIANT,
|
|
proc { |ability, battler, stat, user|
|
|
next if user && !user.opposes?(battler)
|
|
battler.pbRaiseStatStageByAbility(:ATTACK, 2, battler)
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# PriorityChange handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::PriorityChange.add(:GALEWINGS,
|
|
proc { |ability, battler, move, pri|
|
|
next pri + 1 if (Settings::MECHANICS_GENERATION <= 6 || battler.hp == battler.totalhp) &&
|
|
move.type == :FLYING
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::PriorityChange.add(:PRANKSTER,
|
|
proc { |ability, battler, move, pri|
|
|
if move.statusMove?
|
|
battler.effects[PBEffects::Prankster] = true
|
|
next pri + 1
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::PriorityChange.add(:TRIAGE,
|
|
proc { |ability, battler, move, pri|
|
|
next pri + 3 if move.healingMove?
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# PriorityBracketChange handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::PriorityBracketChange.add(:QUICKDRAW,
|
|
proc { |ability, battler, battle|
|
|
next 1 if battle.pbRandom(100) < 30
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::PriorityBracketChange.add(:STALL,
|
|
proc { |ability, battler, battle|
|
|
next -1
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# PriorityBracketUse handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::PriorityBracketUse.add(:QUICKDRAW,
|
|
proc { |ability, battler, battle|
|
|
battle.pbShowAbilitySplash(battler)
|
|
battle.pbDisplay(_INTL("{1} made {2} move faster!", battler.abilityName, battler.pbThis(true)))
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# OnFlinch handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::OnFlinch.add(:STEADFAST,
|
|
proc { |ability, battler, battle|
|
|
battler.pbRaiseStatStageByAbility(:SPEED, 1, battler)
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# MoveBlocking handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::MoveBlocking.add(:DAZZLING,
|
|
proc { |ability, bearer, user, targets, move, battle|
|
|
next false if battle.choices[user.index][4] <= 0
|
|
next false if !bearer.opposes?(user)
|
|
ret = false
|
|
targets.each { |b| ret = true if b.opposes?(user) }
|
|
next ret
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::MoveBlocking.copy(:DAZZLING, :QUEENLYMAJESTY)
|
|
|
|
#===============================================================================
|
|
# MoveImmunity handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::MoveImmunity.add(:BULLETPROOF,
|
|
proc { |ability, user, target, move, type, battle, show_message|
|
|
next false if !move.bombMove?
|
|
if show_message
|
|
battle.pbShowAbilitySplash(target)
|
|
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
|
|
battle.pbHideAbilitySplash(target)
|
|
end
|
|
next true
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::MoveImmunity.add(:FLASHFIRE,
|
|
proc { |ability, user, target, move, type, battle, show_message|
|
|
next false if user.index == target.index
|
|
next false if type != :FIRE
|
|
if show_message
|
|
battle.pbShowAbilitySplash(target)
|
|
if !target.effects[PBEffects::FlashFire]
|
|
target.effects[PBEffects::FlashFire] = true
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("The power of {1}'s Fire-type moves rose!", target.pbThis(true)))
|
|
else
|
|
battle.pbDisplay(_INTL("The power of {1}'s Fire-type moves rose because of its {2}!",
|
|
target.pbThis(true), target.abilityName))
|
|
end
|
|
elsif 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
|
|
battle.pbHideAbilitySplash(target)
|
|
end
|
|
next true
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::MoveImmunity.add(:LIGHTNINGROD,
|
|
proc { |ability, user, target, move, type, battle, show_message|
|
|
next target.pbMoveImmunityStatRaisingAbility(user, move, type,
|
|
:ELECTRIC, :SPECIAL_ATTACK, 1, show_message)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::MoveImmunity.add(:MOTORDRIVE,
|
|
proc { |ability, user, target, move, type, battle, show_message|
|
|
next target.pbMoveImmunityStatRaisingAbility(user, move, type,
|
|
:ELECTRIC, :SPEED, 1, show_message)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::MoveImmunity.add(:SAPSIPPER,
|
|
proc { |ability, user, target, move, type, battle, show_message|
|
|
next target.pbMoveImmunityStatRaisingAbility(user, move, type,
|
|
:GRASS, :ATTACK, 1, show_message)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::MoveImmunity.add(:SOUNDPROOF,
|
|
proc { |ability, user, target, move, type, battle, show_message|
|
|
next false if !move.soundMove?
|
|
next false if Settings::MECHANICS_GENERATION >= 8 && user.index == target.index
|
|
if show_message
|
|
battle.pbShowAbilitySplash(target)
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("It doesn't affect {1}...", target.pbThis(true)))
|
|
else
|
|
battle.pbDisplay(_INTL("{1}'s {2} blocks {3}!", target.pbThis, target.abilityName, move.name))
|
|
end
|
|
battle.pbHideAbilitySplash(target)
|
|
end
|
|
next true
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::MoveImmunity.add(:STORMDRAIN,
|
|
proc { |ability, user, target, move, type, battle, show_message|
|
|
next target.pbMoveImmunityStatRaisingAbility(user, move, type,
|
|
:WATER, :SPECIAL_ATTACK, 1, show_message)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::MoveImmunity.add(:TELEPATHY,
|
|
proc { |ability, user, target, move, type, battle, show_message|
|
|
next false if move.statusMove?
|
|
next false if user.index == target.index || target.opposes?(user)
|
|
if show_message
|
|
battle.pbShowAbilitySplash(target)
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1} avoids attacks by its ally Pokémon!", target.pbThis(true)))
|
|
else
|
|
battle.pbDisplay(_INTL("{1} avoids attacks by its ally Pokémon with {2}!",
|
|
target.pbThis, target.abilityName))
|
|
end
|
|
battle.pbHideAbilitySplash(target)
|
|
end
|
|
next true
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::MoveImmunity.add(:VOLTABSORB,
|
|
proc { |ability, user, target, move, type, battle, show_message|
|
|
next target.pbMoveImmunityHealingAbility(user, move, type, :ELECTRIC, show_message)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::MoveImmunity.add(:WATERABSORB,
|
|
proc { |ability, user, target, move, type, battle, show_message|
|
|
next target.pbMoveImmunityHealingAbility(user, move, type, :WATER, show_message)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::MoveImmunity.copy(:WATERABSORB, :DRYSKIN)
|
|
|
|
Battle::AbilityEffects::MoveImmunity.add(:WONDERGUARD,
|
|
proc { |ability, user, target, move, type, battle, show_message|
|
|
next false if move.statusMove?
|
|
next false if !type || Effectiveness.super_effective?(target.damageState.typeMod)
|
|
if show_message
|
|
battle.pbShowAbilitySplash(target)
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("It doesn't affect {1}...", target.pbThis(true)))
|
|
else
|
|
battle.pbDisplay(_INTL("{1} avoided damage with {2}!", target.pbThis, target.abilityName))
|
|
end
|
|
battle.pbHideAbilitySplash(target)
|
|
end
|
|
next true
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# ModifyMoveBaseType handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::ModifyMoveBaseType.add(:AERILATE,
|
|
proc { |ability, user, move, type|
|
|
next if type != :NORMAL || !GameData::Type.exists?(:FLYING)
|
|
move.powerBoost = true
|
|
next :FLYING
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::ModifyMoveBaseType.add(:GALVANIZE,
|
|
proc { |ability, user, move, type|
|
|
next if type != :NORMAL || !GameData::Type.exists?(:ELECTRIC)
|
|
move.powerBoost = true
|
|
next :ELECTRIC
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::ModifyMoveBaseType.add(:LIQUIDVOICE,
|
|
proc { |ability, user, move, type|
|
|
next :WATER if GameData::Type.exists?(:WATER) && move.soundMove?
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::ModifyMoveBaseType.add(:NORMALIZE,
|
|
proc { |ability, user, move, type|
|
|
next if !GameData::Type.exists?(:NORMAL)
|
|
move.powerBoost = true if Settings::MECHANICS_GENERATION >= 7
|
|
next :NORMAL
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::ModifyMoveBaseType.add(:PIXILATE,
|
|
proc { |ability, user, move, type|
|
|
next if type != :NORMAL || !GameData::Type.exists?(:FAIRY)
|
|
move.powerBoost = true
|
|
next :FAIRY
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::ModifyMoveBaseType.add(:REFRIGERATE,
|
|
proc { |ability, user, move, type|
|
|
next if type != :NORMAL || !GameData::Type.exists?(:ICE)
|
|
move.powerBoost = true
|
|
next :ICE
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# AccuracyCalcFromUser handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::AccuracyCalcFromUser.add(:COMPOUNDEYES,
|
|
proc { |ability, mods, user, target, move, type|
|
|
mods[:accuracy_multiplier] *= 1.3
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::AccuracyCalcFromUser.add(:HUSTLE,
|
|
proc { |ability, mods, user, target, move, type|
|
|
mods[:accuracy_multiplier] *= 0.8 if move.physicalMove?
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::AccuracyCalcFromUser.add(:KEENEYE,
|
|
proc { |ability, mods, user, target, move, type|
|
|
mods[:evasion_stage] = 0 if mods[:evasion_stage] > 0 && Settings::MECHANICS_GENERATION >= 6
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::AccuracyCalcFromUser.add(:NOGUARD,
|
|
proc { |ability, mods, user, target, move, type|
|
|
mods[:base_accuracy] = 0
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::AccuracyCalcFromUser.add(:UNAWARE,
|
|
proc { |ability, mods, user, target, move, type|
|
|
mods[:evasion_stage] = 0 if move.damagingMove?
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::AccuracyCalcFromUser.add(:VICTORYSTAR,
|
|
proc { |ability, mods, user, target, move, type|
|
|
mods[:accuracy_multiplier] *= 1.1
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# AccuracyCalcFromAlly handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::AccuracyCalcFromAlly.add(:VICTORYSTAR,
|
|
proc { |ability, mods, user, target, move, type|
|
|
mods[:accuracy_multiplier] *= 1.1
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# AccuracyCalcFromTarget handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::AccuracyCalcFromTarget.add(:LIGHTNINGROD,
|
|
proc { |ability, mods, user, target, move, type|
|
|
mods[:base_accuracy] = 0 if type == :ELECTRIC
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::AccuracyCalcFromTarget.add(:NOGUARD,
|
|
proc { |ability, mods, user, target, move, type|
|
|
mods[:base_accuracy] = 0
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::AccuracyCalcFromTarget.add(:SANDVEIL,
|
|
proc { |ability, mods, user, target, move, type|
|
|
mods[:evasion_multiplier] *= 1.25 if target.effectiveWeather == :Sandstorm
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::AccuracyCalcFromTarget.add(:SNOWCLOAK,
|
|
proc { |ability, mods, user, target, move, type|
|
|
mods[:evasion_multiplier] *= 1.25 if target.effectiveWeather == :Hail
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::AccuracyCalcFromTarget.add(:STORMDRAIN,
|
|
proc { |ability, mods, user, target, move, type|
|
|
mods[:base_accuracy] = 0 if type == :WATER
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::AccuracyCalcFromTarget.add(:TANGLEDFEET,
|
|
proc { |ability, mods, user, target, move, type|
|
|
mods[:accuracy_multiplier] /= 2 if target.effects[PBEffects::Confusion] > 0
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::AccuracyCalcFromTarget.add(:UNAWARE,
|
|
proc { |ability, mods, user, target, move, type|
|
|
mods[:accuracy_stage] = 0 if move.damagingMove?
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::AccuracyCalcFromTarget.add(:WONDERSKIN,
|
|
proc { |ability, mods, user, target, move, type|
|
|
if move.statusMove? && user.opposes?(target) && mods[:base_accuracy] > 50
|
|
mods[:base_accuracy] = 50
|
|
end
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# DamageCalcFromUser handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:AERILATE,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:power_multiplier] *= 1.2 if move.powerBoost
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.copy(:AERILATE, :PIXILATE, :REFRIGERATE, :GALVANIZE, :NORMALIZE)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:ANALYTIC,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
# NOTE: In the official games, if another battler faints earlier in the
|
|
# round but it would have moved after the user, then Analytic does not
|
|
# power up the move. However, this makes the determination so much
|
|
# more complicated (involving pbPriority and counting or not counting
|
|
# speed/priority modifiers depending on which Generation's mechanics
|
|
# are being used), so I'm choosing to ignore it. The effect is thus:
|
|
# "power up the move if all other battlers on the field right now have
|
|
# already moved".
|
|
if move.pbMoveFailedLastInRound?(user, false)
|
|
mults[:power_multiplier] *= 1.3
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:BLAZE,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
if user.hp <= user.totalhp / 3 && type == :FIRE
|
|
mults[:attack_multiplier] *= 1.5
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:DEFEATIST,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:attack_multiplier] /= 2 if user.hp <= user.totalhp / 2
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:DRAGONSMAW,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:attack_multiplier] *= 1.5 if type == :DRAGON
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:FLAREBOOST,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:power_multiplier] *= 1.5 if user.burned? && move.specialMove?
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:FLASHFIRE,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
if user.effects[PBEffects::FlashFire] && type == :FIRE
|
|
mults[:attack_multiplier] *= 1.5
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:FLOWERGIFT,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
if move.physicalMove? && [:Sun, :HarshSun].include?(user.effectiveWeather)
|
|
mults[:attack_multiplier] *= 1.5
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:GORILLATACTICS,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:attack_multiplier] *= 1.5 if move.physicalMove?
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:GUTS,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
if user.pbHasAnyStatus? && move.physicalMove?
|
|
mults[:attack_multiplier] *= 1.5
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:HUGEPOWER,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:attack_multiplier] *= 2 if move.physicalMove?
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.copy(:HUGEPOWER, :PUREPOWER)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:HUSTLE,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:attack_multiplier] *= 1.5 if move.physicalMove?
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:IRONFIST,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:power_multiplier] *= 1.2 if move.punchingMove?
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:MEGALAUNCHER,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:power_multiplier] *= 1.5 if move.pulseMove?
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:MINUS,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
next if !move.specialMove?
|
|
if user.allAllies.any? { |b| b.hasActiveAbility?([:MINUS, :PLUS]) }
|
|
mults[:attack_multiplier] *= 1.5
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.copy(:MINUS, :PLUS)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:NEUROFORCE,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
if Effectiveness.super_effective?(target.damageState.typeMod)
|
|
mults[:final_damage_multiplier] *= 1.25
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:OVERGROW,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
if user.hp <= user.totalhp / 3 && type == :GRASS
|
|
mults[:attack_multiplier] *= 1.5
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:PUNKROCK,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:attack_multiplier] *= 1.3 if move.soundMove?
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:RECKLESS,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:power_multiplier] *= 1.2 if move.recoilMove?
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:RIVALRY,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
if user.gender != 2 && target.gender != 2
|
|
if user.gender == target.gender
|
|
mults[:power_multiplier] *= 1.25
|
|
else
|
|
mults[:power_multiplier] *= 0.75
|
|
end
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:SANDFORCE,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
if user.effectiveWeather == :Sandstorm &&
|
|
[:ROCK, :GROUND, :STEEL].include?(type)
|
|
mults[:power_multiplier] *= 1.3
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:SHEERFORCE,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:power_multiplier] *= 1.3 if move.addlEffect > 0
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:SLOWSTART,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:attack_multiplier] /= 2 if user.effects[PBEffects::SlowStart] > 0 && move.physicalMove?
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:SOLARPOWER,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
if move.specialMove? && [:Sun, :HarshSun].include?(user.effectiveWeather)
|
|
mults[:attack_multiplier] *= 1.5
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:SNIPER,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:final_damage_multiplier] *= 1.5 if target.damageState.critical
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:STAKEOUT,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:attack_multiplier] *= 2 if target.battle.choices[target.index][0] == :SwitchOut
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:STEELWORKER,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:attack_multiplier] *= 1.5 if type == :STEEL
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:STEELYSPIRIT,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:final_damage_multiplier] *= 1.5 if type == :STEEL
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:STRONGJAW,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:power_multiplier] *= 1.5 if move.bitingMove?
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:SWARM,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
if user.hp <= user.totalhp / 3 && type == :BUG
|
|
mults[:attack_multiplier] *= 1.5
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:TECHNICIAN,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
if user.index != target.index && move && move.id != :STRUGGLE &&
|
|
power * mults[:power_multiplier] <= 60
|
|
mults[:power_multiplier] *= 1.5
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:TINTEDLENS,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:final_damage_multiplier] *= 2 if Effectiveness.resistant?(target.damageState.typeMod)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:TORRENT,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
if user.hp <= user.totalhp / 3 && type == :WATER
|
|
mults[:attack_multiplier] *= 1.5
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:TOUGHCLAWS,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:power_multiplier] *= 4 / 3.0 if move.contactMove?
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:TOXICBOOST,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
if user.poisoned? && move.physicalMove?
|
|
mults[:power_multiplier] *= 1.5
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:TRANSISTOR,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:attack_multiplier] *= 1.5 if type == :ELECTRIC
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromUser.add(:WATERBUBBLE,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:attack_multiplier] *= 2 if type == :WATER
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# DamageCalcFromAlly handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::DamageCalcFromAlly.add(:BATTERY,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
next if !move.specialMove?
|
|
mults[:final_damage_multiplier] *= 1.3
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromAlly.add(:FLOWERGIFT,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
if move.physicalMove? && [:Sun, :HarshSun].include?(user.effectiveWeather)
|
|
mults[:attack_multiplier] *= 1.5
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromAlly.add(:POWERSPOT,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:final_damage_multiplier] *= 1.3
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromAlly.add(:STEELYSPIRIT,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:final_damage_multiplier] *= 1.5 if type == :STEEL
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# DamageCalcFromTarget handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::DamageCalcFromTarget.add(:DRYSKIN,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:power_multiplier] *= 1.25 if type == :FIRE
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromTarget.add(:FILTER,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
if Effectiveness.super_effective?(target.damageState.typeMod)
|
|
mults[:final_damage_multiplier] *= 0.75
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromTarget.copy(:FILTER, :SOLIDROCK)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromTarget.add(:FLOWERGIFT,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
if move.specialMove? && [:Sun, :HarshSun].include?(target.effectiveWeather)
|
|
mults[:defense_multiplier] *= 1.5
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromTarget.add(:FLUFFY,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:final_damage_multiplier] *= 2 if move.calcType == :FIRE
|
|
mults[:final_damage_multiplier] /= 2 if move.pbContactMove?(user)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromTarget.add(:FURCOAT,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:defense_multiplier] *= 2 if move.physicalMove? ||
|
|
move.function == "UseTargetDefenseInsteadOfTargetSpDef" # Psyshock
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromTarget.add(:GRASSPELT,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:defense_multiplier] *= 1.5 if user.battle.field.terrain == :Grassy
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromTarget.add(:HEATPROOF,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:power_multiplier] /= 2 if type == :FIRE
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromTarget.add(:ICESCALES,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:final_damage_multiplier] /= 2 if move.specialMove?
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromTarget.add(:MARVELSCALE,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
if target.pbHasAnyStatus? && move.physicalMove?
|
|
mults[:defense_multiplier] *= 1.5
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromTarget.add(:MULTISCALE,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:final_damage_multiplier] /= 2 if target.hp == target.totalhp
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromTarget.add(:PUNKROCK,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:final_damage_multiplier] /= 2 if move.soundMove?
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromTarget.add(:THICKFAT,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:power_multiplier] /= 2 if [:FIRE, :ICE].include?(type)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromTarget.add(:WATERBUBBLE,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:final_damage_multiplier] /= 2 if type == :FIRE
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# DamageCalcFromTargetNonIgnorable handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::DamageCalcFromTargetNonIgnorable.add(:PRISMARMOR,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
if Effectiveness.super_effective?(target.damageState.typeMod)
|
|
mults[:final_damage_multiplier] *= 0.75
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromTargetNonIgnorable.add(:SHADOWSHIELD,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:final_damage_multiplier] /= 2 if target.hp == target.totalhp
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# DamageCalcFromTargetAlly handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::DamageCalcFromTargetAlly.add(:FLOWERGIFT,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
if move.specialMove? && [:Sun, :HarshSun].include?(target.effectiveWeather)
|
|
mults[:defense_multiplier] *= 1.5
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::DamageCalcFromTargetAlly.add(:FRIENDGUARD,
|
|
proc { |ability, user, target, move, mults, power, type|
|
|
mults[:final_damage_multiplier] *= 0.75
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# CriticalCalcFromUser handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::CriticalCalcFromUser.add(:MERCILESS,
|
|
proc { |ability, user, target, c|
|
|
next 99 if target.poisoned?
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::CriticalCalcFromUser.add(:SUPERLUCK,
|
|
proc { |ability, user, target, c|
|
|
next c + 1
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# CriticalCalcFromTarget handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::CriticalCalcFromTarget.add(:BATTLEARMOR,
|
|
proc { |ability, user, target, c|
|
|
next -1
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::CriticalCalcFromTarget.copy(:BATTLEARMOR, :SHELLARMOR)
|
|
|
|
#===============================================================================
|
|
# OnBeingHit handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:AFTERMATH,
|
|
proc { |ability, user, target, move, battle|
|
|
next if !target.fainted?
|
|
next if !move.pbContactMove?(user)
|
|
battle.pbShowAbilitySplash(target)
|
|
if !battle.moldBreaker
|
|
dampBattler = battle.pbCheckGlobalAbility(:DAMP)
|
|
if dampBattler
|
|
battle.pbShowAbilitySplash(dampBattler)
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1} cannot use {2}!", target.pbThis, target.abilityName))
|
|
else
|
|
battle.pbDisplay(_INTL("{1} cannot use {2} because of {3}'s {4}!",
|
|
target.pbThis, target.abilityName, dampBattler.pbThis(true), dampBattler.abilityName))
|
|
end
|
|
battle.pbHideAbilitySplash(dampBattler)
|
|
battle.pbHideAbilitySplash(target)
|
|
next
|
|
end
|
|
end
|
|
if user.takesIndirectDamage?(Battle::Scene::USE_ABILITY_SPLASH) &&
|
|
user.affectedByContactEffect?(Battle::Scene::USE_ABILITY_SPLASH)
|
|
battle.scene.pbDamageAnimation(user)
|
|
user.pbReduceHP(user.totalhp / 4, false)
|
|
battle.pbDisplay(_INTL("{1} was caught in the aftermath!", user.pbThis))
|
|
end
|
|
battle.pbHideAbilitySplash(target)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:ANGERPOINT,
|
|
proc { |ability, user, target, move, battle|
|
|
next if !target.damageState.critical
|
|
next if !target.pbCanRaiseStatStage?(:ATTACK, target)
|
|
battle.pbShowAbilitySplash(target)
|
|
target.stages[:ATTACK] = 6
|
|
target.statsRaisedThisRound = true
|
|
battle.pbCommonAnimation("StatUp", target)
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1} maxed its {2}!", target.pbThis, GameData::Stat.get(:ATTACK).name))
|
|
else
|
|
battle.pbDisplay(_INTL("{1}'s {2} maxed its {3}!",
|
|
target.pbThis, target.abilityName, GameData::Stat.get(:ATTACK).name))
|
|
end
|
|
battle.pbHideAbilitySplash(target)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:COTTONDOWN,
|
|
proc { |ability, user, target, move, battle|
|
|
next if battle.allBattlers.none? { |b| b.index != target.index && b.pbCanLowerStatStage?(:SPEED, target) }
|
|
battle.pbShowAbilitySplash(target)
|
|
battle.allBattlers.each do |b|
|
|
b.pbLowerStatStageByAbility(:SPEED, 1, target, false) if b.index != target.index
|
|
end
|
|
battle.pbHideAbilitySplash(target)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:CURSEDBODY,
|
|
proc { |ability, user, target, move, battle|
|
|
next if user.fainted?
|
|
next if user.effects[PBEffects::Disable] > 0
|
|
regularMove = nil
|
|
user.eachMove do |m|
|
|
next if m.id != user.lastRegularMoveUsed
|
|
regularMove = m
|
|
break
|
|
end
|
|
next if !regularMove || (regularMove.pp == 0 && regularMove.total_pp > 0)
|
|
next if battle.pbRandom(100) >= 30
|
|
battle.pbShowAbilitySplash(target)
|
|
if !move.pbMoveFailedAromaVeil?(target, user, Battle::Scene::USE_ABILITY_SPLASH)
|
|
user.effects[PBEffects::Disable] = 3
|
|
user.effects[PBEffects::DisableMove] = regularMove.id
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1}'s {2} was disabled!", user.pbThis, regularMove.name))
|
|
else
|
|
battle.pbDisplay(_INTL("{1}'s {2} was disabled by {3}'s {4}!",
|
|
user.pbThis, regularMove.name, target.pbThis(true), target.abilityName))
|
|
end
|
|
battle.pbHideAbilitySplash(target)
|
|
user.pbItemStatusCureCheck
|
|
end
|
|
battle.pbHideAbilitySplash(target)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:CUTECHARM,
|
|
proc { |ability, user, target, move, battle|
|
|
next if target.fainted?
|
|
next if !move.pbContactMove?(user)
|
|
next if battle.pbRandom(100) >= 30
|
|
battle.pbShowAbilitySplash(target)
|
|
if user.pbCanAttract?(target, Battle::Scene::USE_ABILITY_SPLASH) &&
|
|
user.affectedByContactEffect?(Battle::Scene::USE_ABILITY_SPLASH)
|
|
msg = nil
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
msg = _INTL("{1}'s {2} made {3} fall in love!", target.pbThis,
|
|
target.abilityName, user.pbThis(true))
|
|
end
|
|
user.pbAttract(target, msg)
|
|
end
|
|
battle.pbHideAbilitySplash(target)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:EFFECTSPORE,
|
|
proc { |ability, user, target, move, battle|
|
|
# NOTE: This ability has a 30% chance of triggering, not a 30% chance of
|
|
# inflicting a status condition. It can try (and fail) to inflict a
|
|
# status condition that the user is immune to.
|
|
next if !move.pbContactMove?(user)
|
|
next if battle.pbRandom(100) >= 30
|
|
r = battle.pbRandom(3)
|
|
next if r == 0 && user.asleep?
|
|
next if r == 1 && user.poisoned?
|
|
next if r == 2 && user.paralyzed?
|
|
battle.pbShowAbilitySplash(target)
|
|
if user.affectedByPowder?(Battle::Scene::USE_ABILITY_SPLASH) &&
|
|
user.affectedByContactEffect?(Battle::Scene::USE_ABILITY_SPLASH)
|
|
case r
|
|
when 0
|
|
if user.pbCanSleep?(target, Battle::Scene::USE_ABILITY_SPLASH)
|
|
msg = nil
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
msg = _INTL("{1}'s {2} made {3} fall asleep!", target.pbThis,
|
|
target.abilityName, user.pbThis(true))
|
|
end
|
|
user.pbSleep(msg)
|
|
end
|
|
when 1
|
|
if user.pbCanPoison?(target, Battle::Scene::USE_ABILITY_SPLASH)
|
|
msg = nil
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
msg = _INTL("{1}'s {2} poisoned {3}!", target.pbThis,
|
|
target.abilityName, user.pbThis(true))
|
|
end
|
|
user.pbPoison(target, msg)
|
|
end
|
|
when 2
|
|
if user.pbCanParalyze?(target, Battle::Scene::USE_ABILITY_SPLASH)
|
|
msg = nil
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
msg = _INTL("{1}'s {2} paralyzed {3}! It may be unable to move!",
|
|
target.pbThis, target.abilityName, user.pbThis(true))
|
|
end
|
|
user.pbParalyze(target, msg)
|
|
end
|
|
end
|
|
end
|
|
battle.pbHideAbilitySplash(target)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:FLAMEBODY,
|
|
proc { |ability, user, target, move, battle|
|
|
next if !move.pbContactMove?(user)
|
|
next if user.burned? || battle.pbRandom(100) >= 30
|
|
battle.pbShowAbilitySplash(target)
|
|
if user.pbCanBurn?(target, Battle::Scene::USE_ABILITY_SPLASH) &&
|
|
user.affectedByContactEffect?(Battle::Scene::USE_ABILITY_SPLASH)
|
|
msg = nil
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
msg = _INTL("{1}'s {2} burned {3}!", target.pbThis, target.abilityName, user.pbThis(true))
|
|
end
|
|
user.pbBurn(target, msg)
|
|
end
|
|
battle.pbHideAbilitySplash(target)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:GOOEY,
|
|
proc { |ability, user, target, move, battle|
|
|
next if !move.pbContactMove?(user)
|
|
user.pbLowerStatStageByAbility(:SPEED, 1, target, true, true)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.copy(:GOOEY, :TANGLINGHAIR)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:ILLUSION,
|
|
proc { |ability, user, target, move, battle|
|
|
# NOTE: This intentionally doesn't show the ability splash.
|
|
next if !target.effects[PBEffects::Illusion]
|
|
target.effects[PBEffects::Illusion] = nil
|
|
battle.scene.pbChangePokemon(target, target.pokemon)
|
|
battle.pbDisplay(_INTL("{1}'s illusion wore off!", target.pbThis))
|
|
battle.pbSetSeen(target)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:INNARDSOUT,
|
|
proc { |ability, user, target, move, battle|
|
|
next if !target.fainted? || user.dummy
|
|
battle.pbShowAbilitySplash(target)
|
|
if user.takesIndirectDamage?(Battle::Scene::USE_ABILITY_SPLASH)
|
|
battle.scene.pbDamageAnimation(user)
|
|
user.pbReduceHP(target.damageState.hpLost, false)
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1} is hurt!", user.pbThis))
|
|
else
|
|
battle.pbDisplay(_INTL("{1} is hurt by {2}'s {3}!", user.pbThis,
|
|
target.pbThis(true), target.abilityName))
|
|
end
|
|
end
|
|
battle.pbHideAbilitySplash(target)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:IRONBARBS,
|
|
proc { |ability, user, target, move, battle|
|
|
next if !move.pbContactMove?(user)
|
|
battle.pbShowAbilitySplash(target)
|
|
if user.takesIndirectDamage?(Battle::Scene::USE_ABILITY_SPLASH) &&
|
|
user.affectedByContactEffect?(Battle::Scene::USE_ABILITY_SPLASH)
|
|
battle.scene.pbDamageAnimation(user)
|
|
user.pbReduceHP(user.totalhp / 8, false)
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1} is hurt!", user.pbThis))
|
|
else
|
|
battle.pbDisplay(_INTL("{1} is hurt by {2}'s {3}!", user.pbThis,
|
|
target.pbThis(true), target.abilityName))
|
|
end
|
|
end
|
|
battle.pbHideAbilitySplash(target)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.copy(:IRONBARBS, :ROUGHSKIN)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:JUSTIFIED,
|
|
proc { |ability, user, target, move, battle|
|
|
next if move.calcType != :DARK
|
|
target.pbRaiseStatStageByAbility(:ATTACK, 1, target)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:MUMMY,
|
|
proc { |ability, user, target, move, battle|
|
|
next if !move.pbContactMove?(user)
|
|
next if user.fainted?
|
|
next if user.unstoppableAbility? || user.ability == ability
|
|
oldAbil = nil
|
|
battle.pbShowAbilitySplash(target) if user.opposes?(target)
|
|
if user.affectedByContactEffect?(Battle::Scene::USE_ABILITY_SPLASH)
|
|
oldAbil = user.ability
|
|
battle.pbShowAbilitySplash(user, true, false) if user.opposes?(target)
|
|
user.ability = ability
|
|
battle.pbReplaceAbilitySplash(user) if user.opposes?(target)
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1}'s Ability became {2}!", user.pbThis, user.abilityName))
|
|
else
|
|
battle.pbDisplay(_INTL("{1}'s Ability became {2} because of {3}!",
|
|
user.pbThis, user.abilityName, target.pbThis(true)))
|
|
end
|
|
battle.pbHideAbilitySplash(user) if user.opposes?(target)
|
|
end
|
|
battle.pbHideAbilitySplash(target) if user.opposes?(target)
|
|
user.pbOnLosingAbility(oldAbil)
|
|
user.pbTriggerAbilityOnGainingIt
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:PERISHBODY,
|
|
proc { |ability, user, target, move, battle|
|
|
next if !move.pbContactMove?(user)
|
|
next if user.fainted?
|
|
next if user.effects[PBEffects::PerishSong] > 0 || target.effects[PBEffects::PerishSong] > 0
|
|
battle.pbShowAbilitySplash(target)
|
|
if user.affectedByContactEffect?(Battle::Scene::USE_ABILITY_SPLASH)
|
|
user.effects[PBEffects::PerishSong] = 4
|
|
user.effects[PBEffects::PerishSongUser] = target.index
|
|
target.effects[PBEffects::PerishSong] = 4
|
|
target.effects[PBEffects::PerishSongUser] = target.index
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("Both Pokémon will faint in three turns!"))
|
|
else
|
|
battle.pbDisplay(_INTL("Both Pokémon will faint in three turns because of {1}'s {2}!",
|
|
target.pbThis(true), target.abilityName))
|
|
end
|
|
end
|
|
battle.pbHideAbilitySplash(target)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:POISONPOINT,
|
|
proc { |ability, user, target, move, battle|
|
|
next if !move.pbContactMove?(user)
|
|
next if user.poisoned? || battle.pbRandom(100) >= 30
|
|
battle.pbShowAbilitySplash(target)
|
|
if user.pbCanPoison?(target, Battle::Scene::USE_ABILITY_SPLASH) &&
|
|
user.affectedByContactEffect?(Battle::Scene::USE_ABILITY_SPLASH)
|
|
msg = nil
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
msg = _INTL("{1}'s {2} poisoned {3}!", target.pbThis, target.abilityName, user.pbThis(true))
|
|
end
|
|
user.pbPoison(target, msg)
|
|
end
|
|
battle.pbHideAbilitySplash(target)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:RATTLED,
|
|
proc { |ability, user, target, move, battle|
|
|
next if ![:BUG, :DARK, :GHOST].include?(move.calcType)
|
|
target.pbRaiseStatStageByAbility(:SPEED, 1, target)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:SANDSPIT,
|
|
proc { |ability, user, target, move, battle|
|
|
battle.pbStartWeatherAbility(:Sandstorm, target)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:STAMINA,
|
|
proc { |ability, user, target, move, battle|
|
|
target.pbRaiseStatStageByAbility(:DEFENSE, 1, target)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:STATIC,
|
|
proc { |ability, user, target, move, battle|
|
|
next if !move.pbContactMove?(user)
|
|
next if user.paralyzed? || battle.pbRandom(100) >= 30
|
|
battle.pbShowAbilitySplash(target)
|
|
if user.pbCanParalyze?(target, Battle::Scene::USE_ABILITY_SPLASH) &&
|
|
user.affectedByContactEffect?(Battle::Scene::USE_ABILITY_SPLASH)
|
|
msg = nil
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
msg = _INTL("{1}'s {2} paralyzed {3}! It may be unable to move!",
|
|
target.pbThis, target.abilityName, user.pbThis(true))
|
|
end
|
|
user.pbParalyze(target, msg)
|
|
end
|
|
battle.pbHideAbilitySplash(target)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:WANDERINGSPIRIT,
|
|
proc { |ability, user, target, move, battle|
|
|
next if !move.pbContactMove?(user)
|
|
next if user.ungainableAbility? || [:RECEIVER, :WONDERGUARD].include?(user.ability_id)
|
|
oldUserAbil = nil
|
|
oldTargetAbil = nil
|
|
battle.pbShowAbilitySplash(target) if user.opposes?(target)
|
|
if user.affectedByContactEffect?(Battle::Scene::USE_ABILITY_SPLASH)
|
|
battle.pbShowAbilitySplash(user, true, false) if user.opposes?(target)
|
|
oldUserAbil = user.ability
|
|
oldTargetAbil = target.ability
|
|
user.ability = oldTargetAbil
|
|
target.ability = oldUserAbil
|
|
if user.opposes?(target)
|
|
battle.pbReplaceAbilitySplash(user)
|
|
battle.pbReplaceAbilitySplash(target)
|
|
end
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1} swapped Abilities with {2}!", target.pbThis, user.pbThis(true)))
|
|
else
|
|
battle.pbDisplay(_INTL("{1} swapped its {2} Ability with {3}'s {4} Ability!",
|
|
target.pbThis, user.abilityName, user.pbThis(true), target.abilityName))
|
|
end
|
|
if user.opposes?(target)
|
|
battle.pbHideAbilitySplash(user)
|
|
battle.pbHideAbilitySplash(target)
|
|
end
|
|
end
|
|
battle.pbHideAbilitySplash(target) if user.opposes?(target)
|
|
user.pbOnLosingAbility(oldUserAbil)
|
|
target.pbOnLosingAbility(oldTargetAbil)
|
|
user.pbTriggerAbilityOnGainingIt
|
|
target.pbTriggerAbilityOnGainingIt
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:WATERCOMPACTION,
|
|
proc { |ability, user, target, move, battle|
|
|
next if move.calcType != :WATER
|
|
target.pbRaiseStatStageByAbility(:DEFENSE, 2, target)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnBeingHit.add(:WEAKARMOR,
|
|
proc { |ability, user, target, move, battle|
|
|
next if !move.physicalMove?
|
|
next if !target.pbCanLowerStatStage?(:DEFENSE, target) &&
|
|
!target.pbCanRaiseStatStage?(:SPEED, target)
|
|
battle.pbShowAbilitySplash(target)
|
|
target.pbLowerStatStageByAbility(:DEFENSE, 1, target, false)
|
|
target.pbRaiseStatStageByAbility(:SPEED,
|
|
(Settings::MECHANICS_GENERATION >= 7) ? 2 : 1, target, false)
|
|
battle.pbHideAbilitySplash(target)
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# OnDealingHit handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::OnDealingHit.add(:POISONTOUCH,
|
|
proc { |ability, user, target, move, battle|
|
|
next if !move.contactMove?
|
|
next if battle.pbRandom(100) >= 30
|
|
battle.pbShowAbilitySplash(user)
|
|
if target.hasActiveAbility?(:SHIELDDUST) && !battle.moldBreaker
|
|
battle.pbShowAbilitySplash(target)
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1} is unaffected!", target.pbThis))
|
|
end
|
|
battle.pbHideAbilitySplash(target)
|
|
elsif target.pbCanPoison?(user, Battle::Scene::USE_ABILITY_SPLASH)
|
|
msg = nil
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
msg = _INTL("{1}'s {2} poisoned {3}!", user.pbThis, user.abilityName, target.pbThis(true))
|
|
end
|
|
target.pbPoison(user, msg)
|
|
end
|
|
battle.pbHideAbilitySplash(user)
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# OnEndOfUsingMove handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::OnEndOfUsingMove.add(:BEASTBOOST,
|
|
proc { |ability, user, targets, move, battle|
|
|
next if battle.pbAllFainted?(user.idxOpposingSide)
|
|
numFainted = 0
|
|
targets.each { |b| numFainted += 1 if b.damageState.fainted }
|
|
next if numFainted == 0
|
|
userStats = user.plainStats
|
|
highestStatValue = 0
|
|
userStats.each_value { |value| highestStatValue = value if highestStatValue < value }
|
|
GameData::Stat.each_main_battle do |s|
|
|
next if userStats[s.id] < highestStatValue
|
|
if user.pbCanRaiseStatStage?(s.id, user)
|
|
user.pbRaiseStatStageByAbility(s.id, numFainted, user)
|
|
end
|
|
break
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnEndOfUsingMove.add(:CHILLINGNEIGH,
|
|
proc { |ability, user, targets, move, battle|
|
|
next if battle.pbAllFainted?(user.idxOpposingSide)
|
|
numFainted = 0
|
|
targets.each { |b| numFainted += 1 if b.damageState.fainted }
|
|
next if numFainted == 0 || !user.pbCanRaiseStatStage?(:ATTACK, user)
|
|
user.ability_id = :CHILLINGNEIGH # So the As One abilities can just copy this
|
|
user.pbRaiseStatStageByAbility(:ATTACK, 1, user)
|
|
user.ability_id = ability
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnEndOfUsingMove.copy(:CHILLINGNEIGH, :ASONECHILLINGNEIGH)
|
|
|
|
Battle::AbilityEffects::OnEndOfUsingMove.add(:GRIMNEIGH,
|
|
proc { |ability, user, targets, move, battle|
|
|
next if battle.pbAllFainted?(user.idxOpposingSide)
|
|
numFainted = 0
|
|
targets.each { |b| numFainted += 1 if b.damageState.fainted }
|
|
next if numFainted == 0 || !user.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user)
|
|
user.ability_id = :GRIMNEIGH # So the As One abilities can just copy this
|
|
user.pbRaiseStatStageByAbility(:SPECIAL_ATTACK, 1, user)
|
|
user.ability_id = ability
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnEndOfUsingMove.copy(:GRIMNEIGH, :ASONEGRIMNEIGH)
|
|
|
|
Battle::AbilityEffects::OnEndOfUsingMove.add(:MAGICIAN,
|
|
proc { |ability, user, targets, move, battle|
|
|
next if battle.futureSight
|
|
next if !move.pbDamagingMove?
|
|
next if user.item
|
|
next if user.wild?
|
|
targets.each do |b|
|
|
next if b.damageState.unaffected || b.damageState.substitute
|
|
next if !b.item
|
|
next if b.unlosableItem?(b.item) || user.unlosableItem?(b.item)
|
|
battle.pbShowAbilitySplash(user)
|
|
if b.hasActiveAbility?(:STICKYHOLD)
|
|
battle.pbShowAbilitySplash(b) if user.opposes?(b)
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1}'s item cannot be stolen!", b.pbThis))
|
|
end
|
|
battle.pbHideAbilitySplash(b) if user.opposes?(b)
|
|
next
|
|
end
|
|
user.item = b.item
|
|
b.item = nil
|
|
b.effects[PBEffects::Unburden] = true if b.hasActiveAbility?(:UNBURDEN)
|
|
if battle.wildBattle? && !user.initialItem && user.item == b.initialItem
|
|
user.setInitialItem(user.item)
|
|
b.setInitialItem(nil)
|
|
end
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1} stole {2}'s {3}!", user.pbThis,
|
|
b.pbThis(true), user.itemName))
|
|
else
|
|
battle.pbDisplay(_INTL("{1} stole {2}'s {3} with {4}!", user.pbThis,
|
|
b.pbThis(true), user.itemName, user.abilityName))
|
|
end
|
|
battle.pbHideAbilitySplash(user)
|
|
user.pbHeldItemTriggerCheck
|
|
break
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnEndOfUsingMove.add(:MOXIE,
|
|
proc { |ability, user, targets, move, battle|
|
|
next if battle.pbAllFainted?(user.idxOpposingSide)
|
|
numFainted = 0
|
|
targets.each { |b| numFainted += 1 if b.damageState.fainted }
|
|
next if numFainted == 0 || !user.pbCanRaiseStatStage?(:ATTACK, user)
|
|
user.pbRaiseStatStageByAbility(:ATTACK, numFainted, user)
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# AfterMoveUseFromTarget handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::AfterMoveUseFromTarget.add(:BERSERK,
|
|
proc { |ability, target, user, move, switched_battlers, battle|
|
|
next if !move.damagingMove?
|
|
next if !target.droppedBelowHalfHP
|
|
next if !target.pbCanRaiseStatStage?(:SPECIAL_ATTACK, target)
|
|
target.pbRaiseStatStageByAbility(:SPECIAL_ATTACK, 1, target)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::AfterMoveUseFromTarget.add(:COLORCHANGE,
|
|
proc { |ability, target, user, move, switched_battlers, battle|
|
|
next if target.damageState.calcDamage == 0 || target.damageState.substitute
|
|
next if !move.calcType || GameData::Type.get(move.calcType).pseudo_type
|
|
next if target.pbHasType?(move.calcType) && !target.pbHasOtherType?(move.calcType)
|
|
typeName = GameData::Type.get(move.calcType).name
|
|
battle.pbShowAbilitySplash(target)
|
|
target.pbChangeTypes(move.calcType)
|
|
battle.pbDisplay(_INTL("{1}'s type changed to {2} because of its {3}!",
|
|
target.pbThis, typeName, target.abilityName))
|
|
battle.pbHideAbilitySplash(target)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::AfterMoveUseFromTarget.add(:PICKPOCKET,
|
|
proc { |ability, target, user, move, switched_battlers, battle|
|
|
# NOTE: According to Bulbapedia, this can still trigger to steal the user's
|
|
# item even if it was switched out by a Red Card. That doesn't make
|
|
# sense, so this code doesn't do it.
|
|
next if target.wild?
|
|
next if switched_battlers.include?(user.index) # User was switched out
|
|
next if !move.contactMove?
|
|
next if user.effects[PBEffects::Substitute] > 0 || target.damageState.substitute
|
|
next if target.item || !user.item
|
|
next if user.unlosableItem?(user.item) || target.unlosableItem?(user.item)
|
|
battle.pbShowAbilitySplash(target)
|
|
if user.hasActiveAbility?(:STICKYHOLD)
|
|
battle.pbShowAbilitySplash(user) if target.opposes?(user)
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1}'s item cannot be stolen!", user.pbThis))
|
|
end
|
|
battle.pbHideAbilitySplash(user) if target.opposes?(user)
|
|
battle.pbHideAbilitySplash(target)
|
|
next
|
|
end
|
|
target.item = user.item
|
|
user.item = nil
|
|
user.effects[PBEffects::Unburden] = true if user.hasActiveAbility?(:UNBURDEN)
|
|
if battle.wildBattle? && !target.initialItem && target.item == user.initialItem
|
|
target.setInitialItem(target.item)
|
|
user.setInitialItem(nil)
|
|
end
|
|
battle.pbDisplay(_INTL("{1} pickpocketed {2}'s {3}!", target.pbThis,
|
|
user.pbThis(true), target.itemName))
|
|
battle.pbHideAbilitySplash(target)
|
|
target.pbHeldItemTriggerCheck
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# EndOfRoundWeather handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::EndOfRoundWeather.add(:DRYSKIN,
|
|
proc { |ability, weather, battler, battle|
|
|
case weather
|
|
when :Sun, :HarshSun
|
|
battle.pbShowAbilitySplash(battler)
|
|
battle.scene.pbDamageAnimation(battler)
|
|
battler.pbReduceHP(battler.totalhp / 8, false)
|
|
battle.pbDisplay(_INTL("{1} was hurt by the sunlight!", battler.pbThis))
|
|
battle.pbHideAbilitySplash(battler)
|
|
battler.pbItemHPHealCheck
|
|
when :Rain, :HeavyRain
|
|
next if !battler.canHeal?
|
|
battle.pbShowAbilitySplash(battler)
|
|
battler.pbRecoverHP(battler.totalhp / 8)
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1}'s HP was restored.", battler.pbThis))
|
|
else
|
|
battle.pbDisplay(_INTL("{1}'s {2} restored its HP.", battler.pbThis, battler.abilityName))
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::EndOfRoundWeather.add(:ICEBODY,
|
|
proc { |ability, weather, battler, battle|
|
|
next unless weather == :Hail
|
|
next if !battler.canHeal?
|
|
battle.pbShowAbilitySplash(battler)
|
|
battler.pbRecoverHP(battler.totalhp / 16)
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1}'s HP was restored.", battler.pbThis))
|
|
else
|
|
battle.pbDisplay(_INTL("{1}'s {2} restored its HP.", battler.pbThis, battler.abilityName))
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::EndOfRoundWeather.add(:ICEFACE,
|
|
proc { |ability, weather, battler, battle|
|
|
next if weather != :Hail
|
|
next if !battler.canRestoreIceFace || battler.form != 1
|
|
battle.pbShowAbilitySplash(battler)
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1}'s {2} activated!", battler.pbThis, battler.abilityName))
|
|
end
|
|
battler.pbChangeForm(0, _INTL("{1} transformed!", battler.pbThis))
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::EndOfRoundWeather.add(:RAINDISH,
|
|
proc { |ability, weather, battler, battle|
|
|
next unless [:Rain, :HeavyRain].include?(weather)
|
|
next if !battler.canHeal?
|
|
battle.pbShowAbilitySplash(battler)
|
|
battler.pbRecoverHP(battler.totalhp / 16)
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1}'s HP was restored.", battler.pbThis))
|
|
else
|
|
battle.pbDisplay(_INTL("{1}'s {2} restored its HP.", battler.pbThis, battler.abilityName))
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::EndOfRoundWeather.add(:SOLARPOWER,
|
|
proc { |ability, weather, battler, battle|
|
|
next unless [:Sun, :HarshSun].include?(weather)
|
|
battle.pbShowAbilitySplash(battler)
|
|
battle.scene.pbDamageAnimation(battler)
|
|
battler.pbReduceHP(battler.totalhp / 8, false)
|
|
battle.pbDisplay(_INTL("{1} was hurt by the sunlight!", battler.pbThis))
|
|
battle.pbHideAbilitySplash(battler)
|
|
battler.pbItemHPHealCheck
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# EndOfRoundHealing handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::EndOfRoundHealing.add(:HEALER,
|
|
proc { |ability, battler, battle|
|
|
next unless battle.pbRandom(100) < 30
|
|
battler.allAllies.each do |b|
|
|
next if b.status == :NONE
|
|
battle.pbShowAbilitySplash(battler)
|
|
oldStatus = b.status
|
|
b.pbCureStatus(Battle::Scene::USE_ABILITY_SPLASH)
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
case oldStatus
|
|
when :SLEEP
|
|
battle.pbDisplay(_INTL("{1}'s {2} woke its partner up!", battler.pbThis, battler.abilityName))
|
|
when :POISON
|
|
battle.pbDisplay(_INTL("{1}'s {2} cured its partner's poison!", battler.pbThis, battler.abilityName))
|
|
when :BURN
|
|
battle.pbDisplay(_INTL("{1}'s {2} healed its partner's burn!", battler.pbThis, battler.abilityName))
|
|
when :PARALYSIS
|
|
battle.pbDisplay(_INTL("{1}'s {2} cured its partner's paralysis!", battler.pbThis, battler.abilityName))
|
|
when :FROZEN
|
|
battle.pbDisplay(_INTL("{1}'s {2} defrosted its partner!", battler.pbThis, battler.abilityName))
|
|
end
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::EndOfRoundHealing.add(:HYDRATION,
|
|
proc { |ability, battler, battle|
|
|
next if battler.status == :NONE
|
|
next if ![:Rain, :HeavyRain].include?(battler.effectiveWeather)
|
|
battle.pbShowAbilitySplash(battler)
|
|
oldStatus = battler.status
|
|
battler.pbCureStatus(Battle::Scene::USE_ABILITY_SPLASH)
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
case oldStatus
|
|
when :SLEEP
|
|
battle.pbDisplay(_INTL("{1}'s {2} woke it up!", battler.pbThis, battler.abilityName))
|
|
when :POISON
|
|
battle.pbDisplay(_INTL("{1}'s {2} cured its poison!", battler.pbThis, battler.abilityName))
|
|
when :BURN
|
|
battle.pbDisplay(_INTL("{1}'s {2} healed its burn!", battler.pbThis, battler.abilityName))
|
|
when :PARALYSIS
|
|
battle.pbDisplay(_INTL("{1}'s {2} cured its paralysis!", battler.pbThis, battler.abilityName))
|
|
when :FROZEN
|
|
battle.pbDisplay(_INTL("{1}'s {2} defrosted it!", battler.pbThis, battler.abilityName))
|
|
end
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::EndOfRoundHealing.add(:SHEDSKIN,
|
|
proc { |ability, battler, battle|
|
|
next if battler.status == :NONE
|
|
next unless battle.pbRandom(100) < 30
|
|
battle.pbShowAbilitySplash(battler)
|
|
oldStatus = battler.status
|
|
battler.pbCureStatus(Battle::Scene::USE_ABILITY_SPLASH)
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
case oldStatus
|
|
when :SLEEP
|
|
battle.pbDisplay(_INTL("{1}'s {2} woke it up!", battler.pbThis, battler.abilityName))
|
|
when :POISON
|
|
battle.pbDisplay(_INTL("{1}'s {2} cured its poison!", battler.pbThis, battler.abilityName))
|
|
when :BURN
|
|
battle.pbDisplay(_INTL("{1}'s {2} healed its burn!", battler.pbThis, battler.abilityName))
|
|
when :PARALYSIS
|
|
battle.pbDisplay(_INTL("{1}'s {2} cured its paralysis!", battler.pbThis, battler.abilityName))
|
|
when :FROZEN
|
|
battle.pbDisplay(_INTL("{1}'s {2} defrosted it!", battler.pbThis, battler.abilityName))
|
|
end
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# EndOfRoundEffect handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::EndOfRoundEffect.add(:BADDREAMS,
|
|
proc { |ability, battler, battle|
|
|
battle.allOtherSideBattlers(battler.index).each do |b|
|
|
next if !b.near?(battler) || !b.asleep?
|
|
battle.pbShowAbilitySplash(battler)
|
|
next if !b.takesIndirectDamage?(Battle::Scene::USE_ABILITY_SPLASH)
|
|
b.pbTakeEffectDamage(b.totalhp / 8) do |hp_lost|
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1} is tormented!", b.pbThis))
|
|
else
|
|
battle.pbDisplay(_INTL("{1} is tormented by {2}'s {3}!",
|
|
b.pbThis, battler.pbThis(true), battler.abilityName))
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
end
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::EndOfRoundEffect.add(:MOODY,
|
|
proc { |ability, battler, battle|
|
|
randomUp = []
|
|
randomDown = []
|
|
if Settings::MECHANICS_GENERATION >= 8
|
|
GameData::Stat.each_main_battle do |s|
|
|
randomUp.push(s.id) if battler.pbCanRaiseStatStage?(s.id, battler)
|
|
randomDown.push(s.id) if battler.pbCanLowerStatStage?(s.id, battler)
|
|
end
|
|
else
|
|
GameData::Stat.each_battle do |s|
|
|
randomUp.push(s.id) if battler.pbCanRaiseStatStage?(s.id, battler)
|
|
randomDown.push(s.id) if battler.pbCanLowerStatStage?(s.id, battler)
|
|
end
|
|
end
|
|
next if randomUp.length == 0 && randomDown.length == 0
|
|
battle.pbShowAbilitySplash(battler)
|
|
if randomUp.length > 0
|
|
r = battle.pbRandom(randomUp.length)
|
|
battler.pbRaiseStatStageByAbility(randomUp[r], 2, battler, false)
|
|
randomDown.delete(randomUp[r])
|
|
end
|
|
if randomDown.length > 0
|
|
r = battle.pbRandom(randomDown.length)
|
|
battler.pbLowerStatStageByAbility(randomDown[r], 1, battler, false)
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
battler.pbItemStatRestoreCheck if randomDown.length > 0
|
|
battler.pbItemOnStatDropped
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::EndOfRoundEffect.add(:SPEEDBOOST,
|
|
proc { |ability, battler, battle|
|
|
# A Pokémon's turnCount is 0 if it became active after the beginning of a
|
|
# round
|
|
if battler.turnCount > 0 && battle.choices[battler.index][0] != :Run &&
|
|
battler.pbCanRaiseStatStage?(:SPEED, battler)
|
|
battler.pbRaiseStatStageByAbility(:SPEED, 1, battler)
|
|
end
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# EndOfRoundGainItem handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::EndOfRoundGainItem.add(:BALLFETCH,
|
|
proc { |ability, battler, battle|
|
|
next if battler.item
|
|
next if battle.first_poke_ball.nil?
|
|
battle.pbShowAbilitySplash(battler)
|
|
battler.item = battle.first_poke_ball
|
|
battler.setInitialItem(battler.item) if !battler.initialItem
|
|
battle.first_poke_ball = nil
|
|
battle.pbDisplay(_INTL("{1} retrieved the thrown {2}!", battler.pbThis, battler.itemName))
|
|
battle.pbHideAbilitySplash(battler)
|
|
battler.pbHeldItemTriggerCheck
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::EndOfRoundGainItem.add(:HARVEST,
|
|
proc { |ability, battler, battle|
|
|
next if battler.item
|
|
next if !battler.recycleItem || !GameData::Item.get(battler.recycleItem).is_berry?
|
|
if ![:Sun, :HarshSun].include?(battler.effectiveWeather)
|
|
next unless battle.pbRandom(100) < 50
|
|
end
|
|
battle.pbShowAbilitySplash(battler)
|
|
battler.item = battler.recycleItem
|
|
battler.setRecycleItem(nil)
|
|
battler.setInitialItem(battler.item) if !battler.initialItem
|
|
battle.pbDisplay(_INTL("{1} harvested one {2}!", battler.pbThis, battler.itemName))
|
|
battle.pbHideAbilitySplash(battler)
|
|
battler.pbHeldItemTriggerCheck
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::EndOfRoundGainItem.add(:PICKUP,
|
|
proc { |ability, battler, battle|
|
|
next if battler.item
|
|
foundItem = nil
|
|
fromBattler = nil
|
|
use = 0
|
|
battle.allBattlers.each do |b|
|
|
next if b.index == battler.index
|
|
next if b.effects[PBEffects::PickupUse] <= use
|
|
foundItem = b.effects[PBEffects::PickupItem]
|
|
fromBattler = b
|
|
use = b.effects[PBEffects::PickupUse]
|
|
end
|
|
next if !foundItem
|
|
battle.pbShowAbilitySplash(battler)
|
|
battler.item = foundItem
|
|
fromBattler.effects[PBEffects::PickupItem] = nil
|
|
fromBattler.effects[PBEffects::PickupUse] = 0
|
|
fromBattler.setRecycleItem(nil) if fromBattler.recycleItem == foundItem
|
|
if battle.wildBattle? && !battler.initialItem && fromBattler.initialItem == foundItem
|
|
battler.setInitialItem(foundItem)
|
|
fromBattler.setInitialItem(nil)
|
|
end
|
|
battle.pbDisplay(_INTL("{1} found one {2}!", battler.pbThis, battler.itemName))
|
|
battle.pbHideAbilitySplash(battler)
|
|
battler.pbHeldItemTriggerCheck
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# CertainSwitching handlers
|
|
#===============================================================================
|
|
|
|
# There aren't any!
|
|
|
|
#===============================================================================
|
|
# TrappingByTarget handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::TrappingByTarget.add(:ARENATRAP,
|
|
proc { |ability, switcher, bearer, battle|
|
|
next true if !switcher.airborne?
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::TrappingByTarget.add(:MAGNETPULL,
|
|
proc { |ability, switcher, bearer, battle|
|
|
next true if switcher.pbHasType?(:STEEL)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::TrappingByTarget.add(:SHADOWTAG,
|
|
proc { |ability, switcher, bearer, battle|
|
|
next true if !switcher.hasActiveAbility?(:SHADOWTAG)
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# OnSwitchIn handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:AIRLOCK,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbShowAbilitySplash(battler)
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1} has {2}!", battler.pbThis, battler.abilityName))
|
|
end
|
|
battle.pbDisplay(_INTL("The effects of the weather disappeared."))
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.copy(:AIRLOCK, :CLOUDNINE)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:ANTICIPATION,
|
|
proc { |ability, battler, battle, switch_in|
|
|
next if !battler.pbOwnedByPlayer?
|
|
battlerTypes = battler.pbTypes(true)
|
|
types = battlerTypes
|
|
found = false
|
|
battle.allOtherSideBattlers(battler.index).each do |b|
|
|
b.eachMove do |m|
|
|
next if m.statusMove?
|
|
if types.length > 0
|
|
moveType = m.type
|
|
if Settings::MECHANICS_GENERATION >= 6 && m.function == "TypeDependsOnUserIVs" # Hidden Power
|
|
moveType = pbHiddenPower(b.pokemon)[0]
|
|
end
|
|
eff = Effectiveness.calculate(moveType, *types)
|
|
next if Effectiveness.ineffective?(eff)
|
|
next if !Effectiveness.super_effective?(eff) &&
|
|
!["OHKO", "OHKOIce", "OHKOHitsUndergroundTarget"].include?(m.function)
|
|
elsif !["OHKO", "OHKOIce", "OHKOHitsUndergroundTarget"].include?(m.function)
|
|
next
|
|
end
|
|
found = true
|
|
break
|
|
end
|
|
break if found
|
|
end
|
|
if found
|
|
battle.pbShowAbilitySplash(battler)
|
|
battle.pbDisplay(_INTL("{1} shuddered with anticipation!", battler.pbThis))
|
|
battle.pbHideAbilitySplash(battler)
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:ASONECHILLINGNEIGH,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbShowAbilitySplash(battler)
|
|
battle.pbDisplay(_INTL("{1} has two Abilities!", battler.pbThis))
|
|
battle.pbHideAbilitySplash(battler)
|
|
battler.ability_id = :UNNERVE
|
|
battle.pbShowAbilitySplash(battler)
|
|
battle.pbDisplay(_INTL("{1} is too nervous to eat Berries!", battler.pbOpposingTeam))
|
|
battle.pbHideAbilitySplash(battler)
|
|
battler.ability_id = ability
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.copy(:ASONECHILLINGNEIGH, :ASONEGRIMNEIGH)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:AURABREAK,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbShowAbilitySplash(battler)
|
|
battle.pbDisplay(_INTL("{1} reversed all other Pokémon's auras!", battler.pbThis))
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:COMATOSE,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbShowAbilitySplash(battler)
|
|
battle.pbDisplay(_INTL("{1} is drowsing!", battler.pbThis))
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:CURIOUSMEDICINE,
|
|
proc { |ability, battler, battle, switch_in|
|
|
next if battler.allAllies.none? { |b| b.hasAlteredStatStages? }
|
|
battle.pbShowAbilitySplash(battler)
|
|
battler.allAllies.each do |b|
|
|
next if !b.hasAlteredStatStages?
|
|
b.pbResetStatStages
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1}'s stat changes were removed!", b.pbThis))
|
|
else
|
|
battle.pbDisplay(_INTL("{1}'s stat changes were removed by {2}'s {3}!",
|
|
b.pbThis, battler.pbThis(true), battler.abilityName))
|
|
end
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:DARKAURA,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbShowAbilitySplash(battler)
|
|
battle.pbDisplay(_INTL("{1} is radiating a dark aura!", battler.pbThis))
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:DAUNTLESSSHIELD,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battler.pbRaiseStatStageByAbility(:DEFENSE, 1, battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:DELTASTREAM,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbStartWeatherAbility(:StrongWinds, battler, true)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:DESOLATELAND,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbStartWeatherAbility(:HarshSun, battler, true)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:DOWNLOAD,
|
|
proc { |ability, battler, battle, switch_in|
|
|
oDef = oSpDef = 0
|
|
battle.allOtherSideBattlers(battler.index).each do |b|
|
|
oDef += b.defense
|
|
oSpDef += b.spdef
|
|
end
|
|
stat = (oDef < oSpDef) ? :ATTACK : :SPECIAL_ATTACK
|
|
battler.pbRaiseStatStageByAbility(stat, 1, battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:DRIZZLE,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbStartWeatherAbility(:Rain, battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:DROUGHT,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbStartWeatherAbility(:Sun, battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:ELECTRICSURGE,
|
|
proc { |ability, battler, battle, switch_in|
|
|
next if battle.field.terrain == :Electric
|
|
battle.pbShowAbilitySplash(battler)
|
|
battle.pbStartTerrain(battler, :Electric)
|
|
# NOTE: The ability splash is hidden again in def pbStartTerrain.
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:FAIRYAURA,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbShowAbilitySplash(battler)
|
|
battle.pbDisplay(_INTL("{1} is radiating a fairy aura!", battler.pbThis))
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:FOREWARN,
|
|
proc { |ability, battler, battle, switch_in|
|
|
next if !battler.pbOwnedByPlayer?
|
|
highestPower = 0
|
|
forewarnMoves = []
|
|
battle.allOtherSideBattlers(battler.index).each do |b|
|
|
b.eachMove do |m|
|
|
power = m.power
|
|
power = 160 if ["OHKO", "OHKOIce", "OHKOHitsUndergroundTarget"].include?(m.function)
|
|
power = 150 if ["PowerHigherWithUserHP"].include?(m.function) # Eruption
|
|
# Counter, Mirror Coat, Metal Burst
|
|
power = 120 if ["CounterPhysicalDamage",
|
|
"CounterSpecialDamage",
|
|
"CounterDamagePlusHalf"].include?(m.function)
|
|
# Sonic Boom, Dragon Rage, Night Shade, Endeavor, Psywave,
|
|
# Return, Frustration, Crush Grip, Gyro Ball, Hidden Power,
|
|
# Natural Gift, Trump Card, Flail, Grass Knot
|
|
power = 80 if ["FixedDamage20",
|
|
"FixedDamage40",
|
|
"FixedDamageUserLevel",
|
|
"LowerTargetHPToUserHP",
|
|
"FixedDamageUserLevelRandom",
|
|
"PowerHigherWithUserHappiness",
|
|
"PowerLowerWithUserHappiness",
|
|
"PowerHigherWithUserHP",
|
|
"PowerHigherWithTargetFasterThanUser",
|
|
"TypeAndPowerDependOnUserBerry",
|
|
"PowerHigherWithLessPP",
|
|
"PowerLowerWithUserHP",
|
|
"PowerHigherWithTargetWeight"].include?(m.function)
|
|
power = 80 if Settings::MECHANICS_GENERATION <= 5 && m.function == "TypeDependsOnUserIVs"
|
|
next if power < highestPower
|
|
forewarnMoves = [] if power > highestPower
|
|
forewarnMoves.push(m.name)
|
|
highestPower = power
|
|
end
|
|
end
|
|
if forewarnMoves.length > 0
|
|
battle.pbShowAbilitySplash(battler)
|
|
forewarnMoveName = forewarnMoves[battle.pbRandom(forewarnMoves.length)]
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1} was alerted to {2}!",
|
|
battler.pbThis, forewarnMoveName))
|
|
else
|
|
battle.pbDisplay(_INTL("{1}'s Forewarn alerted it to {2}!",
|
|
battler.pbThis, forewarnMoveName))
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:FRISK,
|
|
proc { |ability, battler, battle, switch_in|
|
|
next if !battler.pbOwnedByPlayer?
|
|
foes = battle.allOtherSideBattlers(battler.index).select { |b| b.item }
|
|
if foes.length > 0
|
|
battle.pbShowAbilitySplash(battler)
|
|
if Settings::MECHANICS_GENERATION >= 6
|
|
foes.each do |b|
|
|
battle.pbDisplay(_INTL("{1} frisked {2} and found its {3}!",
|
|
battler.pbThis, b.pbThis(true), b.itemName))
|
|
end
|
|
else
|
|
foe = foes[battle.pbRandom(foes.length)]
|
|
battle.pbDisplay(_INTL("{1} frisked the foe and found one {2}!",
|
|
battler.pbThis, foe.itemName))
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:GRASSYSURGE,
|
|
proc { |ability, battler, battle, switch_in|
|
|
next if battle.field.terrain == :Grassy
|
|
battle.pbShowAbilitySplash(battler)
|
|
battle.pbStartTerrain(battler, :Grassy)
|
|
# NOTE: The ability splash is hidden again in def pbStartTerrain.
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:ICEFACE,
|
|
proc { |ability, battler, battle, switch_in|
|
|
next if !battler.isSpecies?(:EISCUE) || battler.form != 1
|
|
next if battler.effectiveWeather != :Hail
|
|
battle.pbShowAbilitySplash(battler)
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1}'s {2} activated!", battler.pbThis, battler.abilityName))
|
|
end
|
|
battler.pbChangeForm(0, _INTL("{1} transformed!", battler.pbThis))
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:IMPOSTER,
|
|
proc { |ability, battler, battle, switch_in|
|
|
next if !switch_in || battler.effects[PBEffects::Transform]
|
|
choice = battler.pbDirectOpposing
|
|
next if choice.fainted?
|
|
next if choice.effects[PBEffects::Transform] ||
|
|
choice.effects[PBEffects::Illusion] ||
|
|
choice.effects[PBEffects::Substitute] > 0 ||
|
|
choice.effects[PBEffects::SkyDrop] >= 0 ||
|
|
choice.semiInvulnerable?
|
|
battle.pbShowAbilitySplash(battler, true)
|
|
battle.pbHideAbilitySplash(battler)
|
|
battle.pbAnimation(:TRANSFORM, battler, choice)
|
|
battle.scene.pbChangePokemon(battler, choice.pokemon)
|
|
battler.pbTransform(choice)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:INTIMIDATE,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbShowAbilitySplash(battler)
|
|
battle.allOtherSideBattlers(battler.index).each do |b|
|
|
next if !b.near?(battler)
|
|
check_item = true
|
|
if b.hasActiveAbility?(:CONTRARY)
|
|
check_item = false if b.statStageAtMax?(:ATTACK)
|
|
elsif b.statStageAtMin?(:ATTACK)
|
|
check_item = false
|
|
end
|
|
check_ability = b.pbLowerAttackStatStageIntimidate(battler)
|
|
b.pbAbilitiesOnIntimidated if check_ability
|
|
b.pbItemOnIntimidatedCheck if check_item
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:INTREPIDSWORD,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battler.pbRaiseStatStageByAbility(:ATTACK, 1, battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:MIMICRY,
|
|
proc { |ability, battler, battle, switch_in|
|
|
next if battle.field.terrain == :None
|
|
Battle::AbilityEffects.triggerOnTerrainChange(ability, battler, battle, false)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:MISTYSURGE,
|
|
proc { |ability, battler, battle, switch_in|
|
|
next if battle.field.terrain == :Misty
|
|
battle.pbShowAbilitySplash(battler)
|
|
battle.pbStartTerrain(battler, :Misty)
|
|
# NOTE: The ability splash is hidden again in def pbStartTerrain.
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:MOLDBREAKER,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbShowAbilitySplash(battler)
|
|
battle.pbDisplay(_INTL("{1} breaks the mold!", battler.pbThis))
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:NEUTRALIZINGGAS,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbShowAbilitySplash(battler, true)
|
|
battle.pbHideAbilitySplash(battler)
|
|
battle.pbDisplay(_INTL("Neutralizing gas filled the area!"))
|
|
battle.allBattlers.each do |b|
|
|
# Slow Start - end all turn counts
|
|
b.effects[PBEffects::SlowStart] = 0
|
|
# Truant - let b move on its first turn after Neutralizing Gas disappears
|
|
b.effects[PBEffects::Truant] = false
|
|
# Gorilla Tactics - end choice lock
|
|
if !b.hasActiveItem?([:CHOICEBAND, :CHOICESPECS, :CHOICESCARF])
|
|
b.effects[PBEffects::ChoiceBand] = nil
|
|
end
|
|
# Illusion - end illusions
|
|
if b.effects[PBEffects::Illusion]
|
|
b.effects[PBEffects::Illusion] = nil
|
|
if !b.effects[PBEffects::Transform]
|
|
battle.scene.pbChangePokemon(b, b.pokemon)
|
|
battle.pbDisplay(_INTL("{1}'s {2} wore off!", b.pbThis, b.abilityName))
|
|
battle.pbSetSeen(b)
|
|
end
|
|
end
|
|
end
|
|
# Trigger items upon Unnerve being negated
|
|
battler.ability_id = nil # Allows checking if Unnerve was active before
|
|
had_unnerve = battle.pbCheckGlobalAbility(:UNNERVE)
|
|
battler.ability_id = :NEUTRALIZINGGAS
|
|
if had_unnerve && !battle.pbCheckGlobalAbility(:UNNERVE)
|
|
battle.allBattlers.each { |b| b.pbItemsOnUnnerveEnding }
|
|
end
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:PASTELVEIL,
|
|
proc { |ability, battler, battle, switch_in|
|
|
next if battler.allAllies.none? { |b| b.status == :POISON }
|
|
battle.pbShowAbilitySplash(battler)
|
|
battler.allAllies.each do |b|
|
|
next if b.status != :POISON
|
|
b.pbCureStatus(Battle::Scene::USE_ABILITY_SPLASH)
|
|
if !Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1}'s {2} cured {3}'s poisoning!",
|
|
battler.pbThis, battler.abilityName, b.pbThis(true)))
|
|
end
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:PRESSURE,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbShowAbilitySplash(battler)
|
|
battle.pbDisplay(_INTL("{1} is exerting its pressure!", battler.pbThis))
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:PRIMORDIALSEA,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbStartWeatherAbility(:HeavyRain, battler, true)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:PSYCHICSURGE,
|
|
proc { |ability, battler, battle, switch_in|
|
|
next if battle.field.terrain == :Psychic
|
|
battle.pbShowAbilitySplash(battler)
|
|
battle.pbStartTerrain(battler, :Psychic)
|
|
# NOTE: The ability splash is hidden again in def pbStartTerrain.
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:SANDSTREAM,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbStartWeatherAbility(:Sandstorm, battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:SCREENCLEANER,
|
|
proc { |ability, battler, battle, switch_in|
|
|
next if battler.pbOwnSide.effects[PBEffects::AuroraVeil] == 0 &&
|
|
battler.pbOwnSide.effects[PBEffects::LightScreen] == 0 &&
|
|
battler.pbOwnSide.effects[PBEffects::Reflect] == 0 &&
|
|
battler.pbOpposingSide.effects[PBEffects::AuroraVeil] == 0 &&
|
|
battler.pbOpposingSide.effects[PBEffects::LightScreen] == 0 &&
|
|
battler.pbOpposingSide.effects[PBEffects::Reflect] == 0
|
|
battle.pbShowAbilitySplash(battler)
|
|
if battler.pbOpposingSide.effects[PBEffects::AuroraVeil] > 0
|
|
battler.pbOpposingSide.effects[PBEffects::AuroraVeil] = 0
|
|
battle.pbDisplay(_INTL("{1}'s Aurora Veil wore off!", battler.pbOpposingTeam))
|
|
end
|
|
if battler.pbOpposingSide.effects[PBEffects::LightScreen] > 0
|
|
battler.pbOpposingSide.effects[PBEffects::LightScreen] = 0
|
|
battle.pbDisplay(_INTL("{1}'s Light Screen wore off!", battler.pbOpposingTeam))
|
|
end
|
|
if battler.pbOpposingSide.effects[PBEffects::Reflect] > 0
|
|
battler.pbOpposingSide.effects[PBEffects::Reflect] = 0
|
|
battle.pbDisplay(_INTL("{1}'s Reflect wore off!", battler.pbOpposingTeam))
|
|
end
|
|
if battler.pbOwnSide.effects[PBEffects::AuroraVeil] > 0
|
|
battler.pbOwnSide.effects[PBEffects::AuroraVeil] = 0
|
|
battle.pbDisplay(_INTL("{1}'s Aurora Veil wore off!", battler.pbTeam))
|
|
end
|
|
if battler.pbOwnSide.effects[PBEffects::LightScreen] > 0
|
|
battler.pbOwnSide.effects[PBEffects::LightScreen] = 0
|
|
battle.pbDisplay(_INTL("{1}'s Light Screen wore off!", battler.pbTeam))
|
|
end
|
|
if battler.pbOwnSide.effects[PBEffects::Reflect] > 0
|
|
battler.pbOwnSide.effects[PBEffects::Reflect] = 0
|
|
battle.pbDisplay(_INTL("{1}'s Reflect wore off!", battler.pbTeam))
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:SLOWSTART,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbShowAbilitySplash(battler)
|
|
battler.effects[PBEffects::SlowStart] = 5
|
|
if Battle::Scene::USE_ABILITY_SPLASH
|
|
battle.pbDisplay(_INTL("{1} can't get it going!", battler.pbThis))
|
|
else
|
|
battle.pbDisplay(_INTL("{1} can't get it going because of its {2}!",
|
|
battler.pbThis, battler.abilityName))
|
|
end
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:SNOWWARNING,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbStartWeatherAbility(:Hail, battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:TERAVOLT,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbShowAbilitySplash(battler)
|
|
battle.pbDisplay(_INTL("{1} is radiating a bursting aura!", battler.pbThis))
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:TURBOBLAZE,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbShowAbilitySplash(battler)
|
|
battle.pbDisplay(_INTL("{1} is radiating a blazing aura!", battler.pbThis))
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchIn.add(:UNNERVE,
|
|
proc { |ability, battler, battle, switch_in|
|
|
battle.pbShowAbilitySplash(battler)
|
|
battle.pbDisplay(_INTL("{1} is too nervous to eat Berries!", battler.pbOpposingTeam))
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# OnSwitchOut handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::OnSwitchOut.add(:IMMUNITY,
|
|
proc { |ability, battler, endOfBattle|
|
|
next if battler.status != :POISON
|
|
PBDebug.log("[Ability triggered] #{battler.pbThis}'s #{battler.abilityName}")
|
|
battler.status = :NONE
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchOut.add(:INSOMNIA,
|
|
proc { |ability, battler, endOfBattle|
|
|
next if battler.status != :SLEEP
|
|
PBDebug.log("[Ability triggered] #{battler.pbThis}'s #{battler.abilityName}")
|
|
battler.status = :NONE
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchOut.copy(:INSOMNIA, :VITALSPIRIT)
|
|
|
|
Battle::AbilityEffects::OnSwitchOut.add(:LIMBER,
|
|
proc { |ability, battler, endOfBattle|
|
|
next if battler.status != :PARALYSIS
|
|
PBDebug.log("[Ability triggered] #{battler.pbThis}'s #{battler.abilityName}")
|
|
battler.status = :NONE
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchOut.add(:MAGMAARMOR,
|
|
proc { |ability, battler, endOfBattle|
|
|
next if battler.status != :FROZEN
|
|
PBDebug.log("[Ability triggered] #{battler.pbThis}'s #{battler.abilityName}")
|
|
battler.status = :NONE
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchOut.add(:NATURALCURE,
|
|
proc { |ability, battler, endOfBattle|
|
|
PBDebug.log("[Ability triggered] #{battler.pbThis}'s #{battler.abilityName}")
|
|
battler.status = :NONE
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchOut.add(:REGENERATOR,
|
|
proc { |ability, battler, endOfBattle|
|
|
next if endOfBattle
|
|
PBDebug.log("[Ability triggered] #{battler.pbThis}'s #{battler.abilityName}")
|
|
battler.pbRecoverHP(battler.totalhp / 3, false, false)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchOut.add(:WATERVEIL,
|
|
proc { |ability, battler, endOfBattle|
|
|
next if battler.status != :BURN
|
|
PBDebug.log("[Ability triggered] #{battler.pbThis}'s #{battler.abilityName}")
|
|
battler.status = :NONE
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::OnSwitchOut.copy(:WATERVEIL, :WATERBUBBLE)
|
|
|
|
#===============================================================================
|
|
# ChangeOnBattlerFainting handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::ChangeOnBattlerFainting.add(:POWEROFALCHEMY,
|
|
proc { |ability, battler, fainted, battle|
|
|
next if battler.opposes?(fainted)
|
|
next if fainted.ungainableAbility? ||
|
|
[:POWEROFALCHEMY, :RECEIVER, :TRACE, :WONDERGUARD].include?(fainted.ability_id)
|
|
battle.pbShowAbilitySplash(battler, true)
|
|
battler.ability = fainted.ability
|
|
battle.pbReplaceAbilitySplash(battler)
|
|
battle.pbDisplay(_INTL("{1}'s {2} was taken over!", fainted.pbThis, fainted.abilityName))
|
|
battle.pbHideAbilitySplash(battler)
|
|
}
|
|
)
|
|
|
|
Battle::AbilityEffects::ChangeOnBattlerFainting.copy(:POWEROFALCHEMY, :RECEIVER)
|
|
|
|
#===============================================================================
|
|
# OnBattlerFainting handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::OnBattlerFainting.add(:SOULHEART,
|
|
proc { |ability, battler, fainted, battle|
|
|
battler.pbRaiseStatStageByAbility(:SPECIAL_ATTACK, 1, battler)
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# OnTerrainChange handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::OnTerrainChange.add(:MIMICRY,
|
|
proc { |ability, battler, battle, ability_changed|
|
|
if battle.field.terrain == :None
|
|
# Revert to original typing
|
|
battle.pbShowAbilitySplash(battler)
|
|
battler.pbResetTypes
|
|
battle.pbDisplay(_INTL("{1} changed back to its regular type!", battler.pbThis))
|
|
battle.pbHideAbilitySplash(battler)
|
|
else
|
|
# Change to new typing
|
|
terrain_hash = {
|
|
:Electric => :ELECTRIC,
|
|
:Grassy => :GRASS,
|
|
:Misty => :FAIRY,
|
|
:Psychic => :PSYCHIC
|
|
}
|
|
new_type = terrain_hash[battle.field.terrain]
|
|
new_type_name = nil
|
|
if new_type
|
|
type_data = GameData::Type.try_get(new_type)
|
|
new_type = nil if !type_data
|
|
new_type_name = type_data.name if type_data
|
|
end
|
|
if new_type
|
|
battle.pbShowAbilitySplash(battler)
|
|
battler.pbChangeTypes(new_type)
|
|
battle.pbDisplay(_INTL("{1}'s type changed to {2}!", battler.pbThis, new_type_name))
|
|
battle.pbHideAbilitySplash(battler)
|
|
end
|
|
end
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# OnIntimidated handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::OnIntimidated.add(:RATTLED,
|
|
proc { |ability, battler, battle|
|
|
next if Settings::MECHANICS_GENERATION < 8
|
|
battler.pbRaiseStatStageByAbility(:SPEED, 1, battler)
|
|
}
|
|
)
|
|
|
|
#===============================================================================
|
|
# CertainEscapeFromBattle handlers
|
|
#===============================================================================
|
|
|
|
Battle::AbilityEffects::CertainEscapeFromBattle.add(:RUNAWAY,
|
|
proc { |ability, battler|
|
|
next true
|
|
}
|
|
)
|