Snowstorm, forfeiting trainer battles, battle outcome values

This commit is contained in:
Maruno17
2024-06-15 21:29:00 +01:00
parent 22b33ca6c2
commit 8e9417c3b7
41 changed files with 284 additions and 214 deletions

View File

@@ -1,4 +1,4 @@
# Results of battle:
# Results of battle (see module Outcome):
# 0 - Undecided or aborted
# 1 - Player won
# 2 - Player lost
@@ -38,6 +38,29 @@
# (There is no guarantee that this list is complete.)
class Battle
module Outcome
UNDECIDED = 0
WIN = 1
LOSE = 2 # Also used when player forfeits a trainer battle
FLEE = 3 # Player or wild Pokémon ran away, count as a win
CATCH = 4 # Counts as a win
DRAW = 5
def self.decided?(decision)
return decision != UNDECIDED
end
def self.should_black_out?(decision)
return decision == LOSE || decision == DRAW
end
def self.success?(decision)
return !self.should_black_out?(decision)
end
end
#-----------------------------------------------------------------------------
attr_reader :scene # Scene object for this battle
attr_reader :peer
attr_reader :field # Effects common to the whole of a battle
@@ -50,7 +73,7 @@ class Battle
attr_accessor :time # Time of day (0=day, 1=eve, 2=night)
attr_accessor :environment # Battle surroundings (for mechanics purposes)
attr_reader :turnCount
attr_accessor :decision # Decision: 0=undecided; 1=win; 2=loss; 3=escaped; 4=caught
attr_accessor :decision # Outcome of battle
attr_reader :player # Player trainer (or array of trainers)
attr_reader :opponent # Opponent trainer (or array of trainers)
attr_accessor :items # Items held by opponents
@@ -114,7 +137,7 @@ class Battle
@time = 0
@environment = :None # e.g. Tall grass, cave, still water
@turnCount = 0
@decision = 0
@decision = Outcome::UNDECIDED
@caughtPokemon = []
player = [player] if !player.nil? && !player.is_a?(Array)
opponent = [opponent] if !opponent.nil? && !opponent.is_a?(Array)
@@ -173,6 +196,10 @@ class Battle
@battleAI = AI.new(self)
end
def decided?
return Outcome.decided?(@decision)
end
#=============================================================================
# Information about the type and size of the battle
#=============================================================================
@@ -730,6 +757,7 @@ class Battle
when :Rain then pbDisplay(_INTL("It started to rain!"))
when :Sandstorm then pbDisplay(_INTL("A sandstorm brewed!"))
when :Hail then pbDisplay(_INTL("It started to hail!"))
when :Snowstorm then pbDisplay(_INTL("It started to snow!"))
when :HarshSun then pbDisplay(_INTL("The sunlight turned extremely harsh!"))
when :HeavyRain then pbDisplay(_INTL("A heavy rain began to fall!"))
when :StrongWinds then pbDisplay(_INTL("Mysterious strong winds are protecting Flying-type Pokémon!"))

View File

@@ -270,7 +270,7 @@ class Battle
begin
pbStartBattleCore
rescue BattleAbortedException
@decision = 0
@decision = Outcome::UNDECIDED
@scene.pbEndBattle(@decision)
end
return @decision
@@ -292,6 +292,7 @@ class Battle
when :Rain then pbDisplay(_INTL("It is raining."))
when :Sandstorm then pbDisplay(_INTL("A sandstorm is raging."))
when :Hail then pbDisplay(_INTL("Hail is falling."))
when :Snowstorm then pbDisplay(_INTL("It is snowing."))
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."))
@@ -334,13 +335,13 @@ class Battle
PBDebug.log("")
# Command phase
PBDebug.logonerr { pbCommandPhase }
break if @decision > 0
break if decided?
# Attack phase
PBDebug.logonerr { pbAttackPhase }
break if @decision > 0
break if decided?
# End of round phase
PBDebug.logonerr { pbEndOfRoundPhase }
break if @decision > 0
break if decided?
@turnCount += 1
end
pbEndOfBattle
@@ -404,10 +405,9 @@ class Battle
def pbEndOfBattle
oldDecision = @decision
@decision = 4 if @decision == 1 && wildBattle? && @caughtPokemon.length > 0
@decision = Outcome::CATCH if @decision == Outcome::WIN && wildBattle? && @caughtPokemon.length > 0
case oldDecision
##### WIN #####
when 1
when Outcome::WIN
PBDebug.log("")
PBDebug.log_header("===== Player won =====")
PBDebug.log("")
@@ -432,33 +432,34 @@ class Battle
PBDebug.log("")
end
# Gain money from winning a trainer battle, and from Pay Day
pbGainMoney if @decision != 4
pbGainMoney if @decision != Outcome::CATCH
# Hide remaining trainer
@scene.pbShowOpponent(@opponent.length) if trainerBattle? && @caughtPokemon.length > 0
##### LOSE, DRAW #####
when 2, 5
when Outcome::LOSE, Outcome::DRAW
PBDebug.log("")
PBDebug.log_header("===== Player lost =====") if @decision == 2
PBDebug.log_header("===== Player drew with opponent =====") if @decision == 5
PBDebug.log_header("===== Player lost =====") if @decision == Outcome::LOSE
PBDebug.log_header("===== Player drew with opponent =====") if @decision == Outcome::DRAW
PBDebug.log("")
if @internalBattle
pbDisplayPaused(_INTL("You have no more Pokémon that can fight!"))
if trainerBattle?
case @opponent.length
when 1
pbDisplayPaused(_INTL("You lost against {1}!", @opponent[0].full_name))
when 2
pbDisplayPaused(_INTL("You lost against {1} and {2}!",
@opponent[0].full_name, @opponent[1].full_name))
when 3
pbDisplayPaused(_INTL("You lost against {1}, {2} and {3}!",
@opponent[0].full_name, @opponent[1].full_name, @opponent[2].full_name))
if pbPlayerBattlerCount == 0
pbDisplayPaused(_INTL("You have no more Pokémon that can fight!"))
if trainerBattle?
case @opponent.length
when 1
pbDisplayPaused(_INTL("You lost against {1}!", @opponent[0].full_name))
when 2
pbDisplayPaused(_INTL("You lost against {1} and {2}!",
@opponent[0].full_name, @opponent[1].full_name))
when 3
pbDisplayPaused(_INTL("You lost against {1}, {2} and {3}!",
@opponent[0].full_name, @opponent[1].full_name, @opponent[2].full_name))
end
end
end
# Lose money from losing a battle
pbLoseMoney
pbDisplayPaused(_INTL("You blacked out!")) if !@canLose
elsif @decision == 2 # Lost in a Battle Frontier battle
pbDisplayPaused(_INTL("You blacked out!")) if !@canLose && pbPlayerBattlerCount == 0
elsif @decision == Outcome::LOSE # Lost in a Battle Frontier battle
if @opponent
@opponent.each_with_index do |trainer, i|
@scene.pbShowOpponent(i)
@@ -469,8 +470,7 @@ class Battle
PBDebug.log("")
end
end
##### CAUGHT WILD POKÉMON #####
when 4
when Outcome::CATCH
PBDebug.log("")
PBDebug.log_header("===== Pokémon caught =====")
PBDebug.log("")
@@ -479,7 +479,7 @@ class Battle
# Register captured Pokémon in the Pokédex, and store them
pbRecordAndStoreCaughtPokemon
# Collect Pay Day money in a wild battle that ended in a capture
pbGainMoney if @decision == 4
pbGainMoney if @decision == Outcome::CATCH
# Pass on Pokérus within the party
if @internalBattle
infected = []
@@ -526,11 +526,11 @@ class Battle
hpTotals[side] += pkmn.hp
end
end
return 1 if counts[0] > counts[1] # Win (player has more able Pokémon)
return 2 if counts[0] < counts[1] # Loss (foe has more able Pokémon)
return 1 if hpTotals[0] > hpTotals[1] # Win (player has more HP in total)
return 2 if hpTotals[0] < hpTotals[1] # Loss (foe has more HP in total)
return 5 # Draw
return Outcome::WIN if counts[0] > counts[1] # Win (player has more able Pokémon)
return Outcome::LOSE if counts[0] < counts[1] # Loss (foe has more able Pokémon)
return Outcome::WIN if hpTotals[0] > hpTotals[1] # Win (player has more HP in total)
return Outcome::LOSE if hpTotals[0] < hpTotals[1] # Loss (foe has more HP in total)
return Outcome::DRAW
end
# Unused
@@ -545,24 +545,24 @@ class Battle
end
hpTotals[side] /= counts[side] if counts[side] > 1
end
return 1 if counts[0] > counts[1] # Win (player has more able Pokémon)
return 2 if counts[0] < counts[1] # Loss (foe has more able Pokémon)
return 1 if hpTotals[0] > hpTotals[1] # Win (player has a bigger average HP %)
return 2 if hpTotals[0] < hpTotals[1] # Loss (foe has a bigger average HP %)
return 5 # Draw
return Outcome::WIN if counts[0] > counts[1] # Win (player has more able Pokémon)
return Outcome::LOSE if counts[0] < counts[1] # Loss (foe has more able Pokémon)
return Outcome::WIN if hpTotals[0] > hpTotals[1] # Win (player has a bigger average HP %)
return Outcome::LOSE if hpTotals[0] < hpTotals[1] # Loss (foe has a bigger average HP %)
return Outcome::DRAW
end
def pbDecisionOnDraw; return 5; end # Draw
def pbDecisionOnDraw; return Outcome::DRAW; end # Draw
def pbJudge
fainted1 = pbAllFainted?(0)
fainted2 = pbAllFainted?(1)
if fainted1 && fainted2
@decision = pbDecisionOnDraw # Draw
@decision = pbDecisionOnDraw
elsif fainted1
@decision = 2 # Loss
@decision = Outcome::LOSE
elsif fainted2
@decision = 1 # Win
@decision = Outcome::WIN
end
end
end

View File

@@ -140,10 +140,10 @@ class Battle
# General switching method that checks if any Pokémon need to be sent out and,
# if so, does. Called at the end of each round.
def pbEORSwitch(favorDraws = false)
return if @decision > 0 && !favorDraws
return if @decision == 5 && favorDraws
return if decided? && !favorDraws
return if @decision == Outcome::DRAW && favorDraws
pbJudge
return if @decision > 0
return if decided?
# Check through each fainted battler to see if that spot can be filled.
switched = []
loop do

View File

@@ -32,19 +32,19 @@ class Battle
commands.push(_INTL("Treat as a capture")) if wildBattle?
commands.push(_INTL("Cancel"))
case pbShowCommands(_INTL("Choose the outcome of this battle."), commands)
when 0 # Win
@decision = 1
when 1 # Loss
@decision = 2
when 2 # Draw
@decision = 5
when 3 # Run away/forfeit
when 0
@decision = Outcome::WIN
when 1
@decision = Outcome::LOSE
when 2
@decision = Outcome::DRAW
when 3
pbSEPlay("Battle flee")
pbDisplayPaused(_INTL("You got away safely!"))
@decision = 3
when 4 # Capture
@decision = Outcome::FLEE
when 4
return -1 if trainerBattle?
@decision = 4
@decision = Outcome::CATCH
else
return -1
end
@@ -72,11 +72,19 @@ class Battle
# Running from trainer battles
if trainerBattle?
if @internalBattle
pbDisplayPaused(_INTL("No! There's no running from a Trainer battle!"))
if Settings::CAN_FORFEIT_TRAINER_BATTLES
pbDisplayPaused(_INTL("Would you like to give up on this battle and quit now?"))
if pbDisplayConfirm(_INTL("Quitting the battle is the same as losing the battle."))
@decision = Outcome::LOSE # Treated as a loss
return 1
end
else
pbDisplayPaused(_INTL("No! There's no running from a Trainer battle!"))
end
elsif pbDisplayConfirm(_INTL("Would you like to forfeit the match and quit now?"))
pbSEPlay("Battle flee")
pbDisplay(_INTL("{1} forfeited the match!", self.pbPlayer.name))
@decision = 3
@decision = Outcome::FLEE
return 1
end
return 0
@@ -89,7 +97,7 @@ class Battle
if battler.pbHasType?(:GHOST) && Settings::MORE_TYPE_EFFECTS
pbSEPlay("Battle flee")
pbDisplayPaused(_INTL("You got away safely!"))
@decision = 3
@decision = Outcome::FLEE
return 1
end
# Abilities that guarantee escape
@@ -99,7 +107,7 @@ class Battle
pbHideAbilitySplash(battler)
pbSEPlay("Battle flee")
pbDisplayPaused(_INTL("You got away safely!"))
@decision = 3
@decision = Outcome::FLEE
return 1
end
# Held items that guarantee escape
@@ -107,7 +115,7 @@ class Battle
Battle::ItemEffects.triggerCertainEscapeFromBattle(battler.item, battler)
pbSEPlay("Battle flee")
pbDisplayPaused(_INTL("{1} fled using its {2}!", battler.pbThis, battler.itemName))
@decision = 3
@decision = Outcome::FLEE
return 1
end
# Other certain trapping effects
@@ -151,7 +159,7 @@ class Battle
if rate >= 256 || @battleAI.pbAIRandom(256) < rate
pbSEPlay("Battle flee")
pbDisplayPaused(_INTL("You got away safely!"))
@decision = 3
@decision = Outcome::FLEE
return 1
end
pbDisplayPaused(_INTL("You couldn't get away!"))

View File

@@ -187,7 +187,7 @@ class Battle
end
# Choose actions for the round (player first, then AI)
pbCommandPhaseLoop(true) # Player chooses their actions
if @decision != 0 # Battle ended, stop choosing actions
if decided? # Battle ended, stop choosing actions
@command_phase = false
return
end
@@ -201,7 +201,7 @@ class Battle
actioned = []
idxBattler = -1
loop do
break if @decision != 0 # Battle ended, stop choosing actions
break if decided? # Battle ended, stop choosing actions
idxBattler += 1
break if idxBattler >= @battlers.length
next if !@battlers[idxBattler] || pbOwnedByPlayer?(idxBattler) != isPlayer

View File

@@ -40,7 +40,7 @@ class Battle
# Use Pursuit
@choices[b.index][3] = idxSwitcher # Change Pursuit's target
b.pbProcessTurn(@choices[b.index], false)
break if @decision > 0 || @battlers[idxSwitcher].fainted?
break if decided? || @battlers[idxSwitcher].fainted?
end
@switching = false
end
@@ -55,7 +55,7 @@ class Battle
pbMessageOnRecall(b)
# Pursuit interrupts switching
pbPursuit(b.index)
return if @decision > 0
return if decided?
# Switch Pokémon
allBattlers.each do |b2|
b2.droppedBelowHalfHP = false
@@ -84,7 +84,7 @@ class Battle
else
next
end
return if @decision > 0
return if decided?
end
pbCalculatePriority if Settings::RECALCULATE_TURN_ORDER_AFTER_SPEED_CHANGES
end
@@ -118,7 +118,7 @@ class Battle
advance = b.pbProcessTurn(@choices[b.index])
break if advance
end
return if @decision > 0
return if decided?
next if advance
# Regular priority order
priority.each do |b|
@@ -128,7 +128,7 @@ class Battle
advance = b.pbProcessTurn(@choices[b.index])
break if advance
end
return if @decision > 0
return if decided?
next if advance
# Quashed
if Settings::MECHANICS_GENERATION >= 8
@@ -155,7 +155,7 @@ class Battle
break if advance || !moreQuash
end
end
return if @decision > 0
return if decided?
next if advance
# Check for all done
priority.each do |b|
@@ -193,9 +193,9 @@ class Battle
pbAttackPhasePriorityChangeMessages
pbAttackPhaseCall
pbAttackPhaseSwitch
return if @decision > 0
return if decided?
pbAttackPhaseItems
return if @decision > 0
return if decided?
pbAttackPhaseMegaEvolution
pbAttackPhaseMoves
end

View File

@@ -14,6 +14,7 @@ class Battle
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 :Snowstorm then pbDisplay(_INTL("The snow stopped."))
when :ShadowSky then pbDisplay(_INTL("The shadow sky faded."))
end
@field.weather = :None
@@ -31,6 +32,7 @@ class Battle
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 :Snowstorm then pbDisplay(_INTL("The snow is blowing about!"))
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."))
@@ -390,7 +392,6 @@ class Battle
(perishSongUsers.find_all { |idxBattler| !opposes?(idxBattler) }.length == perishSongUsers.length))
pbJudgeCheckpoint(@battlers[perishSongUsers[0]])
end
return if @decision > 0
end
#=============================================================================
@@ -675,7 +676,7 @@ class Battle
# Effects that apply to a battler that wear off after a number of rounds
pbEOREndBattlerEffects(priority)
# Check for end of battle (i.e. because of Perish Song)
if @decision > 0
if decided?
pbGainExp
return
end
@@ -702,12 +703,12 @@ class Battle
end
end
pbGainExp
return if @decision > 0
return if decided?
# Form checks
priority.each { |battler| battler.pbCheckForm(true) }
# Switch Pokémon in if possible
pbEORSwitch
return if @decision > 0
return if decided?
# In battles with at least one side of size 3+, move battlers around if none
# are near to any foes
pbEORShiftDistantBattlers