Added prompt for what to do with a caught Pokémon if the party is full, and a battle rule that forces a capture into the party

This commit is contained in:
Maruno17
2022-04-05 23:01:07 +01:00
parent 22e0d1dfc5
commit 0680f8665d
9 changed files with 140 additions and 38 deletions

View File

@@ -70,22 +70,26 @@ module Settings
# Whether the Exp gained from beating a Pokémon should be scaled depending on # Whether the Exp gained from beating a Pokémon should be scaled depending on
# the gainer's level. # the gainer's level.
SCALED_EXP_FORMULA = (MECHANICS_GENERATION == 5 || MECHANICS_GENERATION >= 7) SCALED_EXP_FORMULA = (MECHANICS_GENERATION == 5 || MECHANICS_GENERATION >= 7)
# Whether the Exp gained from beating a Pokémon should be divided equally # Whether the Exp gained from beating a Pokémon should be divided equally
# between each participant (true), or whether each participant should gain # between each participant (true), or whether each participant should gain
# that much Exp (false). This also applies to Exp gained via the Exp Share # that much Exp (false). This also applies to Exp gained via the Exp Share
# (held item version) being distributed to all Exp Share holders. # (held item version) being distributed to all Exp Share holders.
SPLIT_EXP_BETWEEN_GAINERS = (MECHANICS_GENERATION <= 5) SPLIT_EXP_BETWEEN_GAINERS = (MECHANICS_GENERATION <= 5)
# Whether a Pokémon holding a Power item gains 8 (true) or 4 (false) EVs in # Whether a Pokémon holding a Power item gains 8 (true) or 4 (false) EVs in
# the relevant stat. # the relevant stat.
MORE_EVS_FROM_POWER_ITEMS = (MECHANICS_GENERATION >= 7) MORE_EVS_FROM_POWER_ITEMS = (MECHANICS_GENERATION >= 7)
# Whether the critical capture mechanic applies. Note that its calculation is # Whether the critical capture mechanic applies. Note that its calculation is
# based on a total of 600+ species (i.e. that many species need to be caught # based on a total of 600+ species (i.e. that many species need to be caught
# to provide the greatest critical capture chance of 2.5x), and there may be # to provide the greatest critical capture chance of 2.5x), and there may be
# fewer species in your game. # fewer species in your game.
ENABLE_CRITICAL_CAPTURES = (MECHANICS_GENERATION >= 5) ENABLE_CRITICAL_CAPTURES = (MECHANICS_GENERATION >= 5)
# Whether Pokémon gain Exp for capturing a Pokémon. # Whether Pokémon gain Exp for capturing a Pokémon.
GAIN_EXP_FOR_CAPTURE = (MECHANICS_GENERATION >= 6) GAIN_EXP_FOR_CAPTURE = (MECHANICS_GENERATION >= 6)
# Whether the player is asked what to do with a newly caught Pokémon if their
# party is full. If true, the player can toggle whether they are asked this in
# the Options screen.
NEW_CAPTURE_CAN_REPLACE_PARTY_MEMBER = (MECHANICS_GENERATION >= 7)
#============================================================================= #=============================================================================

View File

@@ -259,11 +259,12 @@ end
#=============================================================================== #===============================================================================
SaveData.register_conversion(:v20_add_default_nicknaming_option) do SaveData.register_conversion(:v20_add_new_default_options) do
essentials_version 20 essentials_version 20
display_title "Updating Options to include nicknaming setting" display_title "Updating Options to include new settings"
to_value :pokemon_system do |option| to_value :pokemon_system do |option|
option.givenicknames = 0 if option.givenicknames.nil? option.givenicknames = 0 if option.givenicknames.nil?
option.sendtoboxes = 0 if option.sendtoboxes.nil?
end end
end end

View File

@@ -69,6 +69,7 @@ class Battle
attr_accessor :expGain # Whether Pokémon can gain Exp/EVs attr_accessor :expGain # Whether Pokémon can gain Exp/EVs
attr_accessor :moneyGain # Whether the player can gain/lose money attr_accessor :moneyGain # Whether the player can gain/lose money
attr_accessor :disablePokeBalls # Whether Poké Balls cannot be thrown at all attr_accessor :disablePokeBalls # Whether Poké Balls cannot be thrown at all
attr_accessor :sendToBoxes # Send to Boxes (0=ask, 1=don't ask, 2=must add to party)
attr_accessor :rules attr_accessor :rules
attr_accessor :choices # Choices made by each Pokémon this round attr_accessor :choices # Choices made by each Pokémon this round
attr_accessor :megaEvolution # Battle index of each trainer's Pokémon to Mega Evolve attr_accessor :megaEvolution # Battle index of each trainer's Pokémon to Mega Evolve
@@ -140,6 +141,7 @@ class Battle
@expGain = true @expGain = true
@moneyGain = true @moneyGain = true
@disablePokeBalls = false @disablePokeBalls = false
@sendToBoxes = 1
@rules = {} @rules = {}
@priority = [] @priority = []
@priorityTrickRoom = false @priorityTrickRoom = false
@@ -830,8 +832,10 @@ class Battle
return @scene.pbDisplayConfirmMessage(msg) return @scene.pbDisplayConfirmMessage(msg)
end end
def pbShowCommands(msg, commands, canCancel = true) # defaultValue of -1 means "can't cancel". If it's 0 or greater, returns that
@scene.pbShowCommands(msg, commands, canCancel) # value when pressing the "Back" button.
def pbShowCommands(msg, commands, defaultValue = -1)
return @scene.pbShowCommands(msg, commands, defaultValue)
end end
def pbAnimation(move, user, targets, hitNum = 0) def pbAnimation(move, user, targets, hitNum = 0)

View File

@@ -86,7 +86,9 @@ class Battle::Battler
# Do other things # Do other things
@battle.pbClearChoice(@index) # Reset choice @battle.pbClearChoice(@index) # Reset choice
pbOwnSide.effects[PBEffects::LastRoundFainted] = @battle.turnCount pbOwnSide.effects[PBEffects::LastRoundFainted] = @battle.turnCount
if $game_temp.party_direct_damage_taken && pbOwnedByPlayer? if $game_temp.party_direct_damage_taken &&
$game_temp.party_direct_damage_taken[@pokemonIndex] &&
pbOwnedByPlayer?
$game_temp.party_direct_damage_taken[@pokemonIndex] = 0 $game_temp.party_direct_damage_taken[@pokemonIndex] = 0
end end
# Check other battlers' abilities that trigger upon a battler fainting # Check other battlers' abilities that trigger upon a battler fainting

View File

@@ -294,7 +294,9 @@ class Battle::Move
@battle.pbDisplay(_INTL("The substitute took damage for {1}!", target.pbThis(true))) @battle.pbDisplay(_INTL("The substitute took damage for {1}!", target.pbThis(true)))
end end
if target.damageState.critical if target.damageState.critical
if $game_temp.party_critical_hits_dealt && user.pbOwnedByPlayer? if $game_temp.party_critical_hits_dealt &&
$game_temp.party_critical_hits_dealt[user.pokemonIndex] &&
user.pbOwnedByPlayer?
$game_temp.party_critical_hits_dealt[user.pokemonIndex] += 1 $game_temp.party_critical_hits_dealt[user.pokemonIndex] += 1
end end
if target.damageState.affection_critical if target.damageState.affection_critical
@@ -388,7 +390,9 @@ class Battle::Move
target.lastHPLostFromFoe = damage # For Metal Burst target.lastHPLostFromFoe = damage # For Metal Burst
target.lastFoeAttacker.push(user.index) # For Metal Burst target.lastFoeAttacker.push(user.index) # For Metal Burst
end end
if $game_temp.party_direct_damage_taken && target.pbOwnedByPlayer? if $game_temp.party_direct_damage_taken &&
$game_temp.party_direct_damage_taken[target.pokemonIndex] &&
target.pbOwnedByPlayer?
$game_temp.party_direct_damage_taken[target.pokemonIndex] += damage $game_temp.party_direct_damage_taken[target.pokemonIndex] += damage
end end
end end

View File

@@ -139,8 +139,10 @@ class Battle::Scene
#============================================================================= #=============================================================================
# Opens the party screen to choose a Pokémon to switch in (or just view its # Opens the party screen to choose a Pokémon to switch in (or just view its
# summary screens) # summary screens)
# mode: 0=Pokémon command, 1=choose a Pokémon to send to the Boxes, 2=view
# summaries only
#============================================================================= #=============================================================================
def pbPartyScreen(idxBattler, canCancel = false) def pbPartyScreen(idxBattler, canCancel = false, mode = 0)
# Fade out and hide all sprites # Fade out and hide all sprites
visibleSprites = pbFadeOutAndHide(@sprites) visibleSprites = pbFadeOutAndHide(@sprites)
# Get player's party # Get player's party
@@ -150,11 +152,13 @@ class Battle::Scene
# Start party screen # Start party screen
scene = PokemonParty_Scene.new scene = PokemonParty_Scene.new
switchScreen = PokemonPartyScreen.new(scene, modParty) switchScreen = PokemonPartyScreen.new(scene, modParty)
switchScreen.pbStartScene(_INTL("Choose a Pokémon."), @battle.pbNumPositions(0, 0)) msg = _INTL("Choose a Pokémon.")
msg = _INTL("Send which Pokémon to Boxes?") if mode == 1
switchScreen.pbStartScene(msg, @battle.pbNumPositions(0, 0))
# Loop while in party screen # Loop while in party screen
loop do loop do
# Select a Pokémon # Select a Pokémon
scene.pbSetHelpText(_INTL("Choose a Pokémon.")) scene.pbSetHelpText(msg)
idxParty = switchScreen.pbChoosePokemon idxParty = switchScreen.pbChoosePokemon
if idxParty < 0 if idxParty < 0
next if !canCancel next if !canCancel
@@ -162,13 +166,16 @@ class Battle::Scene
end end
# Choose a command for the selected Pokémon # Choose a command for the selected Pokémon
cmdSwitch = -1 cmdSwitch = -1
cmdBoxes = -1
cmdSummary = -1 cmdSummary = -1
commands = [] commands = []
commands[cmdSwitch = commands.length] = _INTL("Switch In") if modParty[idxParty].able? commands[cmdSwitch = commands.length] = _INTL("Switch In") if mode == 0 && modParty[idxParty].able?
commands[cmdBoxes = commands.length] = _INTL("Send to Boxes") if mode == 1
commands[cmdSummary = commands.length] = _INTL("Summary") commands[cmdSummary = commands.length] = _INTL("Summary")
commands[commands.length] = _INTL("Cancel") commands[commands.length] = _INTL("Cancel")
command = scene.pbShowCommands(_INTL("Do what with {1}?", modParty[idxParty].name), commands) command = scene.pbShowCommands(_INTL("Do what with {1}?", modParty[idxParty].name), commands)
if cmdSwitch >= 0 && command == cmdSwitch # Switch In if (cmdSwitch >= 0 && command == cmdSwitch) || # Switch In
(cmdBoxes >= 0 && command == cmdBoxes) # Send to Boxes
idxPartyRet = -1 idxPartyRet = -1
partyPos.each_with_index do |pos, i| partyPos.each_with_index do |pos, i|
next if pos != idxParty + partyStart next if pos != idxParty + partyStart

View File

@@ -12,6 +12,69 @@ module Battle::CatchAndStoreMixin
end end
end end
# Store the Pokémon # Store the Pokémon
if pbPlayer.party_full? && (@sendToBoxes == 0 || @sendToBoxes == 2) # Ask/must add to party
cmds = [_INTL("Add to your party"),
_INTL("Send to a Box"),
_INTL("See {1}'s summary", pkmn.name),
_INTL("Check party")]
cmds.delete_at(1) if @sendToBoxes == 2
loop do
cmd = pbShowCommands(_INTL("Where do you want to send {1} to?", pkmn.name), cmds, 99)
break if cmd == 99 # Cancelling = send to a Box
cmd += 1 if cmd >= 1 && @sendToBoxes == 2
case cmd
when 0 # Add to your party
pbDisplay(_INTL("Choose a Pokémon in your party to send to your Boxes."))
party_index = -1
@scene.pbPartyScreen(0, true, 1) { |idxParty, _partyScene|
party_index = idxParty
next true
}
next if party_index < 0 # Cancelled
party_size = pbPlayer.party.length
# Send chosen Pokémon to storage
# NOTE: This doesn't work properly if you catch multiple Pokémon in
# the same battle, because the code below doesn't alter the
# contents of pbParty(0), only pbPlayer.party. This means that
# viewing the party in battle after replacing a party Pokémon
# with a caught one (which is possible if you've caught a second
# Pokémon) will not show the first caught Pokémon in the party
# but will still show the boxed Pokémon in the party. Correcting
# this would take a surprising amount of code, and it's very
# unlikely to be needed anyway, so I'm ignoring it for now.
send_pkmn = pbPlayer.party[party_index]
box_name = @peer.pbStorePokemon(pbPlayer, send_pkmn)
pbPlayer.party.delete_at(party_index)
pbDisplayPaused(_INTL("{1} has been sent to Box \"{2}\".", send_pkmn.name, box_name))
# Rearrange all remembered properties of party Pokémon
(party_index...party_size).each do |idx|
if idx < party_size - 1
@initialItems[0][idx] = @initialItems[0][idx + 1]
$game_temp.party_levels_before_battle[idx] = $game_temp.party_levels_before_battle[idx + 1]
$game_temp.party_critical_hits_dealt[idx] = $game_temp.party_critical_hits_dealt[idx + 1]
$game_temp.party_direct_damage_taken[idx] = $game_temp.party_direct_damage_taken[idx + 1]
else
@initialItems[0][idx] = nil
$game_temp.party_levels_before_battle[idx] = nil
$game_temp.party_critical_hits_dealt[idx] = nil
$game_temp.party_direct_damage_taken[idx] = nil
end
end
break
when 1 # Send to a Box
break
when 2 # See X's summary
pbFadeOutIn {
summary_scene = PokemonSummary_Scene.new
summary_screen = PokemonSummaryScreen.new(summary_scene, true)
summary_screen.pbStartScreen([pkmn], 0)
}
when 3 # Check party
@scene.pbPartyScreen(0, true, 2)
end
end
end
# Store as normal (add to party if there's space, or send to a Box if not)
stored_box = @peer.pbStorePokemon(pbPlayer, pkmn) stored_box = @peer.pbStorePokemon(pbPlayer, pkmn)
if stored_box < 0 if stored_box < 0
pbDisplayPaused(_INTL("{1} has been added to your party.", pkmn.name)) pbDisplayPaused(_INTL("{1} has been added to your party.", pkmn.name))

View File

@@ -32,28 +32,29 @@ class Game_Temp
when "single", "1v1", "1v2", "2v1", "1v3", "3v1", when "single", "1v1", "1v2", "2v1", "1v3", "3v1",
"double", "2v2", "2v3", "3v2", "triple", "3v3" "double", "2v2", "2v3", "3v2", "triple", "3v3"
rules["size"] = rule.to_s.downcase rules["size"] = rule.to_s.downcase
when "canlose" then rules["canLose"] = true when "canlose" then rules["canLose"] = true
when "cannotlose" then rules["canLose"] = false when "cannotlose" then rules["canLose"] = false
when "canrun" then rules["canRun"] = true when "canrun" then rules["canRun"] = true
when "cannotrun" then rules["canRun"] = false when "cannotrun" then rules["canRun"] = false
when "roamerflees" then rules["roamerFlees"] = true when "roamerflees" then rules["roamerFlees"] = true
when "noexp" then rules["expGain"] = false when "noexp" then rules["expGain"] = false
when "nomoney" then rules["moneyGain"] = false when "nomoney" then rules["moneyGain"] = false
when "disablepokeballs" then rules["disablePokeBalls"] = true when "disablepokeballs" then rules["disablePokeBalls"] = true
when "switchstyle" then rules["switchStyle"] = true when "forcecatchintoparty" then rules["forceCatchIntoParty"] = true
when "setstyle" then rules["switchStyle"] = false when "switchstyle" then rules["switchStyle"] = true
when "anims" then rules["battleAnims"] = true when "setstyle" then rules["switchStyle"] = false
when "noanims" then rules["battleAnims"] = false when "anims" then rules["battleAnims"] = true
when "noanims" then rules["battleAnims"] = false
when "terrain" when "terrain"
rules["defaultTerrain"] = GameData::BattleTerrain.try_get(var)&.id rules["defaultTerrain"] = GameData::BattleTerrain.try_get(var)&.id
when "weather" when "weather"
rules["defaultWeather"] = GameData::BattleWeather.try_get(var)&.id rules["defaultWeather"] = GameData::BattleWeather.try_get(var)&.id
when "environment", "environ" when "environment", "environ"
rules["environment"] = GameData::Environment.try_get(var)&.id rules["environment"] = GameData::Environment.try_get(var)&.id
when "backdrop", "battleback" then rules["backdrop"] = var when "backdrop", "battleback" then rules["backdrop"] = var
when "base" then rules["base"] = var when "base" then rules["base"] = var
when "outcome", "outcomevar" then rules["outcomeVar"] = var when "outcome", "outcomevar" then rules["outcomeVar"] = var
when "nopartner" then rules["noPartner"] = true when "nopartner" then rules["noPartner"] = true
else else
raise _INTL("Battle rule \"{1}\" does not exist.", rule) raise _INTL("Battle rule \"{1}\" does not exist.", rule)
end end
@@ -102,6 +103,9 @@ def pbPrepareBattle(battle)
battle.moneyGain = battleRules["moneyGain"] if !battleRules["moneyGain"].nil? battle.moneyGain = battleRules["moneyGain"] if !battleRules["moneyGain"].nil?
# Whether Poké Balls cannot be thrown at all # Whether Poké Balls cannot be thrown at all
battle.disablePokeBalls = battleRules["disablePokeBalls"] if !battleRules["disablePokeBalls"].nil? battle.disablePokeBalls = battleRules["disablePokeBalls"] if !battleRules["disablePokeBalls"].nil?
# Whether the player is asked what to do with a new Pokémon when their party is full
battle.sendToBoxes = $PokemonSystem.sendtoboxes if Settings::NEW_CAPTURE_CAN_REPLACE_PARTY_MEMBER
battle.sendToBoxes = 2 if battleRules["forceCatchIntoParty"]
# Whether the player is able to switch when an opponent's Pokémon faints # Whether the player is able to switch when an opponent's Pokémon faints
battle.switchStyle = ($PokemonSystem.battlestyle == 0) battle.switchStyle = ($PokemonSystem.battlestyle == 0)
battle.switchStyle = battleRules["switchStyle"] if !battleRules["switchStyle"].nil? battle.switchStyle = battleRules["switchStyle"] if !battleRules["switchStyle"].nil?

View File

@@ -5,6 +5,7 @@ class PokemonSystem
attr_accessor :textspeed attr_accessor :textspeed
attr_accessor :battlescene attr_accessor :battlescene
attr_accessor :battlestyle attr_accessor :battlestyle
attr_accessor :sendtoboxes
attr_accessor :givenicknames attr_accessor :givenicknames
attr_accessor :frame attr_accessor :frame
attr_accessor :textskin attr_accessor :textskin
@@ -19,6 +20,7 @@ class PokemonSystem
@textspeed = 1 # Text speed (0=slow, 1=normal, 2=fast) @textspeed = 1 # Text speed (0=slow, 1=normal, 2=fast)
@battlescene = 0 # Battle effects (animations) (0=on, 1=off) @battlescene = 0 # Battle effects (animations) (0=on, 1=off)
@battlestyle = 0 # Battle style (0=switch, 1=set) @battlestyle = 0 # Battle style (0=switch, 1=set)
@sendtoboxes = 0 # Send to Boxes (0=manual, 1=automatic)
@givenicknames = 0 # Give nicknames (0=give, 1=don't give) @givenicknames = 0 # Give nicknames (0=give, 1=don't give)
@frame = 0 # Default window frame (see also Settings::MENU_WINDOWSKINS) @frame = 0 # Default window frame (see also Settings::MENU_WINDOWSKINS)
@textskin = 0 # Speech frame @textskin = 0 # Speech frame
@@ -466,9 +468,20 @@ MenuHandlers.add(:options_menu, :movement_style, {
"set_proc" => proc { |value, _sceme| $PokemonSystem.runstyle = value } "set_proc" => proc { |value, _sceme| $PokemonSystem.runstyle = value }
}) })
MenuHandlers.add(:options_menu, :send_to_boxes, {
"name" => _INTL("Send to Boxes"),
"order" => 70,
"type" => EnumOption,
"parameters" => [_INTL("Manual"), _INTL("Automatic")],
"description" => _INTL("Choose whether caught Pokémon are sent to your Boxes when your party is full."),
"condition" => proc { next Settings::NEW_CAPTURE_CAN_REPLACE_PARTY_MEMBER },
"get_proc" => proc { next $PokemonSystem.sendtoboxes },
"set_proc" => proc { |value, _scene| $PokemonSystem.sendtoboxes = value }
})
MenuHandlers.add(:options_menu, :give_nicknames, { MenuHandlers.add(:options_menu, :give_nicknames, {
"name" => _INTL("Give Nicknames"), "name" => _INTL("Give Nicknames"),
"order" => 70, "order" => 80,
"type" => EnumOption, "type" => EnumOption,
"parameters" => [_INTL("Give"), _INTL("Don't give")], "parameters" => [_INTL("Give"), _INTL("Don't give")],
"description" => _INTL("Choose whether you can give a nickname to a Pokémon when you obtain it."), "description" => _INTL("Choose whether you can give a nickname to a Pokémon when you obtain it."),
@@ -478,7 +491,7 @@ MenuHandlers.add(:options_menu, :give_nicknames, {
MenuHandlers.add(:options_menu, :speech_frame, { MenuHandlers.add(:options_menu, :speech_frame, {
"name" => _INTL("Speech Frame"), "name" => _INTL("Speech Frame"),
"order" => 80, "order" => 90,
"type" => NumberOption, "type" => NumberOption,
"parameters" => 1..Settings::SPEECH_WINDOWSKINS.length, "parameters" => 1..Settings::SPEECH_WINDOWSKINS.length,
"description" => _INTL("Choose the appearance of dialogue boxes."), "description" => _INTL("Choose the appearance of dialogue boxes."),
@@ -493,7 +506,7 @@ MenuHandlers.add(:options_menu, :speech_frame, {
MenuHandlers.add(:options_menu, :menu_frame, { MenuHandlers.add(:options_menu, :menu_frame, {
"name" => _INTL("Menu Frame"), "name" => _INTL("Menu Frame"),
"order" => 90, "order" => 100,
"type" => NumberOption, "type" => NumberOption,
"parameters" => 1..Settings::MENU_WINDOWSKINS.length, "parameters" => 1..Settings::MENU_WINDOWSKINS.length,
"description" => _INTL("Choose the appearance of menu boxes."), "description" => _INTL("Choose the appearance of menu boxes."),
@@ -508,7 +521,7 @@ MenuHandlers.add(:options_menu, :menu_frame, {
MenuHandlers.add(:options_menu, :text_input_style, { MenuHandlers.add(:options_menu, :text_input_style, {
"name" => _INTL("Text Entry"), "name" => _INTL("Text Entry"),
"order" => 100, "order" => 110,
"type" => EnumOption, "type" => EnumOption,
"parameters" => [_INTL("Cursor"), _INTL("Keyboard")], "parameters" => [_INTL("Cursor"), _INTL("Keyboard")],
"description" => _INTL("Choose how you want to enter text."), "description" => _INTL("Choose how you want to enter text."),
@@ -518,7 +531,7 @@ MenuHandlers.add(:options_menu, :text_input_style, {
MenuHandlers.add(:options_menu, :screen_size, { MenuHandlers.add(:options_menu, :screen_size, {
"name" => _INTL("Screen Size"), "name" => _INTL("Screen Size"),
"order" => 110, "order" => 120,
"type" => EnumOption, "type" => EnumOption,
"parameters" => [_INTL("S"), _INTL("M"), _INTL("L"), _INTL("XL"), _INTL("Full")], "parameters" => [_INTL("S"), _INTL("M"), _INTL("L"), _INTL("XL"), _INTL("Full")],
"description" => _INTL("Choose the size of the game window."), "description" => _INTL("Choose the size of the game window."),