Refactored ability/item/ball battle handlers, added "UltraBeast" species flag for Beast Ball

This commit is contained in:
Maruno17
2021-11-18 22:52:19 +00:00
parent 8307222009
commit 048a18b415
33 changed files with 1265 additions and 1228 deletions

View File

@@ -87,8 +87,6 @@ class Battle
attr_accessor :moldBreaker # True if Mold Breaker applies
attr_reader :struggle # The Struggle move
include Battle::Common
def pbRandom(x); return rand(x); end
#=============================================================================
@@ -703,7 +701,7 @@ class Battle
@field.weather = newWeather
duration = (fixedDuration) ? 5 : -1
if duration>0 && user && user.itemActive?
duration = BattleHandlers.triggerWeatherExtenderItem(user.item,
duration = Battle::ItemEffects.triggerWeatherExtender(user.item,
@field.weather,duration,user,self)
end
@field.weatherDuration = duration
@@ -781,7 +779,7 @@ class Battle
@field.terrain = newTerrain
duration = (fixedDuration) ? 5 : -1
if duration>0 && user && user.itemActive?
duration = BattleHandlers.triggerTerrainExtenderItem(user.item,
duration = Battle::ItemEffects.triggerTerrainExtender(user.item,
newTerrain,duration,user,self)
end
@field.terrainDuration = duration

View File

@@ -1,222 +0,0 @@
module Battle::Common
#=============================================================================
# Store caught Pokémon
#=============================================================================
def pbStorePokemon(pkmn)
# Nickname the Pokémon (unless it's a Shadow Pokémon)
if !pkmn.shadowPokemon?
if pbDisplayConfirm(_INTL("Would you like to give a nickname to {1}?", pkmn.name))
nickname = @scene.pbNameEntry(_INTL("{1}'s nickname?", pkmn.speciesName), pkmn)
pkmn.name = nickname
end
end
# Store the Pokémon
currentBox = @peer.pbCurrentBox
storedBox = @peer.pbStorePokemon(pbPlayer,pkmn)
if storedBox<0
pbDisplayPaused(_INTL("{1} has been added to your party.",pkmn.name))
@initialItems[0][pbPlayer.party.length-1] = pkmn.item_id if @initialItems
return
end
# Messages saying the Pokémon was stored in a PC box
creator = @peer.pbGetStorageCreatorName
curBoxName = @peer.pbBoxName(currentBox)
boxName = @peer.pbBoxName(storedBox)
if storedBox!=currentBox
if creator
pbDisplayPaused(_INTL("Box \"{1}\" on {2}'s PC was full.",curBoxName,creator))
else
pbDisplayPaused(_INTL("Box \"{1}\" on someone's PC was full.",curBoxName))
end
pbDisplayPaused(_INTL("{1} was transferred to box \"{2}\".",pkmn.name,boxName))
else
if creator
pbDisplayPaused(_INTL("{1} was transferred to {2}'s PC.",pkmn.name,creator))
else
pbDisplayPaused(_INTL("{1} was transferred to someone's PC.",pkmn.name))
end
pbDisplayPaused(_INTL("It was stored in box \"{1}\".",boxName))
end
end
# Register all caught Pokémon in the Pokédex, and store them.
def pbRecordAndStoreCaughtPokemon
@caughtPokemon.each do |pkmn|
pbSetCaught(pkmn)
pbSetSeen(pkmn) # In case the form changed upon leaving battle
# Record the Pokémon's species as owned in the Pokédex
if !pbPlayer.owned?(pkmn.species)
pbPlayer.pokedex.set_owned(pkmn.species)
if $player.has_pokedex
pbDisplayPaused(_INTL("{1}'s data was added to the Pokédex.",pkmn.name))
pbPlayer.pokedex.register_last_seen(pkmn)
@scene.pbShowPokedex(pkmn.species)
end
end
# Record a Shadow Pokémon's species as having been caught
pbPlayer.pokedex.set_shadow_pokemon_owned(pkmn.species) if pkmn.shadowPokemon?
# Store caught Pokémon
pbStorePokemon(pkmn)
end
@caughtPokemon.clear
end
#=============================================================================
# Throw a Poké Ball
#=============================================================================
def pbThrowPokeBall(idxBattler,ball,catch_rate=nil,showPlayer=false)
# Determine which Pokémon you're throwing the Poké Ball at
battler = nil
if opposes?(idxBattler)
battler = @battlers[idxBattler]
else
battler = @battlers[idxBattler].pbDirectOpposing(true)
end
battler = battler.allAllies[0] if battler.fainted?
# Messages
itemName = GameData::Item.get(ball).name
if battler.fainted?
if itemName.starts_with_vowel?
pbDisplay(_INTL("{1} threw an {2}!",pbPlayer.name,itemName))
else
pbDisplay(_INTL("{1} threw a {2}!",pbPlayer.name,itemName))
end
pbDisplay(_INTL("But there was no target..."))
return
end
if itemName.starts_with_vowel?
pbDisplayBrief(_INTL("{1} threw an {2}!",pbPlayer.name,itemName))
else
pbDisplayBrief(_INTL("{1} threw a {2}!",pbPlayer.name,itemName))
end
# Animation of opposing trainer blocking Poké Balls (unless it's a Snag Ball
# at a Shadow Pokémon)
if trainerBattle? && !(GameData::Item.get(ball).is_snag_ball? && battler.shadowPokemon?)
@scene.pbThrowAndDeflect(ball,1)
pbDisplay(_INTL("The Trainer blocked your Poké Ball! Don't be a thief!"))
return
end
# Calculate the number of shakes (4=capture)
pkmn = battler.pokemon
@criticalCapture = false
numShakes = pbCaptureCalc(pkmn,battler,catch_rate,ball)
PBDebug.log("[Threw Poké Ball] #{itemName}, #{numShakes} shakes (4=capture)")
# Animation of Ball throw, absorb, shake and capture/burst out
@scene.pbThrow(ball,numShakes,@criticalCapture,battler.index,showPlayer)
# Outcome message
case numShakes
when 0
pbDisplay(_INTL("Oh no! The Pokémon broke free!"))
BallHandlers.onFailCatch(ball,self,battler)
when 1
pbDisplay(_INTL("Aww! It appeared to be caught!"))
BallHandlers.onFailCatch(ball,self,battler)
when 2
pbDisplay(_INTL("Aargh! Almost had it!"))
BallHandlers.onFailCatch(ball,self,battler)
when 3
pbDisplay(_INTL("Gah! It was so close, too!"))
BallHandlers.onFailCatch(ball,self,battler)
when 4
pbDisplayBrief(_INTL("Gotcha! {1} was caught!",pkmn.name))
@scene.pbThrowSuccess # Play capture success jingle
pbRemoveFromParty(battler.index,battler.pokemonIndex)
# Gain Exp
if Settings::GAIN_EXP_FOR_CAPTURE
battler.captured = true
pbGainExp
battler.captured = false
end
battler.pbReset
if pbAllFainted?(battler.index)
@decision = (trainerBattle?) ? 1 : 4 # Battle ended by win/capture
end
# Modify the Pokémon's properties because of the capture
if GameData::Item.get(ball).is_snag_ball?
pkmn.owner = Pokemon::Owner.new_from_trainer(pbPlayer)
end
BallHandlers.onCatch(ball,self,pkmn)
pkmn.poke_ball = ball
pkmn.makeUnmega if pkmn.mega?
pkmn.makeUnprimal
pkmn.update_shadow_moves if pkmn.shadowPokemon?
pkmn.record_first_moves
# Reset form
pkmn.forced_form = nil if MultipleForms.hasFunction?(pkmn.species,"getForm")
@peer.pbOnLeavingBattle(self,pkmn,true,true)
# Make the Poké Ball and data box disappear
@scene.pbHideCaptureBall(idxBattler)
# Save the Pokémon for storage at the end of battle
@caughtPokemon.push(pkmn)
end
if numShakes != 4
@first_poke_ball = ball if !@poke_ball_failed
@poke_ball_failed = true
end
end
#=============================================================================
# Calculate how many shakes a thrown Poké Ball will make (4 = capture)
#=============================================================================
def pbCaptureCalc(pkmn,battler,catch_rate,ball)
return 4 if $DEBUG && Input.press?(Input::CTRL)
# Get a catch rate if one wasn't provided
catch_rate = pkmn.species_data.catch_rate if !catch_rate
# Modify catch_rate depending on the Poké Ball's effect
ultraBeast = [:NIHILEGO, :BUZZWOLE, :PHEROMOSA, :XURKITREE, :CELESTEELA,
:KARTANA, :GUZZLORD, :POIPOLE, :NAGANADEL, :STAKATAKA,
:BLACEPHALON].include?(pkmn.species)
if !ultraBeast || ball == :BEASTBALL
catch_rate = BallHandlers.modifyCatchRate(ball,catch_rate,self,battler,ultraBeast)
else
catch_rate /= 10
end
# First half of the shakes calculation
a = battler.totalhp
b = battler.hp
x = ((3*a-2*b)*catch_rate.to_f)/(3*a)
# Calculation modifiers
if battler.status == :SLEEP || battler.status == :FROZEN
x *= 2.5
elsif battler.status != :NONE
x *= 1.5
end
x = x.floor
x = 1 if x<1
# Definite capture, no need to perform randomness checks
return 4 if x>=255 || BallHandlers.isUnconditional?(ball,self,battler)
# Second half of the shakes calculation
y = ( 65536 / ((255.0/x)**0.1875) ).floor
# Critical capture check
if Settings::ENABLE_CRITICAL_CAPTURES
dex_modifier = 0
numOwned = $player.pokedex.owned_count
if numOwned>600
dex_modifier = 5
elsif numOwned>450
dex_modifier = 4
elsif numOwned>300
dex_modifier = 3
elsif numOwned>150
dex_modifier = 2
elsif numOwned>30
dex_modifier = 1
end
dex_modifier *= 2 if $bag.has?(:CATCHINGCHARM)
c = x * dex_modifier / 12
# Calculate the number of shakes
if c>0 && pbRandom(256)<c
@criticalCapture = true
return 4 if pbRandom(65536)<y
return 0
end
end
# Calculate the number of shakes
numShakes = 0
for i in 0...4
break if numShakes<i
numShakes += 1 if pbRandom(65536)<y
end
return numShakes
end
end

View File

@@ -478,7 +478,7 @@ class Battle
@battlers.each do |b|
next if !b
pbCancelChoice(b.index) # Restore unused items to Bag
BattleHandlers.triggerAbilityOnSwitchOut(b.ability,b,true) if b.abilityActive?
Battle::AbilityEffects.triggerOnSwitchOut(b.ability, b, true) if b.abilityActive?
end
pbParty(0).each_with_index do |pkmn,i|
next if !pkmn

View File

@@ -63,8 +63,8 @@ class Battle
evTotal = 0
GameData::Stat.each_main { |s| evTotal += pkmn.ev[s.id] }
# Modify EV yield based on pkmn's held item
if !BattleHandlers.triggerEVGainModifierItem(pkmn.item,pkmn,evYield)
BattleHandlers.triggerEVGainModifierItem(@initialItems[0][idxParty],pkmn,evYield)
if !Battle::ItemEffects.triggerEVGainModifier(pkmn.item, pkmn, evYield)
Battle::ItemEffects.triggerEVGainModifier(@initialItems[0][idxParty], pkmn, evYield)
end
# Double EV gain because of Pokérus
if pkmn.pokerusStage>=1 # Infected or cured
@@ -147,9 +147,9 @@ class Battle
# Exp. Charm increases Exp gained
exp = exp * 3 / 2 if $bag.has?(:EXPCHARM)
# Modify Exp gain based on pkmn's held item
i = BattleHandlers.triggerExpGainModifierItem(pkmn.item,pkmn,exp)
i = Battle::ItemEffects.triggerExpGainModifier(pkmn.item, pkmn, exp)
if i<0
i = BattleHandlers.triggerExpGainModifierItem(@initialItems[0][idxParty],pkmn,exp)
i = Battle::ItemEffects.triggerExpGainModifier(@initialItems[0][idxParty], pkmn, exp)
end
exp = i if i>=0
# Boost Exp gained with high affection

View File

@@ -155,7 +155,7 @@ class Battle
move = @choices[b.index][2]
pri = move.pbPriority(b)
if b.abilityActive?
pri = BattleHandlers.triggerPriorityChangeAbility(b.ability,b,move,pri)
pri = Battle::AbilityEffects.triggerPriorityChange(b.ability, b, move, pri)
end
bArray[3] = pri
@choices[b.index][4] = pri
@@ -167,8 +167,7 @@ class Battle
subPri = 0
# Abilities (Stall)
if b.abilityActive?
newSubPri = BattleHandlers.triggerPriorityBracketChangeAbility(b.ability,
b,subPri,self)
newSubPri = Battle::AbilityEffects.triggerPriorityBracketChange(b.ability, b, subPri, self)
if subPri!=newSubPri
subPri = newSubPri
b.effects[PBEffects::PriorityAbility] = true
@@ -177,8 +176,7 @@ class Battle
end
# Items (Quick Claw, Custap Berry, Lagging Tail, Full Incense)
if b.itemActive?
newSubPri = BattleHandlers.triggerPriorityBracketChangeItem(b.item,
b,subPri,self)
newSubPri = Battle::ItemEffects.triggerPriorityBracketChange(b.item, b, subPri, self)
if subPri!=newSubPri
subPri = newSubPri
b.effects[PBEffects::PriorityAbility] = false

View File

@@ -56,12 +56,12 @@ class Battle
return true if battler.fainted?
# Ability/item effects that allow switching no matter what
if battler.abilityActive?
if BattleHandlers.triggerCertainSwitchingUserAbility(battler.ability,battler,self)
if Battle::AbilityEffects.triggerCertainSwitching(battler.ability, battler, self)
return true
end
end
if battler.itemActive?
if BattleHandlers.triggerCertainSwitchingUserItem(battler.item,battler,self)
if Battle::ItemEffects.triggerCertainSwitching(battler.item, battler, self)
return true
end
end
@@ -75,7 +75,7 @@ class Battle
# Trapping abilities/items
allOtherSideBattlers(idxBattler).each do |b|
next if !b.abilityActive?
if BattleHandlers.triggerTrappingTargetAbility(b.ability,battler,b,self)
if Battle::AbilityEffects.triggerTrappingByTarget(b.ability, battler, b, self)
partyScene.pbDisplay(_INTL("{1}'s {2} prevents switching!",
b.pbThis,b.abilityName)) if partyScene
return false
@@ -83,7 +83,7 @@ class Battle
end
allOtherSideBattlers(idxBattler).each do |b|
next if !b.itemActive?
if BattleHandlers.triggerTrappingTargetItem(b.item,battler,b,self)
if Battle::ItemEffects.triggerTrappingByTarget(b.item,battler,b,self)
partyScene.pbDisplay(_INTL("{1}'s {2} prevents switching!",
b.pbThis,b.itemName)) if partyScene
return false
@@ -353,12 +353,12 @@ class Battle
b.pbContinualAbilityChecks(true)
# Abilities that trigger upon switching in
if (!b.fainted? && b.unstoppableAbility?) || b.abilityActive?
BattleHandlers.triggerAbilityOnSwitchIn(b.ability, b, self)
Battle::AbilityEffects.triggerOnSwitchIn(b.ability, b, self)
end
pbEndPrimordialWeather # Checking this again just in case
# Items that trigger upon switching in (Air Balloon message)
if b.itemActive?
BattleHandlers.triggerItemOnSwitchIn(b.item, b, self)
Battle::ItemEffects.triggerOnSwitchIn(b.item, b, self)
end
# Berry check, status-curing ability check
b.pbHeldItemTriggerCheck

View File

@@ -8,15 +8,15 @@ class Battle
return false if !@canRun && !battler.opposes?
return true if battler.pbHasType?(:GHOST) && Settings::MORE_TYPE_EFFECTS
return true if battler.abilityActive? &&
BattleHandlers.triggerRunFromBattleAbility(battler.ability,battler)
Battle::AbilityEffects.triggerCertainEscapeFromBattle(battler.ability, battler)
return true if battler.itemActive? &&
BattleHandlers.triggerRunFromBattleItem(battler.item,battler)
Battle::ItemEffects.triggerCertainEscapeFromBattle(battler.item, battler)
return false if battler.trappedInBattle?
allOtherSideBattlers(idxBattler).each do |b|
return false if b.abilityActive? &&
BattleHandlers.triggerTrappingTargetAbility(b.ability,battler,b,self)
Battle::AbilityEffects.triggerTrappingByTarget(b.ability, battler, b, self)
return false if b.itemActive? &&
BattleHandlers.triggerTrappingTargetItem(b.item,battler,b,self)
Battle::ItemEffects.triggerTrappingByTarget(b.item, battler, b, self)
end
return true
end
@@ -76,7 +76,7 @@ class Battle
end
# Abilities that guarantee escape
if battler.abilityActive?
if BattleHandlers.triggerRunFromBattleAbility(battler.ability,battler)
if Battle::AbilityEffects.triggerCertainEscapeFromBattle(battler.ability, battler)
pbShowAbilitySplash(battler,true)
pbHideAbilitySplash(battler)
pbSEPlay("Battle flee")
@@ -87,10 +87,9 @@ class Battle
end
# Held items that guarantee escape
if battler.itemActive?
if BattleHandlers.triggerRunFromBattleItem(battler.item,battler)
if Battle::ItemEffects.triggerCertainEscapeFromBattle(battler.item, battler)
pbSEPlay("Battle flee")
pbDisplayPaused(_INTL("{1} fled using its {2}!",
battler.pbThis,battler.itemName))
pbDisplayPaused(_INTL("{1} fled using its {2}!", battler.pbThis,battler.itemName))
@decision = 3
return 1
end
@@ -103,14 +102,14 @@ class Battle
# Trapping abilities/items
allOtherSideBattlers(idxBattler).each do |b|
next if !b.abilityActive?
if BattleHandlers.triggerTrappingTargetAbility(b.ability,battler,b,self)
if Battle::AbilityEffects.triggerTrappingByTarget(b.ability, battler, b, self)
pbDisplayPaused(_INTL("{1} prevents escape with {2}!",b.pbThis,b.abilityName))
return 0
end
end
allOtherSideBattlers(idxBattler).each do |b|
next if !b.itemActive?
if BattleHandlers.triggerTrappingTargetItem(b.item,battler,b,self)
if Battle::ItemEffects.triggerTrappingByTarget(b.item, battler, b, self)
pbDisplayPaused(_INTL("{1} prevents escape with {2}!",b.pbThis,b.itemName))
return 0
end

View File

@@ -132,7 +132,7 @@ class Battle
old_ability = battler.ability_id
# Break Illusion
if battler.hasActiveAbility?(:ILLUSION)
BattleHandlers.triggerTargetAbilityOnHit(battler.ability,nil,battler,nil,self)
Battle::AbilityEffects.triggerOnBeingHit(battler.ability, nil, battler, nil, self)
end
# Mega Evolve
case battler.pokemon.megaMessage

View File

@@ -6,9 +6,9 @@ class Battle
def pbAttackPhasePriorityChangeMessages
pbPriority.each do |b|
if b.effects[PBEffects::PriorityAbility] && b.abilityActive?
BattleHandlers.triggerPriorityBracketUseAbility(b.ability,b,self)
Battle::AbilityEffects.triggerPriorityBracketUse(b.ability, b, self)
elsif b.effects[PBEffects::PriorityItem] && b.itemActive?
BattleHandlers.triggerPriorityBracketUseItem(b.item,b,self)
Battle::ItemEffects.triggerPriorityBracketUse(b.item, b, self)
end
end
end

View File

@@ -70,7 +70,7 @@ class Battle
priority.each do |b|
# Weather-related abilities
if b.abilityActive?
BattleHandlers.triggerEORWeatherAbility(b.ability, b.effectiveWeather, b, self)
Battle::AbilityEffects.triggerEndOfRoundWeather(b.ability, b.effectiveWeather, b, self)
b.pbFaint if b.fainted?
end
# Weather damage
@@ -279,9 +279,9 @@ class Battle
pbDisplay(_INTL("{1}'s HP was restored.",b.pbThis))
end
# Healer, Hydration, Shed Skin
BattleHandlers.triggerEORHealingAbility(b.ability,b,self) if b.abilityActive?
Battle::AbilityEffects.triggerEndOfRoundHealing(b.ability, b, self) if b.abilityActive?
# Black Sludge, Leftovers
BattleHandlers.triggerEORHealingItem(b.item,b,self) if b.itemActive?
Battle::ItemEffects.triggerEndOfRoundHealing(b.item, b, self) if b.itemActive?
end
# Self-curing of status due to affection
if Settings::AFFECTION_EFFECTS && @internalBattle
@@ -597,11 +597,11 @@ class Battle
end
end
# Bad Dreams, Moody, Speed Boost
BattleHandlers.triggerEOREffectAbility(b.ability,b,self) if b.abilityActive?
Battle::AbilityEffects.triggerEndOfRoundEffect(b.ability, b, self) if b.abilityActive?
# Flame Orb, Sticky Barb, Toxic Orb
BattleHandlers.triggerEOREffectItem(b.item,b,self) if b.itemActive?
Battle::ItemEffects.triggerEndOfRoundEffect(b.item, b, self) if b.itemActive?
# Harvest, Pickup, Ball Fetch
BattleHandlers.triggerEORGainItemAbility(b.ability,b,self) if b.abilityActive?
Battle::AbilityEffects.triggerEndOfRoundGainItem(b.ability, b, self) if b.abilityActive?
end
pbGainExp
return if @decision>0