Merge branch 'ai' into dev

This commit is contained in:
Maruno17
2023-05-14 18:36:25 +01:00
160 changed files with 75932 additions and 5730 deletions

View File

@@ -84,6 +84,7 @@ class Battle
attr_accessor :poke_ball_failed # Set after first_poke_ball to prevent it being set again
attr_reader :switching # True if during the switching phase of the round
attr_reader :futureSight # True if Future Sight is hitting
attr_reader :command_phase
attr_reader :endOfRound # True during the end of round
attr_accessor :moldBreaker # True if Mold Breaker applies
attr_reader :struggle # The Struggle move
@@ -159,15 +160,12 @@ class Battle
@lastMoveUser = -1
@switching = false
@futureSight = false
@command_phase = false
@endOfRound = false
@moldBreaker = false
@runCommand = 0
@nextPickupUse = 0
if GameData::Move.exists?(:STRUGGLE)
@struggle = Move.from_pokemon_move(self, Pokemon::Move.new(:STRUGGLE))
else
@struggle = Move::Struggle.new(self, nil)
end
@struggle = Move::Struggle.new(self, nil)
@mega_rings = []
GameData::Item.each { |item| @mega_rings.push(item.id) if item.has_flag?("MegaRing") }
@battleAI = AI.new(self)

View File

@@ -246,7 +246,8 @@ class Battle
#=============================================================================
def pbStartBattle
PBDebug.log("")
PBDebug.log("******************************************")
PBDebug.log("================================================================")
PBDebug.log("")
logMsg = "[Started battle] "
if @sideSizes[0] == 1 && @sideSizes[1] == 1
logMsg += "Single "
@@ -278,6 +279,7 @@ class Battle
def pbStartBattleCore
# Set up the battlers on each side
sendOuts = pbSetUpSides
@battleAI.create_ai_objects
# Create all the sprites and play the battle intro animation
@scene.pbStartBattle(self)
# Show trainers on both sides sending out Pokémon
@@ -321,7 +323,7 @@ class Battle
@turnCount = 0
loop do # Now begin the battle loop
PBDebug.log("")
PBDebug.log("***Round #{@turnCount + 1}***")
PBDebug.log_header("===== Round #{@turnCount + 1} =====")
if @debug && @turnCount >= 100
@decision = pbDecisionOnTime
PBDebug.log("")
@@ -407,7 +409,8 @@ class Battle
##### WIN #####
when 1
PBDebug.log("")
PBDebug.log("***Player won***")
PBDebug.log_header("===== Player won =====")
PBDebug.log("")
if trainerBattle?
@scene.pbTrainerBattleSuccess
case @opponent.length
@@ -426,6 +429,7 @@ class Battle
msg = "..." if !msg || msg.empty?
pbDisplayPaused(msg.gsub(/\\[Pp][Nn]/, pbPlayer.name))
end
PBDebug.log("")
end
# Gain money from winning a trainer battle, and from Pay Day
pbGainMoney if @decision != 4
@@ -434,8 +438,9 @@ class Battle
##### LOSE, DRAW #####
when 2, 5
PBDebug.log("")
PBDebug.log("***Player lost***") if @decision == 2
PBDebug.log("***Player drew with opponent***") if @decision == 5
PBDebug.log_header("===== Player lost =====") if @decision == 2
PBDebug.log_header("===== Player drew with opponent =====") if @decision == 5
PBDebug.log("")
if @internalBattle
pbDisplayPaused(_INTL("You have no more Pokémon that can fight!"))
if trainerBattle?
@@ -461,10 +466,14 @@ class Battle
msg = "..." if !msg || msg.empty?
pbDisplayPaused(msg.gsub(/\\[Pp][Nn]/, pbPlayer.name))
end
PBDebug.log("")
end
end
##### CAUGHT WILD POKÉMON #####
when 4
PBDebug.log("")
PBDebug.log_header("===== Pokémon caught =====")
PBDebug.log("")
@scene.pbWildBattleSuccess if !Settings::GAIN_EXP_FOR_CAPTURE
end
# Register captured Pokémon in the Pokédex, and store them

View File

@@ -243,14 +243,14 @@ class Battle
end
end
# Write the priority order to the debug log
logMsg = (fullCalc) ? "[Round order] " : "[Round order recalculated] "
comma = false
@priority.each do |entry|
logMsg += ", " if comma
logMsg += "#{entry[0].pbThis(comma)} (#{entry[0].index})"
comma = true
if fullCalc && $INTERNAL
logMsg = "[Round order] "
@priority.each_with_index do |entry, i|
logMsg += ", " if i > 0
logMsg += "#{entry[0].pbThis(i > 0)} (#{entry[0].index})"
end
PBDebug.log(logMsg)
end
PBDebug.log(logMsg)
end
end

View File

@@ -6,7 +6,7 @@ class Battle
# battle.
# NOTE: Messages are only shown while in the party screen when choosing a
# command for the next round.
def pbCanSwitchLax?(idxBattler, idxParty, partyScene = nil)
def pbCanSwitchIn?(idxBattler, idxParty, partyScene = nil)
return true if idxParty < 0
party = pbParty(idxBattler)
return false if idxParty >= party.length
@@ -18,8 +18,7 @@ class Battle
if !pbIsOwner?(idxBattler, idxParty)
if partyScene
owner = pbGetOwnerFromPartyIndex(idxBattler, idxParty)
partyScene.pbDisplay(_INTL("You can't switch {1}'s Pokémon with one of yours!",
owner.name))
partyScene.pbDisplay(_INTL("You can't switch {1}'s Pokémon with one of yours!", owner.name))
end
return false
end
@@ -35,30 +34,15 @@ class Battle
end
# Check whether the currently active Pokémon (at battler index idxBattler) can
# switch out (and that its replacement at party index idxParty can switch in).
# NOTE: Messages are only shown while in the party screen when choosing a
# command for the next round.
def pbCanSwitch?(idxBattler, idxParty = -1, partyScene = nil)
# Check whether party Pokémon can switch in
return false if !pbCanSwitchLax?(idxBattler, idxParty, partyScene)
# Make sure another battler isn't already choosing to switch to the party
# Pokémon
allSameSideBattlers(idxBattler).each do |b|
next if choices[b.index][0] != :SwitchOut || choices[b.index][1] != idxParty
partyScene&.pbDisplay(_INTL("{1} has already been selected.",
pbParty(idxBattler)[idxParty].name))
return false
end
# Check whether battler can switch out
# switch out.
def pbCanSwitchOut?(idxBattler, partyScene = nil)
battler = @battlers[idxBattler]
return true if battler.fainted?
# Ability/item effects that allow switching no matter what
if battler.abilityActive? &&
Battle::AbilityEffects.triggerCertainSwitching(battler.ability, battler, self)
if battler.abilityActive? && Battle::AbilityEffects.triggerCertainSwitching(battler.ability, battler, self)
return true
end
if battler.itemActive? &&
Battle::ItemEffects.triggerCertainSwitching(battler.item, battler, self)
if battler.itemActive? && Battle::ItemEffects.triggerCertainSwitching(battler.item, battler, self)
return true
end
# Other certain switching effects
@@ -72,25 +56,42 @@ class Battle
allOtherSideBattlers(idxBattler).each do |b|
next if !b.abilityActive?
if Battle::AbilityEffects.triggerTrappingByTarget(b.ability, battler, b, self)
partyScene&.pbDisplay(_INTL("{1}'s {2} prevents switching!",
b.pbThis, b.abilityName))
partyScene&.pbDisplay(_INTL("{1}'s {2} prevents switching!", b.pbThis, b.abilityName))
return false
end
end
allOtherSideBattlers(idxBattler).each do |b|
next if !b.itemActive?
if Battle::ItemEffects.triggerTrappingByTarget(b.item, battler, b, self)
partyScene&.pbDisplay(_INTL("{1}'s {2} prevents switching!",
b.pbThis, b.itemName))
partyScene&.pbDisplay(_INTL("{1}'s {2} prevents switching!", b.pbThis, b.itemName))
return false
end
end
return true
end
# Check whether the currently active Pokémon (at battler index idxBattler) can
# switch out (and that its replacement at party index idxParty can switch in).
# NOTE: Messages are only shown while in the party screen when choosing a
# command for the next round.
def pbCanSwitch?(idxBattler, idxParty = -1, partyScene = nil)
# Check whether party Pokémon can switch in
return false if !pbCanSwitchIn?(idxBattler, idxParty, partyScene)
# Make sure another battler isn't already choosing to switch to the party
# Pokémon
allSameSideBattlers(idxBattler).each do |b|
next if choices[b.index][0] != :SwitchOut || choices[b.index][1] != idxParty
partyScene&.pbDisplay(_INTL("{1} has already been selected.",
pbParty(idxBattler)[idxParty].name))
return false
end
# Check whether battler can switch out
return pbCanSwitchOut?(idxBattler, partyScene)
end
def pbCanChooseNonActive?(idxBattler)
pbParty(idxBattler).each_with_index do |_pkmn, i|
return true if pbCanSwitchLax?(idxBattler, i)
return true if pbCanSwitchIn?(idxBattler, i)
end
return false
end
@@ -113,7 +114,7 @@ class Battle
ret = -1
@scene.pbPartyScreen(idxBattler, canCancel) do |idxParty, partyScene|
if checkLaxOnly
next false if !pbCanSwitchLax?(idxBattler, idxParty, partyScene)
next false if !pbCanSwitchIn?(idxBattler, idxParty, partyScene)
elsif !pbCanSwitch?(idxBattler, idxParty, partyScene)
next false
end
@@ -129,8 +130,8 @@ class Battle
# For choosing a replacement Pokémon when prompted in the middle of other
# things happening (U-turn, Baton Pass, in def pbEORSwitch).
def pbSwitchInBetween(idxBattler, checkLaxOnly = false, canCancel = false)
return pbPartyScreen(idxBattler, checkLaxOnly, canCancel) if pbOwnedByPlayer?(idxBattler)
return @battleAI.pbDefaultChooseNewEnemy(idxBattler, pbParty(idxBattler))
return pbPartyScreen(idxBattler, checkLaxOnly, canCancel) if !@controlPlayer && pbOwnedByPlayer?(idxBattler)
return @battleAI.pbDefaultChooseNewEnemy(idxBattler)
end
#=============================================================================
@@ -206,7 +207,7 @@ class Battle
if random
choices = [] # Find all Pokémon that can switch in
eachInTeamFromBattlerIndex(idxBattler) do |_pkmn, i|
choices.push(i) if pbCanSwitchLax?(idxBattler, i)
choices.push(i) if pbCanSwitchIn?(idxBattler, i)
end
return -1 if choices.length == 0
return choices[pbRandom(choices.length)]

View File

@@ -140,7 +140,7 @@ class Battle
def pbPartyMenu(idxBattler)
ret = -1
if @debug
ret = @battleAI.pbDefaultChooseNewEnemy(idxBattler, pbParty(idxBattler))
ret = @battleAI.pbDefaultChooseNewEnemy(idxBattler)
else
ret = pbPartyScreen(idxBattler, false, true, true)
end
@@ -172,6 +172,7 @@ class Battle
# Command phase
#=============================================================================
def pbCommandPhase
@command_phase = true
@scene.pbBeginCommandPhase
# Reset choices if commands can be shown
@battlers.each_with_index do |b, i|
@@ -186,8 +187,12 @@ class Battle
end
# Choose actions for the round (player first, then AI)
pbCommandPhaseLoop(true) # Player chooses their actions
return if @decision != 0 # Battle ended, stop choosing actions
if @decision != 0 # Battle ended, stop choosing actions
@command_phase = false
return
end
pbCommandPhaseLoop(false) # AI chooses their actions
@command_phase = false
end
def pbCommandPhaseLoop(isPlayer)
@@ -200,8 +205,11 @@ class Battle
idxBattler += 1
break if idxBattler >= @battlers.length
next if !@battlers[idxBattler] || pbOwnedByPlayer?(idxBattler) != isPlayer
next if @choices[idxBattler][0] != :None # Action is forced, can't choose one
next if !pbCanShowCommands?(idxBattler) # Action is forced, can't choose one
if @choices[idxBattler][0] != :None || !pbCanShowCommands?(idxBattler)
# Action is forced, can't choose one
PBDebug.log_ai("#{@battlers[idxBattler].pbThis} (#{idxBattler}) is forced to use a multi-turn move")
next
end
# AI controls this battler
if @controlPlayer || !pbOwnedByPlayer?(idxBattler)
@battleAI.pbDefaultChooseEnemyCommand(idxBattler)

View File

@@ -186,9 +186,9 @@ class Battle
end
b.effects[PBEffects::Rage] = false if !pbChoseMoveFunctionCode?(i, "StartRaiseUserAtk1WhenDamaged")
end
PBDebug.log("")
# Calculate move order for this round
pbCalculatePriority(true)
PBDebug.log("")
# Perform actions
pbAttackPhasePriorityChangeMessages
pbAttackPhaseCall

View File

@@ -134,6 +134,8 @@ class Battle
#=============================================================================
def pbEORSeaOfFireDamage(priority)
2.times do |side|
next if sides[side].effects[PBEffects::SeaOfFire] == 0
sides[side].effects[PBEffects::SeaOfFire] -= 1
next if sides[side].effects[PBEffects::SeaOfFire] == 0
pbCommonAnimation("SeaOfFire") if side == 0
pbCommonAnimation("SeaOfFireOpp") if side == 1
@@ -594,7 +596,7 @@ class Battle
#=============================================================================
def pbEndOfRoundPhase
PBDebug.log("")
PBDebug.log("[End of round]")
PBDebug.log("[End of round #{@turnCount + 1}]")
@endOfRound = true
@scene.pbBeginEndOfRoundPhase
pbCalculatePriority # recalculate speeds
@@ -747,6 +749,7 @@ class Battle
battler.lastHPLostFromFoe = 0
battler.droppedBelowHalfHP = false
battler.statsDropped = false
battler.tookMoveDamageThisRound = false
battler.tookDamageThisRound = false
battler.tookPhysicalHit = false
battler.statsRaisedThisRound = false