mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-10 06:34:59 +00:00
Renamed all battle-related classes and modules
This commit is contained in:
147
Data/Scripts/011_Battle/003_Move/001_Battle_Move.rb
Normal file
147
Data/Scripts/011_Battle/003_Move/001_Battle_Move.rb
Normal file
@@ -0,0 +1,147 @@
|
||||
class Battle::Move
|
||||
attr_reader :battle
|
||||
attr_reader :realMove
|
||||
attr_accessor :id
|
||||
attr_reader :name
|
||||
attr_reader :function
|
||||
attr_reader :baseDamage
|
||||
attr_reader :type
|
||||
attr_reader :category
|
||||
attr_reader :accuracy
|
||||
attr_accessor :pp
|
||||
attr_writer :total_pp
|
||||
attr_reader :addlEffect
|
||||
attr_reader :target
|
||||
attr_reader :priority
|
||||
attr_reader :flags
|
||||
attr_accessor :calcType
|
||||
attr_accessor :powerBoost
|
||||
attr_accessor :snatched
|
||||
|
||||
def to_int; return @id; end
|
||||
|
||||
#=============================================================================
|
||||
# Creating a move
|
||||
#=============================================================================
|
||||
def initialize(battle, move)
|
||||
@battle = battle
|
||||
@realMove = move
|
||||
@id = move.id
|
||||
@name = move.name # Get the move's name
|
||||
# Get data on the move
|
||||
@function = move.function_code
|
||||
@baseDamage = move.base_damage
|
||||
@type = move.type
|
||||
@category = move.category
|
||||
@accuracy = move.accuracy
|
||||
@pp = move.pp # Can be changed with Mimic/Transform
|
||||
@addlEffect = move.effect_chance
|
||||
@target = move.target
|
||||
@priority = move.priority
|
||||
@flags = move.flags.clone
|
||||
@calcType = nil
|
||||
@powerBoost = false # For Aerilate, Pixilate, Refrigerate, Galvanize
|
||||
@snatched = false
|
||||
end
|
||||
|
||||
# This is the code actually used to generate a Battle::Move object. The
|
||||
# object generated is a subclass of this one which depends on the move's
|
||||
# function code.
|
||||
def self.from_pokemon_move(battle, move)
|
||||
validate move => Pokemon::Move
|
||||
code = move.function_code || "None"
|
||||
if code[/^\d/] # Begins with a digit
|
||||
class_name = sprintf("Battle::Move::Effect%s", code)
|
||||
else
|
||||
class_name = sprintf("Battle::Move::%s", code)
|
||||
end
|
||||
if Object.const_defined?(class_name)
|
||||
return Object.const_get(class_name).new(battle, move)
|
||||
end
|
||||
return Battle::Move::Unimplemented.new(battle, move)
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# About the move
|
||||
#=============================================================================
|
||||
def pbTarget(_user); return GameData::Target.get(@target); end
|
||||
|
||||
def total_pp
|
||||
return @total_pp if @total_pp && @total_pp>0 # Usually undefined
|
||||
return @realMove.total_pp if @realMove
|
||||
return 0
|
||||
end
|
||||
|
||||
# NOTE: This method is only ever called while using a move (and also by the
|
||||
# AI), so using @calcType here is acceptable.
|
||||
def physicalMove?(thisType=nil)
|
||||
return (@category==0) if Settings::MOVE_CATEGORY_PER_MOVE
|
||||
thisType ||= @calcType
|
||||
thisType ||= @type
|
||||
return true if !thisType
|
||||
return GameData::Type.get(thisType).physical?
|
||||
end
|
||||
|
||||
# NOTE: This method is only ever called while using a move (and also by the
|
||||
# AI), so using @calcType here is acceptable.
|
||||
def specialMove?(thisType=nil)
|
||||
return (@category==1) if Settings::MOVE_CATEGORY_PER_MOVE
|
||||
thisType ||= @calcType
|
||||
thisType ||= @type
|
||||
return false if !thisType
|
||||
return GameData::Type.get(thisType).special?
|
||||
end
|
||||
|
||||
def damagingMove?; return @category!=2; end
|
||||
def statusMove?; return @category==2; end
|
||||
|
||||
def pbPriority(user); return @priority; end
|
||||
|
||||
def usableWhenAsleep?; return false; end
|
||||
def unusableInGravity?; return false; end
|
||||
def healingMove?; return false; end
|
||||
def recoilMove?; return false; end
|
||||
def flinchingMove?; return false; end
|
||||
def callsAnotherMove?; return false; end
|
||||
# Whether the move can/will hit more than once in the same turn (including
|
||||
# Beat Up which may instead hit just once). Not the same as pbNumHits>1.
|
||||
def multiHitMove?; return false; end
|
||||
def chargingTurnMove?; return false; end
|
||||
def successCheckPerHit?; return false; end
|
||||
def hitsFlyingTargets?; return false; end
|
||||
def hitsDiggingTargets?; return false; end
|
||||
def hitsDivingTargets?; return false; end
|
||||
def ignoresReflect?; return false; end # For Brick Break
|
||||
def targetsPosition?; return false; end # For Future Sight/Doom Desire
|
||||
def cannotRedirect?; return false; end # For Snipe Shot
|
||||
def worksWithNoTargets?; return false; end # For Explosion
|
||||
def damageReducedByBurn?; return true; end # For Facade
|
||||
def triggersHyperMode?; return false; end
|
||||
def canSnatch?; return false; end
|
||||
def canMagicCoat?; return false; end
|
||||
|
||||
def contactMove?; return @flags.any? { |f| f[/^Contact$/i] }; end
|
||||
def canProtectAgainst?; return @flags.any? { |f| f[/^CanProtect$/i] }; end
|
||||
def canMirrorMove?; return @flags.any? { |f| f[/^CanMirrorMove$/i] }; end
|
||||
def thawsUser?; return @flags.any? { |f| f[/^ThawsUser$/i] }; end
|
||||
def highCriticalRate?; return @flags.any? { |f| f[/^HighCriticalHitRate$/i] }; end
|
||||
def bitingMove?; return @flags.any? { |f| f[/^Biting$/i] }; end
|
||||
def punchingMove?; return @flags.any? { |f| f[/^Punching$/i] }; end
|
||||
def soundMove?; return @flags.any? { |f| f[/^Sound$/i] }; end
|
||||
def powderMove?; return @flags.any? { |f| f[/^Powder$/i] }; end
|
||||
def pulseMove?; return @flags.any? { |f| f[/^Pulse$/i] }; end
|
||||
def bombMove?; return @flags.any? { |f| f[/^Bomb$/i] }; end
|
||||
def danceMove?; return @flags.any? { |f| f[/^Dance$/i] }; end
|
||||
|
||||
# Causes perfect accuracy (param=1) and double damage (param=2).
|
||||
def tramplesMinimize?(_param=1); return false; end
|
||||
def nonLethal?(_user,_target); return false; end # For False Swipe
|
||||
|
||||
def ignoresSubstitute?(user) # user is the Pokémon using this move
|
||||
if Settings::MECHANICS_GENERATION >= 6
|
||||
return true if soundMove?
|
||||
return true if user && user.hasActiveAbility?(:INFILTRATOR)
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
387
Data/Scripts/011_Battle/003_Move/002_Move_Usage.rb
Normal file
387
Data/Scripts/011_Battle/003_Move/002_Move_Usage.rb
Normal file
@@ -0,0 +1,387 @@
|
||||
class Battle::Move
|
||||
#=============================================================================
|
||||
# Effect methods per move usage
|
||||
#=============================================================================
|
||||
def pbCanChooseMove?(user,commandPhase,showMessages); return true; end # For Belch
|
||||
def pbDisplayChargeMessage(user); end # For Focus Punch/shell Trap/Beak Blast
|
||||
def pbOnStartUse(user,targets); end
|
||||
def pbAddTarget(targets,user); end # For Counter, etc. and Bide
|
||||
def pbModifyTargets(targets, user); end # For Dragon Darts
|
||||
|
||||
# Reset move usage counters (child classes can increment them).
|
||||
def pbChangeUsageCounters(user,specialUsage)
|
||||
user.effects[PBEffects::FuryCutter] = 0
|
||||
user.effects[PBEffects::ParentalBond] = 0
|
||||
user.effects[PBEffects::ProtectRate] = 1
|
||||
@battle.field.effects[PBEffects::FusionBolt] = false
|
||||
@battle.field.effects[PBEffects::FusionFlare] = false
|
||||
end
|
||||
|
||||
def pbDisplayUseMessage(user)
|
||||
@battle.pbDisplayBrief(_INTL("{1} used {2}!",user.pbThis,@name))
|
||||
end
|
||||
|
||||
def pbShowFailMessages?(targets); return true; end
|
||||
def pbMissMessage(user,target); return false; end
|
||||
|
||||
#=============================================================================
|
||||
#
|
||||
#=============================================================================
|
||||
# Whether the move is currently in the "charging" turn of a two turn attack.
|
||||
# Is false if Power Herb or another effect lets a two turn move charge and
|
||||
# attack in the same turn.
|
||||
# user.effects[PBEffects::TwoTurnAttack] is set to the move's ID during the
|
||||
# charging turn, and is nil during the attack turn.
|
||||
def pbIsChargingTurn?(user); return false; end
|
||||
def pbDamagingMove?; return damagingMove?; end
|
||||
|
||||
def pbContactMove?(user)
|
||||
return false if user.hasActiveAbility?(:LONGREACH)
|
||||
return contactMove?
|
||||
end
|
||||
|
||||
# The maximum number of hits in a round this move will actually perform. This
|
||||
# can be 1 for Beat Up, and can be 2 for any moves affected by Parental Bond.
|
||||
def pbNumHits(user,targets)
|
||||
if user.hasActiveAbility?(:PARENTALBOND) && pbDamagingMove? &&
|
||||
!chargingTurnMove? && targets.length==1
|
||||
# Record that Parental Bond applies, to weaken the second attack
|
||||
user.effects[PBEffects::ParentalBond] = 3
|
||||
return 2
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Effect methods per hit
|
||||
#=============================================================================
|
||||
def pbOverrideSuccessCheckPerHit(user,target); return false; end
|
||||
def pbCrashDamage(user); end
|
||||
def pbInitialEffect(user,targets,hitNum); end
|
||||
def pbDesignateTargetsForHit(targets, hitNum); return targets; end # For Dragon Darts
|
||||
def pbRepeatHit?; return false; end # For Dragon Darts
|
||||
|
||||
def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true)
|
||||
return if !showAnimation
|
||||
if user.effects[PBEffects::ParentalBond]==1
|
||||
@battle.pbCommonAnimation("ParentalBond",user,targets)
|
||||
else
|
||||
@battle.pbAnimation(id,user,targets,hitNum)
|
||||
end
|
||||
end
|
||||
|
||||
def pbSelfKO(user); end
|
||||
def pbEffectWhenDealingDamage(user,target); end
|
||||
def pbEffectAgainstTarget(user,target); end
|
||||
def pbEffectGeneral(user); end
|
||||
def pbAdditionalEffect(user,target); end
|
||||
def pbEffectAfterAllHits(user,target); end # Move effects that occur after all hits
|
||||
def pbSwitchOutTargetEffect(user, targets, numHits, switched_battlers); end
|
||||
def pbEndOfMoveUsageEffect(user,targets,numHits,switchedBattlers); end
|
||||
|
||||
#=============================================================================
|
||||
# Check if target is immune to the move because of its ability
|
||||
#=============================================================================
|
||||
def pbImmunityByAbility(user, target, show_message)
|
||||
return false if @battle.moldBreaker
|
||||
ret = false
|
||||
if target.abilityActive?
|
||||
ret = BattleHandlers.triggerMoveImmunityTargetAbility(target.ability,
|
||||
user, target, self, @calcType, @battle, show_message)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Move failure checks
|
||||
#=============================================================================
|
||||
# Check whether the move fails completely due to move-specific requirements.
|
||||
def pbMoveFailed?(user,targets); return false; end
|
||||
# Checks whether the move will be ineffective against the target.
|
||||
def pbFailsAgainstTarget?(user, target, show_message); return false; end
|
||||
|
||||
def pbMoveFailedLastInRound?(user, showMessage = true)
|
||||
unmoved = @battle.allBattlers.any? { |b|
|
||||
next b.index != user.index &&
|
||||
[:UseMove, :Shift].include?(@battle.choices[b.index][0]) &&
|
||||
!b.movedThisRound?
|
||||
}
|
||||
if !unmoved
|
||||
@battle.pbDisplay(_INTL("But it failed!")) if showMessage
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbMoveFailedTargetAlreadyMoved?(target, showMessage = true)
|
||||
if (@battle.choices[target.index][0]!=:UseMove &&
|
||||
@battle.choices[target.index][0]!=:Shift) || target.movedThisRound?
|
||||
@battle.pbDisplay(_INTL("But it failed!")) if showMessage
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbMoveFailedAromaVeil?(user,target,showMessage=true)
|
||||
return false if @battle.moldBreaker
|
||||
if target.hasActiveAbility?(:AROMAVEIL)
|
||||
if showMessage
|
||||
@battle.pbShowAbilitySplash(target)
|
||||
if Battle::Scene::USE_ABILITY_SPLASH
|
||||
@battle.pbDisplay(_INTL("{1} is unaffected!",target.pbThis))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("{1} is unaffected because of its {2}!",
|
||||
target.pbThis,target.abilityName))
|
||||
end
|
||||
@battle.pbHideAbilitySplash(target)
|
||||
end
|
||||
return true
|
||||
end
|
||||
target.allAllies.each do |b|
|
||||
next if !b.hasActiveAbility?(:AROMAVEIL)
|
||||
if showMessage
|
||||
@battle.pbShowAbilitySplash(target)
|
||||
if Battle::Scene::USE_ABILITY_SPLASH
|
||||
@battle.pbDisplay(_INTL("{1} is unaffected!",target.pbThis))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("{1} is unaffected because of {2}'s {3}!",
|
||||
target.pbThis,b.pbThis(true),b.abilityName))
|
||||
end
|
||||
@battle.pbHideAbilitySplash(target)
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Weaken the damage dealt (doesn't actually change a battler's HP)
|
||||
#=============================================================================
|
||||
def pbCheckDamageAbsorption(user,target)
|
||||
# Substitute will take the damage
|
||||
if target.effects[PBEffects::Substitute]>0 && !ignoresSubstitute?(user) &&
|
||||
(!user || user.index!=target.index)
|
||||
target.damageState.substitute = true
|
||||
return
|
||||
end
|
||||
# Ice Face will take the damage
|
||||
if !@battle.moldBreaker && target.isSpecies?(:EISCUE) &&
|
||||
target.form == 0 && target.ability == :ICEFACE && physicalMove?
|
||||
target.damageState.iceFace = true
|
||||
return
|
||||
end
|
||||
# Disguise will take the damage
|
||||
if !@battle.moldBreaker && target.isSpecies?(:MIMIKYU) &&
|
||||
target.form==0 && target.ability == :DISGUISE
|
||||
target.damageState.disguise = true
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
def pbReduceDamage(user,target)
|
||||
damage = target.damageState.calcDamage
|
||||
# Substitute takes the damage
|
||||
if target.damageState.substitute
|
||||
damage = target.effects[PBEffects::Substitute] if damage>target.effects[PBEffects::Substitute]
|
||||
target.damageState.hpLost = damage
|
||||
target.damageState.totalHPLost += damage
|
||||
return
|
||||
end
|
||||
# Disguise/Ice Face takes the damage
|
||||
return if target.damageState.disguise || target.damageState.iceFace
|
||||
# Target takes the damage
|
||||
if damage>=target.hp
|
||||
damage = target.hp
|
||||
# Survive a lethal hit with 1 HP effects
|
||||
if nonLethal?(user,target)
|
||||
damage -= 1
|
||||
elsif target.effects[PBEffects::Endure]
|
||||
target.damageState.endured = true
|
||||
damage -= 1
|
||||
elsif damage==target.totalhp
|
||||
if target.hasActiveAbility?(:STURDY) && !@battle.moldBreaker
|
||||
target.damageState.sturdy = true
|
||||
damage -= 1
|
||||
elsif target.hasActiveItem?(:FOCUSSASH) && target.hp==target.totalhp
|
||||
target.damageState.focusSash = true
|
||||
damage -= 1
|
||||
elsif target.hasActiveItem?(:FOCUSBAND) && @battle.pbRandom(100)<10
|
||||
target.damageState.focusBand = true
|
||||
damage -= 1
|
||||
elsif Settings::AFFECTION_EFFECTS && @battle.internalBattle &&
|
||||
target.pbOwnedByPlayer? && !target.mega?
|
||||
chance = [0, 0, 0, 10, 15, 25][target.affection_level]
|
||||
if chance > 0 && @battle.pbRandom(100) < chance
|
||||
target.damageState.affection_endured = true
|
||||
damage -= 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
damage = 0 if damage<0
|
||||
target.damageState.hpLost = damage
|
||||
target.damageState.totalHPLost += damage
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Change the target's HP by the amount calculated above
|
||||
#=============================================================================
|
||||
def pbInflictHPDamage(target)
|
||||
if target.damageState.substitute
|
||||
target.effects[PBEffects::Substitute] -= target.damageState.hpLost
|
||||
elsif target.damageState.hpLost > 0
|
||||
target.pbReduceHP(target.damageState.hpLost, false, true, false)
|
||||
end
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Animate the damage dealt, including lowering the HP
|
||||
#=============================================================================
|
||||
# Animate being damaged and losing HP (by a move)
|
||||
def pbAnimateHitAndHPLost(user,targets)
|
||||
# Animate allies first, then foes
|
||||
animArray = []
|
||||
for side in 0...2 # side here means "allies first, then foes"
|
||||
targets.each do |b|
|
||||
next if b.damageState.unaffected || b.damageState.hpLost==0
|
||||
next if (side==0 && b.opposes?(user)) || (side==1 && !b.opposes?(user))
|
||||
oldHP = b.hp+b.damageState.hpLost
|
||||
PBDebug.log("[Move damage] #{b.pbThis} lost #{b.damageState.hpLost} HP (#{oldHP}=>#{b.hp})")
|
||||
effectiveness = 0
|
||||
if Effectiveness.resistant?(b.damageState.typeMod)
|
||||
effectiveness = 1
|
||||
elsif Effectiveness.super_effective?(b.damageState.typeMod)
|
||||
effectiveness = 2
|
||||
end
|
||||
animArray.push([b,oldHP,effectiveness])
|
||||
end
|
||||
if animArray.length>0
|
||||
@battle.scene.pbHitAndHPLossAnimation(animArray)
|
||||
animArray.clear
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Messages upon being hit
|
||||
#=============================================================================
|
||||
def pbEffectivenessMessage(user,target,numTargets=1)
|
||||
return if target.damageState.disguise || target.damageState.iceFace
|
||||
if Effectiveness.super_effective?(target.damageState.typeMod)
|
||||
if numTargets>1
|
||||
@battle.pbDisplay(_INTL("It's super effective on {1}!",target.pbThis(true)))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("It's super effective!"))
|
||||
end
|
||||
elsif Effectiveness.not_very_effective?(target.damageState.typeMod)
|
||||
if numTargets>1
|
||||
@battle.pbDisplay(_INTL("It's not very effective on {1}...",target.pbThis(true)))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("It's not very effective..."))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def pbHitEffectivenessMessages(user,target,numTargets=1)
|
||||
return if target.damageState.disguise || target.damageState.iceFace
|
||||
if target.damageState.substitute
|
||||
@battle.pbDisplay(_INTL("The substitute took damage for {1}!",target.pbThis(true)))
|
||||
end
|
||||
if target.damageState.critical
|
||||
$game_temp.party_critical_hits_dealt[user.pokemonIndex] += 1 if user.pbOwnedByPlayer?
|
||||
if target.damageState.affection_critical
|
||||
if numTargets > 1
|
||||
@battle.pbDisplay(_INTL("{1} landed a critical hit on {2}, wishing to be praised!",
|
||||
user.pbThis, target.pbThis(true)))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("{1} landed a critical hit, wishing to be praised!", user.pbThis))
|
||||
end
|
||||
else
|
||||
if numTargets > 1
|
||||
@battle.pbDisplay(_INTL("A critical hit on {1}!", target.pbThis(true)))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("A critical hit!"))
|
||||
end
|
||||
end
|
||||
end
|
||||
# Effectiveness message, for moves with 1 hit
|
||||
if !multiHitMove? && user.effects[PBEffects::ParentalBond]==0
|
||||
pbEffectivenessMessage(user,target,numTargets)
|
||||
end
|
||||
if target.damageState.substitute && target.effects[PBEffects::Substitute]==0
|
||||
target.effects[PBEffects::Substitute] = 0
|
||||
@battle.pbDisplay(_INTL("{1}'s substitute faded!",target.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
def pbEndureKOMessage(target)
|
||||
if target.damageState.disguise
|
||||
@battle.pbShowAbilitySplash(target)
|
||||
if Battle::Scene::USE_ABILITY_SPLASH
|
||||
@battle.pbDisplay(_INTL("Its disguise served it as a decoy!"))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("{1}'s disguise served it as a decoy!",target.pbThis))
|
||||
end
|
||||
@battle.pbHideAbilitySplash(target)
|
||||
target.pbChangeForm(1,_INTL("{1}'s disguise was busted!",target.pbThis))
|
||||
target.pbReduceHP(target.totalhp / 8, false) if Settings::MECHANICS_GENERATION >= 8
|
||||
elsif target.damageState.iceFace
|
||||
@battle.pbShowAbilitySplash(target)
|
||||
if !Battle::Scene::USE_ABILITY_SPLASH
|
||||
@battle.pbDisplay(_INTL("{1}'s {2} activated!", target.pbThis, target.abilityName))
|
||||
end
|
||||
target.pbChangeForm(1, _INTL("{1} transformed!", target.pbThis))
|
||||
@battle.pbHideAbilitySplash(target)
|
||||
elsif target.damageState.endured
|
||||
@battle.pbDisplay(_INTL("{1} endured the hit!",target.pbThis))
|
||||
elsif target.damageState.sturdy
|
||||
@battle.pbShowAbilitySplash(target)
|
||||
if Battle::Scene::USE_ABILITY_SPLASH
|
||||
@battle.pbDisplay(_INTL("{1} endured the hit!",target.pbThis))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("{1} hung on with Sturdy!",target.pbThis))
|
||||
end
|
||||
@battle.pbHideAbilitySplash(target)
|
||||
elsif target.damageState.focusSash
|
||||
@battle.pbCommonAnimation("UseItem",target)
|
||||
@battle.pbDisplay(_INTL("{1} hung on using its Focus Sash!",target.pbThis))
|
||||
target.pbConsumeItem
|
||||
elsif target.damageState.focusBand
|
||||
@battle.pbCommonAnimation("UseItem",target)
|
||||
@battle.pbDisplay(_INTL("{1} hung on using its Focus Band!",target.pbThis))
|
||||
elsif target.damageState.affection_endured
|
||||
@battle.pbDisplay(_INTL("{1} toughed it out so you wouldn't feel sad!", target.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
# Used by Counter/Mirror Coat/Metal Burst/Revenge/Focus Punch/Bide/Assurance.
|
||||
def pbRecordDamageLost(user,target)
|
||||
damage = target.damageState.hpLost
|
||||
# NOTE: In Gen 3 where a move's category depends on its type, Hidden Power
|
||||
# is for some reason countered by Counter rather than Mirror Coat,
|
||||
# regardless of its calculated type. Hence the following two lines of
|
||||
# code.
|
||||
moveType = nil
|
||||
moveType = :NORMAL if @function=="TypeDependsOnUserIVs" # Hidden Power
|
||||
if physicalMove?(moveType)
|
||||
target.effects[PBEffects::Counter] = damage
|
||||
target.effects[PBEffects::CounterTarget] = user.index
|
||||
elsif specialMove?(moveType)
|
||||
target.effects[PBEffects::MirrorCoat] = damage
|
||||
target.effects[PBEffects::MirrorCoatTarget] = user.index
|
||||
end
|
||||
if target.effects[PBEffects::Bide]>0
|
||||
target.effects[PBEffects::BideDamage] += damage
|
||||
target.effects[PBEffects::BideTarget] = user.index
|
||||
end
|
||||
target.damageState.fainted = true if target.fainted?
|
||||
target.lastHPLost = damage # For Focus Punch
|
||||
target.tookDamageThisRound = true if damage > 0 # For Assurance
|
||||
target.lastAttacker.push(user.index) # For Revenge
|
||||
if target.opposes?(user)
|
||||
target.lastHPLostFromFoe = damage # For Metal Burst
|
||||
target.lastFoeAttacker.push(user.index) # For Metal Burst
|
||||
end
|
||||
$game_temp.party_direct_damage_taken[target.pokemonIndex] += damage if target.pbOwnedByPlayer?
|
||||
end
|
||||
end
|
||||
504
Data/Scripts/011_Battle/003_Move/003_Move_UsageCalculations.rb
Normal file
504
Data/Scripts/011_Battle/003_Move/003_Move_UsageCalculations.rb
Normal file
@@ -0,0 +1,504 @@
|
||||
class Battle::Move
|
||||
#=============================================================================
|
||||
# Move's type calculation
|
||||
#=============================================================================
|
||||
def pbBaseType(user)
|
||||
ret = @type
|
||||
if ret && user.abilityActive?
|
||||
ret = BattleHandlers.triggerMoveBaseTypeModifierAbility(user.ability,user,self,ret)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
def pbCalcType(user)
|
||||
@powerBoost = false
|
||||
ret = pbBaseType(user)
|
||||
if ret && GameData::Type.exists?(:ELECTRIC)
|
||||
if @battle.field.effects[PBEffects::IonDeluge] && ret == :NORMAL
|
||||
ret = :ELECTRIC
|
||||
@powerBoost = false
|
||||
end
|
||||
if user.effects[PBEffects::Electrify]
|
||||
ret = :ELECTRIC
|
||||
@powerBoost = false
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Type effectiveness calculation
|
||||
#=============================================================================
|
||||
def pbCalcTypeModSingle(moveType,defType,user,target)
|
||||
ret = Effectiveness.calculate_one(moveType, defType)
|
||||
# Ring Target
|
||||
if target.hasActiveItem?(:RINGTARGET)
|
||||
ret = Effectiveness::NORMAL_EFFECTIVE_ONE if Effectiveness.ineffective_type?(moveType, defType)
|
||||
end
|
||||
# Foresight
|
||||
if user.hasActiveAbility?(:SCRAPPY) || target.effects[PBEffects::Foresight]
|
||||
ret = Effectiveness::NORMAL_EFFECTIVE_ONE if defType == :GHOST &&
|
||||
Effectiveness.ineffective_type?(moveType, defType)
|
||||
end
|
||||
# Miracle Eye
|
||||
if target.effects[PBEffects::MiracleEye]
|
||||
ret = Effectiveness::NORMAL_EFFECTIVE_ONE if defType == :DARK &&
|
||||
Effectiveness.ineffective_type?(moveType, defType)
|
||||
end
|
||||
# Delta Stream's weather
|
||||
if target.effectiveWeather == :StrongWinds
|
||||
ret = Effectiveness::NORMAL_EFFECTIVE_ONE if defType == :FLYING &&
|
||||
Effectiveness.super_effective_type?(moveType, defType)
|
||||
end
|
||||
# Grounded Flying-type Pokémon become susceptible to Ground moves
|
||||
if !target.airborne?
|
||||
ret = Effectiveness::NORMAL_EFFECTIVE_ONE if defType == :FLYING && moveType == :GROUND
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
def pbCalcTypeMod(moveType,user,target)
|
||||
return Effectiveness::NORMAL_EFFECTIVE if !moveType
|
||||
return Effectiveness::NORMAL_EFFECTIVE if moveType == :GROUND &&
|
||||
target.pbHasType?(:FLYING) && target.hasActiveItem?(:IRONBALL)
|
||||
# Determine types
|
||||
tTypes = target.pbTypes(true)
|
||||
# Get effectivenesses
|
||||
typeMods = [Effectiveness::NORMAL_EFFECTIVE_ONE] * 3 # 3 types max
|
||||
if moveType == :SHADOW
|
||||
if target.shadowPokemon?
|
||||
typeMods[0] = Effectiveness::NOT_VERY_EFFECTIVE_ONE
|
||||
else
|
||||
typeMods[0] = Effectiveness::SUPER_EFFECTIVE_ONE
|
||||
end
|
||||
else
|
||||
tTypes.each_with_index do |type,i|
|
||||
typeMods[i] = pbCalcTypeModSingle(moveType,type,user,target)
|
||||
end
|
||||
end
|
||||
# Multiply all effectivenesses together
|
||||
ret = 1
|
||||
typeMods.each { |m| ret *= m }
|
||||
ret *= 2 if target.effects[PBEffects::TarShot] && moveType == :FIRE
|
||||
return ret
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Accuracy check
|
||||
#=============================================================================
|
||||
def pbBaseAccuracy(user,target); return @accuracy; end
|
||||
|
||||
# Accuracy calculations for one-hit KO moves are handled elsewhere.
|
||||
def pbAccuracyCheck(user,target)
|
||||
# "Always hit" effects and "always hit" accuracy
|
||||
return true if target.effects[PBEffects::Telekinesis]>0
|
||||
return true if target.effects[PBEffects::Minimize] && tramplesMinimize?(1)
|
||||
baseAcc = pbBaseAccuracy(user,target)
|
||||
return true if baseAcc==0
|
||||
# Calculate all multiplier effects
|
||||
modifiers = {}
|
||||
modifiers[:base_accuracy] = baseAcc
|
||||
modifiers[:accuracy_stage] = user.stages[:ACCURACY]
|
||||
modifiers[:evasion_stage] = target.stages[:EVASION]
|
||||
modifiers[:accuracy_multiplier] = 1.0
|
||||
modifiers[:evasion_multiplier] = 1.0
|
||||
pbCalcAccuracyModifiers(user,target,modifiers)
|
||||
# Check if move can't miss
|
||||
return true if modifiers[:base_accuracy] == 0
|
||||
# Calculation
|
||||
accStage = [[modifiers[:accuracy_stage], -6].max, 6].min + 6
|
||||
evaStage = [[modifiers[:evasion_stage], -6].max, 6].min + 6
|
||||
stageMul = [3,3,3,3,3,3, 3, 4,5,6,7,8,9]
|
||||
stageDiv = [9,8,7,6,5,4, 3, 3,3,3,3,3,3]
|
||||
accuracy = 100.0 * stageMul[accStage] / stageDiv[accStage]
|
||||
evasion = 100.0 * stageMul[evaStage] / stageDiv[evaStage]
|
||||
accuracy = (accuracy * modifiers[:accuracy_multiplier]).round
|
||||
evasion = (evasion * modifiers[:evasion_multiplier]).round
|
||||
evasion = 1 if evasion < 1
|
||||
threshold = modifiers[:base_accuracy] * accuracy / evasion
|
||||
# Calculation
|
||||
r = @battle.pbRandom(100)
|
||||
if Settings::AFFECTION_EFFECTS && @battle.internalBattle &&
|
||||
target.pbOwnedByPlayer? && target.affection_level == 5 && !target.mega?
|
||||
return true if r < threshold - 10
|
||||
target.damageState.affection_missed = true if r < threshold
|
||||
return false
|
||||
end
|
||||
return r < threshold
|
||||
end
|
||||
|
||||
def pbCalcAccuracyModifiers(user,target,modifiers)
|
||||
# Ability effects that alter accuracy calculation
|
||||
if user.abilityActive?
|
||||
BattleHandlers.triggerAccuracyCalcUserAbility(user.ability,
|
||||
modifiers,user,target,self,@calcType)
|
||||
end
|
||||
user.allAllies.each do |b|
|
||||
next if !b.abilityActive?
|
||||
BattleHandlers.triggerAccuracyCalcUserAllyAbility(b.ability,
|
||||
modifiers,user,target,self,@calcType)
|
||||
end
|
||||
if target.abilityActive? && !@battle.moldBreaker
|
||||
BattleHandlers.triggerAccuracyCalcTargetAbility(target.ability,
|
||||
modifiers,user,target,self,@calcType)
|
||||
end
|
||||
# Item effects that alter accuracy calculation
|
||||
if user.itemActive?
|
||||
BattleHandlers.triggerAccuracyCalcUserItem(user.item,
|
||||
modifiers,user,target,self,@calcType)
|
||||
end
|
||||
if target.itemActive?
|
||||
BattleHandlers.triggerAccuracyCalcTargetItem(target.item,
|
||||
modifiers,user,target,self,@calcType)
|
||||
end
|
||||
# Other effects, inc. ones that set accuracy_multiplier or evasion_stage to
|
||||
# specific values
|
||||
if @battle.field.effects[PBEffects::Gravity] > 0
|
||||
modifiers[:accuracy_multiplier] *= 5 / 3.0
|
||||
end
|
||||
if user.effects[PBEffects::MicleBerry]
|
||||
user.effects[PBEffects::MicleBerry] = false
|
||||
modifiers[:accuracy_multiplier] *= 1.2
|
||||
end
|
||||
modifiers[:evasion_stage] = 0 if target.effects[PBEffects::Foresight] && modifiers[:evasion_stage] > 0
|
||||
modifiers[:evasion_stage] = 0 if target.effects[PBEffects::MiracleEye] && modifiers[:evasion_stage] > 0
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Critical hit check
|
||||
#=============================================================================
|
||||
# Return values:
|
||||
# -1: Never a critical hit.
|
||||
# 0: Calculate normally.
|
||||
# 1: Always a critical hit.
|
||||
def pbCritialOverride(user,target); return 0; end
|
||||
|
||||
# Returns whether the move will be a critical hit.
|
||||
def pbIsCritical?(user,target)
|
||||
return false if target.pbOwnSide.effects[PBEffects::LuckyChant]>0
|
||||
# Set up the critical hit ratios
|
||||
ratios = (Settings::NEW_CRITICAL_HIT_RATE_MECHANICS) ? [24,8,2,1] : [16,8,4,3,2]
|
||||
c = 0
|
||||
# Ability effects that alter critical hit rate
|
||||
if c>=0 && user.abilityActive?
|
||||
c = BattleHandlers.triggerCriticalCalcUserAbility(user.ability,user,target,c)
|
||||
end
|
||||
if c>=0 && target.abilityActive? && !@battle.moldBreaker
|
||||
c = BattleHandlers.triggerCriticalCalcTargetAbility(target.ability,user,target,c)
|
||||
end
|
||||
# Item effects that alter critical hit rate
|
||||
if c>=0 && user.itemActive?
|
||||
c = BattleHandlers.triggerCriticalCalcUserItem(user.item,user,target,c)
|
||||
end
|
||||
if c>=0 && target.itemActive?
|
||||
c = BattleHandlers.triggerCriticalCalcTargetItem(target.item,user,target,c)
|
||||
end
|
||||
return false if c<0
|
||||
# Move-specific "always/never a critical hit" effects
|
||||
case pbCritialOverride(user,target)
|
||||
when 1 then return true
|
||||
when -1 then return false
|
||||
end
|
||||
# Other effects
|
||||
return true if c>50 # Merciless
|
||||
return true if user.effects[PBEffects::LaserFocus]>0
|
||||
c += 1 if highCriticalRate?
|
||||
c += user.effects[PBEffects::FocusEnergy]
|
||||
c += 1 if user.inHyperMode? && @type == :SHADOW
|
||||
c = ratios.length-1 if c>=ratios.length
|
||||
# Calculation
|
||||
return true if ratios[c] == 1
|
||||
r = @battle.pbRandom(ratios[c])
|
||||
return true if r == 0
|
||||
if r == 1 && Settings::AFFECTION_EFFECTS && @battle.internalBattle &&
|
||||
user.pbOwnedByPlayer? && user.affection_level == 5 && !target.mega?
|
||||
target.damageState.affection_critical = true
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Damage calculation
|
||||
#=============================================================================
|
||||
def pbBaseDamage(baseDmg,user,target); return baseDmg; end
|
||||
def pbBaseDamageMultiplier(damageMult,user,target); return damageMult; end
|
||||
def pbModifyDamage(damageMult,user,target); return damageMult; end
|
||||
|
||||
def pbGetAttackStats(user,target)
|
||||
if specialMove?
|
||||
return user.spatk, user.stages[:SPECIAL_ATTACK]+6
|
||||
end
|
||||
return user.attack, user.stages[:ATTACK]+6
|
||||
end
|
||||
|
||||
def pbGetDefenseStats(user,target)
|
||||
if specialMove?
|
||||
return target.spdef, target.stages[:SPECIAL_DEFENSE]+6
|
||||
end
|
||||
return target.defense, target.stages[:DEFENSE]+6
|
||||
end
|
||||
|
||||
def pbCalcDamage(user,target,numTargets=1)
|
||||
return if statusMove?
|
||||
if target.damageState.disguise || target.damageState.iceFace
|
||||
target.damageState.calcDamage = 1
|
||||
return
|
||||
end
|
||||
stageMul = [2,2,2,2,2,2, 2, 3,4,5,6,7,8]
|
||||
stageDiv = [8,7,6,5,4,3, 2, 2,2,2,2,2,2]
|
||||
# Get the move's type
|
||||
type = @calcType # nil is treated as physical
|
||||
# Calculate whether this hit deals critical damage
|
||||
target.damageState.critical = pbIsCritical?(user,target)
|
||||
# Calcuate base power of move
|
||||
baseDmg = pbBaseDamage(@baseDamage,user,target)
|
||||
# Calculate user's attack stat
|
||||
atk, atkStage = pbGetAttackStats(user,target)
|
||||
if !target.hasActiveAbility?(:UNAWARE) || @battle.moldBreaker
|
||||
atkStage = 6 if target.damageState.critical && atkStage<6
|
||||
atk = (atk.to_f*stageMul[atkStage]/stageDiv[atkStage]).floor
|
||||
end
|
||||
# Calculate target's defense stat
|
||||
defense, defStage = pbGetDefenseStats(user,target)
|
||||
if !user.hasActiveAbility?(:UNAWARE)
|
||||
defStage = 6 if target.damageState.critical && defStage>6
|
||||
defense = (defense.to_f*stageMul[defStage]/stageDiv[defStage]).floor
|
||||
end
|
||||
# Calculate all multiplier effects
|
||||
multipliers = {
|
||||
:base_damage_multiplier => 1.0,
|
||||
:attack_multiplier => 1.0,
|
||||
:defense_multiplier => 1.0,
|
||||
:final_damage_multiplier => 1.0
|
||||
}
|
||||
pbCalcDamageMultipliers(user,target,numTargets,type,baseDmg,multipliers)
|
||||
# Main damage calculation
|
||||
baseDmg = [(baseDmg * multipliers[:base_damage_multiplier]).round, 1].max
|
||||
atk = [(atk * multipliers[:attack_multiplier]).round, 1].max
|
||||
defense = [(defense * multipliers[:defense_multiplier]).round, 1].max
|
||||
damage = (((2.0 * user.level / 5 + 2).floor * baseDmg * atk / defense).floor / 50).floor + 2
|
||||
damage = [(damage * multipliers[:final_damage_multiplier]).round, 1].max
|
||||
target.damageState.calcDamage = damage
|
||||
end
|
||||
|
||||
def pbCalcDamageMultipliers(user,target,numTargets,type,baseDmg,multipliers)
|
||||
# Global abilities
|
||||
if (@battle.pbCheckGlobalAbility(:DARKAURA) && type == :DARK) ||
|
||||
(@battle.pbCheckGlobalAbility(:FAIRYAURA) && type == :FAIRY)
|
||||
if @battle.pbCheckGlobalAbility(:AURABREAK)
|
||||
multipliers[:base_damage_multiplier] *= 2 / 3.0
|
||||
else
|
||||
multipliers[:base_damage_multiplier] *= 4 / 3.0
|
||||
end
|
||||
end
|
||||
# Ability effects that alter damage
|
||||
if user.abilityActive?
|
||||
BattleHandlers.triggerDamageCalcUserAbility(user.ability,
|
||||
user,target,self,multipliers,baseDmg,type)
|
||||
end
|
||||
if !@battle.moldBreaker
|
||||
# NOTE: It's odd that the user's Mold Breaker prevents its partner's
|
||||
# beneficial abilities (i.e. Flower Gift boosting Atk), but that's
|
||||
# how it works.
|
||||
user.allAllies.each do |b|
|
||||
next if !b.abilityActive?
|
||||
BattleHandlers.triggerDamageCalcUserAllyAbility(b.ability,
|
||||
user,target,self,multipliers,baseDmg,type)
|
||||
end
|
||||
if target.abilityActive?
|
||||
BattleHandlers.triggerDamageCalcTargetAbility(target.ability,
|
||||
user,target,self,multipliers,baseDmg,type) if !@battle.moldBreaker
|
||||
BattleHandlers.triggerDamageCalcTargetAbilityNonIgnorable(target.ability,
|
||||
user,target,self,multipliers,baseDmg,type)
|
||||
end
|
||||
target.allAllies.each do |b|
|
||||
next if !b.abilityActive?
|
||||
BattleHandlers.triggerDamageCalcTargetAllyAbility(b.ability,
|
||||
user,target,self,multipliers,baseDmg,type)
|
||||
end
|
||||
end
|
||||
# Item effects that alter damage
|
||||
if user.itemActive?
|
||||
BattleHandlers.triggerDamageCalcUserItem(user.item,
|
||||
user,target,self,multipliers,baseDmg,type)
|
||||
end
|
||||
if target.itemActive?
|
||||
BattleHandlers.triggerDamageCalcTargetItem(target.item,
|
||||
user,target,self,multipliers,baseDmg,type)
|
||||
end
|
||||
# Parental Bond's second attack
|
||||
if user.effects[PBEffects::ParentalBond]==1
|
||||
multipliers[:base_damage_multiplier] /= (Settings::MECHANICS_GENERATION >= 7) ? 4 : 2
|
||||
end
|
||||
# Other
|
||||
if user.effects[PBEffects::MeFirst]
|
||||
multipliers[:base_damage_multiplier] *= 1.5
|
||||
end
|
||||
if user.effects[PBEffects::HelpingHand] && !self.is_a?(Battle::Move::Confusion)
|
||||
multipliers[:base_damage_multiplier] *= 1.5
|
||||
end
|
||||
if user.effects[PBEffects::Charge]>0 && type == :ELECTRIC
|
||||
multipliers[:base_damage_multiplier] *= 2
|
||||
end
|
||||
# Mud Sport
|
||||
if type == :ELECTRIC
|
||||
if @battle.allBattlers.any? { |b| b.effects[PBEffects::MudSport] }
|
||||
multipliers[:base_damage_multiplier] /= 3
|
||||
end
|
||||
if @battle.field.effects[PBEffects::MudSportField]>0
|
||||
multipliers[:base_damage_multiplier] /= 3
|
||||
end
|
||||
end
|
||||
# Water Sport
|
||||
if type == :FIRE
|
||||
if @battle.allBattlers.any? { |b| b.effects[PBEffects::WaterSport] }
|
||||
multipliers[:base_damage_multiplier] /= 3
|
||||
end
|
||||
if @battle.field.effects[PBEffects::WaterSportField]>0
|
||||
multipliers[:base_damage_multiplier] /= 3
|
||||
end
|
||||
end
|
||||
# Terrain moves
|
||||
terrain_multiplier = (Settings::MECHANICS_GENERATION >= 8) ? 1.3 : 1.5
|
||||
case @battle.field.terrain
|
||||
when :Electric
|
||||
multipliers[:base_damage_multiplier] *= terrain_multiplier if type == :ELECTRIC && user.affectedByTerrain?
|
||||
when :Grassy
|
||||
multipliers[:base_damage_multiplier] *= terrain_multiplier if type == :GRASS && user.affectedByTerrain?
|
||||
when :Psychic
|
||||
multipliers[:base_damage_multiplier] *= terrain_multiplier if type == :PSYCHIC && user.affectedByTerrain?
|
||||
when :Misty
|
||||
multipliers[:base_damage_multiplier] /= 2 if type == :DRAGON && target.affectedByTerrain?
|
||||
end
|
||||
# Badge multipliers
|
||||
if @battle.internalBattle
|
||||
if user.pbOwnedByPlayer?
|
||||
if physicalMove? && @battle.pbPlayer.badge_count >= Settings::NUM_BADGES_BOOST_ATTACK
|
||||
multipliers[:attack_multiplier] *= 1.1
|
||||
elsif specialMove? && @battle.pbPlayer.badge_count >= Settings::NUM_BADGES_BOOST_SPATK
|
||||
multipliers[:attack_multiplier] *= 1.1
|
||||
end
|
||||
end
|
||||
if target.pbOwnedByPlayer?
|
||||
if physicalMove? && @battle.pbPlayer.badge_count >= Settings::NUM_BADGES_BOOST_DEFENSE
|
||||
multipliers[:defense_multiplier] *= 1.1
|
||||
elsif specialMove? && @battle.pbPlayer.badge_count >= Settings::NUM_BADGES_BOOST_SPDEF
|
||||
multipliers[:defense_multiplier] *= 1.1
|
||||
end
|
||||
end
|
||||
end
|
||||
# Multi-targeting attacks
|
||||
if numTargets>1
|
||||
multipliers[:final_damage_multiplier] *= 0.75
|
||||
end
|
||||
# Weather
|
||||
case user.effectiveWeather
|
||||
when :Sun, :HarshSun
|
||||
if type == :FIRE
|
||||
multipliers[:final_damage_multiplier] *= 1.5
|
||||
elsif type == :WATER
|
||||
multipliers[:final_damage_multiplier] /= 2
|
||||
end
|
||||
when :Rain, :HeavyRain
|
||||
if type == :FIRE
|
||||
multipliers[:final_damage_multiplier] /= 2
|
||||
elsif type == :WATER
|
||||
multipliers[:final_damage_multiplier] *= 1.5
|
||||
end
|
||||
when :Sandstorm
|
||||
if target.pbHasType?(:ROCK) && specialMove? && @function != "UseTargetDefenseInsteadOfTargetSpDef"
|
||||
multipliers[:defense_multiplier] *= 1.5
|
||||
end
|
||||
end
|
||||
# Critical hits
|
||||
if target.damageState.critical
|
||||
if Settings::NEW_CRITICAL_HIT_RATE_MECHANICS
|
||||
multipliers[:final_damage_multiplier] *= 1.5
|
||||
else
|
||||
multipliers[:final_damage_multiplier] *= 2
|
||||
end
|
||||
end
|
||||
# Random variance
|
||||
if !self.is_a?(Battle::Move::Confusion)
|
||||
random = 85+@battle.pbRandom(16)
|
||||
multipliers[:final_damage_multiplier] *= random / 100.0
|
||||
end
|
||||
# STAB
|
||||
if type && user.pbHasType?(type)
|
||||
if user.hasActiveAbility?(:ADAPTABILITY)
|
||||
multipliers[:final_damage_multiplier] *= 2
|
||||
else
|
||||
multipliers[:final_damage_multiplier] *= 1.5
|
||||
end
|
||||
end
|
||||
# Type effectiveness
|
||||
multipliers[:final_damage_multiplier] *= target.damageState.typeMod.to_f / Effectiveness::NORMAL_EFFECTIVE
|
||||
# Burn
|
||||
if user.status == :BURN && physicalMove? && damageReducedByBurn? &&
|
||||
!user.hasActiveAbility?(:GUTS)
|
||||
multipliers[:final_damage_multiplier] /= 2
|
||||
end
|
||||
# Aurora Veil, Reflect, Light Screen
|
||||
if !ignoresReflect? && !target.damageState.critical &&
|
||||
!user.hasActiveAbility?(:INFILTRATOR)
|
||||
if target.pbOwnSide.effects[PBEffects::AuroraVeil] > 0
|
||||
if @battle.pbSideBattlerCount(target)>1
|
||||
multipliers[:final_damage_multiplier] *= 2 / 3.0
|
||||
else
|
||||
multipliers[:final_damage_multiplier] /= 2
|
||||
end
|
||||
elsif target.pbOwnSide.effects[PBEffects::Reflect] > 0 && physicalMove?
|
||||
if @battle.pbSideBattlerCount(target)>1
|
||||
multipliers[:final_damage_multiplier] *= 2 / 3.0
|
||||
else
|
||||
multipliers[:final_damage_multiplier] /= 2
|
||||
end
|
||||
elsif target.pbOwnSide.effects[PBEffects::LightScreen] > 0 && specialMove?
|
||||
if @battle.pbSideBattlerCount(target) > 1
|
||||
multipliers[:final_damage_multiplier] *= 2 / 3.0
|
||||
else
|
||||
multipliers[:final_damage_multiplier] /= 2
|
||||
end
|
||||
end
|
||||
end
|
||||
# Minimize
|
||||
if target.effects[PBEffects::Minimize] && tramplesMinimize?(2)
|
||||
multipliers[:final_damage_multiplier] *= 2
|
||||
end
|
||||
# Move-specific base damage modifiers
|
||||
multipliers[:base_damage_multiplier] = pbBaseDamageMultiplier(multipliers[:base_damage_multiplier], user, target)
|
||||
# Move-specific final damage modifiers
|
||||
multipliers[:final_damage_multiplier] = pbModifyDamage(multipliers[:final_damage_multiplier], user, target)
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Additional effect chance
|
||||
#=============================================================================
|
||||
def pbAdditionalEffectChance(user,target,effectChance=0)
|
||||
return 0 if target.hasActiveAbility?(:SHIELDDUST) && !@battle.moldBreaker
|
||||
ret = (effectChance>0) ? effectChance : @addlEffect
|
||||
if Settings::MECHANICS_GENERATION >= 6 || @function != "EffectDependsOnEnvironment"
|
||||
ret *= 2 if user.hasActiveAbility?(:SERENEGRACE) ||
|
||||
user.pbOwnSide.effects[PBEffects::Rainbow]>0
|
||||
end
|
||||
ret = 100 if $DEBUG && Input.press?(Input::CTRL)
|
||||
return ret
|
||||
end
|
||||
|
||||
# NOTE: Flinching caused by a move's effect is applied in that move's code,
|
||||
# not here.
|
||||
def pbFlinchChance(user,target)
|
||||
return 0 if flinchingMove?
|
||||
return 0 if target.hasActiveAbility?(:SHIELDDUST) && !@battle.moldBreaker
|
||||
ret = 0
|
||||
if user.hasActiveAbility?(:STENCH,true)
|
||||
ret = 10
|
||||
elsif user.hasActiveItem?([:KINGSROCK,:RAZORFANG],true)
|
||||
ret = 10
|
||||
end
|
||||
ret *= 2 if user.hasActiveAbility?(:SERENEGRACE) ||
|
||||
user.pbOwnSide.effects[PBEffects::Rainbow]>0
|
||||
return ret
|
||||
end
|
||||
end
|
||||
782
Data/Scripts/011_Battle/003_Move/004_Move_BaseEffects.rb
Normal file
782
Data/Scripts/011_Battle/003_Move/004_Move_BaseEffects.rb
Normal file
@@ -0,0 +1,782 @@
|
||||
# DO NOT USE ANY CLASS NAMES IN HERE AS FUNCTION CODES!
|
||||
# These are base classes for other classes to build on; those other classes are
|
||||
# named after function codes, so use those instead.
|
||||
|
||||
#===============================================================================
|
||||
# Superclass that handles moves using a non-existent function code.
|
||||
# Damaging moves just do damage with no additional effect.
|
||||
# Status moves always fail.
|
||||
#===============================================================================
|
||||
class Battle::Move::Unimplemented < Battle::Move
|
||||
def pbMoveFailed?(user,targets)
|
||||
if statusMove?
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Pseudomove for confusion damage.
|
||||
#===============================================================================
|
||||
class Battle::Move::Confusion < Battle::Move
|
||||
def initialize(battle,move)
|
||||
@battle = battle
|
||||
@realMove = move
|
||||
@id = :CONFUSEDAMAGE
|
||||
@name = ""
|
||||
@function = "None"
|
||||
@baseDamage = 40
|
||||
@type = nil
|
||||
@category = 0
|
||||
@accuracy = 100
|
||||
@pp = -1
|
||||
@target = 0
|
||||
@priority = 0
|
||||
@flags = ""
|
||||
@addlEffect = 0
|
||||
@calcType = nil
|
||||
@powerBoost = false
|
||||
@snatched = false
|
||||
end
|
||||
|
||||
def physicalMove?(thisType=nil); return true; end
|
||||
def specialMove?(thisType=nil); return false; end
|
||||
def pbCritialOverride(user,target); return -1; end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Implements the move Struggle.
|
||||
#===============================================================================
|
||||
class Battle::Move::Struggle < Battle::Move
|
||||
def initialize(battle,move)
|
||||
@battle = battle
|
||||
@realMove = nil # Not associated with a move
|
||||
@id = (move) ? move.id : :STRUGGLE
|
||||
@name = (move) ? move.name : _INTL("Struggle")
|
||||
@function = "Struggle"
|
||||
@baseDamage = 50
|
||||
@type = nil
|
||||
@category = 0
|
||||
@accuracy = 0
|
||||
@pp = -1
|
||||
@target = 0
|
||||
@priority = 0
|
||||
@flags = ""
|
||||
@addlEffect = 0
|
||||
@calcType = nil
|
||||
@powerBoost = false
|
||||
@snatched = false
|
||||
end
|
||||
|
||||
def physicalMove?(thisType=nil); return true; end
|
||||
def specialMove?(thisType=nil); return false; end
|
||||
|
||||
def pbEffectAfterAllHits(user,target)
|
||||
return if target.damageState.unaffected
|
||||
user.pbReduceHP((user.totalhp/4.0).round,false)
|
||||
@battle.pbDisplay(_INTL("{1} is damaged by recoil!",user.pbThis))
|
||||
user.pbItemHPHealCheck
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Generic status problem-inflicting classes.
|
||||
#===============================================================================
|
||||
class Battle::Move::SleepMove < Battle::Move
|
||||
def canMagicCoat?; return true; end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
return false if damagingMove?
|
||||
return !target.pbCanSleep?(user, show_message, self)
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if damagingMove?
|
||||
target.pbSleep
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
target.pbSleep if target.pbCanSleep?(user,false,self)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class Battle::Move::PoisonMove < Battle::Move
|
||||
def canMagicCoat?; return true; end
|
||||
|
||||
def initialize(battle,move)
|
||||
super
|
||||
@toxic = false
|
||||
end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
return false if damagingMove?
|
||||
return !target.pbCanPoison?(user, show_message, self)
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if damagingMove?
|
||||
target.pbPoison(user,nil,@toxic)
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
target.pbPoison(user,nil,@toxic) if target.pbCanPoison?(user,false,self)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class Battle::Move::ParalysisMove < Battle::Move
|
||||
def canMagicCoat?; return true; end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
return false if damagingMove?
|
||||
return !target.pbCanParalyze?(user, show_message, self)
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if damagingMove?
|
||||
target.pbParalyze(user)
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
target.pbParalyze(user) if target.pbCanParalyze?(user,false,self)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class Battle::Move::BurnMove < Battle::Move
|
||||
def canMagicCoat?; return true; end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
return false if damagingMove?
|
||||
return !target.pbCanBurn?(user, show_message, self)
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if damagingMove?
|
||||
target.pbBurn(user)
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
target.pbBurn(user) if target.pbCanBurn?(user,false,self)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class Battle::Move::FreezeMove < Battle::Move
|
||||
def canMagicCoat?; return true; end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
return false if damagingMove?
|
||||
return !target.pbCanFreeze?(user, show_message, self)
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if damagingMove?
|
||||
target.pbFreeze
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
target.pbFreeze if target.pbCanFreeze?(user,false,self)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Other problem-causing classes.
|
||||
#===============================================================================
|
||||
class Battle::Move::FlinchMove < Battle::Move
|
||||
def flinchingMove?; return true; end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if damagingMove?
|
||||
target.pbFlinch(user)
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
target.pbFlinch(user)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class Battle::Move::ConfuseMove < Battle::Move
|
||||
def canMagicCoat?; return true; end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
return false if damagingMove?
|
||||
return !target.pbCanConfuse?(user, show_message, self)
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if damagingMove?
|
||||
target.pbConfuse
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
return if !target.pbCanConfuse?(user,false,self)
|
||||
target.pbConfuse
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Generic user's stat increase/decrease classes.
|
||||
#===============================================================================
|
||||
class Battle::Move::StatUpMove < Battle::Move
|
||||
def canSnatch?; return true; end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
return false if damagingMove?
|
||||
return !user.pbCanRaiseStatStage?(@statUp[0],user,self,true)
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
return if damagingMove?
|
||||
user.pbRaiseStatStage(@statUp[0],@statUp[1],user)
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
if user.pbCanRaiseStatStage?(@statUp[0],user,self)
|
||||
user.pbRaiseStatStage(@statUp[0],@statUp[1],user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class Battle::Move::MultiStatUpMove < Battle::Move
|
||||
def canSnatch?; return true; end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
return false if damagingMove?
|
||||
failed = true
|
||||
for i in 0...@statUp.length/2
|
||||
next if !user.pbCanRaiseStatStage?(@statUp[i*2],user,self)
|
||||
failed = false
|
||||
break
|
||||
end
|
||||
if failed
|
||||
@battle.pbDisplay(_INTL("{1}'s stats won't go any higher!",user.pbThis))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
return if damagingMove?
|
||||
showAnim = true
|
||||
for i in 0...@statUp.length/2
|
||||
next if !user.pbCanRaiseStatStage?(@statUp[i*2],user,self)
|
||||
if user.pbRaiseStatStage(@statUp[i*2],@statUp[i*2+1],user,showAnim)
|
||||
showAnim = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
showAnim = true
|
||||
for i in 0...@statUp.length/2
|
||||
next if !user.pbCanRaiseStatStage?(@statUp[i*2],user,self)
|
||||
if user.pbRaiseStatStage(@statUp[i*2],@statUp[i*2+1],user,showAnim)
|
||||
showAnim = false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class Battle::Move::StatDownMove < Battle::Move
|
||||
def pbEffectWhenDealingDamage(user,target)
|
||||
return if @battle.pbAllFainted?(target.idxOwnSide)
|
||||
showAnim = true
|
||||
for i in 0...@statDown.length/2
|
||||
next if !user.pbCanLowerStatStage?(@statDown[i*2],user,self)
|
||||
if user.pbLowerStatStage(@statDown[i*2],@statDown[i*2+1],user,showAnim)
|
||||
showAnim = false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Generic target's stat increase/decrease classes.
|
||||
#===============================================================================
|
||||
class Battle::Move::TargetStatDownMove < Battle::Move
|
||||
def canMagicCoat?; return true; end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
return false if damagingMove?
|
||||
return !target.pbCanLowerStatStage?(@statDown[0], user, self, show_message)
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if damagingMove?
|
||||
target.pbLowerStatStage(@statDown[0],@statDown[1],user)
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
return if !target.pbCanLowerStatStage?(@statDown[0],user,self)
|
||||
target.pbLowerStatStage(@statDown[0],@statDown[1],user)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class Battle::Move::TargetMultiStatDownMove < Battle::Move
|
||||
def canMagicCoat?; return true; end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
return false if damagingMove?
|
||||
failed = true
|
||||
for i in 0...@statDown.length/2
|
||||
next if !target.pbCanLowerStatStage?(@statDown[i*2],user,self)
|
||||
failed = false
|
||||
break
|
||||
end
|
||||
if failed
|
||||
# NOTE: It's a bit of a faff to make sure the appropriate failure message
|
||||
# is shown here, I know.
|
||||
canLower = false
|
||||
if target.hasActiveAbility?(:CONTRARY) && !@battle.moldBreaker
|
||||
for i in 0...@statDown.length/2
|
||||
next if target.statStageAtMax?(@statDown[i*2])
|
||||
canLower = true
|
||||
break
|
||||
end
|
||||
@battle.pbDisplay(_INTL("{1}'s stats won't go any higher!",user.pbThis)) if !canLower && show_message
|
||||
else
|
||||
for i in 0...@statDown.length/2
|
||||
next if target.statStageAtMin?(@statDown[i*2])
|
||||
canLower = true
|
||||
break
|
||||
end
|
||||
@battle.pbDisplay(_INTL("{1}'s stats won't go any lower!",user.pbThis)) if !canLower && show_message
|
||||
end
|
||||
if canLower
|
||||
target.pbCanLowerStatStage?(@statDown[0], user, self, show_message)
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbCheckForMirrorArmor(user, target)
|
||||
if target.hasActiveAbility?(:MIRRORARMOR) && user.index != target.index
|
||||
failed = true
|
||||
for i in 0...@statDown.length / 2
|
||||
next if target.statStageAtMin?(@statDown[i * 2])
|
||||
next if !user.pbCanLowerStatStage?(@statDown[i * 2], target, self, false, false, true)
|
||||
failed = false
|
||||
break
|
||||
end
|
||||
if failed
|
||||
@battle.pbShowAbilitySplash(target)
|
||||
if !Battle::Scene::USE_ABILITY_SPLASH
|
||||
@battle.pbDisplay(_INTL("{1}'s {2} activated!", target.pbThis, target.abilityName))
|
||||
end
|
||||
user.pbCanLowerStatStage?(@statDown[0], target, self, true, false, true) # Show fail message
|
||||
@battle.pbHideAbilitySplash(target)
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
def pbLowerTargetMultipleStats(user, target)
|
||||
return if !pbCheckForMirrorArmor(user, target)
|
||||
showAnim = true
|
||||
showMirrorArmorSplash = true
|
||||
for i in 0...@statDown.length / 2
|
||||
next if !target.pbCanLowerStatStage?(@statDown[i * 2], user, self)
|
||||
if target.pbLowerStatStage(@statDown[i * 2], @statDown[i * 2 + 1], user,
|
||||
showAnim, false, (showMirrorArmorSplash) ? 1 : 3)
|
||||
showAnim = false
|
||||
end
|
||||
showMirrorArmorSplash = false
|
||||
end
|
||||
@battle.pbHideAbilitySplash(target) # To hide target's Mirror Armor splash
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
pbLowerTargetMultipleStats(user, target) if !damagingMove?
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
pbLowerTargetMultipleStats(user, target) if !target.damageState.substitute
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Fixed damage-inflicting move.
|
||||
#===============================================================================
|
||||
class Battle::Move::FixedDamageMove < Battle::Move
|
||||
def pbFixedDamage(user,target); return 1; end
|
||||
|
||||
def pbCalcDamage(user,target,numTargets=1)
|
||||
target.damageState.critical = false
|
||||
target.damageState.calcDamage = pbFixedDamage(user,target)
|
||||
target.damageState.calcDamage = 1 if target.damageState.calcDamage<1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Two turn move.
|
||||
#===============================================================================
|
||||
class Battle::Move::TwoTurnMove < Battle::Move
|
||||
attr_reader :chargingTurn
|
||||
|
||||
def chargingTurnMove?; return true; end
|
||||
|
||||
# user.effects[PBEffects::TwoTurnAttack] is set to the move's ID if this
|
||||
# method returns true, or nil if false.
|
||||
# Non-nil means the charging turn. nil means the attacking turn.
|
||||
def pbIsChargingTurn?(user)
|
||||
@powerHerb = false
|
||||
@chargingTurn = false # Assume damaging turn by default
|
||||
@damagingTurn = true
|
||||
# nil at start of charging turn, move's ID at start of damaging turn
|
||||
if !user.effects[PBEffects::TwoTurnAttack]
|
||||
@powerHerb = user.hasActiveItem?(:POWERHERB)
|
||||
@chargingTurn = true
|
||||
@damagingTurn = @powerHerb
|
||||
end
|
||||
return !@damagingTurn # Deliberately not "return @chargingTurn"
|
||||
end
|
||||
|
||||
def pbDamagingMove? # Stops damage being dealt in the first (charging) turn
|
||||
return false if !@damagingTurn
|
||||
return super
|
||||
end
|
||||
|
||||
def pbAccuracyCheck(user,target)
|
||||
return true if !@damagingTurn
|
||||
return super
|
||||
end
|
||||
|
||||
def pbInitialEffect(user,targets,hitNum)
|
||||
pbChargingTurnMessage(user,targets) if @chargingTurn
|
||||
if @chargingTurn && @damagingTurn # Move only takes one turn to use
|
||||
pbShowAnimation(@id,user,targets,1) # Charging anim
|
||||
targets.each { |b| pbChargingTurnEffect(user,b) }
|
||||
if @powerHerb
|
||||
# Moves that would make the user semi-invulnerable will hide the user
|
||||
# after the charging animation, so the "UseItem" animation shouldn't show
|
||||
# for it
|
||||
if !["TwoTurnAttackInvulnerableInSky",
|
||||
"TwoTurnAttackInvulnerableUnderground",
|
||||
"TwoTurnAttackInvulnerableUnderwater",
|
||||
"TwoTurnAttackInvulnerableInSkyParalyzeTarget",
|
||||
"TwoTurnAttackInvulnerableRemoveProtections",
|
||||
"TwoTurnAttackInvulnerableInSkyTargetCannotAct"].include?(@function)
|
||||
@battle.pbCommonAnimation("UseItem",user)
|
||||
end
|
||||
@battle.pbDisplay(_INTL("{1} became fully charged due to its Power Herb!",user.pbThis))
|
||||
user.pbConsumeItem
|
||||
end
|
||||
end
|
||||
pbAttackingTurnMessage(user,targets) if @damagingTurn
|
||||
end
|
||||
|
||||
def pbChargingTurnMessage(user,targets)
|
||||
@battle.pbDisplay(_INTL("{1} began charging up!",user.pbThis))
|
||||
end
|
||||
|
||||
def pbAttackingTurnMessage(user,targets)
|
||||
end
|
||||
|
||||
def pbChargingTurnEffect(user,target)
|
||||
# Skull Bash/Sky Drop are the only two-turn moves with an effect here, and
|
||||
# the latter just records the target is being Sky Dropped
|
||||
end
|
||||
|
||||
def pbAttackingTurnEffect(user,target)
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
if @damagingTurn
|
||||
pbAttackingTurnEffect(user,target)
|
||||
elsif @chargingTurn
|
||||
pbChargingTurnEffect(user,target)
|
||||
end
|
||||
end
|
||||
|
||||
def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true)
|
||||
hitNum = 1 if @chargingTurn && !@damagingTurn # Charging anim
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Healing move.
|
||||
#===============================================================================
|
||||
class Battle::Move::HealingMove < Battle::Move
|
||||
def healingMove?; return true; end
|
||||
def pbHealAmount(user); return 1; end
|
||||
def canSnatch?; return true; end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if user.hp==user.totalhp
|
||||
@battle.pbDisplay(_INTL("{1}'s HP is full!",user.pbThis))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
amt = pbHealAmount(user)
|
||||
user.pbRecoverHP(amt)
|
||||
@battle.pbDisplay(_INTL("{1}'s HP was restored.",user.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Recoil move.
|
||||
#===============================================================================
|
||||
class Battle::Move::RecoilMove < Battle::Move
|
||||
def recoilMove?; return true; end
|
||||
def pbRecoilDamage(user,target); return 1; end
|
||||
|
||||
def pbEffectAfterAllHits(user,target)
|
||||
return if target.damageState.unaffected
|
||||
return if !user.takesIndirectDamage?
|
||||
return if user.hasActiveAbility?(:ROCKHEAD)
|
||||
amt = pbRecoilDamage(user,target)
|
||||
amt = 1 if amt<1
|
||||
user.pbReduceHP(amt,false)
|
||||
@battle.pbDisplay(_INTL("{1} is damaged by recoil!",user.pbThis))
|
||||
user.pbItemHPHealCheck
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Protect move.
|
||||
#===============================================================================
|
||||
class Battle::Move::ProtectMove < Battle::Move
|
||||
def initialize(battle,move)
|
||||
super
|
||||
@sidedEffect = false
|
||||
end
|
||||
|
||||
def pbChangeUsageCounters(user,specialUsage)
|
||||
oldVal = user.effects[PBEffects::ProtectRate]
|
||||
super
|
||||
user.effects[PBEffects::ProtectRate] = oldVal
|
||||
end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if @sidedEffect
|
||||
if user.pbOwnSide.effects[@effect]
|
||||
user.effects[PBEffects::ProtectRate] = 1
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
elsif user.effects[@effect]
|
||||
user.effects[PBEffects::ProtectRate] = 1
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
if (!@sidedEffect || Settings::MECHANICS_GENERATION <= 5) &&
|
||||
user.effects[PBEffects::ProtectRate]>1 &&
|
||||
@battle.pbRandom(user.effects[PBEffects::ProtectRate])!=0
|
||||
user.effects[PBEffects::ProtectRate] = 1
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
if pbMoveFailedLastInRound?(user)
|
||||
user.effects[PBEffects::ProtectRate] = 1
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
if @sidedEffect
|
||||
user.pbOwnSide.effects[@effect] = true
|
||||
else
|
||||
user.effects[@effect] = true
|
||||
end
|
||||
user.effects[PBEffects::ProtectRate] *= (Settings::MECHANICS_GENERATION >= 6) ? 3 : 2
|
||||
pbProtectMessage(user)
|
||||
end
|
||||
|
||||
def pbProtectMessage(user)
|
||||
if @sidedEffect
|
||||
@battle.pbDisplay(_INTL("{1} protected {2}!",@name,user.pbTeam(true)))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("{1} protected itself!",user.pbThis))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Weather-inducing move.
|
||||
#===============================================================================
|
||||
class Battle::Move::WeatherMove < Battle::Move
|
||||
def initialize(battle,move)
|
||||
super
|
||||
@weatherType = :None
|
||||
end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
case @battle.field.weather
|
||||
when :HarshSun
|
||||
@battle.pbDisplay(_INTL("The extremely harsh sunlight was not lessened at all!"))
|
||||
return true
|
||||
when :HeavyRain
|
||||
@battle.pbDisplay(_INTL("There is no relief from this heavy rain!"))
|
||||
return true
|
||||
when :StrongWinds
|
||||
@battle.pbDisplay(_INTL("The mysterious air current blows on regardless!"))
|
||||
return true
|
||||
when @weatherType
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
@battle.pbStartWeather(user,@weatherType,true,false)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Pledge move.
|
||||
#===============================================================================
|
||||
class Battle::Move::PledgeMove < Battle::Move
|
||||
def pbOnStartUse(user,targets)
|
||||
@pledgeSetup = false
|
||||
@pledgeCombo = false
|
||||
@pledgeOtherUser = nil
|
||||
@comboEffect = nil
|
||||
@overrideAnim = nil
|
||||
# Check whether this is the use of a combo move
|
||||
@combos.each do |i|
|
||||
next if i[0]!=user.effects[PBEffects::FirstPledge]
|
||||
@battle.pbDisplay(_INTL("The two moves have become one! It's a combined move!"))
|
||||
@pledgeCombo = true
|
||||
@comboEffect = i[1]
|
||||
@overrideAnim = i[3]
|
||||
break
|
||||
end
|
||||
return if @pledgeCombo
|
||||
# Check whether this is the setup of a combo move
|
||||
user.allAllies.each do |b|
|
||||
next if @battle.choices[b.index][0]!=:UseMove || b.movedThisRound?
|
||||
move = @battle.choices[b.index][2]
|
||||
next if !move
|
||||
@combos.each do |i|
|
||||
next if i[0]!=move.function
|
||||
@pledgeSetup = true
|
||||
@pledgeOtherUser = b
|
||||
break
|
||||
end
|
||||
break if @pledgeSetup
|
||||
end
|
||||
end
|
||||
|
||||
def pbDamagingMove?
|
||||
return false if @pledgeSetup
|
||||
return super
|
||||
end
|
||||
|
||||
def pbBaseType(user)
|
||||
# This method is called before pbOnStartUse, so it has to calculate the type
|
||||
# separately
|
||||
@combos.each do |i|
|
||||
next if i[0] != user.effects[PBEffects::FirstPledge]
|
||||
next if !GameData::Type.exists?(i[2])
|
||||
return i[2]
|
||||
end
|
||||
return super
|
||||
end
|
||||
|
||||
def pbBaseDamage(baseDmg,user,target)
|
||||
baseDmg *= 2 if @pledgeCombo
|
||||
return baseDmg
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
user.effects[PBEffects::FirstPledge] = 0
|
||||
return if !@pledgeSetup
|
||||
@battle.pbDisplay(_INTL("{1} is waiting for {2}'s move...",
|
||||
user.pbThis,@pledgeOtherUser.pbThis(true)))
|
||||
@pledgeOtherUser.effects[PBEffects::FirstPledge] = @function
|
||||
@pledgeOtherUser.effects[PBEffects::MoveNext] = true
|
||||
user.lastMoveFailed = true # Treated as a failure for Stomping Tantrum
|
||||
end
|
||||
|
||||
def pbEffectAfterAllHits(user,target)
|
||||
return if !@pledgeCombo
|
||||
msg = nil
|
||||
animName = nil
|
||||
case @comboEffect
|
||||
when :SeaOfFire # Grass + Fire
|
||||
if user.pbOpposingSide.effects[PBEffects::SeaOfFire]==0
|
||||
user.pbOpposingSide.effects[PBEffects::SeaOfFire] = 4
|
||||
msg = _INTL("A sea of fire enveloped {1}!",user.pbOpposingTeam(true))
|
||||
animName = (user.opposes?) ? "SeaOfFire" : "SeaOfFireOpp"
|
||||
end
|
||||
when :Rainbow # Fire + Water
|
||||
if user.pbOwnSide.effects[PBEffects::Rainbow]==0
|
||||
user.pbOwnSide.effects[PBEffects::Rainbow] = 4
|
||||
msg = _INTL("A rainbow appeared in the sky on {1}'s side!",user.pbTeam(true))
|
||||
animName = (user.opposes?) ? "RainbowOpp" : "Rainbow"
|
||||
end
|
||||
when :Swamp # Water + Grass
|
||||
if user.pbOpposingSide.effects[PBEffects::Swamp]==0
|
||||
user.pbOpposingSide.effects[PBEffects::Swamp] = 4
|
||||
msg = _INTL("A swamp enveloped {1}!",user.pbOpposingTeam(true))
|
||||
animName = (user.opposes?) ? "Swamp" : "SwampOpp"
|
||||
end
|
||||
end
|
||||
@battle.pbDisplay(msg) if msg
|
||||
@battle.pbCommonAnimation(animName) if animName
|
||||
end
|
||||
|
||||
def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true)
|
||||
return if @pledgeSetup # No animation for setting up
|
||||
id = @overrideAnim if @overrideAnim
|
||||
return super
|
||||
end
|
||||
end
|
||||
691
Data/Scripts/011_Battle/003_Move/005_MoveEffects_Misc.rb
Normal file
691
Data/Scripts/011_Battle/003_Move/005_MoveEffects_Misc.rb
Normal file
@@ -0,0 +1,691 @@
|
||||
#===============================================================================
|
||||
# No additional effect.
|
||||
#===============================================================================
|
||||
class Battle::Move::None < Battle::Move
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Does absolutely nothing. Shows a special message. (Celebrate)
|
||||
#===============================================================================
|
||||
class Battle::Move::DoesNothingCongratuations < Battle::Move
|
||||
def pbEffectGeneral(user)
|
||||
if user.wild?
|
||||
@battle.pbDisplay(_INTL("Congratulations from {1}!",user.pbThis(true)))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("Congratulations, {1}!",@battle.pbGetOwnerName(user.index)))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Does absolutely nothing. (Hold Hands)
|
||||
#===============================================================================
|
||||
class Battle::Move::DoesNothingFailsIfNoAlly < Battle::Move
|
||||
def ignoresSubstitute?(user); return true; end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if user.allAllies.length == 0
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Does absolutely nothing. (Splash)
|
||||
#===============================================================================
|
||||
class Battle::Move::DoesNothingUnusableInGravity < Battle::Move
|
||||
def unusableInGravity?; return true; end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
@battle.pbDisplay(_INTL("But nothing happened!"))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Scatters coins that the player picks up after winning the battle. (Pay Day)
|
||||
# NOTE: In Gen 6+, if the user levels up after this move is used, the amount of
|
||||
# money picked up depends on the user's new level rather than its level
|
||||
# when it used the move. I think this is silly, so I haven't coded this
|
||||
# effect.
|
||||
#===============================================================================
|
||||
class Battle::Move::AddMoneyGainedFromBattle < Battle::Move
|
||||
def pbEffectGeneral(user)
|
||||
if user.pbOwnedByPlayer?
|
||||
@battle.field.effects[PBEffects::PayDay] += 5*user.level
|
||||
end
|
||||
@battle.pbDisplay(_INTL("Coins were scattered everywhere!"))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Doubles the prize money the player gets after winning the battle. (Happy Hour)
|
||||
#===============================================================================
|
||||
class Battle::Move::DoubleMoneyGainedFromBattle < Battle::Move
|
||||
def pbEffectGeneral(user)
|
||||
@battle.field.effects[PBEffects::HappyHour] = true if !user.opposes?
|
||||
@battle.pbDisplay(_INTL("Everyone is caught up in the happy atmosphere!"))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Fails if this isn't the user's first turn. (First Impression)
|
||||
#===============================================================================
|
||||
class Battle::Move::FailsIfNotUserFirstTurn < Battle::Move
|
||||
def pbMoveFailed?(user,targets)
|
||||
if user.turnCount > 1
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Fails unless user has already used all other moves it knows. (Last Resort)
|
||||
#===============================================================================
|
||||
class Battle::Move::FailsIfUserHasUnusedMove < Battle::Move
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
hasThisMove = false
|
||||
hasOtherMoves = false
|
||||
hasUnusedMoves = false
|
||||
user.eachMove do |m|
|
||||
hasThisMove = true if m.id==@id
|
||||
hasOtherMoves = true if m.id!=@id
|
||||
hasUnusedMoves = true if m.id!=@id && !user.movesUsed.include?(m.id)
|
||||
end
|
||||
if !hasThisMove || !hasOtherMoves || hasUnusedMoves
|
||||
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Fails unless user has consumed a berry at some point. (Belch)
|
||||
#===============================================================================
|
||||
class Battle::Move::FailsIfUserNotConsumedBerry < Battle::Move
|
||||
def pbCanChooseMove?(user,commandPhase,showMessages)
|
||||
if !user.belched?
|
||||
if showMessages
|
||||
msg = _INTL("{1} hasn't eaten any held berry, so it can't possibly belch!",user.pbThis)
|
||||
(commandPhase) ? @battle.pbDisplayPaused(msg) : @battle.pbDisplay(msg)
|
||||
end
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if !user.belched?
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Fails if the target is not holding an item, or if the target is affected by
|
||||
# Magic Room/Klutz. (Poltergeist)
|
||||
#===============================================================================
|
||||
class Battle::Move::FailsIfTargetHasNoItem < Battle::Move
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
if !target.item || !target.itemActive?
|
||||
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
||||
return true
|
||||
end
|
||||
@battle.pbDisplay(_INTL("{1} is about to be attacked by its {2}!", target.pbThis, target.itemName))
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Only damages Pokémon that share a type with the user. (Synchronoise)
|
||||
#===============================================================================
|
||||
class Battle::Move::FailsUnlessTargetSharesTypeWithUser < Battle::Move
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
userTypes = user.pbTypes(true)
|
||||
targetTypes = target.pbTypes(true)
|
||||
sharesType = false
|
||||
userTypes.each do |t|
|
||||
next if !targetTypes.include?(t)
|
||||
sharesType = true
|
||||
break
|
||||
end
|
||||
if !sharesType
|
||||
@battle.pbDisplay(_INTL("{1} is unaffected!",target.pbThis)) if show_message
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Fails if user was hit by a damaging move this round. (Focus Punch)
|
||||
#===============================================================================
|
||||
class Battle::Move::FailsIfUserDamagedThisTurn < Battle::Move
|
||||
def pbDisplayChargeMessage(user)
|
||||
user.effects[PBEffects::FocusPunch] = true
|
||||
@battle.pbCommonAnimation("FocusPunch",user)
|
||||
@battle.pbDisplay(_INTL("{1} is tightening its focus!",user.pbThis))
|
||||
end
|
||||
|
||||
def pbDisplayUseMessage(user)
|
||||
super if !user.effects[PBEffects::FocusPunch] || user.lastHPLost==0
|
||||
end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if user.effects[PBEffects::FocusPunch] && user.lastHPLost>0
|
||||
@battle.pbDisplay(_INTL("{1} lost its focus and couldn't move!",user.pbThis))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Fails if the target didn't chose a damaging move to use this round, or has
|
||||
# already moved. (Sucker Punch)
|
||||
#===============================================================================
|
||||
class Battle::Move::FailsIfTargetActed < Battle::Move
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
if @battle.choices[target.index][0]!=:UseMove
|
||||
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
||||
return true
|
||||
end
|
||||
oppMove = @battle.choices[target.index][2]
|
||||
if !oppMove ||
|
||||
(oppMove.function!="UseMoveTargetIsAboutToUse" &&
|
||||
(target.movedThisRound? || oppMove.statusMove?))
|
||||
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# If attack misses, user takes crash damage of 1/2 of max HP.
|
||||
# (High Jump Kick, Jump Kick)
|
||||
#===============================================================================
|
||||
class Battle::Move::CrashDamageIfFailsUnusableInGravity < Battle::Move
|
||||
def recoilMove?; return true; end
|
||||
def unusableInGravity?; return true; end
|
||||
|
||||
def pbCrashDamage(user)
|
||||
return if !user.takesIndirectDamage?
|
||||
@battle.pbDisplay(_INTL("{1} kept going and crashed!",user.pbThis))
|
||||
@battle.scene.pbDamageAnimation(user)
|
||||
user.pbReduceHP(user.totalhp/2,false)
|
||||
user.pbItemHPHealCheck
|
||||
user.pbFaint if user.fainted?
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Starts sunny weather. (Sunny Day)
|
||||
#===============================================================================
|
||||
class Battle::Move::StartSunWeather < Battle::Move::WeatherMove
|
||||
def initialize(battle,move)
|
||||
super
|
||||
@weatherType = :Sun
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Starts rainy weather. (Rain Dance)
|
||||
#===============================================================================
|
||||
class Battle::Move::StartRainWeather < Battle::Move::WeatherMove
|
||||
def initialize(battle,move)
|
||||
super
|
||||
@weatherType = :Rain
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Starts sandstorm weather. (Sandstorm)
|
||||
#===============================================================================
|
||||
class Battle::Move::StartSandstormWeather < Battle::Move::WeatherMove
|
||||
def initialize(battle,move)
|
||||
super
|
||||
@weatherType = :Sandstorm
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Starts hail weather. (Hail)
|
||||
#===============================================================================
|
||||
class Battle::Move::StartHailWeather < Battle::Move::WeatherMove
|
||||
def initialize(battle,move)
|
||||
super
|
||||
@weatherType = :Hail
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# For 5 rounds, creates an electric terrain which boosts Electric-type moves and
|
||||
# prevents Pokémon from falling asleep. Affects non-airborne Pokémon only.
|
||||
# (Electric Terrain)
|
||||
#===============================================================================
|
||||
class Battle::Move::StartElectricTerrain < Battle::Move
|
||||
def pbMoveFailed?(user,targets)
|
||||
if @battle.field.terrain == :Electric
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
@battle.pbStartTerrain(user, :Electric)
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# For 5 rounds, creates a grassy terrain which boosts Grass-type moves and heals
|
||||
# Pokémon at the end of each round. Affects non-airborne Pokémon only.
|
||||
# (Grassy Terrain)
|
||||
#===============================================================================
|
||||
class Battle::Move::StartGrassyTerrain < Battle::Move
|
||||
def pbMoveFailed?(user,targets)
|
||||
if @battle.field.terrain == :Grassy
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
@battle.pbStartTerrain(user, :Grassy)
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# For 5 rounds, creates a misty terrain which weakens Dragon-type moves and
|
||||
# protects Pokémon from status problems. Affects non-airborne Pokémon only.
|
||||
# (Misty Terrain)
|
||||
#===============================================================================
|
||||
class Battle::Move::StartMistyTerrain < Battle::Move
|
||||
def pbMoveFailed?(user,targets)
|
||||
if @battle.field.terrain == :Misty
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
@battle.pbStartTerrain(user, :Misty)
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# For 5 rounds, creates a psychic terrain which boosts Psychic-type moves and
|
||||
# prevents Pokémon from being hit by >0 priority moves. Affects non-airborne
|
||||
# Pokémon only. (Psychic Terrain)
|
||||
#===============================================================================
|
||||
class Battle::Move::StartPsychicTerrain < Battle::Move
|
||||
def pbMoveFailed?(user,targets)
|
||||
if @battle.field.terrain == :Psychic
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
@battle.pbStartTerrain(user, :Psychic)
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Removes the current terrain. Fails if there is no terrain in effect.
|
||||
# (Steel Roller)
|
||||
#===============================================================================
|
||||
class Battle::Move::RemoveTerrain < Battle::Move
|
||||
def pbMoveFailed?(user, targets)
|
||||
if @battle.field.terrain == :None
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
case @battle.field.terrain
|
||||
when :Electric
|
||||
@battle.pbDisplay(_INTL("The electricity disappeared from the battlefield."))
|
||||
when :Grassy
|
||||
@battle.pbDisplay(_INTL("The grass disappeared from the battlefield."))
|
||||
when :Misty
|
||||
@battle.pbDisplay(_INTL("The mist disappeared from the battlefield."))
|
||||
when :Psychic
|
||||
@battle.pbDisplay(_INTL("The weirdness disappeared from the battlefield."))
|
||||
end
|
||||
@battle.field.terrain = :None
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Entry hazard. Lays spikes on the opposing side (max. 3 layers). (Spikes)
|
||||
#===============================================================================
|
||||
class Battle::Move::AddSpikesToFoeSide < Battle::Move
|
||||
def canMagicCoat?; return true; end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if user.pbOpposingSide.effects[PBEffects::Spikes]>=3
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
user.pbOpposingSide.effects[PBEffects::Spikes] += 1
|
||||
@battle.pbDisplay(_INTL("Spikes were scattered all around {1}'s feet!",
|
||||
user.pbOpposingTeam(true)))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Entry hazard. Lays poison spikes on the opposing side (max. 2 layers).
|
||||
# (Toxic Spikes)
|
||||
#===============================================================================
|
||||
class Battle::Move::AddToxicSpikesToFoeSide < Battle::Move
|
||||
def canMagicCoat?; return true; end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if user.pbOpposingSide.effects[PBEffects::ToxicSpikes]>=2
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
user.pbOpposingSide.effects[PBEffects::ToxicSpikes] += 1
|
||||
@battle.pbDisplay(_INTL("Poison spikes were scattered all around {1}'s feet!",
|
||||
user.pbOpposingTeam(true)))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Entry hazard. Lays stealth rocks on the opposing side. (Stealth Rock)
|
||||
#===============================================================================
|
||||
class Battle::Move::AddStealthRocksToFoeSide < Battle::Move
|
||||
def canMagicCoat?; return true; end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if user.pbOpposingSide.effects[PBEffects::StealthRock]
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
user.pbOpposingSide.effects[PBEffects::StealthRock] = true
|
||||
@battle.pbDisplay(_INTL("Pointed stones float in the air around {1}!",
|
||||
user.pbOpposingTeam(true)))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Entry hazard. Lays stealth rocks on the opposing side. (Sticky Web)
|
||||
#===============================================================================
|
||||
class Battle::Move::AddStickyWebToFoeSide < Battle::Move
|
||||
def canMagicCoat?; return true; end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if user.pbOpposingSide.effects[PBEffects::StickyWeb]
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
user.pbOpposingSide.effects[PBEffects::StickyWeb] = true
|
||||
@battle.pbDisplay(_INTL("A sticky web has been laid out beneath {1}'s feet!",
|
||||
user.pbOpposingTeam(true)))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# All effects that apply to one side of the field are swapped to the opposite
|
||||
# side. (Court Change)
|
||||
#===============================================================================
|
||||
class Battle::Move::SwapSideEffects < Battle::Move
|
||||
def initialize(battle, move)
|
||||
super
|
||||
@number_effects = [
|
||||
PBEffects::AuroraVeil,
|
||||
PBEffects::LightScreen,
|
||||
PBEffects::Mist,
|
||||
PBEffects::Rainbow,
|
||||
PBEffects::Reflect,
|
||||
PBEffects::Safeguard,
|
||||
PBEffects::SeaOfFire,
|
||||
PBEffects::Spikes,
|
||||
PBEffects::Swamp,
|
||||
PBEffects::Tailwind,
|
||||
PBEffects::ToxicSpikes
|
||||
]
|
||||
@boolean_effects = [
|
||||
PBEffects::StealthRock,
|
||||
PBEffects::StickyWeb
|
||||
]
|
||||
end
|
||||
|
||||
def pbMoveFailed?(user, targets)
|
||||
has_effect = false
|
||||
for side in 0...2
|
||||
effects = @battle.sides[side].effects
|
||||
@number_effects.each do |e|
|
||||
next if effects[e] == 0
|
||||
has_effect = true
|
||||
break
|
||||
end
|
||||
break if has_effect
|
||||
@boolean_effects.each do |e|
|
||||
next if !effects[e]
|
||||
has_effect = true
|
||||
break
|
||||
end
|
||||
break if has_effect
|
||||
end
|
||||
if !has_effect
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
side0 = @battle.sides[0]
|
||||
side1 = @battle.sides[1]
|
||||
@number_effects.each do |e|
|
||||
side0.effects[e], side1.effects[e] = side1.effects[e], side0.effects[e]
|
||||
end
|
||||
@boolean_effects.each do |e|
|
||||
side0.effects[e], side1.effects[e] = side1.effects[e], side0.effects[e]
|
||||
end
|
||||
@battle.pbDisplay(_INTL("{1} swapped the battle effects affecting each side of the field!", user.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# User turns 1/4 of max HP into a substitute. (Substitute)
|
||||
#===============================================================================
|
||||
class Battle::Move::UserMakeSubstitute < Battle::Move
|
||||
def canSnatch?; return true; end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if user.effects[PBEffects::Substitute]>0
|
||||
@battle.pbDisplay(_INTL("{1} already has a substitute!",user.pbThis))
|
||||
return true
|
||||
end
|
||||
@subLife = user.totalhp/4
|
||||
@subLife = 1 if @subLife<1
|
||||
if user.hp<=@subLife
|
||||
@battle.pbDisplay(_INTL("But it does not have enough HP left to make a substitute!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbOnStartUse(user,targets)
|
||||
user.pbReduceHP(@subLife,false,false)
|
||||
user.pbItemHPHealCheck
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
user.effects[PBEffects::Trapping] = 0
|
||||
user.effects[PBEffects::TrappingMove] = nil
|
||||
user.effects[PBEffects::Substitute] = @subLife
|
||||
@battle.pbDisplay(_INTL("{1} put in a substitute!",user.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Removes trapping moves, entry hazards and Leech Seed on user/user's side.
|
||||
# Raises user's Speed by 1 stage (Gen 8+). (Rapid Spin)
|
||||
#===============================================================================
|
||||
class Battle::Move::RemoveUserBindingAndEntryHazards < Battle::Move::StatUpMove
|
||||
def initialize(battle,move)
|
||||
super
|
||||
@statUp = [:SPEED, 1]
|
||||
end
|
||||
|
||||
def pbEffectAfterAllHits(user,target)
|
||||
return if user.fainted? || target.damageState.unaffected
|
||||
if user.effects[PBEffects::Trapping]>0
|
||||
trapMove = GameData::Move.get(user.effects[PBEffects::TrappingMove]).name
|
||||
trapUser = @battle.battlers[user.effects[PBEffects::TrappingUser]]
|
||||
@battle.pbDisplay(_INTL("{1} got free of {2}'s {3}!",user.pbThis,trapUser.pbThis(true),trapMove))
|
||||
user.effects[PBEffects::Trapping] = 0
|
||||
user.effects[PBEffects::TrappingMove] = nil
|
||||
user.effects[PBEffects::TrappingUser] = -1
|
||||
end
|
||||
if user.effects[PBEffects::LeechSeed]>=0
|
||||
user.effects[PBEffects::LeechSeed] = -1
|
||||
@battle.pbDisplay(_INTL("{1} shed Leech Seed!",user.pbThis))
|
||||
end
|
||||
if user.pbOwnSide.effects[PBEffects::StealthRock]
|
||||
user.pbOwnSide.effects[PBEffects::StealthRock] = false
|
||||
@battle.pbDisplay(_INTL("{1} blew away stealth rocks!",user.pbThis))
|
||||
end
|
||||
if user.pbOwnSide.effects[PBEffects::Spikes]>0
|
||||
user.pbOwnSide.effects[PBEffects::Spikes] = 0
|
||||
@battle.pbDisplay(_INTL("{1} blew away spikes!",user.pbThis))
|
||||
end
|
||||
if user.pbOwnSide.effects[PBEffects::ToxicSpikes]>0
|
||||
user.pbOwnSide.effects[PBEffects::ToxicSpikes] = 0
|
||||
@battle.pbDisplay(_INTL("{1} blew away poison spikes!",user.pbThis))
|
||||
end
|
||||
if user.pbOwnSide.effects[PBEffects::StickyWeb]
|
||||
user.pbOwnSide.effects[PBEffects::StickyWeb] = false
|
||||
@battle.pbDisplay(_INTL("{1} blew away sticky webs!",user.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
super if Settings::MECHANICS_GENERATION >= 8
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Attacks 2 rounds in the future. (Doom Desire, Future Sight)
|
||||
#===============================================================================
|
||||
class Battle::Move::AttackTwoTurnsLater < Battle::Move
|
||||
def targetsPosition?; return true; end
|
||||
|
||||
def pbDamagingMove? # Stops damage being dealt in the setting-up turn
|
||||
return false if !@battle.futureSight
|
||||
return super
|
||||
end
|
||||
|
||||
def pbAccuracyCheck(user,target)
|
||||
return true if !@battle.futureSight
|
||||
return super
|
||||
end
|
||||
|
||||
def pbDisplayUseMessage(user)
|
||||
super if !@battle.futureSight
|
||||
end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
if !@battle.futureSight &&
|
||||
@battle.positions[target.index].effects[PBEffects::FutureSightCounter]>0
|
||||
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if @battle.futureSight # Attack is hitting
|
||||
effects = @battle.positions[target.index].effects
|
||||
effects[PBEffects::FutureSightCounter] = 3
|
||||
effects[PBEffects::FutureSightMove] = @id
|
||||
effects[PBEffects::FutureSightUserIndex] = user.index
|
||||
effects[PBEffects::FutureSightUserPartyIndex] = user.pokemonIndex
|
||||
if @id == :DOOMDESIRE
|
||||
@battle.pbDisplay(_INTL("{1} chose Doom Desire as its destiny!",user.pbThis))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("{1} foresaw an attack!",user.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true)
|
||||
hitNum = 1 if !@battle.futureSight # Charging anim
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# User switches places with its ally. (Ally Switch)
|
||||
#===============================================================================
|
||||
class Battle::Move::UserSwapsPositionsWithAlly < Battle::Move
|
||||
def pbMoveFailed?(user,targets)
|
||||
numTargets = 0
|
||||
@idxAlly = -1
|
||||
idxUserOwner = @battle.pbGetOwnerIndexFromBattlerIndex(user.index)
|
||||
user.allAllies.each do |b|
|
||||
next if @battle.pbGetOwnerIndexFromBattlerIndex(b.index)!=idxUserOwner
|
||||
next if !b.near?(user)
|
||||
numTargets += 1
|
||||
@idxAlly = b.index
|
||||
end
|
||||
if numTargets!=1
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
idxA = user.index
|
||||
idxB = @idxAlly
|
||||
if @battle.pbSwapBattlers(idxA,idxB)
|
||||
@battle.pbDisplay(_INTL("{1} and {2} switched places!",
|
||||
@battle.battlers[idxB].pbThis,@battle.battlers[idxA].pbThis(true)))
|
||||
[idxA, idxB].each { |idx| @battle.pbEffectsOnBattlerEnteringPosition(@battle.battlers[idx]) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# If a Pokémon makes contact with the user before it uses this move, the
|
||||
# attacker is burned. (Beak Blast)
|
||||
#===============================================================================
|
||||
class Battle::Move::BurnAttackerBeforeUserActs < Battle::Move
|
||||
def pbDisplayChargeMessage(user)
|
||||
user.effects[PBEffects::BeakBlast] = true
|
||||
@battle.pbCommonAnimation("BeakBlast",user)
|
||||
@battle.pbDisplay(_INTL("{1} started heating up its beak!",user.pbThis))
|
||||
end
|
||||
end
|
||||
1938
Data/Scripts/011_Battle/003_Move/006_MoveEffects_BattlerStats.rb
Normal file
1938
Data/Scripts/011_Battle/003_Move/006_MoveEffects_BattlerStats.rb
Normal file
File diff suppressed because it is too large
Load Diff
1282
Data/Scripts/011_Battle/003_Move/007_MoveEffects_BattlerOther.rb
Normal file
1282
Data/Scripts/011_Battle/003_Move/007_MoveEffects_BattlerOther.rb
Normal file
File diff suppressed because it is too large
Load Diff
1710
Data/Scripts/011_Battle/003_Move/008_MoveEffects_MoveAttributes.rb
Normal file
1710
Data/Scripts/011_Battle/003_Move/008_MoveEffects_MoveAttributes.rb
Normal file
File diff suppressed because it is too large
Load Diff
621
Data/Scripts/011_Battle/003_Move/009_MoveEffects_MultiHit.rb
Normal file
621
Data/Scripts/011_Battle/003_Move/009_MoveEffects_MultiHit.rb
Normal file
@@ -0,0 +1,621 @@
|
||||
#===============================================================================
|
||||
# Hits twice.
|
||||
#===============================================================================
|
||||
class Battle::Move::HitTwoTimes < Battle::Move
|
||||
def multiHitMove?; return true; end
|
||||
def pbNumHits(user,targets); return 2; end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Hits twice. May poison the target on each hit. (Twineedle)
|
||||
#===============================================================================
|
||||
class Battle::Move::HitTwoTimesPoisonTarget < Battle::Move::PoisonMove
|
||||
def multiHitMove?; return true; end
|
||||
def pbNumHits(user,targets); return 2; end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Hits twice. Causes the target to flinch. Does double damage and has perfect
|
||||
# accuracy if the target is Minimized. (Double Iron Bash)
|
||||
#===============================================================================
|
||||
class Battle::Move::HitTwoTimesFlinchTarget < Battle::Move::FlinchMove
|
||||
def multiHitMove?; return true; end
|
||||
def pbNumHits(user,targets); return 2; end
|
||||
def tramplesMinimize?(param=1); return Settings::MECHANICS_GENERATION <= 7; end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Hits in 2 volleys. The second volley targets the original target's ally if it
|
||||
# has one (that can be targeted), or the original target if not. A battler
|
||||
# cannot be targeted if it is is immune to or protected from this move somehow,
|
||||
# or if this move will miss it. (Dragon Darts)
|
||||
# NOTE: This move sometimes shows a different failure message compared to the
|
||||
# official games. This is because of the order in which failure checks are
|
||||
# done (all checks for each target in turn, versus all targets for each
|
||||
# check in turn). This is considered unimportant, and since correcting it
|
||||
# would involve extensive code rewrites, it is being ignored.
|
||||
#===============================================================================
|
||||
class Battle::Move::HitTwoTimesTargetThenTargetAlly < Battle::Move
|
||||
def pbNumHits(user, targets); return 1; end
|
||||
def pbRepeatHit?; return true; end
|
||||
|
||||
def pbModifyTargets(targets, user)
|
||||
return if targets.length != 1
|
||||
choices = []
|
||||
targets[0].allAllies.each { |b| user.pbAddTarget(choices, user, b, self) }
|
||||
return if choices.length == 0
|
||||
idxChoice = (choices.length > 1) ? @battle.pbRandom(choices.length) : 0
|
||||
user.pbAddTarget(targets, user, choices[idxChoice], self, !pbTarget(user).can_choose_distant_target?)
|
||||
end
|
||||
|
||||
def pbShowFailMessages?(targets)
|
||||
if targets.length > 1
|
||||
valid_targets = targets.select { |b| !b.fainted? && !b.damageState.unaffected }
|
||||
return valid_targets.length <= 1
|
||||
end
|
||||
return super
|
||||
end
|
||||
|
||||
def pbDesignateTargetsForHit(targets, hitNum)
|
||||
valid_targets = []
|
||||
targets.each { |b| valid_targets.push(b) if !b.damageState.unaffected }
|
||||
return [valid_targets[1]] if valid_targets[1] && hitNum == 1
|
||||
return [valid_targets[0]]
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Hits 3 times. Power is multiplied by the hit number. (Triple Kick)
|
||||
# An accuracy check is performed for each hit.
|
||||
#===============================================================================
|
||||
class Battle::Move::HitThreeTimesPowersUpWithEachHit < Battle::Move
|
||||
def multiHitMove?; return true; end
|
||||
def pbNumHits(user,targets); return 3; end
|
||||
|
||||
def successCheckPerHit?
|
||||
return @accCheckPerHit
|
||||
end
|
||||
|
||||
def pbOnStartUse(user,targets)
|
||||
@calcBaseDmg = 0
|
||||
@accCheckPerHit = !user.hasActiveAbility?(:SKILLLINK)
|
||||
end
|
||||
|
||||
def pbBaseDamage(baseDmg,user,target)
|
||||
@calcBaseDmg += baseDmg
|
||||
return @calcBaseDmg
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Hits 3 times in a row. If each hit could be a critical hit, it will definitely
|
||||
# be a critical hit. (Surging Strikes)
|
||||
#===============================================================================
|
||||
class Battle::Move::HitThreeTimesAlwaysCriticalHit < Battle::Move
|
||||
def multiHitMove?; return true; end
|
||||
def pbNumHits(user, targets); return 3; end
|
||||
def pbCritialOverride(user, target); return 1; end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Hits 2-5 times.
|
||||
#===============================================================================
|
||||
class Battle::Move::HitTwoToFiveTimes < Battle::Move
|
||||
def multiHitMove?; return true; end
|
||||
|
||||
def pbNumHits(user,targets)
|
||||
hitChances = [
|
||||
2, 2, 2, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 3, 3, 3,
|
||||
4, 4, 4,
|
||||
5, 5, 5
|
||||
]
|
||||
r = @battle.pbRandom(hitChances.length)
|
||||
r = hitChances.length-1 if user.hasActiveAbility?(:SKILLLINK)
|
||||
return hitChances[r]
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Hits 2-5 times. If the user is Ash Greninja, powers up and hits 3 times.
|
||||
# (Water Shuriken)
|
||||
#===============================================================================
|
||||
class Battle::Move::HitTwoToFiveTimesOrThreeForAshGreninja < Battle::Move::HitTwoToFiveTimes
|
||||
def pbNumHits(user,targets)
|
||||
return 3 if user.isSpecies?(:GRENINJA) && user.form == 2
|
||||
return super
|
||||
end
|
||||
|
||||
def pbBaseDamage(baseDmg,user,target)
|
||||
return 20 if user.isSpecies?(:GRENINJA) && user.form == 2
|
||||
return super
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Hits 2-5 times in a row. If the move does not fail, increases the user's Speed
|
||||
# by 1 stage and decreases the user's Defense by 1 stage. (Scale Shot)
|
||||
#===============================================================================
|
||||
class Battle::Move::HitTwoToFiveTimesRaiseUserSpd1LowerUserDef1 < Battle::Move
|
||||
def multiHitMove?; return true; end
|
||||
|
||||
def pbNumHits(user, targets)
|
||||
hitChances = [
|
||||
2, 2, 2, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 3, 3, 3,
|
||||
4, 4, 4,
|
||||
5, 5, 5]
|
||||
r = @battle.pbRandom(hitChances.length)
|
||||
r = hitChances.length - 1 if user.hasActiveAbility?(:SKILLLINK)
|
||||
return hitChances[r]
|
||||
end
|
||||
|
||||
def pbEffectAfterAllHits(user, target)
|
||||
return if target.damageState.unaffected
|
||||
if user.pbCanLowerStatStage?(:DEFENSE, user, self)
|
||||
user.pbLowerStatStage(:DEFENSE, 1, user)
|
||||
end
|
||||
if user.pbCanRaiseStatStage?(:SPEED, user, self)
|
||||
user.pbRaiseStatStage(:SPEED, 1, user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Hits X times, where X is the number of non-user unfainted status-free Pokémon
|
||||
# in the user's party (not including partner trainers). Fails if X is 0.
|
||||
# Base power of each hit depends on the base Attack stat for the species of that
|
||||
# hit's participant. (Beat Up)
|
||||
#===============================================================================
|
||||
class Battle::Move::HitOncePerUserTeamMember < Battle::Move
|
||||
def multiHitMove?; return true; end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
@beatUpList = []
|
||||
@battle.eachInTeamFromBattlerIndex(user.index) do |pkmn,i|
|
||||
next if !pkmn.able? || pkmn.status != :NONE
|
||||
@beatUpList.push(i)
|
||||
end
|
||||
if @beatUpList.length==0
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbNumHits(user,targets)
|
||||
return @beatUpList.length
|
||||
end
|
||||
|
||||
def pbBaseDamage(baseDmg,user,target)
|
||||
i = @beatUpList.shift # First element in array, and removes it from array
|
||||
atk = @battle.pbParty(user.index)[i].baseStats[:ATTACK]
|
||||
return 5+(atk/10)
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Attacks first turn, skips second turn (if successful).
|
||||
#===============================================================================
|
||||
class Battle::Move::AttackAndSkipNextTurn < Battle::Move
|
||||
def pbEffectGeneral(user)
|
||||
user.effects[PBEffects::HyperBeam] = 2
|
||||
user.currentMove = @id
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Two turn attack. Skips first turn, attacks second turn. (Razor Wind)
|
||||
#===============================================================================
|
||||
class Battle::Move::TwoTurnAttack < Battle::Move::TwoTurnMove
|
||||
def pbChargingTurnMessage(user,targets)
|
||||
@battle.pbDisplay(_INTL("{1} whipped up a whirlwind!",user.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Two turn attack. Skips first turn, attacks second turn. (Solar Beam, Solar Blade)
|
||||
# Power halved in all weather except sunshine. In sunshine, takes 1 turn instead.
|
||||
#===============================================================================
|
||||
class Battle::Move::TwoTurnAttackOneTurnInSun < Battle::Move::TwoTurnMove
|
||||
def pbIsChargingTurn?(user)
|
||||
ret = super
|
||||
if !user.effects[PBEffects::TwoTurnAttack]
|
||||
if [:Sun, :HarshSun].include?(user.effectiveWeather)
|
||||
@powerHerb = false
|
||||
@chargingTurn = true
|
||||
@damagingTurn = true
|
||||
return false
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
def pbChargingTurnMessage(user,targets)
|
||||
@battle.pbDisplay(_INTL("{1} took in sunlight!",user.pbThis))
|
||||
end
|
||||
|
||||
def pbBaseDamageMultiplier(damageMult,user,target)
|
||||
damageMult /= 2 if ![:None, :Sun, :HarshSun].include?(user.effectiveWeather)
|
||||
return damageMult
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Two turn attack. Skips first turn, attacks second turn. (Freeze Shock)
|
||||
# May paralyze the target.
|
||||
#===============================================================================
|
||||
class Battle::Move::TwoTurnAttackParalyzeTarget < Battle::Move::TwoTurnMove
|
||||
def pbChargingTurnMessage(user,targets)
|
||||
@battle.pbDisplay(_INTL("{1} became cloaked in a freezing light!",user.pbThis))
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
target.pbParalyze(user) if target.pbCanParalyze?(user,false,self)
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Two turn attack. Skips first turn, attacks second turn. (Ice Burn)
|
||||
# May burn the target.
|
||||
#===============================================================================
|
||||
class Battle::Move::TwoTurnAttackBurnTarget < Battle::Move::TwoTurnMove
|
||||
def pbChargingTurnMessage(user,targets)
|
||||
@battle.pbDisplay(_INTL("{1} became cloaked in freezing air!",user.pbThis))
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
target.pbBurn(user) if target.pbCanBurn?(user,false,self)
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Two turn attack. Skips first turn, attacks second turn. (Sky Attack)
|
||||
# May make the target flinch.
|
||||
#===============================================================================
|
||||
class Battle::Move::TwoTurnAttackFlinchTarget < Battle::Move::TwoTurnMove
|
||||
def flinchingMove?; return true; end
|
||||
|
||||
def pbChargingTurnMessage(user,targets)
|
||||
@battle.pbDisplay(_INTL("{1} became cloaked in a harsh light!",user.pbThis))
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
target.pbFlinch(user)
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Two turn attack. Skips first turn, and increases the user's Special Attack,
|
||||
# Special Defense and Speed by 2 stages each in the second turn. (Geomancy)
|
||||
#===============================================================================
|
||||
class Battle::Move::TwoTurnAttackRaiseUserSpAtkSpDefSpd2 < Battle::Move::TwoTurnMove
|
||||
def pbMoveFailed?(user,targets)
|
||||
return false if user.effects[PBEffects::TwoTurnAttack] # Charging turn
|
||||
if !user.pbCanRaiseStatStage?(:SPECIAL_ATTACK,user,self) &&
|
||||
!user.pbCanRaiseStatStage?(:SPECIAL_DEFENSE,user,self) &&
|
||||
!user.pbCanRaiseStatStage?(:SPEED,user,self)
|
||||
@battle.pbDisplay(_INTL("{1}'s stats won't go any higher!",user.pbThis))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbChargingTurnMessage(user,targets)
|
||||
@battle.pbDisplay(_INTL("{1} is absorbing power!",user.pbThis))
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
return if !@damagingTurn
|
||||
showAnim = true
|
||||
[:SPECIAL_ATTACK,:SPECIAL_DEFENSE,:SPEED].each do |s|
|
||||
next if !user.pbCanRaiseStatStage?(s,user,self)
|
||||
if user.pbRaiseStatStage(s,2,user,showAnim)
|
||||
showAnim = false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Two turn attack. Ups user's Defense by 1 stage first turn, attacks second turn.
|
||||
# (Skull Bash)
|
||||
#===============================================================================
|
||||
class Battle::Move::TwoTurnAttackChargeRaiseUserDefense1 < Battle::Move::TwoTurnMove
|
||||
def pbChargingTurnMessage(user,targets)
|
||||
@battle.pbDisplay(_INTL("{1} tucked in its head!",user.pbThis))
|
||||
end
|
||||
|
||||
def pbChargingTurnEffect(user,target)
|
||||
if user.pbCanRaiseStatStage?(:DEFENSE,user,self)
|
||||
user.pbRaiseStatStage(:DEFENSE,1,user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Two-turn attack. On the first turn, increases the user's Special Attack by 1
|
||||
# stage. On the second turn, does damage. (Meteor Beam)
|
||||
#===============================================================================
|
||||
class Battle::Move::TwoTurnAttackChargeRaiseUserSpAtk1 < Battle::Move::TwoTurnMove
|
||||
def pbChargingTurnMessage(user, targets)
|
||||
@battle.pbDisplay(_INTL("{1} is overflowing with space power!", user.pbThis))
|
||||
end
|
||||
|
||||
def pbChargingTurnEffect(user, target)
|
||||
if user.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user, self)
|
||||
user.pbRaiseStatStage(:SPECIAL_ATTACK, 1, user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Two turn attack. Skips first turn, attacks second turn. (Dig)
|
||||
# (Handled in Battler's pbSuccessCheckPerHit): Is semi-invulnerable during use.
|
||||
#===============================================================================
|
||||
class Battle::Move::TwoTurnAttackInvulnerableUnderground < Battle::Move::TwoTurnMove
|
||||
def pbChargingTurnMessage(user,targets)
|
||||
@battle.pbDisplay(_INTL("{1} burrowed its way under the ground!",user.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Two turn attack. Skips first turn, attacks second turn. (Dive)
|
||||
# (Handled in Battler's pbSuccessCheckPerHit): Is semi-invulnerable during use.
|
||||
#===============================================================================
|
||||
class Battle::Move::TwoTurnAttackInvulnerableUnderwater < Battle::Move::TwoTurnMove
|
||||
def pbChargingTurnMessage(user,targets)
|
||||
@battle.pbDisplay(_INTL("{1} hid underwater!",user.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Two turn attack. Skips first turn, attacks second turn. (Fly)
|
||||
# (Handled in Battler's pbSuccessCheckPerHit): Is semi-invulnerable during use.
|
||||
#===============================================================================
|
||||
class Battle::Move::TwoTurnAttackInvulnerableInSky < Battle::Move::TwoTurnMove
|
||||
def unusableInGravity?; return true; end
|
||||
|
||||
def pbChargingTurnMessage(user,targets)
|
||||
@battle.pbDisplay(_INTL("{1} flew up high!",user.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Two turn attack. Skips first turn, attacks second turn. (Bounce)
|
||||
# May paralyze the target.
|
||||
# (Handled in Battler's pbSuccessCheckPerHit): Is semi-invulnerable during use.
|
||||
#===============================================================================
|
||||
class Battle::Move::TwoTurnAttackInvulnerableInSkyParalyzeTarget < Battle::Move::TwoTurnMove
|
||||
def unusableInGravity?; return true; end
|
||||
|
||||
def pbChargingTurnMessage(user,targets)
|
||||
@battle.pbDisplay(_INTL("{1} sprang up!",user.pbThis))
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
target.pbParalyze(user) if target.pbCanParalyze?(user,false,self)
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Two turn attack. Skips first turn, attacks second turn. (Sky Drop)
|
||||
# (Handled in Battler's pbSuccessCheckPerHit): Is semi-invulnerable during use.
|
||||
# Target is also semi-invulnerable during use, and can't take any action.
|
||||
# Doesn't damage airborne Pokémon (but still makes them unable to move during).
|
||||
#===============================================================================
|
||||
class Battle::Move::TwoTurnAttackInvulnerableInSkyTargetCannotAct < Battle::Move::TwoTurnMove
|
||||
def unusableInGravity?; return true; end
|
||||
|
||||
def pbIsChargingTurn?(user)
|
||||
# NOTE: Sky Drop doesn't benefit from Power Herb, probably because it works
|
||||
# differently (i.e. immobilises the target during use too).
|
||||
@powerHerb = false
|
||||
@chargingTurn = (user.effects[PBEffects::TwoTurnAttack].nil?)
|
||||
@damagingTurn = (!user.effects[PBEffects::TwoTurnAttack].nil?)
|
||||
return !@damagingTurn
|
||||
end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
if !target.opposes?(user)
|
||||
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
||||
return true
|
||||
end
|
||||
if target.effects[PBEffects::Substitute]>0 && !ignoresSubstitute?(user)
|
||||
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
||||
return true
|
||||
end
|
||||
if Settings::MECHANICS_GENERATION >= 6 && target.pbWeight>=2000 # 200.0kg
|
||||
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
||||
return true
|
||||
end
|
||||
if target.semiInvulnerable? ||
|
||||
(target.effects[PBEffects::SkyDrop]>=0 && @chargingTurn)
|
||||
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
||||
return true
|
||||
end
|
||||
if target.effects[PBEffects::SkyDrop]!=user.index && @damagingTurn
|
||||
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbCalcTypeMod(movetype,user,target)
|
||||
return Effectiveness::INEFFECTIVE if target.pbHasType?(:FLYING)
|
||||
return super
|
||||
end
|
||||
|
||||
def pbChargingTurnMessage(user,targets)
|
||||
@battle.pbDisplay(_INTL("{1} took {2} into the sky!",user.pbThis,targets[0].pbThis(true)))
|
||||
end
|
||||
|
||||
def pbAttackingTurnMessage(user,targets)
|
||||
@battle.pbDisplay(_INTL("{1} was freed from the Sky Drop!",targets[0].pbThis))
|
||||
end
|
||||
|
||||
def pbChargingTurnEffect(user,target)
|
||||
target.effects[PBEffects::SkyDrop] = user.index
|
||||
end
|
||||
|
||||
def pbAttackingTurnEffect(user,target)
|
||||
target.effects[PBEffects::SkyDrop] = -1
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Two turn attack. Skips first turn, attacks second turn. Is invulnerable during
|
||||
# use. Ends target's protections upon hit. (Shadow Force, Phantom Force)
|
||||
#===============================================================================
|
||||
class Battle::Move::TwoTurnAttackInvulnerableRemoveProtections < Battle::Move::TwoTurnMove
|
||||
def pbChargingTurnMessage(user,targets)
|
||||
@battle.pbDisplay(_INTL("{1} vanished instantly!",user.pbThis))
|
||||
end
|
||||
|
||||
def pbAttackingTurnEffect(user,target)
|
||||
target.effects[PBEffects::BanefulBunker] = false
|
||||
target.effects[PBEffects::KingsShield] = false
|
||||
target.effects[PBEffects::Obstruct] = false
|
||||
target.effects[PBEffects::Protect] = false
|
||||
target.effects[PBEffects::SpikyShield] = false
|
||||
target.pbOwnSide.effects[PBEffects::CraftyShield] = false
|
||||
target.pbOwnSide.effects[PBEffects::MatBlock] = false
|
||||
target.pbOwnSide.effects[PBEffects::QuickGuard] = false
|
||||
target.pbOwnSide.effects[PBEffects::WideGuard] = false
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# User must use this move for 2 more rounds. No battlers can sleep. (Uproar)
|
||||
# NOTE: Bulbapedia claims that an uproar will wake up Pokémon even if they have
|
||||
# Soundproof, and will not allow Pokémon to fall asleep even if they have
|
||||
# Soundproof. I think this is an oversight, so I've let Soundproof Pokémon
|
||||
# be unaffected by Uproar waking/non-sleeping effects.
|
||||
#===============================================================================
|
||||
class Battle::Move::MultiTurnAttackPreventSleeping < Battle::Move
|
||||
def pbEffectGeneral(user)
|
||||
return if user.effects[PBEffects::Uproar]>0
|
||||
user.effects[PBEffects::Uproar] = 3
|
||||
user.currentMove = @id
|
||||
@battle.pbDisplay(_INTL("{1} caused an uproar!",user.pbThis))
|
||||
@battle.pbPriority(true).each do |b|
|
||||
next if b.fainted? || b.status != :SLEEP
|
||||
next if b.hasActiveAbility?(:SOUNDPROOF)
|
||||
b.pbCureStatus
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# User must use this move for 1 or 2 more rounds. At end, user becomes confused.
|
||||
# (Outrage, Petal Dange, Thrash)
|
||||
#===============================================================================
|
||||
class Battle::Move::MultiTurnAttackConfuseUserAtEnd < Battle::Move
|
||||
def pbEffectAfterAllHits(user,target)
|
||||
if !target.damageState.unaffected && user.effects[PBEffects::Outrage]==0
|
||||
user.effects[PBEffects::Outrage] = 2+@battle.pbRandom(2)
|
||||
user.currentMove = @id
|
||||
end
|
||||
if user.effects[PBEffects::Outrage]>0
|
||||
user.effects[PBEffects::Outrage] -= 1
|
||||
if user.effects[PBEffects::Outrage]==0 && user.pbCanConfuseSelf?(false)
|
||||
user.pbConfuse(_INTL("{1} became confused due to fatigue!",user.pbThis))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# User must use this move for 4 more rounds. Power doubles each round.
|
||||
# Power is also doubled if user has curled up. (Ice Ball, Rollout)
|
||||
#===============================================================================
|
||||
class Battle::Move::MultiTurnAttackPowersUpEachTurn < Battle::Move
|
||||
def pbBaseDamage(baseDmg,user,target)
|
||||
shift = (5 - user.effects[PBEffects::Rollout]) # 0-4, where 0 is most powerful
|
||||
shift = 0 if user.effects[PBEffects::Rollout] == 0 # For first turn
|
||||
shift += 1 if user.effects[PBEffects::DefenseCurl]
|
||||
baseDmg *= 2**shift
|
||||
return baseDmg
|
||||
end
|
||||
|
||||
def pbEffectAfterAllHits(user,target)
|
||||
if !target.damageState.unaffected && user.effects[PBEffects::Rollout] == 0
|
||||
user.effects[PBEffects::Rollout] = 5
|
||||
user.currentMove = @id
|
||||
end
|
||||
user.effects[PBEffects::Rollout] -= 1 if user.effects[PBEffects::Rollout] > 0
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# User bides its time this round and next round. The round after, deals 2x the
|
||||
# total direct damage it took while biding to the last battler that damaged it.
|
||||
# (Bide)
|
||||
#===============================================================================
|
||||
class Battle::Move::MultiTurnAttackBideThenReturnDoubleDamage < Battle::Move::FixedDamageMove
|
||||
def pbAddTarget(targets,user)
|
||||
return if user.effects[PBEffects::Bide]!=1 # Not the attack turn
|
||||
idxTarget = user.effects[PBEffects::BideTarget]
|
||||
t = (idxTarget>=0) ? @battle.battlers[idxTarget] : nil
|
||||
if !user.pbAddTarget(targets,user,t,self,false)
|
||||
user.pbAddTargetRandomFoe(targets,user,self,false)
|
||||
end
|
||||
end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
return false if user.effects[PBEffects::Bide]!=1 # Not the attack turn
|
||||
if user.effects[PBEffects::BideDamage]==0
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
user.effects[PBEffects::Bide] = 0 # No need to reset other Bide variables
|
||||
return true
|
||||
end
|
||||
if targets.length==0
|
||||
@battle.pbDisplay(_INTL("But there was no target..."))
|
||||
user.effects[PBEffects::Bide] = 0 # No need to reset other Bide variables
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbOnStartUse(user,targets)
|
||||
@damagingTurn = (user.effects[PBEffects::Bide]==1) # If attack turn
|
||||
end
|
||||
|
||||
def pbDisplayUseMessage(user)
|
||||
if @damagingTurn # Attack turn
|
||||
@battle.pbDisplayBrief(_INTL("{1} unleashed energy!",user.pbThis))
|
||||
elsif user.effects[PBEffects::Bide]>1 # Charging turns
|
||||
@battle.pbDisplayBrief(_INTL("{1} is storing energy!",user.pbThis))
|
||||
else
|
||||
super # Start using Bide
|
||||
end
|
||||
end
|
||||
|
||||
def pbDamagingMove? # Stops damage being dealt in the charging turns
|
||||
return false if !@damagingTurn
|
||||
return super
|
||||
end
|
||||
|
||||
def pbFixedDamage(user,target)
|
||||
return user.effects[PBEffects::BideDamage]*2
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
if user.effects[PBEffects::Bide]==0 # Starting using Bide
|
||||
user.effects[PBEffects::Bide] = 3
|
||||
user.effects[PBEffects::BideDamage] = 0
|
||||
user.effects[PBEffects::BideTarget] = -1
|
||||
user.currentMove = @id
|
||||
end
|
||||
user.effects[PBEffects::Bide] -= 1
|
||||
end
|
||||
|
||||
def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true)
|
||||
hitNum = 1 if !@damagingTurn # Charging anim
|
||||
super
|
||||
end
|
||||
end
|
||||
686
Data/Scripts/011_Battle/003_Move/010_MoveEffects_Healing.rb
Normal file
686
Data/Scripts/011_Battle/003_Move/010_MoveEffects_Healing.rb
Normal file
@@ -0,0 +1,686 @@
|
||||
#===============================================================================
|
||||
# Heals user to full HP. User falls asleep for 2 more rounds. (Rest)
|
||||
#===============================================================================
|
||||
class Battle::Move::HealUserFullyAndFallAsleep < Battle::Move::HealingMove
|
||||
def pbMoveFailed?(user,targets)
|
||||
if user.asleep?
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return true if !user.pbCanSleep?(user,true,self,true)
|
||||
return true if super
|
||||
return false
|
||||
end
|
||||
|
||||
def pbHealAmount(user)
|
||||
return user.totalhp-user.hp
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
user.pbSleepSelf(_INTL("{1} slept and became healthy!",user.pbThis),3)
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Heals user by 1/2 of its max HP.
|
||||
#===============================================================================
|
||||
class Battle::Move::HealUserHalfOfTotalHP < Battle::Move::HealingMove
|
||||
def pbHealAmount(user)
|
||||
return (user.totalhp/2.0).round
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Heals user by an amount depending on the weather. (Moonlight, Morning Sun,
|
||||
# Synthesis)
|
||||
#===============================================================================
|
||||
class Battle::Move::HealUserDependingOnWeather < Battle::Move::HealingMove
|
||||
def pbOnStartUse(user,targets)
|
||||
case user.effectiveWeather
|
||||
when :Sun, :HarshSun
|
||||
@healAmount = (user.totalhp*2/3.0).round
|
||||
when :None, :StrongWinds
|
||||
@healAmount = (user.totalhp/2.0).round
|
||||
else
|
||||
@healAmount = (user.totalhp/4.0).round
|
||||
end
|
||||
end
|
||||
|
||||
def pbHealAmount(user)
|
||||
return @healAmount
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Heals user by 1/2 of its max HP, or 2/3 of its max HP in a sandstorm. (Shore Up)
|
||||
#===============================================================================
|
||||
class Battle::Move::HealUserDependingOnSandstorm < Battle::Move::HealingMove
|
||||
def pbHealAmount(user)
|
||||
return (user.totalhp * 2 / 3.0).round if user.effectiveWeather == :Sandstorm
|
||||
return (user.totalhp / 2.0).round
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Heals user by 1/2 of its max HP. (Roost)
|
||||
# User roosts, and its Flying type is ignored for attacks used against it.
|
||||
#===============================================================================
|
||||
class Battle::Move::HealUserHalfOfTotalHPLoseFlyingTypeThisTurn < Battle::Move::HealingMove
|
||||
def pbHealAmount(user)
|
||||
return (user.totalhp/2.0).round
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
super
|
||||
user.effects[PBEffects::Roost] = true
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Cures the target's permanent status problems. Heals user by 1/2 of its max HP.
|
||||
# (Purify)
|
||||
#===============================================================================
|
||||
class Battle::Move::CureTargetStatusHealUserHalfOfTotalHP < Battle::Move::HealingMove
|
||||
def canSnatch?; return false; end # Because it affects a target
|
||||
def canMagicCoat?; return true; end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
if target.status == :NONE
|
||||
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbHealAmount(user)
|
||||
return (user.totalhp/2.0).round
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
target.pbCureStatus
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Decreases the target's Attack by 1 stage. Heals user by an amount equal to the
|
||||
# target's Attack stat (after applying stat stages, before this move decreases
|
||||
# it). (Strength Sap)
|
||||
#===============================================================================
|
||||
class Battle::Move::HealUserByTargetAttackLowerTargetAttack1 < Battle::Move
|
||||
def healingMove?; return true; end
|
||||
def canMagicCoat?; return true; end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
# NOTE: The official games appear to just check whether the target's Attack
|
||||
# stat stage is -6 and fail if so, but I've added the "fail if target
|
||||
# has Contrary and is at +6" check too for symmetry. This move still
|
||||
# works even if the stat stage cannot be changed due to an ability or
|
||||
# other effect.
|
||||
if !@battle.moldBreaker && target.hasActiveAbility?(:CONTRARY) &&
|
||||
target.statStageAtMax?(:ATTACK)
|
||||
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
||||
return true
|
||||
elsif target.statStageAtMin?(:ATTACK)
|
||||
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
# Calculate target's effective attack value
|
||||
stageMul = [2,2,2,2,2,2, 2, 3,4,5,6,7,8]
|
||||
stageDiv = [8,7,6,5,4,3, 2, 2,2,2,2,2,2]
|
||||
atk = target.attack
|
||||
atkStage = target.stages[:ATTACK]+6
|
||||
healAmt = (atk.to_f*stageMul[atkStage]/stageDiv[atkStage]).floor
|
||||
# Reduce target's Attack stat
|
||||
if target.pbCanLowerStatStage?(:ATTACK,user,self)
|
||||
target.pbLowerStatStage(:ATTACK,1,user)
|
||||
end
|
||||
# Heal user
|
||||
if target.hasActiveAbility?(:LIQUIDOOZE)
|
||||
@battle.pbShowAbilitySplash(target)
|
||||
user.pbReduceHP(healAmt)
|
||||
@battle.pbDisplay(_INTL("{1} sucked up the liquid ooze!",user.pbThis))
|
||||
@battle.pbHideAbilitySplash(target)
|
||||
user.pbItemHPHealCheck
|
||||
elsif user.canHeal?
|
||||
healAmt = (healAmt*1.3).floor if user.hasActiveItem?(:BIGROOT)
|
||||
user.pbRecoverHP(healAmt)
|
||||
@battle.pbDisplay(_INTL("{1}'s HP was restored.",user.pbThis))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# User gains half the HP it inflicts as damage.
|
||||
#===============================================================================
|
||||
class Battle::Move::HealUserByHalfOfDamageDone < Battle::Move
|
||||
def healingMove?; return Settings::MECHANICS_GENERATION >= 6; end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if target.damageState.hpLost<=0
|
||||
hpGain = (target.damageState.hpLost/2.0).round
|
||||
user.pbRecoverHPFromDrain(hpGain,target)
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# User gains half the HP it inflicts as damage. Fails if target is not asleep.
|
||||
# (Dream Eater)
|
||||
#===============================================================================
|
||||
class Battle::Move::HealUserByHalfOfDamageDoneIfTargetAsleep < Battle::Move
|
||||
def healingMove?; return Settings::MECHANICS_GENERATION >= 6; end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
if !target.asleep?
|
||||
@battle.pbDisplay(_INTL("{1} wasn't affected!", target.pbThis)) if show_message
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if target.damageState.hpLost<=0
|
||||
hpGain = (target.damageState.hpLost/2.0).round
|
||||
user.pbRecoverHPFromDrain(hpGain,target)
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# User gains 3/4 the HP it inflicts as damage. (Draining Kiss, Oblivion Wing)
|
||||
#===============================================================================
|
||||
class Battle::Move::HealUserByThreeQuartersOfDamageDone < Battle::Move
|
||||
def healingMove?; return Settings::MECHANICS_GENERATION >= 6; end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if target.damageState.hpLost<=0
|
||||
hpGain = (target.damageState.hpLost*0.75).round
|
||||
user.pbRecoverHPFromDrain(hpGain,target)
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# The user and its allies gain 25% of their total HP. (Life Dew)
|
||||
#===============================================================================
|
||||
class Battle::Move::HealUserAndAlliesQuarterOfTotalHP < Battle::Move
|
||||
def healingMove?; return true; end
|
||||
|
||||
def pbMoveFailed?(user, targets)
|
||||
if @battle.allSameSideBattlers(user).none? { |b| b.canHeal? }
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
return !target.canHeal?
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user, target)
|
||||
target.pbRecoverHP(target.totalhp / 4)
|
||||
@battle.pbDisplay(_INTL("{1}'s HP was restored.", target.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# The user and its allies gain 25% of their total HP and are cured of their
|
||||
# permanent status problems. (Jungle Healing)
|
||||
#===============================================================================
|
||||
class Battle::Move::HealUserAndAlliesQuarterOfTotalHPCureStatus < Battle::Move
|
||||
def healingMove?; return true; end
|
||||
|
||||
def pbMoveFailed?(user, targets)
|
||||
if @battle.allSameSideBattlers(user).none? { |b| b.canHeal? || b.status != :NONE }
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
return target.status == :NONE && !target.canHeal?
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user, target)
|
||||
if target.canHeal?
|
||||
target.pbRecoverHP(target.totalhp / 4)
|
||||
@battle.pbDisplay(_INTL("{1}'s HP was restored.", target.pbThis))
|
||||
end
|
||||
if target.status != :NONE
|
||||
old_status = target.status
|
||||
target.pbCureStatus(false)
|
||||
case old_status
|
||||
when :SLEEP
|
||||
@battle.pbDisplay(_INTL("{1} was woken from sleep.", target.pbThis))
|
||||
when :POISON
|
||||
@battle.pbDisplay(_INTL("{1} was cured of its poisoning.", target.pbThis))
|
||||
when :BURN
|
||||
@battle.pbDisplay(_INTL("{1}'s burn was healed.", target.pbThis))
|
||||
when :PARALYSIS
|
||||
@battle.pbDisplay(_INTL("{1} was cured of paralysis.", target.pbThis))
|
||||
when :FROZEN
|
||||
@battle.pbDisplay(_INTL("{1} was thawed out.", target.pbThis))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Heals target by 1/2 of its max HP. (Heal Pulse)
|
||||
#===============================================================================
|
||||
class Battle::Move::HealTargetHalfOfTotalHP < Battle::Move
|
||||
def healingMove?; return true; end
|
||||
def canMagicCoat?; return true; end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
if target.hp==target.totalhp
|
||||
@battle.pbDisplay(_INTL("{1}'s HP is full!", target.pbThis)) if show_message
|
||||
return true
|
||||
elsif !target.canHeal?
|
||||
@battle.pbDisplay(_INTL("{1} is unaffected!", target.pbThis)) if show_message
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
hpGain = (target.totalhp/2.0).round
|
||||
if pulseMove? && user.hasActiveAbility?(:MEGALAUNCHER)
|
||||
hpGain = (target.totalhp*3/4.0).round
|
||||
end
|
||||
target.pbRecoverHP(hpGain)
|
||||
@battle.pbDisplay(_INTL("{1}'s HP was restored.",target.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Heals target by 1/2 of its max HP, or 2/3 of its max HP in Grassy Terrain.
|
||||
# (Floral Healing)
|
||||
#===============================================================================
|
||||
class Battle::Move::HealTargetDependingOnGrassyTerrain < Battle::Move
|
||||
def healingMove?; return true; end
|
||||
def canMagicCoat?; return true; end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
if target.hp==target.totalhp
|
||||
@battle.pbDisplay(_INTL("{1}'s HP is full!", target.pbThis)) if show_message
|
||||
return true
|
||||
elsif !target.canHeal?
|
||||
@battle.pbDisplay(_INTL("{1} is unaffected!", target.pbThis)) if show_message
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
hpGain = (target.totalhp/2.0).round
|
||||
hpGain = (target.totalhp*2/3.0).round if @battle.field.terrain == :Grassy
|
||||
target.pbRecoverHP(hpGain)
|
||||
@battle.pbDisplay(_INTL("{1}'s HP was restored.",target.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Battler in user's position is healed by 1/2 of its max HP, at the end of the
|
||||
# next round. (Wish)
|
||||
#===============================================================================
|
||||
class Battle::Move::HealUserPositionNextTurn < Battle::Move
|
||||
def healingMove?; return true; end
|
||||
def canSnatch?; return true; end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if @battle.positions[user.index].effects[PBEffects::Wish]>0
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
@battle.positions[user.index].effects[PBEffects::Wish] = 2
|
||||
@battle.positions[user.index].effects[PBEffects::WishAmount] = (user.totalhp/2.0).round
|
||||
@battle.positions[user.index].effects[PBEffects::WishMaker] = user.pokemonIndex
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Rings the user. Ringed Pokémon gain 1/16 of max HP at the end of each round.
|
||||
# (Aqua Ring)
|
||||
#===============================================================================
|
||||
class Battle::Move::StartHealUserEachTurn < Battle::Move
|
||||
def canSnatch?; return true; end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if user.effects[PBEffects::AquaRing]
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
user.effects[PBEffects::AquaRing] = true
|
||||
@battle.pbDisplay(_INTL("{1} surrounded itself with a veil of water!",user.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Ingrains the user. Ingrained Pokémon gain 1/16 of max HP at the end of each
|
||||
# round, and cannot flee or switch out. (Ingrain)
|
||||
#===============================================================================
|
||||
class Battle::Move::StartHealUserEachTurnTrapUserInBattle < Battle::Move
|
||||
def canSnatch?; return true; end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if user.effects[PBEffects::Ingrain]
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
user.effects[PBEffects::Ingrain] = true
|
||||
@battle.pbDisplay(_INTL("{1} planted its roots!",user.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Target will lose 1/4 of max HP at end of each round, while asleep. (Nightmare)
|
||||
#===============================================================================
|
||||
class Battle::Move::StartDamageTargetEachTurnIfTargetAsleep < Battle::Move
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
if !target.asleep? || target.effects[PBEffects::Nightmare]
|
||||
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
target.effects[PBEffects::Nightmare] = true
|
||||
@battle.pbDisplay(_INTL("{1} began having a nightmare!",target.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Seeds the target. Seeded Pokémon lose 1/8 of max HP at the end of each round,
|
||||
# and the Pokémon in the user's position gains the same amount. (Leech Seed)
|
||||
#===============================================================================
|
||||
class Battle::Move::StartLeechSeedTarget < Battle::Move
|
||||
def canMagicCoat?; return true; end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
if target.effects[PBEffects::LeechSeed]>=0
|
||||
@battle.pbDisplay(_INTL("{1} evaded the attack!", target.pbThis)) if show_message
|
||||
return true
|
||||
end
|
||||
if target.pbHasType?(:GRASS)
|
||||
@battle.pbDisplay(_INTL("It doesn't affect {1}...", target.pbThis(true))) if show_message
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbMissMessage(user,target)
|
||||
@battle.pbDisplay(_INTL("{1} evaded the attack!",target.pbThis))
|
||||
return true
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
target.effects[PBEffects::LeechSeed] = user.index
|
||||
@battle.pbDisplay(_INTL("{1} was seeded!",target.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# The user takes damage equal to 1/2 of its total HP, even if the target is
|
||||
# unaffected (this is not recoil damage). (Steel Beam)
|
||||
#===============================================================================
|
||||
class Battle::Move::UserLosesHalfOfTotalHP < Battle::Move
|
||||
def pbEffectAfterAllHits(user, target)
|
||||
return if !user.takesIndirectDamage?
|
||||
amt = (user.totalhp / 2.0).ceil
|
||||
amt = 1 if amt < 1
|
||||
user.pbReduceHP(amt, false)
|
||||
@battle.pbDisplay(_INTL("{1} is damaged by recoil!", user.pbThis))
|
||||
user.pbItemHPHealCheck
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Damages user by 1/2 of its max HP, even if this move misses. (Mind Blown)
|
||||
#===============================================================================
|
||||
class Battle::Move::UserLosesHalfOfTotalHPExplosive < Battle::Move
|
||||
def worksWithNoTargets?; return true; end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if !@battle.moldBreaker
|
||||
bearer = @battle.pbCheckGlobalAbility(:DAMP)
|
||||
if bearer!=nil
|
||||
@battle.pbShowAbilitySplash(bearer)
|
||||
if Battle::Scene::USE_ABILITY_SPLASH
|
||||
@battle.pbDisplay(_INTL("{1} cannot use {2}!",user.pbThis,@name))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("{1} cannot use {2} because of {3}'s {4}!",
|
||||
user.pbThis,@name,bearer.pbThis(true),bearer.abilityName))
|
||||
end
|
||||
@battle.pbHideAbilitySplash(bearer)
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbSelfKO(user)
|
||||
return if !user.takesIndirectDamage?
|
||||
user.pbReduceHP((user.totalhp/2.0).round,false)
|
||||
user.pbItemHPHealCheck
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# User faints, even if the move does nothing else. (Explosion, Self-Destruct)
|
||||
#===============================================================================
|
||||
class Battle::Move::UserFaintsExplosive < Battle::Move
|
||||
def worksWithNoTargets?; return true; end
|
||||
def pbNumHits(user,targets); return 1; end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if !@battle.moldBreaker
|
||||
bearer = @battle.pbCheckGlobalAbility(:DAMP)
|
||||
if bearer!=nil
|
||||
@battle.pbShowAbilitySplash(bearer)
|
||||
if Battle::Scene::USE_ABILITY_SPLASH
|
||||
@battle.pbDisplay(_INTL("{1} cannot use {2}!",user.pbThis,@name))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("{1} cannot use {2} because of {3}'s {4}!",
|
||||
user.pbThis,@name,bearer.pbThis(true),bearer.abilityName))
|
||||
end
|
||||
@battle.pbHideAbilitySplash(bearer)
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbSelfKO(user)
|
||||
return if user.fainted?
|
||||
user.pbReduceHP(user.hp,false)
|
||||
user.pbItemHPHealCheck
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# User faints. If Misty Terrain applies, base power is multiplied by 1.5.
|
||||
# (Misty Explosion)
|
||||
#===============================================================================
|
||||
class Battle::Move::UserFaintsPowersUpInMistyTerrainExplosive < Battle::Move::UserFaintsExplosive
|
||||
def pbBaseDamage(baseDmg, user, target)
|
||||
baseDmg = baseDmg * 3 / 2 if @battle.field.terrain == :Misty
|
||||
return baseDmg
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Inflicts fixed damage equal to user's current HP. (Final Gambit)
|
||||
# User faints (if successful).
|
||||
#===============================================================================
|
||||
class Battle::Move::UserFaintsFixedDamageUserHP < Battle::Move::FixedDamageMove
|
||||
def pbNumHits(user,targets); return 1; end
|
||||
|
||||
def pbOnStartUse(user,targets)
|
||||
@finalGambitDamage = user.hp
|
||||
end
|
||||
|
||||
def pbFixedDamage(user,target)
|
||||
return @finalGambitDamage
|
||||
end
|
||||
|
||||
def pbSelfKO(user)
|
||||
return if user.fainted?
|
||||
user.pbReduceHP(user.hp,false)
|
||||
user.pbItemHPHealCheck
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Decreases the target's Attack and Special Attack by 2 stages each. (Memento)
|
||||
# User faints (if successful).
|
||||
#===============================================================================
|
||||
class Battle::Move::UserFaintsLowerTargetAtkSpAtk2 < Battle::Move::TargetMultiStatDownMove
|
||||
def canMagicCoat?; return false; end
|
||||
|
||||
def initialize(battle,move)
|
||||
super
|
||||
@statDown = [:ATTACK,2,:SPECIAL_ATTACK,2]
|
||||
end
|
||||
|
||||
# NOTE: The user faints even if the target's stats cannot be changed, so this
|
||||
# method must always return false to allow the move's usage to continue.
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
return false
|
||||
end
|
||||
|
||||
def pbSelfKO(user)
|
||||
return if user.fainted?
|
||||
user.pbReduceHP(user.hp,false)
|
||||
user.pbItemHPHealCheck
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# User faints. The Pokémon that replaces the user is fully healed (HP and
|
||||
# status). Fails if user won't be replaced. (Healing Wish)
|
||||
#===============================================================================
|
||||
class Battle::Move::UserFaintsHealAndCureReplacement < Battle::Move
|
||||
def healingMove?; return true; end
|
||||
def canSnatch?; return true; end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if !@battle.pbCanChooseNonActive?(user.index)
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbSelfKO(user)
|
||||
return if user.fainted?
|
||||
user.pbReduceHP(user.hp,false)
|
||||
user.pbItemHPHealCheck
|
||||
@battle.positions[user.index].effects[PBEffects::HealingWish] = true
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# User faints. The Pokémon that replaces the user is fully healed (HP, PP and
|
||||
# status). Fails if user won't be replaced. (Lunar Dance)
|
||||
#===============================================================================
|
||||
class Battle::Move::UserFaintsHealAndCureReplacementRestorePP < Battle::Move
|
||||
def healingMove?; return true; end
|
||||
def canSnatch?; return true; end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if !@battle.pbCanChooseNonActive?(user.index)
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbSelfKO(user)
|
||||
return if user.fainted?
|
||||
user.pbReduceHP(user.hp,false)
|
||||
user.pbItemHPHealCheck
|
||||
@battle.positions[user.index].effects[PBEffects::LunarDance] = true
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# All current battlers will perish after 3 more rounds. (Perish Song)
|
||||
#===============================================================================
|
||||
class Battle::Move::StartPerishCountsForAllBattlers < Battle::Move
|
||||
def pbMoveFailed?(user,targets)
|
||||
failed = true
|
||||
targets.each do |b|
|
||||
next if b.effects[PBEffects::PerishSong]>0 # Heard it before
|
||||
failed = false
|
||||
break
|
||||
end
|
||||
if failed
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
return target.effects[PBEffects::PerishSong]>0 # Heard it before
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
target.effects[PBEffects::PerishSong] = 4
|
||||
target.effects[PBEffects::PerishSongUser] = user.index
|
||||
end
|
||||
|
||||
def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true)
|
||||
super
|
||||
@battle.pbDisplay(_INTL("All Pokémon that hear the song will faint in three turns!"))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# If user is KO'd before it next moves, the battler that caused it also faints.
|
||||
# (Destiny Bond)
|
||||
#===============================================================================
|
||||
class Battle::Move::AttackerFaintsIfUserFaints < Battle::Move
|
||||
def pbMoveFailed?(user,targets)
|
||||
if Settings::MECHANICS_GENERATION >= 7 && user.effects[PBEffects::DestinyBondPrevious]
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
user.effects[PBEffects::DestinyBond] = true
|
||||
@battle.pbDisplay(_INTL("{1} is hoping to take its attacker down with it!",user.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# If user is KO'd before it next moves, the attack that caused it loses all PP.
|
||||
# (Grudge)
|
||||
#===============================================================================
|
||||
class Battle::Move::SetAttackerMovePPTo0IfUserFaints < Battle::Move
|
||||
def pbEffectGeneral(user)
|
||||
user.effects[PBEffects::Grudge] = true
|
||||
@battle.pbDisplay(_INTL("{1} wants its target to bear a grudge!",user.pbThis))
|
||||
end
|
||||
end
|
||||
600
Data/Scripts/011_Battle/003_Move/011_MoveEffects_Items.rb
Normal file
600
Data/Scripts/011_Battle/003_Move/011_MoveEffects_Items.rb
Normal file
@@ -0,0 +1,600 @@
|
||||
#===============================================================================
|
||||
# User steals the target's item, if the user has none itself. (Covet, Thief)
|
||||
# Items stolen from wild Pokémon are kept after the battle.
|
||||
#===============================================================================
|
||||
class Battle::Move::UserTakesTargetItem < Battle::Move
|
||||
def pbEffectAfterAllHits(user,target)
|
||||
return if user.wild? # Wild Pokémon can't thieve
|
||||
return if user.fainted?
|
||||
return if target.damageState.unaffected || target.damageState.substitute
|
||||
return if !target.item || user.item
|
||||
return if target.unlosableItem?(target.item)
|
||||
return if user.unlosableItem?(target.item)
|
||||
return if target.hasActiveAbility?(:STICKYHOLD) && !@battle.moldBreaker
|
||||
itemName = target.itemName
|
||||
user.item = target.item
|
||||
# Permanently steal the item from wild Pokémon
|
||||
if target.wild? && !user.initialItem && target.item == target.initialItem
|
||||
user.setInitialItem(target.item)
|
||||
target.pbRemoveItem
|
||||
else
|
||||
target.pbRemoveItem(false)
|
||||
end
|
||||
@battle.pbDisplay(_INTL("{1} stole {2}'s {3}!",user.pbThis,target.pbThis(true),itemName))
|
||||
user.pbHeldItemTriggerCheck
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# User gives its item to the target. The item remains given after wild battles.
|
||||
# (Bestow)
|
||||
#===============================================================================
|
||||
class Battle::Move::TargetTakesUserItem < Battle::Move
|
||||
def ignoresSubstitute?(user)
|
||||
return true if Settings::MECHANICS_GENERATION >= 6
|
||||
return super
|
||||
end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if !user.item || user.unlosableItem?(user.item)
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
if target.item || target.unlosableItem?(user.item)
|
||||
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
itemName = user.itemName
|
||||
target.item = user.item
|
||||
# Permanently steal the item from wild Pokémon
|
||||
if user.wild? && !target.initialItem && user.item == user.initialItem
|
||||
target.setInitialItem(user.item)
|
||||
user.pbRemoveItem
|
||||
else
|
||||
user.pbRemoveItem(false)
|
||||
end
|
||||
@battle.pbDisplay(_INTL("{1} received {2} from {3}!",target.pbThis,itemName,user.pbThis(true)))
|
||||
target.pbHeldItemTriggerCheck
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# User and target swap items. They remain swapped after wild battles.
|
||||
# (Switcheroo, Trick)
|
||||
#===============================================================================
|
||||
class Battle::Move::UserTargetSwapItems < Battle::Move
|
||||
def pbMoveFailed?(user,targets)
|
||||
if user.wild?
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
if !user.item && !target.item
|
||||
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
||||
return true
|
||||
end
|
||||
if target.unlosableItem?(target.item) ||
|
||||
target.unlosableItem?(user.item) ||
|
||||
user.unlosableItem?(user.item) ||
|
||||
user.unlosableItem?(target.item)
|
||||
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
||||
return true
|
||||
end
|
||||
if target.hasActiveAbility?(:STICKYHOLD) && !@battle.moldBreaker
|
||||
if show_message
|
||||
@battle.pbShowAbilitySplash(target)
|
||||
if Battle::Scene::USE_ABILITY_SPLASH
|
||||
@battle.pbDisplay(_INTL("But it failed to affect {1}!", target.pbThis(true)))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("But it failed to affect {1} because of its {2}!",
|
||||
target.pbThis(true), target.abilityName))
|
||||
end
|
||||
@battle.pbHideAbilitySplash(target)
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
oldUserItem = user.item
|
||||
oldUserItemName = user.itemName
|
||||
oldTargetItem = target.item
|
||||
oldTargetItemName = target.itemName
|
||||
user.item = oldTargetItem
|
||||
user.effects[PBEffects::ChoiceBand] = nil if !user.hasActiveAbility?(:GORILLATACTICS)
|
||||
user.effects[PBEffects::Unburden] = (!user.item && oldUserItem) if user.hasActiveAbility?(:UNBURDEN)
|
||||
target.item = oldUserItem
|
||||
target.effects[PBEffects::ChoiceBand] = nil if !target.hasActiveAbility?(:GORILLATACTICS)
|
||||
target.effects[PBEffects::Unburden] = (!target.item && oldTargetItem) if target.hasActiveAbility?(:UNBURDEN)
|
||||
# Permanently steal the item from wild Pokémon
|
||||
if target.wild? && !user.initialItem && oldTargetItem == target.initialItem
|
||||
user.setInitialItem(oldTargetItem)
|
||||
end
|
||||
@battle.pbDisplay(_INTL("{1} switched items with its opponent!",user.pbThis))
|
||||
@battle.pbDisplay(_INTL("{1} obtained {2}.",user.pbThis,oldTargetItemName)) if oldTargetItem
|
||||
@battle.pbDisplay(_INTL("{1} obtained {2}.",target.pbThis,oldUserItemName)) if oldUserItem
|
||||
user.pbHeldItemTriggerCheck
|
||||
target.pbHeldItemTriggerCheck
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# User recovers the last item it held and consumed. (Recycle)
|
||||
#===============================================================================
|
||||
class Battle::Move::RestoreUserConsumedItem < Battle::Move
|
||||
def canSnatch?; return true; end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if !user.recycleItem
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
item = user.recycleItem
|
||||
user.item = item
|
||||
user.setInitialItem(item) if @battle.wildBattle? && !user.initialItem
|
||||
user.setRecycleItem(nil)
|
||||
user.effects[PBEffects::PickupItem] = nil
|
||||
user.effects[PBEffects::PickupUse] = 0
|
||||
itemName = GameData::Item.get(item).name
|
||||
if itemName.starts_with_vowel?
|
||||
@battle.pbDisplay(_INTL("{1} found an {2}!",user.pbThis,itemName))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("{1} found a {2}!",user.pbThis,itemName))
|
||||
end
|
||||
user.pbHeldItemTriggerCheck
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Target drops its item. It regains the item at the end of the battle. (Knock Off)
|
||||
# If target has a losable item, damage is multiplied by 1.5.
|
||||
#===============================================================================
|
||||
class Battle::Move::RemoveTargetItem < Battle::Move
|
||||
def pbBaseDamage(baseDmg,user,target)
|
||||
if Settings::MECHANICS_GENERATION >= 6 &&
|
||||
target.item && !target.unlosableItem?(target.item)
|
||||
# NOTE: Damage is still boosted even if target has Sticky Hold or a
|
||||
# substitute.
|
||||
baseDmg = (baseDmg*1.5).round
|
||||
end
|
||||
return baseDmg
|
||||
end
|
||||
|
||||
def pbEffectAfterAllHits(user,target)
|
||||
return if user.wild? # Wild Pokémon can't knock off
|
||||
return if user.fainted?
|
||||
return if target.damageState.unaffected || target.damageState.substitute
|
||||
return if !target.item || target.unlosableItem?(target.item)
|
||||
return if target.hasActiveAbility?(:STICKYHOLD) && !@battle.moldBreaker
|
||||
itemName = target.itemName
|
||||
target.pbRemoveItem(false)
|
||||
@battle.pbDisplay(_INTL("{1} dropped its {2}!",target.pbThis,itemName))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Target's berry/Gem is destroyed. (Incinerate)
|
||||
#===============================================================================
|
||||
class Battle::Move::DestroyTargetBerryOrGem < Battle::Move
|
||||
def pbEffectWhenDealingDamage(user,target)
|
||||
return if target.damageState.substitute || target.damageState.berryWeakened
|
||||
return if !target.item || (!target.item.is_berry? &&
|
||||
!(Settings::MECHANICS_GENERATION >= 6 && target.item.is_gem?))
|
||||
target.pbRemoveItem
|
||||
@battle.pbDisplay(_INTL("{1}'s {2} was incinerated!",target.pbThis,target.itemName))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Negates the effect and usability of the target's held item for the rest of the
|
||||
# battle (even if it is switched out). Fails if the target doesn't have a held
|
||||
# item, the item is unlosable, the target has Sticky Hold, or the target is
|
||||
# behind a substitute. (Corrosive Gas)
|
||||
#===============================================================================
|
||||
class Battle::Move::CorrodeTargetItem < Battle::Move
|
||||
def canMagicCoat?; return true; end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
if !target.item || target.unlosableItem?(target.item) ||
|
||||
target.effects[PBEffects::Substitute] > 0
|
||||
@battle.pbDisplay(_INTL("{1} is unaffected!", target.pbThis)) if show_message
|
||||
return true
|
||||
end
|
||||
if target.hasActiveAbility?(:STICKYHOLD) && !@battle.moldBreaker
|
||||
if show_message
|
||||
@battle.pbShowAbilitySplash(target)
|
||||
if Battle::Scene::USE_ABILITY_SPLASH
|
||||
@battle.pbDisplay(_INTL("{1} is unaffected!", target.pbThis))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("{1} is unaffected because of its {2}!",
|
||||
target.pbThis(true), target.abilityName))
|
||||
end
|
||||
@battle.pbHideAbilitySplash(target)
|
||||
end
|
||||
return true
|
||||
end
|
||||
if @battle.corrosiveGas[target.index % 2][target.pokemonIndex]
|
||||
@battle.pbDisplay(_INTL("{1} is unaffected!", target.pbThis)) if show_message
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user, target)
|
||||
@battle.corrosiveGas[target.index % 2][target.pokemonIndex] = true
|
||||
@battle.pbDisplay(_INTL("{1} corroded {2}'s {3}!",
|
||||
user.pbThis, target.pbThis(true), target.itemName))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# For 5 rounds, the target cannnot use its held item, its held item has no
|
||||
# effect, and no items can be used on it. (Embargo)
|
||||
#===============================================================================
|
||||
class Battle::Move::StartTargetCannotUseItem < Battle::Move
|
||||
def canMagicCoat?; return true; end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
if target.effects[PBEffects::Embargo]>0
|
||||
@battle.pbDisplay(_INTL("But it failed!")) if show_message
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
target.effects[PBEffects::Embargo] = 5
|
||||
@battle.pbDisplay(_INTL("{1} can't use items anymore!",target.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# For 5 rounds, all held items cannot be used in any way and have no effect.
|
||||
# Held items can still change hands, but can't be thrown. (Magic Room)
|
||||
#===============================================================================
|
||||
class Battle::Move::StartNegateHeldItems < Battle::Move
|
||||
def pbEffectGeneral(user)
|
||||
if @battle.field.effects[PBEffects::MagicRoom]>0
|
||||
@battle.field.effects[PBEffects::MagicRoom] = 0
|
||||
@battle.pbDisplay(_INTL("The area returned to normal!"))
|
||||
else
|
||||
@battle.field.effects[PBEffects::MagicRoom] = 5
|
||||
@battle.pbDisplay(_INTL("It created a bizarre area in which Pokémon's held items lose their effects!"))
|
||||
end
|
||||
end
|
||||
|
||||
def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true)
|
||||
return if @battle.field.effects[PBEffects::MagicRoom]>0 # No animation
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# The user consumes its held berry and gains its effect. Also, increases the
|
||||
# user's Defense by 2 stages. The berry can be consumed even if Unnerve/Magic
|
||||
# Room apply. Fails if the user is not holding a berry. This move cannot be
|
||||
# chosen to be used if the user is not holding a berry. (Stuff Cheeks)
|
||||
#===============================================================================
|
||||
class Battle::Move::UserConsumeBerryRaiseDefense2 < Battle::Move::StatUpMove
|
||||
def initialize(battle, move)
|
||||
super
|
||||
@statUp = [:DEFENSE, 2]
|
||||
end
|
||||
|
||||
def pbCanChooseMove?(user, commandPhase, showMessages)
|
||||
item = user.item
|
||||
if !item || !item.is_berry? || !user.itemActive?
|
||||
if showMessages
|
||||
msg = _INTL("{1} can't use that move because it doesn't have a Berry!", user.pbThis)
|
||||
(commandPhase) ? @battle.pbDisplayPaused(msg) : @battle.pbDisplay(msg)
|
||||
end
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
def pbMoveFailed?(user, targets)
|
||||
# NOTE: Unnerve does not stop a Pokémon using this move.
|
||||
item = user.item
|
||||
if !item || !item.is_berry? || !user.itemActive?
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return super
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
super
|
||||
@battle.pbDisplay(_INTL("{1} ate its {2}!", user.pbThis, user.itemName))
|
||||
item = user.item
|
||||
user.pbConsumeItem(true, false) # Don't trigger Symbiosis yet
|
||||
user.pbHeldItemTriggerCheck(item, false)
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# All Pokémon (except semi-invulnerable ones) consume their held berries and
|
||||
# gain their effects. Berries can be consumed even if Unnerve/Magic Room apply.
|
||||
# Fails if no Pokémon have a held berry. If this move would trigger an ability
|
||||
# that negates the move, e.g. Lightning Rod, the bearer of that ability will
|
||||
# have their ability triggered regardless of whether they are holding a berry,
|
||||
# and they will not consume their berry. (Teatime)
|
||||
# TODO: This isn't quite right for the messages shown when a berry is consumed.
|
||||
#===============================================================================
|
||||
class Battle::Move::AllBattlersConsumeBerry < Battle::Move
|
||||
def pbMoveFailed?(user, targets)
|
||||
failed = true
|
||||
targets.each do |b|
|
||||
next if !b.item || !b.item.is_berry?
|
||||
next if b.semiInvulnerable?
|
||||
failed = false
|
||||
break
|
||||
end
|
||||
if failed
|
||||
@battle.pbDisplay(_INTL("But nothing happened!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbOnStartUse(user, targets)
|
||||
@battle.pbDisplay(_INTL("It's teatime! Everyone dug in to their Berries!"))
|
||||
end
|
||||
|
||||
def pbFailsAgainstTarget?(user, target, show_message)
|
||||
return true if !target.item || !target.item.is_berry? || target.semiInvulnerable?
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user, target)
|
||||
@battle.pbCommonAnimation("EatBerry", target)
|
||||
item = target.item
|
||||
target.pbConsumeItem(true, false) # Don't trigger Symbiosis yet
|
||||
target.pbHeldItemTriggerCheck(item, false)
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# User consumes target's berry and gains its effect. (Bug Bite, Pluck)
|
||||
#===============================================================================
|
||||
class Battle::Move::UserConsumeTargetBerry < Battle::Move
|
||||
def pbEffectAfterAllHits(user,target)
|
||||
return if user.fainted? || target.fainted?
|
||||
return if target.damageState.unaffected || target.damageState.substitute
|
||||
return if !target.item || !target.item.is_berry?
|
||||
return if target.hasActiveAbility?(:STICKYHOLD) && !@battle.moldBreaker
|
||||
item = target.item
|
||||
itemName = target.itemName
|
||||
target.pbRemoveItem
|
||||
@battle.pbDisplay(_INTL("{1} stole and ate its target's {2}!",user.pbThis,itemName))
|
||||
user.pbHeldItemTriggerCheck(item,false)
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# User flings its item at the target. Power/effect depend on the item. (Fling)
|
||||
#===============================================================================
|
||||
class Battle::Move::ThrowUserItemAtTarget < Battle::Move
|
||||
def initialize(battle,move)
|
||||
super
|
||||
# 80 => all Mega Stones
|
||||
# 10 => all Berries
|
||||
@flingPowers = {
|
||||
130 => [:IRONBALL
|
||||
],
|
||||
100 => [:HARDSTONE,:RAREBONE,
|
||||
# Fossils
|
||||
:ARMORFOSSIL,:CLAWFOSSIL,:COVERFOSSIL,:DOMEFOSSIL,:HELIXFOSSIL,
|
||||
:JAWFOSSIL,:OLDAMBER,:PLUMEFOSSIL,:ROOTFOSSIL,:SAILFOSSIL,
|
||||
:SKULLFOSSIL
|
||||
],
|
||||
90 => [:DEEPSEATOOTH,:GRIPCLAW,:THICKCLUB,
|
||||
# Plates
|
||||
:DRACOPLATE,:DREADPLATE,:EARTHPLATE,:FISTPLATE,:FLAMEPLATE,
|
||||
:ICICLEPLATE,:INSECTPLATE,:IRONPLATE,:MEADOWPLATE,:MINDPLATE,
|
||||
:PIXIEPLATE,:SKYPLATE,:SPLASHPLATE,:SPOOKYPLATE,:STONEPLATE,
|
||||
:TOXICPLATE,:ZAPPLATE
|
||||
],
|
||||
80 => [:ASSAULTVEST,:CHIPPEDPOT,:CRACKEDPOT,:DAWNSTONE,:DUSKSTONE,
|
||||
:ELECTIRIZER,:HEAVYDUTYBOOTS,:MAGMARIZER,:ODDKEYSTONE,:OVALSTONE,
|
||||
:PROTECTOR,:QUICKCLAW,:RAZORCLAW,:SACHET,:SAFETYGOGGLES,
|
||||
:SHINYSTONE,:STICKYBARB,:WEAKNESSPOLICY,:WHIPPEDDREAM
|
||||
],
|
||||
70 => [:DRAGONFANG,:POISONBARB,
|
||||
# EV-training items (Macho Brace is 60)
|
||||
:POWERANKLET,:POWERBAND,:POWERBELT,:POWERBRACER,:POWERLENS,
|
||||
:POWERWEIGHT,
|
||||
# Drives
|
||||
:BURNDRIVE,:CHILLDRIVE,:DOUSEDRIVE,:SHOCKDRIVE
|
||||
],
|
||||
60 => [:ADAMANTORB,:DAMPROCK,:GRISEOUSORB,:HEATROCK,:LEEK,:LUSTROUSORB,
|
||||
:MACHOBRACE,:ROCKYHELMET,:STICK,:TERRAINEXTENDER
|
||||
],
|
||||
50 => [:DUBIOUSDISC,:SHARPBEAK,
|
||||
# Memories
|
||||
:BUGMEMORY,:DARKMEMORY,:DRAGONMEMORY,:ELECTRICMEMORY,:FAIRYMEMORY,
|
||||
:FIGHTINGMEMORY,:FIREMEMORY,:FLYINGMEMORY,:GHOSTMEMORY,
|
||||
:GRASSMEMORY,:GROUNDMEMORY,:ICEMEMORY,:POISONMEMORY,
|
||||
:PSYCHICMEMORY,:ROCKMEMORY,:STEELMEMORY,:WATERMEMORY
|
||||
],
|
||||
40 => [:EVIOLITE,:ICYROCK,:LUCKYPUNCH
|
||||
],
|
||||
30 => [:ABSORBBULB,:ADRENALINEORB,:AMULETCOIN,:BINDINGBAND,:BLACKBELT,
|
||||
:BLACKGLASSES,:BLACKSLUDGE,:BOTTLECAP,:CELLBATTERY,:CHARCOAL,
|
||||
:CLEANSETAG,:DEEPSEASCALE,:DRAGONSCALE,:EJECTBUTTON,:ESCAPEROPE,
|
||||
:EXPSHARE,:FLAMEORB,:FLOATSTONE,:FLUFFYTAIL,:GOLDBOTTLECAP,
|
||||
:HEARTSCALE,:HONEY,:KINGSROCK,:LIFEORB,:LIGHTBALL,:LIGHTCLAY,
|
||||
:LUCKYEGG,:LUMINOUSMOSS,:MAGNET,:METALCOAT,:METRONOME,
|
||||
:MIRACLESEED,:MYSTICWATER,:NEVERMELTICE,:PASSORB,:POKEDOLL,
|
||||
:POKETOY,:PRISMSCALE,:PROTECTIVEPADS,:RAZORFANG,:SACREDASH,
|
||||
:SCOPELENS,:SHELLBELL,:SHOALSALT,:SHOALSHELL,:SMOKEBALL,:SNOWBALL,
|
||||
:SOULDEW,:SPELLTAG,:TOXICORB,:TWISTEDSPOON,:UPGRADE,
|
||||
# Healing items
|
||||
:ANTIDOTE,:AWAKENING,:BERRYJUICE,:BIGMALASADA,:BLUEFLUTE,
|
||||
:BURNHEAL,:CASTELIACONE,:ELIXIR,:ENERGYPOWDER,:ENERGYROOT,:ETHER,
|
||||
:FRESHWATER,:FULLHEAL,:FULLRESTORE,:HEALPOWDER,:HYPERPOTION,
|
||||
:ICEHEAL,:LAVACOOKIE,:LEMONADE,:LUMIOSEGALETTE,:MAXELIXIR,
|
||||
:MAXETHER,:MAXHONEY,:MAXPOTION,:MAXREVIVE,:MOOMOOMILK,:OLDGATEAU,
|
||||
:PARALYZEHEAL,:PARLYZHEAL,:PEWTERCRUNCHIES,:POTION,:RAGECANDYBAR,
|
||||
:REDFLUTE,:REVIVALHERB,:REVIVE,:SHALOURSABLE,:SODAPOP,
|
||||
:SUPERPOTION,:SWEETHEART,:YELLOWFLUTE,
|
||||
# Battle items
|
||||
:XACCURACY,:XACCURACY2,:XACCURACY3,:XACCURACY6,
|
||||
:XATTACK,:XATTACK2,:XATTACK3,:XATTACK6,
|
||||
:XDEFEND,:XDEFEND2,:XDEFEND3,:XDEFEND6,
|
||||
:XDEFENSE,:XDEFENSE2,:XDEFENSE3,:XDEFENSE6,
|
||||
:XSPATK,:XSPATK2,:XSPATK3,:XSPATK6,
|
||||
:XSPECIAL,:XSPECIAL2,:XSPECIAL3,:XSPECIAL6,
|
||||
:XSPDEF,:XSPDEF2,:XSPDEF3,:XSPDEF6,
|
||||
:XSPEED,:XSPEED2,:XSPEED3,:XSPEED6,
|
||||
:DIREHIT,:DIREHIT2,:DIREHIT3,
|
||||
:ABILITYURGE,:GUARDSPEC,:ITEMDROP,:ITEMURGE,:RESETURGE,
|
||||
:MAXMUSHROOMS,
|
||||
# Vitamins
|
||||
:CALCIUM,:CARBOS,:HPUP,:IRON,:PPUP,:PPMAX,:PROTEIN,:ZINC,
|
||||
:RARECANDY,
|
||||
# Most evolution stones (see also 80)
|
||||
:EVERSTONE,:FIRESTONE,:ICESTONE,:LEAFSTONE,:MOONSTONE,:SUNSTONE,
|
||||
:THUNDERSTONE,:WATERSTONE,:SWEETAPPLE,:TARTAPPLE, :GALARICACUFF,
|
||||
:GALARICAWREATH,
|
||||
# Repels
|
||||
:MAXREPEL,:REPEL,:SUPERREPEL,
|
||||
# Mulches
|
||||
:AMAZEMULCH,:BOOSTMULCH,:DAMPMULCH,:GOOEYMULCH,:GROWTHMULCH,
|
||||
:RICHMULCH,:STABLEMULCH,:SURPRISEMULCH,
|
||||
# Shards
|
||||
:BLUESHARD,:GREENSHARD,:REDSHARD,:YELLOWSHARD,
|
||||
# Valuables
|
||||
:BALMMUSHROOM,:BIGMUSHROOM,:BIGNUGGET,:BIGPEARL,:COMETSHARD,
|
||||
:NUGGET,:PEARL,:PEARLSTRING,:RELICBAND,:RELICCOPPER,:RELICCROWN,
|
||||
:RELICGOLD,:RELICSILVER,:RELICSTATUE,:RELICVASE,:STARDUST,
|
||||
:STARPIECE,:STRANGESOUVENIR,:TINYMUSHROOM,
|
||||
# Exp Candies
|
||||
:EXPCANDYXS, :EXPCANDYS, :EXPCANDYM, :EXPCANDYL, :EXPCANDYXL
|
||||
],
|
||||
20 => [# Feathers
|
||||
:CLEVERFEATHER,:GENIUSFEATHER,:HEALTHFEATHER,:MUSCLEFEATHER,
|
||||
:PRETTYFEATHER,:RESISTFEATHER,:SWIFTFEATHER,
|
||||
:CLEVERWING,:GENIUSWING,:HEALTHWING,:MUSCLEWING,:PRETTYWING,
|
||||
:RESISTWING,:SWIFTWING
|
||||
],
|
||||
10 => [:AIRBALLOON,:BIGROOT,:BRIGHTPOWDER,:CHOICEBAND,:CHOICESCARF,
|
||||
:CHOICESPECS,:DESTINYKNOT,:DISCOUNTCOUPON,:EXPERTBELT,:FOCUSBAND,
|
||||
:FOCUSSASH,:LAGGINGTAIL,:LEFTOVERS,:MENTALHERB,:METALPOWDER,
|
||||
:MUSCLEBAND,:POWERHERB,:QUICKPOWDER,:REAPERCLOTH,:REDCARD,
|
||||
:RINGTARGET,:SHEDSHELL,:SILKSCARF,:SILVERPOWDER,:SMOOTHROCK,
|
||||
:SOFTSAND,:SOOTHEBELL,:WHITEHERB,:WIDELENS,:WISEGLASSES,:ZOOMLENS,
|
||||
# Terrain seeds
|
||||
:ELECTRICSEED,:GRASSYSEED,:MISTYSEED,:PSYCHICSEED,
|
||||
# Nectar
|
||||
:PINKNECTAR,:PURPLENECTAR,:REDNECTAR,:YELLOWNECTAR,
|
||||
# Incenses
|
||||
:FULLINCENSE,:LAXINCENSE,:LUCKINCENSE,:ODDINCENSE,:PUREINCENSE,
|
||||
:ROCKINCENSE,:ROSEINCENSE,:SEAINCENSE,:WAVEINCENSE,
|
||||
# Scarves
|
||||
:BLUESCARF,:GREENSCARF,:PINKSCARF,:REDSCARF,:YELLOWSCARF,
|
||||
# Mints
|
||||
:LONELYMINT, :ADAMANTMINT, :NAUGHTYMINT, :BRAVEMINT, :BOLDMINT,
|
||||
:IMPISHMINT, :LAXMINT, :RELAXEDMINT, :MODESTMINT, :MILDMINT,
|
||||
:RASHMINT, :QUIETMINT, :CALMMINT, :GENTLEMINT, :CAREFULMINT,
|
||||
:SASSYMINT, :TIMIDMINT, :HASTYMINT, :JOLLYMINT, :NAIVEMINT,
|
||||
:SERIOUSMINT,
|
||||
# Sweets
|
||||
:STRAWBERRYSWEET, :LOVESWEET, :BERRYSWEET, :CLOVERSWEET,
|
||||
:FLOWERSWEET, :STARSWEET, :RIBBONSWEET
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
def pbCheckFlingSuccess(user)
|
||||
@willFail = false
|
||||
@willFail = true if !user.item || !user.itemActive? || user.unlosableItem?(user.item)
|
||||
return if @willFail
|
||||
@willFail = true if user.item.is_berry? && !user.canConsumeBerry?
|
||||
return if @willFail
|
||||
return if user.item.is_mega_stone? || user.item.is_TR?
|
||||
flingableItem = false
|
||||
@flingPowers.each do |_power, items|
|
||||
next if !items.include?(user.item_id)
|
||||
flingableItem = true
|
||||
break
|
||||
end
|
||||
@willFail = true if !flingableItem
|
||||
end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if @willFail
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbDisplayUseMessage(user)
|
||||
super
|
||||
pbCheckFlingSuccess(user)
|
||||
if !@willFail
|
||||
@battle.pbDisplay(_INTL("{1} flung its {2}!",user.pbThis,user.itemName))
|
||||
end
|
||||
end
|
||||
|
||||
def pbNumHits(user,targets); return 1; end
|
||||
|
||||
def pbBaseDamage(baseDmg,user,target)
|
||||
return 0 if !user.item
|
||||
return 10 if user.item.is_berry?
|
||||
return 80 if user.item.is_mega_stone?
|
||||
if user.item.is_TR?
|
||||
ret = GameData::Move.get(user.item.move).base_damage
|
||||
ret = 10 if ret < 10
|
||||
return ret
|
||||
end
|
||||
@flingPowers.each do |power,items|
|
||||
return power if items.include?(user.item_id)
|
||||
end
|
||||
return 10
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if target.damageState.substitute
|
||||
return if target.hasActiveAbility?(:SHIELDDUST) && !@battle.moldBreaker
|
||||
case user.item_id
|
||||
when :POISONBARB
|
||||
target.pbPoison(user) if target.pbCanPoison?(user,false,self)
|
||||
when :TOXICORB
|
||||
target.pbPoison(user,nil,true) if target.pbCanPoison?(user,false,self)
|
||||
when :FLAMEORB
|
||||
target.pbBurn(user) if target.pbCanBurn?(user,false,self)
|
||||
when :LIGHTBALL
|
||||
target.pbParalyze(user) if target.pbCanParalyze?(user,false,self)
|
||||
when :KINGSROCK, :RAZORFANG
|
||||
target.pbFlinch(user)
|
||||
else
|
||||
target.pbHeldItemTriggerCheck(user.item,true)
|
||||
end
|
||||
end
|
||||
|
||||
def pbEndOfMoveUsageEffect(user,targets,numHits,switchedBattlers)
|
||||
# NOTE: The item is consumed even if this move was Protected against or it
|
||||
# missed. The item is not consumed if the target was switched out by
|
||||
# an effect like a target's Red Card.
|
||||
# NOTE: There is no item consumption animation.
|
||||
user.pbConsumeItem(true,true,false) if user.item
|
||||
end
|
||||
end
|
||||
1311
Data/Scripts/011_Battle/003_Move/012_MoveEffects_ChangeMoveEffect.rb
Normal file
1311
Data/Scripts/011_Battle/003_Move/012_MoveEffects_ChangeMoveEffect.rb
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,925 @@
|
||||
#===============================================================================
|
||||
# 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, as long as
|
||||
# the user remains active. (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
|
||||
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 == :Grass && user.affectedByTerrain?
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Decreases the PP of the last attack used by the target by 3 (or as much as
|
||||
# possible). (Eerie Spell)
|
||||
#===============================================================================
|
||||
class Battle::Move::LowerPPOfTargetLastMoveBy3 < Battle::Move
|
||||
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 = [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. (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
|
||||
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
|
||||
@battle.pbDisplay(_INTL("The effects of {1} prevent {2} from using certain moves!",
|
||||
@name,target.pbThis(true))) if target.effects[PBEffects::ThroatChop]==0
|
||||
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
|
||||
Reference in New Issue
Block a user