From 72c50db6c08760d083c8682ac2f90007954abb4c Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Sun, 17 Oct 2021 19:49:25 +0100 Subject: [PATCH] Tidying up of Gen 8 ability code, fixed Analytic's effect, added trigger for berry consuming when Unnerve ends --- .../001_Battler/001_PokeBattle_Battler.rb | 4 + .../001_Battler/006_Battler_AbilityAndItem.rb | 12 +- .../011_Battle/002_Move/002_Move_Usage.rb | 4 +- .../003_BattleHandlers_Abilities.rb | 349 ++++++++++++++++- Data/Scripts/011_Battle/Gen 8 abilities.rb | 351 ------------------ Data/Scripts/Gen 8 notes.txt | 23 +- 6 files changed, 373 insertions(+), 370 deletions(-) delete mode 100644 Data/Scripts/011_Battle/Gen 8 abilities.rb diff --git a/Data/Scripts/011_Battle/001_Battler/001_PokeBattle_Battler.rb b/Data/Scripts/011_Battle/001_Battler/001_PokeBattle_Battler.rb index 7107ed581..cbcf2df55 100644 --- a/Data/Scripts/011_Battle/001_Battler/001_PokeBattle_Battler.rb +++ b/Data/Scripts/011_Battle/001_Battler/001_PokeBattle_Battler.rb @@ -373,6 +373,8 @@ class PokeBattle_Battler :STANCECHANGE, :ZENMODE, # Abilities intended to be inherent properties of a certain species + :ASONECHILLINGNEIGH, + :ASONEGRIMNEIGH, :COMATOSE, :RKSSYSTEM ] @@ -402,6 +404,8 @@ class PokeBattle_Battler :ILLUSION, :IMPOSTER, # Abilities intended to be inherent properties of a certain species + :ASONECHILLINGNEIGH, + :ASONEGRIMNEIGH, :COMATOSE, :RKSSYSTEM, # Abilities that can't be negated diff --git a/Data/Scripts/011_Battle/001_Battler/006_Battler_AbilityAndItem.rb b/Data/Scripts/011_Battle/001_Battler/006_Battler_AbilityAndItem.rb index 5c6627433..4a0b84ace 100644 --- a/Data/Scripts/011_Battle/001_Battler/006_Battler_AbilityAndItem.rb +++ b/Data/Scripts/011_Battle/001_Battler/006_Battler_AbilityAndItem.rb @@ -11,8 +11,9 @@ class PokeBattle_Battler # Treat self as fainted @hp = 0 @fainted = true - # Check for end of Neutralizing Gas + # Check for end of Neutralizing Gas/Unnerve pbAbilitiesOnNeutralizingGasEnding if hasActiveAbility?(:NEUTRALIZINGGAS, true) + pbItemsOnUnnerveEnding if hasActiveAbility?(:UNNERVE, true) # Check for end of primordial weather @battle.pbEndPrimordialWeather end @@ -28,6 +29,7 @@ class PokeBattle_Battler BattleHandlers.triggerAbilityOnBattlerFainting(b.ability,b,self,@battle) end pbAbilitiesOnNeutralizingGasEnding if hasActiveAbility?(:NEUTRALIZINGGAS, true) + pbItemsOnUnnerveEnding if hasActiveAbility?(:UNNERVE, true) end # Used for Emergency Exit/Wimp Out. Returns whether self has switched out. @@ -105,6 +107,8 @@ class PokeBattle_Battler def pbOnLosingAbility(oldAbil, suppressed = false) if oldAbil == :NEUTRALIZINGGAS && (suppressed || !@effects[PBEffects::GastroAcid]) pbAbilitiesOnNeutralizingGasEnding + elsif oldAbil == :UNNERVE && (suppressed || !@effects[PBEffects::GastroAcid]) + pbItemsOnUnnerveEnding elsif oldAbil == :ILLUSION && @effects[PBEffects::Illusion] @effects[PBEffects::Illusion] = nil if !@effects[PBEffects::Transform] @@ -316,4 +320,10 @@ class PokeBattle_Battler return false if !itemActive? return BattleHandlers.triggerItemOnStatDropped(self.item, self, move_user, @battle) end + + def pbItemsOnUnnerveEnding + @battle.pbPriority(true).each do |b| + b.pbHeldItemTriggerCheck if b.item && b.item.is_berry? + end + end end diff --git a/Data/Scripts/011_Battle/002_Move/002_Move_Usage.rb b/Data/Scripts/011_Battle/002_Move/002_Move_Usage.rb index 871478820..f6b7280c7 100644 --- a/Data/Scripts/011_Battle/002_Move/002_Move_Usage.rb +++ b/Data/Scripts/011_Battle/002_Move/002_Move_Usage.rb @@ -100,7 +100,7 @@ class PokeBattle_Move # Checks whether the move will be ineffective against the target. def pbFailsAgainstTarget?(user, target, show_message); return false; end - def pbMoveFailedLastInRound?(user) + def pbMoveFailedLastInRound?(user, showMessage = true) unmoved = false @battle.eachBattler do |b| next if b.index==user.index @@ -110,7 +110,7 @@ class PokeBattle_Move break end if !unmoved - @battle.pbDisplay(_INTL("But it failed!")) + @battle.pbDisplay(_INTL("But it failed!")) if showMessage return true end return false diff --git a/Data/Scripts/011_Battle/003_BattleHandlers_Abilities.rb b/Data/Scripts/011_Battle/003_BattleHandlers_Abilities.rb index 0618d49ce..fa06fee32 100644 --- a/Data/Scripts/011_Battle/003_BattleHandlers_Abilities.rb +++ b/Data/Scripts/011_Battle/003_BattleHandlers_Abilities.rb @@ -140,6 +140,8 @@ BattleHandlers::StatusImmunityAbility.add(:IMMUNITY, } ) +BattleHandlers::StatusImmunityAbility.copy(:IMMUNITY, :PASTELVEIL) + BattleHandlers::StatusImmunityAbility.add(:INSOMNIA, proc { |ability,battler,status| next true if status == :SLEEP @@ -540,6 +542,12 @@ BattleHandlers::PriorityChangeAbility.add(:TRIAGE, # PriorityBracketChangeAbility handlers #=============================================================================== +BattleHandlers::PriorityBracketChangeAbility.add(:QUICKDRAW, + proc { |ability, battler, subPri, battle| + next 1 if subPri == 0 && battle.pbRandom(100) < 30 + } +) + BattleHandlers::PriorityBracketChangeAbility.add(:STALL, proc { |ability,battler,subPri,battle| next -1 if subPri==0 @@ -550,7 +558,13 @@ BattleHandlers::PriorityBracketChangeAbility.add(:STALL, # PriorityBracketUseAbility handlers #=============================================================================== -# There aren't any! +BattleHandlers::PriorityBracketUseAbility.add(:QUICKDRAW, + proc { |ability, battler, battle| + battle.pbShowAbilitySplash(battler) + battle.pbDisplay(_INTL("{1} made {2} move faster!", battler.abilityName, battler.pbThis(true))) + battle.pbHideAbilitySplash(battler) + } +) #=============================================================================== # AbilityOnFlinch handlers @@ -888,9 +902,14 @@ BattleHandlers::DamageCalcUserAbility.copy(:AERILATE, :PIXILATE, :REFRIGERATE, : BattleHandlers::DamageCalcUserAbility.add(:ANALYTIC, proc { |ability,user,target,move,mults,baseDmg,type| - if (target.battle.choices[target.index][0]!=:UseMove && - target.battle.choices[target.index][0]!=:Shift) || - target.movedThisRound? + # NOTE: If another battler faints earlier in the round, but it would have + # moved after the user, then Analytic would not power up the move. + # However, this makes the determination so much more complicated + # (involving pbPriority and counting or not counting speed/priority + # modifiers depending on which Generation's mechanics are being used), + # so I'm choosing to ignore it. The effect is thus: "power up the move + # if all other battlers on the field right now have already moved". + if move.pbMoveFailedLastInRound?(user, false) mults[:base_damage_multiplier] *= 1.3 end } @@ -910,6 +929,12 @@ BattleHandlers::DamageCalcUserAbility.add(:DEFEATIST, } ) +BattleHandlers::DamageCalcUserAbility.add(:DRAGONSMAW, + proc { |ability, user, target, move, mults, baseDmg, type| + mults[:attack_multiplier] *= 1.5 if type == :DRAGON + } +) + BattleHandlers::DamageCalcUserAbility.add(:FLAREBOOST, proc { |ability,user,target,move,mults,baseDmg,type| if user.burned? && move.specialMove? @@ -934,6 +959,12 @@ BattleHandlers::DamageCalcUserAbility.add(:FLOWERGIFT, } ) +BattleHandlers::DamageCalcUserAbility.add(:GORILLATACTICS, + proc { |ability, user, target, move, mults, baseDmg, type| + mults[:attack_multiplier] *= 1.5 + } +) + BattleHandlers::DamageCalcUserAbility.add(:GUTS, proc { |ability,user,target,move,mults,baseDmg,type| if user.pbHasAnyStatus? && move.physicalMove? @@ -997,6 +1028,12 @@ BattleHandlers::DamageCalcUserAbility.add(:OVERGROW, } ) +BattleHandlers::DamageCalcUserAbility.add(:PUNKROCK, + proc { |ability, user, target, move, mults, baseDmg, type| + mults[:attack_multiplier] *= 1.3 if move.soundMove? + } +) + BattleHandlers::DamageCalcUserAbility.add(:RECKLESS, proc { |ability,user,target,move,mults,baseDmg,type| mults[:base_damage_multiplier] *= 1.2 if move.recoilMove? @@ -1064,6 +1101,12 @@ BattleHandlers::DamageCalcUserAbility.add(:STEELWORKER, } ) +BattleHandlers::DamageCalcUserAbility.add(:STEELYSPIRIT, + proc { |ability, user, target, move, mults, baseDmg, type| + mults[:final_damage_multiplier] *= 1.5 if type == :STEEL + } +) + BattleHandlers::DamageCalcUserAbility.add(:STRONGJAW, proc { |ability,user,target,move,mults,baseDmg,type| mults[:base_damage_multiplier] *= 1.5 if move.bitingMove? @@ -1115,6 +1158,12 @@ BattleHandlers::DamageCalcUserAbility.add(:TOXICBOOST, } ) +BattleHandlers::DamageCalcUserAbility.add(:TRANSISTOR, + proc { |ability, user, target, move, mults, baseDmg, type| + mults[:attack_multiplier] *= 1.5 if type == :ELECTRIC + } +) + BattleHandlers::DamageCalcUserAbility.add(:WATERBUBBLE, proc { |ability,user,target,move,mults,baseDmg,type| mults[:attack_multiplier] *= 2 if type == :WATER @@ -1140,6 +1189,18 @@ BattleHandlers::DamageCalcUserAllyAbility.add(:FLOWERGIFT, } ) +BattleHandlers::DamageCalcUserAllyAbility.add(:POWERSPOT, + proc { |ability, user, target, move, mults, baseDmg, type| + mults[:final_damage_multiplier] *= 1.3 + } +) + +BattleHandlers::DamageCalcUserAllyAbility.add(:STEELYSPIRIT, + proc { |ability, user, target, move, mults, baseDmg, type| + mults[:final_damage_multiplier] *= 1.5 if type == :STEEL + } +) + #=============================================================================== # DamageCalcTargetAbility handlers #=============================================================================== @@ -1196,6 +1257,12 @@ BattleHandlers::DamageCalcTargetAbility.add(:HEATPROOF, } ) +BattleHandlers::DamageCalcTargetAbility.add(:ICESCALES, + proc { |ability, user, target, move, mults, baseDmg, type| + mults[:final_damage_multiplier] /= 2 if move.specialMove? + } +) + BattleHandlers::DamageCalcTargetAbility.add(:MARVELSCALE, proc { |ability,user,target,move,mults,baseDmg,type| if target.pbHasAnyStatus? && move.physicalMove? @@ -1210,6 +1277,12 @@ BattleHandlers::DamageCalcTargetAbility.add(:MULTISCALE, } ) +BattleHandlers::DamageCalcTargetAbility.add(:PUNKROCK, + proc { |ability, user, target, move, mults, baseDmg, type| + mults[:final_damage_multiplier] /= 2 if move.soundMove? + } +) + BattleHandlers::DamageCalcTargetAbility.add(:THICKFAT, proc { |ability,user,target,move,mults,baseDmg,type| mults[:base_damage_multiplier] /= 2 if type == :FIRE || type == :ICE @@ -1340,6 +1413,23 @@ BattleHandlers::TargetAbilityOnHit.add(:ANGERPOINT, } ) +BattleHandlers::TargetAbilityOnHit.add(:COTTONDOWN, + proc { |ability, user, target, move, battle| + has_effect = false + battle.eachBattler do |b| + next if !b.pbCanLowerStatStage?(:DEFENSE, target) + has_effect = true + break + end + next if !has_effect + battle.pbShowAbilitySplash(battler) + battle.eachBattler do |b| + b.pbLowerStatStageByAbility(:SPEED, 1, target, false) + end + battle.pbHideAbilitySplash(battler) + } +) + BattleHandlers::TargetAbilityOnHit.add(:CURSEDBODY, proc { |ability,user,target,move,battle| next if user.fainted? @@ -1545,6 +1635,28 @@ BattleHandlers::TargetAbilityOnHit.add(:MUMMY, } ) +BattleHandlers::TargetAbilityOnHit.add(:PERISHBODY, + proc { |ability, user, target, move, battle| + next if !move.pbContactMove?(user) + next if user.fainted? + next if user.effects[PBEffects::PerishSong] > 0 || target.effects[PBEffects::PerishSong] > 0 + battle.pbShowAbilitySplash(target) + if user.affectedByContactEffect?(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) + user.effects[PBEffects::PerishSong] = 4 + user.effects[PBEffects::PerishSongUser] = target.index + target.effects[PBEffects::PerishSong] = 4 + target.effects[PBEffects::PerishSongUser] = target.index + if PokeBattle_SceneConstants::USE_ABILITY_SPLASH + battle.pbDisplay(_INTL("Both Pokémon will faint in three turns!")) + else + battle.pbDisplay(_INTL("Both Pokémon will faint in three turns because of {1}'s {2}!", + target.pbThis(true), target.abilityName)) + end + end + battle.pbHideAbilitySplash(target) + } +) + BattleHandlers::TargetAbilityOnHit.add(:POISONPOINT, proc { |ability,user,target,move,battle| next if !move.pbContactMove?(user) @@ -1569,6 +1681,12 @@ BattleHandlers::TargetAbilityOnHit.add(:RATTLED, } ) +BattleHandlers::TargetAbilityOnHit.add(:SANDSPIT, + proc { |ability, user, target, move, battle| + pbBattleWeatherAbility(:Sandstorm, battler, battle) + } +) + BattleHandlers::TargetAbilityOnHit.add(:STAMINA, proc { |ability,user,target,move,battle| target.pbRaiseStatStageByAbility(:DEFENSE,1,target) @@ -1593,6 +1711,42 @@ BattleHandlers::TargetAbilityOnHit.add(:STATIC, } ) +BattleHandlers::TargetAbilityOnHit.add(:WANDERINGSPIRIT, + proc { |ability, user, target, move, battle| + next if !move.pbContactMove?(user) + next if user.ungainableAbility? || [:RECEIVER, :WONDERGUARD].include?(user.ability_id) + oldUserAbil = nil + oldTargetAbil = nil + battle.pbShowAbilitySplash(target) if user.opposes?(target) + if user.affectedByContactEffect?(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) + battle.pbShowAbilitySplash(user, true, false) if user.opposes?(target) + oldUserAbil = user.ability + oldTargetAbil = target.ability + user.ability = oldTargetAbil + target.ability = oldUserAbil + if user.opposes?(target) + battle.pbReplaceAbilitySplash(user) + battle.pbReplaceAbilitySplash(target) + end + if PokeBattle_SceneConstants::USE_ABILITY_SPLASH + battle.pbDisplay(_INTL("{1} swapped Abilities with {2}!", target.pbThis, user.pbThis(true))) + else + battle.pbDisplay(_INTL("{1} swapped its {2} Ability with {3}'s {4} Ability!", + target.pbThis, user.abilityName, user.pbThis(true), target.abilityName)) + end + if user.opposes?(target) + battle.pbHideAbilitySplash(user) + battle.pbHideAbilitySplash(target) + end + end + battle.pbHideAbilitySplash(target) if user.opposes?(target) + user.pbOnLosingAbility(oldUserAbil) + target.pbOnLosingAbility(oldTargetAbil) + user.pbTriggerAbilityOnGainingIt + target.pbTriggerAbilityOnGainingIt + } +) + BattleHandlers::TargetAbilityOnHit.add(:WATERCOMPACTION, proc { |ability,user,target,move,battle| next if move.calcType != :WATER @@ -1662,6 +1816,34 @@ BattleHandlers::UserAbilityEndOfMove.add(:BEASTBOOST, } ) +BattleHandlers::UserAbilityEndOfMove.add(:CHILLINGNEIGH, + proc { |ability, user, targets, move, battle| + next if battle.pbAllFainted?(user.idxOpposingSide) + numFainted = 0 + targets.each { |b| numFainted += 1 if b.damageState.fainted } + next if numFainted == 0 || !user.pbCanRaiseStatStage?(:ATTACK, user) + user.ability_id = :CHILLINGNEIGH # So the As One abilities can just copy this + user.pbRaiseStatStageByAbility(:ATTACK, 1, user) + user.ability_id = ability + } +) + +BattleHandlers::UserAbilityEndOfMove.copy(:CHILLINGNEIGH, :ASONECHILLINGNEIGH) + +BattleHandlers::UserAbilityEndOfMove.add(:GRIMNEIGH, + proc { |ability, user, targets, move, battle| + next if battle.pbAllFainted?(user.idxOpposingSide) + numFainted = 0 + targets.each { |b| numFainted += 1 if b.damageState.fainted } + next if numFainted == 0 || !user.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user) + user.ability_id = :GRIMNEIGH # So the As One abilities can just copy this + user.pbRaiseStatStageByAbility(:SPECIAL_ATTACK, 1, user) + user.ability_id = ability + } +) + +BattleHandlers::UserAbilityEndOfMove.copy(:GRIMNEIGH, :ASONEGRIMNEIGH) + BattleHandlers::UserAbilityEndOfMove.add(:MAGICIAN, proc { |ability,user,targets,move,battle| next if battle.futureSight @@ -1817,6 +1999,19 @@ BattleHandlers::EORWeatherAbility.add(:ICEBODY, } ) +BattleHandlers::EORWeatherAbility.add(:ICEFACE, + proc { |ability, weather, battler, battle| + next if weather != :Hail + next if !battler.canRestoreIceFace || battler.form != 1 + battle.pbShowAbilitySplash(battler) + if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH + battle.pbDisplay(_INTL("{1}'s {2} activated!", battler.pbThis, battler.abilityName)) + end + battler.pbChangeForm(0, _INTL("{1} transformed!", battler.pbThis)) + battle.pbHideAbilitySplash(battler) + } +) + BattleHandlers::EORWeatherAbility.add(:RAINDISH, proc { |ability,weather,battler,battle| next unless [:Rain, :HeavyRain].include?(weather) @@ -1995,6 +2190,20 @@ BattleHandlers::EOREffectAbility.add(:SPEEDBOOST, # EORGainItemAbility handlers #=============================================================================== +BattleHandlers::EORGainItemAbility.add(:BALLFETCH, + proc { |ability, battler, battle| + next if battler.item + next if battle.first_poke_ball.nil? + battle.pbShowAbilitySplash(battler) + battler.item = battle.first_poke_ball + battler.setInitialItem(battler.item) if !battler.initialItem + battle.first_poke_ball = nil + battle.pbDisplay(_INTL("{1} retrieved the thrown {2}!", battler.pbThis, battler.itemName)) + battle.pbHideAbilitySplash(battler) + battler.pbHeldItemTriggerCheck + } +) + BattleHandlers::EORGainItemAbility.add(:HARVEST, proc { |ability,battler,battle| next if battler.item @@ -2122,6 +2331,21 @@ BattleHandlers::AbilityOnSwitchIn.add(:ANTICIPATION, } ) +BattleHandlers::AbilityOnSwitchIn.add(:ASONECHILLINGNEIGH, + proc { |ability, battler, battle| + battle.pbShowAbilitySplash(battler) + battle.pbDisplay(_INTL("{1} has two Abilities!", battler.pbThis)) + battle.pbHideAbilitySplash(battler) + battler.ability_id = :UNNERVE + battle.pbShowAbilitySplash(battler) + battle.pbDisplay(_INTL("{1} is too nervous to eat Berries!", battler.pbOpposingTeam)) + battle.pbHideAbilitySplash(battler) + battler.ability_id = ability + } +) + +BattleHandlers::AbilityOnSwitchIn.copy(:ASONECHILLINGNEIGH, :ASONEGRIMNEIGH) + BattleHandlers::AbilityOnSwitchIn.add(:AURABREAK, proc { |ability,battler,battle| battle.pbShowAbilitySplash(battler) @@ -2138,6 +2362,30 @@ BattleHandlers::AbilityOnSwitchIn.add(:COMATOSE, } ) +BattleHandlers::AbilityOnSwitchIn.add(:CURIOUSMEDICINE, + proc { |ability, battler, battle| + has_effect = false + battler.eachAlly do |b| + next if !b.hasAlteredStatStages? + has_effect = true + break + end + next if !has_effect + battle.pbShowAbilitySplash(battler) + battler.eachAlly do |b| + next if !b.hasAlteredStatStages? + b.pbResetStatStages + if PokeBattle_SceneConstants::USE_ABILITY_SPLASH + battle.pbDisplay(_INTL("{1}'s stat changes were removed!", b.pbThis)) + else + battle.pbDisplay(_INTL("{1}'s stat changes were removed by {2}'s {3}!", + b.pbThis, battler.pbThis(true), battler.abilityName)) + end + end + battle.pbHideAbilitySplash(battler) + } +) + BattleHandlers::AbilityOnSwitchIn.add(:DARKAURA, proc { |ability,battler,battle| battle.pbShowAbilitySplash(battler) @@ -2146,6 +2394,12 @@ BattleHandlers::AbilityOnSwitchIn.add(:DARKAURA, } ) +BattleHandlers::AbilityOnSwitchIn.add(:DAUNTLESSSHIELD, + proc { |ability, battler, battle| + battler.pbRaiseStatStageByAbility(:ATTACK, 1, battler) + } +) + BattleHandlers::AbilityOnSwitchIn.add(:DELTASTREAM, proc { |ability,battler,battle| pbBattleWeatherAbility(:StrongWinds, battler, battle, true) @@ -2225,11 +2479,11 @@ BattleHandlers::AbilityOnSwitchIn.add(:FOREWARN, "PowerLowerWithUserHappiness", "PowerHigherWithUserHP", "PowerHigherWithTargetFasterThanUser", - "TypeDependsOnUserIVs", "TypeAndPowerDependOnUserBerry", "PowerHigherWithLessPP", "PowerLowerWithUserHP", "PowerHigherWithTargetWeight"].include?(m.function) + power = 80 if Settings::MECHANICS_GENERATION <= 5 && m.function == "TypeDependsOnUserIVs" next if powerhighestPower forewarnMoves.push(m.name) @@ -2284,6 +2538,19 @@ BattleHandlers::AbilityOnSwitchIn.add(:GRASSYSURGE, } ) +BattleHandlers::AbilityOnSwitchIn.add(:ICEFACE, + proc { |ability, battler, battle| + next if !battler.isSpecies?(:EISCUE) || battler.form != 1 + next if battler.effectiveWeather != :Hail + battle.pbShowAbilitySplash(battler) + if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH + battle.pbDisplay(_INTL("{1}'s {2} activated!", battler.pbThis, battler.abilityName)) + end + battler.pbChangeForm(0, _INTL("{1} transformed!", battler.pbThis)) + battle.pbHideAbilitySplash(battler) + } +) + BattleHandlers::AbilityOnSwitchIn.add(:IMPOSTER, proc { |ability,battler,battle| next if battler.effects[PBEffects::Transform] @@ -2321,6 +2588,19 @@ BattleHandlers::AbilityOnSwitchIn.add(:INTIMIDATE, } ) +BattleHandlers::AbilityOnSwitchIn.add(:INTREPIDSWORD, + proc { |ability, battler, battle| + battler.pbRaiseStatStageByAbility(:ATTACK, 1, battler) + } +) + +BattleHandlers::AbilityOnSwitchIn.add(:MIMICRY, + proc { |ability, battler, battle| + next if battle.field.terrain == :None + BattleHandlers.triggerAbilityOnTerrainChange(ability, battler, battle, false) + } +) + BattleHandlers::AbilityOnSwitchIn.add(:MISTYSURGE, proc { |ability,battler,battle| next if battle.field.terrain == :Misty @@ -2365,6 +2645,28 @@ BattleHandlers::AbilityOnSwitchIn.add(:NEUTRALIZINGGAS, } ) +BattleHandlers::AbilityOnSwitchIn.add(:PASTELVEIL, + proc { |ability, battler, battle| + has_effect = false + battler.eachAlly do |b| + next if b.status != :POISON + has_effect = true + break + end + next if !has_effect + battle.pbShowAbilitySplash(battler) + battler.eachAlly do |b| + next if b.status != :POISON + b.pbCureStatus(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) + if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH + battle.pbDisplay(_INTL("{1}'s {2} cured {3}'s poisoning!", + battler.pbThis, battler.abilityName, b.pbThis(true))) + end + end + battle.pbHideAbilitySplash(battler) + } +) + BattleHandlers::AbilityOnSwitchIn.add(:PRESSURE, proc { |ability,battler,battle| battle.pbShowAbilitySplash(battler) @@ -2394,6 +2696,43 @@ BattleHandlers::AbilityOnSwitchIn.add(:SANDSTREAM, } ) +BattleHandlers::AbilityOnSwitchIn.add(:SCREENCLEANER, + proc { |ability, battler, battle| + next if target.pbOwnSide.effects[PBEffects::AuroraVeil] == 0 && + target.pbOwnSide.effects[PBEffects::LightScreen] == 0 && + target.pbOwnSide.effects[PBEffects::Reflect] == 0 && + target.pbOpposingSide.effects[PBEffects::AuroraVeil] == 0 && + target.pbOpposingSide.effects[PBEffects::LightScreen] == 0 && + target.pbOpposingSide.effects[PBEffects::Reflect] == 0 + battle.pbShowAbilitySplash(battler) + if battler.pbOpposingSide.effects[PBEffects::AuroraVeil] > 0 + battler.pbOpposingSide.effects[PBEffects::AuroraVeil] = 0 + battle.pbDisplay(_INTL("{1}'s Aurora Veil wore off!", battler.pbOpposingTeam)) + end + if battler.pbOpposingSide.effects[PBEffects::LightScreen] > 0 + battler.pbOpposingSide.effects[PBEffects::LightScreen] = 0 + battle.pbDisplay(_INTL("{1}'s Light Screen wore off!", battler.pbOpposingTeam)) + end + if battler.pbOpposingSide.effects[PBEffects::Reflect] > 0 + battler.pbOpposingSide.effects[PBEffects::Reflect] = 0 + battle.pbDisplay(_INTL("{1}'s Reflect wore off!", battler.pbOpposingTeam)) + end + if battler.pbOwnSide.effects[PBEffects::AuroraVeil] > 0 + battler.pbOwnSide.effects[PBEffects::AuroraVeil] = 0 + battle.pbDisplay(_INTL("{1}'s Aurora Veil wore off!", battler.pbTeam)) + end + if battler.pbOwnSide.effects[PBEffects::LightScreen] > 0 + battler.pbOwnSide.effects[PBEffects::LightScreen] = 0 + battle.pbDisplay(_INTL("{1}'s Light Screen wore off!", battler.pbTeam)) + end + if battler.pbOwnSide.effects[PBEffects::Reflect] > 0 + battler.pbOwnSide.effects[PBEffects::Reflect] = 0 + battle.pbDisplay(_INTL("{1}'s Reflect wore off!", battler.pbTeam)) + end + battle.pbHideAbilitySplash(battler) + } +) + BattleHandlers::AbilityOnSwitchIn.add(:SLOWSTART, proc { |ability,battler,battle| battle.pbShowAbilitySplash(battler) diff --git a/Data/Scripts/011_Battle/Gen 8 abilities.rb b/Data/Scripts/011_Battle/Gen 8 abilities.rb deleted file mode 100644 index 955bab63c..000000000 --- a/Data/Scripts/011_Battle/Gen 8 abilities.rb +++ /dev/null @@ -1,351 +0,0 @@ -BattleHandlers::AbilityOnSwitchIn.add(:INTREPIDSWORD, - proc { |ability, battler, battle| - battler.pbRaiseStatStageByAbility(:ATTACK, 1, battler) - } -) - -BattleHandlers::AbilityOnSwitchIn.add(:DAUNTLESSSHIELD, - proc { |ability, battler, battle| - battler.pbRaiseStatStageByAbility(:ATTACK, 1, battler) - } -) - -BattleHandlers::AbilityOnSwitchIn.add(:CURIOUSMEDICINE, - proc { |ability, battler, battle| - has_effect = false - battler.eachAlly do |b| - next if !b.hasAlteredStatStages? - has_effect = true - break - end - next if !has_effect - battle.pbShowAbilitySplash(battler) - battler.eachAlly do |b| - next if !b.hasAlteredStatStages? - b.pbResetStatStages - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s stat changes were removed!", b.pbThis)) - else - battle.pbDisplay(_INTL("{1}'s stat changes were removed by {2}'s {3}!", - b.pbThis, battler.pbThis(true), battler.abilityName)) - end - end - battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::AbilityOnSwitchIn.add(:SCREENCLEANER, - proc { |ability, battler, battle| - next if target.pbOwnSide.effects[PBEffects::AuroraVeil] == 0 && - target.pbOwnSide.effects[PBEffects::LightScreen] == 0 && - target.pbOwnSide.effects[PBEffects::Reflect] == 0 && - target.pbOpposingSide.effects[PBEffects::AuroraVeil] == 0 && - target.pbOpposingSide.effects[PBEffects::LightScreen] == 0 && - target.pbOpposingSide.effects[PBEffects::Reflect] == 0 - battle.pbShowAbilitySplash(battler) - if battler.pbOpposingSide.effects[PBEffects::AuroraVeil] > 0 - battler.pbOpposingSide.effects[PBEffects::AuroraVeil] = 0 - battle.pbDisplay(_INTL("{1}'s Aurora Veil wore off!", battler.pbOpposingTeam)) - end - if battler.pbOpposingSide.effects[PBEffects::LightScreen] > 0 - battler.pbOpposingSide.effects[PBEffects::LightScreen] = 0 - battle.pbDisplay(_INTL("{1}'s Light Screen wore off!", battler.pbOpposingTeam)) - end - if battler.pbOpposingSide.effects[PBEffects::Reflect] > 0 - battler.pbOpposingSide.effects[PBEffects::Reflect] = 0 - battle.pbDisplay(_INTL("{1}'s Reflect wore off!", battler.pbOpposingTeam)) - end - if battler.pbOwnSide.effects[PBEffects::AuroraVeil] > 0 - battler.pbOwnSide.effects[PBEffects::AuroraVeil] = 0 - battle.pbDisplay(_INTL("{1}'s Aurora Veil wore off!", battler.pbTeam)) - end - if battler.pbOwnSide.effects[PBEffects::LightScreen] > 0 - battler.pbOwnSide.effects[PBEffects::LightScreen] = 0 - battle.pbDisplay(_INTL("{1}'s Light Screen wore off!", battler.pbTeam)) - end - if battler.pbOwnSide.effects[PBEffects::Reflect] > 0 - battler.pbOwnSide.effects[PBEffects::Reflect] = 0 - battle.pbDisplay(_INTL("{1}'s Reflect wore off!", battler.pbTeam)) - end - battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::TargetAbilityOnHit.add(:SANDSPIT, - proc { |ability, user, target, move, battle| - pbBattleWeatherAbility(:Sandstorm, battler, battle) - } -) - -BattleHandlers::TargetAbilityOnHit.add(:COTTONDOWN, - proc { |ability, user, target, move, battle| - has_effect = false - battle.eachBattler do |b| - next if !b.pbCanLowerStatStage?(:DEFENSE, target) - has_effect = true - break - end - next if !has_effect - battle.pbShowAbilitySplash(battler) - battle.eachBattler do |b| - b.pbLowerStatStageByAbility(:SPEED, 1, target, false) - end - battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::TargetAbilityOnHit.add(:PERISHBODY, - proc { |ability, user, target, move, battle| - next if !move.pbContactMove?(user) - next if user.fainted? - next if user.effects[PBEffects::PerishSong] > 0 || target.effects[PBEffects::PerishSong] > 0 - battle.pbShowAbilitySplash(target) - if user.affectedByContactEffect?(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - user.effects[PBEffects::PerishSong] = 4 - user.effects[PBEffects::PerishSongUser] = target.index - target.effects[PBEffects::PerishSong] = 4 - target.effects[PBEffects::PerishSongUser] = target.index - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("Both Pokémon will faint in three turns!")) - else - battle.pbDisplay(_INTL("Both Pokémon will faint in three turns because of {1}'s {2}!", - target.pbThis(true), target.abilityName)) - end - end - battle.pbHideAbilitySplash(target) - } -) - -BattleHandlers::TargetAbilityOnHit.add(:WANDERINGSPIRIT, - proc { |ability, user, target, move, battle| - next if !move.pbContactMove?(user) - next if user.ungainableAbility? || [:RECEIVER, :WONDERGUARD].include?(user.ability_id) - oldUserAbil = nil - oldTargetAbil = nil - battle.pbShowAbilitySplash(target) if user.opposes?(target) - if user.affectedByContactEffect?(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - battle.pbShowAbilitySplash(user, true, false) if user.opposes?(target) - oldUserAbil = user.ability - oldTargetAbil = target.ability - user.ability = oldTargetAbil - target.ability = oldUserAbil - if user.opposes?(target) - battle.pbReplaceAbilitySplash(user) - battle.pbReplaceAbilitySplash(target) - end - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1} swapped Abilities with {2}!", target.pbThis, user.pbThis(true))) - else - battle.pbDisplay(_INTL("{1} swapped its {2} Ability with {3}'s {4} Ability!", - target.pbThis, user.abilityName, user.pbThis(true), target.abilityName)) - end - if user.opposes?(target) - battle.pbHideAbilitySplash(user) - battle.pbHideAbilitySplash(target) - end - end - battle.pbHideAbilitySplash(target) if user.opposes?(target) - user.pbOnLosingAbility(oldUserAbil) - target.pbOnLosingAbility(oldTargetAbil) - user.pbTriggerAbilityOnGainingIt - target.pbTriggerAbilityOnGainingIt - } -) - -BattleHandlers::UserAbilityEndOfMove.add(:CHILLINGNEIGH, - proc { |ability, user, targets, move, battle| - next if battle.pbAllFainted?(user.idxOpposingSide) - numFainted = 0 - targets.each { |b| numFainted += 1 if b.damageState.fainted } - next if numFainted == 0 || !user.pbCanRaiseStatStage?(:ATTACK, user) - user.ability_id = :CHILLINGNEIGH # So the As One abilities can just copy this - user.pbRaiseStatStageByAbility(:ATTACK, 1, user) - user.ability_id = ability - } -) - -BattleHandlers::UserAbilityEndOfMove.add(:GRIMNEIGH, - proc { |ability, user, targets, move, battle| - next if battle.pbAllFainted?(user.idxOpposingSide) - numFainted = 0 - targets.each { |b| numFainted += 1 if b.damageState.fainted } - next if numFainted == 0 || !user.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user) - user.ability_id = :GRIMNEIGH # So the As One abilities can just copy this - user.pbRaiseStatStageByAbility(:SPECIAL_ATTACK, 1, user) - user.ability_id = ability - } -) - -BattleHandlers::DamageCalcUserAbility.add(:TRANSISTOR , - proc { |ability, user, target, move, mults, baseDmg, type| - mults[:attack_multiplier] *= 1.5 if type == :ELECTRIC - } -) - -BattleHandlers::DamageCalcUserAbility.add(:DRAGONSMAW , - proc { |ability, user, target, move, mults, baseDmg, type| - mults[:attack_multiplier] *= 1.5 if type == :DRAGON - } -) - -BattleHandlers::DamageCalcUserAbility.add(:PUNKROCK , - proc { |ability, user, target, move, mults, baseDmg, type| - mults[:attack_multiplier] *= 1.3 if move.soundMove? - } -) - -BattleHandlers::DamageCalcTargetAbility.add(:PUNKROCK, - proc { |ability, user, target, move, mults, baseDmg, type| - mults[:final_damage_multiplier] /= 2 if move.soundMove? - } -) - -BattleHandlers::DamageCalcUserAbility.add(:STEELYSPIRIT , - proc { |ability, user, target, move, mults, baseDmg, type| - mults[:final_damage_multiplier] *= 1.5 if type == :STEEL - } -) - -BattleHandlers::DamageCalcUserAllyAbility.add(:STEELYSPIRIT, - proc { |ability, user, target, move, mults, baseDmg, type| - mults[:final_damage_multiplier] *= 1.5 if type == :STEEL - } -) - -BattleHandlers::DamageCalcUserAllyAbility.add(:POWERSPOT, - proc { |ability, user, target, move, mults, baseDmg, type| - mults[:final_damage_multiplier] *= 1.3 - } -) - -BattleHandlers::DamageCalcTargetAbility.add(:ICESCALES, - proc { |ability, user, target, move, mults, baseDmg, type| - mults[:final_damage_multiplier] /= 2 if move.specialMove? - } -) - -BattleHandlers::StatusImmunityAbility.copy(:IMMUNITY, :PASTELVEIL) - -BattleHandlers::StatusImmunityAbility.add(:PASTELVEIL, - proc { |ability, battler, status| - next true if status == :POISON - } -) - -BattleHandlers::AbilityOnSwitchIn.add(:PASTELVEIL, - proc { |ability, battler, battle| - has_effect = false - battler.eachAlly do |b| - next if b.status != :POISON - has_effect = true - break - end - next if !has_effect - battle.pbShowAbilitySplash(battler) - battler.eachAlly do |b| - next if b.status != :POISON - b.pbCureStatus(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s {2} cured {3}'s poisoning!", - battler.pbThis, battler.abilityName, b.pbThis(true))) - end - end - battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::PriorityBracketChangeAbility.add(:QUICKDRAW, - proc { |ability, battler, subPri, battle| - next 1 if subPri == 0 && battle.pbRandom(100) < 30 - } -) - -BattleHandlers::PriorityBracketUseAbility.add(:QUICKDRAW, - proc { |ability, battler, battle| - battle.pbShowAbilitySplash(battler) - battle.pbDisplay(_INTL("{1} made {2} move faster!", battler.abilityName, battler.pbThis(true))) - battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::EORGainItemAbility.add(:BALLFETCH, - proc { |ability, battler, battle| - next if battler.item - next if battle.first_poke_ball.nil? - battle.pbShowAbilitySplash(battler) - battler.item = battle.first_poke_ball - battler.setInitialItem(battler.item) if !battler.initialItem - battle.first_poke_ball = nil - battle.pbDisplay(_INTL("{1} retrieved the thrown {2}!", battler.pbThis, battler.itemName)) - battle.pbHideAbilitySplash(battler) - battler.pbHeldItemTriggerCheck - } -) - -BattleHandlers::AbilityOnSwitchIn.add(:ASONECHILLINGNEIGH, - proc { |ability, battler, battle| - battle.pbShowAbilitySplash(battler) - battle.pbDisplay(_INTL("{1} has two Abilities!", battler.pbThis)) - battle.pbHideAbilitySplash(battler) - battler.ability_id = :UNNERVE - battle.pbShowAbilitySplash(battler) - battle.pbDisplay(_INTL("{1} is too nervous to eat Berries!", battler.pbOpposingTeam)) - battle.pbHideAbilitySplash(battler) - battler.ability_id = ability - } -) - -BattleHandlers::AbilityOnSwitchIn.copy(:ASONECHILLINGNEIGH, :ASONEGRIMNEIGH) -BattleHandlers::UserAbilityEndOfMove.copy(:CHILLINGNEIGH, :ASONECHILLINGNEIGH) -BattleHandlers::UserAbilityEndOfMove.copy(:GRIMNEIGH, :ASONEGRIMNEIGH) - -BattleHandlers::AbilityOnSwitchIn.add(:ICEFACE, - proc { |ability, battler, battle| - next if !battler.isSpecies?(:EISCUE) || battler.form != 1 - next if battler.effectiveWeather != :Hail - battle.pbShowAbilitySplash(battler) - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s {2} activated!", battler.pbThis, battler.abilityName)) - end - battler.pbChangeForm(0, _INTL("{1} transformed!", battler.pbThis)) - battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::EORWeatherAbility.add(:ICEFACE, - proc { |ability, weather, battler, battle| - next if weather != :Hail - next if !battler.canRestoreIceFace || battler.form != 1 - battle.pbShowAbilitySplash(battler) - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s {2} activated!", battler.pbThis, battler.abilityName)) - end - battler.pbChangeForm(0, _INTL("{1} transformed!", battler.pbThis)) - battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::DamageCalcUserAbility.add(:GORILLATACTICS, - proc { |ability, user, target, move, mults, baseDmg, type| - mults[:attack_multiplier] *= 1.5 - } -) - -BattleHandlers::AbilityOnSwitchIn.add(:MIMICRY, - proc { |ability, battler, battle| - next if battle.field.terrain == :None - BattleHandlers.triggerAbilityOnTerrainChange(ability, battler, battle, false) - } -) - - -=begin - -#=============================================================================== - -Neutralizing Gas -Suppresses all other abilities. Once this ability stops applying, triggers all -abilities that activate when gained (if this happens because bearer switches -out, abilities trigger before the replacement switches in). - -=end diff --git a/Data/Scripts/Gen 8 notes.txt b/Data/Scripts/Gen 8 notes.txt index 90cabaff8..cc5476d7b 100644 --- a/Data/Scripts/Gen 8 notes.txt +++ b/Data/Scripts/Gen 8 notes.txt @@ -4,17 +4,6 @@ # To do #=============================================================================== -Some moves have changed properties/effects: -- Parting Shot is able to make the user switch out if its effect is redirected - by Mirror Armor. Throat Spray is triggered and applies before the switch. - (The Throat Spray part is done by default) - -Some abilities have changed effects: -- If another Pokémon faints before a Pokémon with Analytic makes its move, - Analytic calculates whether it would have moved before or after the fainted - Pokémon. In Gen 8, speed- and priority-modifying effects aren't considered, - but in earlier Gens they are. - Other notes: - If a battle ends because of Rocky Helmet damage, the side that the Rocky Helmet holder is on should lose (Gen 7+) or win (Gen 6-). @@ -72,6 +61,13 @@ apply above 179 happiness. Pokémon Camp will not be added. Affection effects an the 179 soft cap/160 evolution threshold may be added (the latter two should be treated as related rather than separate settings). +Some abilities have changed effects: +- If another Pokémon faints before a Pokémon with Analytic makes its move, + Analytic calculates whether it would have moved before or after the fainted + Pokémon. In Gen 8, speed- and priority-modifying effects aren't considered, + but in earlier Gens they are. Ignoring as this would be far too complicated to + care about. + #=============================================================================== # Implemented #=============================================================================== @@ -172,4 +168,9 @@ The game records, for each species, how many have been caught or defeated (counts both wild and trainer battles), and the shiny chance increases for that species because of this. This value is also shown in the Pokédex entry screen. +Some moves have changed properties/effects: +- Parting Shot is able to make the user switch out if its effect is redirected + by Mirror Armor. Throat Spray is triggered and applies before the switch. + (The Throat Spray part is done by default). All this already works this way. + =end