Files
infinitefusion-e18/Data/Scripts/011_Battle/001_Battle/011_Battle_EndOfRoundPhase.rb
2021-12-23 00:27:17 +00:00

685 lines
30 KiB
Ruby

class Battle
#=============================================================================
# Decrement effect counters
#=============================================================================
def pbEORCountDownBattlerEffect(priority, effect)
priority.each do |b|
next if b.fainted? || b.effects[effect] == 0
b.effects[effect] -= 1
yield b if block_given? && b.effects[effect] == 0
end
end
def pbEORCountDownSideEffect(side, effect, msg)
if @sides[side].effects[effect] > 0
@sides[side].effects[effect] -= 1
pbDisplay(msg) if @sides[side].effects[effect] == 0
end
end
def pbEORCountDownFieldEffect(effect, msg)
if @field.effects[effect] > 0
@field.effects[effect] -= 1
if @field.effects[effect] == 0
pbDisplay(msg)
if effect == PBEffects::MagicRoom
pbPriority(true).each { |b| b.pbItemTerrainStatBoostCheck }
end
end
end
end
#=============================================================================
# End Of Round weather
#=============================================================================
def pbEORWeather(priority)
# NOTE: Primordial weather doesn't need to be checked here, because if it
# could wear off here, it will have worn off already.
# Count down weather duration
@field.weatherDuration -= 1 if @field.weatherDuration > 0
# Weather wears off
if @field.weatherDuration == 0
case @field.weather
when :Sun then pbDisplay(_INTL("The sunlight faded."))
when :Rain then pbDisplay(_INTL("The rain stopped."))
when :Sandstorm then pbDisplay(_INTL("The sandstorm subsided."))
when :Hail then pbDisplay(_INTL("The hail stopped."))
when :ShadowSky then pbDisplay(_INTL("The shadow sky faded."))
end
@field.weather = :None
# Check for form changes caused by the weather changing
allBattlers.each { |b| b.pbCheckFormOnWeatherChange }
# Start up the default weather
pbStartWeather(nil, @field.defaultWeather) if @field.defaultWeather != :None
return if @field.weather == :None
end
# Weather continues
weather_data = GameData::BattleWeather.try_get(@field.weather)
pbCommonAnimation(weather_data.animation) if weather_data
case @field.weather
# when :Sun then pbDisplay(_INTL("The sunlight is strong."))
# when :Rain then pbDisplay(_INTL("Rain continues to fall."))
when :Sandstorm then pbDisplay(_INTL("The sandstorm is raging."))
when :Hail then pbDisplay(_INTL("The hail is crashing down."))
# when :HarshSun then pbDisplay(_INTL("The sunlight is extremely harsh."))
# when :HeavyRain then pbDisplay(_INTL("It is raining heavily."))
# when :StrongWinds then pbDisplay(_INTL("The wind is strong."))
when :ShadowSky then pbDisplay(_INTL("The shadow sky continues."))
end
# Effects due to weather
priority.each do |b|
# Weather-related abilities
if b.abilityActive?
Battle::AbilityEffects.triggerEndOfRoundWeather(b.ability, b.effectiveWeather, b, self)
b.pbFaint if b.fainted?
end
# Weather damage
case b.effectiveWeather
when :Sandstorm
next if !b.takesSandstormDamage?
pbDisplay(_INTL("{1} is buffeted by the sandstorm!", b.pbThis))
@scene.pbDamageAnimation(b)
b.pbReduceHP(b.totalhp / 16, false)
b.pbItemHPHealCheck
b.pbFaint if b.fainted?
when :Hail
next if !b.takesHailDamage?
pbDisplay(_INTL("{1} is buffeted by the hail!", b.pbThis))
@scene.pbDamageAnimation(b)
b.pbReduceHP(b.totalhp / 16, false)
b.pbItemHPHealCheck
b.pbFaint if b.fainted?
when :ShadowSky
next if !b.takesShadowSkyDamage?
pbDisplay(_INTL("{1} is hurt by the shadow sky!", b.pbThis))
@scene.pbDamageAnimation(b)
b.pbReduceHP(b.totalhp / 16, false)
b.pbItemHPHealCheck
b.pbFaint if b.fainted?
end
end
end
#=============================================================================
# End Of Round terrain
#=============================================================================
def pbEORTerrain
# Count down terrain duration
@field.terrainDuration -= 1 if @field.terrainDuration > 0
# Terrain wears off
if @field.terrain != :None && @field.terrainDuration == 0
case @field.terrain
when :Electric
pbDisplay(_INTL("The electric current disappeared from the battlefield!"))
when :Grassy
pbDisplay(_INTL("The grass disappeared from the battlefield!"))
when :Misty
pbDisplay(_INTL("The mist disappeared from the battlefield!"))
when :Psychic
pbDisplay(_INTL("The weirdness disappeared from the battlefield!"))
end
@field.terrain = :None
allBattlers.each { |b| b.pbAbilityOnTerrainChange }
# Start up the default terrain
if @field.defaultTerrain != :None
pbStartTerrain(nil, @field.defaultTerrain, false)
allBattlers.each { |b| b.pbAbilityOnTerrainChange }
allBattlers.each { |b| b.pbItemTerrainStatBoostCheck }
end
return if @field.terrain == :None
end
# Terrain continues
terrain_data = GameData::BattleTerrain.try_get(@field.terrain)
pbCommonAnimation(terrain_data.animation) if terrain_data
case @field.terrain
when :Electric then pbDisplay(_INTL("An electric current is running across the battlefield."))
when :Grassy then pbDisplay(_INTL("Grass is covering the battlefield."))
when :Misty then pbDisplay(_INTL("Mist is swirling about the battlefield."))
when :Psychic then pbDisplay(_INTL("The battlefield is weird."))
end
end
#=============================================================================
# End Of Round shift distant battlers to middle positions
#=============================================================================
def pbEORShiftDistantBattlers
# Move battlers around if none are near to each other
# NOTE: This code assumes each side has a maximum of 3 battlers on it, and
# is not generalised to larger side sizes.
if !singleBattle?
swaps = [] # Each element is an array of two battler indices to swap
2.times do |side|
next if pbSideSize(side) == 1 # Only battlers on sides of size 2+ need to move
# Check if any battler on this side is near any battler on the other side
anyNear = false
allSameSideBattlers(side).each do |b|
anyNear = allOtherSideBattlers(b).any? { |otherB| nearBattlers?(otherB.index, b.index) }
break if anyNear
end
break if anyNear
# No battlers on this side are near any battlers on the other side; try
# to move them
# NOTE: If we get to here (assuming both sides are of size 3 or less),
# there is definitely only 1 able battler on this side, so we
# don't need to worry about multiple battlers trying to move into
# the same position. If you add support for a side of size 4+,
# this code will need revising to account for that, as well as to
# add more complex code to ensure battlers will end up near each
# other.
allSameSideBattlers(side).each do |b|
# Get the position to move to
pos = -1
case pbSideSize(side)
when 2 then pos = [2, 3, 0, 1][b.index] # The unoccupied position
when 3 then pos = (side == 0) ? 2 : 3 # The centre position
end
next if pos < 0
# Can't move if the same trainer doesn't control both positions
idxOwner = pbGetOwnerIndexFromBattlerIndex(b.index)
next if pbGetOwnerIndexFromBattlerIndex(pos) != idxOwner
swaps.push([b.index, pos])
end
end
# Move battlers around
swaps.each do |pair|
next if pbSideSize(pair[0]) == 2 && swaps.length > 1
next if !pbSwapBattlers(pair[0], pair[1])
case pbSideSize(side)
when 2
pbDisplay(_INTL("{1} moved across!", @battlers[pair[1]].pbThis))
when 3
pbDisplay(_INTL("{1} moved to the center!", @battlers[pair[1]].pbThis))
end
end
end
end
#=============================================================================
# End Of Round phase
#=============================================================================
def pbEndOfRoundPhase
PBDebug.log("")
PBDebug.log("[End of round]")
@endOfRound = true
@scene.pbBeginEndOfRoundPhase
pbCalculatePriority # recalculate speeds
priority = pbPriority(true) # in order of fastest -> slowest speeds only
# Weather
pbEORWeather(priority)
# Future Sight/Doom Desire
@positions.each_with_index do |pos, idxPos|
next if !pos || pos.effects[PBEffects::FutureSightCounter] == 0
pos.effects[PBEffects::FutureSightCounter] -= 1
next if pos.effects[PBEffects::FutureSightCounter] > 0
next if !@battlers[idxPos] || @battlers[idxPos].fainted? # No target
moveUser = nil
allBattlers.each do |b|
next if b.opposes?(pos.effects[PBEffects::FutureSightUserIndex])
next if b.pokemonIndex != pos.effects[PBEffects::FutureSightUserPartyIndex]
moveUser = b
break
end
next if moveUser && moveUser.index == idxPos # Target is the user
if !moveUser # User isn't in battle, get it from the party
party = pbParty(pos.effects[PBEffects::FutureSightUserIndex])
pkmn = party[pos.effects[PBEffects::FutureSightUserPartyIndex]]
if pkmn&.able?
moveUser = Battler.new(self, pos.effects[PBEffects::FutureSightUserIndex])
moveUser.pbInitDummyPokemon(pkmn, pos.effects[PBEffects::FutureSightUserPartyIndex])
end
end
next if !moveUser # User is fainted
move = pos.effects[PBEffects::FutureSightMove]
pbDisplay(_INTL("{1} took the {2} attack!", @battlers[idxPos].pbThis,
GameData::Move.get(move).name))
# NOTE: Future Sight failing against the target here doesn't count towards
# Stomping Tantrum.
userLastMoveFailed = moveUser.lastMoveFailed
@futureSight = true
moveUser.pbUseMoveSimple(move, idxPos)
@futureSight = false
moveUser.lastMoveFailed = userLastMoveFailed
@battlers[idxPos].pbFaint if @battlers[idxPos].fainted?
pos.effects[PBEffects::FutureSightCounter] = 0
pos.effects[PBEffects::FutureSightMove] = nil
pos.effects[PBEffects::FutureSightUserIndex] = -1
pos.effects[PBEffects::FutureSightUserPartyIndex] = -1
end
# Wish
@positions.each_with_index do |pos, idxPos|
next if !pos || pos.effects[PBEffects::Wish] == 0
pos.effects[PBEffects::Wish] -= 1
next if pos.effects[PBEffects::Wish] > 0
next if !@battlers[idxPos] || !@battlers[idxPos].canHeal?
wishMaker = pbThisEx(idxPos, pos.effects[PBEffects::WishMaker])
@battlers[idxPos].pbRecoverHP(pos.effects[PBEffects::WishAmount])
pbDisplay(_INTL("{1}'s wish came true!", wishMaker))
end
# Sea of Fire damage (Fire Pledge + Grass Pledge combination)
2.times do |side|
next if sides[side].effects[PBEffects::SeaOfFire] == 0
@battle.pbCommonAnimation("SeaOfFire") if side == 0
@battle.pbCommonAnimation("SeaOfFireOpp") if side == 1
priority.each do |b|
next if b.opposes?(side)
next if !b.takesIndirectDamage? || b.pbHasType?(:FIRE)
@scene.pbDamageAnimation(b)
b.pbTakeEffectDamage(b.totalhp / 8, false) { |hp_lost|
pbDisplay(_INTL("{1} is hurt by the sea of fire!", b.pbThis))
}
end
end
# Status-curing effects/abilities and HP-healing items
priority.each do |b|
next if b.fainted?
# Grassy Terrain (healing)
if @field.terrain == :Grassy && b.affectedByTerrain? && b.canHeal?
PBDebug.log("[Lingering effect] Grassy Terrain heals #{b.pbThis(true)}")
b.pbRecoverHP(b.totalhp / 16)
pbDisplay(_INTL("{1}'s HP was restored.", b.pbThis))
end
# Healer, Hydration, Shed Skin
Battle::AbilityEffects.triggerEndOfRoundHealing(b.ability, b, self) if b.abilityActive?
# Black Sludge, Leftovers
Battle::ItemEffects.triggerEndOfRoundHealing(b.item, b, self) if b.itemActive?
end
# Self-curing of status due to affection
if Settings::AFFECTION_EFFECTS && @internalBattle
priority.each do |b|
next if b.fainted? || b.status == :NONE
next if !b.pbOwnedByPlayer? || b.affection_level < 4 || b.mega?
next if pbRandom(100) < 80
old_status = b.status
b.pbCureStatus(false)
case old_status
when :SLEEP
pbDisplay(_INTL("{1} shook itself awake so you wouldn't worry!", b.pbThis))
when :POISON
pbDisplay(_INTL("{1} managed to expel the poison so you wouldn't worry!", b.pbThis))
when :BURN
pbDisplay(_INTL("{1} healed its burn with its sheer determination so you wouldn't worry!", b.pbThis))
when :PARALYSIS
pbDisplay(_INTL("{1} gathered all its energy to break through its paralysis so you wouldn't worry!", b.pbThis))
when :FROZEN
pbDisplay(_INTL("{1} melted the ice with its fiery determination so you wouldn't worry!", b.pbThis))
end
end
end
# Aqua Ring
priority.each do |b|
next if !b.effects[PBEffects::AquaRing]
next if !b.canHeal?
hpGain = b.totalhp / 16
hpGain = (hpGain * 1.3).floor if b.hasActiveItem?(:BIGROOT)
b.pbRecoverHP(hpGain)
pbDisplay(_INTL("Aqua Ring restored {1}'s HP!", b.pbThis(true)))
end
# Ingrain
priority.each do |b|
next if !b.effects[PBEffects::Ingrain]
next if !b.canHeal?
hpGain = b.totalhp / 16
hpGain = (hpGain * 1.3).floor if b.hasActiveItem?(:BIGROOT)
b.pbRecoverHP(hpGain)
pbDisplay(_INTL("{1} absorbed nutrients with its roots!", b.pbThis))
end
# Leech Seed
priority.each do |b|
next if b.effects[PBEffects::LeechSeed] < 0
next if !b.takesIndirectDamage?
recipient = @battlers[b.effects[PBEffects::LeechSeed]]
next if !recipient || recipient.fainted?
pbCommonAnimation("LeechSeed", recipient, b)
b.pbTakeEffectDamage(b.totalhp / 8) { |hp_lost|
recipient.pbRecoverHPFromDrain(hp_lost, b,
_INTL("{1}'s health is sapped by Leech Seed!", b.pbThis))
recipient.pbAbilitiesOnDamageTaken
}
recipient.pbFaint if recipient.fainted?
end
# Damage from Hyper Mode (Shadow Pokémon)
priority.each do |b|
next if !b.inHyperMode? || @choices[b.index][0] != :UseMove
hpLoss = b.totalhp / 24
@scene.pbDamageAnimation(b)
b.pbReduceHP(hpLoss, false)
pbDisplay(_INTL("The Hyper Mode attack hurts {1}!", b.pbThis(true)))
b.pbFaint if b.fainted?
end
# Damage from poisoning
priority.each do |b|
next if b.fainted?
next if b.status != :POISON
if b.statusCount > 0
b.effects[PBEffects::Toxic] += 1
b.effects[PBEffects::Toxic] = 16 if b.effects[PBEffects::Toxic] > 16
end
if b.hasActiveAbility?(:POISONHEAL)
if b.canHeal?
anim_name = GameData::Status.get(:POISON).animation
pbCommonAnimation(anim_name, b) if anim_name
pbShowAbilitySplash(b)
b.pbRecoverHP(b.totalhp / 8)
if Scene::USE_ABILITY_SPLASH
pbDisplay(_INTL("{1}'s HP was restored.", b.pbThis))
else
pbDisplay(_INTL("{1}'s {2} restored its HP.", b.pbThis, b.abilityName))
end
pbHideAbilitySplash(b)
end
elsif b.takesIndirectDamage?
b.droppedBelowHalfHP = false
dmg = (b.statusCount == 0) ? b.totalhp / 8 : b.totalhp * b.effects[PBEffects::Toxic] / 16
b.pbContinueStatus { b.pbReduceHP(dmg, false) }
b.pbItemHPHealCheck
b.pbAbilitiesOnDamageTaken
b.pbFaint if b.fainted?
b.droppedBelowHalfHP = false
end
end
# Damage from burn
priority.each do |b|
next if b.status != :BURN || !b.takesIndirectDamage?
b.droppedBelowHalfHP = false
dmg = (Settings::MECHANICS_GENERATION >= 7) ? b.totalhp / 16 : b.totalhp / 8
dmg = (dmg / 2.0).round if b.hasActiveAbility?(:HEATPROOF)
b.pbContinueStatus { b.pbReduceHP(dmg, false) }
b.pbItemHPHealCheck
b.pbAbilitiesOnDamageTaken
b.pbFaint if b.fainted?
b.droppedBelowHalfHP = false
end
# Damage from sleep (Nightmare)
priority.each do |b|
b.effects[PBEffects::Nightmare] = false if !b.asleep?
next if !b.effects[PBEffects::Nightmare] || !b.takesIndirectDamage?
b.pbTakeEffectDamage(b.totalhp / 4) { |hp_lost|
pbDisplay(_INTL("{1} is locked in a nightmare!", b.pbThis))
}
end
# Curse
priority.each do |b|
next if !b.effects[PBEffects::Curse] || !b.takesIndirectDamage?
b.pbTakeEffectDamage(b.totalhp / 4) { |hp_lost|
pbDisplay(_INTL("{1} is afflicted by the curse!", b.pbThis))
}
end
# Trapping attacks (Bind/Clamp/Fire Spin/Magma Storm/Sand Tomb/Whirlpool/Wrap)
priority.each do |b|
next if b.fainted? || b.effects[PBEffects::Trapping] == 0
b.effects[PBEffects::Trapping] -= 1
moveName = GameData::Move.get(b.effects[PBEffects::TrappingMove]).name
if b.effects[PBEffects::Trapping] == 0
pbDisplay(_INTL("{1} was freed from {2}!", b.pbThis, moveName))
else
case b.effects[PBEffects::TrappingMove]
when :BIND then pbCommonAnimation("Bind", b)
when :CLAMP then pbCommonAnimation("Clamp", b)
when :FIRESPIN then pbCommonAnimation("FireSpin", b)
when :MAGMASTORM then pbCommonAnimation("MagmaStorm", b)
when :SANDTOMB then pbCommonAnimation("SandTomb", b)
when :WRAP then pbCommonAnimation("Wrap", b)
when :INFESTATION then pbCommonAnimation("Infestation", b)
else pbCommonAnimation("Wrap", b)
end
if b.takesIndirectDamage?
hpLoss = (Settings::MECHANICS_GENERATION >= 6) ? b.totalhp / 8 : b.totalhp / 16
if @battlers[b.effects[PBEffects::TrappingUser]].hasActiveItem?(:BINDINGBAND)
hpLoss = (Settings::MECHANICS_GENERATION >= 6) ? b.totalhp / 6 : b.totalhp / 8
end
@scene.pbDamageAnimation(b)
b.pbTakeEffectDamage(hpLoss, false) { |hp_lost|
pbDisplay(_INTL("{1} is hurt by {2}!", b.pbThis, moveName))
}
end
end
end
# Octolock
priority.each do |b|
next if b.fainted? || b.effects[PBEffects::Octolock] < 0
pbCommonAnimation("Octolock", b)
b.pbLowerStatStage(:DEFENSE, 1, nil) if b.pbCanLowerStatStage?(:DEFENSE)
b.pbLowerStatStage(:SPECIAL_DEFENSE, 1, nil) if b.pbCanLowerStatStage?(:SPECIAL_DEFENSE)
b.pbItemOnStatDropped
end
# Taunt
pbEORCountDownBattlerEffect(priority, PBEffects::Taunt) { |battler|
pbDisplay(_INTL("{1}'s taunt wore off!", battler.pbThis))
}
# Encore
priority.each do |b|
next if b.fainted? || b.effects[PBEffects::Encore] == 0
idxEncoreMove = b.pbEncoredMoveIndex
if idxEncoreMove >= 0
b.effects[PBEffects::Encore] -= 1
if b.effects[PBEffects::Encore] == 0 || b.moves[idxEncoreMove].pp == 0
b.effects[PBEffects::Encore] = 0
pbDisplay(_INTL("{1}'s encore ended!", b.pbThis))
end
else
PBDebug.log("[End of effect] #{b.pbThis}'s encore ended (encored move no longer known)")
b.effects[PBEffects::Encore] = 0
b.effects[PBEffects::EncoreMove] = nil
end
end
# Disable/Cursed Body
pbEORCountDownBattlerEffect(priority, PBEffects::Disable) { |battler|
battler.effects[PBEffects::DisableMove] = nil
pbDisplay(_INTL("{1} is no longer disabled!", battler.pbThis))
}
# Magnet Rise
pbEORCountDownBattlerEffect(priority, PBEffects::MagnetRise) { |battler|
pbDisplay(_INTL("{1}'s electromagnetism wore off!", battler.pbThis))
}
# Telekinesis
pbEORCountDownBattlerEffect(priority, PBEffects::Telekinesis) { |battler|
pbDisplay(_INTL("{1} was freed from the telekinesis!", battler.pbThis))
}
# Heal Block
pbEORCountDownBattlerEffect(priority, PBEffects::HealBlock) { |battler|
pbDisplay(_INTL("{1}'s Heal Block wore off!", battler.pbThis))
}
# Embargo
pbEORCountDownBattlerEffect(priority, PBEffects::Embargo) { |battler|
pbDisplay(_INTL("{1} can use items again!", battler.pbThis))
battler.pbItemTerrainStatBoostCheck
}
# Yawn
pbEORCountDownBattlerEffect(priority, PBEffects::Yawn) { |battler|
if battler.pbCanSleepYawn?
PBDebug.log("[Lingering effect] #{battler.pbThis} fell asleep because of Yawn")
battler.pbSleep
end
}
# Perish Song
perishSongUsers = []
priority.each do |b|
next if b.fainted? || b.effects[PBEffects::PerishSong] == 0
b.effects[PBEffects::PerishSong] -= 1
pbDisplay(_INTL("{1}'s perish count fell to {2}!", b.pbThis, b.effects[PBEffects::PerishSong]))
if b.effects[PBEffects::PerishSong] == 0
perishSongUsers.push(b.effects[PBEffects::PerishSongUser])
b.pbReduceHP(b.hp)
end
b.pbItemHPHealCheck
b.pbFaint if b.fainted?
end
# Judge if all remaining Pokemon fainted by a Perish Song triggered by a single side
if perishSongUsers.length > 0 &&
((perishSongUsers.find_all { |idxBattler| opposes?(idxBattler) }.length == perishSongUsers.length) ||
(perishSongUsers.find_all { |idxBattler| !opposes?(idxBattler) }.length == perishSongUsers.length))
pbJudgeCheckpoint(@battlers[perishSongUsers[0]])
end
# Check for end of battle
if @decision > 0
pbGainExp
return
end
2.times do |side|
# Reflect
pbEORCountDownSideEffect(side, PBEffects::Reflect,
_INTL("{1}'s Reflect wore off!", @battlers[side].pbTeam))
# Light Screen
pbEORCountDownSideEffect(side, PBEffects::LightScreen,
_INTL("{1}'s Light Screen wore off!", @battlers[side].pbTeam))
# Safeguard
pbEORCountDownSideEffect(side, PBEffects::Safeguard,
_INTL("{1} is no longer protected by Safeguard!", @battlers[side].pbTeam))
# Mist
pbEORCountDownSideEffect(side, PBEffects::Mist,
_INTL("{1} is no longer protected by mist!", @battlers[side].pbTeam))
# Tailwind
pbEORCountDownSideEffect(side, PBEffects::Tailwind,
_INTL("{1}'s Tailwind petered out!", @battlers[side].pbTeam))
# Lucky Chant
pbEORCountDownSideEffect(side, PBEffects::LuckyChant,
_INTL("{1}'s Lucky Chant wore off!", @battlers[side].pbTeam))
# Pledge Rainbow
pbEORCountDownSideEffect(side, PBEffects::Rainbow,
_INTL("The rainbow on {1}'s side disappeared!", @battlers[side].pbTeam(true)))
# Pledge Sea of Fire
pbEORCountDownSideEffect(side, PBEffects::SeaOfFire,
_INTL("The sea of fire around {1} disappeared!", @battlers[side].pbTeam(true)))
# Pledge Swamp
pbEORCountDownSideEffect(side, PBEffects::Swamp,
_INTL("The swamp around {1} disappeared!", @battlers[side].pbTeam(true)))
# Aurora Veil
pbEORCountDownSideEffect(side, PBEffects::AuroraVeil,
_INTL("{1}'s Aurora Veil wore off!", @battlers[side].pbTeam(true)))
end
# Trick Room
pbEORCountDownFieldEffect(PBEffects::TrickRoom,
_INTL("The twisted dimensions returned to normal!"))
# Gravity
pbEORCountDownFieldEffect(PBEffects::Gravity,
_INTL("Gravity returned to normal!"))
# Water Sport
pbEORCountDownFieldEffect(PBEffects::WaterSportField,
_INTL("The effects of Water Sport have faded."))
# Mud Sport
pbEORCountDownFieldEffect(PBEffects::MudSportField,
_INTL("The effects of Mud Sport have faded."))
# Wonder Room
pbEORCountDownFieldEffect(PBEffects::WonderRoom,
_INTL("Wonder Room wore off, and Defense and Sp. Def stats returned to normal!"))
# Magic Room
pbEORCountDownFieldEffect(PBEffects::MagicRoom,
_INTL("Magic Room wore off, and held items' effects returned to normal!"))
# End of terrains
pbEORTerrain
priority.each do |b|
next if b.fainted?
# Hyper Mode (Shadow Pokémon)
if b.inHyperMode?
if pbRandom(100) < 10
b.pokemon.hyper_mode = false
pbDisplay(_INTL("{1} came to its senses!", b.pbThis))
else
pbDisplay(_INTL("{1} is in Hyper Mode!", b.pbThis))
end
end
# Uproar
if b.effects[PBEffects::Uproar] > 0
b.effects[PBEffects::Uproar] -= 1
if b.effects[PBEffects::Uproar] == 0
pbDisplay(_INTL("{1} calmed down.", b.pbThis))
else
pbDisplay(_INTL("{1} is making an uproar!", b.pbThis))
end
end
# Slow Start's end message
if b.effects[PBEffects::SlowStart] > 0
b.effects[PBEffects::SlowStart] -= 1
if b.effects[PBEffects::SlowStart] == 0
pbDisplay(_INTL("{1} finally got its act together!", b.pbThis))
end
end
# Bad Dreams, Moody, Speed Boost
Battle::AbilityEffects.triggerEndOfRoundEffect(b.ability, b, self) if b.abilityActive?
# Flame Orb, Sticky Barb, Toxic Orb
Battle::ItemEffects.triggerEndOfRoundEffect(b.item, b, self) if b.itemActive?
# Harvest, Pickup, Ball Fetch
Battle::AbilityEffects.triggerEndOfRoundGainItem(b.ability, b, self) if b.abilityActive?
end
pbGainExp
return if @decision > 0
# Form checks
priority.each { |b| b.pbCheckForm(true) }
# Switch Pokémon in if possible
pbEORSwitch
return if @decision > 0
# In battles with at least one side of size 3+, move battlers around if none
# are near to any foes
pbEORShiftDistantBattlers
# Try to make Trace work, check for end of primordial weather
priority.each { |b| b.pbContinualAbilityChecks }
# Reset/count down battler-specific effects (no messages)
allBattlers.each do |b|
b.effects[PBEffects::BanefulBunker] = false
b.effects[PBEffects::Charge] -= 1 if b.effects[PBEffects::Charge] > 0
b.effects[PBEffects::Counter] = -1
b.effects[PBEffects::CounterTarget] = -1
b.effects[PBEffects::Electrify] = false
b.effects[PBEffects::Endure] = false
b.effects[PBEffects::FirstPledge] = nil
b.effects[PBEffects::Flinch] = false
b.effects[PBEffects::FocusPunch] = false
b.effects[PBEffects::FollowMe] = 0
b.effects[PBEffects::HelpingHand] = false
b.effects[PBEffects::HyperBeam] -= 1 if b.effects[PBEffects::HyperBeam] > 0
b.effects[PBEffects::KingsShield] = false
b.effects[PBEffects::LaserFocus] -= 1 if b.effects[PBEffects::LaserFocus] > 0
if b.effects[PBEffects::LockOn] > 0 # Also Mind Reader
b.effects[PBEffects::LockOn] -= 1
b.effects[PBEffects::LockOnPos] = -1 if b.effects[PBEffects::LockOn] == 0
end
b.effects[PBEffects::MagicBounce] = false
b.effects[PBEffects::MagicCoat] = false
b.effects[PBEffects::MirrorCoat] = -1
b.effects[PBEffects::MirrorCoatTarget] = -1
b.effects[PBEffects::Obstruct] = false
b.effects[PBEffects::Powder] = false
b.effects[PBEffects::Prankster] = false
b.effects[PBEffects::PriorityAbility] = false
b.effects[PBEffects::PriorityItem] = false
b.effects[PBEffects::Protect] = false
b.effects[PBEffects::RagePowder] = false
b.effects[PBEffects::Roost] = false
b.effects[PBEffects::Snatch] = 0
b.effects[PBEffects::SpikyShield] = false
b.effects[PBEffects::Spotlight] = 0
b.effects[PBEffects::ThroatChop] -= 1 if b.effects[PBEffects::ThroatChop] > 0
b.lastHPLost = 0
b.lastHPLostFromFoe = 0
b.droppedBelowHalfHP = false
b.statsDropped = false
b.tookDamageThisRound = false
b.tookPhysicalHit = false
b.statsRaisedThisRound = false
b.statsLoweredThisRound = false
b.canRestoreIceFace = false
b.lastRoundMoveFailed = b.lastMoveFailed
b.lastAttacker.clear
b.lastFoeAttacker.clear
end
# Reset/count down side-specific effects (no messages)
2.times do |side|
@sides[side].effects[PBEffects::CraftyShield] = false
if !@sides[side].effects[PBEffects::EchoedVoiceUsed]
@sides[side].effects[PBEffects::EchoedVoiceCounter] = 0
end
@sides[side].effects[PBEffects::EchoedVoiceUsed] = false
@sides[side].effects[PBEffects::MatBlock] = false
@sides[side].effects[PBEffects::QuickGuard] = false
@sides[side].effects[PBEffects::Round] = false
@sides[side].effects[PBEffects::WideGuard] = false
end
# Reset/count down field-specific effects (no messages)
@field.effects[PBEffects::IonDeluge] = false
@field.effects[PBEffects::FairyLock] -= 1 if @field.effects[PBEffects::FairyLock] > 0
@field.effects[PBEffects::FusionBolt] = false
@field.effects[PBEffects::FusionFlare] = false
@endOfRound = false
end
end