Files
infinitefusion-e18/Data/Scripts/011_Battle/003_Move/013_MoveEffects_SwitchingActing.rb

923 lines
37 KiB
Ruby

#===============================================================================
# User flees from battle. (Teleport (Gen 7-))
#===============================================================================
class Battle::Move::FleeFromBattle < Battle::Move
def pbMoveFailed?(user, targets)
if !@battle.pbCanRun?(user.index)
@battle.pbDisplay(_INTL("But it failed!"))
return true
end
return false
end
def pbEffectGeneral(user)
@battle.pbDisplay(_INTL("{1} fled from battle!", user.pbThis))
@battle.decision = 3 # Escaped
end
end
#===============================================================================
# User switches out. If user is a wild Pokémon, ends the battle instead.
# (Teleport (Gen 8+))
#===============================================================================
class Battle::Move::SwitchOutUserStatusMove < Battle::Move
def pbMoveFailed?(user, targets)
if user.wild?
if !@battle.pbCanRun?(user.index)
@battle.pbDisplay(_INTL("But it failed!"))
return true
end
elsif !@battle.pbCanChooseNonActive?(user.index)
@battle.pbDisplay(_INTL("But it failed!"))
return true
end
return false
end
def pbEndOfMoveUsageEffect(user, targets, numHits, switchedBattlers)
return if user.wild?
@battle.pbDisplay(_INTL("{1} went back to {2}!", user.pbThis,
@battle.pbGetOwnerName(user.index)))
@battle.pbPursuit(user.index)
return if user.fainted?
newPkmn = @battle.pbGetReplacementPokemonIndex(user.index) # Owner chooses
return if newPkmn < 0
@battle.pbRecallAndReplace(user.index, newPkmn)
@battle.pbClearChoice(user.index) # Replacement Pokémon does nothing this round
@battle.moldBreaker = false
@battle.pbOnBattlerEnteringBattle(user.index)
switchedBattlers.push(user.index)
end
def pbEffectGeneral(user)
if user.wild?
@battle.pbDisplay(_INTL("{1} fled from battle!", user.pbThis))
@battle.decision = 3 # Escaped
end
end
end
#===============================================================================
# After inflicting damage, user switches out. Ignores trapping moves.
# (U-turn, Volt Switch)
#===============================================================================
class Battle::Move::SwitchOutUserDamagingMove < Battle::Move
def pbEndOfMoveUsageEffect(user, targets, numHits, switchedBattlers)
return if user.fainted? || numHits == 0 || @battle.pbAllFainted?(user.idxOpposingSide)
targetSwitched = true
targets.each do |b|
targetSwitched = false if !switchedBattlers.include?(b.index)
end
return if targetSwitched
return if !@battle.pbCanChooseNonActive?(user.index)
@battle.pbDisplay(_INTL("{1} went back to {2}!", user.pbThis,
@battle.pbGetOwnerName(user.index)))
@battle.pbPursuit(user.index)
return if user.fainted?
newPkmn = @battle.pbGetReplacementPokemonIndex(user.index) # Owner chooses
return if newPkmn < 0
@battle.pbRecallAndReplace(user.index, newPkmn)
@battle.pbClearChoice(user.index) # Replacement Pokémon does nothing this round
@battle.moldBreaker = false
@battle.pbOnBattlerEnteringBattle(user.index)
switchedBattlers.push(user.index)
end
end
#===============================================================================
# Decreases the target's Attack and Special Attack by 1 stage each. Then, user
# switches out. Ignores trapping moves. (Parting Shot)
#===============================================================================
class Battle::Move::LowerTargetAtkSpAtk1SwitchOutUser < Battle::Move::TargetMultiStatDownMove
def initialize(battle, move)
super
@statDown = [:ATTACK, 1, :SPECIAL_ATTACK, 1]
end
def pbEndOfMoveUsageEffect(user, targets, numHits, switchedBattlers)
switcher = user
targets.each do |b|
next if switchedBattlers.include?(b.index)
switcher = b if b.effects[PBEffects::MagicCoat] || b.effects[PBEffects::MagicBounce]
end
return if switcher.fainted? || numHits == 0
return if !@battle.pbCanChooseNonActive?(switcher.index)
@battle.pbDisplay(_INTL("{1} went back to {2}!", switcher.pbThis,
@battle.pbGetOwnerName(switcher.index)))
@battle.pbPursuit(switcher.index)
return if switcher.fainted?
newPkmn = @battle.pbGetReplacementPokemonIndex(switcher.index) # Owner chooses
return if newPkmn < 0
@battle.pbRecallAndReplace(switcher.index, newPkmn)
@battle.pbClearChoice(switcher.index) # Replacement Pokémon does nothing this round
@battle.moldBreaker = false if switcher.index == user.index
@battle.pbOnBattlerEnteringBattle(switcher.index)
switchedBattlers.push(switcher.index)
end
end
#===============================================================================
# User switches out. Various effects affecting the user are passed to the
# replacement. (Baton Pass)
#===============================================================================
class Battle::Move::SwitchOutUserPassOnEffects < Battle::Move
def pbMoveFailed?(user, targets)
if !@battle.pbCanChooseNonActive?(user.index)
@battle.pbDisplay(_INTL("But it failed!"))
return true
end
return false
end
def pbEndOfMoveUsageEffect(user, targets, numHits, switchedBattlers)
return if user.fainted? || numHits == 0
return if !@battle.pbCanChooseNonActive?(user.index)
@battle.pbPursuit(user.index)
return if user.fainted?
newPkmn = @battle.pbGetReplacementPokemonIndex(user.index) # Owner chooses
return if newPkmn < 0
@battle.pbRecallAndReplace(user.index, newPkmn, false, true)
@battle.pbClearChoice(user.index) # Replacement Pokémon does nothing this round
@battle.moldBreaker = false
@battle.pbOnBattlerEnteringBattle(user.index)
switchedBattlers.push(user.index)
end
end
#===============================================================================
# In wild battles, makes target flee. Fails if target is a higher level than the
# user.
# In trainer battles, target switches out.
# For status moves. (Roar, Whirlwind)
#===============================================================================
class Battle::Move::SwitchOutTargetStatusMove < Battle::Move
def ignoresSubstitute?(user); return true; end
def canMagicCoat?; return true; end
def pbFailsAgainstTarget?(user, target, show_message)
if target.hasActiveAbility?(:SUCTIONCUPS) && !@battle.moldBreaker
if show_message
@battle.pbShowAbilitySplash(target)
if Battle::Scene::USE_ABILITY_SPLASH
@battle.pbDisplay(_INTL("{1} anchors itself!", target.pbThis))
else
@battle.pbDisplay(_INTL("{1} anchors itself with {2}!", target.pbThis, target.abilityName))
end
@battle.pbHideAbilitySplash(target)
end
return true
end
if target.effects[PBEffects::Ingrain]
@battle.pbDisplay(_INTL("{1} anchored itself with its roots!", target.pbThis)) if show_message
return true
end
if !@battle.canRun
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
if @battle.wildBattle? && target.level > user.level
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
if @battle.trainerBattle?
canSwitch = false
@battle.eachInTeamFromBattlerIndex(target.index) do |_pkmn, i|
next if !@battle.pbCanSwitchLax?(target.index, i)
canSwitch = true
break
end
if !canSwitch
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
end
return false
end
def pbEffectGeneral(user)
@battle.decision = 3 if @battle.wildBattle? # Escaped from battle
end
def pbSwitchOutTargetEffect(user, targets, numHits, switched_battlers)
return if @battle.wildBattle? || !switched_battlers.empty?
return if user.fainted? || numHits == 0
targets.each do |b|
next if b.fainted? || b.damageState.unaffected
next if b.effects[PBEffects::Ingrain]
next if b.hasActiveAbility?(:SUCTIONCUPS) && !@battle.moldBreaker
newPkmn = @battle.pbGetReplacementPokemonIndex(b.index, true) # Random
next if newPkmn < 0
@battle.pbRecallAndReplace(b.index, newPkmn, true)
@battle.pbDisplay(_INTL("{1} was dragged out!", b.pbThis))
@battle.pbClearChoice(b.index) # Replacement Pokémon does nothing this round
@battle.pbOnBattlerEnteringBattle(b.index)
switched_battlers.push(b.index)
break
end
end
end
#===============================================================================
# In wild battles, makes target flee. Fails if target is a higher level than the
# user.
# In trainer battles, target switches out.
# For damaging moves. (Circle Throw, Dragon Tail)
#===============================================================================
class Battle::Move::SwitchOutTargetDamagingMove < Battle::Move
def pbEffectAgainstTarget(user, target)
if @battle.wildBattle? && target.level <= user.level && @battle.canRun &&
(target.effects[PBEffects::Substitute] == 0 || ignoresSubstitute?(user))
@battle.decision = 3
end
end
def pbSwitchOutTargetEffect(user, targets, numHits, switched_battlers)
return if @battle.wildBattle? || !switched_battlers.empty?
return if user.fainted? || numHits == 0
targets.each do |b|
next if b.fainted? || b.damageState.unaffected || b.damageState.substitute
next if b.effects[PBEffects::Ingrain]
next if b.hasActiveAbility?(:SUCTIONCUPS) && !@battle.moldBreaker
newPkmn = @battle.pbGetReplacementPokemonIndex(b.index, true) # Random
next if newPkmn < 0
@battle.pbRecallAndReplace(b.index, newPkmn, true)
@battle.pbDisplay(_INTL("{1} was dragged out!", b.pbThis))
@battle.pbClearChoice(b.index) # Replacement Pokémon does nothing this round
@battle.pbOnBattlerEnteringBattle(b.index)
switched_battlers.push(b.index)
break
end
end
end
#===============================================================================
# Trapping move. Traps for 5 or 6 rounds. Trapped Pokémon lose 1/16 of max HP
# at end of each round.
#===============================================================================
class Battle::Move::BindTarget < Battle::Move
def pbEffectAgainstTarget(user, target)
return if target.fainted? || target.damageState.substitute
return if target.effects[PBEffects::Trapping] > 0
# Set trapping effect duration and info
if user.hasActiveItem?(:GRIPCLAW)
target.effects[PBEffects::Trapping] = (Settings::MECHANICS_GENERATION >= 5) ? 8 : 6
else
target.effects[PBEffects::Trapping] = 5 + @battle.pbRandom(2)
end
target.effects[PBEffects::TrappingMove] = @id
target.effects[PBEffects::TrappingUser] = user.index
# Message
msg = _INTL("{1} was trapped in the vortex!", target.pbThis)
case @id
when :BIND
msg = _INTL("{1} was squeezed by {2}!", target.pbThis, user.pbThis(true))
when :CLAMP
msg = _INTL("{1} clamped {2}!", user.pbThis, target.pbThis(true))
when :FIRESPIN
msg = _INTL("{1} was trapped in the fiery vortex!", target.pbThis)
when :INFESTATION
msg = _INTL("{1} has been afflicted with an infestation by {2}!", target.pbThis, user.pbThis(true))
when :MAGMASTORM
msg = _INTL("{1} became trapped by Magma Storm!", target.pbThis)
when :SANDTOMB
msg = _INTL("{1} became trapped by Sand Tomb!", target.pbThis)
when :WHIRLPOOL
msg = _INTL("{1} became trapped in the vortex!", target.pbThis)
when :WRAP
msg = _INTL("{1} was wrapped by {2}!", target.pbThis, user.pbThis(true))
end
@battle.pbDisplay(msg)
end
end
#===============================================================================
# Trapping move. Traps for 5 or 6 rounds. Trapped Pokémon lose 1/16 of max HP
# at end of each round. (Whirlpool)
# Power is doubled if target is using Dive. Hits some semi-invulnerable targets.
#===============================================================================
class Battle::Move::BindTargetDoublePowerIfTargetUnderwater < Battle::Move::BindTarget
def hitsDivingTargets?; return true; end
def pbModifyDamage(damageMult, user, target)
damageMult *= 2 if target.inTwoTurnAttack?("TwoTurnAttackInvulnerableUnderwater")
return damageMult
end
end
#===============================================================================
# Target can no longer switch out or flee, as long as the user remains active.
# (Anchor Shot, Block, Mean Look, Spider Web, Spirit Shackle, Thousand Waves)
#===============================================================================
class Battle::Move::TrapTargetInBattle < Battle::Move
def canMagicCoat?; return true; end
def pbFailsAgainstTarget?(user, target, show_message)
return false if damagingMove?
if target.effects[PBEffects::MeanLook] >= 0
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
if Settings::MORE_TYPE_EFFECTS && target.pbHasType?(:GHOST)
@battle.pbDisplay(_INTL("It doesn't affect {1}...", target.pbThis(true))) if show_message
return true
end
return false
end
def pbEffectAgainstTarget(user, target)
return if damagingMove?
target.effects[PBEffects::MeanLook] = user.index
@battle.pbDisplay(_INTL("{1} can no longer escape!", target.pbThis))
end
def pbAdditionalEffect(user, target)
return if target.fainted? || target.damageState.substitute
return if target.effects[PBEffects::MeanLook] >= 0
return if Settings::MORE_TYPE_EFFECTS && target.pbHasType?(:GHOST)
target.effects[PBEffects::MeanLook] = user.index
@battle.pbDisplay(_INTL("{1} can no longer escape!", target.pbThis))
end
end
#===============================================================================
# The target can no longer switch out or flee, while the user remains in battle.
# At the end of each round, the target's Defense and Special Defense are lowered
# by 1 stage each. (Octolock)
#===============================================================================
class Battle::Move::TrapTargetInBattleLowerTargetDefSpDef1EachTurn < Battle::Move
def pbFailsAgainstTarget?(user, target, show_message)
return false if damagingMove?
if target.effects[PBEffects::Octolock] >= 0
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
if Settings::MORE_TYPE_EFFECTS && target.pbHasType?(:GHOST)
@battle.pbDisplay(_INTL("It doesn't affect {1}...", target.pbThis(true))) if show_message
return true
end
return false
end
def pbEffectAgainstTarget(user, target)
target.effects[PBEffects::Octolock] = user.index
@battle.pbDisplay(_INTL("{1} can no longer escape because of {2}!", target.pbThis, @name))
end
end
#===============================================================================
# Prevents the user and the target from switching out or fleeing. This effect
# isn't applied if either Pokémon is already prevented from switching out or
# fleeing. (Jaw Lock)
#===============================================================================
class Battle::Move::TrapUserAndTargetInBattle < Battle::Move
def pbAdditionalEffect(user, target)
return if user.fainted? || target.fainted? || target.damageState.substitute
return if Settings::MORE_TYPE_EFFECTS && target.pbHasType?(:GHOST)
return if user.trappedInBattle? || target.trappedInBattle?
target.effects[PBEffects::JawLock] = user.index
@battle.pbDisplay(_INTL("Neither Pokémon can run away!"))
end
end
#===============================================================================
# No Pokémon can switch out or flee until the end of the next round. (Fairy Lock)
#===============================================================================
class Battle::Move::TrapAllBattlersInBattleForOneTurn < Battle::Move
def pbMoveFailed?(user, targets)
if @battle.field.effects[PBEffects::FairyLock] > 0
@battle.pbDisplay(_INTL("But it failed!"))
return true
end
return false
end
def pbEffectGeneral(user)
@battle.field.effects[PBEffects::FairyLock] = 2
@battle.pbDisplay(_INTL("No one will be able to run away during the next turn!"))
end
end
#===============================================================================
# Interrupts a foe switching out or using U-turn/Volt Switch/Parting Shot. Power
# is doubled in that case. (Pursuit)
# (Handled in Battle's pbAttackPhase): Makes this attack happen before switching.
#===============================================================================
class Battle::Move::PursueSwitchingFoe < Battle::Move
def pbAccuracyCheck(user, target)
return true if @battle.switching
return super
end
def pbBaseDamage(baseDmg, user, target)
baseDmg *= 2 if @battle.switching
return baseDmg
end
end
#===============================================================================
# Fails if user has not been hit by an opponent's physical move this round.
# (Shell Trap)
#===============================================================================
class Battle::Move::UsedAfterUserTakesPhysicalDamage < Battle::Move
def pbDisplayChargeMessage(user)
user.effects[PBEffects::ShellTrap] = true
@battle.pbCommonAnimation("ShellTrap", user)
@battle.pbDisplay(_INTL("{1} set a shell trap!", user.pbThis))
end
def pbDisplayUseMessage(user)
super if user.tookPhysicalHit
end
def pbMoveFailed?(user, targets)
if !user.effects[PBEffects::ShellTrap]
@battle.pbDisplay(_INTL("But it failed!"))
return true
end
if !user.tookPhysicalHit
@battle.pbDisplay(_INTL("{1}'s shell trap didn't work!", user.pbThis))
return true
end
return false
end
end
#===============================================================================
# Power is doubled if a user's ally has already used this move this round. (Round)
# If an ally is about to use the same move, make it go next, ignoring priority.
#===============================================================================
class Battle::Move::UsedAfterAllyRoundWithDoublePower < Battle::Move
def pbBaseDamage(baseDmg, user, target)
baseDmg *= 2 if user.pbOwnSide.effects[PBEffects::Round]
return baseDmg
end
def pbEffectGeneral(user)
user.pbOwnSide.effects[PBEffects::Round] = true
user.allAllies.each do |b|
next if @battle.choices[b.index][0] != :UseMove || b.movedThisRound?
next if @battle.choices[b.index][2].function != @function
b.effects[PBEffects::MoveNext] = true
b.effects[PBEffects::Quash] = 0
break
end
end
end
#===============================================================================
# Target moves immediately after the user, ignoring priority/speed. (After You)
#===============================================================================
class Battle::Move::TargetActsNext < Battle::Move
def ignoresSubstitute?(user); return true; end
def pbFailsAgainstTarget?(user, target, show_message)
# Target has already moved this round
return true if pbMoveFailedTargetAlreadyMoved?(target, show_message)
# Target was going to move next anyway (somehow)
if target.effects[PBEffects::MoveNext]
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
# Target didn't choose to use a move this round
oppMove = @battle.choices[target.index][2]
if !oppMove
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
return false
end
def pbEffectAgainstTarget(user, target)
target.effects[PBEffects::MoveNext] = true
target.effects[PBEffects::Quash] = 0
@battle.pbDisplay(_INTL("{1} took the kind offer!", target.pbThis))
end
end
#===============================================================================
# Target moves last this round, ignoring priority/speed. (Quash)
#===============================================================================
class Battle::Move::TargetActsLast < Battle::Move
def pbFailsAgainstTarget?(user, target, show_message)
return true if pbMoveFailedTargetAlreadyMoved?(target, show_message)
# Target isn't going to use a move
oppMove = @battle.choices[target.index][2]
if !oppMove
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
# Target is already maximally Quashed and will move last anyway
highestQuash = 0
@battle.allBattlers.each do |b|
next if b.effects[PBEffects::Quash] <= highestQuash
highestQuash = b.effects[PBEffects::Quash]
end
if highestQuash > 0 && target.effects[PBEffects::Quash] == highestQuash
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
# Target was already going to move last
if highestQuash == 0 && @battle.pbPriority.last.index == target.index
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
return false
end
def pbEffectAgainstTarget(user, target)
highestQuash = 0
@battle.allBattlers.each do |b|
next if b.effects[PBEffects::Quash] <= highestQuash
highestQuash = b.effects[PBEffects::Quash]
end
target.effects[PBEffects::Quash] = highestQuash + 1
target.effects[PBEffects::MoveNext] = false
@battle.pbDisplay(_INTL("{1}'s move was postponed!", target.pbThis))
end
end
#===============================================================================
# The target uses its most recent move again. (Instruct)
#===============================================================================
class Battle::Move::TargetUsesItsLastUsedMoveAgain < Battle::Move
attr_reader :moveBlacklist
def ignoresSubstitute?(user); return true; end
def initialize(battle, move)
super
@moveBlacklist = [
"MultiTurnAttackBideThenReturnDoubleDamage", # Bide
"ProtectUserFromDamagingMovesKingsShield", # King's Shield
"TargetUsesItsLastUsedMoveAgain", # Instruct (this move)
# Struggle
"Struggle", # Struggle
# Moves that affect the moveset
"ReplaceMoveThisBattleWithTargetLastMoveUsed", # Mimic
"ReplaceMoveWithTargetLastMoveUsed", # Sketch
"TransformUserIntoTarget", # Transform
# Moves that call other moves
"UseLastMoveUsedByTarget", # Mirror Move
"UseLastMoveUsed", # Copycat
"UseMoveTargetIsAboutToUse", # Me First
"UseMoveDependingOnEnvironment", # Nature Power
"UseRandomUserMoveIfAsleep", # Sleep Talk
"UseRandomMoveFromUserParty", # Assist
"UseRandomMove", # Metronome
# Moves that require a recharge turn
"AttackAndSkipNextTurn", # Hyper Beam
# Two-turn attacks
"TwoTurnAttack", # Razor Wind
"TwoTurnAttackOneTurnInSun", # Solar Beam, Solar Blade
"TwoTurnAttackParalyzeTarget", # Freeze Shock
"TwoTurnAttackBurnTarget", # Ice Burn
"TwoTurnAttackFlinchTarget", # Sky Attack
"TwoTurnAttackChargeRaiseUserDefense1", # Skull Bash
"TwoTurnAttackInvulnerableInSky", # Fly
"TwoTurnAttackInvulnerableUnderground", # Dig
"TwoTurnAttackInvulnerableUnderwater", # Dive
"TwoTurnAttackInvulnerableInSkyParalyzeTarget", # Bounce
"TwoTurnAttackInvulnerableRemoveProtections", # Shadow Force, Phantom Force
"TwoTurnAttackInvulnerableInSkyTargetCannotAct", # Sky Drop
"AllBattlersLoseHalfHPUserSkipsNextTurn", # Shadow Half
"TwoTurnAttackRaiseUserSpAtkSpDefSpd2", # Geomancy
# Moves that start focussing at the start of the round
"FailsIfUserDamagedThisTurn", # Focus Punch
"UsedAfterUserTakesPhysicalDamage", # Shell Trap
"BurnAttackerBeforeUserActs" # Beak Blast
]
end
def pbFailsAgainstTarget?(user, target, show_message)
if !target.lastRegularMoveUsed || !target.pbHasMove?(target.lastRegularMoveUsed)
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
if target.usingMultiTurnAttack?
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
targetMove = @battle.choices[target.index][2]
if targetMove && (targetMove.function == "FailsIfUserDamagedThisTurn" || # Focus Punch
targetMove.function == "UsedAfterUserTakesPhysicalDamage" || # Shell Trap
targetMove.function == "BurnAttackerBeforeUserActs") # Beak Blast
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
if @moveBlacklist.include?(GameData::Move.get(target.lastRegularMoveUsed).function_code)
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
idxMove = -1
target.eachMoveWithIndex do |m, i|
idxMove = i if m.id == target.lastRegularMoveUsed
end
if target.moves[idxMove].pp == 0 && target.moves[idxMove].total_pp > 0
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
return false
end
def pbEffectAgainstTarget(user, target)
target.effects[PBEffects::Instruct] = true
end
end
#===============================================================================
# For 5 rounds, for each priority bracket, slow Pokémon move before fast ones.
# (Trick Room)
#===============================================================================
class Battle::Move::StartSlowerBattlersActFirst < Battle::Move
def pbEffectGeneral(user)
if @battle.field.effects[PBEffects::TrickRoom] > 0
@battle.field.effects[PBEffects::TrickRoom] = 0
@battle.pbDisplay(_INTL("{1} reverted the dimensions!", user.pbThis))
else
@battle.field.effects[PBEffects::TrickRoom] = 5
@battle.pbDisplay(_INTL("{1} twisted the dimensions!", user.pbThis))
end
end
def pbShowAnimation(id, user, targets, hitNum = 0, showAnimation = true)
return if @battle.field.effects[PBEffects::TrickRoom] > 0 # No animation
super
end
end
#===============================================================================
# If Grassy Terrain applies, priority is increased by 1. (Grassy Glide)
#===============================================================================
class Battle::Move::HigherPriorityInGrassyTerrain < Battle::Move
def pbPriority(user)
ret = super
ret += 1 if @battle.field.terrain == :Grassy && user.affectedByTerrain?
return ret
end
end
#===============================================================================
# Target's last move used loses 3 PP. Damaging move. (Eerie Spell)
#===============================================================================
class Battle::Move::LowerPPOfTargetLastMoveBy3 < Battle::Move
def pbEffectAgainstTarget(user, target)
return if target.fainted?
last_move = target.pbGetMoveWithID(target.lastRegularMoveUsed)
return if !last_move || last_move.pp == 0 || last_move.total_pp <= 0
reduction = [3, last_move.pp].min
target.pbSetPP(last_move, last_move.pp - reduction)
@battle.pbDisplay(_INTL("It reduced the PP of {1}'s {2} by {3}!",
target.pbThis(true), last_move.name, reduction))
end
end
#===============================================================================
# Target's last move used loses 4 PP. Status move. (Spite)
#===============================================================================
class Battle::Move::LowerPPOfTargetLastMoveBy4 < Battle::Move
def ignoresSubstitute?(user); return true; end
def canMagicCoat?; return true; end
def pbFailsAgainstTarget?(user, target, show_message)
last_move = target.pbGetMoveWithID(target.lastRegularMoveUsed)
if !last_move || last_move.pp == 0 || last_move.total_pp <= 0
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
return false
end
def pbEffectAgainstTarget(user, target)
last_move = target.pbGetMoveWithID(target.lastRegularMoveUsed)
reduction = [4, last_move.pp].min
target.pbSetPP(last_move, last_move.pp - reduction)
@battle.pbDisplay(_INTL("It reduced the PP of {1}'s {2} by {3}!",
target.pbThis(true), last_move.name, reduction))
end
end
#===============================================================================
# For 5 rounds, disables the last move the target used. (Disable)
#===============================================================================
class Battle::Move::DisableTargetLastMoveUsed < Battle::Move
def ignoresSubstitute?(user); return true; end
def canMagicCoat?; return true; end
def pbFailsAgainstTarget?(user, target, show_message)
if target.effects[PBEffects::Disable] > 0 || !target.lastRegularMoveUsed
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
return true if pbMoveFailedAromaVeil?(user, target, show_message)
canDisable = false
target.eachMove do |m|
next if m.id != target.lastRegularMoveUsed
next if m.pp == 0 && m.total_pp > 0
canDisable = true
break
end
if !canDisable
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
return false
end
def pbEffectAgainstTarget(user, target)
target.effects[PBEffects::Disable] = 5
target.effects[PBEffects::DisableMove] = target.lastRegularMoveUsed
@battle.pbDisplay(_INTL("{1}'s {2} was disabled!", target.pbThis,
GameData::Move.get(target.lastRegularMoveUsed).name))
target.pbItemStatusCureCheck
end
end
#===============================================================================
# The target can no longer use the same move twice in a row. (Torment)
#===============================================================================
class Battle::Move::DisableTargetUsingSameMoveConsecutively < Battle::Move
def ignoresSubstitute?(user); return true; end
def canMagicCoat?; return true; end
def pbFailsAgainstTarget?(user, target, show_message)
if target.effects[PBEffects::Torment]
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
return true if pbMoveFailedAromaVeil?(user, target, show_message)
return false
end
def pbEffectAgainstTarget(user, target)
target.effects[PBEffects::Torment] = true
@battle.pbDisplay(_INTL("{1} was subjected to torment!", target.pbThis))
target.pbItemStatusCureCheck
end
end
#===============================================================================
# For 4 rounds, the target must use the same move each round. (Encore)
#===============================================================================
class Battle::Move::DisableTargetUsingDifferentMove < Battle::Move
attr_reader :moveBlacklist
def ignoresSubstitute?(user); return true; end
def canMagicCoat?; return true; end
def initialize(battle, move)
super
@moveBlacklist = [
"DisableTargetUsingDifferentMove", # Encore
# Struggle
"Struggle", # Struggle
# Moves that affect the moveset
"ReplaceMoveThisBattleWithTargetLastMoveUsed", # Mimic
"ReplaceMoveWithTargetLastMoveUsed", # Sketch
"TransformUserIntoTarget", # Transform
# Moves that call other moves (see also below)
"UseLastMoveUsedByTarget" # Mirror Move
]
if Settings::MECHANICS_GENERATION >= 7
@moveBlacklist += [
# Moves that call other moves
# "UseLastMoveUsedByTarget", # Mirror Move # See above
"UseLastMoveUsed", # Copycat
"UseMoveTargetIsAboutToUse", # Me First
"UseMoveDependingOnEnvironment", # Nature Power
"UseRandomUserMoveIfAsleep", # Sleep Talk
"UseRandomMoveFromUserParty", # Assist
"UseRandomMove" # Metronome
]
end
end
def pbFailsAgainstTarget?(user, target, show_message)
if target.effects[PBEffects::Encore] > 0
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
if !target.lastRegularMoveUsed ||
@moveBlacklist.include?(GameData::Move.get(target.lastRegularMoveUsed).function_code)
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
if target.effects[PBEffects::ShellTrap]
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
return true if pbMoveFailedAromaVeil?(user, target, show_message)
canEncore = false
target.eachMove do |m|
next if m.id != target.lastRegularMoveUsed
next if m.pp == 0 && m.total_pp > 0
canEncore = true
break
end
if !canEncore
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
return false
end
def pbEffectAgainstTarget(user, target)
target.effects[PBEffects::Encore] = 4
target.effects[PBEffects::EncoreMove] = target.lastRegularMoveUsed
@battle.pbDisplay(_INTL("{1} received an encore!", target.pbThis))
target.pbItemStatusCureCheck
end
end
#===============================================================================
# For 4 rounds, disables the target's non-damaging moves. (Taunt)
#===============================================================================
class Battle::Move::DisableTargetStatusMoves < Battle::Move
def ignoresSubstitute?(user); return true; end
def canMagicCoat?; return true; end
def pbFailsAgainstTarget?(user, target, show_message)
if target.effects[PBEffects::Taunt] > 0
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
return true if pbMoveFailedAromaVeil?(user, target, show_message)
if Settings::MECHANICS_GENERATION >= 6 && target.hasActiveAbility?(:OBLIVIOUS) &&
!@battle.moldBreaker
if show_message
@battle.pbShowAbilitySplash(target)
if Battle::Scene::USE_ABILITY_SPLASH
@battle.pbDisplay(_INTL("But it failed!"))
else
@battle.pbDisplay(_INTL("But it failed because of {1}'s {2}!",
target.pbThis(true), target.abilityName))
end
@battle.pbHideAbilitySplash(target)
end
return true
end
return false
end
def pbEffectAgainstTarget(user, target)
target.effects[PBEffects::Taunt] = 4
@battle.pbDisplay(_INTL("{1} fell for the taunt!", target.pbThis))
target.pbItemStatusCureCheck
end
end
#===============================================================================
# For 5 rounds, disables the target's healing moves. (Heal Block)
#===============================================================================
class Battle::Move::DisableTargetHealingMoves < Battle::Move
def canMagicCoat?; return true; end
def pbFailsAgainstTarget?(user, target, show_message)
if target.effects[PBEffects::HealBlock] > 0
@battle.pbDisplay(_INTL("But it failed!")) if show_message
return true
end
return true if pbMoveFailedAromaVeil?(user, target, show_message)
return false
end
def pbEffectAgainstTarget(user, target)
target.effects[PBEffects::HealBlock] = 5
@battle.pbDisplay(_INTL("{1} was prevented from healing!", target.pbThis))
target.pbItemStatusCureCheck
end
end
#===============================================================================
# Target cannot use sound-based moves for 2 more rounds. (Throat Chop)
#===============================================================================
class Battle::Move::DisableTargetSoundMoves < Battle::Move
def pbAdditionalEffect(user, target)
return if target.fainted? || target.damageState.substitute
if target.effects[PBEffects::ThroatChop] == 0
@battle.pbDisplay(_INTL("The effects of {1} prevent {2} from using certain moves!",
@name, target.pbThis(true)))
end
target.effects[PBEffects::ThroatChop] = 3
end
end
#===============================================================================
# Disables all target's moves that the user also knows. (Imprison)
#===============================================================================
class Battle::Move::DisableTargetMovesKnownByUser < Battle::Move
def canSnatch?; return true; end
def pbMoveFailed?(user, targets)
if user.effects[PBEffects::Imprison]
@battle.pbDisplay(_INTL("But it failed!"))
return true
end
return false
end
def pbEffectGeneral(user)
user.effects[PBEffects::Imprison] = true
@battle.pbDisplay(_INTL("{1} sealed any moves its target shares with it!", user.pbThis))
end
end