Files
infinitefusion-e18/Data/Scripts/011_Battle/001_Battle/009_Battle_CommandPhase.rb
2021-12-20 17:18:21 +00:00

258 lines
9.2 KiB
Ruby

class Battle
#=============================================================================
# Clear commands
#=============================================================================
def pbClearChoice(idxBattler)
@choices[idxBattler] = [] if !@choices[idxBattler]
@choices[idxBattler][0] = :None
@choices[idxBattler][1] = 0
@choices[idxBattler][2] = nil
@choices[idxBattler][3] = -1
end
def pbCancelChoice(idxBattler)
# If idxBattler's choice was to use an item, return that item to the Bag
if @choices[idxBattler][0] == :UseItem
item = @choices[idxBattler][1]
pbReturnUnusedItemToBag(item, idxBattler) if item
end
# If idxBattler chose to Mega Evolve, cancel it
pbUnregisterMegaEvolution(idxBattler)
# Clear idxBattler's choice
pbClearChoice(idxBattler)
end
#=============================================================================
# Use main command menu (Fight/Pokémon/Bag/Run)
#=============================================================================
def pbCommandMenu(idxBattler, firstAction)
return @scene.pbCommandMenu(idxBattler, firstAction)
end
#=============================================================================
# Check whether actions can be taken
#=============================================================================
def pbCanShowCommands?(idxBattler)
battler = @battlers[idxBattler]
return false if !battler || battler.fainted?
return false if battler.usingMultiTurnAttack?
return true
end
def pbCanShowFightMenu?(idxBattler)
battler = @battlers[idxBattler]
# Encore
return false if battler.effects[PBEffects::Encore] > 0
# No moves that can be chosen (will Struggle instead)
usable = false
battler.eachMoveWithIndex do |_m, i|
next if !pbCanChooseMove?(idxBattler, i, false)
usable = true
break
end
return usable
end
#=============================================================================
# Use sub-menus to choose an action, and register it if is allowed
#=============================================================================
# Returns true if a choice was made, false if cancelled.
def pbFightMenu(idxBattler)
# Auto-use Encored move or no moves choosable, so auto-use Struggle
return pbAutoChooseMove(idxBattler) if !pbCanShowFightMenu?(idxBattler)
# Battle Palace only
return true if pbAutoFightMenu(idxBattler)
# Regular move selection
ret = false
@scene.pbFightMenu(idxBattler, pbCanMegaEvolve?(idxBattler)) { |cmd|
case cmd
when -1 # Cancel
when -2 # Toggle Mega Evolution
pbToggleRegisteredMegaEvolution(idxBattler)
next false
when -3 # Shift
pbUnregisterMegaEvolution(idxBattler)
pbRegisterShift(idxBattler)
ret = true
else # Chose a move to use
next false if cmd < 0 || !@battlers[idxBattler].moves[cmd] ||
!@battlers[idxBattler].moves[cmd].id
next false if !pbRegisterMove(idxBattler, cmd)
next false if !singleBattle? &&
!pbChooseTarget(@battlers[idxBattler], @battlers[idxBattler].moves[cmd])
ret = true
end
next true
}
return ret
end
def pbAutoFightMenu(idxBattler); return false; end
def pbChooseTarget(battler, move)
target_data = move.pbTarget(battler)
idxTarget = @scene.pbChooseTarget(battler.index, target_data)
return false if idxTarget < 0
pbRegisterTarget(battler.index, idxTarget)
return true
end
def pbItemMenu(idxBattler, firstAction)
if !@internalBattle
pbDisplay(_INTL("Items can't be used here."))
return false
end
ret = false
@scene.pbItemMenu(idxBattler, firstAction) { |item, useType, idxPkmn, idxMove, itemScene|
next false if !item
battler = pkmn = nil
case useType
when 1, 2 # Use on Pokémon/Pokémon's move
next false if !ItemHandlers.hasBattleUseOnPokemon(item)
battler = pbFindBattler(idxPkmn, idxBattler)
pkmn = pbParty(idxBattler)[idxPkmn]
next false if !pbCanUseItemOnPokemon?(item, pkmn, battler, itemScene)
when 3 # Use on battler
next false if !ItemHandlers.hasBattleUseOnBattler(item)
battler = pbFindBattler(idxPkmn, idxBattler)
pkmn = battler.pokemon if battler
next false if !pbCanUseItemOnPokemon?(item, pkmn, battler, itemScene)
when 4 # Poké Balls
next false if idxPkmn < 0
battler = @battlers[idxPkmn]
pkmn = battler.pokemon if battler
when 5 # No target (Poké Doll, Guard Spec., Launcher items)
battler = @battlers[idxBattler]
pkmn = battler.pokemon if battler
else
next false
end
next false if !pkmn
next false if !ItemHandlers.triggerCanUseInBattle(item, pkmn, battler, idxMove,
firstAction, self, itemScene)
next false if !pbRegisterItem(idxBattler, item, idxPkmn, idxMove)
ret = true
next true
}
return ret
end
def pbPartyMenu(idxBattler)
ret = -1
if @debug
ret = @battleAI.pbDefaultChooseNewEnemy(idxBattler, pbParty(idxBattler))
else
ret = pbPartyScreen(idxBattler, false, true, true)
end
return ret >= 0
end
def pbRunMenu(idxBattler)
# Regardless of succeeding or failing to run, stop choosing actions
return pbRun(idxBattler) != 0
end
def pbCallMenu(idxBattler)
return pbRegisterCall(idxBattler)
end
def pbDebugMenu
pbBattleDebug(self)
@scene.pbRefreshEverything
allBattlers.each { |b| b.pbCheckFormOnWeatherChange }
pbEndPrimordialWeather
allBattlers.each { |b| b.pbAbilityOnTerrainChange }
allBattlers.each do |b|
b.pbCheckFormOnMovesetChange
b.pbCheckFormOnStatusChange
end
end
#=============================================================================
# Command phase
#=============================================================================
def pbCommandPhase
@scene.pbBeginCommandPhase
# Reset choices if commands can be shown
@battlers.each_with_index do |b, i|
next if !b
pbClearChoice(i) if pbCanShowCommands?(i)
end
# Reset choices to perform Mega Evolution if it wasn't done somehow
2.times do |side|
@megaEvolution[side].each_with_index do |megaEvo, i|
@megaEvolution[side][i] = -1 if megaEvo >= 0
end
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
pbCommandPhaseLoop(false) # AI chooses their actions
end
def pbCommandPhaseLoop(isPlayer)
# NOTE: Doing some things (e.g. running, throwing a Poké Ball) takes up all
# your actions in a round.
actioned = []
idxBattler = -1
loop do
break if @decision != 0 # Battle ended, stop choosing actions
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
# AI controls this battler
if @controlPlayer || !pbOwnedByPlayer?(idxBattler)
@battleAI.pbDefaultChooseEnemyCommand(idxBattler)
next
end
# Player chooses an action
actioned.push(idxBattler)
commandsEnd = false # Whether to cancel choosing all other actions this round
loop do
cmd = pbCommandMenu(idxBattler, actioned.length == 1)
# If being Sky Dropped, can't do anything except use a move
if cmd > 0 && @battlers[idxBattler].effects[PBEffects::SkyDrop] >= 0
pbDisplay(_INTL("Sky Drop won't let {1} go!", @battlers[idxBattler].pbThis(true)))
next
end
case cmd
when 0 # Fight
break if pbFightMenu(idxBattler)
when 1 # Bag
if pbItemMenu(idxBattler, actioned.length == 1)
commandsEnd = true if pbItemUsesAllActions?(@choices[idxBattler][1])
break
end
when 2 # Pokémon
break if pbPartyMenu(idxBattler)
when 3 # Run
# NOTE: "Run" is only an available option for the first battler the
# player chooses an action for in a round. Attempting to run
# from battle prevents you from choosing any other actions in
# that round.
if pbRunMenu(idxBattler)
commandsEnd = true
break
end
when 4 # Call
break if pbCallMenu(idxBattler)
when -2 # Debug
pbDebugMenu
next
when -1 # Go back to previous battler's action choice
next if actioned.length <= 1
actioned.pop # Forget this battler was done
idxBattler = actioned.last - 1
pbCancelChoice(idxBattler + 1) # Clear the previous battler's choice
actioned.pop # Forget the previous battler was done
break
end
pbCancelChoice(idxBattler)
end
break if commandsEnd
end
end
end