diff --git a/Data/Scripts/011_Battle/002_Battler/001_Battle_Battler.rb b/Data/Scripts/011_Battle/002_Battler/001_Battle_Battler.rb index b3b6bef1a..7b042b9b0 100644 --- a/Data/Scripts/011_Battle/002_Battler/001_Battle_Battler.rb +++ b/Data/Scripts/011_Battle/002_Battler/001_Battle_Battler.rb @@ -638,6 +638,29 @@ class Battle::Battler return false end + # Returns whether this battler can be made to switch out because of another + # battler's move. + def canBeForcedOutOfBattle?(show_message = true) + if hasActiveAbility?(:SUCTIONCUPS) && !beingMoldBroken? + if show_message + @battle.pbShowAbilitySplash(self) + if Battle::Scene::USE_ABILITY_SPLASH + @battle.pbDisplay(_INTL("{1} anchors itself!", pbThis)) + else + @battle.pbDisplay(_INTL("{1} anchors itself with {2}!", pbThis, abilityName)) + end + @battle.pbHideAbilitySplash(self) + end + return false + end + return false if hasActiveAbility?(:GUARDDOG) && !beingMoldBroken? + if @effects[PBEffects::Ingrain] + @battle.pbDisplay(_INTL("{1} anchored itself with its roots!", pbThis)) if show_message + return false + end + return true + end + def movedThisRound? return @lastRoundMoved && @lastRoundMoved == @battle.turnCount end diff --git a/Data/Scripts/011_Battle/002_Battler/005_Battler_StatStages.rb b/Data/Scripts/011_Battle/002_Battler/005_Battler_StatStages.rb index 16871723b..19c43d2dc 100644 --- a/Data/Scripts/011_Battle/002_Battler/005_Battler_StatStages.rb +++ b/Data/Scripts/011_Battle/002_Battler/005_Battler_StatStages.rb @@ -332,7 +332,14 @@ class Battle::Battler return false end if Battle::Scene::USE_ABILITY_SPLASH - return pbLowerStatStageByAbility(:ATTACK, 1, user, false) + if hasActiveAbility?(:GUARDDOG) + @battle.pbShowAbilitySplash(self) + ret = pbRaiseStatStageByAbility(:ATTACK, 1, user, false) + @battle.pbHideAbilitySplash(self) + return ret + else + return pbLowerStatStageByAbility(:ATTACK, 1, user, false) + end end # NOTE: These checks exist to ensure appropriate messages are shown if # Intimidate is blocked somehow (i.e. the messages should mention the @@ -365,6 +372,10 @@ class Battle::Battler return false end end + if hasActiveAbility?(:GUARDDOG) + return false if !pbCanRaiseStatStage?(:ATTACK, user) + return pbRaiseStatStageByCause(:ATTACK, 1, user, user.abilityName) + end return false if !pbCanLowerStatStage?(:ATTACK, user) return pbLowerStatStageByCause(:ATTACK, 1, user, user.abilityName) end diff --git a/Data/Scripts/011_Battle/003_Move/013_MoveEffects_SwitchingActing.rb b/Data/Scripts/011_Battle/003_Move/013_MoveEffects_SwitchingActing.rb index 60124b06c..02eb581df 100644 --- a/Data/Scripts/011_Battle/003_Move/013_MoveEffects_SwitchingActing.rb +++ b/Data/Scripts/011_Battle/003_Move/013_MoveEffects_SwitchingActing.rb @@ -155,22 +155,7 @@ class Battle::Move::SwitchOutTargetStatusMove < Battle::Move def canMagicCoat?; return true; end def pbFailsAgainstTarget?(user, target, show_message) - if target.hasActiveAbility?(:SUCTIONCUPS) && !target.beingMoldBroken? - if show_message - @battle.pbShowAbilitySplash(target) - if Battle::Scene::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("{1} anchors itself!", target.pbThis)) - else - @battle.pbDisplay(_INTL("{1} anchors itself with {2}!", target.pbThis, target.abilityName)) - end - @battle.pbHideAbilitySplash(target) - end - return true - end - if target.effects[PBEffects::Ingrain] - @battle.pbDisplay(_INTL("{1} anchored itself with its roots!", target.pbThis)) if show_message - return true - end + return true if !target.canBeForcedOutOfBattle?(show_message) if target.wild? && target.allAllies.length == 0 && @battle.canRun # End the battle if target.level > user.level @@ -205,8 +190,7 @@ class Battle::Move::SwitchOutTargetStatusMove < Battle::Move targets.each do |b| next if b.fainted? || b.damageState.unaffected next if b.wild? - next if b.effects[PBEffects::Ingrain] - next if b.hasActiveAbility?(:SUCTIONCUPS) && !b.beingMoldBroken? + next if !b.canBeForcedOutOfBattle?(false) newPkmn = @battle.pbGetReplacementPokemonIndex(b.index, true) # Random next if newPkmn < 0 @battle.pbRecallAndReplace(b.index, newPkmn, true) @@ -240,8 +224,7 @@ class Battle::Move::SwitchOutTargetDamagingMove < Battle::Move targets.each do |b| next if b.fainted? || b.damageState.unaffected || b.damageState.substitute next if b.wild? - next if b.effects[PBEffects::Ingrain] - next if b.hasActiveAbility?(:SUCTIONCUPS) && !b.beingMoldBroken? + next if !b.canBeForcedOutOfBattle?(false) newPkmn = @battle.pbGetReplacementPokemonIndex(b.index, true) # Random next if newPkmn < 0 @battle.pbRecallAndReplace(b.index, newPkmn, true) diff --git a/Data/Scripts/011_Battle/006_AI MoveEffects/009_AI_MoveEffects_SwitchingActing.rb b/Data/Scripts/011_Battle/006_AI MoveEffects/009_AI_MoveEffects_SwitchingActing.rb index f625bc555..e7c610998 100644 --- a/Data/Scripts/011_Battle/006_AI MoveEffects/009_AI_MoveEffects_SwitchingActing.rb +++ b/Data/Scripts/011_Battle/006_AI MoveEffects/009_AI_MoveEffects_SwitchingActing.rb @@ -202,6 +202,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("SwitchOutTargetDamagingM next score if target.wild? # No score modification if the target can't be made to switch out next score if target.has_active_ability?(:SUCTIONCUPS) && !target.being_mold_broken? + next score if target.has_active_ability?(:GUARDDOG) && !target.being_mold_broken? next score if target.effects[PBEffects::Ingrain] # No score modification if the target can't be replaced can_switch = false diff --git a/Data/Scripts/011_Battle/007_Other battle code/008_Battle_AbilityEffects.rb b/Data/Scripts/011_Battle/007_Other battle code/008_Battle_AbilityEffects.rb index 94872c954..ed76cb525 100644 --- a/Data/Scripts/011_Battle/007_Other battle code/008_Battle_AbilityEffects.rb +++ b/Data/Scripts/011_Battle/007_Other battle code/008_Battle_AbilityEffects.rb @@ -364,6 +364,61 @@ Battle::AbilityEffects::WeightCalc.add(:LIGHTMETAL, # OnHPDroppedBelowHalf handlers #=============================================================================== +Battle::AbilityEffects::OnHPDroppedBelowHalf.add(:ANGERSHELL, + proc { |ability, battler, move_user, battle| + next false if !move_user # Not triggered if damage wasn't from a move + next false if move_user.index == battler.index # Not triggered by self-injury + stat_up = [:ATTACK, 1, :SPECIAL_ATTACK, 1, :SPEED, 1] + stat_down = [:DEFENSE, 1, :SPECIAL_DEFENSE, 1] + # Check if it will have any effect + failed = true + (stat_down.length / 2).times do |i| + next if !battler.pbCanLowerStatStage?(stat_down[i * 2], battler) + failed = false + break + end + (stat_up.length / 2).times do |i| + next if !battler.pbCanRaiseStatStage?(stat_up[i * 2], battler) + failed = false + break + end + next false if failed + # Ability will have an effect; do it + battle.pbShowAbilitySplash(battler) + # Lower stats + show_anim = true + (stat_down.length / 2).times do |i| + next if !battler.pbCanLowerStatStage?(stat_down[i * 2], battler) + if Battle::Scene::USE_ABILITY_SPLASH + if battler.pbLowerStatStage(stat_down[i * 2], stat_down[(i * 2) + 1], battler, show_anim) + show_anim = false + end + else + if battler.pbLowerStatStageByCause(stat_down[i * 2], stat_down[(i * 2) + 1], battler, battler.abilityName, show_anim) + show_anim = false + end + end + end + # Raise stats + show_anim = true + (stat_up.length / 2).times do |i| + next if !battler.pbCanRaiseStatStage?(stat_up[i * 2], battler) + if Battle::Scene::USE_ABILITY_SPLASH + if battler.pbRaiseStatStage(stat_up[i * 2], stat_up[(i * 2) + 1], battler, show_anim) + show_anim = false + end + else + if battler.pbRaiseStatStageByCause(stat_up[i * 2], stat_up[(i * 2) + 1], battler, battler.abilityName, show_anim) + show_anim = false + end + end + end + battle.pbHideAbilitySplash(battler) + next false + } +) + + Battle::AbilityEffects::OnHPDroppedBelowHalf.add(:EMERGENCYEXIT, proc { |ability, battler, move_user, battle| next false if battler.effects[PBEffects::SkyDrop] >= 0 || diff --git a/Data/Scripts/011_Battle/007_Other battle code/009_Battle_ItemEffects.rb b/Data/Scripts/011_Battle/007_Other battle code/009_Battle_ItemEffects.rb index 5bfeffadd..bad91f00a 100644 --- a/Data/Scripts/011_Battle/007_Other battle code/009_Battle_ItemEffects.rb +++ b/Data/Scripts/011_Battle/007_Other battle code/009_Battle_ItemEffects.rb @@ -1591,20 +1591,7 @@ Battle::ItemEffects::AfterMoveUseFromTarget.add(:REDCARD, battle.pbDisplay(_INTL("{1} held up its {2} against {3}!", battler.pbThis, battler.itemName, user.pbThis(true))) battler.pbConsumeItem - if user.hasActiveAbility?(:SUCTIONCUPS) && !user.being_mold_broken? - battle.pbShowAbilitySplash(user) - if Battle::Scene::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1} anchors itself!", user.pbThis)) - else - battle.pbDisplay(_INTL("{1} anchors itself with {2}!", user.pbThis, user.abilityName)) - end - battle.pbHideAbilitySplash(user) - next - end - if user.effects[PBEffects::Ingrain] - battle.pbDisplay(_INTL("{1} anchored itself with its roots!", user.pbThis)) - next - end + next if !user.canBeForcedOutOfBattle? battle.pbRecallAndReplace(user.index, newPkmn, true) battle.pbDisplay(_INTL("{1} was dragged out!", user.pbThis)) battle.pbClearChoice(user.index) # Replacement Pokémon does nothing this round