From 0680f8665d4e1336e066bd905851d276c5bb2099 Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Tue, 5 Apr 2022 23:01:07 +0100 Subject: [PATCH] =?UTF-8?q?Added=20prompt=20for=20what=20to=20do=20with=20?= =?UTF-8?q?a=20caught=20Pok=C3=A9mon=20if=20the=20party=20is=20full,=20and?= =?UTF-8?q?=20a=20battle=20rule=20that=20forces=20a=20capture=20into=20the?= =?UTF-8?q?=20party?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Data/Scripts/002_BattleSettings.rb | 14 +++-- .../002_Save data/005_Game_SaveConversions.rb | 5 +- .../011_Battle/001_Battle/001_Battle.rb | 8 ++- .../002_Battler/003_Battler_ChangeSelf.rb | 4 +- .../011_Battle/003_Move/002_Move_Usage.rb | 8 ++- .../004_Scene/003_Scene_ChooseCommands.rb | 17 +++-- .../005_Battle_CatchAndStoreMixin.rb | 63 +++++++++++++++++++ .../001_Overworld_BattleStarting.rb | 36 ++++++----- Data/Scripts/016_UI/015_UI_Options.rb | 23 +++++-- 9 files changed, 140 insertions(+), 38 deletions(-) diff --git a/Data/Scripts/002_BattleSettings.rb b/Data/Scripts/002_BattleSettings.rb index 28fbb7602..664d2f191 100644 --- a/Data/Scripts/002_BattleSettings.rb +++ b/Data/Scripts/002_BattleSettings.rb @@ -70,22 +70,26 @@ module Settings # Whether the Exp gained from beating a Pokémon should be scaled depending on # 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 # between each participant (true), or whether each participant should gain # that much Exp (false). This also applies to Exp gained via the Exp Share # (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 # 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 # 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 # 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. - 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) #============================================================================= diff --git a/Data/Scripts/002_Save data/005_Game_SaveConversions.rb b/Data/Scripts/002_Save data/005_Game_SaveConversions.rb index 619b4a4e0..a07b846eb 100644 --- a/Data/Scripts/002_Save data/005_Game_SaveConversions.rb +++ b/Data/Scripts/002_Save data/005_Game_SaveConversions.rb @@ -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 - display_title "Updating Options to include nicknaming setting" + display_title "Updating Options to include new settings" to_value :pokemon_system do |option| option.givenicknames = 0 if option.givenicknames.nil? + option.sendtoboxes = 0 if option.sendtoboxes.nil? end end diff --git a/Data/Scripts/011_Battle/001_Battle/001_Battle.rb b/Data/Scripts/011_Battle/001_Battle/001_Battle.rb index cfb1a59b7..45f30a037 100644 --- a/Data/Scripts/011_Battle/001_Battle/001_Battle.rb +++ b/Data/Scripts/011_Battle/001_Battle/001_Battle.rb @@ -69,6 +69,7 @@ class Battle attr_accessor :expGain # Whether Pokémon can gain Exp/EVs attr_accessor :moneyGain # Whether the player can gain/lose money 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 :choices # Choices made by each Pokémon this round attr_accessor :megaEvolution # Battle index of each trainer's Pokémon to Mega Evolve @@ -140,6 +141,7 @@ class Battle @expGain = true @moneyGain = true @disablePokeBalls = false + @sendToBoxes = 1 @rules = {} @priority = [] @priorityTrickRoom = false @@ -830,8 +832,10 @@ class Battle return @scene.pbDisplayConfirmMessage(msg) end - def pbShowCommands(msg, commands, canCancel = true) - @scene.pbShowCommands(msg, commands, canCancel) + # defaultValue of -1 means "can't cancel". If it's 0 or greater, returns that + # value when pressing the "Back" button. + def pbShowCommands(msg, commands, defaultValue = -1) + return @scene.pbShowCommands(msg, commands, defaultValue) end def pbAnimation(move, user, targets, hitNum = 0) diff --git a/Data/Scripts/011_Battle/002_Battler/003_Battler_ChangeSelf.rb b/Data/Scripts/011_Battle/002_Battler/003_Battler_ChangeSelf.rb index f20a2c42c..cfaaf60de 100644 --- a/Data/Scripts/011_Battle/002_Battler/003_Battler_ChangeSelf.rb +++ b/Data/Scripts/011_Battle/002_Battler/003_Battler_ChangeSelf.rb @@ -86,7 +86,9 @@ class Battle::Battler # Do other things @battle.pbClearChoice(@index) # Reset choice 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 end # Check other battlers' abilities that trigger upon a battler fainting diff --git a/Data/Scripts/011_Battle/003_Move/002_Move_Usage.rb b/Data/Scripts/011_Battle/003_Move/002_Move_Usage.rb index cbd3dcbf6..62037a3e7 100644 --- a/Data/Scripts/011_Battle/003_Move/002_Move_Usage.rb +++ b/Data/Scripts/011_Battle/003_Move/002_Move_Usage.rb @@ -294,7 +294,9 @@ class Battle::Move @battle.pbDisplay(_INTL("The substitute took damage for {1}!", target.pbThis(true))) end 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 end if target.damageState.affection_critical @@ -388,7 +390,9 @@ class Battle::Move target.lastHPLostFromFoe = damage # For Metal Burst target.lastFoeAttacker.push(user.index) # For Metal Burst 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 end end diff --git a/Data/Scripts/011_Battle/004_Scene/003_Scene_ChooseCommands.rb b/Data/Scripts/011_Battle/004_Scene/003_Scene_ChooseCommands.rb index 06c17bd05..dc42d3a46 100644 --- a/Data/Scripts/011_Battle/004_Scene/003_Scene_ChooseCommands.rb +++ b/Data/Scripts/011_Battle/004_Scene/003_Scene_ChooseCommands.rb @@ -139,8 +139,10 @@ class Battle::Scene #============================================================================= # Opens the party screen to choose a Pokémon to switch in (or just view its # 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 visibleSprites = pbFadeOutAndHide(@sprites) # Get player's party @@ -150,11 +152,13 @@ class Battle::Scene # Start party screen scene = PokemonParty_Scene.new 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 do # Select a Pokémon - scene.pbSetHelpText(_INTL("Choose a Pokémon.")) + scene.pbSetHelpText(msg) idxParty = switchScreen.pbChoosePokemon if idxParty < 0 next if !canCancel @@ -162,13 +166,16 @@ class Battle::Scene end # Choose a command for the selected Pokémon cmdSwitch = -1 + cmdBoxes = -1 cmdSummary = -1 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[commands.length] = _INTL("Cancel") 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 partyPos.each_with_index do |pos, i| next if pos != idxParty + partyStart diff --git a/Data/Scripts/011_Battle/006_Other battle code/005_Battle_CatchAndStoreMixin.rb b/Data/Scripts/011_Battle/006_Other battle code/005_Battle_CatchAndStoreMixin.rb index 952f31c01..063ee8e0b 100644 --- a/Data/Scripts/011_Battle/006_Other battle code/005_Battle_CatchAndStoreMixin.rb +++ b/Data/Scripts/011_Battle/006_Other battle code/005_Battle_CatchAndStoreMixin.rb @@ -12,6 +12,69 @@ module Battle::CatchAndStoreMixin end end # 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) if stored_box < 0 pbDisplayPaused(_INTL("{1} has been added to your party.", pkmn.name)) diff --git a/Data/Scripts/012_Overworld/002_Battle triggering/001_Overworld_BattleStarting.rb b/Data/Scripts/012_Overworld/002_Battle triggering/001_Overworld_BattleStarting.rb index eb377c8cf..9049809e6 100644 --- a/Data/Scripts/012_Overworld/002_Battle triggering/001_Overworld_BattleStarting.rb +++ b/Data/Scripts/012_Overworld/002_Battle triggering/001_Overworld_BattleStarting.rb @@ -32,28 +32,29 @@ class Game_Temp when "single", "1v1", "1v2", "2v1", "1v3", "3v1", "double", "2v2", "2v3", "3v2", "triple", "3v3" rules["size"] = rule.to_s.downcase - when "canlose" then rules["canLose"] = true - when "cannotlose" then rules["canLose"] = false - when "canrun" then rules["canRun"] = true - when "cannotrun" then rules["canRun"] = false - when "roamerflees" then rules["roamerFlees"] = true - when "noexp" then rules["expGain"] = false - when "nomoney" then rules["moneyGain"] = false - when "disablepokeballs" then rules["disablePokeBalls"] = true - when "switchstyle" then rules["switchStyle"] = true - when "setstyle" then rules["switchStyle"] = false - when "anims" then rules["battleAnims"] = true - when "noanims" then rules["battleAnims"] = false + when "canlose" then rules["canLose"] = true + when "cannotlose" then rules["canLose"] = false + when "canrun" then rules["canRun"] = true + when "cannotrun" then rules["canRun"] = false + when "roamerflees" then rules["roamerFlees"] = true + when "noexp" then rules["expGain"] = false + when "nomoney" then rules["moneyGain"] = false + when "disablepokeballs" then rules["disablePokeBalls"] = true + when "forcecatchintoparty" then rules["forceCatchIntoParty"] = true + when "switchstyle" then rules["switchStyle"] = true + when "setstyle" then rules["switchStyle"] = false + when "anims" then rules["battleAnims"] = true + when "noanims" then rules["battleAnims"] = false when "terrain" rules["defaultTerrain"] = GameData::BattleTerrain.try_get(var)&.id when "weather" rules["defaultWeather"] = GameData::BattleWeather.try_get(var)&.id when "environment", "environ" rules["environment"] = GameData::Environment.try_get(var)&.id - when "backdrop", "battleback" then rules["backdrop"] = var - when "base" then rules["base"] = var - when "outcome", "outcomevar" then rules["outcomeVar"] = var - when "nopartner" then rules["noPartner"] = true + when "backdrop", "battleback" then rules["backdrop"] = var + when "base" then rules["base"] = var + when "outcome", "outcomevar" then rules["outcomeVar"] = var + when "nopartner" then rules["noPartner"] = true else raise _INTL("Battle rule \"{1}\" does not exist.", rule) end @@ -102,6 +103,9 @@ def pbPrepareBattle(battle) battle.moneyGain = battleRules["moneyGain"] if !battleRules["moneyGain"].nil? # Whether Poké Balls cannot be thrown at all 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 battle.switchStyle = ($PokemonSystem.battlestyle == 0) battle.switchStyle = battleRules["switchStyle"] if !battleRules["switchStyle"].nil? diff --git a/Data/Scripts/016_UI/015_UI_Options.rb b/Data/Scripts/016_UI/015_UI_Options.rb index d0a6efc0f..21bb52188 100644 --- a/Data/Scripts/016_UI/015_UI_Options.rb +++ b/Data/Scripts/016_UI/015_UI_Options.rb @@ -5,6 +5,7 @@ class PokemonSystem attr_accessor :textspeed attr_accessor :battlescene attr_accessor :battlestyle + attr_accessor :sendtoboxes attr_accessor :givenicknames attr_accessor :frame attr_accessor :textskin @@ -19,6 +20,7 @@ class PokemonSystem @textspeed = 1 # Text speed (0=slow, 1=normal, 2=fast) @battlescene = 0 # Battle effects (animations) (0=on, 1=off) @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) @frame = 0 # Default window frame (see also Settings::MENU_WINDOWSKINS) @textskin = 0 # Speech frame @@ -466,9 +468,20 @@ MenuHandlers.add(:options_menu, :movement_style, { "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, { "name" => _INTL("Give Nicknames"), - "order" => 70, + "order" => 80, "type" => EnumOption, "parameters" => [_INTL("Give"), _INTL("Don't give")], "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, { "name" => _INTL("Speech Frame"), - "order" => 80, + "order" => 90, "type" => NumberOption, "parameters" => 1..Settings::SPEECH_WINDOWSKINS.length, "description" => _INTL("Choose the appearance of dialogue boxes."), @@ -493,7 +506,7 @@ MenuHandlers.add(:options_menu, :speech_frame, { MenuHandlers.add(:options_menu, :menu_frame, { "name" => _INTL("Menu Frame"), - "order" => 90, + "order" => 100, "type" => NumberOption, "parameters" => 1..Settings::MENU_WINDOWSKINS.length, "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, { "name" => _INTL("Text Entry"), - "order" => 100, + "order" => 110, "type" => EnumOption, "parameters" => [_INTL("Cursor"), _INTL("Keyboard")], "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, { "name" => _INTL("Screen Size"), - "order" => 110, + "order" => 120, "type" => EnumOption, "parameters" => [_INTL("S"), _INTL("M"), _INTL("L"), _INTL("XL"), _INTL("Full")], "description" => _INTL("Choose the size of the game window."),