Pikalex04
The Project Hyper creator (Discord: Pikalex04#3285
- 36
- Posts
- 6
- Years
- Italy
- Seen Oct 12, 2019
Hello, I'm getting this error, and I can't fix it. It's a syntax error. So, when I start my game, it gives me a syntax error on "PokeBattle_Battler", on the last line. I thought that I wrote two ends or two ifs etc.. After checking the script three times, I fixed all the problems. But my game still gives me that error. In the "panic" I did a little thing: I wrote a second end at the last line and the game started. I guess that this means I forgot an end. Is this right? Well, I thought that I was right, and I've searched other five times for the missing end, but nothing. Since I'm pretty sure that leaving the second end can cause problems to the events in game (in this case the work of the abilities), but I'm not that sure, that's why I'm asking for some help, what should I do? Leave the end or search another time for some errors?
Anyway, this is the script, if someone hasn't anything to do and wants to search for errors.
Btw, anyone that can tell me how to put Ruby codes in PokéCommunity posts?
Anyway, this is the script, if someone hasn't anything to do and wants to search for errors.
Spoiler:
Code:
<$zygardeform=-1 # Records, eventually, to what form should Zygarde return after battle
class PokeBattle_Battler
attr_reader :battle
attr_reader :pokemon
attr_reader :name
attr_reader :index
attr_accessor :pokemonIndex
attr_reader :totalhp
attr_reader :fainted
attr_accessor :lastAttacker
attr_accessor :turncount
attr_accessor :effects
attr_accessor :species
attr_accessor :type1
attr_accessor :type2
attr_accessor :ability
attr_accessor :gender
attr_accessor :attack
attr_writer :defense
attr_accessor :spatk
attr_writer :spdef
attr_accessor :speed
attr_accessor :stages
attr_accessor :iv
attr_accessor :moves
attr_accessor :participants
attr_accessor :tookDamage
attr_accessor :lastHPLost
attr_accessor :lastMoveUsed
attr_accessor :lastMoveUsedType
attr_accessor :lastMoveUsedSketch
attr_accessor :lastRegularMoveUsed
attr_accessor :lastRoundMoved
attr_accessor :movesUsed
attr_accessor :currentMove
attr_accessor :damagestate
attr_accessor :captured
def inHyperMode?; return false; end
def isShadow?; return false; end
################################################################################
# Complex accessors
################################################################################
def defense
return @battle.field.effects[PBEffects::WonderRoom]>0 ? @spdef : @defense
end
def spdef
return @battle.field.effects[PBEffects::WonderRoom]>0 ? @defense : @spdef
end
def nature
return (@pokemon) ? @pokemon.nature : 0
end
def happiness
return (@pokemon) ? @pokemon.happiness : 0
end
def pokerusStage
return (@pokemon) ? @pokemon.pokerusStage : 0
end
attr_reader :form
def form=(value)
@form=value
@pokemon.form=value if @pokemon
end
def hasMega?
return false if @effects[PBEffects::Transform]
if @pokemon
return (@pokemon.hasMegaForm? rescue false)
end
return false
end
def isMega?
if @pokemon
return (@pokemon.isMega? rescue false)
end
return false
end
def hasPrimal?
return false if @effects[PBEffects::Transform]
if @pokemon
return (@pokemon.hasPrimalForm? rescue false)
end
return false
end
def isPrimal?
if @pokemon
return (@pokemon.isPrimal? rescue false)
end
return false
end
attr_reader :level
def level=(value)
@level=value
@pokemon.level=(value) if @pokemon
end
attr_reader :status
def status=(value)
if @status==PBStatuses::SLEEP && value==0
@effects[PBEffects::Truant]=false
end
@status=value
@pokemon.status=value if @pokemon
if value!=PBStatuses::POISON
@effects[PBEffects::Toxic]=0
end
if value!=PBStatuses::POISON && value!=PBStatuses::SLEEP
@statusCount=0
@pokemon.statusCount=0 if @pokemon
end
end
attr_reader :statusCount
def statusCount=(value)
@statusCount=value
@pokemon.statusCount=value if @pokemon
end
attr_reader :hp
def hp=(value)
@hp=value.to_i
@pokemon.hp=value.to_i if @pokemon
end
attr_reader :item
def item=(value)
@item=value
@pokemon.setItem(value) if @pokemon
end
def weight(attacker=nil)
w=(@pokemon) ? @pokemon.weight : 500
if !attacker || !attacker.hasMoldBreaker
w*=2 if self.hasWorkingAbility(:HEAVYMETAL)
w/=2 if self.hasWorkingAbility(:LIGHTMETAL)
end
w/=2 if self.hasWorkingItem(:FLOATSTONE)
w+=@effects[PBEffects::WeightChange]
w=w.floor
w=1 if w<1
return w
end
def name
if @effects[PBEffects::Illusion]
return @effects[PBEffects::Illusion].name
end
return @name
end
def displayGender
if @effects[PBEffects::Illusion]
return @effects[PBEffects::Illusion].gender
end
return self.gender
end
def isShiny?
if @effects[PBEffects::Illusion]
return @effects[PBEffects::Illusion].isShiny?
end
return @pokemon.isShiny? if @pokemon
return false
end
def owned
return (@pokemon) ? $Trainer.owned[@pokemon.species] && [email protected] : false
end
################################################################################
# Creating a battler
################################################################################
def initialize(btl,index)
@battle = btl
@index = index
@hp = 0
@totalhp = 0
@fainted = true
@captured = false
@stages = []
@effects = []
@damagestate = PokeBattle_DamageState.new
pbInitBlank
pbInitEffects(false)
pbInitPermanentEffects
end
def pbInitPokemon(pkmn,pkmnIndex)
if pkmn.egg?
raise _INTL("An egg can't be an active Pokémon")
end
@name = pkmn.name
@species = pkmn.species
@level = pkmn.level
@hp = pkmn.hp
@totalhp = pkmn.totalhp
@gender = pkmn.gender
@ability = pkmn.ability
@item = pkmn.item
@type1 = pkmn.type1
@type2 = pkmn.type2
@form = pkmn.form
@attack = pkmn.attack
@defense = pkmn.defense
@speed = pkmn.speed
@spatk = pkmn.spatk
@spdef = pkmn.spdef
@status = pkmn.status
@statusCount = pkmn.statusCount
@pokemon = pkmn
@pokemonIndex = pkmnIndex
@participants = [] # Participants will earn Exp. Points if this battler is defeated
@moves = [
PokeBattle_Move.pbFromPBMove(@battle,pkmn.moves[0]),
PokeBattle_Move.pbFromPBMove(@battle,pkmn.moves[1]),
PokeBattle_Move.pbFromPBMove(@battle,pkmn.moves[2]),
PokeBattle_Move.pbFromPBMove(@battle,pkmn.moves[3])
]
@iv = []
@iv[0] = pkmn.iv[0]
@iv[1] = pkmn.iv[1]
@iv[2] = pkmn.iv[2]
@iv[3] = pkmn.iv[3]
@iv[4] = pkmn.iv[4]
@iv[5] = pkmn.iv[5]
end
def pbInitDummyPokemon(pkmn,pkmnIndex)
if pkmn.egg?
raise _INTL("An egg can't be an active Pokémon")
end
@name = pkmn.name
@species = pkmn.species
@level = pkmn.level
@hp = pkmn.hp
@totalhp = pkmn.totalhp
@gender = pkmn.gender
@type1 = pkmn.type1
@type2 = pkmn.type2
@form = pkmn.form
@attack = pkmn.attack
@defense = pkmn.defense
@speed = pkmn.speed
@spatk = pkmn.spatk
@spdef = pkmn.spdef
@status = pkmn.status
@statusCount = pkmn.statusCount
@pokemon = pkmn
@pokemonIndex = pkmnIndex
@participants = []
@iv = []
@iv[0] = pkmn.iv[0]
@iv[1] = pkmn.iv[1]
@iv[2] = pkmn.iv[2]
@iv[3] = pkmn.iv[3]
@iv[4] = pkmn.iv[4]
@iv[5] = pkmn.iv[5]
end
def pbInitBlank
@name = ""
@species = 0
@level = 0
@hp = 0
@totalhp = 0
@gender = 0
@ability = 0
@type1 = 0
@type2 = 0
@form = 0
@attack = 0
@defense = 0
@speed = 0
@spatk = 0
@spdef = 0
@status = 0
@statusCount = 0
@pokemon = nil
@pokemonIndex = -1
@participants = []
@moves = [nil,nil,nil,nil]
@iv = [0,0,0,0,0,0]
@item = 0
@weight = nil
end
def pbInitPermanentEffects
# These effects are always retained even if a Pokémon is replaced
@effects[PBEffects::FutureSight] = 0
@effects[PBEffects::FutureSightMove] = 0
@effects[PBEffects::FutureSightUser] = -1
@effects[PBEffects::FutureSightUserPos] = -1
@effects[PBEffects::HealingWish] = false
@effects[PBEffects::LunarDance] = false
@effects[PBEffects::Wish] = 0
@effects[PBEffects::WishAmount] = 0
@effects[PBEffects::WishMaker] = -1
@effects[PBEffects::ShellTrap] = false
end
def pbInitEffects(batonpass)
if !batonpass
# These effects are retained if Baton Pass is used
@stages[PBStats::ATTACK] = 0
@stages[PBStats::DEFENSE] = 0
@stages[PBStats::SPEED] = 0
@stages[PBStats::SPATK] = 0
@stages[PBStats::SPDEF] = 0
@stages[PBStats::EVASION] = 0
@stages[PBStats::ACCURACY] = 0
@lastMoveUsedSketch = -1
@effects[PBEffects::AquaRing] = false
@effects[PBEffects::Confusion] = 0
@effects[PBEffects::Curse] = false
@effects[PBEffects::Embargo] = 0
@effects[PBEffects::FocusEnergy] = 0
@effects[PBEffects::LaserFocus] = 0
@effects[PBEffects::GastroAcid] = false
@effects[PBEffects::HealBlock] = 0
@effects[PBEffects::Ingrain] = false
@effects[PBEffects::LeechSeed] = -1
@effects[PBEffects::LockOn] = 0
@effects[PBEffects::LockOnPos] = -1
for i in 0...4
next if [email protected][i]
if @battle.battlers[i].effects[PBEffects::LockOnPos]==@index &&
@battle.battlers[i].effects[PBEffects::LockOn]>0
@battle.battlers[i].effects[PBEffects::LockOn]=0
@battle.battlers[i].effects[PBEffects::LockOnPos]=-1
end
end
@effects[PBEffects::MagnetRise] = 0
@effects[PBEffects::PerishSong] = 0
@effects[PBEffects::PerishSongUser] = -1
@effects[PBEffects::PowerTrick] = false
@effects[PBEffects::Substitute] = 0
@effects[PBEffects::Telekinesis] = 0
else
if @effects[PBEffects::LockOn]>0
@effects[PBEffects::LockOn]=2
else
@effects[PBEffects::LockOn]=0
end
if @effects[PBEffects::PowerTrick]
@attack,@defense=@defense,@attack
end
end
@damagestate.reset
@fainted = false
@lastAttacker = []
@lastHPLost = 0
@tookDamage = false
@lastMoveUsed = -1
@lastMoveUsedType = -1
@lastRoundMoved = -1
@movesUsed = []
@turncount = 0
@effects[PBEffects::Attract] = -1
for i in 0...4
next if [email protected][i]
if @battle.battlers[i].effects[PBEffects::Attract]==@index
@battle.battlers[i].effects[PBEffects::Attract]=-1
end
end
@effects[PBEffects::BatonPass] = false
@effects[PBEffects::Bide] = 0
@effects[PBEffects::BideDamage] = 0
@effects[PBEffects::BideTarget] = -1
@effects[PBEffects::Charge] = 0
@effects[PBEffects::ChoiceBand] = -1
@effects[PBEffects::Counter] = -1
@effects[PBEffects::CounterTarget] = -1
@effects[PBEffects::DefenseCurl] = false
@effects[PBEffects::DestinyBond] = false
@effects[PBEffects::Disable] = 0
@effects[PBEffects::DisableMove] = 0
@effects[PBEffects::Electrify] = false
@effects[PBEffects::Encore] = 0
@effects[PBEffects::EncoreIndex] = 0
@effects[PBEffects::EncoreMove] = 0
@effects[PBEffects::Endure] = false
@effects[PBEffects::FirstPledge] = 0
@effects[PBEffects::FlashFire] = false
@effects[PBEffects::Flinch] = false
@effects[PBEffects::FollowMe] = 0
@effects[PBEffects::Foresight] = false
@effects[PBEffects::FuryCutter] = 0
@effects[PBEffects::Grudge] = false
@effects[PBEffects::HelpingHand] = false
@effects[PBEffects::HyperBeam] = 0
@effects[PBEffects::Illusion] = nil
if self.hasWorkingAbility(:ILLUSION)
[email protected](@index)
if lastpoke!=@pokemonIndex
@effects[PBEffects::Illusion] = @battle.pbParty(@index)[lastpoke]
end
end
@effects[PBEffects::Imprison] = false
@effects[PBEffects::KingsShield] = false
@effects[PBEffects::LifeOrb] = false
@effects[PBEffects::MagicCoat] = false
@effects[PBEffects::MeanLook] = -1
for i in 0...4
next if [email protected][i]
if @battle.battlers[i].effects[PBEffects::MeanLook]==@index
@battle.battlers[i].effects[PBEffects::MeanLook]=-1
end
end
@effects[PBEffects::MeFirst] = false
@effects[PBEffects::Metronome] = 0
@effects[PBEffects::MicleBerry] = false
@effects[PBEffects::Minimize] = false
@effects[PBEffects::MiracleEye] = false
@effects[PBEffects::MirrorCoat] = -1
@effects[PBEffects::MirrorCoatTarget] = -1
@effects[PBEffects::MoveNext] = false
@effects[PBEffects::MudSport] = false
@effects[PBEffects::MultiTurn] = 0
@effects[PBEffects::MultiTurnAttack] = 0
@effects[PBEffects::MultiTurnUser] = -1
for i in 0...4
next if [email protected][i]
if @battle.battlers[i].effects[PBEffects::MultiTurnUser]==@index
@battle.battlers[i].effects[PBEffects::MultiTurn]=0
@battle.battlers[i].effects[PBEffects::MultiTurnUser]=-1
end
end
@effects[PBEffects::Nightmare] = false
@effects[PBEffects::Outrage] = 0
@effects[PBEffects::ParentalBond] = 0
@effects[PBEffects::PickupItem] = 0
@effects[PBEffects::PickupUse] = 0
@effects[PBEffects::Pinch] = false
@effects[PBEffects::Powder] = false
@effects[PBEffects::Protect] = false
@effects[PBEffects::ProtectNegation] = false
@effects[PBEffects::ProtectRate] = 1
@effects[PBEffects::Pursuit] = false
@effects[PBEffects::Quash] = false
@effects[PBEffects::Rage] = false
@effects[PBEffects::Revenge] = 0
@effects[PBEffects::Roar] = false
@effects[PBEffects::Rollout] = 0
@effects[PBEffects::Roost] = false
@effects[PBEffects::BurnUp] = false
@effects[PBEffects::SkipTurn] = false
@effects[PBEffects::SkyDrop] = false
@effects[PBEffects::SmackDown] = false
@effects[PBEffects::Snatch] = false
@effects[PBEffects::SpikyShield] = false
@effects[PBEffects::Stockpile] = 0
@effects[PBEffects::StockpileDef] = 0
@effects[PBEffects::StockpileSpDef] = 0
@effects[PBEffects::Taunt] = 0
@effects[PBEffects::Torment] = false
@effects[PBEffects::Toxic] = 0
@effects[PBEffects::Transform] = false
@effects[PBEffects::Truant] = false
@effects[PBEffects::TwoTurnAttack] = 0
@effects[PBEffects::Type3] = -1
@effects[PBEffects::Unburden] = false
@effects[PBEffects::Uproar] = 0
@effects[PBEffects::Uturn] = false
@effects[PBEffects::WaterSport] = false
@effects[PBEffects::WeightChange] = 0
@effects[PBEffects::Yawn] = 0
@effects[PBEffects::BeakBlast] = 0
end
def pbUpdate(fullchange=false)
if @pokemon
@pokemon.calcStats
@level = @pokemon.level
@hp = @pokemon.hp
@totalhp = @pokemon.totalhp
if !@effects[PBEffects::Transform]
@attack = @pokemon.attack
@defense = @pokemon.defense
@speed = @pokemon.speed
@spatk = @pokemon.spatk
@spdef = @pokemon.spdef
if fullchange
@ability = @pokemon.ability
@type1 = @pokemon.type1
@type2 = @pokemon.type2
end
end
end
end
def pbInitialize(pkmn,index,batonpass)
# Cure status of previous Pokemon with Natural Cure
if self.hasWorkingAbility(:NATURALCURE)
self.status=0
end
if self.hasWorkingAbility(:REGENERATOR)
self.pbRecoverHP((totalhp/3).floor)
end
pbInitPokemon(pkmn,index)
pbInitEffects(batonpass)
end
# Used only to erase the battler of a Shadow Pokémon that has been snagged.
def pbReset
@pokemon = nil
@pokemonIndex = -1
self.hp = 0
pbInitEffects(false)
# reset status
self.status = 0
self.statusCount = 0
@fainted = true
# reset choice
@battle.choices[@index] = [0,0,nil,-1]
return true
end
# Update Pokémon who will gain EXP if this battler is defeated
def pbUpdateParticipants
return if fainted? # can't update if already fainted
if @battle.pbIsOpposing?(@index)
found1=false
found2=false
for i in @participants
found1=true if i==pbOpposing1.pokemonIndex
found2=true if i==pbOpposing2.pokemonIndex
end
if !found1 && !pbOpposing1.fainted?
@participants[@participants.length]=pbOpposing1.pokemonIndex
end
if !found2 && !pbOpposing2.fainted?
@participants[@participants.length]=pbOpposing2.pokemonIndex
end
end
end
################################################################################
# About this battler
################################################################################
def fainted?
return @hp<=0
end
alias isFainted? fainted?
def pbThis(lowercase=false)
if @battle.pbIsOpposing?(@index)
if @battle.opponent
return lowercase ? _INTL("the opposing {1}",self.name) : _INTL("The opposing {1}",self.name)
else
return lowercase ? _INTL("the wild {1}",self.name) : _INTL("The wild {1}",self.name)
end
elsif @battle.pbOwnedByPlayer?(@index)
return self.name
else
return lowercase ? _INTL("the ally {1}",self.name) : _INTL("The ally {1}",self.name)
end
end
def pbHasType?(type)
if type.is_a?(Symbol) || type.is_a?(String)
type = getConst(PBTypes,type)
end
return false if type==nil || type<0
ret = (self.type1==type || self.type2==type)
ret |= (@effects[PBEffects::Type3]==type) if @effects[PBEffects::Type3]>=0
return ret
end
def pbHasMove?(id)
if id.is_a?(String) || id.is_a?(Symbol)
id = getID(PBMoves,id)
end
return false if !id || id==0
for i in @moves
return true if i.id==id
end
return false
end
def pbHasPrimaryType?(type)
ret=false
if type.is_a?(Symbol) || type.is_a?(String)
ret=isConst?(self.type1,PBTypes,type.to_sym)
if @effects[PBEffects::Type3]>=0
ret=isConst?(@effects[PBEffects::Type3],PBTypes,type.to_sym)
end
end
return ret
end
def pbHasMoveType?(type)
if type.is_a?(String) || type.is_a?(Symbol)
type = getConst(PBTypes,type)
end
return false if type==nil || type<0
for i in @moves
return true if i.type==type
end
return false
end
def pbHasMoveFunction?(code)
return false if !code
for i in @moves
return true if i.function==code
end
return false
end
def hasMovedThisRound?
return false if !@lastRoundMoved
return @[email protected]
end
def hasMoldBreaker
return true if hasWorkingAbility(:MOLDBREAKER) ||
hasWorkingAbility(:TERAVOLT) ||
hasWorkingAbility(:TURBOBLAZE)
return false
end
def hasWorkingAbility(ability,ignorefainted=false)
return false if fainted? && !ignorefainted
return false if @effects[PBEffects::GastroAcid]
return isConst?(@ability,PBAbilities,ability)
end
def hasWorkingItem(item,ignorefainted=false)
return false if fainted? && !ignorefainted
return false if @effects[PBEffects::Embargo]>0
return false if @battle.field.effects[PBEffects::MagicRoom]>0
return false if self.hasWorkingAbility(:KLUTZ,ignorefainted)
return isConst?(@item,PBItems,item)
end
def hasWorkingBerry(ignorefainted=false)
return false if fainted? && !ignorefainted
return false if @effects[PBEffects::Embargo]>0
return false if @battle.field.effects[PBEffects::MagicRoom]>0
return false if self.hasWorkingAbility(:KLUTZ,ignorefainted)
return pbIsBerry?(@item)
end
def isAirborne?(ignoreability=false)
return false if self.hasWorkingItem(:IRONBALL)
return false if @effects[PBEffects::Ingrain]
return false if @effects[PBEffects::SmackDown]
return false if @battle.field.effects[PBEffects::Gravity]>0
return true if self.pbHasType?(:FLYING) && !@effects[PBEffects::Roost]
return true if self.hasWorkingAbility(:LEVITATE) && !ignoreability
return true if self.hasWorkingItem(:AIRBALLOON)
return true if @effects[PBEffects::MagnetRise]>0
return true if @effects[PBEffects::Telekinesis]>0
return false
end
def pbSpeed
stagemul=[10,10,10,10,10,10,10,15,20,25,30,35,40]
stagediv=[40,35,30,25,20,15,10,10,10,10,10,10,10]
speed=@speed
stage=@stages[PBStats::SPEED]+6
speed=(speed*stagemul[stage]/stagediv[stage]).floor
speedmult=0x1000
if @battle.field.effects[PBEffects::ElectricTerrain]>0
speedmult=speedmult*2 if self.hasWorkingAbility(:SURGESURFER)
end
case @battle.pbWeather
when PBWeather::RAINDANCE, PBWeather::HEAVYRAIN
speedmult=speedmult*2 if self.hasWorkingAbility(:SWIFTSWIM)
when PBWeather::SUNNYDAY, PBWeather::HARSHSUN
speedmult=speedmult*2 if self.hasWorkingAbility(:CHLOROPHYLL)
when PBWeather::SANDSTORM
speedmult=speedmult*2 if self.hasWorkingAbility(:SANDRUSH)
when PBWeather::HAIL
speedmult=speedmult*2 if self.hasWorkingAbility(:SLUSHRUSH)
end
if self.hasWorkingAbility(:QUICKFEET) && self.status>0
speedmult=(speedmult*1.5).round
end
if self.hasWorkingAbility(:UNBURDEN) && @effects[PBEffects::Unburden] &&
self.item==0
speedmult=speedmult*2
end
if self.hasWorkingAbility(:SLOWSTART) && self.turncount<=5
speedmult=(speedmult/2).round
end
if self.hasWorkingItem(:MACHOBRACE) ||
self.hasWorkingItem(:POWERWEIGHT) ||
self.hasWorkingItem(:POWERBRACER) ||
self.hasWorkingItem(:POWERBELT) ||
self.hasWorkingItem(:POWERANKLET) ||
self.hasWorkingItem(:POWERLENS) ||
self.hasWorkingItem(:POWERBAND)
speedmult=(speedmult/2).round
end
if self.hasWorkingItem(:CHOICESCARF)
speedmult=(speedmult*1.5).round
end
if isConst?(self.item,PBItems,:IRONBALL)
speedmult=(speedmult/2).round
end
if self.hasWorkingItem(:QUICKPOWDER) && isConst?(self.species,PBSpecies,:DITTO) &&
!@effects[PBEffects::Transform]
speedmult=speedmult*2
end
if self.pbOwnSide.effects[PBEffects::Tailwind]>0
speedmult=speedmult*2
end
if self.pbOwnSide.effects[PBEffects::Swamp]>0
speedmult=(speedmult/2).round
end
if self.status==PBStatuses::PARALYSIS && !self.hasWorkingAbility(:QUICKFEET)
speedmult=(speedmult/4).round
end
if @battle.internalbattle && @battle.pbOwnedByPlayer?(@index) &&
@battle.pbPlayer.numbadges>=BADGESBOOSTSPEED
speedmult=(speedmult*1.1).round
end
speed=(speed*speedmult*1.0/0x1000).round
return [speed,1].max
end
################################################################################
# Change HP
################################################################################
def pbReduceHP(amt,anim=false,registerDamage=true)
if amt>=self.hp
amt=self.hp
elsif amt<1 && !fainted?
amt=1
end
oldhp=self.hp
self.hp-=amt
raise _INTL("HP less than 0") if self.hp<0
raise _INTL("HP greater than total HP") if self.hp>@totalhp
@battle.scene.pbHPChanged(self,oldhp,anim) if amt>0
@tookDamage=true if amt>0 && registerDamage
return amt
end
def pbRecoverHP(amt,anim=false)
if self.hp+amt>@totalhp
[email protected]
elsif amt<1 && self.hp!=@totalhp
amt=1
end
oldhp=self.hp
self.hp+=amt
raise _INTL("HP less than 0") if self.hp<0
raise _INTL("HP greater than total HP") if self.hp>@totalhp
@battle.scene.pbHPChanged(self,oldhp,anim) if amt>0
return amt
end
def pbFaint(showMessage=true)
unless fainted?
PBDebug.log("!!!***Can't faint with HP greater than 0")
return true
end
if @fainted
# PBDebug.log("!!!***Can't faint if already fainted")
return true
end
@battle.scene.pbFainted(self)
pbInitEffects(false)
# Reset status
self.status=0
self.statusCount=0
if @pokemon && @battle.internalbattle
@pokemon.changeHappiness("faint")
end
@pokemon.makeUnmega if self.isMega?
@pokemon.makeUnprimal if self.isPrimal?
@pokemon.revertOtherForms
@fainted=true
# reset choice
@battle.choices[@index]=[0,0,nil,-1]
pbOwnSide.effects[PBEffects::LastRoundFainted][email protected]
@battle.pbDisplayPaused(_INTL("{1} fainted!",pbThis)) if showMessage
PBDebug.log("[Pokémon fainted] #{pbThis}")
# Soul Heart
for i in 0...4
[email protected][i]
if user && user.hasWorkingAbility(:SOULHEART) && !user.fainted?
if user.pbIncreaseStatWithCause(PBStats::SPATK,1,user,PBAbilities.getName(user.ability))
PBDebug.log("[Ability triggered] #{user.pbThis}'s Soul Heart")
end
end
end
return true
end
################################################################################
# Find other battlers/sides in relation to this battler
################################################################################
# Returns the data structure for this battler's side
def pbOwnSide
return @battle.sides[@index&1] # Player: 0 and 2; Foe: 1 and 3
end
# Returns the data structure for the opposing Pokémon's side
def pbOpposingSide
return @battle.sides[(@index&1)^1] # Player: 1 and 3; Foe: 0 and 2
end
# Returns whether the position belongs to the opposing Pokémon's side
def pbIsOpposing?(i)
return (@index&1)!=(i&1)
end
# Returns the battler's partner
def pbPartner
return @battle.battlers[(@index&1)|((@index&2)^2)]
end
# Returns the battler's first opposing Pokémon
def pbOpposing1
return @battle.battlers[((@index&1)^1)]
end
# Returns the battler's second opposing Pokémon
def pbOpposing2
return @battle.battlers[((@index&1)^1)+2]
end
def pbOppositeOpposing
return @battle.battlers[(@index^1)]
end
def pbOppositeOpposing2
return @battle.battlers[(@index^1)|((@index&2)^2)]
end
def pbNonActivePokemonCount()
count=0
[email protected](self.index)
for i in 0...party.length
if (fainted? || i!=self.pokemonIndex) &&
(pbPartner.fainted? || i!=self.pbPartner.pokemonIndex) &&
party[i] && !party[i].egg? && party[i].hp>0
count+=1
end
end
return count
end
################################################################################
# Forms
################################################################################
@@miniorform = 0 # Records the form of Minior at the beginning of battle
def pbCheckForm
return if @effects[PBEffects::Transform]
return if fainted?
transformed=false
# Forecast
if isConst?(self.species,PBSpecies,:CASTFORM)
if self.hasWorkingAbility(:FORECAST)
case @battle.pbWeather
when PBWeather::SUNNYDAY, PBWeather::HARSHSUN
if self.form!=1
self.form=1; transformed=true
end
when PBWeather::RAINDANCE, PBWeather::HEAVYRAIN
if self.form!=2
self.form=2; transformed=true
end
when PBWeather::HAIL
if self.form!=3
self.form=3; transformed=true
end
else
if self.form!=0
self.form=0; transformed=true
end
end
else
if self.form!=0
self.form=0; transformed=true
end
end
end
# Cherrim
if isConst?(self.species,PBSpecies,:CHERRIM)
if self.hasWorkingAbility(:FLOWERGIFT) &&
(@battle.pbWeather==PBWeather::SUNNYDAY ||
@battle.pbWeather==PBWeather::HARSHSUN)
if self.form!=1
self.form=1; transformed=true
end
else
if self.form!=0
self.form=0; transformed=true
end
end
end
# Shaymin
if isConst?(self.species,PBSpecies,:SHAYMIN)
if [email protected]
[email protected]
transformed=true
end
end
# Giratina
if isConst?(self.species,PBSpecies,:GIRATINA)
if [email protected]
[email protected]
transformed=true
end
end
# Arceus
if isConst?(self.ability,PBAbilities,:MULTITYPE) &&
isConst?(self.species,PBSpecies,:ARCEUS)
if [email protected]
[email protected]
transformed=true
end
end
# Zen Mode
if isConst?(self.species,PBSpecies,:DARMANITAN)
if self.hasWorkingAbility(:ZENMODE) && @hp<=((@totalhp/2).floor)
if self.form!=1
self.form=1; transformed=true
end
else
if self.form!=0
self.form=0; transformed=true
end
end
end
# Wishiwashi
if isConst?(self.species,PBSpecies,:WISHIWASHI)
if self.hasWorkingAbility(:SCHOOLING) && @hp<=((@totalhp/4).floor)
if self.form!=0
self.form=0; transformed=true
end
else
if self.form!=1 && @level >=20
self.form=1; transformed=true
end
end
end
# Silvally
if isConst?(self.ability,PBAbilities,:RKSSYSTEM) &&
isConst?(self.species,PBSpecies,:SILVALLY)
if [email protected]
[email protected]
transformed=true
end
end
# Keldeo
if isConst?(self.species,PBSpecies,:KELDEO)
if [email protected]
[email protected]
transformed=true
end
end
# Zygarde
if self.hasWorkingAbility(:POWERCONSTRUCT) &&
isConst?(self.species,PBSpecies,:ZYGARDE) && self.form!=2 &&
self.hp<(self.totalhp/2).ceil
$zygardeform=self.form
self.form=2
transformed=true
@battle.pbDisplay(_INTL("{1} sensed the presence of many...",pbThis))
end
# Minior
if self.hasWorkingAbility(:SHIELDSDOWN) &&
isConst?(self.species,PBSpecies,:MINIOR) &&
self.hp>(self.totalhp*0.5).floor && self.form!=0
@@miniorform=self.form
self.form=0
@battle.pbDisplay(_INTL("{1}'s outer body was petrified!",self.pbThis))
transformed=true
elsif self.hasWorkingAbility(:SHIELDSDOWN) &&
isConst?(self.species,PBSpecies,:MINIOR) &&
self.hp<=(self.totalhp*0.5).floor && self.form==0 && @@miniorform>0
self.form=@@miniorform
@battle.pbDisplay(_INTL("{1}'s rocky shield was broken!",self.pbThis))
transformed=true
elsif self.hasWorkingAbility(:SHIELDSDOWN) &&
isConst?(self.species,PBSpecies,:MINIOR) &&
self.hp<=(self.totalhp*0.5).floor && self.form==0 && @@miniorform=0
self.form=1+rand(7)
@@miniorform=self.form
@battle.pbDisplay(_INTL("{1}'s core was busted!",self.pbThis))
transformed=true
end
if transformed
pbUpdate(true)
@battle.scene.pbChangePokemon(self,@pokemon)
PBDebug.log("[Form changed] #{pbThis} changed to form #{self.form}")
end
# Genesect
if isConst?(self.species,PBSpecies,:GENESECT)
if [email protected]
[email protected]
transformed=true
end
end
def pbResetUsualForms
if !@effects[PBEffects::Transform]
if isConst?(self.species,PBSpecies,:CASTFORM) ||
isConst?(self.species,PBSpecies,:CHERRIM) ||
isConst?(self.species,PBSpecies,:DARMANITAN) ||
isConst?(self.species,PBSpecies,:MELOETTA) ||
isConst?(self.species,PBSpecies,:AEGISLASH) ||
isConst?(self.species,PBSpecies,:XERNEAS) ||
isConst?(self.species,PBSpecies,:WISHIWASHI)
self.form=0
end
if isConst?(self.species,PBSpecies,:MINIOR)
if @@miniorform>0
self.form=@@miniorform
else
self.form=1+rand(7)
@@miniorform=self.form
end
end
end
pbUpdate(true)
end
################################################################################
# Ability effects
################################################################################
def pbAbilitiesOnSwitchIn(onactive)
return if fainted?
if onactive
@battle.pbPrimalReversion(self.index)
end
# Weather
if onactive
if self.hasWorkingAbility(:PRIMORDIALSEA) && @battle.weather!=PBWeather::HEAVYRAIN
@battle.weather=PBWeather::HEAVYRAIN
@battle.weatherduration=-1
@battle.pbCommonAnimation("HeavyRain",nil,nil)
@battle.pbDisplay(_INTL("{1}'s {2} made a heavy rain begin to fall!",pbThis,PBAbilities.getName(self.ability)))
PBDebug.log("[Ability triggered] #{pbThis}'s Primordial Sea made it rain heavily")
end
if self.hasWorkingAbility(:DESOLATELAND) && @battle.weather!=PBWeather::HARSHSUN
@battle.weather=PBWeather::HARSHSUN
@battle.weatherduration=-1
@battle.pbCommonAnimation("HarshSun",nil,nil)
@battle.pbDisplay(_INTL("{1}'s {2} turned the sunlight extremely harsh!",pbThis,PBAbilities.getName(self.ability)))
PBDebug.log("[Ability triggered] #{pbThis}'s Desolate Land made the sun shine harshly")
end
if self.hasWorkingAbility(:DELTASTREAM) && @battle.weather!=PBWeather::STRONGWINDS
@battle.weather=PBWeather::STRONGWINDS
@battle.weatherduration=-1
@battle.pbCommonAnimation("StrongWinds",nil,nil)
@battle.pbDisplay(_INTL("{1}'s {2} caused a mysterious air current that protects Flying-type Pokémon!",pbThis,PBAbilities.getName(self.ability)))
PBDebug.log("[Ability triggered] #{pbThis}'s Delta Stream made an air current blow")
end
if @battle.weather!=PBWeather::HEAVYRAIN &&
@battle.weather!=PBWeather::HARSHSUN &&
@battle.weather!=PBWeather::STRONGWINDS
if self.hasWorkingAbility(:DRIZZLE) && (@battle.weather!=PBWeather::RAINDANCE || @battle.weatherduration!=-1)
@battle.weather=PBWeather::RAINDANCE
if USENEWBATTLEMECHANICS
@battle.weatherduration=5
@battle.weatherduration=8 if hasWorkingItem(:DAMPROCK)
else
@battle.weatherduration=-1
end
@battle.pbCommonAnimation("Rain",nil,nil)
@battle.pbDisplay(_INTL("{1}'s {2} made it rain!",pbThis,PBAbilities.getName(self.ability)))
PBDebug.log("[Ability triggered] #{pbThis}'s Drizzle made it rain")
end
if self.hasWorkingAbility(:DROUGHT) && (@battle.weather!=PBWeather::SUNNYDAY || @battle.weatherduration!=-1)
@battle.weather=PBWeather::SUNNYDAY
if USENEWBATTLEMECHANICS
@battle.weatherduration=5
@battle.weatherduration=8 if hasWorkingItem(:HEATROCK)
else
@battle.weatherduration=-1
end
@battle.pbCommonAnimation("Sunny",nil,nil)
@battle.pbDisplay(_INTL("{1}'s {2} intensified the sun's rays!",pbThis,PBAbilities.getName(self.ability)))
PBDebug.log("[Ability triggered] #{pbThis}'s Drought made it sunny")
end
if self.hasWorkingAbility(:SANDSTREAM) && (@battle.weather!=PBWeather::SANDSTORM || @battle.weatherduration!=-1)
@battle.weather=PBWeather::SANDSTORM
if USENEWBATTLEMECHANICS
@battle.weatherduration=5
@battle.weatherduration=8 if hasWorkingItem(:SMOOTHROCK)
else
@battle.weatherduration=-1
end
@battle.pbCommonAnimation("Sandstorm",nil,nil)
@battle.pbDisplay(_INTL("{1}'s {2} whipped up a sandstorm!",pbThis,PBAbilities.getName(self.ability)))
PBDebug.log("[Ability triggered] #{pbThis}'s Sand Stream made it sandstorm")
end
if self.hasWorkingAbility(:SNOWWARNING) && (@battle.weather!=PBWeather::HAIL || @battle.weatherduration!=-1)
@battle.weather=PBWeather::HAIL
if USENEWBATTLEMECHANICS
@battle.weatherduration=5
@battle.weatherduration=8 if hasWorkingItem(:ICYROCK)
else
@battle.weatherduration=-1
end
@battle.pbCommonAnimation("Hail",nil,nil)
@battle.pbDisplay(_INTL("{1}'s {2} made it hail!",pbThis,PBAbilities.getName(self.ability)))
PBDebug.log("[Ability triggered] #{pbThis}'s Snow Warning made it hail")
end
end
if self.hasWorkingAbility(:AIRLOCK) ||
self.hasWorkingAbility(:CLOUDNINE)
@battle.pbDisplay(_INTL("{1} has {2}!",pbThis,PBAbilities.getName(self.ability)))
@battle.pbDisplay(_INTL("The effects of the weather disappeared."))
end
end
@battle.pbPrimordialWeather
# Trace
if self.hasWorkingAbility(:TRACE)
choices=[]
for i in 0...4
[email protected][i]
if pbIsOpposing?(i) && !foe.fainted?
abil=foe.ability
if abil>0 &&
!isConst?(abil,PBAbilities,:TRACE) &&
!isConst?(abil,PBAbilities,:MULTITYPE) &&
!isConst?(abil,PBAbilities,:ILLUSION) &&
!isConst?(abil,PBAbilities,:FLOWERGIFT) &&
!isConst?(abil,PBAbilities,:IMPOSTER) &&
!isConst?(abil,PBAbilities,:STANCECHANGE) &&
!isConst?(abil,PBAbilities,:COMATOSE) &&
!isConst?(abil,PBAbilities,:DISGUISE) &&
!isConst?(abil,PBAbilities,:POWEROFALCHEMY) &&
!isConst?(abil,PBAbilities,:RECEIVER) &&
!isConst?(abil,PBAbilities,:SHIELDSDOWN) &&
!isConst?(abil,PBAbilities,:BATTLEBOND) &&
!isConst?(abil,PBAbilities,:POWERCONSTRUCT) &&
!isConst?(abil,PBAbilities,:RKSSYSTEM) &&
!isConst?(abil,PBAbilities,:SCHOOLING)
choices.push(i)
end
end
end
if choices.length>0
choice=choices[@battle.pbRandom(choices.length)]
[email protected][choice].pbThis(true)
[email protected][choice].ability
@ability=battlerability
abilityname=PBAbilities.getName(battlerability)
@battle.pbDisplay(_INTL("{1} traced {2}'s {3}!",pbThis,battlername,abilityname))
PBDebug.log("[Ability triggered] #{pbThis}'s Trace turned into #{abilityname} from #{battlername}")
end
end
# Intimidate
if self.hasWorkingAbility(:INTIMIDATE) && onactive
PBDebug.log("[Ability triggered] #{pbThis}'s Intimidate")
for i in 0...4
if pbIsOpposing?(i) && [email protected][i].fainted?
@battle.battlers[i].pbReduceAttackStatIntimidate(self)
end
end
end
# Power of Alchemist & Receiver
if (self.hasWorkingAbility(:POWEROFALCHEMY) || self.hasWorkingAbility(:RECEIVER)) &&
@battle.doublebattle && pbPartner.fainted?
usable=false
abil=pbPartner.ability
if abil>0 &&
!isConst?(abil,PBAbilities,:POWEROFALCHEMY) &&
!isConst?(abil,PBAbilities,:RECEIVER) &&
!isConst?(abil,PBAbilities,:TRACE) &&
!isConst?(abil,PBAbilities,:FORECAST) &&
!isConst?(abil,PBAbilities,:FLOWERGIFT) &&
!isConst?(abil,PBAbilities,:MULTITYPE) &&
!isConst?(abil,PBAbilities,:ILLUSION) &&
!isConst?(abil,PBAbilities,:WONDERGUARD) &&
!isConst?(abil,PBAbilities,:ZENMODE) &&
!isConst?(abil,PBAbilities,:IMPOSTER) &&
!isConst?(abil,PBAbilities,:STANCECHANGE) &&
!isConst?(abil,PBAbilities,:POWERCONSTRUCT) &&
!isConst?(abil,PBAbilities,:SCHOOLING) &&
!isConst?(abil,PBAbilities,:COMATOSE) &&
!isConst?(abil,PBAbilities,:SHIELDSDOWN) &&
!isConst?(abil,PBAbilities,:DISGUISE) &&
!isConst?(abil,PBAbilities,:RKSSYSTEM) &&
!isConst?(abil,PBAbilities,:BATTLEBOND) &&
!isConst?(abil,PBAbilities,:SHIELDSDOWN)
usable=true
end
if usable
battlername=pbPartner.pbThis(true)
abilityname=PBAbilities.getName(abil)
PBDebug.log("[Ability triggered] #{self.pbThis}'s #{PBAbilities.getName(self.ability)} turned into #{abilityname} from #{battlername}")
self.ability=abil
@battle.pbDisplay(_INTL("{1} copied {2}'s {3}!",pbThis,battlername,abilityname))
end
end
# Download
if self.hasWorkingAbility(:DOWNLOAD) && onactive
odef=ospdef=0
if pbOpposing1 && !pbOpposing1.fainted?
odef+=pbOpposing1.defense
ospdef+=pbOpposing1.spdef
end
if pbOpposing2 && !pbOpposing2.fainted?
odef+=pbOpposing2.defense
ospdef+=pbOpposing1.spdef
end
if ospdef>odef
if pbIncreaseStatWithCause(PBStats::ATTACK,1,self,PBAbilities.getName(ability))
PBDebug.log("[Ability triggered] #{pbThis}'s Download (raising Attack)")
end
else
if pbIncreaseStatWithCause(PBStats::SPATK,1,self,PBAbilities.getName(ability))
PBDebug.log("[Ability triggered] #{pbThis}'s Download (raising Special Attack)")
end
end
end
# Frisk
if self.hasWorkingAbility(:FRISK) && @battle.pbOwnedByPlayer?(@index) && onactive
foes=[]
foes.push(pbOpposing1) if pbOpposing1.item>0 && !pbOpposing1.fainted?
foes.push(pbOpposing2) if pbOpposing2.item>0 && !pbOpposing2.fainted?
if USENEWBATTLEMECHANICS
PBDebug.log("[Ability triggered] #{pbThis}'s Frisk") if foes.length>0
for i in foes
itemname=PBItems.getName(i.item)
@battle.pbDisplay(_INTL("{1} frisked {2} and found its {3}!",pbThis,i.pbThis(true),itemname))
end
elsif foes.length>0
PBDebug.log("[Ability triggered] #{pbThis}'s Frisk")
foe=foes[@battle.pbRandom(foes.length)]
itemname=PBItems.getName(foe.item)
@battle.pbDisplay(_INTL("{1} frisked the foe and found one {2}!",pbThis,itemname))
end
end
# Anticipation
if self.hasWorkingAbility(:ANTICIPATION) && @battle.pbOwnedByPlayer?(@index) && onactive
PBDebug.log("[Ability triggered] #{pbThis} has Anticipation")
found=false
for foe in [pbOpposing1,pbOpposing2]
next if foe.fainted?
for j in foe.moves
movedata=PBMoveData.new(j.id)
eff=PBTypes.getCombinedEffectiveness(movedata.type,type1,type2,@effects[PBEffects::Type3])
if (movedata.basedamage>0 && eff>8) ||
(movedata.function==0x70 && eff>0) # OHKO
found=true
break
end
end
break if found
end
@battle.pbDisplay(_INTL("{1} shuddered with anticipation!",pbThis)) if found
end
# Forewarn
if self.hasWorkingAbility(:FOREWARN) && @battle.pbOwnedByPlayer?(@index) && onactive
PBDebug.log("[Ability triggered] #{pbThis} has Forewarn")
highpower=0
fwmoves=[]
for foe in [pbOpposing1,pbOpposing2]
next if foe.fainted?
for j in foe.moves
movedata=PBMoveData.new(j.id)
power=movedata.basedamage
power=150 if movedata.function==0x8B || # Eruption
movedata.function==0x70 || # OHKO
power=120 if movedata.function==0x71 || # Counter
movedata.function==0x72 || # Mirror Coat
movedata.function==0x73 || # Metal Burst
power=80 if movedata.function==0x6A || # Sonic Boom
movedata.function==0x6B || # Dragon Rage
movedata.function==0x6C || # Super Fang, Nature's Madness
movedata.function==0x6D || # Night Shade, Seismic Toss
movedata.function==0x6E || # Endeavor
movedata.function==0x6F || # Psywave
movedata.function==0x89 || # Return
movedata.function==0x8A || # Frustration
movedata.function==0x8C || # Crush Grip, Wring Out
movedata.function==0x8D || # Gyro Ball
movedata.function==0x8F || # Punishment
movedata.function==0x94 || # Present
movedata.function==0x96 || # Natural Gift
movedata.function==0x97 || # Trump Card
movedata.function==0x98 || # Flail, Reversal
movedata.function==0x99 || # Electro Ball
movedata.function==0x9A || # Grass Knot, Low Kick
movedata.function==0x9B || # Heat Crash, Heavy Slam
movedata.function==0xE1 || # Final Gambit
movedata.function==0xF7 || # Fling
movedata.function==0x113 || # Spit Up
power=80 if movedata.function==0x8E # Stored Power, Power Trip
if power>highpower
fwmoves=[j.id]; highpower=power
elsif power==highpower
fwmoves.push(j.id)
end
end
end
if fwmoves.length>0
fwmove=fwmoves[@battle.pbRandom(fwmoves.length)]
movename=PBMoves.getName(fwmove)
@battle.pbDisplay(_INTL("{1}'s Forewarn alerted it to {2}!",pbThis,movename))
end
end
# Pressure message
if self.hasWorkingAbility(:PRESSURE) && onactive
@battle.pbDisplay(_INTL("{1} is exerting its pressure!",pbThis))
end
# Electric Terrain
if @field.effects[PBEffects::ElectricTerrain]>0
for i in 0...4
user=@battlers[i]
if user.hasWorkingItem(:ELECTRICSEED)
user.pbIncreaseStatWithCause(PBStats::DEFENSE,1,user,
PBItems.getName(user.item))
pbDisplay(_INTL("{1}'s {2} boosted its Defense.",
user.pbThis,PBItems.getName(user.item)))
user.pbConsumeItem
end
end
@field.effects[PBEffects::ElectricTerrain]-=1
if @field.effects[PBEffects::ElectricTerrain]==0
pbDisplay(_INTL("The electric current disappeared from the battlefield."))
PBDebug.log("[End of effect] Electric Terrain ended")
end
end
# Grassy Terrain
if @field.effects[PBEffects::GrassyTerrain]>0
for i in 0...4
user=@battlers[i]
if user.hasWorkingItem(:GRASSYSEED)
user.pbIncreaseStatWithCause(PBStats::DEFENSE,1,user,
PBItems.getName(user.item))
pbDisplay(_INTL("{1}'s {2} boosted its Defense.",
user.pbThis,PBItems.getName(user.item)))
user.pbConsumeItem
end
end
@field.effects[PBEffects::GrassyTerrain]-=1
if @field.effects[PBEffects::GrassyTerrain]==0
pbDisplay(_INTL("The grass disappeared from the battlefield."))
PBDebug.log("[End of effect] Grassy Terrain ended")
end
end
# Misty Terrain
if @field.effects[PBEffects::MistyTerrain]>0
for i in 0...4
user=@battlers[i]
if user.hasWorkingItem(:MISTYSEED)
user.pbIncreaseStatWithCause(PBStats::SPDEF,1,user,
PBItems.getName(user.item))
pbDisplay(_INTL("{1}'s {2} boosted its Special Defense.",
user.pbThis,PBItems.getName(user.item)))
user.pbConsumeItem
end
end
@field.effects[PBEffects::MistyTerrain]-=1
if @field.effects[PBEffects::MistyTerrain]==0
pbDisplay(_INTL("The mist disappeared from the battlefield."))
PBDebug.log("[End of effect] Misty Terrain ended")
end
end
# Psychic Terrain
if @field.effects[PBEffects::PsychicTerrain]>0
for i in 0...4
user=user=@battlers[i]
if user.hasWorkingItem(:PSYCHICSEED)
user.pbIncreaseStatWithCause(PBStats::SPDEF,1,user,
PBItems.getName(user.item))
pbDisplay(_INTL("{1}'s {2} boosted its Special Defense.",
user.pbThis,PBItems.getName(user.item)))
user.pbConsumeItem
end
end
@field.effects[PBEffects::PsychicTerrain]-=1
if @field.effects[PBEffects::PsychicTerrain]==0
pbDisplay(_INTL("The battlefield returned to its normal state."))
PBDebug.log("[End of effect] Misty Terrain ended")
end
end
# Mold Breaker message
if self.hasWorkingAbility(:MOLDBREAKER) && onactive
@battle.pbDisplay(_INTL("{1} breaks the mold!",pbThis))
end
# Turboblaze message
if self.hasWorkingAbility(:TURBOBLAZE) && onactive
@battle.pbDisplay(_INTL("{1} is radiating a blazing aura!",pbThis))
end
# Teravolt message
if self.hasWorkingAbility(:TERAVOLT) && onactive
@battle.pbDisplay(_INTL("{1} is radiating a bursting aura!",pbThis))
end
# Dark Aura message
if self.hasWorkingAbility(:DARKAURA) && onactive
@battle.pbDisplay(_INTL("{1} is radiating a dark aura!",pbThis))
end
# Fairy Aura message
if self.hasWorkingAbility(:FAIRYAURA) && onactive
@battle.pbDisplay(_INTL("{1} is radiating a fairy aura!",pbThis))
end
# Aura Break message
if self.hasWorkingAbility(:AURABREAK) && onactive
@battle.pbDisplay(_INTL("{1} reversed all other Pokémon's auras!",pbThis))
end
# Slow Start message
if self.hasWorkingAbility(:SLOWSTART) && onactive
@battle.pbDisplay(_INTL("{1} can't get it going because of its {2}!",
pbThis,PBAbilities.getName(self.ability)))
end
# Imposter
if self.hasWorkingAbility(:IMPOSTER) && !@effects[PBEffects::Transform] && onactive
choice=pbOppositeOpposing
blacklist=[
0xC9, # Fly
0xCA, # Dig
0xCB, # Dive
0xCC, # Bounce
0xCD, # Shadow Force
0xCE, # Sky Drop
0x14D # Phantom Force
]
if choice.effects[PBEffects::Transform] ||
choice.effects[PBEffects::Illusion] ||
choice.effects[PBEffects::Substitute]>0 ||
choice.effects[PBEffects::SkyDrop] ||
blacklist.include?(PBMoveData.new(choice.effects[PBEffects::TwoTurnAttack]).function)
PBDebug.log("[Ability triggered] #{pbThis}'s Imposter couldn't transform")
else
PBDebug.log("[Ability triggered] #{pbThis}'s Imposter")
@battle.pbAnimation(getConst(PBMoves,:TRANSFORM),self,choice)
@effects[PBEffects::Transform]=true
@type1=choice.type1
@type2=choice.type2
@effects[PBEffects::Type3]=-1
@ability=choice.ability
@attack=choice.attack
@defense=choice.defense
@speed=choice.speed
@spatk=choice.spatk
@spdef=choice.spdef
for i in [PBStats::ATTACK,PBStats::DEFENSE,PBStats::SPEED,
PBStats::SPATK,PBStats::SPDEF,PBStats::ACCURACY,PBStats::EVASION]
@stages[i]=choice.stages[i]
end
for i in 0...4
@moves[i]=PokeBattle_Move.pbFromPBMove(@battle,PBMove.new(choice.moves[i].id))
@moves[i].pp=5
@moves[i].totalpp=5
end
@effects[PBEffects::Disable]=0
@effects[PBEffects::DisableMove]=0
@battle.pbDisplay(_INTL("{1} transformed into {2}!",pbThis,choice.pbThis(true)))
PBDebug.log("[Pokémon transformed] #{pbThis} transformed into #{choice.pbThis(true)}")
end
end
# Air Balloon message
if self.hasWorkingItem(:AIRBALLOON) && onactive
@battle.pbDisplay(_INTL("{1} floats in the air with its {2}!",pbThis,PBItems.getName(self.item)))
end
end
def pbEffectsOnDealingDamage(move,user,target,damage)
movetype=move.pbType(move.type,user,target)
if damage>0 && move.isContactMove?(user)
if target.hasWorkingAbility(:WATERCOMPACTION) && isConst?(movetype,PBTypes,:WATER)
if target.pbIncreaseStatWithCause(PBStats::DEFENSE,2,target,PBAbilities.getName(target.ability))
PBDebug.log("[Ability triggered] #{target.pbThis}'s Water Compaction")
end
end
if !target.damagestate.substitute
if target.hasWorkingItem(:STICKYBARB,true) && user.item==0 && !user.fainted?
user.item=target.item
target.item=0
target.effects[PBEffects::Unburden]=true
if [email protected] && [email protected]?(user.index)
if user.pokemon.itemInitial==0 && target.pokemon.itemInitial==user.item
user.pokemon.itemInitial=user.item
target.pokemon.itemInitial=0
end
end
@battle.pbDisplay(_INTL("{1}'s {2} was transferred to {3}!",
target.pbThis,PBItems.getName(user.item),user.pbThis(true)))
PBDebug.log("[Item triggered] #{target.pbThis}'s Sticky Barb moved to #{user.pbThis(true)}")
end
if target.hasWorkingItem(:ROCKYHELMET,true) && !user.fainted?
if !user.hasWorkingAbility(:MAGICGUARD)
PBDebug.log("[Item triggered] #{target.pbThis}'s Rocky Helmet")
@battle.scene.pbDamageAnimation(user,0)
user.pbReduceHP((user.totalhp/6).floor)
@battle.pbDisplay(_INTL("{1} was hurt by the {2}!",user.pbThis,
PBItems.getName(target.item)))
end
[email protected][target.index][2]
if movex.function==0x192 && # Shell Trap
move.pbisPhysical?(move.type,user,target)
target.effects[PBEffects::ShellTrap]=true
end
if movex.function==0x1BC && # Beak Blast
move.isContactMove? && user.pbCanBurn?(false,movex,target)
user.pbBurn(target)
end
end
if target.hasWorkingAbility(:AFTERMATH,true) && target.fainted? &&
!user.fainted?
if [email protected](:DAMP) &&
!user.hasMoldBreaker && !user.hasWorkingAbility(:MAGICGUARD)
PBDebug.log("[Ability triggered] #{target.pbThis}'s Aftermath")
@battle.scene.pbDamageAnimation(user,0)
user.pbReduceHP((user.totalhp/4).floor)
@battle.pbDisplay(_INTL("{1} was caught in the aftermath!",user.pbThis))
end
end
if target.hasWorkingAbility(:INNARDSOUT,true) && target.isFainted? &&
!user.isFainted?
PBDebug.log("[Ability triggered] #{target.pbThis}'s Innards Out")
@battle.scene.pbDamageAnimation(user,0)
user.pbReduceHP(target.lastHPLost)
@battle.pbDisplay(_INTL("{1} was hurt by {2}'s {3}!",user.pbThis,
target.pbThis,PBAbilities.getName(target.ability)))
end
if target.hasWorkingAbility(:CUTECHARM) && @battle.pbRandom(10)<3
if !user.fainted? && user.pbCanAttract?(target,false)
PBDebug.log("[Ability triggered] #{target.pbThis}'s Cute Charm")
user.pbAttract(target,_INTL("{1}'s {2} made {3} fall in love!",target.pbThis,
PBAbilities.getName(target.ability),user.pbThis(true)))
end
end
if target.hasWorkingAbility(:EFFECTSPORE,true) && @battle.pbRandom(10)<3
if USENEWBATTLEMECHANICS &&
(user.pbHasType?(:GRASS) ||
user.hasWorkingAbility(:OVERCOAT) ||
user.hasWorkingItem(:SAFETYGOGGLES))
else
PBDebug.log("[Ability triggered] #{target.pbThis}'s Effect Spore")
case @battle.pbRandom(3)
when 0
if user.pbCanPoison?(nil,false)
user.pbPoison(target,_INTL("{1}'s {2} poisoned {3}!",target.pbThis,
PBAbilities.getName(target.ability),user.pbThis(true)))
end
when 1
if user.pbCanSleep?(nil,false)
user.pbSleep(_INTL("{1}'s {2} made {3} fall asleep!",target.pbThis,
PBAbilities.getName(target.ability),user.pbThis(true)))
end
when 2
if user.pbCanParalyze?(nil,false)
user.pbParalyze(target,_INTL("{1}'s {2} paralyzed {3}! It may be unable to move!",
target.pbThis,PBAbilities.getName(target.ability),user.pbThis(true)))
end
end
end
end
if target.hasWorkingAbility(:FLAMEBODY,true) && @battle.pbRandom(10)<3 &&
user.pbCanBurn?(nil,false)
PBDebug.log("[Ability triggered] #{target.pbThis}'s Flame Body")
user.pbBurn(target,_INTL("{1}'s {2} burned {3}!",target.pbThis,
PBAbilities.getName(target.ability),user.pbThis(true)))
end
if target.hasWorkingAbility(:MUMMY,true) && !user.fainted?
if !isConst?(user.ability,PBAbilities,:MULTITYPE) &&
!isConst?(user.ability,PBAbilities,:STANCECHANGE) &&
!isConst?(user.ability,PBAbilities,:MUMMY) &&
!isConst?(user.ability,PBAbilities,:COMATOSE) &&
!isConst?(user.ability,PBAbilities,:DISGUISE) &&
!isConst?(user.ability,PBAbilities,:SHIELDSDOWN) &&
!isConst?(user.ability,PBAbilities,:RKSSYSTEM) &&
!isConst?(user.ability,PBAbilities,:SCHOOLING)
PBDebug.log("[Ability triggered] #{target.pbThis}'s Mummy copied onto #{user.pbThis(true)}")
user.ability=getConst(PBAbilities,:MUMMY) || 0
@battle.pbDisplay(_INTL("{1} was mummified by {2}!",
user.pbThis,target.pbThis(true)))
end
end
if target.hasWorkingAbility(:POISONPOINT,true) && @battle.pbRandom(10)<3 &&
user.pbCanPoison?(nil,false)
PBDebug.log("[Ability triggered] #{target.pbThis}'s #{PBAbilities.getName(target.ability)}")
user.pbPoison(target,_INTL("{1}'s {2} poisoned {3}!",target.pbThis,
PBAbilities.getName(target.ability),user.pbThis(true)))
end
if (target.hasWorkingAbility(:ROUGHSKIN,true) ||
target.hasWorkingAbility(:IRONBARBS,true)) && !user.fainted?
if !user.hasWorkingAbility(:MAGICGUARD)
PBDebug.log("[Ability triggered] #{target.pbThis}'s #{PBAbilities.getName(target.ability)}")
@battle.scene.pbDamageAnimation(user,0)
user.pbReduceHP((user.totalhp/8).floor)
@battle.pbDisplay(_INTL("{1}'s {2} hurt {3}!",target.pbThis,
PBAbilities.getName(target.ability),user.pbThis(true)))
end
end
if target.hasWorkingAbility(:STATIC,true) && @battle.pbRandom(10)<3 &&
user.pbCanParalyze?(nil,false)
PBDebug.log("[Ability triggered] #{target.pbThis}'s Static")
user.pbParalyze(target,_INTL("{1}'s {2} paralyzed {3}! It may be unable to move!",
target.pbThis,PBAbilities.getName(target.ability),user.pbThis(true)))
end
if target.hasWorkingAbility(:GOOEY,true)
if user.pbReduceStatWithCause(PBStats::SPEED,1,target,PBAbilities.getName(target.ability))
PBDebug.log("[Ability triggered] #{target.pbThis}'s Gooey")
end
end
if user.hasWorkingAbility(:POISONTOUCH,true) &&
target.pbCanPoison?(nil,false) && @battle.pbRandom(10)<3
PBDebug.log("[Ability triggered] #{user.pbThis}'s Poison Touch")
target.pbPoison(user,_INTL("{1}'s {2} poisoned {3}!",user.pbThis,
PBAbilities.getName(user.ability),target.pbThis(true)))
end
end
end
if damage>0
if !target.damagestate.substitute
if target.hasWorkingAbility(:CURSEDBODY,true) && @battle.pbRandom(10)<3
if user.effects[PBEffects::Disable]<=0 && move.pp>0 && !user.fainted?
user.effects[PBEffects::Disable]=3
user.effects[PBEffects::DisableMove]=move.id
@battle.pbDisplay(_INTL("{1}'s {2} disabled {3}!",target.pbThis,
PBAbilities.getName(target.ability),user.pbThis(true)))
PBDebug.log("[Ability triggered] #{target.pbThis}'s Cursed Body disabled #{user.pbThis(true)}")
end
end
if target.hasWorkingAbility(:JUSTIFIED) && isConst?(movetype,PBTypes,:DARK)
if target.pbIncreaseStatWithCause(PBStats::ATTACK,1,target,PBAbilities.getName(target.ability))
PBDebug.log("[Ability triggered] #{target.pbThis}'s Justified")
end
end
if target.hasWorkingAbility(:RATTLED) &&
(isConst?(movetype,PBTypes,:BUG) ||
isConst?(movetype,PBTypes,:DARK) ||
isConst?(movetype,PBTypes,:GHOST))
if target.pbIncreaseStatWithCause(PBStats::SPEED,1,target,PBAbilities.getName(target.ability))
PBDebug.log("[Ability triggered] #{target.pbThis}'s Rattled")
end
end
if target.hasWorkingAbility(:WEAKARMOR) && move.pbIsPhysical?(movetype)
if target.pbReduceStatWithCause(PBStats::DEFENSE,2,target,PBAbilities.getName(target.ability))
PBDebug.log("[Ability triggered] #{target.pbThis}'s Weak Armor (lower Defense)")
end
if target.pbIncreaseStatWithCause(PBStats::SPEED,1,target,PBAbilities.getName(target.ability))
PBDebug.log("[Ability triggered] #{target.pbThis}'s Weak Armor (raise Speed)")
end
end
if target.hasWorkingItem(:AIRBALLOON,true)
PBDebug.log("[Item triggered] #{target.pbThis}'s Air Balloon popped")
@battle.pbDisplay(_INTL("{1}'s Air Balloon popped!",target.pbThis))
target.pbConsumeItem(true,false)
elsif target.hasWorkingItem(:ABSORBBULB) && isConst?(movetype,PBTypes,:WATER)
if target.pbIncreaseStatWithCause(PBStats::SPATK,1,target,PBItems.getName(target.item))
PBDebug.log("[Item triggered] #{target.pbThis}'s #{PBItems.getName(target.item)}")
target.pbConsumeItem
end
elsif target.hasWorkingItem(:LUMINOUSMOSS) && isConst?(movetype,PBTypes,:WATER)
if target.pbIncreaseStatWithCause(PBStats::SPDEF,1,target,PBItems.getName(target.item))
PBDebug.log("[Item triggered] #{target.pbThis}'s #{PBItems.getName(target.item)}")
target.pbConsumeItem
end
elsif target.hasWorkingItem(:CELLBATTERY) && isConst?(movetype,PBTypes,:ELECTRIC)
if target.pbIncreaseStatWithCause(PBStats::ATTACK,1,target,PBItems.getName(target.item))
PBDebug.log("[Item triggered] #{target.pbThis}'s #{PBItems.getName(target.item)}")
target.pbConsumeItem
end
elsif target.hasWorkingItem(:SNOWBALL) && isConst?(movetype,PBTypes,:ICE)
if target.pbIncreaseStatWithCause(PBStats::ATTACK,1,target,PBItems.getName(target.item))
PBDebug.log("[Item triggered] #{target.pbThis}'s #{PBItems.getName(target.item)}")
target.pbConsumeItem
end
elsif target.hasWorkingItem(:WEAKNESSPOLICY) && target.damagestate.typemod>8
showanim=true
if !target.hasWorkingAbility(:DISGUISE) || target.form!=0
if target.pbIncreaseStatWithCause(PBStats::ATTACK,2,target,PBItems.getName(target.item),showanim)
PBDebug.log("[Item triggered] #{target.pbThis}'s Weakness Policy (Attack)")
showanim=false
end
if target.pbIncreaseStatWithCause(PBStats::SPATK,2,target,PBItems.getName(target.item),showanim)
PBDebug.log("[Item triggered] #{target.pbThis}'s Weakness Policy (Special Attack)")
showanim=false
end
end
target.pbConsumeItem if !showanim
elsif target.hasWorkingItem(:ENIGMABERRY) && target.damagestate.typemod>8
target.pbActivateBerryEffect
elsif (target.hasWorkingItem(:JABOCABERRY) && move.pbIsPhysical?(movetype)) ||
(target.hasWorkingItem(:ROWAPBERRY) && move.pbIsSpecial?(movetype))
if !user.hasWorkingAbility(:MAGICGUARD) && !user.fainted?
PBDebug.log("[Item triggered] #{target.pbThis}'s #{PBItems.getName(target.item)}")
@battle.scene.pbDamageAnimation(user,0)
user.pbReduceHP((user.totalhp/8).floor)
@battle.pbDisplay(_INTL("{1} consumed its {2} and hurt {3}!",target.pbThis,
PBItems.getName(target.item),user.pbThis(true)))
target.pbConsumeItem
end
elsif target.hasWorkingItem(:KEEBERRY) && move.pbIsPhysical?(movetype)
target.pbActivateBerryEffect
elsif target.hasWorkingItem(:MARANGABERRY) && move.pbIsSpecial?(movetype)
target.pbActivateBerryEffect
end
end
if target.hasWorkingAbility(:ANGERPOINT)
if target.damagestate.critical && !target.damagestate.substitute &&
target.pbCanIncreaseStatStage?(PBStats::ATTACK,target)
PBDebug.log("[Ability triggered] #{target.pbThis}'s Anger Point")
target.stages[PBStats::ATTACK]=6
@battle.pbCommonAnimation("StatUp",target,nil)
@battle.pbDisplay(_INTL("{1}'s {2} maxed its {3}!",
target.pbThis,PBAbilities.getName(target.ability),PBStats.getName(PBStats::ATTACK)))
end
end
end
user.pbAbilityCureCheck
target.pbAbilityCureCheck
end
def pbEffectsAfterHit(user,target,thismove,turneffects)
return if turneffects[PBEffects::TotalDamage]==0
if !(user.hasWorkingAbility(:SHEERFORCE) && thismove.addlEffect>0)
# Target's held items:
# Red Card
if target.hasWorkingItem(:REDCARD) && @battle.pbCanSwitch?(user.index,-1,false)
user.effects[PBEffects::Roar]=true
@battle.pbDisplay(_INTL("{1} held up its {2} against the {3}!",
target.pbThis,PBItems.getName(target.item),user.pbThis(true)))
target.pbConsumeItem
# Eject Button
elsif target.hasWorkingItem(:EJECTBUTTON) && @battle.pbCanChooseNonActive?(target.index)
target.effects[PBEffects::Uturn]=true
@battle.pbDisplay(_INTL("{1} is switched out with the {2}!",
target.pbThis,PBItems.getName(target.item)))
target.pbConsumeItem
end
# User's held items:
# Shell Bell
if user.hasWorkingItem(:SHELLBELL) && user.effects[PBEffects::HealBlock]==0
PBDebug.log("[Item triggered] #{user.pbThis}'s Shell Bell (total damage=#{turneffects[PBEffects::TotalDamage]})")
hpgain=user.pbRecoverHP((turneffects[PBEffects::TotalDamage]/8).floor,true)
if hpgain>0
@battle.pbDisplay(_INTL("{1} restored a little HP using its {2}!",
user.pbThis,PBItems.getName(user.item)))
end
end
# Life Orb
if user.effects[PBEffects::LifeOrb] && !user.hasWorkingAbility(:MAGICGUARD)
PBDebug.log("[Item triggered] #{user.pbThis}'s Life Orb (recoil)")
hploss=user.pbReduceHP((user.totalhp/10).floor,true)
if hploss>0
@battle.pbDisplay(_INTL("{1} lost some of its HP!",user.pbThis))
end
end
user.pbFaint if user.fainted? # no return
# Color Change
movetype=thismove.pbType(thismove.type,user,target)
if target.hasWorkingAbility(:COLORCHANGE) &&
!PBTypes.isPseudoType?(movetype) && !target.pbHasType?(movetype)
PBDebug.log("[Ability triggered] #{target.pbThis}'s Color Change made it #{PBTypes.getName(movetype)}-type")
target.type1=movetype
target.type2=movetype
target.effects[PBEffects::Type3]=-1
@battle.pbDisplay(_INTL("{1}'s {2} made it the {3} type!",target.pbThis,
PBAbilities.getName(target.ability),PBTypes.getName(movetype)))
end
# Berserk
if target.hasWorkingAbility(:BERSERK) &&
target.hp+turneffects[PBEffects::TotalDamage]>(target.totalhp/2).floor &&
target.hp<=(target.totalhp/2).floor
target.pbIncreaseStatWithCause(PBStats::SPATK,1,target,PBAbilities.getName(target.ability))
PBDebug.log("[Ability triggered] #{target.pbThis}'s Berserk")
end
end
# Moxie
if user.hasWorkingAbility(:MOXIE) && target.fainted? &&
[email protected]?(@battle.pbParty(target.index))
if user.pbIncreaseStatWithCause(PBStats::ATTACK,1,user,PBAbilities.getName(user.ability))
PBDebug.log("[Ability triggered] #{user.pbThis}'s Moxie")
end
end
# Stakeout
if user.hasWorkingAbility(:STAKEOUT) && target.effects[PBEffects::Stakeout]
PBDebug.log("[Ability triggered] #{user.pbThis}'s Stakeout worked")
@battle.pbDisplay(_INTL("{1}'s stakeout resulted in a stronger attack!",user.pbThis))
end
# Beast Boost
if self.hasWorkingAbility(:BEASTBOOST) && target.isFainted? &&
[email protected]?(@battle.pbParty(target.index))
if user.attack >= user.defense && user.attack >= user.spatk &&
user.attack >= user.spdef && user.attack >= user.speed
if pbIncreaseStatWithCause(PBStats::ATTACK,1,self,PBAbilities.getName(ability))
PBDebug.log("[Ability triggered] #{pbThis}'s Beast Boost (raising Attack)")
end
elsif user.defense >= user.spatk && user.defense >= user.spdef && user.defense >= user.speed
if pbIncreaseStatWithCause(PBStats::DEFENSE,1,self,PBAbilities.getName(ability))
PBDebug.log("[Ability triggered] #{pbThis}'s Beast Boost (raising Defense)")
end
elsif user.spatk >= user.spdef && user.spatk >= user.speed
if pbIncreaseStatWithCause(PBStats::SPATK,1,self,PBAbilities.getName(ability))
PBDebug.log("[Ability triggered] #{pbThis}'s Beast Boost (raising Special Attack)")
end
elsif user.spdef >= user.speed
if pbIncreaseStatWithCause(PBStats::SPDEF,1,self,PBAbilities.getName(ability))
PBDebug.log("[Ability triggered] #{pbThis}'s Beast Boost (raising Special Defense)")
end
else
if pbIncreaseStatWithCause(PBStats::SPEED,1,self,PBAbilities.getName(ability))
PBDebug.log("[Ability triggered] #{pbThis}'s Beast Boost (raising Speed)")
end
end
end
# Beak Blast
if target.effects[PBEffects::BeakBlast]>0 && thismove.isContactMove?(user)
user.status=PBStatuses::BURN
end
# Magician
if user.hasWorkingAbility(:MAGICIAN)
if target.item>0 && user.item==0 &&
user.effects[PBEffects::Substitute]==0 &&
target.effects[PBEffects::Substitute]==0 &&
!target.hasWorkingAbility(:STICKYHOLD) &&
[email protected](target,target.item) &&
[email protected](user,target.item) &&
(@battle.opponent || [email protected]?(user.index))
user.item=target.item
target.item=0
target.effects[PBEffects::Unburden]=true
if [email protected] && # In a wild battle
user.pokemon.itemInitial==0 &&
target.pokemon.itemInitial==user.item
user.pokemon.itemInitial=user.item
target.pokemon.itemInitial=0
end
@battle.pbDisplay(_INTL("{1} stole {2}'s {3} with {4}!",user.pbThis,
target.pbThis(true),PBItems.getName(user.item),PBAbilities.getName(user.ability)))
PBDebug.log("[Ability triggered] #{user.pbThis}'s Magician stole #{target.pbThis(true)}'s #{PBItems.getName(user.item)}")
end
end
# Pickpocket
if target.hasWorkingAbility(:PICKPOCKET)
if target.item==0 && user.item>0 &&
user.effects[PBEffects::Substitute]==0 &&
target.effects[PBEffects::Substitute]==0 &&
!user.hasWorkingAbility(:STICKYHOLD) &&
[email protected](user,user.item) &&
[email protected](target,user.item) &&
(@battle.opponent || [email protected]?(target.index))
target.item=user.item
user.item=0
user.effects[PBEffects::Unburden]=true
if [email protected] && # In a wild battle
target.pokemon.itemInitial==0 &&
user.pokemon.itemInitial==target.item
target.pokemon.itemInitial=target.item
user.pokemon.itemInitial=0
end
@battle.pbDisplay(_INTL("{1} pickpocketed {2}'s {3}!",target.pbThis,
user.pbThis(true),PBItems.getName(target.item)))
PBDebug.log("[Ability triggered] #{target.pbThis}'s Pickpocket stole #{user.pbThis(true)}'s #{PBItems.getName(target.item)}")
end
end
end
def pbAbilityCureCheck
return if fainted?
case self.status
when PBStatuses::SLEEP
if self.hasWorkingAbility(:VITALSPIRIT) || self.hasWorkingAbility(:INSOMNIA)
PBDebug.log("[Ability triggered] #{pbThis}'s #{PBAbilities.getName(@ability)}")
pbCureStatus(false)
@battle.pbDisplay(_INTL("{1}'s {2} woke it up!",pbThis,PBAbilities.getName(@ability)))
end
when PBStatuses::POISON
if self.hasWorkingAbility(:IMMUNITY)
PBDebug.log("[Ability triggered] #{pbThis}'s #{PBAbilities.getName(@ability)}")
pbCureStatus(false)
@battle.pbDisplay(_INTL("{1}'s {2} cured its poisoning!",pbThis,PBAbilities.getName(@ability)))
end
when PBStatuses::BURN
if self.hasWorkingAbility(:WATERVEIL)
PBDebug.log("[Ability triggered] #{pbThis}'s #{PBAbilities.getName(@ability)}")
pbCureStatus(false)
@battle.pbDisplay(_INTL("{1}'s {2} healed its burn!",pbThis,PBAbilities.getName(@ability)))
end
when PBStatuses::PARALYSIS
if self.hasWorkingAbility(:LIMBER)
PBDebug.log("[Ability triggered] #{pbThis}'s #{PBAbilities.getName(@ability)}")
pbCureStatus(false)
@battle.pbDisplay(_INTL("{1}'s {2} cured its paralysis!",pbThis,PBAbilities.getName(@ability)))
end
when PBStatuses::FROZEN
if self.hasWorkingAbility(:MAGMAARMOR)
PBDebug.log("[Ability triggered] #{pbThis}'s #{PBAbilities.getName(@ability)}")
pbCureStatus(false)
@battle.pbDisplay(_INTL("{1}'s {2} defrosted it!",pbThis,PBAbilities.getName(@ability)))
end
end
if @effects[PBEffects::Confusion]>0 && self.hasWorkingAbility(:OWNTEMPO)
PBDebug.log("[Ability triggered] #{pbThis}'s #{PBAbilities.getName(@ability)} (attract)")
pbCureConfusion(false)
@battle.pbDisplay(_INTL("{1}'s {2} snapped it out of its confusion!",pbThis,PBAbilities.getName(@ability)))
end
if @effects[PBEffects::Attract]>=0 && self.hasWorkingAbility(:OBLIVIOUS)
PBDebug.log("[Ability triggered] #{pbThis}'s #{PBAbilities.getName(@ability)}")
pbCureAttract
@battle.pbDisplay(_INTL("{1}'s {2} cured its infatuation status!",pbThis,PBAbilities.getName(@ability)))
end
if USENEWBATTLEMECHANICS && @effects[PBEffects::Taunt]>0 && self.hasWorkingAbility(:OBLIVIOUS)
PBDebug.log("[Ability triggered] #{pbThis}'s #{PBAbilities.getName(@ability)} (taunt)")
@effects[PBEffects::Taunt]=0
@battle.pbDisplay(_INTL("{1}'s {2} made its taunt wear off!",pbThis,PBAbilities.getName(@ability)))
end
end
################################################################################
# Held item effects
################################################################################
def pbConsumeItem(recycle=true,pickup=true)
itemname=PBItems.getName(self.item)
@pokemon.itemRecycle=self.item if recycle
@pokemon.itemInitial=0 if @pokemon.itemInitial==self.item
if pickup
@effects[PBEffects::PickupItem]=self.item
@effects[PBEffects::PickupUse][email protected]
end
self.item=0
self.effects[PBEffects::Unburden]=true
# Symbiosis
if pbPartner && pbPartner.hasWorkingAbility(:SYMBIOSIS) && recycle
if pbPartner.item>0 &&
[email protected](pbPartner,pbPartner.item) &&
[email protected](self,pbPartner.item)
@battle.pbDisplay(_INTL("{1}'s {2} let it share its {3} with {4}!",
pbPartner.pbThis,PBAbilities.getName(pbPartner.ability),
PBItems.getName(pbPartner.item),pbThis(true)))
self.item=pbPartner.item
pbPartner.item=0
pbPartner.effects[PBEffects::Unburden]=true
pbBerryCureCheck
end
end
end
def pbConfusionBerry(flavor,message1,message2)
return false if @effects[PBEffects::HealBlock]>0
amt=self.pbRecoverHP((self.totalhp/8).floor,true)
if amt>0
@battle.pbDisplay(message1)
if (self.nature%5)==flavor && (self.nature/5).floor!=(self.nature%5)
@battle.pbDisplay(message2)
pbConfuseSelf
end
return true
end
return false
end
def pbStatIncreasingBerry(stat,berryname)
return pbIncreaseStatWithCause(stat,1,self,berryname)
end
def pbActivateBerryEffect(berry=0,consume=true)
berry=self.item if berry==0
berryname=(berry==0) ? "" : PBItems.getName(berry)
PBDebug.log("[Item triggered] #{pbThis}'s #{berryname}")
consumed=false
if isConst?(berry,PBItems,:ORANBERRY)
if @effects[PBEffects::HealBlock]==0
amt=self.pbRecoverHP(10,true)
if amt>0
@battle.pbDisplay(_INTL("{1} restored its health using its {2}!",pbThis,berryname))
consumed=true
end
end
elsif isConst?(berry,PBItems,:SITRUSBERRY) ||
isConst?(berry,PBItems,:ENIGMABERRY)
if @effects[PBEffects::HealBlock]==0
amt=self.pbRecoverHP((self.totalhp/4).floor,true)
if amt>0
@battle.pbDisplay(_INTL("{1} restored its health using its {2}!",pbThis,berryname))
consumed=true
end
end
elsif isConst?(berry,PBItems,:CHESTOBERRY)
if self.status==PBStatuses::SLEEP
pbCureStatus(false)
@battle.pbDisplay(_INTL("{1}'s {2} cured its sleep problem.",pbThis,berryname))
consumed=true
end
elsif isConst?(berry,PBItems,:PECHABERRY)
if self.status==PBStatuses::POISON
pbCureStatus(false)
@battle.pbDisplay(_INTL("{1}'s {2} cured its poisoning.",pbThis,berryname))
consumed=true
end
elsif isConst?(berry,PBItems,:RAWSTBERRY)
if self.status==PBStatuses::BURN
pbCureStatus(false)
@battle.pbDisplay(_INTL("{1}'s {2} healed its burn.",pbThis,berryname))
consumed=true
end
elsif isConst?(berry,PBItems,:CHERIBERRY)
if self.status==PBStatuses::PARALYSIS
pbCureStatus(false)
@battle.pbDisplay(_INTL("{1}'s {2} cured its paralysis.",pbThis,berryname))
consumed=true
end
elsif isConst?(berry,PBItems,:ASPEARBERRY)
if self.status==PBStatuses::FROZEN
pbCureStatus(false)
@battle.pbDisplay(_INTL("{1}'s {2} thawed it out.",pbThis,berryname))
consumed=true
end
elsif isConst?(berry,PBItems,:LEPPABERRY)
found=[]
for i in [email protected]
if @pokemon.moves[i].id!=0
if (consume && @pokemon.moves[i].pp==0) ||
(!consume && @pokemon.moves[i].pp<@pokemon.moves[i].totalpp)
found.push(i)
end
end
end
if found.length>0
choice=(consume) ? found[0] : found[@battle.pbRandom(found.length)]
[email protected][choice]
pokemove.pp+=10
pokemove.pp=pokemove.totalpp if pokemove.pp>pokemove.totalpp
self.moves[choice].pp=pokemove.pp
movename=PBMoves.getName(pokemove.id)
@battle.pbDisplay(_INTL("{1}'s {2} restored {3}'s PP!",pbThis,berryname,movename))
consumed=true
end
elsif isConst?(berry,PBItems,:PERSIMBERRY)
if @effects[PBEffects::Confusion]>0
pbCureConfusion(false)
@battle.pbDisplay(_INTL("{1}'s {2} snapped it out of its confusion!",pbThis,berryname))
consumed=true
end
elsif isConst?(berry,PBItems,:LUMBERRY)
if self.status>0 || @effects[PBEffects::Confusion]>0
st=self.status; conf=(@effects[PBEffects::Confusion]>0)
pbCureStatus(false)
pbCureConfusion(false)
case st
when PBStatuses::SLEEP
@battle.pbDisplay(_INTL("{1}'s {2} woke it up!",pbThis,berryname))
when PBStatuses::POISON
@battle.pbDisplay(_INTL("{1}'s {2} cured its poisoning!",pbThis,berryname))
when PBStatuses::BURN
@battle.pbDisplay(_INTL("{1}'s {2} healed its burn!",pbThis,berryname))
when PBStatuses::PARALYSIS
@battle.pbDisplay(_INTL("{1}'s {2} cured its paralysis!",pbThis,berryname))
when PBStatuses::FROZEN
@battle.pbDisplay(_INTL("{1}'s {2} defrosted it!",pbThis,berryname))
end
if conf
@battle.pbDisplay(_INTL("{1}'s {2} snapped it out of its confusion!",pbThis,berryname))
end
consumed=true
end
elsif isConst?(berry,PBItems,:FIGYBERRY)
consumed=pbConfusionBerry(0,
_INTL("{1}'s {2} restored health!",pbThis,berryname),
_INTL("For {1}, the {2} was too spicy!",pbThis(true),berryname))
elsif isConst?(berry,PBItems,:WIKIBERRY)
consumed=pbConfusionBerry(3,
_INTL("{1}'s {2} restored health!",pbThis,berryname),
_INTL("For {1}, the {2} was too dry!",pbThis(true),berryname))
elsif isConst?(berry,PBItems,:MAGOBERRY)
consumed=pbConfusionBerry(2,
_INTL("{1}'s {2} restored health!",pbThis,berryname),
_INTL("For {1}, the {2} was too sweet!",pbThis(true),berryname))
elsif isConst?(berry,PBItems,:AGUAVBERRY)
consumed=pbConfusionBerry(4,
_INTL("{1}'s {2} restored health!",pbThis,berryname),
_INTL("For {1}, the {2} was too bitter!",pbThis(true),berryname))
elsif isConst?(berry,PBItems,:IAPAPABERRY)
consumed=pbConfusionBerry(1,
_INTL("{1}'s {2} restored health!",pbThis,berryname),
_INTL("For {1}, the {2} was too sour!",pbThis(true),berryname))
elsif isConst?(berry,PBItems,:LIECHIBERRY)
consumed=pbStatIncreasingBerry(PBStats::ATTACK,berryname)
elsif isConst?(berry,PBItems,:GANLONBERRY) ||
isConst?(berry,PBItems,:KEEBERRY)
consumed=pbStatIncreasingBerry(PBStats::DEFENSE,berryname)
elsif isConst?(berry,PBItems,:SALACBERRY)
consumed=pbStatIncreasingBerry(PBStats::SPEED,berryname)
elsif isConst?(berry,PBItems,:PETAYABERRY)
consumed=pbStatIncreasingBerry(PBStats::SPATK,berryname)
elsif isConst?(berry,PBItems,:APICOTBERRY) ||
isConst?(berry,PBItems,:MARANGABERRY)
consumed=pbStatIncreasingBerry(PBStats::SPDEF,berryname)
elsif isConst?(berry,PBItems,:LANSATBERRY)
if @effects[PBEffects::FocusEnergy]<2
@effects[PBEffects::FocusEnergy]=2
@battle.pbDisplay(_INTL("{1} used its {2} to get pumped!",pbThis,berryname))
consumed=true
end
elsif isConst?(berry,PBItems,:MICLEBERRY)
if !@effects[PBEffects::MicleBerry]
@effects[PBEffects::MicleBerry]=true
@battle.pbDisplay(_INTL("{1} boosted the accuracy of its next move using its {2}!",
pbThis,berryname))
consumed=true
end
elsif isConst?(berry,PBItems,:STARFBERRY)
stats=[]
for i in [PBStats::ATTACK,PBStats::DEFENSE,PBStats::SPATK,PBStats::SPDEF,PBStats::SPEED]
stats.push(i) if pbCanIncreaseStatStage?(i,self)
end
if stats.length>0
stat=stats[@battle.pbRandom(stats.length)]
consumed=pbIncreaseStatWithCause(stat,2,self,berryname)
end
end
if consumed
# Cheek Pouch
if hasWorkingAbility(:CHEEKPOUCH) && @effects[PBEffects::HealBlock]==0
amt=self.pbRecoverHP((@totalhp/3).floor,true)
if amt>0
@battle.pbDisplay(_INTL("{1}'s {2} restored its health!",
pbThis,PBAbilities.getName(ability)))
end
end
pbConsumeItem if consume
self.pokemon.belch=true if self.pokemon
end
end
def pbBerryCureCheck(hpcure=false)
return if fainted?
unnerver=(pbOpposing1.hasWorkingAbility(:UNNERVE) ||
pbOpposing2.hasWorkingAbility(:UNNERVE))
itemname=(self.item==0) ? "" : PBItems.getName(self.item)
if hpcure
if self.hasWorkingItem(:BERRYJUICE) && self.hp<=(self.totalhp/2).floor
amt=self.pbRecoverHP(20,true)
if amt>0
@battle.pbCommonAnimation("UseItem",self,nil)
@battle.pbDisplay(_INTL("{1} restored its health using its {2}!",pbThis,itemname))
pbConsumeItem
return
end
end
end
if !unnerver
if hpcure
if self.hp<=(self.totalhp/2).floor
if self.hasWorkingItem(:ORANBERRY) ||
self.hasWorkingItem(:SITRUSBERRY)
pbActivateBerryEffect
return
end
if self.hasWorkingItem(:FIGYBERRY) ||
self.hasWorkingItem(:WIKIBERRY) ||
self.hasWorkingItem(:MAGOBERRY) ||
self.hasWorkingItem(:AGUAVBERRY) ||
self.hasWorkingItem(:IAPAPABERRY)
pbActivateBerryEffect
return
end
end
end
if (self.hasWorkingAbility(:GLUTTONY) && self.hp<=(self.totalhp/2).floor) ||
self.hp<=(self.totalhp/4).floor
if self.hasWorkingItem(:LIECHIBERRY) ||
self.hasWorkingItem(:GANLONBERRY) ||
self.hasWorkingItem(:SALACBERRY) ||
self.hasWorkingItem(:PETAYABERRY) ||
self.hasWorkingItem(:APICOTBERRY)
pbActivateBerryEffect
return
end
if self.hasWorkingItem(:LANSATBERRY) ||
self.hasWorkingItem(:STARFBERRY)
pbActivateBerryEffect
return
end
if self.hasWorkingItem(:MICLEBERRY)
pbActivateBerryEffect
return
end
end
if self.hasWorkingItem(:LEPPABERRY)
pbActivateBerryEffect
return
end
if self.hasWorkingItem(:CHESTOBERRY) ||
self.hasWorkingItem(:PECHABERRY) ||
self.hasWorkingItem(:RAWSTBERRY) ||
self.hasWorkingItem(:CHERIBERRY) ||
self.hasWorkingItem(:ASPEARBERRY) ||
self.hasWorkingItem(:PERSIMBERRY) ||
self.hasWorkingItem(:LUMBERRY)
pbActivateBerryEffect
return
end
if self.hasWorkingItem(:FIGYBERRY) ||
self.hasWorkingItem(:WIKIBERRY) ||
self.hasWorkingItem(:MAGOBERRY) ||
self.hasWorkingItem(:IAPAPABERRY) ||
self.hasWorkingItem(:AGUAVBERRY)
pbActivateBerryEffect
return
end
end
if self.hasWorkingItem(:WHITEHERB)
reducedstats=false
for i in [PBStats::ATTACK,PBStats::DEFENSE,
PBStats::SPEED,PBStats::SPATK,PBStats::SPDEF,
PBStats::ACCURACY,PBStats::EVASION]
if @stages[i]<0
@stages[i]=0; reducedstats=true
end
end
if reducedstats
PBDebug.log("[Item triggered] #{pbThis}'s #{itemname}")
@battle.pbCommonAnimation("UseItem",self,nil)
@battle.pbDisplay(_INTL("{1} restored its status using its {2}!",pbThis,itemname))
pbConsumeItem
return
end
end
if self.hasWorkingItem(:MENTALHERB) &&
(@effects[PBEffects::Attract]>=0 ||
@effects[PBEffects::Taunt]>0 ||
@effects[PBEffects::Encore]>0 ||
@effects[PBEffects::Torment] ||
@effects[PBEffects::Disable]>0 ||
@effects[PBEffects::HealBlock]>0)
PBDebug.log("[Item triggered] #{pbThis}'s #{itemname}")
@battle.pbCommonAnimation("UseItem",self,nil)
@battle.pbDisplay(_INTL("{1} cured its infatuation status using its {2}.",pbThis,itemname)) if @effects[PBEffects::Attract]>=0
@battle.pbDisplay(_INTL("{1}'s taunt wore off!",pbThis)) if @effects[PBEffects::Taunt]>0
@battle.pbDisplay(_INTL("{1}'s encore ended!",pbThis)) if @effects[PBEffects::Encore]>0
@battle.pbDisplay(_INTL("{1}'s torment wore off!",pbThis)) if @effects[PBEffects::Torment]
@battle.pbDisplay(_INTL("{1} is no longer disabled!",pbThis)) if @effects[PBEffects::Disable]>0
@battle.pbDisplay(_INTL("{1}'s Heal Block wore off!",pbThis)) if @effects[PBEffects::HealBlock]>0
self.pbCureAttract
@effects[PBEffects::Taunt]=0
@effects[PBEffects::Encore]=0
@effects[PBEffects::EncoreMove]=0
@effects[PBEffects::EncoreIndex]=0
@effects[PBEffects::Torment]=false
@effects[PBEffects::Disable]=0
@effects[PBEffects::HealBlock]=0
pbConsumeItem
return
end
if hpcure && self.hasWorkingItem(:LEFTOVERS) && self.hp!=self.totalhp &&
@effects[PBEffects::HealBlock]==0
PBDebug.log("[Item triggered] #{pbThis}'s Leftovers")
@battle.pbCommonAnimation("UseItem",self,nil)
pbRecoverHP((self.totalhp/16).floor,true)
@battle.pbDisplay(_INTL("{1} restored a little HP using its {2}!",pbThis,itemname))
end
if hpcure && self.hasWorkingItem(:BLACKSLUDGE)
if pbHasType?(:POISON)
if self.hp!=self.totalhp && @effects[PBEffects::HealBlock]==0
PBDebug.log("[Item triggered] #{pbThis}'s Black Sludge (heal)")
@battle.pbCommonAnimation("UseItem",self,nil)
pbRecoverHP((self.totalhp/16).floor,true)
@battle.pbDisplay(_INTL("{1} restored a little HP using its {2}!",pbThis,itemname))
end
elsif !self.hasWorkingAbility(:MAGICGUARD)
PBDebug.log("[Item triggered] #{pbThis}'s Black Sludge (damage)")
@battle.pbCommonAnimation("UseItem",self,nil)
pbReduceHP((self.totalhp/8).floor,true)
@battle.pbDisplay(_INTL("{1} was hurt by its {2}!",pbThis,itemname))
end
pbFaint if fainted?
end
end
################################################################################
# Move user and targets
################################################################################
def pbEffectsOnMoveEnd(move,user,target,damage)
damage=0 if damage==nil
if damage>0
if !target.damagestate.substitute
if target.hasWorkingAbility(:WIMPOUT) &&
target.hp<target.totalhp/2 && target.hp+damage>target.totalhp/2
PBDebug.log("[#{target.pbThis}'s #{PBAbilities.getName(target.ability)} triggered]")
choices=[]
[email protected](target.index)
for i in 0...party.length
choices[choices.length]=i if @battle.pbCanSwitchLax?(target.index,i,false)
end
if choices.length>0
newpoke=choices[@battle.pbRandom(choices.length)]
target.pbResetForm
@battle.pbReplace(target.index,newpoke,false)
@battle.pbDisplay(_INTL("{1} was dragged out!",target.pbThis))
@battle.pbOnActiveOne(target)
target.pbAbilitiesOnSwitchIn(true)
elsif [email protected]
@battle.decision=3
end
elsif target.hasWorkingAbility(:EMERGENCYEXIT) &&
target.hp<target.totalhp/2 && target.hp+damage>target.totalhp/2
PBDebug.log("[#{target.pbThis}'s #{PBAbilities.getName(target.ability)} triggered]")
choices=[]
[email protected](target.index)
for i in 0...party.length
choices[choices.length]=i if @battle.pbCanSwitchLax?(target.index,i,false)
end
if choices.length>0
newpoke=choices[@battle.pbRandom(choices.length)]
target.pbResetForm
@battle.pbReplace(target.index,newpoke,false)
@battle.pbDisplay(_INTL("{1} was dragged out!",target.pbThis))
@battle.pbOnActiveOne(target)
target.pbAbilitiesOnSwitchIn(true)
elsif [email protected]
@battle.decision=3
end
end
end
end
end
def pbFindUser(choice,targets)
move=choice[2]
target=choice[3]
user=self # Normally, the user is self
# Targets in normal cases
case pbTarget(move)
when PBTargets::SingleNonUser
if target>=0
[email protected][target]
if !pbIsOpposing?(targetBattler.index)
if !pbAddTarget(targets,targetBattler)
pbAddTarget(targets,pbOpposing2) if !pbAddTarget(targets,pbOpposing1)
end
else
pbAddTarget(targets,targetBattler.pbPartner) if !pbAddTarget(targets,targetBattler)
end
else
pbRandomTarget(targets)
end
when PBTargets::SingleOpposing
if target>=0
[email protected][target]
if !pbIsOpposing?(targetBattler.index)
if !pbAddTarget(targets,targetBattler)
pbAddTarget(targets,pbOpposing2) if !pbAddTarget(targets,pbOpposing1)
end
else
pbAddTarget(targets,targetBattler.pbPartner) if !pbAddTarget(targets,targetBattler)
end
else
pbRandomTarget(targets)
end
when PBTargets::OppositeOpposing
pbAddTarget(targets,pbOppositeOpposing) if !pbAddTarget(targets,pbOppositeOpposing2)
when PBTargets::RandomOpposing
pbRandomTarget(targets)
when PBTargets::AllOpposing
# Just pbOpposing1 because partner is determined late
pbAddTarget(targets,pbOpposing2) if !pbAddTarget(targets,pbOpposing1)
when PBTargets::AllNonUsers
for i in 0...4 # not ordered by priority
pbAddTarget(targets,@battle.battlers[i]) if i!=@index
end
when PBTargets::UserOrPartner
if target>=0 # Pre-chosen target
[email protected][target]
pbAddTarget(targets,targetBattler.pbPartner) if !pbAddTarget(targets,targetBattler)
else
pbAddTarget(targets,self)
end
when PBTargets::Partner
pbAddTarget(targets,pbPartner)
else
move.pbAddTarget(targets,self)
end
return user
end
def pbChangeUser(thismove,user)
# Change user to user of Snatch
if thismove.canSnatch?
[email protected]
for i in priority
if i.effects[PBEffects::Snatch]
@battle.pbDisplay(_INTL("{1} snatched {2}'s move!",i.pbThis,user.pbThis(true)))
PBDebug.log("[Lingering effect triggered] #{i.pbThis}'s Snatch made it use #{user.pbThis(true)}'s #{thismove.name}")
i.effects[PBEffects::Snatch]=false
target=user
user=i
# Snatch's PP is reduced if old user has Pressure
[email protected][user.index][1]
if target.hasWorkingAbility(:PRESSURE) && user.pbIsOpposing?(target.index) && userchoice>=0
pressuremove=user.moves[userchoice]
pbSetPP(pressuremove,pressuremove.pp-1) if pressuremove.pp>0
end
break if USENEWBATTLEMECHANICS
end
end
end
return user
end
def pbTarget(move)
target=move.target
if move.function==0x10D && pbHasType?(:GHOST) # Curse
target=PBTargets::OppositeOpposing
end
return target
end
def pbAddTarget(targets,target)
if !target.fainted?
targets[targets.length]=target
return true
end
return false
end
def pbRandomTarget(targets)
choices=[]
pbAddTarget(choices,pbOpposing1)
pbAddTarget(choices,pbOpposing2)
if choices.length>0
pbAddTarget(targets,choices[@battle.pbRandom(choices.length)])
end
end
def pbChangeTarget(thismove,userandtarget,targets)
[email protected]
changeeffect=0
user=userandtarget[0]
target=userandtarget[1]
# Lightningrod
if targets.length==1 && isConst?(thismove.pbType(thismove.type,user,target),PBTypes,:ELECTRIC) &&
!target.hasWorkingAbility(:LIGHTNINGROD)
for i in priority # use Pokémon earliest in priority
next if user.index==i.index || target.index==i.index
if i.hasWorkingAbility(:LIGHTNINGROD)
PBDebug.log("[Ability triggered] #{i.pbThis}'s Lightningrod (change target)")
target=i # X's Lightningrod took the attack!
changeeffect=1
break
end
end
end
# Storm Drain
if targets.length==1 && isConst?(thismove.pbType(thismove.type,user,target),PBTypes,:WATER) &&
!target.hasWorkingAbility(:STORMDRAIN)
for i in priority # use Pokémon earliest in priority
next if user.index==i.index || target.index==i.index
if i.hasWorkingAbility(:STORMDRAIN)
PBDebug.log("[Ability triggered] #{i.pbThis}'s Storm Drain (change target)")
target=i # X's Storm Drain took the attack!
changeeffect=1
break
end
end
end
# Change target to user of Follow Me (overrides Magic Coat
# because check for Magic Coat below uses this target)
if PBTargets.targetsOneOpponent?(thismove)
newtarget=nil; strength=100
for i in priority # use Pokémon latest in priority
next if !user.pbIsOpposing?(i.index)
if !i.fainted? && [email protected] && !i.effects[PBEffects::SkyDrop] &&
i.effects[PBEffects::FollowMe]>0 && i.effects[PBEffects::FollowMe]<strength
PBDebug.log("[Lingering effect triggered] #{i.pbThis}'s Follow Me")
newtarget=i; strength=i.effects[PBEffects::FollowMe]
changeeffect=0
end
end
target=newtarget if newtarget
end
# TODO: Pressure here is incorrect if Magic Coat redirects target
if user.pbIsOpposing?(target.index) && target.hasWorkingAbility(:PRESSURE)
PBDebug.log("[Ability triggered] #{target.pbThis}'s Pressure (in pbChangeTarget)")
user.pbReducePP(thismove) # Reduce PP
end
# Change user to user of Snatch
if thismove.canSnatch?
for i in priority
if i.effects[PBEffects::Snatch]
@battle.pbDisplay(_INTL("{1} Snatched {2}'s move!",i.pbThis,user.pbThis(true)))
PBDebug.log("[Lingering effect triggered] #{i.pbThis}'s Snatch made it use #{user.pbThis(true)}'s #{thismove.name}")
i.effects[PBEffects::Snatch]=false
target=user
user=i
# Snatch's PP is reduced if old user has Pressure
[email protected][user.index][1]
if target.hasWorkingAbility(:PRESSURE) && user.pbIsOpposing?(target.index) && userchoice>=0
PBDebug.log("[Ability triggered] #{target.pbThis}'s Pressure (part of Snatch)")
pressuremove=user.moves[userchoice]
pbSetPP(pressuremove,pressuremove.pp-1) if pressuremove.pp>0
end
end
end
end
if thismove.canMagicCoat?
if target.effects[PBEffects::MagicCoat]
# switch user and target
PBDebug.log("[Lingering effect triggered] #{i.pbThis}'s Magic Coat made it use #{user.pbThis(true)}'s #{thismove.name}")
changeeffect=3
tmp=user
user=target
target=tmp
# Magic Coat's PP is reduced if old user has Pressure
[email protected][user.index][1]
if target.hasWorkingAbility(:PRESSURE) && user.pbIsOpposing?(target.index) && userchoice>=0
PBDebug.log("[Ability triggered] #{target.pbThis}'s Pressure (part of Magic Coat)")
pressuremove=user.moves[userchoice]
pbSetPP(pressuremove,pressuremove.pp-1) if pressuremove.pp>0
end
elsif !user.hasMoldBreaker && target.hasWorkingAbility(:MAGICBOUNCE)
# switch user and target
PBDebug.log("[Ability triggered] #{target.pbThis}'s Magic Bounce made it use #{user.pbThis(true)}'s #{thismove.name}")
changeeffect=3
tmp=user
user=target
target=tmp
end
end
if changeeffect==1
@battle.pbDisplay(_INTL("{1}'s {2} took the move!",target.pbThis,PBAbilities.getName(target.ability)))
elsif changeeffect==3
@battle.pbDisplay(_INTL("{1} bounced the {2} back!",user.pbThis,thismove.name))
end
userandtarget[0]=user
userandtarget[1]=target
if !user.hasMoldBreaker && target.hasWorkingAbility(:SOUNDPROOF) &&
thismove.isSoundBased? &&
thismove.function!=0xE5 && # Perish Song handled elsewhere
thismove.function!=0x151 # Parting Shot handled elsewhere
PBDebug.log("[Ability triggered] #{target.pbThis}'s Soundproof blocked #{user.pbThis(true)}'s #{thismove.name}")
@battle.pbDisplay(_INTL("{1}'s {2} blocks {3}!",target.pbThis,
PBAbilities.getName(target.ability),thismove.name))
return false
end
if !user.hasMoldBreaker && target.hasWorkingAbility(:CACOPHONY) &&
thismove.isSoundBased? &&
thismove.function!=0xE5 && # Perish Song handled elsewhere
thismove.function!=0x151 # Parting Shot handled elsewhere
PBDebug.log("[Ability triggered] #{target.pbThis}'s Soundproof blocked #{user.pbThis(true)}'s #{thismove.name}")
@battle.pbDisplay(_INTL("{1}'s {2} blocks {3}!",target.pbThis,
PBAbilities.getName(target.ability),thismove.name))
return true
end
end
################################################################################
# Move PP
################################################################################
def pbSetPP(move,pp)
move.pp=pp
# Not effects[PBEffects::Mimic], since Mimic can't copy Mimic
if move.thismove && move.id==move.thismove.id && !@effects[PBEffects::Transform]
move.thismove.pp=pp
end
end
def pbReducePP(move)
if @effects[PBEffects::TwoTurnAttack]>0 ||
@effects[PBEffects::Bide]>0 ||
@effects[PBEffects::Outrage]>0 ||
@effects[PBEffects::Rollout]>0 ||
@effects[PBEffects::HyperBeam]>0 ||
@effects[PBEffects::Uproar]>0
# No need to reduce PP if two-turn attack
return true
end
return true if move.pp<0 # No need to reduce PP for special calls of moves
return true if move.totalpp==0 # Infinite PP, can always be used
return false if move.pp==0
if move.pp>0
pbSetPP(move,move.pp-1)
end
return true
end
def pbReducePPOther(move)
pbSetPP(move,move.pp-1) if move.pp>0
end
################################################################################
# Using a move
################################################################################
def pbObedienceCheck?(choice) # Returns true if Pokémon obeys, false if won't
return true if choice[0]!=1
return true if [email protected]
return true if [email protected]?(@index)
disobedient = false
# Pokémon may be disobedient; calculate if it is
badgelevel = 10*(@battle.pbPlayer.numbadges+1)
badgelevel = PBExperience::MAXLEVEL if @battle.pbPlayer.numbadges>=8
move = choice[2]
if @pokemon.isForeign?(@battle.pbPlayer) && @level>badgelevel
a = ((@level+badgelevel)*@battle.pbRandom(256)/256).floor
disobedient |= (a>=badgelevel)
end
if self.respond_to?("pbHyperModeObedience")
disobedient |= !self.pbHyperModeObedience(move)
end
return true if !disobedient
# Pokémon is disobedient; make it do something else
PBDebug.log("[Disobedience] #{pbThis} disobeyed")
@effects[PBEffects::Rage] = false
# Do nothing if using Snore/Sleep Talk
if self.status==PBStatuses::SLEEP && move.pbCanUseWhileAsleep?
@battle.pbDisplay(_INTL("{1} ignored orders and kept sleeping!",pbThis))
return false
end
b = ((@level+badgelevel)*@battle.pbRandom(256)/256).floor
# Use another move
if b<badgelevel
@battle.pbDisplay(_INTL("{1} ignored orders!",pbThis))
return false if [email protected]?(@index)
othermoves = []
for i in 0...4
next if i==choice[1]
othermoves[othermoves.length] = i if @battle.pbCanChooseMove?(@index,i,false)
end
return false if othermoves.length==0 # No other move to use; do nothing
newchoice = othermoves[@battle.pbRandom(othermoves.length)]
choice[1] = newchoice
choice[2] = @moves[newchoice]
choice[3] = -1
return true
end
c = @level-badgelevel
r = @battle.pbRandom(256)
# Fall asleep
if r<c && pbCanSleep?(self,false)
pbSleepSelf
@battle.pbDisplay(_INTL("{1} began to nap!",pbThis))
return false
end
r -= c
# Hurt self in confusion
if r<c && self.status!=PBStatuses::SLEEP
@battle.pbDisplay(_INTL("{1} won't obey! It hurt itself in its confusion!",pbThis))
pbConfusionDamage
return false
end
# Show refusal message and do nothing
case @battle.pbRandom(4)
when 0; @battle.pbDisplay(_INTL("{1} won't obey!",pbThis))
when 1; @battle.pbDisplay(_INTL("{1} turned away!",pbThis))
when 2; @battle.pbDisplay(_INTL("{1} is loafing around!",pbThis))
when 3; @battle.pbDisplay(_INTL("{1} pretended not to notice!",pbThis))
end
return false
end
def pbSuccessCheck(thismove,user,target,turneffects,accuracy=true)
if (target.hasWorkingAbility(:DAZZLING) ||
target.hasWorkingAbility(:QUEENLYMAJESTY)) && thismove.priority>0 &&
!thismove.doesIgnoreDazzling? && !user.hasMoldBreaker
thismove.pp -=1
PBDebug.log("#{target.pbThis}'s #{PBAbilities.getName(target)} prevented #{user.pbThis}'s priority move")
@battle.pbDisplay(_INTL("{1} cannot use {2} due to {3}!",
user.pbThis,
PBMoves.getName(thismove),
PBAbilities.getName(target.ability)))
return false
end
if @battle.field.effects[PBEffects::PsychicTerrain]>0 && thismove.priority>0 &&
!user.isAirborne?(false) && !thismove.doesIgnoreDazzling?
PBDebug.log("Psychic Terrain prevented #{user.pbThis}'s priority move")
@battle.pbDisplay(_INTL("The psychic terrain prevented the use of priority moves!"))
return false
end
if user.effects[PBEffects::TwoTurnAttack]>0
return true
end
# TODO: "Before Protect" applies to Counter/Mirror Coat
if thismove.function==0xDE && # Dream Eater
target.status!=PBStatuses::SLEEP && (!target.hasWorkingAbility(:COMATOSE) || !isConst?(target.species,PBSpecies,:KOMALA))
@battle.pbDisplay(_INTL("{1} wasn't affected!",target.pbThis))
PBDebug.log("[Move failed] #{user.pbThis}'s Dream Eater's target isn't asleep")
return false
end
if thismove.function==0x113 && user.effects[PBEffects::Stockpile]==0 # Spit Up
@battle.pbDisplay(_INTL("But it failed to spit up a thing!"))
PBDebug.log("[Move failed] #{user.pbThis}'s Spit Up did nothing as Stockpile's count is 0")
return false
end
if target.effects[PBEffects::Protect] && thismove.canProtectAgainst? &&
!target.effects[PBEffects::ProtectNegation]
@battle.pbDisplay(_INTL("{1} protected itself!",target.pbThis))
@battle.successStates[user.index].protected=true
PBDebug.log("[Move failed] #{target.pbThis}'s Protect stopped the attack")
return false
end
p=thismove.priority
if USENEWBATTLEMECHANICS
p+=1 if user.hasWorkingAbility(:PRANKSTER) && thismove.pbIsStatus?
p+=1 if user.hasWorkingAbility(:GALEWINGS) && isConst?(thismove.type,PBTypes,:FLYING)
p+=3 if user.hasWorkingAbility(:TRIAGE) && thismove.isHealingMove? &&
!isConst?(thismove.id,PBMoves,:AQUARING) &&
!isConst?(thismove.id,PBMoves,:GRASSYTERRAIN) &&
!isConst?(thismove.id,PBMoves,:INGRAIN) &&
!isConst?(thismove.id,PBMoves,:LEECHSEED) &&
!isConst?(thismove.id,PBMoves,:PAINSPLIT) &&
!isConst?(thismove.id,PBMoves,:PRESENT) &&
!isConst?(thismove.id,PBMoves,:POLLENPUFF)
end
if target.pbOwnSide.effects[PBEffects::QuickGuard] && thismove.canProtectAgainst? &&
p>0 && !target.effects[PBEffects::ProtectNegation]
@battle.pbDisplay(_INTL("{1} was protected by Quick Guard!",target.pbThis))
PBDebug.log("[Move failed] The opposing side's Quick Guard stopped the attack")
return false
end
if @battle.field.effects[PBEffects::PsychicTerrain]>0 && p>0 && !target.isAirborne?
@battle.pbDisplay(_INTL("The Psychic Terrain protected {1}!",target.pbThis))
PBDebug.log("[Move failed] Psychic Terrain stopped the attack")
return false
end
if target.pbOwnSide.effects[PBEffects::WideGuard] &&
PBTargets.hasMultipleTargets?(thismove) && !thismove.pbIsStatus? &&
!target.effects[PBEffects::ProtectNegation]
@battle.pbDisplay(_INTL("{1} was protected by Wide Guard!",target.pbThis))
PBDebug.log("[Move failed] The opposing side's Wide Guard stopped the attack")
return false
end
if target.pbOwnSide.effects[PBEffects::CraftyShield] && thismove.pbIsStatus? &&
thismove.function!=0xE5 # Perish Song
@battle.pbDisplay(_INTL("Crafty Shield protected {1}!",target.pbThis(true)))
PBDebug.log("[Move failed] The opposing side's Crafty Shield stopped the attack")
return false
end
if target.pbOwnSide.effects[PBEffects::MatBlock] && !thismove.pbIsStatus? &&
thismove.canProtectAgainst? && !target.effects[PBEffects::ProtectNegation]
@battle.pbDisplay(_INTL("{1} was blocked by the kicked-up mat!",thismove.name))
PBDebug.log("[Move failed] The opposing side's Mat Block stopped the attack")
return false
end
# TODO: Mind Reader/Lock-On
# --Sketch/FutureSight/PsychUp work even on Fly/Bounce/Dive/Dig
if thismove.pbMoveFailed(user,target) # TODO: Applies to Snore/Fake Out
@battle.pbDisplay(_INTL("But it failed!"))
PBDebug.log(sprintf("[Move failed] Failed pbMoveFailed (function code %02X)",thismove.function))
return false
end
# King's Shield (purposely after pbMoveFailed)
if target.effects[PBEffects::KingsShield] && !thismove.pbIsStatus? &&
thismove.canProtectAgainst? && !target.effects[PBEffects::ProtectNegation]
@battle.pbDisplay(_INTL("{1} protected itself!",target.pbThis))
@battle.successStates[user.index].protected=true
PBDebug.log("[Move failed] #{target.pbThis}'s King's Shield stopped the attack")
if thismove.isContactMove?(user)
user.pbReduceStat(PBStats::ATTACK,2,nil,false)
end
return false
end
# Spiky Shield
if target.effects[PBEffects::SpikyShield] && thismove.canProtectAgainst? &&
!target.effects[PBEffects::ProtectNegation]
@battle.pbDisplay(_INTL("{1} protected itself!",target.pbThis))
@battle.successStates[user.index].protected=true
PBDebug.log("[Move failed] #{user.pbThis}'s Spiky Shield stopped the attack")
if thismove.isContactMove?(user) && !user.fainted?
@battle.scene.pbDamageAnimation(user,0)
amt=user.pbReduceHP((user.totalhp/8).floor)
@battle.pbDisplay(_INTL("{1} was hurt!",user.pbThis)) if amt>0
end
return false
end
# Baneful Bunker
if target.effects[PBEffects::BanefulBunker] && thismove.canProtectAgainst? &&
!target.effects[PBEffects::ProtectNegation]
@battle.pbDisplay(_INTL("{1} protected itself!",target.pbThis))
@battle.successStates[user.index].protected=true
PBDebug.log("[Move failed] #{user.pbThis}'s Baneful Bunker stopped the attack!")
if thismove.isContactMove?(user) && !user.isFainted? && user.pbCanPoison?(nil,false)
PBDebug.log("#{target.pbThis} poisoned by Baneful Bunker")
user.pbPoison(target,_INTL("{1} was poisoned!",target.pbThis))
end
return false
end
# Immunity to powder-based moves
if USENEWBATTLEMECHANICS && thismove.isPowderMove? &&
(target.pbHasType?(:GRASS) ||
(!user.hasMoldBreaker && target.hasWorkingAbility(:OVERCOAT)) ||
target.hasWorkingItem(:SAFETYGOGGLES))
@battle.pbDisplay(_INTL("It doesn't affect\r\n{1}...",target.pbThis(true)))
PBDebug.log("[Move failed] #{target.pbThis} is immune to powder-based moves somehow")
return false
end
if thismove.basedamage>0 && thismove.function!=0x02 && # Struggle
thismove.function!=0x111 # Future Sight
type=thismove.pbType(thismove.type,user,target)
typemod=thismove.pbTypeModifier(type,user,target)
# Airborne-based immunity to Ground moves
if isConst?(type,PBTypes,:GROUND) && target.isAirborne?(user.hasMoldBreaker) &&
!target.hasWorkingItem(:RINGTARGET) && thismove.function!=0x11C # Smack Down
if !user.hasMoldBreaker && target.hasWorkingAbility(:LEVITATE)
@battle.pbDisplay(_INTL("{1} makes Ground moves miss with Levitate!",target.pbThis))
PBDebug.log("[Ability triggered] #{target.pbThis}'s Levitate made the Ground-type move miss")
return false
end
if target.hasWorkingItem(:AIRBALLOON)
@battle.pbDisplay(_INTL("{1}'s Air Balloon makes Ground moves miss!",target.pbThis))
PBDebug.log("[Item triggered] #{target.pbThis}'s Air Balloon made the Ground-type move miss")
return false
end
if target.effects[PBEffects::MagnetRise]>0
@battle.pbDisplay(_INTL("{1} makes Ground moves miss with Magnet Rise!",target.pbThis))
PBDebug.log("[Lingering effect triggered] #{target.pbThis}'s Magnet Rise made the Ground-type move miss")
return false
end
if target.effects[PBEffects::Telekinesis]>0
@battle.pbDisplay(_INTL("{1} makes Ground moves miss with Telekinesis!",target.pbThis))
PBDebug.log("[Lingering effect triggered] #{target.pbThis}'s Telekinesis made the Ground-type move miss")
return false
end
end
if !user.hasMoldBreaker && target.hasWorkingAbility(:WONDERGUARD) &&
type>=0 && typemod<=8
@battle.pbDisplay(_INTL("{1} avoided damage with Wonder Guard!",target.pbThis))
PBDebug.log("[Ability triggered] #{target.pbThis}'s Wonder Guard")
return false
end
if typemod==0
@battle.pbDisplay(_INTL("It doesn't affect\r\n{1}...",target.pbThis(true)))
PBDebug.log("[Move failed] Type immunity")
return false
end
end
if accuracy
if target.effects[PBEffects::LockOn]>0 && target.effects[PBEffects::LockOnPos]==user.index
PBDebug.log("[Lingering effect triggered] #{target.pbThis}'s Lock-On")
return true
end
miss=false; override=false
invulmove=PBMoveData.new(target.effects[PBEffects::TwoTurnAttack]).function
case invulmove
when 0xC9, 0xCC # Fly, Bounce
miss=true unless thismove.function==0x08 || # Thunder
thismove.function==0x15 || # Hurricane
thismove.function==0x77 || # Gust
thismove.function==0x78 || # Twister
thismove.function==0x11B || # Sky Uppercut
thismove.function==0x11C || # Smack Down
isConst?(thismove.id,PBMoves,:WHIRLWIND)
when 0xCA # Dig
miss=true unless thismove.function==0x76 || # Earthquake
thismove.function==0x95 # Magnitude
when 0xCB # Dive
miss=true unless thismove.function==0x75 || # Surf
thismove.function==0xD0 # Whirlpool
when 0xCD # Shadow Force
miss=true
when 0xCE # Sky Drop
miss=true unless thismove.function==0x08 || # Thunder
thismove.function==0x15 || # Hurricane
thismove.function==0x77 || # Gust
thismove.function==0x78 || # Twister
thismove.function==0x11B || # Sky Uppercut
thismove.function==0x11C # Smack Down
when 0x14D # Phantom Force
miss=true
end
if target.effects[PBEffects::SkyDrop]
miss=true unless thismove.function==0x08 || # Thunder
thismove.function==0x15 || # Hurricane
thismove.function==0x77 || # Gust
thismove.function==0x78 || # Twister
thismove.function==0xCE || # Sky Drop
thismove.function==0x11B || # Sky Uppercut
thismove.function==0x11C # Smack Down
end
miss=false if user.hasWorkingAbility(:NOGUARD) ||
target.hasWorkingAbility(:NOGUARD) ||
@battle.futuresight
override=true if USENEWBATTLEMECHANICS && thismove.function==0x06 && # Toxic
thismove.basedamage==0 && user.pbHasType?(:POISON)
override=true if !miss && turneffects[PBEffects::SkipAccuracyCheck] # Called by another move
if !override && (miss || !thismove.pbAccuracyCheck(user,target)) # Includes Counter/Mirror Coat
PBDebug.log(sprintf("[Move failed] Failed pbAccuracyCheck (function code %02X) or target is semi-invulnerable",thismove.function))
if thismove.target==PBTargets::AllOpposing &&
(!user.pbOpposing1.fainted? ? 1 : 0) + (!user.pbOpposing2.fainted? ? 1 : 0) > 1
@battle.pbDisplay(_INTL("{1} avoided the attack!",target.pbThis))
elsif thismove.target==PBTargets::AllNonUsers &&
(!user.pbOpposing1.fainted? ? 1 : 0) + (!user.pbOpposing2.fainted? ? 1 : 0) + (!user.pbPartner.fainted? ? 1 : 0) > 1
@battle.pbDisplay(_INTL("{1} avoided the attack!",target.pbThis))
elsif target.effects[PBEffects::TwoTurnAttack]>0
@battle.pbDisplay(_INTL("{1} avoided the attack!",target.pbThis))
elsif thismove.function==0xDC # Leech Seed
@battle.pbDisplay(_INTL("{1} evaded the attack!",target.pbThis))
else
@battle.pbDisplay(_INTL("{1}'s attack missed!",user.pbThis))
end
return false
end
end
return true
end
def pbTryUseMove(choice,thismove,turneffects)
return true if turneffects[PBEffects::PassedTrying]
# TODO: Return true if attack has been Mirror Coated once already
if @effects[PBEffects::SkyDrop] # Intentionally no message here
PBDebug.log("[Move failed] #{pbThis} can't use #{thismove.name} because of being Sky Dropped")
return false
end
if @battle.field.effects[PBEffects::Gravity]>0 && thismove.unusableInGravity?
@battle.pbDisplay(_INTL("{1} can't use {2} because of gravity!",pbThis,thismove.name))
PBDebug.log("[Move failed] #{pbThis} can't use #{thismove.name} because of Gravity")
return false
end
if @effects[PBEffects::Taunt]>0 && thismove.basedamage==0
@battle.pbDisplay(_INTL("{1} can't use {2} after the taunt!",pbThis,thismove.name))
PBDebug.log("[Move failed] #{pbThis} can't use #{thismove.name} because of Taunt")
return false
end
if @effects[PBEffects::HealBlock]>0 && thismove.isHealingMove?
@battle.pbDisplay(_INTL("{1} can't use {2} because of Heal Block!",pbThis,thismove.name))
PBDebug.log("[Move failed] #{pbThis} can't use #{thismove.name} because of Heal Block")
return false
end
if @effects[PBEffects::Torment] && thismove.id==@lastMoveUsed &&
[email protected] && @effects[PBEffects::TwoTurnAttack]==0
@battle.pbDisplayPaused(_INTL("{1} can't use the same move in a row due to the torment!",pbThis))
PBDebug.log("[Move failed] #{pbThis} can't use #{thismove.name} because of Torment")
return false
end
if pbOpposing1.effects[PBEffects::Imprison] && !pbOpposing1.fainted?
if thismove.id==pbOpposing1.moves[0].id ||
thismove.id==pbOpposing1.moves[1].id ||
thismove.id==pbOpposing1.moves[2].id ||
thismove.id==pbOpposing1.moves[3].id
@battle.pbDisplay(_INTL("{1} can't use the sealed {2}!",pbThis,thismove.name))
PBDebug.log("[Move failed] #{thismove.name} can't use #{thismove.name} because of #{pbOpposing1.pbThis(true)}'s Imprison")
return false
end
end
if pbOpposing2.effects[PBEffects::Imprison] && !pbOpposing2.fainted?
if thismove.id==pbOpposing2.moves[0].id ||
thismove.id==pbOpposing2.moves[1].id ||
thismove.id==pbOpposing2.moves[2].id ||
thismove.id==pbOpposing2.moves[3].id
@battle.pbDisplay(_INTL("{1} can't use the sealed {2}!",pbThis,thismove.name))
PBDebug.log("[Move failed] #{thismove.name} can't use #{thismove.name} because of #{pbOpposing2.pbThis(true)}'s Imprison")
return false
end
end
if @effects[PBEffects::Disable]>0 && thismove.id==@effects[PBEffects::DisableMove] &&
[email protected] # Pursuit ignores if it's disabled
@battle.pbDisplayPaused(_INTL("{1}'s {2} is disabled!",pbThis,thismove.name))
PBDebug.log("[Move failed] #{pbThis}'s #{thismove.name} is disabled")
return false
end
if choice[1]==-2 # Battle Palace
@battle.pbDisplay(_INTL("{1} appears incapable of using its power!",pbThis))
PBDebug.log("[Move failed] Battle Palace: #{pbThis} is incapable of using its power")
return false
end
if @effects[PBEffects::HyperBeam]>0
@battle.pbDisplay(_INTL("{1} must recharge!",pbThis))
PBDebug.log("[Move failed] #{pbThis} must recharge after using #{PokeBattle_Move.pbFromPBMove(@battle,PBMove.new(@currentMove)).name}")
return false
end
if self.hasWorkingAbility(:TRUANT) && @effects[PBEffects::Truant]
@battle.pbDisplay(_INTL("{1} is loafing around!",pbThis))
PBDebug.log("[Ability triggered] #{pbThis}'s Truant")
return false
end
if !turneffects[PBEffects::SkipAccuracyCheck]
if self.status==PBStatuses::SLEEP
self.statusCount-=1
if self.statusCount<=0
self.pbCureStatus
else
self.pbContinueStatus
PBDebug.log("[Status] #{pbThis} remained asleep (count: #{self.statusCount})")
if !thismove.pbCanUseWhileAsleep? # Snore/Sleep Talk/Outrage
PBDebug.log("[Move failed] #{pbThis} couldn't use #{thismove.name} while asleep")
return false
end
end
end
end
if self.status==PBStatuses::FROZEN
if thismove.canThawUser?
PBDebug.log("[Move effect triggered] #{pbThis} was defrosted by using #{thismove.name}")
self.pbCureStatus(false)
@battle.pbDisplay(_INTL("{1} melted the ice!",pbThis))
pbCheckForm
elsif @battle.pbRandom(10)<2 && !turneffects[PBEffects::SkipAccuracyCheck]
self.pbCureStatus
pbCheckForm
elsif !thismove.canThawUser?
self.pbContinueStatus
PBDebug.log("[Status] #{pbThis} remained frozen and couldn't move")
return false
end
end
if !turneffects[PBEffects::SkipAccuracyCheck]
if @effects[PBEffects::Confusion]>0
@effects[PBEffects::Confusion]-=1
if @effects[PBEffects::Confusion]<=0
pbCureConfusion
else
pbContinueConfusion
PBDebug.log("[Status] #{pbThis} remained confused (count: #{@effects[PBEffects::Confusion]})")
if @battle.pbRandom(2)==0
pbConfusionDamage
@battle.pbDisplay(_INTL("It hurt itself in its confusion!"))
PBDebug.log("[Status] #{pbThis} hurt itself in its confusion and couldn't move")
return false
end
end
end
end
if @effects[PBEffects::Flinch]
@effects[PBEffects::Flinch]=false
@battle.pbDisplay(_INTL("{1} flinched and couldn't move!",self.pbThis))
PBDebug.log("[Lingering effect triggered] #{pbThis} flinched")
if self.hasWorkingAbility(:STEADFAST)
if pbIncreaseStatWithCause(PBStats::SPEED,1,self,PBAbilities.getName(self.ability))
PBDebug.log("[Ability triggered] #{pbThis}'s Steadfast")
end
end
return false
end
if !turneffects[PBEffects::SkipAccuracyCheck]
if @effects[PBEffects::Attract]>=0
pbAnnounceAttract(@battle.battlers[@effects[PBEffects::Attract]])
if @battle.pbRandom(2)==0
pbContinueAttract
PBDebug.log("[Lingering effect triggered] #{pbThis} was infatuated and couldn't move")
return false
end
end
if self.status==PBStatuses::PARALYSIS
if @battle.pbRandom(4)==0
pbContinueStatus
PBDebug.log("[Status] #{pbThis} was fully paralysed and couldn't move")
return false
end
end
end
if !turneffects[PBEffects::SkipAccuracyCheck]
return false if !pbObedienceCheck?(choice)
end
turneffects[PBEffects::PassedTrying]=true
return true
end
def pbConfusionDamage
self.damagestate.reset
confmove=PokeBattle_Confusion.new(@battle,nil)
confmove.pbEffect(self,self)
pbFaint if fainted?
end
def pbUpdateTargetedMove(thismove,user)
# TODO: Snatch, moves that use other moves
# TODO: All targeting cases
# Two-turn attacks, Magic Coat, Future Sight, Counter/MirrorCoat/Bide handled
end
def pbProcessMoveAgainstTarget(thismove,user,target,numhits,turneffects,nocheck=false,alltargets=nil,showanimation=true,dancercheck=false)
realnumhits=0
totaldamage=0
destinybond=false
for i in 0...numhits
target.damagestate.reset
# Check success (accuracy/evasion calculation)
if !nocheck &&
!pbSuccessCheck(thismove,user,target,turneffects,i==0 || thismove.successCheckPerHit?)
if thismove.function==0xBF && realnumhits>0 # Triple Kick
break # Considered a success if Triple Kick hits at least once
elsif thismove.function==0x10B # Hi Jump Kick, Jump Kick
if !user.hasWorkingAbility(:MAGICGUARD)
PBDebug.log("[Move effect triggered] #{user.pbThis} took crash damage")
# TODO: Not shown if message is "It doesn't affect XXX..."
@battle.pbDisplay(_INTL("{1} kept going and crashed!",user.pbThis))
damage=(user.totalhp/2).floor
if damage>0
@battle.scene.pbDamageAnimation(user,0)
user.pbReduceHP(damage)
end
user.pbFaint if user.fainted?
end
end
user.effects[PBEffects::Outrage]=0 if thismove.function==0xD2 # Outrage
user.effects[PBEffects::Rollout]=0 if thismove.function==0xD3 # Rollout
user.effects[PBEffects::FuryCutter]=0 if thismove.function==0x91 # Fury Cutter
user.effects[PBEffects::Stockpile]=0 if thismove.function==0x113 # Spit Up
user.effects[PBEffects::StompingTantrum]=true
return
end
# Add to counters for moves which increase them when used in succession
if thismove.function==0x91 # Fury Cutter
user.effects[PBEffects::FuryCutter]+=1 if user.effects[PBEffects::FuryCutter]<4
else
user.effects[PBEffects::FuryCutter]=0
end
if thismove.function==0x92 # Echoed Voice
if !user.pbOwnSide.effects[PBEffects::EchoedVoiceUsed] &&
user.pbOwnSide.effects[PBEffects::EchoedVoiceCounter]<5
user.pbOwnSide.effects[PBEffects::EchoedVoiceCounter]+=1
end
user.pbOwnSide.effects[PBEffects::EchoedVoiceUsed]=true
end
# Count a hit for Parental Bond if it applies
user.effects[PBEffects::ParentalBond]-=1 if user.effects[PBEffects::ParentalBond]>0
# This hit will happen; count it
realnumhits+=1
# Damage calculation and/or main effect
damage=thismove.pbEffect(user,target,i,alltargets,showanimation) # Recoil/drain, etc. are applied here
totaldamage+=damage if damage>0
# Message and consume for type-weakening berries
if target.damagestate.berryweakened
@battle.pbDisplay(_INTL("The {1} weakened the damage to {2}!",
PBItems.getName(target.item),target.pbThis(true)))
target.pbConsumeItem
end
# Illusion
if target.effects[PBEffects::Illusion] && target.hasWorkingAbility(:ILLUSION) &&
damage>0 && !target.damagestate.substitute
PBDebug.log("[Ability triggered] #{target.pbThis}'s Illusion ended")
target.effects[PBEffects::Illusion]=nil
@battle.scene.pbChangePokemon(target,target.pokemon)
@battle.pbDisplay(_INTL("{1}'s {2} wore off!",target.pbThis,
PBAbilities.getName(target.ability)))
end
# Tangling Hair
if target.hasWorkingAbility(:TANGLINGHAIR) && thismove.isContactMove?(user) &&
!target.damagestate.substitute
if user.pbReduceStatWithCause(PBStats::SPEED,1,user,PBAbilities.getName(target.ability))
PBDebug.log("[Ability triggered] #{target.pbThis}'s Tangling Hair was activated")
end
end
# Stamina
if target.hasWorkingAbility(:STAMINA) && damage>0 && !target.damagestate.substitute
if target.pbIncreaseStatWithCause(PBStats::DEFENSE,1,target,PBAbilities.getName(target.ability))
PBDebug.log("[Ability triggered] #{target.pbThis}'s Stamina was activated")
end
end
# Disguise
if target.hasWorkingAbility(:DISGUISE) &&
isConst?(target.species,PBSpecies,:MIMIKYU) && target.form==0 &&
thismove.pbIsDamaging? && !target.damagestate.substitute &&
!user.hasMoldBreaker #&& !thismove.doesBypassIgnorableAbilities?
PBDebug.log("[Ability triggered] #{target.pbThis}'s Disguise ended")
@battle.pbDisplay(_INTL("Its disguise served it as a decoy!"))
target.form=1
target.pbUpdate(true)
@battle.scene.pbChangePokemon(target,target.pokemon)
@battle.pbDisplay(_INTL("{1}'s disguise was busted!",target.pbThis))
if target.hasWorkingItem(:AIRBALLOON,true)
PBDebug.log("[Item triggered] #{target.pbThis}'s Air Balloon popped")
@battle.pbDisplay(_INTL("{1}'s Air Balloon popped!",target.pbThis))
target.pbConsumeItem(true,false)
end
end
user.pbFaint if user.fainted? # no return
if numhits>1 && target.damagestate.calcdamage<=0
user.effects[PBEffects::StompingTantrum]=true
return
end
@battle.pbJudgeCheckpoint(user,thismove)
# Additional effect
if target.damagestate.calcdamage>0 &&
!user.hasWorkingAbility(:SHEERFORCE) &&
(user.hasMoldBreaker || !target.hasWorkingAbility(:SHIELDDUST))
addleffect=thismove.addlEffect
addleffect*=2 if (user.hasWorkingAbility(:SERENEGRACE) ||
user.pbOwnSide.effects[PBEffects::Rainbow]>0) &&
thismove.function!=0xA4 # Secret Power
addleffect=100 if $DEBUG && Input.press?(Input::CTRL)
if @battle.pbRandom(100)<addleffect
PBDebug.log("[Move effect triggered] #{thismove.name}'s added effect")
thismove.pbAdditionalEffect(user,target)
end
end
# Ability effects
pbEffectsOnDealingDamage(thismove,user,target,damage)
# Grudge
if !user.fainted? && target.fainted?
if target.effects[PBEffects::Grudge] && target.pbIsOpposing?(user.index)
thismove.pp=0
@battle.pbDisplay(_INTL("{1}'s {2} lost all its PP due to the grudge!",
user.pbThis,thismove.name))
PBDebug.log("[Lingering effect triggered] #{target.pbThis}'s Grudge made #{thismove.name} lose all its PP")
end
end
if target.fainted?
destinybond=destinybond || target.effects[PBEffects::DestinyBond]
end
user.pbFaint if user.fainted? # no return
break if user.fainted?
break if target.fainted?
# Make the target flinch
if target.damagestate.calcdamage>0 && !target.damagestate.substitute
if user.hasMoldBreaker || !target.hasWorkingAbility(:SHIELDDUST)
canflinch=false
if (user.hasWorkingItem(:KINGSROCK) || user.hasWorkingItem(:RAZORFANG)) &&
thismove.canKingsRock?
canflinch=true
end
if user.hasWorkingAbility(:STENCH) &&
thismove.function!=0x09 && # Thunder Fang
thismove.function!=0x0B && # Fire Fang
thismove.function!=0x0E && # Ice Fang
thismove.function!=0x0F && # flinch-inducing moves
thismove.function!=0x10 && # Stomp
thismove.function!=0x11 && # Snore
thismove.function!=0x12 && # Fake Out
thismove.function!=0x78 && # Twister
thismove.function!=0xC7 # Sky Attack
canflinch=true
end
if canflinch && @battle.pbRandom(10)==0
PBDebug.log("[Item/ability triggered] #{user.pbThis}'s King's Rock/Razor Fang or Stench")
target.pbFlinch(user)
end
end
end
if target.damagestate.calcdamage>0 && !target.fainted?
# Defrost
if target.status==PBStatuses::FROZEN &&
(isConst?(thismove.pbType(thismove.type,user,target),PBTypes,:FIRE) ||
(USENEWBATTLEMECHANICS && isConst?(thismove.id,PBMoves,:SCALD)))
target.pbCureStatus
end
# Rage
if target.effects[PBEffects::Rage] && target.pbIsOpposing?(user.index)
# TODO: Apparently triggers if opposing Pokémon uses Future Sight after a Future Sight attack
if target.pbIncreaseStatWithCause(PBStats::ATTACK,1,target,"",true,false)
PBDebug.log("[Lingering effect triggered] #{target.pbThis}'s Rage")
@battle.pbDisplay(_INTL("{1}'s rage is building!",target.pbThis))
end
end
end
target.pbFaint if target.fainted? # no return
user.pbFaint if user.fainted? # no return
break if user.fainted? || target.fainted?
# Dancer using damaging moves
if thismove.isDanceMove? && !dancercheck
if @battle.doublebattle
for k in @battle.pbPriority(true)
if k!=user && !k.fainted?
if !k.effects[PBEffects::Dancer] &&
k.hasWorkingAbility(:DANCER)
@battle.battlers[user.index].effects[PBEffects::Dancer]=true
if k==user.pbPartner
if !target.fainted?
if target==user.pbPartner
if !user.pbOpposing1.fainted?
@battle.pbDisplay(_INTL("{1} also dances!",k.pbThis))
k.effects[PBEffects::Dancer]=true
pbProcessMoveAgainstTarget(thismove,k,user.pbOpposing1,numhits,turneffects,nocheck,alltargets,showanimation,true)
elsif !user.pbOpposing2.fainted?
@battle.pbDisplay(_INTL("{1} also dances!",k.pbThis))
k.effects[PBEffects::Dancer]=true
pbProcessMoveAgainstTarget(thismove,k,user.pbOpposing2,numhits,turneffects,nocheck,alltargets,showanimation,true)
elsif !user.fainted?
@battle.pbDisplay(_INTL("{1} wants to dance, but will not attack its ally!",user.pbPartner.pbThis))
else
@battle.pbDisplay(_INTL("What a pity! {1} wanted to dance...",user.pbPartner.pbThis))
end
else
@battle.pbDisplay(_INTL("{1} also dances!",k.pbThis))
k.effects[PBEffects::Dancer]=true
pbProcessMoveAgainstTarget(thismove,k,target,numhits,turneffects,nocheck,alltargets,showanimation,true)
end
elsif !target.pbPartner.fainted?
@battle.pbDisplay(_INTL("{1} also dances!",k.pbThis))
k.effects[PBEffects::Dancer]=true
pbProcessMoveAgainstTarget(thismove,k,target.pbPartner,numhits,turneffects,nocheck,alltargets,showanimation,true)
elsif !user.fainted?
@battle.pbDisplay(_INTL("{1} wants to dance, but will not attack its ally!",user.pbPartner.pbThis))
else
@battle.pbDisplay(_INTL("What a pity! {1} wanted to dance...",user.pbPartner.pbThis))
end
elsif k==user.pbOpposing1
if !user.fainted?
@battle.pbDisplay(_INTL("{1} also dances!",k.pbThis))
k.effects[PBEffects::Dancer]=true
pbProcessMoveAgainstTarget(thismove,k,user,numhits,turneffects,nocheck,alltargets,showanimation,true)
elsif !user.pbPartner.fainted?
@battle.pbDisplay(_INTL("{1} also dances!",k.pbThis))
k.effects[PBEffects::Dancer]=true
pbProcessMoveAgainstTarget(thismove,k,user.pbPartner,numhits,turneffects,nocheck,alltargets,showanimation,true)
elsif !user.pbOpposing2.fainted?
@battle.pbDisplay(_INTL("{1} wants to dance, but will not attack its ally!",user.pbOpposing1.pbThis))
else
@battle.pbDisplay(_INTL("What a pity! {1} wanted to dance...",user.pbOpposing1.pbThis))
end
elsif k==user.pbOpposing2
if !user.fainted?
@battle.pbDisplay(_INTL("{1} also dances!",k.pbThis))
k.effects[PBEffects::Dancer]=true
pbProcessMoveAgainstTarget(thismove,k,user,numhits,turneffects,nocheck,alltargets,showanimation,true)
elsif !user.pbPartner.fainted?
@battle.pbDisplay(_INTL("{1} also dances!",k.pbThis))
k.effects[PBEffects::Dancer]=true
pbProcessMoveAgainstTarget(thismove,k,user.pbPartner,numhits,turneffects,nocheck,alltargets,showanimation,true)
elsif !user.pbOpposing1.fainted?
@battle.pbDisplay(_INTL("{1} wants to dance, but will not attack its ally!",user.pbOpposing1.pbThis))
else
@battle.pbDisplay(_INTL("What a pity! {1} wanted to dance...",user.pbOpposing2.pbThis))
end
end
end
end
end
elsif target.hasWorkingAbility(:DANCER) && !target.fainted? && !user.fainted?
@battle.pbDisplay(_INTL("{1} also dances!",target.pbThis))
pbProcessMoveAgainstTarget(thismove,target,user,numhits,turneffects,nocheck,alltargets,showanimation,true)
elsif target.hasWorkingAbility(:DANCER) && !target.fainted? && user.fainted?
@battle.pbDisplay(_INTL("What a pity! {1} wanted to dance...",target.pbThis))
end
end
pbEffectsOnMoveEnd(thismove,user,target,damage)
# Berry check (maybe just called by ability effect, since only necessary Berries are checked)
for j in 0...4
@battle.battlers[j].pbBerryCureCheck
end
break if user.fainted? || target.fainted?
target.pbUpdateTargetedMove(thismove,user)
break if target.damagestate.calcdamage<=0
end
turneffects[PBEffects::TotalDamage]+=totaldamage if totaldamage>0
# Battle Arena only - attack is successful
@battle.successStates[user.index].useState=2
@battle.successStates[user.index].typemod=target.damagestate.typemod
# Type effectiveness
if numhits>1
if target.damagestate.typemod>8
if alltargets.length>1
@battle.pbDisplay(_INTL("It's super effective on {1}!",target.pbThis(true)))
else
@battle.pbDisplay(_INTL("It's super effective!"))
end
elsif target.damagestate.typemod>=1 && target.damagestate.typemod<8
if alltargets.length>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
if realnumhits==1
@battle.pbDisplay(_INTL("Hit {1} time!",realnumhits))
else
@battle.pbDisplay(_INTL("Hit {1} times!",realnumhits))
end
end
PBDebug.log("Move did #{numhits} hit(s), total damage=#{turneffects[PBEffects::TotalDamage]}")
# Faint if 0 HP
target.pbFaint if target.fainted? # no return
user.pbFaint if user.fainted? # no return
thismove.pbEffectAfterHit(user,target,turneffects)
target.pbFaint if target.fainted? # no return
user.pbFaint if user.fainted? # no return
# Destiny Bond
if !user.fainted? && target.fainted?
if destinybond && target.pbIsOpposing?(user.index)
PBDebug.log("[Lingering effect triggered] #{target.pbThis}'s Destiny Bond")
@battle.pbDisplay(_INTL("{1} took its attacker down with it!",target.pbThis))
user.pbReduceHP(user.hp)
user.pbFaint # no return
@battle.pbJudgeCheckpoint(user)
end
end
pbEffectsAfterHit(user,target,thismove,turneffects)
# Berry check
for j in 0...4
@battle.battlers[j].pbBerryCureCheck
end
target.pbUpdateTargetedMove(thismove,user)
end
def pbUseMoveSimple(moveid,index=-1,target=-1)
choice=[]
choice[0]=1 # "Use move"
choice[1]=index # Index of move to be used in user's moveset
choice[2]=PokeBattle_Move.pbFromPBMove(@battle,PBMove.new(moveid)) # PokeBattle_Move object of the move
choice[2].pp=-1
choice[3]=target # Target (-1 means no target yet)
if index>=0
@battle.choices[@index][1]=index
end
PBDebug.log("#{pbThis} used simple move #{choice[2].name}")
pbUseMove(choice,true)
return
end
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
# Photon Geyser, Moongeist Beam and Sunsteel Strike effect on
if (isConst?(species,PBSpecies,:SOLGALEO) &&
isConst?(thismove.id,PBMoves,:SUNSTEELSTRIKE) ||
isConst?(species,PBSpecies,:LUNALA) &&
isConst?(thismove.id,PBMoves,:MOONGEISTBEAM) ||
isConst?(species,PBSpecies,:NECROZMA) &&
isConst?(thismove.id,PBMoves,:PHOTONGEYSER))
if (hasWorkingAbility(:PRESSURE) ||
hasWorkingAbility(:SHADOWSHIELD) ||
hasWorkingAbility(:PRISMARMOR))
effects[PBEffects::GastroAcid]=false
elsif hasWorkingAbility(:INTIMIDATE)
effects[PBEffects::GastroAcid]=true
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
effects[PBEffects::BeakBlast]=0 # Stops Beak Blast burn effect if active
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)
}
# Dancer using non-damaging move
if thismove.isDanceMove?
for s in @battle.pbPriority(true)
if s!=user &&
s.hasWorkingAbility(:DANCER) &&
!s.fainted?
@battle.pbDisplay(_INTL("{1} also dances!",s.pbThis))
PBDebug.logonerr{
thismove.pbEffect(s,nil)
}
end
end
end
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].pbResetForm
@battle.pbRecallAndReplace(i,newpoke,newpokename,false,user.hasMoldBreaker)
@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
def pbCancelMoves
# If failed pbTryUseMove or have already used Pursuit to chase a switching foe
# Cancel multi-turn attacks (note: Hyper Beam effect is not canceled here)
@effects[PBEffects::TwoTurnAttack]=0 if @effects[PBEffects::TwoTurnAttack]>0
@effects[PBEffects::Outrage]=0
@effects[PBEffects::Rollout]=0
@effects[PBEffects::Uproar]=0
@effects[PBEffects::Bide]=0
@currentMove=0
# Reset counters for moves which increase them when used in succession
@effects[PBEffects::FuryCutter]=0
PBDebug.log("Cancelled using the move")
end
user.effects[PBEffects::StompingTantrum]=false
################################################################################
# Turn processing
################################################################################
def pbBeginTurn(choice)
# Cancel some lingering effects which only apply until the user next moves
@effects[PBEffects::DestinyBond]=false
@effects[PBEffects::Grudge]=false
@effects[PBEffects::Dancer]=false
# Reset Parental Bond's count
@effects[PBEffects::ParentalBond]=0
# Encore's effect ends if the encored move is no longer available
if @effects[PBEffects::Encore]>0 &&
@moves[@effects[PBEffects::EncoreIndex]].id!=@effects[PBEffects::EncoreMove]
PBDebug.log("Resetting Encore effect")
@effects[PBEffects::Encore]=0
@effects[PBEffects::EncoreIndex]=0
@effects[PBEffects::EncoreMove]=0
end
# Wake up in an uproar
if self.status==PBStatuses::SLEEP && !self.hasWorkingAbility(:SOUNDPROOF)
for i in 0...4
if @battle.battlers[i].effects[PBEffects::Uproar]>0
pbCureStatus(false)
@battle.pbDisplay(_INTL("{1} woke up in the uproar!",pbThis))
end
end
end
if self.status==PBStatuses::SLEEP && !self.hasWorkingAbility(:CACOPHONY)
for i in 0...4
if @battle.battlers[i].effects[PBEffects::Uproar]>0
pbCureStatus(false)
@battle.pbDisplay(_INTL("{1} woke up in the uproar!",pbThis))
end
end
end
end
def pbEndTurn(choice)
# True end(?)
if @effects[PBEffects::ChoiceBand]<0 && @lastMoveUsed>=0 && !fainted? &&
(self.hasWorkingItem(:CHOICEBAND) ||
self.hasWorkingItem(:CHOICESPECS) ||
self.hasWorkingItem(:CHOICESCARF))
@effects[PBEffects::ChoiceBand]=@lastMoveUsed
end
@battle.pbPrimordialWeather
for i in 0...4
@battle.battlers[i].pbBerryCureCheck
end
for i in 0...4
@battle.battlers[i].pbAbilityCureCheck
end
for i in 0...4
@battle.battlers[i].pbAbilitiesOnSwitchIn(false)
end
for i in 0...4
@battle.battlers[i].pbCheckForm
@battle.battlers[i].effects[PBEffects::Dancer]=false
end
# Photon Geyser, Moongeist Beam and Sunsteel Strike effect off
if (isConst?(species,PBSpecies,:SOLGALEO) || isConst?(species,PBSpecies,:LUNALA) ||
isConst?(species,PBSpecies,:NECROZMA))
effects[PBEffects::GastroAcid]=false
end
#
end
def pbProcessTurn(choice)
# Can't use a move if fainted
return false if fainted?
# Wild roaming Pokémon always flee if possible
if [email protected] && @battle.pbIsOpposing?(self.index) &&
@battle.rules["alwaysflee"] && @battle.pbCanRun?(self.index)
pbBeginTurn(choice)
@battle.pbDisplay(_INTL("{1} fled!",self.pbThis))
@battle.decision=3
pbEndTurn(choice)
PBDebug.log("[Escape] #{pbThis} fled")
return true
end
# If this battler's action for this round wasn't "use a move"
if choice[0]!=1
# Clean up effects that end at battler's turn
pbBeginTurn(choice)
pbEndTurn(choice)
return false
end
# Turn is skipped if Pursuit was used during switch
if @effects[PBEffects::Pursuit]
@effects[PBEffects::Pursuit]=false
pbCancelMoves
pbEndTurn(choice)
@battle.pbJudge # @battle.pbSwitch
return false
end
# Use the move
#@battle.pbDisplayPaused("Before: [#{@lastMoveUsedSketch},#{@lastMoveUsed}]")
PBDebug.log("#{pbThis} used #{choice[2].name}")
PBDebug.logonerr{
pbUseMove(choice,choice[2][email protected])
}
#@battle.pbDisplayPaused("After: [#{@lastMoveUsedSketch},#{@lastMoveUsed}]")
return true
end
end
Btw, anyone that can tell me how to put Ruby codes in PokéCommunity posts?