def pbUseMove(choice,specialusage=false)
# TODO: lastMoveUsed is not to be updated on nested calls
# Note: user.lastMoveUsedType IS to be updated on nested calls; is used for Conversion 2
turneffects=[]
turneffects[PBEffects::SpecialUsage]=specialusage
turneffects[PBEffects::SkipAccuracyCheck]=(specialusage && choice[2][email protected])
turneffects[PBEffects::PassedTrying]=false
turneffects[PBEffects::TotalDamage]=0
# Start using the move
pbBeginTurn(choice)
# Force the use of certain moves if they're already being used
if @effects[PBEffects::TwoTurnAttack]>0 ||
@effects[PBEffects::HyperBeam]>0 ||
@effects[PBEffects::Outrage]>0 ||
@effects[PBEffects::Rollout]>0 ||
@effects[PBEffects::Uproar]>0 ||
@effects[PBEffects::Bide]>0
choice[2]=PokeBattle_Move.pbFromPBMove(@battle,PBMove.new(@currentMove))
turneffects[PBEffects::SpecialUsage]=true
PBDebug.log("Continuing multi-turn move #{choice[2].name}")
elsif @effects[PBEffects::Encore]>0 && choice[1]>=0
if @battle.pbCanShowCommands?(@index) &&
@battle.pbCanChooseMove?(@index,@effects[PBEffects::EncoreIndex],false)
if choice[1]!=@effects[PBEffects::EncoreIndex] # Was Encored mid-round
choice[1]=@effects[PBEffects::EncoreIndex]
choice[2]=@moves[@effects[PBEffects::EncoreIndex]]
choice[3]=-1 # No target chosen
end
PBDebug.log("Using Encored move #{choice[2].name}")
end
end
thismove=choice[2]
return if !thismove || thismove.id==0 # if move was not chosen
if !turneffects[PBEffects::SpecialUsage]
# TODO: Quick Claw message
end
# Stance Change
if hasWorkingAbility(:STANCECHANGE) && isConst?(species,PBSpecies,:AEGISLASH) &&
!@effects[PBEffects::Transform]
if thismove.pbIsDamaging? && self.form!=1
self.form=1
pbUpdate(true)
@battle.scene.pbChangePokemon(self,@pokemon)
@battle.pbDisplay(_INTL("{1} changed to Blade Forme!",pbThis))
PBDebug.log("[Form changed] #{pbThis} changed to Blade Forme")
elsif isConst?(thismove.id,PBMoves,:KINGSSHIELD) && self.form!=0
self.form=0
pbUpdate(true)
@battle.scene.pbChangePokemon(self,@pokemon)
@battle.pbDisplay(_INTL("{1} changed to Shield Forme!",pbThis))
PBDebug.log("[Form changed] #{pbThis} changed to Shield Forme")
end
end
# Record that user has used a move this round (ot at least tried to)
[email protected]
# Try to use the move
if !pbTryUseMove(choice,thismove,turneffects)
self.lastMoveUsed=-1
self.lastMoveUsedType=-1
if !turneffects[PBEffects::SpecialUsage]
self.lastMoveUsedSketch=-1 if self.effects[PBEffects::TwoTurnAttack]==0
self.lastRegularMoveUsed=-1
end
pbCancelMoves
@battle.pbGainEXP
pbEndTurn(choice)
@battle.pbJudge # @battle.pbSwitch
return
end
thismove=choice[2] # Disobedience may have changed the move to be used
return if !thismove || thismove.id==0 # if move was not chosen
if !turneffects[PBEffects::SpecialUsage]
if !pbReducePP(thismove)
@battle.pbDisplay(_INTL("{1} used\r\n{2}!",pbThis,thismove.name))
@battle.pbDisplay(_INTL("But there was no PP left for the move!"))
self.lastMoveUsed=-1
self.lastMoveUsedType=-1
self.lastMoveUsedSketch=-1 if self.effects[PBEffects::TwoTurnAttack]==0
self.lastRegularMoveUsed=-1
pbEndTurn(choice)
@battle.pbJudge # @battle.pbSwitch
PBDebug.log("[Move failed] #{thismove.name} has no PP left")
return
end
end
# Remember that user chose a two-turn move
if thismove.pbTwoTurnAttack(self)
# Beginning use of two-turn attack
@effects[PBEffects::TwoTurnAttack]=thismove.id
@currentMove=thismove.id
else
@effects[PBEffects::TwoTurnAttack]=0 # Cancel use of two-turn attack
end
# Charge up Metronome item
if self.lastMoveUsed==thismove.id
self.effects[PBEffects::Metronome]+=1
else
self.effects[PBEffects::Metronome]=0
end
# "X used Y!" message
case thismove.pbDisplayUseMessage(self)
when 2 # Continuing Bide
return
when 1 # Starting Bide
self.lastMoveUsed=thismove.id
self.lastMoveUsedType=thismove.pbType(thismove.type,self,nil)
if !turneffects[PBEffects::SpecialUsage]
self.lastMoveUsedSketch=thismove.id if self.effects[PBEffects::TwoTurnAttack]==0
self.lastRegularMoveUsed=thismove.id
end
@battle.lastMoveUsed=thismove.id
@battle.lastMoveUser=self.index
@battle.successStates[self.index].useState=2
@battle.successStates[self.index].typemod=8
return
when -1 # Was hurt while readying Focus Punch, fails use
self.lastMoveUsed=thismove.id
self.lastMoveUsedType=thismove.pbType(thismove.type,self,nil)
if !turneffects[PBEffects::SpecialUsage]
self.lastMoveUsedSketch=thismove.id if self.effects[PBEffects::TwoTurnAttack]==0
self.lastRegularMoveUsed=thismove.id
end
@battle.lastMoveUsed=thismove.id
@battle.lastMoveUser=self.index
@battle.successStates[self.index].useState=2 # somehow treated as a success
@battle.successStates[self.index].typemod=8
PBDebug.log("[Move failed] #{pbThis} was hurt while readying Focus Punch")
return
end
# Find the user and target(s)
targets=[]
user=pbFindUser(choice,targets)
# Battle Arena only - assume failure
@battle.successStates[user.index].useState=1
@battle.successStates[user.index].typemod=8
# Check whether Selfdestruct works
if !thismove.pbOnStartUse(user) # Selfdestruct, Natural Gift, Beat Up can return false here
PBDebug.log(sprintf("[Move failed] Failed pbOnStartUse (function code %02X)",thismove.function))
user.lastMoveUsed=thismove.id
user.lastMoveUsedType=thismove.pbType(thismove.type,user,nil)
if !turneffects[PBEffects::SpecialUsage]
user.lastMoveUsedSketch=thismove.id if user.effects[PBEffects::TwoTurnAttack]==0
user.lastRegularMoveUsed=thismove.id
end
@battle.lastMoveUsed=thismove.id
@battle.lastMoveUser=user.index
return
end
# Primordial Sea, Desolate Land
if thismove.pbIsDamaging?
case @battle.pbWeather
when PBWeather::HEAVYRAIN
if isConst?(thismove.pbType(thismove.type,user,nil),PBTypes,:FIRE)
PBDebug.log("[Move failed] Primordial Sea's rain cancelled the Fire-type #{thismove.name}")
@battle.pbDisplay(_INTL("The Fire-type attack fizzled out in the heavy rain!"))
user.lastMoveUsed=thismove.id
user.lastMoveUsedType=thismove.pbType(thismove.type,user,nil)
if !turneffects[PBEffects::SpecialUsage]
user.lastMoveUsedSketch=thismove.id if user.effects[PBEffects::TwoTurnAttack]==0
user.lastRegularMoveUsed=thismove.id
end
@battle.lastMoveUsed=thismove.id
@battle.lastMoveUser=user.index
return
end
when PBWeather::HARSHSUN
if isConst?(thismove.pbType(thismove.type,user,nil),PBTypes,:WATER)
PBDebug.log("[Move failed] Desolate Land's sun cancelled the Water-type #{thismove.name}")
@battle.pbDisplay(_INTL("The Water-type attack evaporated in the harsh sunlight!"))
user.lastMoveUsed=thismove.id
user.lastMoveUsedType=thismove.pbType(thismove.type,user,nil)
if !turneffects[PBEffects::SpecialUsage]
user.lastMoveUsedSketch=thismove.id if user.effects[PBEffects::TwoTurnAttack]==0
user.lastRegularMoveUsed=thismove.id
end
@battle.lastMoveUsed=thismove.id
@battle.lastMoveUser=user.index
return
end
end
end
# Powder
if user.effects[PBEffects::Powder] && isConst?(thismove.pbType(thismove.type,user,nil),PBTypes,:FIRE)
PBDebug.log("[Lingering effect triggered] #{pbThis}'s Powder cancelled the Fire move")
@battle.pbCommonAnimation("Powder",user,nil)
@battle.pbDisplay(_INTL("When the flame touched the powder on the Pokémon, it exploded!"))
user.pbReduceHP(1+(user.totalhp/4).floor) if !user.hasWorkingAbility(:MAGICGUARD)
user.lastMoveUsed=thismove.id
user.lastMoveUsedType=thismove.pbType(thismove.type,user,nil)
if !turneffects[PBEffects::SpecialUsage]
user.lastMoveUsedSketch=thismove.id if user.effects[PBEffects::TwoTurnAttack]==0
user.lastRegularMoveUsed=thismove.id
end
@battle.lastMoveUsed=thismove.id
@battle.lastMoveUser=user.index
user.pbFaint if user.fainted?
pbEndTurn(choice)
return
end
# Protean
if user.hasWorkingAbility(:PROTEAN) &&
thismove.function!=0xAE && # Mirror Move
thismove.function!=0xAF && # Copycat
thismove.function!=0xB0 && # Me First
thismove.function!=0xB3 && # Nature Power
thismove.function!=0xB4 && # Sleep Talk
thismove.function!=0xB5 && # Assist
thismove.function!=0xB6 # Metronome
movetype=thismove.pbType(thismove.type,user,nil)
if !user.pbHasType?(movetype)
typename=PBTypes.getName(movetype)
PBDebug.log("[Ability triggered] #{pbThis}'s Protean made it #{typename}-type")
user.type1=movetype
user.type2=movetype
user.effects[PBEffects::Type3]=-1
@battle.pbDisplay(_INTL("{1} transformed into the {2} type!",user.pbThis,typename))
end
end
# Try to use move against user if there aren't any targets
if targets.length==0
user=pbChangeUser(thismove,user)
if thismove.target==PBTargets::SingleNonUser ||
thismove.target==PBTargets::RandomOpposing ||
thismove.target==PBTargets::AllOpposing ||
thismove.target==PBTargets::AllNonUsers ||
thismove.target==PBTargets::Partner ||
thismove.target==PBTargets::UserOrPartner ||
thismove.target==PBTargets::SingleOpposing ||
thismove.target==PBTargets::OppositeOpposing
@battle.pbDisplay(_INTL("But there was no target..."))
else
PBDebug.logonerr{
thismove.pbEffect(user,nil)
}
end
else
# We have targets
showanimation=true
alltargets=[]
for i in 0...targets.length
alltargets.push(targets[i].index) if !targets.include?(targets[i].index)
end
# For each target in turn
i=0; loop do break if i>=targets.length
# Get next target
userandtarget=[user,targets[i]]
success=pbChangeTarget(thismove,userandtarget,targets)
user=userandtarget[0]
target=userandtarget[1]
if i==0 && thismove.target==PBTargets::AllOpposing
# Add target's partner to list of targets
pbAddTarget(targets,target.pbPartner)
end
# If couldn't get the next target
if !success
i+=1
next
end
# Get the number of hits
numhits=thismove.pbNumHits(user)
# Reset damage state, set Focus Band/Focus Sash to available
target.damagestate.reset
# Use move against the current target
pbProcessMoveAgainstTarget(thismove,user,target,numhits,turneffects,false,alltargets,showanimation)
showanimation=false
i+=1
end
end
# Pokémon switching caused by Roar, Whirlwind, Circle Throw, Dragon Tail, Red Card
if !user.fainted?
switched=[]
for i in 0...4
if @battle.battlers[i].effects[PBEffects::Roar]
@battle.battlers[i].effects[PBEffects::Roar]=false
@battle.battlers[i].effects[PBEffects::Uturn]=false
next if @battle.battlers[i].fainted?
next if [email protected]?(i,-1,false)
choices=[]
[email protected](i)
for j in 0...party.length
choices.push(j) if @battle.pbCanSwitchLax?(i,j,false)
end
if choices.length>0
newpoke=choices[@battle.pbRandom(choices.length)]
newpokename=newpoke
if isConst?(party[newpoke].ability,PBAbilities,:ILLUSION)
newpokename=pbGetLastPokeInTeam(i)
end
switched.push(i)
@battle.battlers[i].pbResetUsualForms
@battle.pbRecallAndReplace(i,newpoke,newpokename,false,user.hasMoldBreaker ||
thismove.doesBypassIgnorableAbilities?)
@battle.pbDisplay(_INTL("{1} was dragged out!",@battle.battlers[i].pbThis))
@battle.choices[i]=[0,0,nil,-1] # Replacement Pokémon does nothing this round
end
end
end
for i in @battle.pbPriority
next if !switched.include?(i.index)
i.pbAbilitiesOnSwitchIn(true)
end
end
# Pokémon switching caused by U-Turn, Volt Switch, Eject Button
switched=[]
for i in 0...4
if @battle.battlers[i].effects[PBEffects::Uturn]
@battle.battlers[i].effects[PBEffects::Uturn]=false
@battle.battlers[i].effects[PBEffects::Roar]=false
if [email protected][i].fainted? && @battle.pbCanChooseNonActive?(i) &&
[email protected]?(@battle.pbOpposingParty(i))
# TODO: Pursuit should go here, and negate this effect if it KO's attacker
@battle.pbDisplay(_INTL("{1} went back to {2}!",@battle.battlers[i].pbThis,@battle.pbGetOwner(i).name))
newpoke=0
[email protected](i,true,false)
newpokename=newpoke
if isConst?(@battle.pbParty(i)[newpoke].ability,PBAbilities,:ILLUSION)
newpokename=pbGetLastPokeInTeam(i)
end
switched.push(i)
@battle.battlers[i].pbResetForm
@battle.pbRecallAndReplace(i,newpoke,newpokename,@battle.battlers[i].effects[PBEffects::BatonPass])
@battle.choices[i]=[0,0,nil,-1] # Replacement Pokémon does nothing this round
end
end
end
for i in @battle.pbPriority
next if !switched.include?(i.index)
i.pbAbilitiesOnSwitchIn(true)
end
# Baton Pass
if user.effects[PBEffects::BatonPass]
user.effects[PBEffects::BatonPass]=false
if !user.fainted? && @battle.pbCanChooseNonActive?(user.index) &&
[email protected]?(@battle.pbParty(user.index))
newpoke=0
[email protected](user.index,true,false)
newpokename=newpoke
if isConst?(@battle.pbParty(user.index)[newpoke].ability,PBAbilities,:ILLUSION)
newpokename=pbGetLastPokeInTeam(user.index)
end
user.pbResetForm
@battle.pbRecallAndReplace(user.index,newpoke,newpokename,true)
@battle.choices[user.index]=[0,0,nil,-1] # Replacement Pokémon does nothing this round
user.pbAbilitiesOnSwitchIn(true)
end
end
# Record move as having been used
user.lastMoveUsed=thismove.id
user.lastMoveUsedType=thismove.pbType(thismove.type,user,nil)
if !turneffects[PBEffects::SpecialUsage]
user.lastMoveUsedSketch=thismove.id if user.effects[PBEffects::TwoTurnAttack]==0
user.lastRegularMoveUsed=thismove.id
user.movesUsed.push(thismove.id) if !user.movesUsed.include?(thismove.id) # For Last Resort
end
@battle.lastMoveUsed=thismove.id
@battle.lastMoveUser=user.index
# Gain Exp
@battle.pbGainEXP
# Battle Arena only - update skills
for i in 0...4
@battle.successStates[i].updateSkill
end
# End of move usage
pbEndTurn(choice)
@battle.pbJudge # @battle.pbSwitch
return
end