Refactoring of code relating to switching, effect damage and effects that trigger after a move is used

This commit is contained in:
Maruno17
2021-09-19 19:03:17 +01:00
parent f00f030825
commit 1fb3ff5408
24 changed files with 345 additions and 343 deletions

View File

@@ -38,13 +38,13 @@ class PokeBattle_Battler
attr_accessor :lastRoundMoveFailed # For Stomping Tantrum
attr_accessor :movesUsed
attr_accessor :currentMove # ID of multi-turn move currently being used
attr_accessor :tookDamage # Boolean for whether self took damage this round
attr_accessor :droppedBelowHalfHP # Used for Emergency Exit/Wimp Out
attr_accessor :tookDamageThisRound # Boolean for whether self took damage this round
attr_accessor :tookPhysicalHit
attr_accessor :statsRaised # Boolean for whether self's stat(s) raised this round
attr_accessor :statsLowered # Boolean for whether self's stat(s) lowered this round
attr_accessor :canRestoreIceFace # Whether Hail started in the round
attr_accessor :damageState
attr_accessor :initialHP # Set at the start of each move's usage
#=============================================================================
# Complex accessors

View File

@@ -143,12 +143,12 @@ class PokeBattle_Battler
@effects[PBEffects::Telekinesis] = 0
end
@fainted = (@hp==0)
@initialHP = 0
@lastAttacker = []
@lastFoeAttacker = []
@lastHPLost = 0
@lastHPLostFromFoe = 0
@tookDamage = false
@droppedBelowHalfHP = false
@tookDamageThisRound = false
@tookPhysicalHit = false
@statsRaised = false
@statsLowered = false

View File

@@ -12,7 +12,10 @@ class PokeBattle_Battler
raise _INTL("HP less than 0") if @hp<0
raise _INTL("HP greater than total HP") if @hp>@totalhp
@battle.scene.pbHPChanged(self,oldHP,anim) if anyAnim && amt>0
@tookDamage = true if amt>0 && registerDamage
if amt > 0 && registerDamage
@droppedBelowHalfHP = true if @hp < @totalhp / 2 && @hp + amt >= @totalhp / 2
@tookDamageThisRound = true
end
return amt
end
@@ -26,6 +29,7 @@ class PokeBattle_Battler
raise _INTL("HP less than 0") if @hp<0
raise _INTL("HP greater than total HP") if @hp>@totalhp
@battle.scene.pbHPChanged(self,oldHP,anim) if anyAnim && amt>0
@droppedBelowHalfHP = false if @hp >= @totalhp / 2
return amt
end
@@ -46,6 +50,14 @@ class PokeBattle_Battler
end
end
def pbTakeEffectDamage(amt, show_anim = true)
hp_lost = pbReduceHP(amt, show_anim)
yield hp_lost if block_given? # Show message
pbItemHPHealCheck
pbAbilitiesOnDamageTaken
pbFaint if fainted?
end
def pbFaint(showMessage=true)
if !fainted?
PBDebug.log("!!!***Can't faint with HP greater than 0")
@@ -310,7 +322,7 @@ class PokeBattle_Battler
@effects[PBEffects::WeightChange] = target.effects[PBEffects::WeightChange]
@battle.scene.pbRefreshOne(@index)
@battle.pbDisplay(_INTL("{1} transformed into {2}!",pbThis,target.pbThis(true)))
pbOnAbilityChanged(oldAbil)
pbOnLosingAbility(oldAbil)
end
def pbHyperMode; end

View File

@@ -1,63 +1,4 @@
class PokeBattle_Battler
#=============================================================================
# Called when a Pokémon (self) is sent into battle or its ability changes.
#=============================================================================
def pbEffectsOnSwitchIn(switchIn=false)
# Healing Wish/Lunar Dance/entry hazards
@battle.pbOnActiveOne(self) if switchIn
# Primal Revert upon entering battle
@battle.pbPrimalReversion(@index) if !fainted?
# Ending primordial weather, checking Trace
pbContinualAbilityChecks(true)
# Abilities that trigger upon switching in
if (!fainted? && unstoppableAbility?) || abilityActive?
BattleHandlers.triggerAbilityOnSwitchIn(self.ability,self,@battle)
end
# Check for end of primordial weather
@battle.pbEndPrimordialWeather
# Items that trigger upon switching in (Air Balloon message)
if switchIn && itemActive?
BattleHandlers.triggerItemOnSwitchIn(self.item,self,@battle)
end
# Berry check, status-curing ability check
pbHeldItemTriggerCheck if switchIn
pbAbilityStatusCureCheck
end
#=============================================================================
# Called when a Pokémon enters battle, and when Ally Switch is used.
#=============================================================================
def pbEffectsOnEnteringPosition
position = @battle.positions[@index]
# Healing Wish
if position.effects[PBEffects::HealingWish]
if canHeal? || self.status != :NONE
@battle.pbCommonAnimation("HealingWish", self)
@battle.pbDisplay(_INTL("The healing wish came true for {1}!", pbThis(true)))
pbRecoverHP(@totalhp)
pbCureStatus(false)
position.effects[PBEffects::HealingWish] = false
elsif Settings::MECHANICS_GENERATION < 8
position.effects[PBEffects::HealingWish] = false
end
end
# Lunar Dance
if position.effects[PBEffects::LunarDance]
full_pp = true
eachMove { |m| full_pp = false if m.pp < m.total_pp }
if canHeal? || self.status != :NONE || !full_pp
@battle.pbCommonAnimation("LunarDance", self)
@battle.pbDisplay(_INTL("{1} became cloaked in mystical moonlight!", pbThis))
pbRecoverHP(@totalhp)
pbCureStatus(false)
eachMove { |m| m.pp = m.total_pp }
position.effects[PBEffects::LunarDance] = false
elsif Settings::MECHANICS_GENERATION < 8
position.effects[PBEffects::LunarDance] = false
end
end
end
#=============================================================================
# Ability effects
#=============================================================================
@@ -86,13 +27,11 @@ class PokeBattle_Battler
end
end
# Used for Emergency Exit/Wimp Out.
def pbAbilitiesOnDamageTaken(oldHP,newHP=-1)
# Used for Emergency Exit/Wimp Out. Returns whether self has switched out.
def pbAbilitiesOnDamageTaken(move_user = nil)
return false if !@droppedBelowHalfHP
return false if !abilityActive?
newHP = @hp if newHP<0
return false if oldHP<@totalhp/2 || newHP>=@totalhp/2 # Didn't drop below half
ret = BattleHandlers.triggerAbilityOnHPDroppedBelowHalf(self.ability,self,@battle)
return ret # Whether self has switched out
return BattleHandlers.triggerAbilityOnHPDroppedBelowHalf(self.ability, self, move_user, @battle)
end
def pbAbilityOnTerrainChange(ability_changed = false)
@@ -149,7 +88,7 @@ class PokeBattle_Battler
#=============================================================================
# Ability change
#=============================================================================
def pbOnAbilityChanged(oldAbil)
def pbOnLosingAbility(oldAbil)
if @effects[PBEffects::Illusion] && oldAbil == :ILLUSION
@effects[PBEffects::Illusion] = nil
if !@effects[PBEffects::Transform]
@@ -160,10 +99,23 @@ class PokeBattle_Battler
end
@effects[PBEffects::GastroAcid] = false if unstoppableAbility?
@effects[PBEffects::SlowStart] = 0 if self.ability != :SLOWSTART
# Check for end of primordial weather
@battle.pbEndPrimordialWeather
# Revert form if Flower Gift/Forecast was lost
pbCheckFormOnWeatherChange(true)
# Abilities that trigger when the terrain changes
pbAbilityOnTerrainChange(true)
end
def pbTriggerAbilityOnGainingIt
# Ending primordial weather, checking Trace
pbContinualAbilityChecks(true) # Don't trigger Traced ability as it's triggered below
# Abilities that trigger upon switching in
if (!fainted? && unstoppableAbility?) || abilityActive?
BattleHandlers.triggerAbilityOnSwitchIn(self.ability, self, @battle)
end
# Status-curing ability check
pbAbilityStatusCureCheck
# Check for end of primordial weather
@battle.pbEndPrimordialWeather
end

View File

@@ -125,7 +125,6 @@ class PokeBattle_Battler
def pbConfusionDamage(msg)
@damageState.reset
@damageState.initialHP = @hp
confusionMove = PokeBattle_Confusion.new(@battle,nil)
confusionMove.calcType = confusionMove.pbCalcType(self) # nil
@damageState.typeMod = confusionMove.pbCalcTypeMod(confusionMove.calcType,self,self) # 8
@@ -326,14 +325,10 @@ class PokeBattle_Battler
@battle.pbDisplay(_INTL("When the flame touched the powder on the Pokémon, it exploded!"))
user.lastMoveFailed = true
if ![:Rain, :HeavyRain].include?(user.effectiveWeather) && user.takesIndirectDamage?
oldHP = user.hp
user.pbReduceHP((user.totalhp/4.0).round,false)
user.pbFaint if user.fainted?
user.pbTakeEffectDamage((user.totalhp / 4.0).round, false) { |hp_lost|
battle.pbDisplay(_INTL("{1} is hurt by its {2}!", battler.pbThis, battler.itemName))
}
@battle.pbGainExp # In case user is KO'd by this
user.pbItemHPHealCheck
if user.pbAbilitiesOnDamageTaken(oldHP)
user.pbEffectsOnSwitchIn(true)
end
end
pbCancelMoves
pbEndTurn(choice)
@@ -389,13 +384,11 @@ class PokeBattle_Battler
user.lastMoveFailed = true
else # We have targets, or move doesn't use targets
# Reset whole damage state, perform various success checks (not accuracy)
user.initialHP = user.hp
@battle.eachBattler { |b| b.droppedBelowHalfHP = false }
targets.each do |b|
b.damageState.reset
b.damageState.initialHP = b.hp
if !pbSuccessCheckAgainstTarget(move, user, b, targets)
b.damageState.unaffected = true
end
next if pbSuccessCheckAgainstTarget(move, user, b, targets)
b.damageState.unaffected = true
end
# Magic Coat/Magic Bounce checks (for moves which don't target Pokémon)
if targets.length==0 && move.statusMove? && move.canMagicCoat?
@@ -503,6 +496,7 @@ class PokeBattle_Battler
user.pbFaint if user.fainted?
# External/general effects after all hits. Eject Button, Shell Bell, etc.
pbEffectsAfterMove(user,targets,move,realNumHits)
@battle.eachBattler { |b| b.droppedBelowHalfHP = false }
end
# End effect of Mold Breaker
@battle.moldBreaker = false

View File

@@ -154,71 +154,65 @@ class PokeBattle_Battler
b.pbConsumeItem
end
end
# Pokémon switching caused by Roar, Whirlwind, Circle Throw, Dragon Tail
switchedBattlers = []
move.pbSwitchOutTargetsEffect(user,targets,numHits,switchedBattlers)
switched_battlers = [] # Indices of battlers that were switched out somehow
# Target switching caused by Roar, Whirlwind, Circle Throw, Dragon Tail
move.pbSwitchOutTargetEffect(user, targets, numHits, switched_battlers)
# Target's item, user's item, target's ability (all negated by Sheer Force)
if move.addlEffect==0 || !user.hasActiveAbility?(:SHEERFORCE)
pbEffectsAfterMove2(user,targets,move,numHits,switchedBattlers)
if !(user.hasActiveAbility?(:SHEERFORCE) && move.addlEffect > 0)
pbEffectsAfterMove2(user, targets, move, numHits, switched_battlers)
end
# Some move effects that need to happen here, i.e. U-turn/Volt Switch
# switching, Baton Pass switching, Parting Shot switching, Relic Song's form
# changing, Fling/Natural Gift consuming item.
# Some move effects that need to happen here, i.e. user switching caused by
# U-turn/Volt Switch/Baton Pass/Parting Shot, Relic Song's form changing,
# Fling/Natural Gift consuming item.
if !switchedBattlers.include?(user.index)
move.pbEndOfMoveUsageEffect(user,targets,numHits,switchedBattlers)
end
# User's ability/item that switches the user out (all negated by Sheer Force)
if !(user.hasActiveAbility?(:SHEERFORCE) && move.addlEffect > 0)
pbEffectsAfterMove3(user, targets, move, numHits, switched_battlers)
end
if numHits>0
@battle.eachBattler { |b| b.pbItemEndOfMoveCheck }
end
end
# Everything in this method is negated by Sheer Force.
def pbEffectsAfterMove2(user,targets,move,numHits,switchedBattlers)
hpNow = user.hp # Intentionally determined now, before Shell Bell
# Target's held item (Eject Button, Red Card)
switchByItem = []
def pbEffectsAfterMove2(user, targets, move, numHits, switched_battlers)
# Target's held item (Eject Button, Red Card, Eject Pack)
@battle.pbPriority(true).each do |b|
next if !targets.any? { |targetB| targetB.index==b.index }
next if b.damageState.unaffected || b.damageState.calcDamage==0 ||
switchedBattlers.include?(b.index)
next if b.damageState.unaffected || b.damageState.calcDamage == 0
next if !b.itemActive?
BattleHandlers.triggerTargetItemAfterMoveUse(b.item,b,user,move,switchByItem,@battle)
BattleHandlers.triggerTargetItemAfterMoveUse(b.item, b, user, move, switched_battlers, @battle)
end
@battle.moldBreaker = false if switchByItem.include?(user.index)
@battle.pbPriority(true).each do |b|
b.pbEffectsOnSwitchIn(true) if switchByItem.include?(b.index)
end
switchByItem.each { |idxB| switchedBattlers.push(idxB) }
# User's held item (Life Orb, Shell Bell)
if !switchedBattlers.include?(user.index) && user.itemActive?
# User's held item (Life Orb, Shell Bell, Throat Spray, Eject Pack)
if !switched_battlers.include?(user.index) && user.itemActive? # Only if user hasn't switched out
BattleHandlers.triggerUserItemAfterMoveUse(user.item,user,targets,move,numHits,@battle)
end
# Target's ability (Berserk, Color Change, Emergency Exit, Pickpocket, Wimp Out)
switchWimpOut = []
@battle.pbPriority(true).each do |b|
next if !targets.any? { |targetB| targetB.index==b.index }
next if b.damageState.unaffected || switchedBattlers.include?(b.index)
next if !b.abilityActive?
BattleHandlers.triggerTargetAbilityAfterMoveUse(b.ability,b,user,move,switchedBattlers,@battle)
if !switchedBattlers.include?(b.index) && move.damagingMove?
if b.pbAbilitiesOnDamageTaken(b.damageState.initialHP) # Emergency Exit, Wimp Out
switchWimpOut.push(b.index)
if targets.any? { |targetB| targetB.index==b.index }
next if b.damageState.unaffected || switched_battlers.include?(b.index)
next if !b.abilityActive?
BattleHandlers.triggerTargetAbilityAfterMoveUse(b.ability, b, user, move, switched_battlers, @battle)
end
# Emergency Exit, Wimp Out (including for Pokémon hurt by Flame Burst)
if switched_battlers.empty? && move.damagingMove? && b.index != user.index
if b.pbAbilitiesOnDamageTaken(user)
switched_battlers.push(b.index)
end
end
end
@battle.moldBreaker = false if switchWimpOut.include?(user.index)
@battle.pbPriority(true).each do |b|
next if b.index==user.index
b.pbEffectsOnSwitchIn(true) if switchWimpOut.include?(b.index)
end
switchWimpOut.each { |idxB| switchedBattlers.push(idxB) }
end
# Everything in this method is negated by Sheer Force.
def pbEffectsAfterMove3(user, targets, move, numHits, switched_battlers)
# TODO: User's Eject Pack.
# User's ability (Emergency Exit, Wimp Out)
if !switchedBattlers.include?(user.index) && move.damagingMove?
hpNow = user.hp if user.hp<hpNow # In case HP was lost because of Life Orb
if user.pbAbilitiesOnDamageTaken(user.initialHP,hpNow)
@battle.moldBreaker = false
user.pbEffectsOnSwitchIn(true)
switchedBattlers.push(user.index)
if switched_battlers.empty? && move.damagingMove?
if user.pbAbilitiesOnDamageTaken(user)
switched_battlers.push(user.index)
end
end
end