From fe2c154b89c5e52f92ecd8bc7b4c69f2d3e7bbe3 Mon Sep 17 00:00:00 2001 From: FosterProgramming Date: Thu, 22 Jan 2026 19:54:19 +0100 Subject: [PATCH] Refactor chooseboxmon (#8491) Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com> --- Makefile | 1 + asm/macros/event.inc | 41 ++ data/maps/BattleFrontier_Lounge1/scripts.inc | 3 +- data/maps/BattleFrontier_Lounge5/scripts.inc | 3 +- data/maps/BattleFrontier_Lounge6/scripts.inc | 22 +- data/maps/BattleFrontier_Lounge7/scripts.inc | 52 +-- .../scripts.inc | 6 +- data/maps/FortreeCity_House1/scripts.inc | 23 +- .../scripts.inc | 3 +- data/maps/PacifidlogTown_House3/scripts.inc | 23 +- data/maps/RustboroCity_House1/scripts.inc | 22 +- .../SlateportCity_NameRatersHouse/scripts.inc | 6 +- .../scripts.inc | 14 +- data/scripts/day_care.inc | 3 +- data/scripts/move_relearner.inc | 7 +- data/scripts/move_tutors.inc | 194 +------- data/scripts/pc_transfer.inc | 3 +- data/specials.inc | 3 +- include/chooseboxmon.h | 19 + include/config/overworld.h | 1 + include/constants/party_menu.h | 19 + include/event_scripts.h | 2 +- include/mail.h | 1 + include/move_relearner.h | 2 + include/pokemon.h | 21 +- include/pokemon_storage_system.h | 7 +- include/pokemon_summary_screen.h | 6 +- include/trade.h | 2 + src/battle_script_commands.c | 2 +- src/chooseboxmon.c | 313 +++++++++++++ src/daycare.c | 47 +- src/evolution_scene.c | 40 +- src/field_specials.c | 368 ++++----------- src/mail_data.c | 36 +- src/move_relearner.c | 433 ++++++++++++++---- src/new_game.c | 1 - src/party_menu.c | 221 +++------ src/pokemon.c | 414 ++--------------- src/pokemon_size_record.c | 77 +--- src/pokemon_storage_system.c | 180 ++++---- src/pokemon_summary_screen.c | 150 +++--- src/trade.c | 156 +++---- src/tv.c | 70 +-- tools/learnset_helpers/make_teachables.py | 2 - tools/learnset_helpers/make_tutors.py | 9 +- 45 files changed, 1337 insertions(+), 1691 deletions(-) create mode 100644 include/chooseboxmon.h create mode 100644 src/chooseboxmon.c diff --git a/Makefile b/Makefile index 7373bb39ce..02a4ad17fe 100644 --- a/Makefile +++ b/Makefile @@ -470,6 +470,7 @@ $(TEST_BUILDDIR)/%.o: CFLAGS := -mthumb -mthumb-interwork -O2 -mabi=apcs-gnu -mt # Dependency rules (for the *.c & *.s sources to .o files) # Have to be explicit or else missing files won't be reported. $(C_BUILDDIR)/pokemon.o: $(C_SUBDIR)/pokemon.c $(DATA_SRC_SUBDIR)/pokemon/teachable_learnsets.h +$(C_BUILDDIR)/move_relearner.o: $(C_SUBDIR)/move_relearner.c $(DATA_SRC_SUBDIR)/tutor_moves.h # As a side effect, they're evaluated immediately instead of when the rule is invoked. # It doesn't look like $(shell) can be deferred so there might not be a better way (Icedude_907: there is soon). diff --git a/asm/macros/event.inc b/asm/macros/event.inc index 1c59bdbe81..a8df701541 100644 --- a/asm/macros/event.inc +++ b/asm/macros/event.inc @@ -2628,6 +2628,47 @@ callnative DoFacilityTrainerBattle .byte \facility .endm + + .macro ingame_trade tradeId:req wantTradeMsg:req, declineTradeJump:req, wrongMonJump:req, tradeCompleteMsg:req + setvar VAR_0x8005, \tradeId + specialvar VAR_0x8009, GetInGameTradeSpeciesInfo + msgbox \wantTradeMsg, MSGBOX_YESNO + goto_if_eq VAR_RESULT, NO, \declineTradeJump + chooseboxmon SELECT_PC_MON_TRADE + waitstate + goto_if_eq VAR_0x8004, PARTY_NOTHING_CHOSEN, \declineTradeJump + specialvar VAR_0x800B, GetTradeSpecies + goto_if_ne VAR_0x800B, VAR_0x8009, \wrongMonJump + special CreateInGameTradePokemon + special DoInGameTradeScene + waitstate + msgbox \tradeCompleteMsg, MSGBOX_DEFAULT + .endm + + .macro move_tutor moveId:req, wantTeachingMsg:req, monSelectMsg:req, declinedJmp:req, taughtJmp:req, flagId=0 + .if \flagId + goto_if_set \flagId, \taughtJmp + .endif + msgbox \wantTeachingMsg, MSGBOX_YESNO + goto_if_eq VAR_RESULT, NO, \declinedJmp + .if \flagId + call MoveTutor_EventScript_CanOnlyBeLearnedOnce + goto_if_eq VAR_RESULT, NO, \declinedJmp + .endif + msgbox \monSelectMsg, MSGBOX_DEFAULT + setvar VAR_0x8005, \moveId + call MoveTutor_EventScript_OpenBox + goto_if_eq VAR_RESULT, FALSE, \declinedJmp + .if \flagId + setflag \flagId + .endif + goto \taughtJmp + .endm + + .macro chooseboxmon selectionType=SELECT_PC_MON_NORMAL + callnative ChooseBoxMon + .byte \selectionType + .endm @ Follower NPCs diff --git a/data/maps/BattleFrontier_Lounge1/scripts.inc b/data/maps/BattleFrontier_Lounge1/scripts.inc index e2e51547cc..e37139cfbd 100644 --- a/data/maps/BattleFrontier_Lounge1/scripts.inc +++ b/data/maps/BattleFrontier_Lounge1/scripts.inc @@ -12,8 +12,7 @@ BattleFrontier_Lounge1_EventScript_Breeder:: end BattleFrontier_Lounge1_EventScript_ChooseMonToShowBreeder:: - fadescreen FADE_TO_BLACK - special ChooseBoxMon + chooseboxmon waitstate goto_if_ne VAR_0x8004, PARTY_NOTHING_CHOSEN, BattleFrontier_Lounge1_EventScript_ShowMonToBreeder goto_if_eq VAR_0x8004, PARTY_NOTHING_CHOSEN, BattleFrontier_Lounge1_EventScript_CancelMonSelect diff --git a/data/maps/BattleFrontier_Lounge5/scripts.inc b/data/maps/BattleFrontier_Lounge5/scripts.inc index c789c5bb76..7183983260 100644 --- a/data/maps/BattleFrontier_Lounge5/scripts.inc +++ b/data/maps/BattleFrontier_Lounge5/scripts.inc @@ -6,8 +6,7 @@ BattleFrontier_Lounge5_EventScript_NatureGirl:: faceplayer msgbox BattleFrontier_Lounge5_Text_NatureGirlGreeting, MSGBOX_YESNO goto_if_eq VAR_RESULT, NO, BattleFrontier_Lounge5_EventScript_NatureGirlNoneShown - fadescreen FADE_TO_BLACK - special ChooseBoxMon + chooseboxmon waitstate lock faceplayer diff --git a/data/maps/BattleFrontier_Lounge6/scripts.inc b/data/maps/BattleFrontier_Lounge6/scripts.inc index cb5e9dcecf..df8787918c 100644 --- a/data/maps/BattleFrontier_Lounge6/scripts.inc +++ b/data/maps/BattleFrontier_Lounge6/scripts.inc @@ -5,27 +5,7 @@ BattleFrontier_Lounge6_EventScript_Trader:: lock faceplayer goto_if_set FLAG_BATTLE_FRONTIER_TRADE_DONE, BattleFrontier_Lounge6_EventScript_TradeCompleted - setvar VAR_0x8008, INGAME_TRADE_MEOWTH - copyvar VAR_0x8004, VAR_0x8008 - specialvar VAR_RESULT, GetInGameTradeSpeciesInfo - copyvar VAR_0x8009, VAR_RESULT - msgbox BattleFrontier_Lounge6_Text_WouldYouLikeToTrade, MSGBOX_YESNO - goto_if_eq VAR_RESULT, NO, BattleFrontier_Lounge6_EventScript_DeclineTrade - fadescreen FADE_TO_BLACK - special ChooseBoxMon - waitstate - copyvar VAR_0x800A, VAR_0x8004 - goto_if_eq VAR_0x8004, PARTY_NOTHING_CHOSEN, BattleFrontier_Lounge6_EventScript_DeclineTrade - copyvar VAR_0x8005, VAR_0x800A - specialvar VAR_RESULT, GetTradeSpecies - copyvar VAR_0x800B, VAR_RESULT - goto_if_ne VAR_RESULT, VAR_0x8009, BattleFrontier_Lounge6_EventScript_NotRequestedMon - copyvar VAR_0x8004, VAR_0x8008 - copyvar VAR_0x8005, VAR_0x800A - special CreateInGameTradePokemon - special DoInGameTradeScene - waitstate - msgbox BattleFrontier_Lounge6_Text_PromiseIllBeGoodToIt, MSGBOX_DEFAULT + ingame_trade INGAME_TRADE_MEOWTH, BattleFrontier_Lounge6_Text_WouldYouLikeToTrade, BattleFrontier_Lounge6_EventScript_DeclineTrade, BattleFrontier_Lounge6_EventScript_NotRequestedMon, BattleFrontier_Lounge6_Text_PromiseIllBeGoodToIt setflag FLAG_BATTLE_FRONTIER_TRADE_DONE release end diff --git a/data/maps/BattleFrontier_Lounge7/scripts.inc b/data/maps/BattleFrontier_Lounge7/scripts.inc index 0a04e00bac..22d75d579e 100644 --- a/data/maps/BattleFrontier_Lounge7/scripts.inc +++ b/data/maps/BattleFrontier_Lounge7/scripts.inc @@ -68,61 +68,61 @@ BattleFrontier_Lounge7_EventScript_ChooseNewLeftTutorMove:: BattleFrontier_Lounge7_EventScript_Softboiled:: setvar VAR_0x8008, 16 - setvar VAR_ITEM_ID, MOVE_SOFT_BOILED + setvar VAR_0x8005, MOVE_SOFT_BOILED goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection end BattleFrontier_Lounge7_EventScript_SeismicToss:: setvar VAR_0x8008, 24 - setvar VAR_ITEM_ID, MOVE_SEISMIC_TOSS + setvar VAR_0x8005, MOVE_SEISMIC_TOSS goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection end BattleFrontier_Lounge7_EventScript_DreamEater:: setvar VAR_0x8008, 24 - setvar VAR_ITEM_ID, MOVE_DREAM_EATER + setvar VAR_0x8005, MOVE_DREAM_EATER goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection end BattleFrontier_Lounge7_EventScript_MegaPunch:: setvar VAR_0x8008, 24 - setvar VAR_ITEM_ID, MOVE_MEGA_PUNCH + setvar VAR_0x8005, MOVE_MEGA_PUNCH goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection end BattleFrontier_Lounge7_EventScript_MegaKick:: setvar VAR_0x8008, 48 - setvar VAR_ITEM_ID, MOVE_MEGA_KICK + setvar VAR_0x8005, MOVE_MEGA_KICK goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection end BattleFrontier_Lounge7_EventScript_BodySlam:: setvar VAR_0x8008, 48 - setvar VAR_ITEM_ID, MOVE_BODY_SLAM + setvar VAR_0x8005, MOVE_BODY_SLAM goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection end BattleFrontier_Lounge7_EventScript_RockSlide:: setvar VAR_0x8008, 48 - setvar VAR_ITEM_ID, MOVE_ROCK_SLIDE + setvar VAR_0x8005, MOVE_ROCK_SLIDE goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection end BattleFrontier_Lounge7_EventScript_Counter:: setvar VAR_0x8008, 48 - setvar VAR_ITEM_ID, MOVE_COUNTER + setvar VAR_0x8005, MOVE_COUNTER goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection end BattleFrontier_Lounge7_EventScript_ThunderWave:: setvar VAR_0x8008, 48 - setvar VAR_ITEM_ID, MOVE_THUNDER_WAVE + setvar VAR_0x8005, MOVE_THUNDER_WAVE goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection end BattleFrontier_Lounge7_EventScript_SwordsDance:: setvar VAR_0x8008, 48 - setvar VAR_ITEM_ID, MOVE_SWORDS_DANCE + setvar VAR_0x8005, MOVE_SWORDS_DANCE goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection end @@ -192,61 +192,61 @@ BattleFrontier_Lounge7_EventScript_ChooseNewRightTutorMove:: BattleFrontier_Lounge7_EventScript_DefenseCurl:: setvar VAR_0x8008, 16 - setvar VAR_ITEM_ID, MOVE_DEFENSE_CURL + setvar VAR_0x8005, MOVE_DEFENSE_CURL goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection end BattleFrontier_Lounge7_EventScript_Snore:: setvar VAR_0x8008, 24 - setvar VAR_ITEM_ID, MOVE_SNORE + setvar VAR_0x8005, MOVE_SNORE goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection end BattleFrontier_Lounge7_EventScript_MudSlap:: setvar VAR_0x8008, 24 - setvar VAR_ITEM_ID, MOVE_MUD_SLAP + setvar VAR_0x8005, MOVE_MUD_SLAP goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection end BattleFrontier_Lounge7_EventScript_Swift:: setvar VAR_0x8008, 24 - setvar VAR_ITEM_ID, MOVE_SWIFT + setvar VAR_0x8005, MOVE_SWIFT goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection end BattleFrontier_Lounge7_EventScript_IcyWind:: setvar VAR_0x8008, 24 - setvar VAR_ITEM_ID, MOVE_ICY_WIND + setvar VAR_0x8005, MOVE_ICY_WIND goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection end BattleFrontier_Lounge7_EventScript_Endure:: setvar VAR_0x8008, 48 - setvar VAR_ITEM_ID, MOVE_ENDURE + setvar VAR_0x8005, MOVE_ENDURE goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection end BattleFrontier_Lounge7_EventScript_PsychUp:: setvar VAR_0x8008, 48 - setvar VAR_ITEM_ID, MOVE_PSYCH_UP + setvar VAR_0x8005, MOVE_PSYCH_UP goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection end BattleFrontier_Lounge7_EventScript_IcePunch:: setvar VAR_0x8008, 48 - setvar VAR_ITEM_ID, MOVE_ICE_PUNCH + setvar VAR_0x8005, MOVE_ICE_PUNCH goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection end BattleFrontier_Lounge7_EventScript_ThunderPunch:: setvar VAR_0x8008, 48 - setvar VAR_ITEM_ID, MOVE_THUNDER_PUNCH + setvar VAR_0x8005, MOVE_THUNDER_PUNCH goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection end BattleFrontier_Lounge7_EventScript_FirePunch:: setvar VAR_0x8008, 48 - setvar VAR_ITEM_ID, MOVE_FIRE_PUNCH + setvar VAR_0x8005, MOVE_FIRE_PUNCH goto BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection end @@ -277,21 +277,15 @@ BattleFrontier_Lounge7_EventScript_ConfirmMoveSelection:: goto BattleFrontier_Lounge7_EventScript_ChooseNewMove end + BattleFrontier_Lounge7_EventScript_TeachTutorMove:: msgbox BattleFrontier_Lounge7_Text_TeachMoveToWhichMon, MSGBOX_DEFAULT fadescreen FADE_TO_BLACK special CloseBattlePointsWindow special CloseBattleFrontierTutorWindow - special ChooseBoxMon + chooseboxmon SELECT_PC_MON_MOVE_TUTOR waitstate - special IsSelectedMonEgg - goto_if_eq VAR_RESULT, TRUE, MoveTutor_EggCantForgetMoves - special CanTeachMoveBoxMon - goto_if_eq VAR_RESULT, 1, MoveTutor_CantLearnMove - goto_if_eq VAR_RESULT, 2, MoveTutor_AlreadyKnowsMove - goto_if_eq VAR_RESULT, 3, MoveTutor_EggCantForgetMoves - waitstate - goto_if_eq VAR_RESULT, 4, BattleFrontier_Lounge7_EventScript_CancelChooseMon + goto_if_eq VAR_RESULT, FALSE, BattleFrontier_Lounge7_EventScript_CancelChooseMon msgbox BattleFrontier_Lounge7_Text_IllTakeBattlePoints, MSGBOX_DEFAULT copyvar VAR_0x8004, VAR_0x8008 special TakeFrontierBattlePoints diff --git a/data/maps/FallarborTown_MoveRelearnersHouse/scripts.inc b/data/maps/FallarborTown_MoveRelearnersHouse/scripts.inc index 4a85028490..9fcded5790 100644 --- a/data/maps/FallarborTown_MoveRelearnersHouse/scripts.inc +++ b/data/maps/FallarborTown_MoveRelearnersHouse/scripts.inc @@ -23,13 +23,13 @@ FallarborTown_MoveRelearnersHouse_EventScript_AskTeachMove:: FallarborTown_MoveRelearnersHouse_EventScript_ChooseMon:: msgbox FallarborTown_MoveRelearnersHouse_Text_TutorWhichMon, MSGBOX_DEFAULT setmoverelearnerstate MOVE_RELEARNER_LEVEL_UP_MOVES @ Specifically supposed to teach level up moves - fadescreen FADE_TO_BLACK - special ChooseBoxMon + chooseboxmon SELECT_PC_MON_MOVE_RELEARNER waitstate goto_if_eq VAR_0x8004, PARTY_NOTHING_CHOSEN, FallarborTown_MoveRelearnersHouse_EventScript_ComeBackWithHeartScale special IsSelectedMonEgg goto_if_eq VAR_RESULT, TRUE, FallarborTown_MoveRelearnersHouse_EventScript_CantTeachEgg - goto_if_eq VAR_0x8005, 0, FallarborTown_MoveRelearnersHouse_EventScript_NoMoveToTeachMon + special HasMovesToRelearn + goto_if_eq VAR_RESULT, FALSE, FallarborTown_MoveRelearnersHouse_EventScript_NoMoveToTeachMon goto FallarborTown_MoveRelearnersHouse_EventScript_ChooseMove end diff --git a/data/maps/FortreeCity_House1/scripts.inc b/data/maps/FortreeCity_House1/scripts.inc index e84348c26a..66d8b39f7e 100644 --- a/data/maps/FortreeCity_House1/scripts.inc +++ b/data/maps/FortreeCity_House1/scripts.inc @@ -5,28 +5,7 @@ FortreeCity_House1_EventScript_Trader:: lock faceplayer goto_if_set FLAG_FORTREE_NPC_TRADE_COMPLETED, FortreeCity_House1_EventScript_TradeCompleted - setvar VAR_0x8008, INGAME_TRADE_PLUSLE - copyvar VAR_0x8004, VAR_0x8008 - specialvar VAR_RESULT, GetInGameTradeSpeciesInfo - copyvar VAR_0x8009, VAR_RESULT - msgbox FortreeCity_House1_Text_YouWillTradeWontYou, MSGBOX_YESNO - goto_if_eq VAR_RESULT, NO, FortreeCity_House1_EventScript_DeclineTrade - fadescreen FADE_TO_BLACK - special ChooseBoxMon - waitstate - copyvar VAR_0x800A, VAR_0x8004 - goto_if_eq VAR_0x8004, PARTY_NOTHING_CHOSEN, FortreeCity_House1_EventScript_DeclineTrade - copyvar VAR_0x8005, VAR_0x800A - specialvar VAR_RESULT, GetTradeSpecies - copyvar VAR_0x800B, VAR_RESULT - goto_if_ne VAR_RESULT, VAR_0x8009, FortreeCity_House1_EventScript_NotRequestedMon - copyvar VAR_0x8004, VAR_0x8008 - copyvar VAR_0x8005, VAR_0x800A - special CreateInGameTradePokemon - special DoInGameTradeScene - waitstate - bufferspeciesname STR_VAR_1, VAR_0x8009 - msgbox FortreeCity_House1_Text_MonYouTakeCare, MSGBOX_DEFAULT + ingame_trade INGAME_TRADE_PLUSLE, FortreeCity_House1_Text_YouWillTradeWontYou, FortreeCity_House1_EventScript_DeclineTrade, FortreeCity_House1_EventScript_NotRequestedMon, FortreeCity_House1_Text_MonYouTakeCare setflag FLAG_FORTREE_NPC_TRADE_COMPLETED release end diff --git a/data/maps/LilycoveCity_MoveDeletersHouse/scripts.inc b/data/maps/LilycoveCity_MoveDeletersHouse/scripts.inc index 4d1b8477fc..4dc933056d 100644 --- a/data/maps/LilycoveCity_MoveDeletersHouse/scripts.inc +++ b/data/maps/LilycoveCity_MoveDeletersHouse/scripts.inc @@ -14,8 +14,7 @@ LilycoveCity_MoveDeletersHouse_EventScript_MoveDeleter:: LilycoveCity_MoveDeletersHouse_EventScript_ChooseMonAndMoveToForget:: msgbox LilycoveCity_MoveDeletersHouse_Text_WhichMonShouldForget, MSGBOX_DEFAULT - fadescreen FADE_TO_BLACK - special ChooseBoxMon + chooseboxmon SELECT_PC_MON_MOVE_DELETER waitstate goto_if_eq VAR_0x8004, PARTY_NOTHING_CHOSEN, LilycoveCity_MoveDeletersHouse_EventScript_ComeAgain special IsSelectedMonEgg diff --git a/data/maps/PacifidlogTown_House3/scripts.inc b/data/maps/PacifidlogTown_House3/scripts.inc index 83c908ffe9..22abdecec8 100644 --- a/data/maps/PacifidlogTown_House3/scripts.inc +++ b/data/maps/PacifidlogTown_House3/scripts.inc @@ -5,28 +5,7 @@ PacifidlogTown_House3_EventScript_Trader:: lock faceplayer goto_if_set FLAG_PACIFIDLOG_NPC_TRADE_COMPLETED, PacifidlogTown_House3_EventScript_TradeCompleted - setvar VAR_0x8008, INGAME_TRADE_HORSEA - copyvar VAR_0x8004, VAR_0x8008 - specialvar VAR_RESULT, GetInGameTradeSpeciesInfo - copyvar VAR_0x8009, VAR_RESULT - msgbox PacifidlogTown_House3_Text_WillingToTradeIt, MSGBOX_YESNO - goto_if_eq VAR_RESULT, NO, PacifidlogTown_House3_EventScript_DeclineTrade - fadescreen FADE_TO_BLACK - special ChooseBoxMon - waitstate - copyvar VAR_0x800A, VAR_0x8004 - goto_if_eq VAR_0x8004, PARTY_NOTHING_CHOSEN, PacifidlogTown_House3_EventScript_DeclineTrade - copyvar VAR_0x8005, VAR_0x800A - specialvar VAR_RESULT, GetTradeSpecies - copyvar VAR_0x800B, VAR_RESULT - goto_if_ne VAR_RESULT, VAR_0x8009, PacifidlogTown_House3_EventScript_NotRequestedMon - copyvar VAR_0x8004, VAR_0x8008 - copyvar VAR_0x8005, VAR_0x800A - special CreateInGameTradePokemon - special DoInGameTradeScene - waitstate - bufferspeciesname STR_VAR_1, VAR_0x8009 - msgbox PacifidlogTown_House3_Text_ItsSubtlyDifferentThankYou, MSGBOX_DEFAULT + ingame_trade INGAME_TRADE_HORSEA, PacifidlogTown_House3_Text_WillingToTradeIt, PacifidlogTown_House3_EventScript_DeclineTrade, PacifidlogTown_House3_EventScript_NotRequestedMon, PacifidlogTown_House3_Text_ItsSubtlyDifferentThankYou setflag FLAG_PACIFIDLOG_NPC_TRADE_COMPLETED release end diff --git a/data/maps/RustboroCity_House1/scripts.inc b/data/maps/RustboroCity_House1/scripts.inc index 7960f4ab62..b12fce094a 100644 --- a/data/maps/RustboroCity_House1/scripts.inc +++ b/data/maps/RustboroCity_House1/scripts.inc @@ -5,27 +5,7 @@ RustboroCity_House1_EventScript_Trader:: lock faceplayer goto_if_set FLAG_RUSTBORO_NPC_TRADE_COMPLETED, RustboroCity_House1_EventScript_TradeCompleted - setvar VAR_0x8008, INGAME_TRADE_SEEDOT - copyvar VAR_0x8004, VAR_0x8008 - specialvar VAR_RESULT, GetInGameTradeSpeciesInfo - copyvar VAR_0x8009, VAR_RESULT - msgbox RustboroCity_House1_Text_IllTradeIfYouWant, MSGBOX_YESNO - goto_if_eq VAR_RESULT, NO, RustboroCity_House1_EventScript_DeclineTrade - fadescreen FADE_TO_BLACK - special ChooseBoxMon - waitstate - copyvar VAR_0x800A, VAR_0x8004 - goto_if_eq VAR_0x8004, PARTY_NOTHING_CHOSEN, RustboroCity_House1_EventScript_DeclineTrade - copyvar VAR_0x8005, VAR_0x800A - specialvar VAR_RESULT, GetTradeSpecies - copyvar VAR_0x800B, VAR_RESULT - goto_if_ne VAR_RESULT, VAR_0x8009, RustboroCity_House1_EventScript_NotRequestedMon - copyvar VAR_0x8004, VAR_0x8008 - copyvar VAR_0x8005, VAR_0x800A - special CreateInGameTradePokemon - special DoInGameTradeScene - waitstate - msgbox RustboroCity_House1_Text_PleaseBeGoodToMyPokemon, MSGBOX_DEFAULT + ingame_trade INGAME_TRADE_SEEDOT, RustboroCity_House1_Text_IllTradeIfYouWant, RustboroCity_House1_EventScript_DeclineTrade, RustboroCity_House1_EventScript_NotRequestedMon, RustboroCity_House1_Text_PleaseBeGoodToMyPokemon setflag FLAG_RUSTBORO_NPC_TRADE_COMPLETED release end diff --git a/data/maps/SlateportCity_NameRatersHouse/scripts.inc b/data/maps/SlateportCity_NameRatersHouse/scripts.inc index 1aeca39111..7c10185096 100644 --- a/data/maps/SlateportCity_NameRatersHouse/scripts.inc +++ b/data/maps/SlateportCity_NameRatersHouse/scripts.inc @@ -11,8 +11,7 @@ SlateportCity_NameRatersHouse_EventScript_NameRater:: SlateportCity_NameRatersHouse_EventScript_ChooseMonToRate:: msgbox SlateportCity_NameRatersHouse_Text_CritiqueWhichMonNickname, MSGBOX_DEFAULT - fadescreen FADE_TO_BLACK - special ChooseBoxMon + chooseboxmon waitstate goto_if_ne VAR_0x8004, PARTY_NOTHING_CHOSEN, SlateportCity_NameRatersHouse_EventScript_RateMonNickname goto_if_eq VAR_0x8004, PARTY_NOTHING_CHOSEN, SlateportCity_NameRatersHouse_EventScript_DeclineNameRate @@ -49,8 +48,7 @@ SlateportCity_NameRatersHouse_EventScript_PlayerNotMonsOT:: SlateportCity_NameRatersHouse_EventScript_ChangeNickname:: msgbox SlateportCity_NameRatersHouse_Text_WhatShallNewNameBe, MSGBOX_DEFAULT - call_if_eq VAR_MON_BOX_ID, 0xFF, Common_EventScript_NameReceivedPartyMon - call_if_ne VAR_MON_BOX_ID, 0xFF, Common_EventScript_NameReceivedBoxMon + call Common_EventScript_NameReceivedPartyMon specialvar VAR_RESULT, TryPutNameRaterShowOnTheAir special BufferMonNickname goto_if_eq VAR_RESULT, TRUE, SlateportCity_NameRatersHouse_EventScript_NewNameDifferent diff --git a/data/maps/SootopolisCity_LotadAndSeedotHouse/scripts.inc b/data/maps/SootopolisCity_LotadAndSeedotHouse/scripts.inc index c683d24f26..c6736eb922 100644 --- a/data/maps/SootopolisCity_LotadAndSeedotHouse/scripts.inc +++ b/data/maps/SootopolisCity_LotadAndSeedotHouse/scripts.inc @@ -6,11 +6,10 @@ SootopolisCity_LotadAndSeedotHouse_EventScript_SeedotBrother:: lock faceplayer msgbox SootopolisCity_LotadAndSeedotHouse_Text_PleaseShowMeBigSeedot, MSGBOX_DEFAULT - fadescreen FADE_TO_BLACK - special ChooseBoxMon + setvar VAR_0x8009, SPECIES_SEEDOT + chooseboxmon SELECT_PC_MON_TRADE waitstate - copyvar VAR_RESULT, VAR_0x8004 - goto_if_eq VAR_RESULT, PARTY_NOTHING_CHOSEN, SootopolisCity_LotadAndSeedotHouse_EventScript_CancelShowSeedot + goto_if_eq VAR_0x8004, PARTY_NOTHING_CHOSEN, SootopolisCity_LotadAndSeedotHouse_EventScript_CancelShowSeedot special CompareSeedotSize goto_if_eq VAR_RESULT, 1, SootopolisCity_LotadAndSeedotHouse_EventScript_NotSeedot goto_if_eq VAR_RESULT, 2, SootopolisCity_LotadAndSeedotHouse_EventScript_SmallSeedot @@ -51,11 +50,10 @@ SootopolisCity_LotadAndSeedotHouse_EventScript_LotadBrother:: lock faceplayer msgbox SootopolisCity_LotadAndSeedotHouse_Text_PleaseShowMeBigLotad, MSGBOX_DEFAULT - fadescreen FADE_TO_BLACK - special ChooseBoxMon + setvar VAR_0x8009, SPECIES_LOTAD + chooseboxmon SELECT_PC_MON_TRADE waitstate - copyvar VAR_RESULT, VAR_0x8004 - goto_if_eq VAR_RESULT, PARTY_NOTHING_CHOSEN, SootopolisCity_LotadAndSeedotHouse_EventScript_CancelShowLotad + goto_if_eq VAR_0x8004, PARTY_NOTHING_CHOSEN, SootopolisCity_LotadAndSeedotHouse_EventScript_CancelShowLotad special CompareLotadSize goto_if_eq VAR_RESULT, 1, SootopolisCity_LotadAndSeedotHouse_EventScript_NotLotad goto_if_eq VAR_RESULT, 2, SootopolisCity_LotadAndSeedotHouse_EventScript_SmallLotad diff --git a/data/scripts/day_care.inc b/data/scripts/day_care.inc index 804f733298..6d5e204632 100644 --- a/data/scripts/day_care.inc +++ b/data/scripts/day_care.inc @@ -89,8 +89,7 @@ Route117_PokemonDayCare_EventScript_GiveMonToRaise:: specialvar VAR_RESULT, CountPartyAliveNonEggMons goto_if_eq VAR_RESULT, 2, Route117_PokemonDayCare_EventScript_OnlyTwoAliveMons msgbox Route117_PokemonDayCare_Text_WhichMonShouldWeRaise, MSGBOX_DEFAULT - fadescreen FADE_TO_BLACK - special ChooseBoxMon + chooseboxmon SELECT_PC_MON_DAYCARE waitstate goto_if_eq VAR_0x8004, PARTY_NOTHING_CHOSEN, Route117_PokemonDayCare_EventScript_ComeAgain specialvar VAR_RESULT, CountPartyAliveNonEggMons_IgnoreVar0x8004Slot diff --git a/data/scripts/move_relearner.inc b/data/scripts/move_relearner.inc index 15c80733df..8a4ae86cbf 100644 --- a/data/scripts/move_relearner.inc +++ b/data/scripts/move_relearner.inc @@ -71,12 +71,13 @@ MoveRelearner_EventScript_TeachMove:: getpartysize goto_if_eq VAR_RESULT, 0, MoveRelearner_EventScript_NoPkmn msgbox MoveRelearner_Text_ChoosePkmn, MSGBOX_DEFAULT - special ChooseMonForMoveRelearner + chooseboxmon SELECT_PC_MON_MOVE_RELEARNER waitstate call_if_eq VAR_0x8004, PARTY_NOTHING_CHOSEN, MoveRelearner_EventScript_AnythingElse special IsSelectedMonEgg - call_if_eq VAR_RESULT, YES, MoveRelearner_EventScript_CantTeachMoveToEgg - call_if_eq VAR_0x8005, NO, MoveRelearner_EventScript_CantTeachMoveToPkmn + call_if_eq VAR_RESULT, TRUE, MoveRelearner_EventScript_CantTeachMoveToEgg + special HasMovesToRelearn + call_if_eq VAR_RESULT, FALSE, MoveRelearner_EventScript_CantTeachMoveToPkmn msgbox MoveRelearner_Text_WhichXmoveShouldTeach, MSGBOX_DEFAULT special TeachMoveRelearnerMove waitstate diff --git a/data/scripts/move_tutors.inc b/data/scripts/move_tutors.inc index 05652b265f..1748d1417b 100644 --- a/data/scripts/move_tutors.inc +++ b/data/scripts/move_tutors.inc @@ -1,18 +1,8 @@ SlateportCity_PokemonFanClub_EventScript_SwaggerTutor:: lock faceplayer - goto_if_set FLAG_MOVE_TUTOR_TAUGHT_SWAGGER, MoveTutor_EventScript_SwaggerTaught - msgbox MoveTutor_Text_SwaggerTeach, MSGBOX_YESNO - goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_SwaggerDeclined - call MoveTutor_EventScript_CanOnlyBeLearnedOnce - goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_SwaggerDeclined - msgbox MoveTutor_Text_SwaggerWhichMon, MSGBOX_DEFAULT - setvar VAR_ITEM_ID, MOVE_SWAGGER - buffermovename STR_VAR_1, MOVE_SWAGGER - call MoveTutor_EventScript_OpenBox - goto_if_eq VAR_RESULT, 4, MoveTutor_EventScript_SwaggerDeclined - setflag FLAG_MOVE_TUTOR_TAUGHT_SWAGGER - goto MoveTutor_EventScript_SwaggerTaught + move_tutor MOVE_SWAGGER, MoveTutor_Text_SwaggerTeach, MoveTutor_Text_SwaggerWhichMon, MoveTutor_EventScript_SwaggerDeclined, MoveTutor_EventScript_SwaggerTaught, FLAG_MOVE_TUTOR_TAUGHT_SWAGGER + release end MoveTutor_EventScript_SwaggerDeclined:: @@ -28,18 +18,8 @@ MoveTutor_EventScript_SwaggerTaught:: MauvilleCity_EventScript_RolloutTutor:: lock faceplayer - goto_if_set FLAG_MOVE_TUTOR_TAUGHT_ROLLOUT, MoveTutor_EventScript_RolloutTaught - msgbox MoveTutor_Text_RolloutTeach, MSGBOX_YESNO - goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_RolloutDeclined - call MoveTutor_EventScript_CanOnlyBeLearnedOnce - goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_RolloutDeclined - msgbox MoveTutor_Text_RolloutWhichMon, MSGBOX_DEFAULT - setvar VAR_ITEM_ID, MOVE_ROLLOUT - buffermovename STR_VAR_1, MOVE_ROLLOUT - call MoveTutor_EventScript_OpenBox - goto_if_eq VAR_RESULT, 4, MoveTutor_EventScript_RolloutDeclined - setflag FLAG_MOVE_TUTOR_TAUGHT_ROLLOUT - goto MoveTutor_EventScript_RolloutTaught + move_tutor MOVE_ROLLOUT, MoveTutor_Text_RolloutTeach, MoveTutor_Text_RolloutWhichMon, MoveTutor_EventScript_RolloutDeclined, MoveTutor_EventScript_RolloutTaught, FLAG_MOVE_TUTOR_TAUGHT_ROLLOUT + release end MoveTutor_EventScript_RolloutDeclined:: @@ -55,18 +35,7 @@ MoveTutor_EventScript_RolloutTaught:: VerdanturfTown_PokemonCenter_1F_EventScript_FuryCutterTutor:: lock faceplayer - goto_if_set FLAG_MOVE_TUTOR_TAUGHT_FURY_CUTTER, MoveTutor_EventScript_FuryCutterTaught - msgbox MoveTutor_Text_FuryCutterTeach, MSGBOX_YESNO - goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_FuryCutterDeclined - call MoveTutor_EventScript_CanOnlyBeLearnedOnce - goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_FuryCutterDeclined - msgbox MoveTutor_Text_FuryCutterWhichMon, MSGBOX_DEFAULT - setvar VAR_ITEM_ID, MOVE_FURY_CUTTER - buffermovename STR_VAR_1, MOVE_FURY_CUTTER - call MoveTutor_EventScript_OpenBox - goto_if_eq VAR_RESULT, 4, MoveTutor_EventScript_FuryCutterDeclined - setflag FLAG_MOVE_TUTOR_TAUGHT_FURY_CUTTER - goto MoveTutor_EventScript_FuryCutterTaught + move_tutor MOVE_FURY_CUTTER, MoveTutor_Text_FuryCutterTeach, MoveTutor_Text_FuryCutterWhichMon, MoveTutor_EventScript_FuryCutterDeclined, MoveTutor_EventScript_FuryCutterTaught, FLAG_MOVE_TUTOR_TAUGHT_FURY_CUTTER end MoveTutor_EventScript_FuryCutterDeclined:: @@ -82,18 +51,7 @@ MoveTutor_EventScript_FuryCutterTaught:: LavaridgeTown_House_EventScript_MimicTutor:: lock faceplayer - goto_if_set FLAG_MOVE_TUTOR_TAUGHT_MIMIC, MoveTutor_EventScript_MimicTaught - msgbox MoveTutor_MimicTeach, MSGBOX_YESNO - goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_MimicDeclined - call MoveTutor_EventScript_CanOnlyBeLearnedOnce - goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_MimicDeclined - msgbox MoveTutor_Text_MimicWhichMon, MSGBOX_DEFAULT - setvar VAR_ITEM_ID, MOVE_MIMIC - buffermovename STR_VAR_1, MOVE_MIMIC - call MoveTutor_EventScript_OpenBox - goto_if_eq VAR_RESULT, 4, MoveTutor_EventScript_MimicDeclined - setflag FLAG_MOVE_TUTOR_TAUGHT_MIMIC - goto MoveTutor_EventScript_MimicTaught + move_tutor MOVE_MIMIC, MoveTutor_MimicTeach, MoveTutor_Text_MimicWhichMon, MoveTutor_EventScript_MimicDeclined, MoveTutor_EventScript_MimicTaught, FLAG_MOVE_TUTOR_TAUGHT_MIMIC end MoveTutor_EventScript_MimicDeclined:: @@ -109,18 +67,7 @@ MoveTutor_EventScript_MimicTaught:: FallarborTown_Mart_EventScript_MetronomeTutor:: lock faceplayer - goto_if_set FLAG_MOVE_TUTOR_TAUGHT_METRONOME, MoveTutor_EventScript_MetronomeTaught - msgbox MoveTutor_Text_MetronomeTeach, MSGBOX_YESNO - goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_MetronomeDeclined - call MoveTutor_EventScript_CanOnlyBeLearnedOnce - goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_MetronomeDeclined - msgbox MoveTutor_Text_MetronomeWhichMon, MSGBOX_DEFAULT - setvar VAR_ITEM_ID, MOVE_METRONOME - buffermovename STR_VAR_1, MOVE_METRONOME - call MoveTutor_EventScript_OpenBox - goto_if_eq VAR_RESULT, 4, MoveTutor_EventScript_MetronomeDeclined - setflag FLAG_MOVE_TUTOR_TAUGHT_METRONOME - goto MoveTutor_EventScript_MetronomeTaught + move_tutor MOVE_METRONOME, MoveTutor_Text_MetronomeTeach, MoveTutor_Text_MetronomeWhichMon, MoveTutor_EventScript_MetronomeDeclined, MoveTutor_EventScript_MetronomeTaught, FLAG_MOVE_TUTOR_TAUGHT_METRONOME end MoveTutor_EventScript_MetronomeDeclined:: @@ -136,18 +83,7 @@ MoveTutor_EventScript_MetronomeTaught:: FortreeCity_House2_EventScript_SleepTalkTutor:: lock faceplayer - goto_if_set FLAG_MOVE_TUTOR_TAUGHT_SLEEP_TALK, MoveTutor_EventScript_SleepTalkTaught - msgbox MoveTutor_Text_SleepTalkTeach, MSGBOX_YESNO - goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_SleepTalkDeclined - call MoveTutor_EventScript_CanOnlyBeLearnedOnce - goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_SleepTalkDeclined - msgbox MoveTutor_Text_SleepTalkWhichMon, MSGBOX_DEFAULT - setvar VAR_ITEM_ID, MOVE_SLEEP_TALK - buffermovename STR_VAR_1, MOVE_SLEEP_TALK - call MoveTutor_EventScript_OpenBox - goto_if_eq VAR_RESULT, 4, MoveTutor_EventScript_SleepTalkDeclined - setflag FLAG_MOVE_TUTOR_TAUGHT_SLEEP_TALK - goto MoveTutor_EventScript_SleepTalkTaught + move_tutor MOVE_SLEEP_TALK, MoveTutor_Text_SleepTalkTeach, MoveTutor_Text_SleepTalkWhichMon, MoveTutor_EventScript_SleepTalkDeclined, MoveTutor_EventScript_SleepTalkTaught, FLAG_MOVE_TUTOR_TAUGHT_SLEEP_TALK end MoveTutor_EventScript_SleepTalkDeclined:: @@ -163,18 +99,7 @@ MoveTutor_EventScript_SleepTalkTaught:: LilycoveCity_DepartmentStoreRooftop_EventScript_SubstituteTutor:: lock faceplayer - goto_if_set FLAG_MOVE_TUTOR_TAUGHT_SUBSTITUTE, MoveTutor_EventScript_SubstituteTaught - msgbox MoveTutor_Text_SubstituteTeach, MSGBOX_YESNO - goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_SubstituteDeclined - call MoveTutor_EventScript_CanOnlyBeLearnedOnce - goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_SubstituteDeclined - msgbox MoveTutor_Text_SubstituteWhichMon, MSGBOX_DEFAULT - setvar VAR_ITEM_ID, MOVE_SUBSTITUTE - buffermovename STR_VAR_1, MOVE_SUBSTITUTE - call MoveTutor_EventScript_OpenBox - goto_if_eq VAR_RESULT, 4, MoveTutor_EventScript_SubstituteDeclined - setflag FLAG_MOVE_TUTOR_TAUGHT_SUBSTITUTE - goto MoveTutor_EventScript_SubstituteTaught + move_tutor MOVE_SUBSTITUTE, MoveTutor_Text_SubstituteTeach, MoveTutor_Text_SubstituteWhichMon, MoveTutor_EventScript_SubstituteDeclined, MoveTutor_EventScript_SubstituteTaught, FLAG_MOVE_TUTOR_TAUGHT_SUBSTITUTE end MoveTutor_EventScript_SubstituteDeclined:: @@ -190,18 +115,7 @@ MoveTutor_EventScript_SubstituteTaught:: MossdeepCity_EventScript_DynamicPunchTutor:: lock faceplayer - goto_if_set FLAG_MOVE_TUTOR_TAUGHT_DYNAMICPUNCH, MoveTutor_EventScript_DynamicPunchTaught - msgbox MoveTutor_Text_DynamicPunchTeach, MSGBOX_YESNO - goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_DynamicPunchDeclined - call MoveTutor_EventScript_CanOnlyBeLearnedOnce - goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_DynamicPunchDeclined - msgbox MoveTutor_Text_DynamicPunchWhichMon, MSGBOX_DEFAULT - setvar VAR_ITEM_ID, MOVE_DYNAMIC_PUNCH - buffermovename STR_VAR_1, MOVE_DYNAMIC_PUNCH - call MoveTutor_EventScript_OpenBox - goto_if_eq VAR_RESULT, 4, MoveTutor_EventScript_DynamicPunchDeclined - setflag FLAG_MOVE_TUTOR_TAUGHT_DYNAMICPUNCH - goto MoveTutor_EventScript_DynamicPunchTaught + move_tutor MOVE_DYNAMIC_PUNCH, MoveTutor_Text_DynamicPunchTeach, MoveTutor_Text_DynamicPunchWhichMon, MoveTutor_EventScript_DynamicPunchDeclined, MoveTutor_EventScript_DynamicPunchTaught, FLAG_MOVE_TUTOR_TAUGHT_DYNAMICPUNCH end MoveTutor_EventScript_DynamicPunchDeclined:: @@ -217,18 +131,7 @@ MoveTutor_EventScript_DynamicPunchTaught:: SootopolisCity_PokemonCenter_1F_EventScript_DoubleEdgeTutor:: lock faceplayer - goto_if_set FLAG_MOVE_TUTOR_TAUGHT_DOUBLE_EDGE, MoveTutor_EventScript_DoubleEdgeTaught - msgbox MoveTutor_Text_DoubleEdgeTeach, MSGBOX_YESNO - goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_DoubleEdgeDeclined - call MoveTutor_EventScript_CanOnlyBeLearnedOnce - goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_DoubleEdgeDeclined - msgbox MoveTutor_Text_DoubleEdgeWhichMon, MSGBOX_DEFAULT - setvar VAR_ITEM_ID, MOVE_DOUBLE_EDGE - buffermovename STR_VAR_1, MOVE_DOUBLE_EDGE - call MoveTutor_EventScript_OpenBox - goto_if_eq VAR_RESULT, 4, MoveTutor_EventScript_DoubleEdgeDeclined - setflag FLAG_MOVE_TUTOR_TAUGHT_DOUBLE_EDGE - goto MoveTutor_EventScript_DoubleEdgeTaught + move_tutor MOVE_DOUBLE_EDGE, MoveTutor_Text_DoubleEdgeTeach, MoveTutor_Text_DoubleEdgeWhichMon, MoveTutor_EventScript_DoubleEdgeDeclined, MoveTutor_EventScript_DoubleEdgeTaught, FLAG_MOVE_TUTOR_TAUGHT_DOUBLE_EDGE end MoveTutor_EventScript_DoubleEdgeDeclined:: @@ -244,18 +147,7 @@ MoveTutor_EventScript_DoubleEdgeTaught:: PacifidlogTown_PokemonCenter_1F_EventScript_ExplosionTutor:: lock faceplayer - goto_if_set FLAG_MOVE_TUTOR_TAUGHT_EXPLOSION, MoveTutor_EventScript_ExplosionTaught - msgbox MoveTutor_Text_ExplosionTeach, MSGBOX_YESNO - goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_ExplosionDeclined - call MoveTutor_EventScript_CanOnlyBeLearnedOnce - goto_if_eq VAR_RESULT, NO, MoveTutor_EventScript_ExplosionDeclined - msgbox MoveTutor_Text_ExplosionWhichMon, MSGBOX_DEFAULT - setvar VAR_ITEM_ID, MOVE_EXPLOSION - buffermovename STR_VAR_1, MOVE_EXPLOSION - call MoveTutor_EventScript_OpenBox - goto_if_eq VAR_RESULT, 4, MoveTutor_EventScript_ExplosionDeclined - setflag FLAG_MOVE_TUTOR_TAUGHT_EXPLOSION - goto MoveTutor_EventScript_ExplosionTaught + move_tutor MOVE_EXPLOSION, MoveTutor_Text_ExplosionTeach, MoveTutor_Text_ExplosionWhichMon, MoveTutor_EventScript_ExplosionDeclined, MoveTutor_EventScript_ExplosionTaught, FLAG_MOVE_TUTOR_TAUGHT_EXPLOSION end MoveTutor_EventScript_ExplosionDeclined:: @@ -276,66 +168,18 @@ MoveTutor_EventScript_OpenPartyMenu:: return MoveTutor_EventScript_OpenBox:: - fadescreen FADE_TO_BLACK - special ChooseBoxMon - waitstate - special IsSelectedMonEgg - goto_if_eq VAR_RESULT, TRUE, MoveTutor_EggCantForgetMoves - special CanTeachMoveBoxMon - goto_if_eq VAR_RESULT, 1, MoveTutor_CantLearnMove - goto_if_eq VAR_RESULT, 2, MoveTutor_AlreadyKnowsMove - goto_if_eq VAR_RESULT, 3, MoveTutor_EggCantForgetMoves - waitstate - return - -MoveTutor_ForgetMove:: - special MoveDeleterChooseMoveToForget - fadescreen FADE_FROM_BLACK - msgbox LilycoveCity_MoveDeletersHouse_Text_MonsMoveShouldBeForgotten, MSGBOX_YESNO - switch VAR_RESULT - case YES, LilycoveCity_MoveDeletersHouse_EventScript_TryForgetMove - case NO, LilycoveCity_MoveDeletersHouse_EventScript_ComeAgain - - goto_if_eq VAR_0x8005, MAX_MON_MOVES, LilycoveCity_MoveDeletersHouse_EventScript_ChooseMonAndMoveToForget - special BufferMoveDeleterNicknameAndMove - msgbox LilycoveCity_MoveDeletersHouse_Text_MonsMoveShouldBeForgotten, MSGBOX_YESNO - switch VAR_RESULT - case YES, LilycoveCity_MoveDeletersHouse_EventScript_TryForgetMove - case NO, LilycoveCity_MoveDeletersHouse_EventScript_ComeAgain - -MoveTutor_MoveDeletersHouse_EventScript_TryForgetMove:: - special MoveDeleterForgetMove - playfanfare MUS_MOVE_DELETED - waitfanfare - msgbox LilycoveCity_MoveDeletersHouse_Text_MonHasForgottenMove, MSGBOX_DEFAULT + chooseboxmon SELECT_PC_MON_MOVE_TUTOR waitstate lock faceplayer return -MoveTutor_EggCantForgetMoves:: - msgbox LilycoveCity_MoveDeletersHouse_Text_EggCantForgetMoves, MSGBOX_DEFAULT - releaseall - end - -MoveTutor_CantLearnMove:: - msgbox MoveTutor_Text_CantLearnMove, MSGBOX_DEFAULT - releaseall - end - -MoveTutor_AlreadyKnowsMove:: - msgbox MoveTutor_Text_AlreadyKnowsMove, MSGBOX_DEFAULT - releaseall - end - -MoveTutor_Text_CantLearnMove: - .string "But that Pokemon can't learn\n" - .string "{STR_VAR_1}.$" - -MoveTutor_Text_AlreadyKnowsMove: - .string "But that Pokemon already knows\n" - .string "{STR_VAR_1}.$" - MoveTutor_EventScript_CanOnlyBeLearnedOnce:: msgbox MoveTutor_Text_ThisMoveCanOnlyBeLearnedOnce, MSGBOX_YESNO return + +MoveTutor_AfterChooseBoxMon:: + waitstate + special CanTeachMoveBoxMon + waitstate + return diff --git a/data/scripts/pc_transfer.inc b/data/scripts/pc_transfer.inc index f279740caa..a1321140fa 100644 --- a/data/scripts/pc_transfer.inc +++ b/data/scripts/pc_transfer.inc @@ -7,7 +7,8 @@ Common_EventScript_GetGiftMonPartySlot:: Common_EventScript_NameReceivedBoxMon:: fadescreen FADE_TO_BLACK - special ChangeBoxPokemonNickname + setvar VAR_0x8004, PC_MON_CHOSEN + special ChangePokemonNickname waitstate lock faceplayer diff --git a/data/specials.inc b/data/specials.inc index 2bd8c670bd..1aee7e91cb 100644 --- a/data/specials.inc +++ b/data/specials.inc @@ -346,6 +346,7 @@ gSpecials:: def_special GetContestMultiplayerId def_special ScriptGetPartyMonSpecies def_special IsSelectedMonEgg + def_special HasMovesToRelearn def_special TryInitBattleTowerAwardManObjectEvent def_special MoveOutOfSecretBaseFromOutside def_special LoadPlayerBag @@ -500,7 +501,6 @@ gSpecials:: def_special StartMirageTowerDisintegration def_special StartMirageTowerShake def_special StartMirageTowerFossilFallAndSink - def_special ChangeBoxPokemonNickname def_special GetPCBoxToSendMon def_special ShouldShowBoxWasFullMessage def_special SetMatchCallRegisteredFlag @@ -565,7 +565,6 @@ gSpecials:: def_special GetCodeFeedback def_special SetHiddenNature def_special SetAbility - def_special ChooseBoxMon def_special CanTeachMoveBoxMon def_special ObjectEventInteractionGetApricornTreeData def_special ObjectEventInteractionPickApricornTree diff --git a/include/chooseboxmon.h b/include/chooseboxmon.h new file mode 100644 index 0000000000..cc88f8bb92 --- /dev/null +++ b/include/chooseboxmon.h @@ -0,0 +1,19 @@ +#ifndef GUARD_CHOOSEBOXMON_H +#define GUARD_CHOOSEBOXMON_H + +struct MoveLearnUI { + void (*askConfirmation)(void); + s32 (*waitConfirmation)(void); + void (*printMessage)(const u8 *message); + void (*playFanfare)(u32 songId); + void (*showMoveList)(u8 taskId); + void (*endTask)(u8 taskId); +}; + +u32 IsBoxMonExcluded(struct BoxPokemon *boxmon); +bool32 CanBoxMonBeSelected(struct BoxPokemon *boxmon); +s32 LearnMove(const struct MoveLearnUI *ui, u8 taskId); +s32 GetLearnMoveStartState(void); +s32 GetLearnMoveResumeAfterSummaryScreenState(void); + +#endif // GUARD_CHOOSEBOXMON_H diff --git a/include/config/overworld.h b/include/config/overworld.h index 1e9a73e095..1fe629d19d 100644 --- a/include/config/overworld.h +++ b/include/config/overworld.h @@ -12,6 +12,7 @@ #define OW_WHITEOUT_CUTSCENE GEN_LATEST // In Gen4+, whiting out shows an additional message and post whiteout event script cutscene with a healing NPC. (While this change was also in FRLG, for the sake of simplicity, setting this to GEN_3 will result in RSE behavior.) #define OW_DEFOG_FIELD_MOVE FALSE // If enabled, Defog can be used as a Field Move as seen in DPPt. #define OW_ROCK_CLIMB_FIELD_MOVE FALSE // If enabled, Rock Climb can be used as a Field Move as seen in DPPt. +#define OW_CHOOSE_FROM_PC_AND_PARTY TRUE // If enabled, NPCs like move tutors or trainers asking for trade will let you pick a pokemon from your PC or party instead of just your party // Item Obtain Description Box #define OW_ITEM_DESCRIPTIONS_OFF 0 // never show descriptions diff --git a/include/constants/party_menu.h b/include/constants/party_menu.h index 3a7ad372ff..523d2f2fa5 100644 --- a/include/constants/party_menu.h +++ b/include/constants/party_menu.h @@ -1,6 +1,7 @@ #ifndef GUARD_CONSTANTS_PARTY_MENU_H #define GUARD_CONSTANTS_PARTY_MENU_H +#define PC_MON_CHOSEN 0xFE #define PARTY_NOTHING_CHOSEN 0xFF #define AILMENT_NONE 0 @@ -109,4 +110,22 @@ #define SELECTWINDOW_CATALOG 4 #define SELECTWINDOW_ZYGARDECUBE 5 +enum PcMonSelectionType +{ + SELECT_PC_MON_NORMAL, + SELECT_PC_MON_TRADE, // Also used for Lotad / Seedot size check + SELECT_PC_MON_DAYCARE, + SELECT_PC_MON_MOVE_TUTOR, + SELECT_PC_MON_MOVE_DELETER, + SELECT_PC_MON_MOVE_RELEARNER, +}; + +enum CanMoveBeLearned +{ + CAN_LEARN_MOVE, + CANNOT_LEARN_MOVE, + ALREADY_KNOWS_MOVE, + CANNOT_LEARN_MOVE_IS_EGG +}; + #endif // GUARD_CONSTANTS_PARTY_MENU_H diff --git a/include/event_scripts.h b/include/event_scripts.h index 646b054195..616638ec42 100644 --- a/include/event_scripts.h +++ b/include/event_scripts.h @@ -686,5 +686,5 @@ extern const u8 EventScript_LostSignal[]; extern const u8 EventScript_TooDark[]; extern const u8 EventScript_MovedTooFast[]; - +extern const u8 MoveTutor_AfterChooseBoxMon[]; #endif // GUARD_EVENT_SCRIPTS_H diff --git a/include/mail.h b/include/mail.h index 58a2d30767..9047ad7ab4 100644 --- a/include/mail.h +++ b/include/mail.h @@ -29,6 +29,7 @@ u16 MailSpeciesToSpecies(u16 mailSpecies, u16 *buffer); u8 GiveMailToMon(struct Pokemon *mon, struct Mail *mail); void TakeMailFromMon(struct Pokemon *mon); void ClearMailItemId(u8 mailId); +u8 SaveMailToPC(struct Mail *mail); u8 TakeMailFromMonAndSave(struct Pokemon *mon); bool8 ItemIsMail(enum Item itemId); diff --git a/include/move_relearner.h b/include/move_relearner.h index 1d22d82a79..4274950d40 100644 --- a/include/move_relearner.h +++ b/include/move_relearner.h @@ -7,6 +7,8 @@ void TeachMoveRelearnerMove(void); void MoveRelearnerShowHideHearts(s32 move); void MoveRelearnerShowHideCategoryIcon(s32); void CB2_InitLearnMove(void); +bool32 CanBoxMonRelearnAnyMove(struct BoxPokemon *boxMon); +bool32 CanBoxMonRelearnMoves(struct BoxPokemon *boxMon, enum MoveRelearnerStates state); extern enum MoveRelearnerStates gMoveRelearnerState; extern enum RelearnMode gRelearnMode; diff --git a/include/pokemon.h b/include/pokemon.h index c98c6681e3..5d5dacca13 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -733,6 +733,7 @@ u16 GiveMoveToMon(struct Pokemon *mon, enum Move move); u16 GiveMoveToBoxMon(struct BoxPokemon *boxMon, enum Move move); u16 GiveMoveToBattleMon(struct BattlePokemon *mon, enum Move move); void SetMonMoveSlot(struct Pokemon *mon, enum Move move, u8 slot); +void SetBoxMonMoveSlot(struct BoxPokemon *mon, enum Move move, u8 slot); void SetBattleMonMoveSlot(struct BattlePokemon *mon, enum Move move, u8 slot); void GiveMonInitialMoveset(struct Pokemon *mon); void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon); @@ -804,6 +805,7 @@ const u16 *GetSpeciesFormTable(u16 species); const struct FormChange *GetSpeciesFormChanges(u16 species); u8 CalculatePPWithBonus(enum Move move, u8 ppBonuses, u8 moveIndex); void RemoveMonPPBonus(struct Pokemon *mon, u8 moveIndex); +void RemoveBoxMonPPBonus(struct BoxPokemon *mon, u8 moveIndex); void RemoveBattleMonPPBonus(struct BattlePokemon *mon, u8 moveIndex); void PokemonToBattleMon(struct Pokemon *src, struct BattlePokemon *dst); void CopyPartyMonToBattleData(u32 battler, u32 partyIndex); @@ -836,24 +838,7 @@ void MonGainEVs(struct Pokemon *mon, u16 defeatedSpecies); u16 GetMonEVCount(struct Pokemon *mon); bool8 TryIncrementMonLevel(struct Pokemon *mon); u8 CanLearnTeachableMove(u16 species, enum Move move); -u32 GetRelearnerLevelUpMoves(struct Pokemon *mon, u16 *moves); -u32 GetRelearnerLevelUpMovesBox(struct BoxPokemon *boxMon, u16 *moves); -u32 GetRelearnerEggMoves(struct Pokemon *mon, u16 *moves); -u32 GetRelearnerEggMovesBox(struct BoxPokemon *boxMon, u16 *moves); -u32 GetRelearnerTMMoves(struct Pokemon *mon, u16 *moves); -u32 GetRelearnerTMMovesBox(struct BoxPokemon *boxMon, u16 *moves); -u32 GetRelearnerTutorMoves(struct Pokemon *mon, u16 *moves); -u32 GetRelearnerTutorMovesBox(struct BoxPokemon *boxMon, u16 *moves); -bool32 HasRelearnerLevelUpMoves(struct Pokemon *mon); -bool32 HasRelearnerLevelUpMovesBox(struct BoxPokemon *boxMon); -bool32 HasRelearnerEggMoves(struct Pokemon *mon); -bool32 HasRelearnerEggMovesBox(struct BoxPokemon *boxMon); -bool32 HasRelearnerTMMoves(struct Pokemon *mon); -bool32 HasRelearnerTMMovesBox(struct BoxPokemon *boxMon); -bool32 HasRelearnerTutorMoves(struct Pokemon *mon); -bool32 HasRelearnerTutorMovesBox(struct BoxPokemon *boxMon); u8 GetLevelUpMovesBySpecies(u16 species, u16 *moves); -u8 GetNumberOfRelearnableMoves(struct Pokemon *mon); u16 SpeciesToPokedexNum(u16 species); bool32 IsSpeciesInHoennDex(u16 species); u16 GetBattleBGM(void); @@ -925,6 +910,8 @@ struct Pokemon *GetSavedPlayerPartyMon(u32 index); u8 *GetSavedPlayerPartyCount(void); void SavePlayerPartyMon(u32 index, struct Pokemon *mon); bool32 IsSpeciesOfType(u32 species, enum Type type); +struct BoxPokemon *GetSelectedBoxMonFromPcOrParty(void); u32 GiveScriptedMonToPlayer(struct Pokemon *mon, u8 slot); +void ChangePokemonNicknameWithCallback(void (*callback)(void)); #endif // GUARD_POKEMON_H diff --git a/include/pokemon_storage_system.h b/include/pokemon_storage_system.h index 52aa6719b6..b80f3c2c3f 100644 --- a/include/pokemon_storage_system.h +++ b/include/pokemon_storage_system.h @@ -43,9 +43,6 @@ u32 GetBoxMonDataAt(u8 boxId, u8 boxPosition, s32 request); void SetBoxMonDataAt(u8 boxId, u8 boxPosition, s32 request, const void *value); u32 GetCurrentBoxMonData(u8 boxPosition, s32 request); void SetCurrentBoxMonData(u8 boxPosition, s32 request, const void *value); -void GetBoxMonNickAt(u8 boxId, u8 boxPosition, u8 *dst); -u32 GetBoxMonLevelAt(u8 boxId, u8 boxPosition); -void SetBoxMonNickAt(u8 boxId, u8 boxPosition, const u8 *nick); u32 GetAndCopyBoxMonDataAt(u8 boxId, u8 boxPosition, s32 request, void *dst); void SetBoxMonAt(u8 boxId, u8 boxPosition, struct BoxPokemon *src); void CopyBoxMonAt(u8 boxId, u8 boxPosition, struct BoxPokemon *dst); @@ -73,8 +70,8 @@ u8 *GetWaldaPhrasePtr(void); void SetWaldaPhrase(const u8 *src); bool32 IsWaldaPhraseEmpty(void); -void EnterPokeStorage(u8 boxOption); +void ChooseMonFromStorage(); u32 CountPartyNonEggMons(void); -void ChooseBoxMon(void); +void RemoveSelectedPcMon(struct Pokemon *mon); #endif // GUARD_POKEMON_STORAGE_SYSTEM_H diff --git a/include/pokemon_summary_screen.h b/include/pokemon_summary_screen.h index 9738d19874..19436483cb 100755 --- a/include/pokemon_summary_screen.h +++ b/include/pokemon_summary_screen.h @@ -32,9 +32,6 @@ enum PokemonSummaryScreenMode SUMMARY_MODE_SELECT_MOVE, SUMMARY_MODE_RELEARNER_BATTLE, // returning from move relearner initiated from battle moves page SUMMARY_MODE_RELEARNER_CONTEST, // returning from move relearner initiated from contest moves page - SUMMARY_MODE_BOX_SELECT_MOVE, - SUMMARY_MODE_BOX_RELEARNER_BATTLE, - SUMMARY_MODE_BOX_RELEARNER_CONTEST, }; enum PokemonSummaryScreenPage @@ -54,8 +51,7 @@ enum PokemonSummarySkillsMode }; void ShowPokemonSummaryScreen(u8 mode, void *mons, u8 monIndex, u8 maxMonIndex, void (*callback)(void)); -void ShowSelectMovePokemonSummaryScreen(struct Pokemon *mons, u8 monIndex, u8 maxMonIndex, void (*callback)(void), u16 newMove); -void ShowSelectMoveBoxPokemonSummaryScreen(struct BoxPokemon *mons, u8 monIndex, u8 maxMonIndex, void (*callback)(void), u16 newMove); +void ShowSelectMovePokemonSummaryScreen(struct Pokemon *mons, u8 monIndex, void (*callback)(void), u16 newMove); u8 GetMoveSlotToReplace(void); void SummaryScreen_SetAnimDelayTaskId(u8 taskId); bool32 CheckRelearnerStateFlag(enum MoveRelearnerStates state); diff --git a/include/trade.h b/include/trade.h index 553d5ab334..6b170d23f1 100644 --- a/include/trade.h +++ b/include/trade.h @@ -4,6 +4,8 @@ #include "link_rfu.h" #include "constants/trade.h" +#define TRADEMON_FROM_PC 1 + extern struct Mail gTradeMail[PARTY_SIZE]; extern u8 gSelectedTradeMonPositions[2]; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 8b13f5ed58..4bce6ce8d9 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -5874,7 +5874,7 @@ static void Cmd_yesnoboxlearnmove(void) if (!gPaletteFade.active) { FreeAllWindowBuffers(); - ShowSelectMovePokemonSummaryScreen(gPlayerParty, gBattleStruct->expGetterMonId, gPlayerPartyCount - 1, ReshowBattleScreenAfterMenu, gMoveToLearn); + ShowSelectMovePokemonSummaryScreen(gPlayerParty, gBattleStruct->expGetterMonId, ReshowBattleScreenAfterMenu, gMoveToLearn); gBattleScripting.learnMoveState++; } break; diff --git a/src/chooseboxmon.c b/src/chooseboxmon.c new file mode 100644 index 0000000000..7cbfe46e2c --- /dev/null +++ b/src/chooseboxmon.c @@ -0,0 +1,313 @@ +#include "global.h" +#include "chooseboxmon.h" +#include "daycare.h" +#include "event_data.h" +#include "event_scripts.h" +#include "field_weather.h" +#include "menu.h" +#include "move.h" +#include "move_relearner.h" +#include "overworld.h" +#include "palette.h" +#include "party_menu.h" +#include "pokemon.h" +#include "pokemon_summary_screen.h" +#include "pokemon_storage_system.h" +#include "script.h" +#include "string_util.h" +#include "strings.h" +#include "constants/party_menu.h" +#include "constants/songs.h" + +#define VALID_MON 0 +#define INVALID_MON 1 + +struct PcMonSelection +{ + void (*partyMonBackup)(void); + u32 (*isMonInvalid)(struct BoxPokemon *); + const u8* postSelectionScript; + u32 isStrict:1; + u32 padding:31; +}; + +static EWRAM_DATA u8 sSelectionType = 0; + +// All these filter functions return 0 when a mon is a valid or a number corresponding to the type of error +static u32 NoFilter(struct BoxPokemon *boxmon); +static u32 IsNotEgg(struct BoxPokemon *boxmon); +static u32 IsMatchingSpecies(struct BoxPokemon *boxmon); +static u32 CanMonDeleteMove(struct BoxPokemon *boxmon); +static u32 CanMonLearnMove(struct BoxPokemon *boxmon); +static u32 CanRelearnMoves(struct BoxPokemon *boxmon); + +static const struct PcMonSelection sPcMonSelectionTypes[] = +{ + [SELECT_PC_MON_NORMAL] = {ChoosePartyMon, NoFilter, NULL, FALSE}, + [SELECT_PC_MON_TRADE] = {ChoosePartyMon, IsMatchingSpecies, NULL, FALSE}, + [SELECT_PC_MON_DAYCARE] = {ChooseSendDaycareMon, IsNotEgg, NULL, TRUE}, + [SELECT_PC_MON_MOVE_TUTOR] = {ChooseMonForMoveTutor, CanMonLearnMove, MoveTutor_AfterChooseBoxMon, FALSE}, + [SELECT_PC_MON_MOVE_DELETER] = {ChoosePartyMon, CanMonDeleteMove, NULL, FALSE}, + [SELECT_PC_MON_MOVE_RELEARNER] = {ChooseMonForMoveRelearner, CanRelearnMoves, NULL, FALSE} +}; + +static u32 NoFilter(struct BoxPokemon *boxmon) +{ + return VALID_MON; +} + +static u32 IsNotEgg(struct BoxPokemon *boxmon) +{ + if (GetBoxMonData(boxmon, MON_DATA_IS_EGG)) + return INVALID_MON; + return VALID_MON; +} + +static u32 CanRelearnMoves(struct BoxPokemon *boxmon) +{ + if (GetBoxMonData(boxmon, MON_DATA_IS_EGG)) + return INVALID_MON; + if (CanBoxMonRelearnMoves(boxmon, gMoveRelearnerState)) + return VALID_MON; + return INVALID_MON; +} + +static u32 IsMatchingSpecies(struct BoxPokemon *boxmon) +{ + if (GetBoxMonData(boxmon, MON_DATA_SPECIES_OR_EGG) == gSpecialVar_0x8009) + return VALID_MON; + return INVALID_MON; +} + +static u32 CanMonDeleteMove(struct BoxPokemon *boxmon) +{ + if (GetBoxMonData(boxmon, MON_DATA_IS_EGG)) + return INVALID_MON; + if (GetBoxMonData(boxmon, MON_DATA_MOVE2) == MOVE_NONE) // Only has One move + return INVALID_MON; + return VALID_MON; +} + +static u32 CanMonLearnMove(struct BoxPokemon *boxmon) +{ + if (GetBoxMonData(boxmon, MON_DATA_IS_EGG)) + return CANNOT_LEARN_MOVE_IS_EGG; + if (BoxMonKnowsMove(boxmon, gSpecialVar_0x8005)) + return ALREADY_KNOWS_MOVE; + if (CanLearnTeachableMove(GetBoxMonData(boxmon, MON_DATA_SPECIES), gSpecialVar_0x8005)) + return VALID_MON; + return CANNOT_LEARN_MOVE; +} + +u32 IsBoxMonExcluded(struct BoxPokemon *boxmon) +{ + return sPcMonSelectionTypes[sSelectionType].isMonInvalid(boxmon); +} + +bool32 CanBoxMonBeSelected(struct BoxPokemon *boxmon) +{ + if (!sPcMonSelectionTypes[sSelectionType].isStrict) + return TRUE; + return !IsBoxMonExcluded(boxmon); +} + +static void Task_ChooseBoxMon(u8 taskId) +{ + if (!gPaletteFade.active) + { + CleanupOverworldWindowsAndTilemaps(); + ChooseMonFromStorage(); + DestroyTask(taskId); + } +} + +// Used as a script special for showing a box mon to various npcs (e.g. in-game trades, move deleter) +void ChooseBoxMon(struct ScriptContext *ctx) +{ + sSelectionType = ScriptReadByte(ctx); + if (!OW_CHOOSE_FROM_PC_AND_PARTY) + { + sPcMonSelectionTypes[sSelectionType].partyMonBackup(); + return; + } + LockPlayerFieldControls(); + FadeScreen(FADE_TO_BLACK, 0); + CreateTask(Task_ChooseBoxMon, 10); + if (sPcMonSelectionTypes[sSelectionType].postSelectionScript) + { + ctx->scriptPtr++; + ScriptCall(ctx, sPcMonSelectionTypes[sSelectionType].postSelectionScript); + } +} + +enum LearnMoveState +{ + LEARN_MOVE_END, + + MON_CAN_LEARN, //Start + + LEARN_MOVE, + + ASK_REPLACEMENT_1, + ASK_REPLACEMENT_2, + ASK_REPLACEMENT_3, + + REFUSE_REPLACE_1, + REFUSE_REPLACE_2, + REFUSE_REPLACE_3, + + WANT_REPLACE_1, + WANT_REPLACE_2, + WANT_REPLACE_3, //Return from Summary screen + + LEARNED_MOVE_1, + LEARNED_MOVE_2, + + FORGOT_MOVE_1, + + REPLACE_MOVE_1, + + DID_NOT_LEARN_1, +}; + +static struct BoxPokemon *LearnMove_GetBoxMonFromTaskData(u8 partyIndex) +{ + struct BoxPokemon *boxmon; + if (partyIndex == PC_MON_CHOSEN) + boxmon = GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos); + else + boxmon = &(gPlayerParty[partyIndex].box); + return boxmon; +} + +#define state gTasks[taskId].data[0] +#define partyIndex gTasks[taskId].data[1] +#define move gTasks[taskId].data[2] +// MoveLearnUI does not contain a waitMessage function and LearnMove assumes the calling task will wait when a printer is active +// Remember to update Task_LearnMove is you wish to change to an explicit waitMessage system +s32 LearnMove(const struct MoveLearnUI *ui, u8 taskId) +{ + struct BoxPokemon *boxmon = LearnMove_GetBoxMonFromTaskData(partyIndex); + switch (state) + { + case MON_CAN_LEARN: + GetBoxMonNickname(boxmon, gStringVar1); + StringCopy(gStringVar2, GetMoveName(move)); + gSpecialVar_Result = FALSE; + switch(CanMonLearnMove(boxmon)) + { + case VALID_MON: + return LEARN_MOVE; + case ALREADY_KNOWS_MOVE: + ui->printMessage(gText_PkmnAlreadyKnows); + return LEARN_MOVE_END; + case CANNOT_LEARN_MOVE_IS_EGG: + case CANNOT_LEARN_MOVE: + default: + ui->printMessage(gText_PkmnCantLearnMove); + return LEARN_MOVE_END; + } + case LEARN_MOVE: + if (GiveMoveToBoxMon(boxmon, move) != MON_HAS_MAX_MOVES) + return LEARNED_MOVE_1; + else + return ASK_REPLACEMENT_1; + case ASK_REPLACEMENT_1: + GetBoxMonNickname(boxmon, gStringVar1); + StringCopy(gStringVar2, GetMoveName(move)); + ui->printMessage(gText_PkmnNeedsToReplaceMove); + return ASK_REPLACEMENT_2; + case ASK_REPLACEMENT_2: + ui->askConfirmation(); + return ASK_REPLACEMENT_3; + case ASK_REPLACEMENT_3: + switch (ui->waitConfirmation()) + { + case 0: // Yes + return WANT_REPLACE_1; + case 1: // No + case MENU_B_PRESSED: + return REFUSE_REPLACE_1; + } + return state; + case REFUSE_REPLACE_1: + StringCopy(gStringVar2, GetMoveName(move)); + ui->printMessage(gText_StopLearningMove2); + return REFUSE_REPLACE_2; + case REFUSE_REPLACE_2: + ui->askConfirmation(); + return REFUSE_REPLACE_3; + case REFUSE_REPLACE_3: + switch (ui->waitConfirmation()) + { + case 0: // Yes + return DID_NOT_LEARN_1; + case 1: // No + case MENU_B_PRESSED: + return WANT_REPLACE_1; + } + return state; + case WANT_REPLACE_1: + ui->printMessage(gText_WhichMoveToForget); + return WANT_REPLACE_2; + case WANT_REPLACE_2: + ui->showMoveList(taskId); + return WANT_REPLACE_3; + case WANT_REPLACE_3: + if (GetMoveSlotToReplace() == MAX_MON_MOVES) + return REFUSE_REPLACE_1; + else + return FORGOT_MOVE_1; + case LEARNED_MOVE_1: + GetBoxMonNickname(boxmon, gStringVar1); + StringCopy(gStringVar2, GetMoveName(move)); + ui->printMessage(gText_PkmnLearnedMove4); + return LEARNED_MOVE_2; + case LEARNED_MOVE_2: + gSpecialVar_Result = TRUE; + ui->playFanfare(MUS_LEVEL_UP); + return LEARN_MOVE_END; + case FORGOT_MOVE_1: + GetBoxMonNickname(boxmon, gStringVar1); + StringCopy(gStringVar2, GetMoveName(GetBoxMonData(boxmon, MON_DATA_MOVE1 + GetMoveSlotToReplace()))); + ui->printMessage(gText_12PoofForgotMove); + return REPLACE_MOVE_1; + case REPLACE_MOVE_1: + u32 slot = GetMoveSlotToReplace(); + RemoveBoxMonPPBonus(boxmon, slot); + u32 pp = GetMovePP(move); + SetBoxMonData(boxmon, MON_DATA_MOVE1 + slot, &move); + SetBoxMonData(boxmon, MON_DATA_PP1 + slot, &pp); + GetBoxMonNickname(boxmon, gStringVar1); + StringCopy(gStringVar2, GetMoveName(move)); + gSpecialVar_Result = TRUE; + ui->printMessage(gText_PkmnLearnedMove4); + return LEARN_MOVE_END; + case DID_NOT_LEARN_1: + GetBoxMonNickname(boxmon, gStringVar1); + StringCopy(gStringVar2, GetMoveName(move)); + gSpecialVar_Result = FALSE; + ui->printMessage(gText_MoveNotLearned); + return LEARN_MOVE_END; + default: + errorf("Unknown LearnMove state %d\nEnding move learning ...", state); + case LEARN_MOVE_END: + ui->endTask(taskId); + return LEARN_MOVE_END; + } +} + +s32 GetLearnMoveStartState(void) +{ + return MON_CAN_LEARN; +} + +//At the time of writing code for this, there was no prescribed way to make a task persist between scenes +//and I didn't want to implement one just for this, feel free to rewrite this if this has changed +s32 GetLearnMoveResumeAfterSummaryScreenState(void) +{ + return WANT_REPLACE_3; +} +#undef state +#undef partyIndex +#undef move diff --git a/src/daycare.c b/src/daycare.c index be6a904d7c..59558d524a 100644 --- a/src/daycare.c +++ b/src/daycare.c @@ -22,9 +22,11 @@ #include "overworld.h" #include "item.h" #include "regions.h" +#include "malloc.h" #include "constants/form_change_types.h" #include "constants/items.h" #include "constants/moves.h" +#include "constants/party_menu.h" #include "constants/region_map_sections.h" #define IS_DITTO(species) (gSpeciesInfo[species].eggGroups[0] == EGG_GROUP_DITTO || gSpeciesInfo[species].eggGroups[1] == EGG_GROUP_DITTO) @@ -276,17 +278,6 @@ void StorePokemonInDaycare(struct Pokemon *mon, struct DaycareMon *daycareMon) TransferEggMoves(); } -static void StoreBoxMonInDaycare(struct BoxPokemon *mon, struct DaycareMon *daycareMon) -{ - - daycareMon->mon = *mon; - daycareMon->steps = 0; - ZeroBoxMonData(mon); - - if (P_EGG_MOVE_TRANSFER >= GEN_8) - TransferEggMoves(); -} - static void StorePokemonInEmptyDaycareSlot(struct Pokemon *mon, struct DayCare *daycare) { s8 slotId = Daycare_FindEmptySpot(daycare); @@ -295,19 +286,19 @@ static void StorePokemonInEmptyDaycareSlot(struct Pokemon *mon, struct DayCare * void StoreSelectedPokemonInDaycare(void) { - if (gSpecialVar_MonBoxId == 0xFF) + struct Pokemon *mon; + if (gSpecialVar_0x8004 == PC_MON_CHOSEN) { - StorePokemonInEmptyDaycareSlot(&gPlayerParty[GetCursorSelectionMonId()], &gSaveBlock1Ptr->daycare); - } - else if (gSpecialVar_MonBoxId == TOTAL_BOXES_COUNT) // Selected party mon from PC - { - StorePokemonInEmptyDaycareSlot(&gPlayerParty[gSpecialVar_MonBoxPos], &gSaveBlock1Ptr->daycare); + mon = Alloc(sizeof(struct Pokemon)); + RemoveSelectedPcMon(mon); } else { - s8 slotId = Daycare_FindEmptySpot(&gSaveBlock1Ptr->daycare); - StoreBoxMonInDaycare(GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos), &gSaveBlock1Ptr->daycare.mons[slotId]); + mon = &gPlayerParty[gSpecialVar_0x8004]; } + StorePokemonInEmptyDaycareSlot(mon, &gSaveBlock1Ptr->daycare); + if (gSpecialVar_0x8004 == PC_MON_CHOSEN) + Free(mon); } // Shifts the second daycare Pokémon slot into the first slot. @@ -1265,21 +1256,9 @@ static void _GetDaycareMonNicknames(struct DayCare *daycare) u16 GetSelectedMonNicknameAndSpecies(void) { - if(gSpecialVar_MonBoxId == 0xFF) - { - GetBoxMonNickname(&gPlayerParty[GetCursorSelectionMonId()].box, gStringVar1); - return GetBoxMonData(&gPlayerParty[GetCursorSelectionMonId()].box, MON_DATA_SPECIES); - } - else if (gSpecialVar_MonBoxId == TOTAL_BOXES_COUNT) // Selected party mon from PC - { - GetBoxMonNickname(&gPlayerParty[gSpecialVar_MonBoxPos].box, gStringVar1); - return GetBoxMonData(&gPlayerParty[gSpecialVar_MonBoxPos].box, MON_DATA_SPECIES); - } - else - { - GetBoxMonNickname(&gPokemonStoragePtr->boxes[gSpecialVar_MonBoxId][gSpecialVar_MonBoxPos], gStringVar1); - return GetBoxMonData(&gPokemonStoragePtr->boxes[gSpecialVar_MonBoxId][gSpecialVar_MonBoxPos], MON_DATA_SPECIES); - } + struct BoxPokemon *boxmon = GetSelectedBoxMonFromPcOrParty(); + GetBoxMonNickname(boxmon, gStringVar1); + return GetBoxMonData(boxmon, MON_DATA_SPECIES); } void GetDaycareMonNicknames(void) diff --git a/src/evolution_scene.c b/src/evolution_scene.c index 5fde973f2f..5a4cab8020 100644 --- a/src/evolution_scene.c +++ b/src/evolution_scene.c @@ -31,9 +31,10 @@ #include "trade.h" #include "util.h" #include "constants/battle_string_ids.h" -#include "constants/songs.h" -#include "constants/rgb.h" #include "constants/items.h" +#include "constants/party_menu.h" +#include "constants/rgb.h" +#include "constants/songs.h" struct EvoInfo { @@ -379,7 +380,11 @@ static void CB2_EvolutionSceneLoadGraphics(void) static void CB2_TradeEvolutionSceneLoadGraphics(void) { - struct Pokemon *mon = &gPlayerParty[gTasks[sEvoStructPtr->evoTaskId].tPartyId]; + struct Pokemon *mon; + if (gTasks[sEvoStructPtr->evoTaskId].tPartyId == PC_MON_CHOSEN) + mon = &gEnemyParty[TRADEMON_FROM_PC]; + else + mon = &gPlayerParty[gTasks[sEvoStructPtr->evoTaskId].tPartyId]; u16 postEvoSpecies = gTasks[sEvoStructPtr->evoTaskId].tPostEvoSpecies; switch (gMain.state) @@ -974,7 +979,7 @@ static void Task_EvolutionScene(u8 taskId) { FreeAllWindowBuffers(); ShowSelectMovePokemonSummaryScreen(gPlayerParty, gTasks[taskId].tPartyId, - gPlayerPartyCount - 1, CB2_EvolutionSceneLoadGraphics, + CB2_EvolutionSceneLoadGraphics, gMoveToLearn); gTasks[taskId].tLearnMoveState++; } @@ -1098,7 +1103,11 @@ enum { static void Task_TradeEvolutionScene(u8 taskId) { u32 var = 0; - struct Pokemon *mon = &gPlayerParty[gTasks[taskId].tPartyId]; + struct Pokemon *mon; + if (gTasks[taskId].tPartyId == PC_MON_CHOSEN) + mon = &gEnemyParty[TRADEMON_FROM_PC]; + else + mon = &gPlayerParty[gTasks[taskId].tPartyId]; switch (gTasks[taskId].tState) { @@ -1357,9 +1366,24 @@ static void Task_TradeEvolutionScene(u8 taskId) Free(GetBgTilemapBuffer(0)); FreeAllWindowBuffers(); - ShowSelectMovePokemonSummaryScreen(gPlayerParty, gTasks[taskId].tPartyId, - gPlayerPartyCount - 1, CB2_TradeEvolutionSceneLoadGraphics, - gMoveToLearn); + if (gTasks[taskId].tPartyId == PC_MON_CHOSEN) + { + ShowSelectMovePokemonSummaryScreen( + gEnemyParty, + TRADEMON_FROM_PC, + CB2_TradeEvolutionSceneLoadGraphics, + gMoveToLearn + ); + } + else + { + ShowSelectMovePokemonSummaryScreen( + gPlayerParty, + gTasks[taskId].tPartyId, + CB2_TradeEvolutionSceneLoadGraphics, + gMoveToLearn + ); + } gTasks[taskId].tLearnMoveState++; } break; diff --git a/src/field_specials.c b/src/field_specials.c index f0d37cd359..a4907e02f7 100644 --- a/src/field_specials.c +++ b/src/field_specials.c @@ -76,6 +76,7 @@ #include "palette.h" #include "battle_util.h" #include "naming_screen.h" +#include "chooseboxmon.h" #define TAG_ITEM_ICON 5500 @@ -86,14 +87,6 @@ #define ELEVATOR_WINDOW_HEIGHT 3 #define ELEVATOR_LIGHT_STAGES 3 -enum -{ - CAN_LEARN_MOVE, - CANNOT_LEARN_MOVE, - ALREADY_KNOWS_MOVE, - CANNOT_LEARN_MOVE_IS_EGG -}; - EWRAM_DATA bool8 gBikeCyclingChallenge = FALSE; EWRAM_DATA u8 gBikeCollisions = 0; static EWRAM_DATA u32 sBikeCyclingTimer = 0; @@ -156,18 +149,8 @@ static void Task_CloseBattlePikeCurtain(u8); static u8 DidPlayerGetFirstFans(void); static void SetInitialFansOfPlayer(void); static u16 PlayerGainRandomTrainerFan(void); -static void Task_LearnedMoveBoxMon(u8); -static void Task_ReplaceBoxMonMoveYesNo(u8); -static void Task_DoLearnedBoxMonMoveFanfareAfterText(u8); -static void Task_HandleReplaceBoxMonMoveYesNoInput(u8); -static void Task_ShowSummaryScreenToForgetBoxMonMove(u8); -static void StopLearningBoxMonMovePrompt(u8); static void CB2_ReturnToFieldWhileLearningMove(void); static void Task_ReturnToFieldWhileLearningMove(void); -static void Task_BoxMonReplaceMove(u8); -static void Task_StopLearningBoxMonMoveYesNo(u8); -static void Task_HandleStopLearningBoxMonMoveYesNoInput(u8); -static void Task_DidntLearnMove(u8); #if FREE_LINK_BATTLE_RECORDS == FALSE static void BufferFanClubTrainerName_(struct LinkBattleRecords *, u8, u8); #else @@ -1610,10 +1593,13 @@ u8 GetLeadMonIndex(void) u16 ScriptGetPartyMonSpecies(void) { - if(gSpecialVar_MonBoxId == 0xFF) - return GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPECIES_OR_EGG); - else - return GetBoxMonDataAt(gSpecialVar_MonBoxId,gSpecialVar_MonBoxPos, MON_DATA_SPECIES_OR_EGG); + return GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPECIES_OR_EGG, NULL); +} + +u16 ScriptGetSelectedMonSpecies(void) +{ + struct BoxPokemon *boxmon = GetSelectedBoxMonFromPcOrParty(); + return GetBoxMonData(boxmon, MON_DATA_SPECIES_OR_EGG); } // Removed for Emerald @@ -1641,10 +1627,11 @@ u16 SetPacifidlogTMReceivedDay(void) bool8 MonOTNameNotPlayer(void) { - if (GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_LANGUAGE) != GAME_LANGUAGE) + struct BoxPokemon *boxmon = GetSelectedBoxMonFromPcOrParty(); + if (GetBoxMonData(boxmon, MON_DATA_LANGUAGE) != GAME_LANGUAGE) return TRUE; - GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_OT_NAME, gStringVar1); + GetBoxMonData(boxmon, MON_DATA_OT_NAME, gStringVar1); if (!StringCompare(gSaveBlock2Ptr->playerName, gStringVar1)) return FALSE; @@ -2038,26 +2025,14 @@ static void Task_MoveElevatorWindowLights(u8 taskId) void BufferVarsForIVRater(void) { - u8 i; + u32 i; u32 ivStorage[NUM_STATS]; - if(gSpecialVar_MonBoxId == 0xFF) + struct BoxPokemon *boxmon = GetSelectedBoxMonFromPcOrParty();; + + for (i = 0; i < NUM_STATS; i++) { - ivStorage[STAT_HP] = GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_HP_IV); - ivStorage[STAT_ATK] = GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_ATK_IV); - ivStorage[STAT_DEF] = GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_DEF_IV); - ivStorage[STAT_SPEED] = GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPEED_IV); - ivStorage[STAT_SPATK] = GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPATK_IV); - ivStorage[STAT_SPDEF] = GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPDEF_IV); - } - else - { - ivStorage[STAT_HP] = GetBoxMonDataAt(gSpecialVar_MonBoxId,gSpecialVar_MonBoxPos, MON_DATA_HP_IV); - ivStorage[STAT_ATK] = GetBoxMonDataAt(gSpecialVar_MonBoxId,gSpecialVar_MonBoxPos, MON_DATA_ATK_IV); - ivStorage[STAT_DEF] = GetBoxMonDataAt(gSpecialVar_MonBoxId,gSpecialVar_MonBoxPos, MON_DATA_DEF_IV); - ivStorage[STAT_SPEED] = GetBoxMonDataAt(gSpecialVar_MonBoxId,gSpecialVar_MonBoxPos, MON_DATA_SPEED_IV); - ivStorage[STAT_SPATK] = GetBoxMonDataAt(gSpecialVar_MonBoxId,gSpecialVar_MonBoxPos, MON_DATA_SPATK_IV); - ivStorage[STAT_SPDEF] = GetBoxMonDataAt(gSpecialVar_MonBoxId,gSpecialVar_MonBoxPos, MON_DATA_SPDEF_IV); + ivStorage[i] = GetBoxMonData(boxmon, MON_DATA_HP_IV + i); } gSpecialVar_0x8005 = 0; @@ -2863,16 +2838,13 @@ void SetBattleTowerLinkPlayerGfx(void) void ShowNatureGirlMessage(void) { - u8 nature; + u32 nature; + u32 personality; - if (gSpecialVar_0x8004 >= PARTY_SIZE) - gSpecialVar_0x8004 = 0; + struct BoxPokemon *boxmon = GetSelectedBoxMonFromPcOrParty(); - if(gSpecialVar_MonBoxId == 0xFF) - nature = GetNature(&gPlayerParty[gSpecialVar_0x8004]); - else - nature = GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_PERSONALITY) % NUM_NATURES; - + personality = GetBoxMonData(boxmon, MON_DATA_PERSONALITY); + nature = GetNatureFromPersonality(personality); ShowFieldMessage(gNaturesInfo[nature].natureGirlMessage); } @@ -3125,7 +3097,7 @@ static void HideFrontierExchangeCornerItemIcon(enum ScrollMulti menu, u16 unused void BufferBattleFrontierTutorMoveName(void) { - StringCopy(gStringVar1, GetMoveName(gSpecialVar_ItemId)); + StringCopy(gStringVar1, GetMoveName(gSpecialVar_0x8005)); } static void ShowBattleFrontierTutorWindow(enum ScrollMulti menu, u16 selection) @@ -4402,244 +4374,92 @@ void UseBlankMessageToCancelPokemonPic(void) ScriptMenu_HidePokemonPic(); } +static void UIAskConfirmation(void) +{ + DisplayYesNoMenuDefaultYes(); +} + +static s32 UIWaitConfirmation(void) +{ + return Menu_ProcessInputNoWrapClearOnChoose(); +} + +static void UIPrintMessage(const u8 *message) +{ + ShowFieldMessage(message); +} + +static void UIPlayFanfare(u32 songId) +{ + PlayFanfare(songId); +} + +static void UIEndTask(u8 taskId) +{ + DestroyTask(taskId); + ScriptContext_Enable(); +} + +#define tState data[0] +#define tPartyIndex data[1] +#define tMove data[2] + +static void UIShowMoveList(u8 taskId) +{ + gSpecialVar_0x8008 = gTasks[taskId].tPartyIndex; + gSpecialVar_0x8009 = gTasks[taskId].tMove; + DestroyTask(taskId); + ShowSelectMovePokemonSummaryScreen(gPlayerParty, gTasks[taskId].tPartyIndex, CB2_ReturnToFieldWhileLearningMove, gTasks[taskId].tMove); +} + +static const struct MoveLearnUI sMoveLearnUI = +{ + .askConfirmation = UIAskConfirmation, + .waitConfirmation = UIWaitConfirmation, + .printMessage = UIPrintMessage, + .playFanfare = UIPlayFanfare, + .showMoveList = UIShowMoveList, + .endTask = UIEndTask +}; + +static void Task_LearnMove(u8 taskId) +{ + if (IsTextPrinterActiveOnWindow(0)) + return; + gTasks[taskId].tState = LearnMove(&sMoveLearnUI, taskId); +} + void CanTeachMoveBoxMon(void) { - ScriptContext_Stop(); - if(gSpecialVar_MonBoxId == 0xFF) + if (gSpecialVar_0x8004 == PARTY_NOTHING_CHOSEN) { - if (GetMonData(&gPlayerParty[gSpecialVar_MonBoxPos], MON_DATA_IS_EGG)) - { - gSpecialVar_Result = CANNOT_LEARN_MOVE_IS_EGG; - ScriptContext_Enable(); - } - else if (MonKnowsMove(&gPlayerParty[gSpecialVar_MonBoxPos], gSpecialVar_ItemId) == TRUE) - { - gSpecialVar_Result = ALREADY_KNOWS_MOVE; - ScriptContext_Enable(); - } - else if (CanLearnTeachableMove(GetMonData(&gPlayerParty[gSpecialVar_MonBoxPos], MON_DATA_SPECIES_OR_EGG), gSpecialVar_ItemId) == FALSE) - { - gSpecialVar_Result = CANNOT_LEARN_MOVE; - ScriptContext_Enable(); - } - else - { - if (GiveMoveToMon(&gPlayerParty[gSpecialVar_MonBoxPos], gSpecialVar_ItemId) != MON_HAS_MAX_MOVES) - { - CreateTask(Task_LearnedMoveBoxMon, 1); - } - else - { - GetMonNickname(&gPlayerParty[gSpecialVar_MonBoxPos], gStringVar1); - StringCopy(gStringVar2, GetMoveName(gSpecialVar_ItemId)); - ShowFieldMessage(gText_PkmnNeedsToReplaceMove); - CreateTask(Task_ReplaceBoxMonMoveYesNo, 1); - } - } - } - else - { - if (GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_IS_EGG)) - { - gSpecialVar_Result = CANNOT_LEARN_MOVE_IS_EGG; - ScriptContext_Enable(); - } - else if (BoxMonKnowsMove(GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos), gSpecialVar_ItemId) == TRUE) - { - gSpecialVar_Result = ALREADY_KNOWS_MOVE; - ScriptContext_Enable(); - } - else if (CanLearnTeachableMove(GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_SPECIES_OR_EGG), gSpecialVar_ItemId) == FALSE) - { - gSpecialVar_Result = CANNOT_LEARN_MOVE; - ScriptContext_Enable(); - } - else - { - if (GiveMoveToBoxMon(GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos), gSpecialVar_ItemId) != MON_HAS_MAX_MOVES) - CreateTask(Task_LearnedMoveBoxMon, 1); - else - { - GetBoxMonNickname(GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos), gStringVar1); - StringCopy(gStringVar2, GetMoveName(gSpecialVar_ItemId)); - ShowFieldMessage(gText_PkmnNeedsToReplaceMove); - CreateTask(Task_ReplaceBoxMonMoveYesNo, 1); - } - } - - } -} - -static void Task_LearnedMoveBoxMon(u8 taskId) -{ - s16 move = gSpecialVar_ItemId; - - if(gSpecialVar_MonBoxId == 0xFF) - GetMonNickname(&gPlayerParty[gSpecialVar_MonBoxPos], gStringVar1); - else - GetBoxMonNickname(GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos), gStringVar1); - StringCopy(gStringVar2, GetMoveName(move)); - ShowFieldMessage(gText_PkmnLearnedMove4); - gTasks[taskId].func = Task_DoLearnedBoxMonMoveFanfareAfterText; -} - -static void Task_DoLearnedBoxMonMoveFanfareAfterText(u8 taskId) -{ - if (IsTextPrinterActiveOnWindow(0) != TRUE) - { - PlayFanfare(MUS_LEVEL_UP); - gSpecialVar_Result = CAN_LEARN_MOVE; - DestroyTask(taskId); - ScriptContext_Enable(); - } -} - -static void Task_ReplaceBoxMonMoveYesNo(u8 taskId) -{ - if (IsTextPrinterActiveOnWindow(0) != TRUE) - { - DisplayYesNoMenuDefaultYes(); - gTasks[taskId].func = Task_HandleReplaceBoxMonMoveYesNoInput; - } -} - -static void Task_HandleReplaceBoxMonMoveYesNoInput(u8 taskId) -{ - switch (Menu_ProcessInputNoWrapClearOnChoose()) - { - case 0: - ShowFieldMessage(gText_WhichMoveToForget); - gTasks[taskId].func = Task_ShowSummaryScreenToForgetBoxMonMove; - break; - case MENU_B_PRESSED: - PlaySE(SE_SELECT); - // fallthrough - case 1: - StopLearningBoxMonMovePrompt(taskId); - break; - } -} - -static void Task_ShowSummaryScreenToForgetBoxMonMove(u8 taskId) -{ - if (IsTextPrinterActiveOnWindow(0) != TRUE) - { - DestroyTask(taskId); - if(gSpecialVar_MonBoxId == 0xFF) - ShowSelectMovePokemonSummaryScreen(gPlayerParty, gSpecialVar_MonBoxPos, gPlayerPartyCount - 1, CB2_ReturnToFieldWhileLearningMove, gSpecialVar_ItemId); - else - ShowSelectMoveBoxPokemonSummaryScreen(GetBoxedMonPtr(StorageGetCurrentBox(), 0), gSpecialVar_MonBoxPos, IN_BOX_COUNT - 1, CB2_ReturnToFieldWhileLearningMove, gSpecialVar_ItemId); + // We want to wait one frame before using ScriptContext_Enable() or the game freezes + CreateTask(UIEndTask, 1); + return; } + u32 taskId = CreateTask(Task_LearnMove, 1); + gTasks[taskId].tState = GetLearnMoveStartState(); + gTasks[taskId].tPartyIndex = gSpecialVar_0x8004; + gTasks[taskId].tMove = gSpecialVar_0x8005; } static void CB2_ReturnToFieldWhileLearningMove(void) { - if (!gPaletteFade.active) - { - gFieldCallback = Task_ReturnToFieldWhileLearningMove; - SetMainCallback2(CB2_ReturnToField); - } + gFieldCallback = Task_ReturnToFieldWhileLearningMove; + CB2_ReturnToField(); } static void Task_ReturnToFieldWhileLearningMove(void) { - if (GetMoveSlotToReplace() < MAX_MON_MOVES) - { - if(gSpecialVar_MonBoxId == 0xFF) - { - GetMonNickname(&gPlayerParty[gSpecialVar_MonBoxPos], gStringVar1); - StringCopy(gStringVar2, GetMoveName(GetMonData(&gPlayerParty[gSpecialVar_MonBoxPos], MON_DATA_MOVE1 + GetMoveSlotToReplace()))); - } - else - { - GetBoxMonNickAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, gStringVar1); - StringCopy(gStringVar2, GetMoveName(GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_MOVE1 + GetMoveSlotToReplace()))); - } - ShowFieldMessage(gText_12PoofForgotMove); - CreateTask(Task_BoxMonReplaceMove,1); - } - else - CreateTask(StopLearningBoxMonMovePrompt,1); + u32 taskId = CreateTask(Task_LearnMove, 1); + gTasks[taskId].tState = GetLearnMoveResumeAfterSummaryScreenState(); + gTasks[taskId].tPartyIndex = gSpecialVar_0x8008; + gTasks[taskId].tMove = gSpecialVar_0x8009; } -static void Task_BoxMonReplaceMove(u8 taskId) -{ - - if (IsTextPrinterActiveOnWindow(0) != TRUE) - { - enum Move move = gSpecialVar_ItemId; - if(gSpecialVar_MonBoxId == 0xFF) - { - RemoveMonPPBonus(&gPlayerParty[gSpecialVar_MonBoxPos], GetMoveSlotToReplace()); - SetMonMoveSlot(&gPlayerParty[gSpecialVar_MonBoxPos], move, GetMoveSlotToReplace()); - } - else - { - struct BoxPokemon *mon = GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos); - - u8 ppBonuses = GetBoxMonData(mon, MON_DATA_PP_BONUSES); - ppBonuses &= gPPUpClearMask[GetMoveSlotToReplace()]; - SetBoxMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses); - - SetBoxMonData(mon, MON_DATA_MOVE1 + GetMoveSlotToReplace(), &move); - SetBoxMonData(mon, MON_DATA_PP1 + GetMoveSlotToReplace(), &gMovesInfo[move].pp); - } - - Task_LearnedMoveBoxMon(taskId); - } -} - -static void StopLearningBoxMonMovePrompt(u8 taskId) -{ - StringCopy(gStringVar2, GetMoveName(gSpecialVar_ItemId)); - ShowFieldMessage(gText_StopLearningMove2); - gTasks[taskId].func = Task_StopLearningBoxMonMoveYesNo; -} - -static void Task_StopLearningBoxMonMoveYesNo(u8 taskId) -{ - if (IsTextPrinterActiveOnWindow(0) != TRUE) - { - DisplayYesNoMenuDefaultYes(); - gTasks[taskId].func = Task_HandleStopLearningBoxMonMoveYesNoInput; - } -} - -static void Task_HandleStopLearningBoxMonMoveYesNoInput(u8 taskId) -{ - switch (Menu_ProcessInputNoWrapClearOnChoose()) - { - case 0: - if(gSpecialVar_MonBoxId == 0xFF) - GetMonNickname(&gPlayerParty[gSpecialVar_MonBoxPos], gStringVar1); - else - GetBoxMonNickAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, gStringVar1); - ShowFieldMessage(gText_MoveNotLearned); - gSpecialVar_Result = 4; - gTasks[taskId].func = Task_DidntLearnMove; - break; - case MENU_B_PRESSED: - PlaySE(SE_SELECT); - // fallthrough - case 1: - if(gSpecialVar_MonBoxId == 0xFF) - GetMonNickname(&gPlayerParty[gSpecialVar_MonBoxPos], gStringVar1); - else - GetBoxMonNickAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, gStringVar1); - ShowFieldMessage(gText_PkmnNeedsToReplaceMove); - gTasks[taskId].func = Task_ReplaceBoxMonMoveYesNo; - break; - } -} - -static void Task_DidntLearnMove(u8 taskId) -{ - if (IsTextPrinterActiveOnWindow(0) != TRUE) - { - DestroyTask(taskId); - ScriptContext_Enable(); - } -} +#undef tState +#undef tPartyIndex +#undef tMove void EnterCode(void) { diff --git a/src/mail_data.c b/src/mail_data.c index d364c72820..bc54a2203d 100644 --- a/src/mail_data.c +++ b/src/mail_data.c @@ -156,32 +156,38 @@ void ClearMailItemId(u8 mailId) gSaveBlock1Ptr->mail[mailId].itemId = ITEM_NONE; } -u8 TakeMailFromMonAndSave(struct Pokemon *mon) +u8 SaveMailToPC(struct Mail *mail) { - u8 i; - u8 newHeldItem[2]; - u8 newMailId; - - newHeldItem[0] = ITEM_NONE; - newHeldItem[1] = ITEM_NONE << 8; - newMailId = MAIL_NONE; - - for (i = PARTY_SIZE; i < MAIL_COUNT; i++) + for (u32 i = PARTY_SIZE; i < MAIL_COUNT; i++) { if (gSaveBlock1Ptr->mail[i].itemId == ITEM_NONE) { - memcpy(&gSaveBlock1Ptr->mail[i], &gSaveBlock1Ptr->mail[GetMonData(mon, MON_DATA_MAIL)], sizeof(struct Mail)); - gSaveBlock1Ptr->mail[GetMonData(mon, MON_DATA_MAIL)].itemId = ITEM_NONE; - SetMonData(mon, MON_DATA_MAIL, &newMailId); - SetMonData(mon, MON_DATA_HELD_ITEM, newHeldItem); + memcpy(&gSaveBlock1Ptr->mail[i], mail, sizeof(struct Mail)); return i; } } - // No space to save mail return MAIL_NONE; } +u8 TakeMailFromMonAndSave(struct Pokemon *mon) +{ + u32 heldItem; + u32 mailId, newMailId; + + mailId = GetMonData(mon, MON_DATA_MAIL); + newMailId = SaveMailToPC(&gSaveBlock1Ptr->mail[mailId]); + if (newMailId != MAIL_NONE) + { + gSaveBlock1Ptr->mail[mailId].itemId = ITEM_NONE; + mailId = MAIL_NONE; + SetMonData(mon, MON_DATA_MAIL, &mailId); + heldItem = ITEM_NONE; + SetMonData(mon, MON_DATA_HELD_ITEM, &heldItem); + } + return newMailId; +} + bool8 ItemIsMail(enum Item itemId) { switch (itemId) diff --git a/src/move_relearner.c b/src/move_relearner.c index 5a15ba53a2..940120ba07 100644 --- a/src/move_relearner.c +++ b/src/move_relearner.c @@ -27,8 +27,11 @@ #include "string_util.h" #include "strings.h" #include "task.h" +#include "constants/party_menu.h" #include "constants/rgb.h" #include "constants/songs.h" +#include "data/pokemon/egg_moves.h" +#include "data/tutor_moves.h" /* * Move relearner state machine @@ -163,6 +166,11 @@ enum { #define GFXTAG_UI 5525 #define PALTAG_UI 5526 +struct RelearnType +{ + bool32 (*hasMoveToRelearn)(struct BoxPokemon*); +}; + static EWRAM_DATA struct { u8 state; @@ -365,6 +373,22 @@ static s32 GetCurrentSelectedMove(void); static void FreeMoveRelearnerResources(void); static void RemoveScrollArrows(void); static void HideHeartSpritesAndShowTeachMoveText(bool8); +static bool32 HasRelearnerLevelUpMoves(struct BoxPokemon *boxMon); +static bool32 HasRelearnerEggMoves(struct BoxPokemon *boxMon); +static bool32 HasRelearnerTMMoves(struct BoxPokemon *boxMon); +static bool32 HasRelearnerTutorMoves(struct BoxPokemon *boxMon); +static u32 GetRelearnerLevelUpMoves(struct BoxPokemon *mon, u16 *moves); +static u32 GetRelearnerEggMoves(struct BoxPokemon *mon, u16 *moves); +static u32 GetRelearnerTMMoves(struct BoxPokemon *mon, u16 *moves); +static u32 GetRelearnerTutorMoves(struct BoxPokemon *mon, u16 *moves); + +static const struct RelearnType sRelearnTypes[MOVE_RELEARNER_COUNT] = +{ + [MOVE_RELEARNER_LEVEL_UP_MOVES] = {HasRelearnerLevelUpMoves}, + [MOVE_RELEARNER_EGG_MOVES] = {HasRelearnerEggMoves}, + [MOVE_RELEARNER_TM_MOVES] = {HasRelearnerTMMoves}, + [MOVE_RELEARNER_TUTOR_MOVES] = {HasRelearnerTutorMoves}, +}; static void VBlankCB_MoveRelearner(void) { @@ -567,30 +591,20 @@ static void DoMoveRelearnerMain(void) if (selection == 0) { - if(gSpecialVar_MonBoxId == 0xFF){ - if (GiveMoveToMon(&gPlayerParty[sMoveRelearnerStruct->partyMon], GetCurrentSelectedMove()) != MON_HAS_MAX_MOVES) - { - PrintMessageWithPlaceholders(gText_MoveRelearnerPkmnLearnedMove); - gSpecialVar_0x8004 = TRUE; - sMoveRelearnerStruct->state = MENU_STATE_PRINT_TEXT_THEN_FANFARE; - } - else - { - sMoveRelearnerStruct->state = MENU_STATE_PRINT_TRYING_TO_LEARN_PROMPT; - } + struct BoxPokemon *boxmon; + if (sMoveRelearnerStruct->partyMon == PC_MON_CHOSEN) + boxmon = GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos); + else + boxmon = &(gPlayerParty[sMoveRelearnerStruct->partyMon].box); + if (GiveMoveToBoxMon(boxmon, GetCurrentSelectedMove()) != MON_HAS_MAX_MOVES) + { + PrintMessageWithPlaceholders(gText_MoveRelearnerPkmnLearnedMove); + gSpecialVar_0x8004 = TRUE; + sMoveRelearnerStruct->state = MENU_STATE_PRINT_TEXT_THEN_FANFARE; } else { - if (GiveMoveToBoxMon(GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos), GetCurrentSelectedMove()) != MON_HAS_MAX_MOVES) - { - PrintMessageWithPlaceholders(gText_MoveRelearnerPkmnLearnedMove); - gSpecialVar_0x8004 = TRUE; - sMoveRelearnerStruct->state = MENU_STATE_PRINT_TEXT_THEN_FANFARE; - } - else - { - sMoveRelearnerStruct->state = MENU_STATE_PRINT_TRYING_TO_LEARN_PROMPT; - } + sMoveRelearnerStruct->state = MENU_STATE_PRINT_TRYING_TO_LEARN_PROMPT; } } else if (selection == MENU_B_PRESSED || selection == 1) @@ -734,10 +748,7 @@ static void DoMoveRelearnerMain(void) case MENU_STATE_SHOW_MOVE_SUMMARY_SCREEN: if (!gPaletteFade.active) { - if(gSpecialVar_MonBoxId == 0xFF) - ShowSelectMovePokemonSummaryScreen(gPlayerParty, sMoveRelearnerStruct->partyMon, gPlayerPartyCount - 1, CB2_InitLearnMoveReturnFromSelectMove, GetCurrentSelectedMove()); - else - ShowPokemonSummaryScreen(SUMMARY_MODE_BOX_SELECT_MOVE, GetBoxedMonPtr(gSpecialVar_MonBoxId, 0), gSpecialVar_MonBoxPos, IN_BOX_COUNT - 1, CB2_InitLearnMoveReturnFromSelectMove); + ShowSelectMovePokemonSummaryScreen(gPlayerParty, gSpecialVar_0x8004, CB2_InitLearnMoveReturnFromSelectMove, GetCurrentSelectedMove()); FreeMoveRelearnerResources(); } break; @@ -772,10 +783,10 @@ static void DoMoveRelearnerMain(void) ShowPokemonSummaryScreen(SUMMARY_MODE_RELEARNER_CONTEST, gPlayerParty, sMoveRelearnerStruct->partyMon, gPlayerPartyCount - 1, gInitialSummaryScreenCallback); break; case RELEARN_MODE_BOX_PSS_PAGE_BATTLE_MOVES: - ShowPokemonSummaryScreen(SUMMARY_MODE_BOX_RELEARNER_BATTLE, GetBoxedMonPtr(gSpecialVar_MonBoxId, 0), gSpecialVar_MonBoxPos, IN_BOX_COUNT - 1, gInitialSummaryScreenCallback); + ShowPokemonSummaryScreen(SUMMARY_MODE_RELEARNER_BATTLE, GetBoxedMonPtr(gSpecialVar_MonBoxId, 0), gSpecialVar_MonBoxPos, IN_BOX_COUNT - 1, gInitialSummaryScreenCallback); break; case RELEARN_MODE_BOX_PSS_PAGE_CONTEST_MOVES: - ShowPokemonSummaryScreen(SUMMARY_MODE_BOX_RELEARNER_CONTEST, GetBoxedMonPtr(gSpecialVar_MonBoxId, 0), gSpecialVar_MonBoxPos, IN_BOX_COUNT - 1, gInitialSummaryScreenCallback); + ShowPokemonSummaryScreen(SUMMARY_MODE_RELEARNER_CONTEST, GetBoxedMonPtr(gSpecialVar_MonBoxId, 0), gSpecialVar_MonBoxPos, IN_BOX_COUNT - 1, gInitialSummaryScreenCallback); break; default: ShowPokemonSummaryScreen(SUMMARY_MODE_NORMAL, gPlayerParty, sMoveRelearnerStruct->partyMon, gPlayerPartyCount - 1, gInitialSummaryScreenCallback); @@ -815,36 +826,20 @@ static void DoMoveRelearnerMain(void) else { enum Move move; - if(gSpecialVar_MonBoxId == 0xFF) - { - move = GetMonData(&gPlayerParty[sMoveRelearnerStruct->partyMon], MON_DATA_MOVE1 + sMoveRelearnerStruct->moveSlot); - u8 originalPP = GetMonData(&gPlayerParty[sMoveRelearnerStruct->partyMon], MON_DATA_PP1 + sMoveRelearnerStruct->moveSlot); - - RemoveMonPPBonus(&gPlayerParty[sMoveRelearnerStruct->partyMon], sMoveRelearnerStruct->moveSlot); - SetMonMoveSlot(&gPlayerParty[sMoveRelearnerStruct->partyMon], GetCurrentSelectedMove(), sMoveRelearnerStruct->moveSlot); - u8 newPP = GetMonData(&gPlayerParty[sMoveRelearnerStruct->partyMon], MON_DATA_PP1 + sMoveRelearnerStruct->moveSlot); - if (!P_SUMMARY_MOVE_RELEARNER_FULL_PP - && (gRelearnMode == RELEARN_MODE_PSS_PAGE_BATTLE_MOVES || gRelearnMode == RELEARN_MODE_PSS_PAGE_CONTEST_MOVES) && originalPP < newPP) - SetMonData(&gPlayerParty[sMoveRelearnerStruct->partyMon], MON_DATA_PP1 + sMoveRelearnerStruct->moveSlot, &originalPP); - } + struct BoxPokemon *boxmon; + if (sMoveRelearnerStruct->partyMon == PC_MON_CHOSEN) + boxmon = GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos); else - { - move = GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_MOVE1 + sMoveRelearnerStruct->moveSlot); - u8 originalPP = GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_PP1 + sMoveRelearnerStruct->moveSlot); - - u8 ppBonuses = GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_PP_BONUSES); - ppBonuses &= gPPUpClearMask[sMoveRelearnerStruct->moveSlot]; - SetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_PP_BONUSES, &ppBonuses); + boxmon = &(gPlayerParty[sMoveRelearnerStruct->partyMon].box); + move = GetBoxMonData(boxmon, MON_DATA_MOVE1 + sMoveRelearnerStruct->moveSlot); + u8 originalPP = GetBoxMonData(boxmon, MON_DATA_PP1 + sMoveRelearnerStruct->moveSlot); - SetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_MOVE1 + sMoveRelearnerStruct->moveSlot, &sMoveRelearnerStruct->menuItems[sMoveRelearnerMenuState.listRow + sMoveRelearnerMenuState.listOffset].id); - SetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_PP1 + sMoveRelearnerStruct->moveSlot, &gMovesInfo[sMoveRelearnerStruct->menuItems[sMoveRelearnerMenuState.listRow + sMoveRelearnerMenuState.listOffset].id].pp); - - u8 newPP = GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_PP1 + sMoveRelearnerStruct->moveSlot); - if (!P_SUMMARY_MOVE_RELEARNER_FULL_PP - && (gRelearnMode == RELEARN_MODE_BOX_PSS_PAGE_BATTLE_MOVES || gRelearnMode == RELEARN_MODE_BOX_PSS_PAGE_CONTEST_MOVES) && originalPP < newPP) - SetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_PP1 + sMoveRelearnerStruct->moveSlot, &originalPP); - - } + RemoveBoxMonPPBonus(boxmon, sMoveRelearnerStruct->moveSlot); + SetBoxMonMoveSlot(boxmon, GetCurrentSelectedMove(), sMoveRelearnerStruct->moveSlot); + u8 newPP = GetBoxMonData(boxmon, MON_DATA_PP1 + sMoveRelearnerStruct->moveSlot); + if (!P_SUMMARY_MOVE_RELEARNER_FULL_PP + && (gRelearnMode == RELEARN_MODE_PSS_PAGE_BATTLE_MOVES || gRelearnMode == RELEARN_MODE_PSS_PAGE_CONTEST_MOVES) && originalPP < newPP) + SetBoxMonData(boxmon, MON_DATA_PP1 + sMoveRelearnerStruct->moveSlot, &originalPP); StringCopy(gStringVar3, GetMoveName(move)); StringCopy(gStringVar2, GetMoveName(GetCurrentSelectedMove())); @@ -1043,36 +1038,24 @@ static void RemoveScrollArrows(void) static void CreateLearnableMovesList(void) { s32 i; - u8 nickname[POKEMON_NAME_LENGTH + 1]; + struct BoxPokemon *boxmon = GetSelectedBoxMonFromPcOrParty(); switch (gMoveRelearnerState) { case MOVE_RELEARNER_EGG_MOVES: - if (gSpecialVar_MonBoxId == 0xFF) - sMoveRelearnerStruct->numMenuChoices = GetRelearnerEggMoves(&gPlayerParty[sMoveRelearnerStruct->partyMon], sMoveRelearnerStruct->movesToLearn); - else - sMoveRelearnerStruct->numMenuChoices = GetRelearnerEggMovesBox(GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos), sMoveRelearnerStruct->movesToLearn); + sMoveRelearnerStruct->numMenuChoices = GetRelearnerEggMoves(boxmon, sMoveRelearnerStruct->movesToLearn); break; case MOVE_RELEARNER_TM_MOVES: - if (gSpecialVar_MonBoxId == 0xFF) - sMoveRelearnerStruct->numMenuChoices = GetRelearnerTMMoves(&gPlayerParty[sMoveRelearnerStruct->partyMon], sMoveRelearnerStruct->movesToLearn); - else - sMoveRelearnerStruct->numMenuChoices = GetRelearnerTMMovesBox(GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos), sMoveRelearnerStruct->movesToLearn); + sMoveRelearnerStruct->numMenuChoices = GetRelearnerTMMoves(boxmon, sMoveRelearnerStruct->movesToLearn); break; case MOVE_RELEARNER_TUTOR_MOVES: - if (gSpecialVar_MonBoxId == 0xFF) - sMoveRelearnerStruct->numMenuChoices = GetRelearnerTutorMoves(&gPlayerParty[sMoveRelearnerStruct->partyMon], sMoveRelearnerStruct->movesToLearn); - else - sMoveRelearnerStruct->numMenuChoices = GetRelearnerTutorMovesBox(GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos), sMoveRelearnerStruct->movesToLearn); + sMoveRelearnerStruct->numMenuChoices = GetRelearnerTutorMoves(boxmon, sMoveRelearnerStruct->movesToLearn); break; case MOVE_RELEARNER_LEVEL_UP_MOVES: default: - if (gSpecialVar_MonBoxId == 0xFF) - sMoveRelearnerStruct->numMenuChoices = GetRelearnerLevelUpMoves(&gPlayerParty[sMoveRelearnerStruct->partyMon], sMoveRelearnerStruct->movesToLearn); - else - sMoveRelearnerStruct->numMenuChoices = GetRelearnerLevelUpMovesBox(GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos), sMoveRelearnerStruct->movesToLearn); + sMoveRelearnerStruct->numMenuChoices = GetRelearnerLevelUpMoves(boxmon, sMoveRelearnerStruct->movesToLearn); break; - } + } for (i = 0; i < sMoveRelearnerStruct->numMenuChoices; i++) { @@ -1080,11 +1063,8 @@ static void CreateLearnableMovesList(void) sMoveRelearnerStruct->menuItems[i].id = sMoveRelearnerStruct->movesToLearn[i]; } - if(gSpecialVar_MonBoxId == 0xFF) - GetMonData(&gPlayerParty[sMoveRelearnerStruct->partyMon], MON_DATA_NICKNAME, nickname); - else - GetBoxMonNickAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, nickname); - StringCopy_Nickname(gStringVar1, nickname); + GetBoxMonData(boxmon, MON_DATA_NICKNAME, gStringVar1); + sMoveRelearnerStruct->menuItems[sMoveRelearnerStruct->numMenuChoices].name = gText_Cancel; sMoveRelearnerStruct->menuItems[sMoveRelearnerStruct->numMenuChoices].id = LIST_CANCEL; sMoveRelearnerStruct->numMenuChoices++; @@ -1151,3 +1131,300 @@ void MoveRelearnerShowHideCategoryIcon(s32 moveId) StartSpriteAnim(&gSprites[sMoveRelearnerStruct->categoryIconSpriteId], GetBattleMoveCategory(moveId)); } } + +static void QuickSortMoves(u16 *moves, s32 left, s32 right) +{ + if (left >= right) + return; + + u16 pivot = moves[(left + right) / 2]; + s32 i = left, j = right; + + while (i <= j) + { + while (moves[i] != MOVE_NONE && StringCompare(GetMoveName(moves[i]), GetMoveName(pivot)) < 0) + i++; + while (moves[j] != MOVE_NONE && StringCompare(GetMoveName(moves[j]), GetMoveName(pivot)) > 0) + j--; + + if (i <= j) + { + u16 temp = moves[i]; + moves[i] = moves[j]; + moves[j] = temp; + i++; + j--; + } + } + + QuickSortMoves(moves, left, j); + QuickSortMoves(moves, i, right); +} + +static void SortMovesAlphabetically(u16 *moves, u32 numMoves) +{ + if (numMoves > 1) + QuickSortMoves(moves, 0, numMoves - 1); +} + +static u32 GetRelearnerLevelUpMoves(struct BoxPokemon *mon, u16 *moves) +{ + u32 numMoves = 0; + u32 species = GetBoxMonData(mon, MON_DATA_SPECIES_OR_EGG); + + if (species == SPECIES_EGG) + return 0; + + u32 level = (P_ENABLE_ALL_LEVEL_UP_MOVES ? MAX_LEVEL : GetLevelFromBoxMonExp(mon)); + do + { + const struct LevelUpMove *learnset = GetSpeciesLevelUpLearnset(species); + + for (u32 i = 0; i < MAX_LEVEL_UP_MOVES && learnset[i].move != LEVEL_UP_MOVE_END; i++) + { + if (learnset[i].level > level) + break; + + if (!BoxMonKnowsMove(mon, learnset[i].move)) + moves[numMoves++] = learnset[i].move; + } + + species = (P_PRE_EVO_MOVES ? GetSpeciesPreEvolution(species) : SPECIES_NONE); + } while (species != SPECIES_NONE); + + if (P_SORT_MOVES) + SortMovesAlphabetically(moves, numMoves); + + return numMoves; +} + +static u32 GetRelearnerEggMoves(struct BoxPokemon *mon, u16 *moves) +{ + if (!FlagGet(P_FLAG_EGG_MOVES) && !P_ENABLE_MOVE_RELEARNERS) + return 0; + + u32 species = GetBoxMonData(mon, MON_DATA_SPECIES_OR_EGG); + + if (species == SPECIES_EGG) + return 0; + + u32 numMoves = 0; + while (GetSpeciesPreEvolution(species) != SPECIES_NONE) + species = GetSpeciesPreEvolution(species); + + const u16 *eggMoves = GetSpeciesEggMoves(species); + + if (eggMoves == sNoneEggMoveLearnset) + return 0; + + for (u32 i = 0; eggMoves[i] != MOVE_UNAVAILABLE; i++) + { + if (!BoxMonKnowsMove(mon, eggMoves[i])) + moves[numMoves++] = eggMoves[i]; + } + + if (P_SORT_MOVES) + SortMovesAlphabetically(moves, numMoves); + + return numMoves; +} + +static u32 GetRelearnerTMMoves(struct BoxPokemon *mon, u16 *moves) +{ + if (!P_TM_MOVES_RELEARNER && !P_ENABLE_MOVE_RELEARNERS) + return 0; + + u32 species = GetBoxMonData(mon, MON_DATA_SPECIES_OR_EGG); + + if (species == SPECIES_EGG) + return 0; + + u32 numMoves = 0; + + for (u32 i = 0; i < NUM_ALL_MACHINES; i++) + { + enum Item item = GetTMHMItemId(i + 1); + enum Move move = GetTMHMMoveId(i + 1); + + if (move == MOVE_NONE) + continue; + + if (!P_ENABLE_ALL_TM_MOVES && !CheckBagHasItem(item, 1)) + continue; + + if (!CanLearnTeachableMove(species, move)) + continue; + + if (!BoxMonKnowsMove(mon, move)) + moves[numMoves++] = move; + } + + if (P_SORT_MOVES) + SortMovesAlphabetically(moves, numMoves); + + return numMoves; +} + +static u32 GetRelearnerTutorMoves(struct BoxPokemon *mon, u16 *moves) +{ + if (!FlagGet(P_FLAG_TUTOR_MOVES) && !P_ENABLE_MOVE_RELEARNERS) + return 0; + + u32 species = GetBoxMonData(mon, MON_DATA_SPECIES_OR_EGG); + + if (species == SPECIES_EGG) + return 0; + + u32 numMoves = 0; + + for (u32 i = 0; gTutorMoves[i] != MOVE_UNAVAILABLE; i++) + { + enum Move move = gTutorMoves[i]; + + if (!CanLearnTeachableMove(species, move)) + continue; + + if (!BoxMonKnowsMove(mon, move)) + moves[numMoves++] = move; + } + + if (P_SORT_MOVES) + SortMovesAlphabetically(moves, numMoves); + + return numMoves; +} + +void HasMovesToRelearn(void) +{ + struct BoxPokemon *boxmon = GetSelectedBoxMonFromPcOrParty(); + if (CanBoxMonRelearnMoves(boxmon, gMoveRelearnerState)) + gSpecialVar_Result = TRUE; + else + gSpecialVar_Result = FALSE; +} + +bool32 CanBoxMonRelearnAnyMove(struct BoxPokemon *boxMon) +{ + for (u32 i = MOVE_RELEARNER_LEVEL_UP_MOVES; i < MOVE_RELEARNER_COUNT; i++) + { + if (sRelearnTypes[i].hasMoveToRelearn(boxMon)) + return TRUE; + } + return FALSE; +} + +bool32 CanBoxMonRelearnMoves(struct BoxPokemon *boxMon, enum MoveRelearnerStates state) +{ + return sRelearnTypes[state].hasMoveToRelearn(boxMon); +} + +static bool32 HasRelearnerLevelUpMoves(struct BoxPokemon *boxMon) +{ + u32 species = GetBoxMonData(boxMon, MON_DATA_SPECIES_OR_EGG); + + if (species == SPECIES_EGG) + return FALSE; + + u32 level = (P_ENABLE_ALL_LEVEL_UP_MOVES == TRUE) ? MAX_LEVEL : GetLevelFromBoxMonExp(boxMon); + + do + { + const struct LevelUpMove *learnset = GetSpeciesLevelUpLearnset(species); + + for (u32 i = 0; i < MAX_LEVEL_UP_MOVES && learnset[i].move != LEVEL_UP_MOVE_END; i++) + { + if (learnset[i].level > level) + break; + + if (!BoxMonKnowsMove(boxMon, learnset[i].move)) + return TRUE; + } + + species = (P_PRE_EVO_MOVES ? GetSpeciesPreEvolution(species) : SPECIES_NONE); + + } while (species != SPECIES_NONE); + + return FALSE; +} + +static bool32 HasRelearnerEggMoves(struct BoxPokemon *boxMon) +{ + if (!FlagGet(P_FLAG_EGG_MOVES) && !P_ENABLE_MOVE_RELEARNERS) + return FALSE; + + u32 species = GetBoxMonData(boxMon, MON_DATA_SPECIES_OR_EGG); + + if (species == SPECIES_EGG) + return FALSE; + + while (GetSpeciesPreEvolution(species) != SPECIES_NONE) + species = GetSpeciesPreEvolution(species); + + const u16 *eggMoves = GetSpeciesEggMoves(species); + + if (eggMoves == sNoneEggMoveLearnset) + return FALSE; + + for (u32 i = 0; eggMoves[i] != MOVE_UNAVAILABLE; i++) + { + if (!BoxMonKnowsMove(boxMon, eggMoves[i])) + return TRUE; + } + + return FALSE; +} + +static bool32 HasRelearnerTMMoves(struct BoxPokemon *boxMon) +{ + if (!P_TM_MOVES_RELEARNER && !P_ENABLE_MOVE_RELEARNERS) + return FALSE; + + u32 species = GetBoxMonData(boxMon, MON_DATA_SPECIES_OR_EGG); + + if (species == SPECIES_EGG) + return FALSE; + + for (u32 i = 0; i < NUM_ALL_MACHINES; i++) + { + enum Item item = GetTMHMItemId(i + 1); + enum Move move = GetTMHMMoveId(i + 1); + + if (move == MOVE_NONE) + continue; + + if (!P_ENABLE_ALL_TM_MOVES && !CheckBagHasItem(item, 1)) + continue; + + if (!CanLearnTeachableMove(species, move)) + continue; + + if (!BoxMonKnowsMove(boxMon, move)) + return TRUE; + } + + return FALSE; +} + +static bool32 HasRelearnerTutorMoves(struct BoxPokemon *boxMon) +{ + if (!FlagGet(P_FLAG_TUTOR_MOVES) && !P_ENABLE_MOVE_RELEARNERS) + return FALSE; + + u32 species = GetBoxMonData(boxMon, MON_DATA_SPECIES_OR_EGG); + + if (species == SPECIES_EGG) + return FALSE; + + for (u32 i = 0; gTutorMoves[i] != MOVE_UNAVAILABLE; i++) + { + enum Move move = gTutorMoves[i]; + + if (!CanLearnTeachableMove(species, move)) + continue; + + if (!BoxMonKnowsMove(boxMon, move)) + return TRUE; + } + + return FALSE; +} diff --git a/src/new_game.c b/src/new_game.c index 4e89296958..1adcee7566 100644 --- a/src/new_game.c +++ b/src/new_game.c @@ -211,7 +211,6 @@ void NewGameInitData(void) ResetContestLinkResults(); SetCurrentDifficultyLevel(DIFFICULTY_NORMAL); ResetItemFlags(); - gSpecialVar_MonBoxId = 0xFF; ResetDexNav(); ClearFollowerNPCData(); } diff --git a/src/party_menu.c b/src/party_menu.c index 21b4af18b8..1255b5f210 100644 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -166,13 +166,6 @@ enum { #define MENU_DIR_RIGHT 2 #define MENU_DIR_LEFT -2 -enum { - CAN_LEARN_MOVE, - CANNOT_LEARN_MOVE, - ALREADY_KNOWS_MOVE, - CANNOT_LEARN_MOVE_IS_EGG -}; - enum { // Window ids 0-5 are implicitly assigned to each party Pokémon in InitPartyMenuBoxes WIN_MSG = PARTY_SIZE, @@ -279,7 +272,7 @@ static void DisplayPartyPokemonHPBarCheck(struct Pokemon *, struct PartyMenuBox static void DisplayPartyPokemonDescriptionText(u8, struct PartyMenuBox *, u8); static bool8 IsMonAllowedInMinigame(u8); static void DisplayPartyPokemonDataToTeachMove(u8, enum Move); -static u8 CanTeachMove(struct Pokemon *, enum Move); +static enum CanMoveBeLearned CanTeachMove(struct Pokemon *, enum Move); static void DisplayPartyPokemonBarDetail(u8, const u8 *, u8, const u8 *); static void DisplayPartyPokemonBarDetailToFit(u8 windowId, const u8 *str, u8 color, const u8 *align, u32 width); static void DisplayPartyPokemonLevel(u8, struct PartyMenuBox *); @@ -463,8 +456,7 @@ static void Task_ChoosePartyMon(u8 taskId); static void Task_ChooseMonForMoveRelearner(u8); static void CB2_ChooseMonForMoveRelearner(void); static void Task_BattlePyramidChooseMonHeldItems(u8); -static void ShiftMoveSlot(struct Pokemon *, u8, u8); -static void ShiftMoveSlotBoxMon(u8, u8); +static void ShiftMoveSlot(struct BoxPokemon *, u8, u8); static void BlitBitmapToPartyWindow_LeftColumn(u8, u8, u8, u8, u8, bool8); static void BlitBitmapToPartyWindow_RightColumn(u8, u8, u8, u8, u8, bool8); static void CursorCb_Summary(u8); @@ -1101,25 +1093,7 @@ static void DisplayPartyPokemonDataForContest(u8 slot) static void DisplayPartyPokemonDataForRelearner(u8 slot) { - struct Pokemon *mon = &gPlayerParty[slot]; - bool32 hasMoves = FALSE; - - switch (gMoveRelearnerState) - { - case MOVE_RELEARNER_EGG_MOVES: - hasMoves = HasRelearnerEggMoves(mon); - break; - case MOVE_RELEARNER_TM_MOVES: - hasMoves = HasRelearnerTMMoves(mon); - break; - case MOVE_RELEARNER_TUTOR_MOVES: - hasMoves = HasRelearnerTutorMoves(mon); - break; - default: - hasMoves = HasRelearnerLevelUpMoves(mon); - break; - } - + bool32 hasMoves = CanBoxMonRelearnMoves(&gPlayerParty[slot].box, gMoveRelearnerState); u32 desc = (hasMoves ? PARTYBOX_DESC_ABLE_2 : PARTYBOX_DESC_NOT_ABLE_2); DisplayPartyPokemonDescriptionData(slot, desc); } @@ -2273,7 +2247,7 @@ static void Task_HandleCancelParticipationYesNoInput(u8 taskId) } } -static u8 CanTeachMove(struct Pokemon *mon, enum Move move) +static enum CanMoveBeLearned CanTeachMove(struct Pokemon *mon, enum Move move) { if (GetMonData(mon, MON_DATA_IS_EGG)) return CANNOT_LEARN_MOVE_IS_EGG; @@ -2883,10 +2857,11 @@ static void SetPartyMonFieldSelectionActions(struct Pokemon *mons, u8 slotId) AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_SUMMARY); if (P_PARTY_MOVE_RELEARNER - && (GetMonData(&mons[slotId], MON_DATA_SPECIES) - && (HasRelearnerLevelUpMoves(&mons[slotId]) || HasRelearnerEggMoves(&mons[slotId]) - || HasRelearnerTMMoves(&mons[slotId]) || HasRelearnerTutorMoves(&mons[slotId])))) + && GetMonData(&mons[slotId], MON_DATA_SPECIES) + && CanBoxMonRelearnAnyMove(&mons[slotId].box)) + { AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_SUB_MOVES); + } // Add field moves to action list for (i = 0; i < MAX_MON_MOVES; i++) @@ -2915,26 +2890,17 @@ static void SetPartyMonFieldSelectionActions(struct Pokemon *mons, u8 slotId) static void SetPartyMonLearnMoveSelectionActions(struct Pokemon *mons, u8 slotId) { - if (GetMonData(&mons[slotId], MON_DATA_SPECIES) != SPECIES_NONE && HasRelearnerLevelUpMoves(&mons[slotId])) + if (CanBoxMonRelearnMoves(&mons[slotId].box, MOVE_RELEARNER_LEVEL_UP_MOVES)) AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_LEVEL_UP_MOVES); - if (P_ENABLE_MOVE_RELEARNERS || (P_FLAG_EGG_MOVES != 0 && FlagGet(P_FLAG_EGG_MOVES))) - { - if (GetMonData(&mons[slotId], MON_DATA_SPECIES) != SPECIES_NONE && HasRelearnerEggMoves(&mons[slotId])) - AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_EGG_MOVES); - } + if (CanBoxMonRelearnMoves(&mons[slotId].box, MOVE_RELEARNER_EGG_MOVES)) + AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_EGG_MOVES); - if (P_ENABLE_MOVE_RELEARNERS || P_TM_MOVES_RELEARNER) - { - if (GetMonData(&mons[slotId], MON_DATA_SPECIES) != SPECIES_NONE && HasRelearnerTMMoves(&mons[slotId])) - AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_TM_MOVES); - } + if (CanBoxMonRelearnMoves(&mons[slotId].box, MOVE_RELEARNER_TM_MOVES)) + AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_TM_MOVES); - if (P_ENABLE_MOVE_RELEARNERS || (P_FLAG_TUTOR_MOVES != 0 && FlagGet(P_FLAG_TUTOR_MOVES))) - { - if (GetMonData(&mons[slotId], MON_DATA_SPECIES) != SPECIES_NONE && HasRelearnerTutorMoves(&mons[slotId])) - AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_TUTOR_MOVES); - } + if (CanBoxMonRelearnMoves(&mons[slotId].box, MOVE_RELEARNER_TUTOR_MOVES)) + AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_TUTOR_MOVES); AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_CANCEL1); } @@ -5509,6 +5475,8 @@ void ItemUseCB_TMHM(u8 taskId, TaskFunc task) case ALREADY_KNOWS_MOVE: DisplayLearnMoveMessageAndClose(taskId, gText_PkmnAlreadyKnows); return; + default: + break; } if (GiveMoveToMon(mon, move) != MON_HAS_MAX_MOVES) @@ -5605,7 +5573,7 @@ static void Task_ShowSummaryScreenToForgetMove(u8 taskId) static void CB2_ShowSummaryScreenToForgetMove(void) { - ShowSelectMovePokemonSummaryScreen(gPlayerParty, gPartyMenu.slotId, gPlayerPartyCount - 1, CB2_ReturnToPartyMenuWhileLearningMove, gPartyMenu.data1); + ShowSelectMovePokemonSummaryScreen(gPlayerParty, gPartyMenu.slotId, CB2_ReturnToPartyMenuWhileLearningMove, gPartyMenu.data1); } static void CB2_ReturnToPartyMenuWhileLearningMove(void) @@ -6265,7 +6233,7 @@ void DeleteMove(struct Pokemon *mon, enum Move move) SetMonMoveSlot(mon, MOVE_NONE, i); RemoveMonPPBonus(mon, i); for (j = i; j < MAX_MON_MOVES - 1; j++) - ShiftMoveSlot(mon, j, j + 1); + ShiftMoveSlot(&mon->box, j, j + 1); break; } } @@ -7412,7 +7380,6 @@ void ChooseMonForTradingBoard(u8 menuType, MainCallback callback) void ChooseMonForMoveTutor(void) { - gSpecialVar_MonBoxId = 0xFF; InitPartyMenu(PARTY_MENU_TYPE_FIELD, PARTY_LAYOUT_SINGLE, PARTY_ACTION_MOVE_TUTOR, FALSE, PARTY_MSG_TEACH_WHICH_MON, Task_HandleChooseMonInput, CB2_ReturnToFieldContinueScriptPlayMapMusic); } @@ -7927,7 +7894,6 @@ static void CB2_ChooseContestMon(void) // Used as a script special for showing a party mon to various npcs (e.g. in-game trades, move deleter) void ChoosePartyMon(void) { - gSpecialVar_MonBoxId = 0xFF; LockPlayerFieldControls(); FadeScreen(FADE_TO_BLACK, 0); CreateTask(Task_ChoosePartyMon, 10); @@ -7945,7 +7911,6 @@ static void Task_ChoosePartyMon(u8 taskId) void ChooseMonForMoveRelearner(void) { - gSpecialVar_MonBoxId = 0xFF; gRelearnMode = RELEARN_MODE_SCRIPT; LockPlayerFieldControls(); FadeScreen(FADE_TO_BLACK, 0); @@ -7969,24 +7934,6 @@ static void CB2_ChooseMonForMoveRelearner(void) { gSpecialVar_0x8004 = PARTY_NOTHING_CHOSEN; } - else - { - switch(gMoveRelearnerState) - { - case MOVE_RELEARNER_EGG_MOVES: - gSpecialVar_0x8005 = HasRelearnerEggMoves(&gPlayerParty[gSpecialVar_0x8004]); - break; - case MOVE_RELEARNER_TM_MOVES: - gSpecialVar_0x8005 = HasRelearnerTMMoves(&gPlayerParty[gSpecialVar_0x8004]); - break; - case MOVE_RELEARNER_TUTOR_MOVES: - gSpecialVar_0x8005 = HasRelearnerTutorMoves(&gPlayerParty[gSpecialVar_0x8004]); - break; - default: - gSpecialVar_0x8005 = HasRelearnerLevelUpMoves(&gPlayerParty[gSpecialVar_0x8004]); - break; - } - } gFieldCallback2 = CB2_FadeFromPartyMenu; SetMainCallback2(CB2_ReturnToField); } @@ -8027,80 +7974,52 @@ static void Task_BattlePyramidChooseMonHeldItems(u8 taskId) void MoveDeleterChooseMoveToForget(void) { - if(gSpecialVar_MonBoxId == 0xFF) - ShowPokemonSummaryScreen(SUMMARY_MODE_SELECT_MOVE, gPlayerParty, gSpecialVar_0x8004, gPlayerPartyCount - 1, CB2_ReturnToField); - else - ShowPokemonSummaryScreen(SUMMARY_MODE_BOX_SELECT_MOVE, GetBoxedMonPtr(StorageGetCurrentBox(), 0), gSpecialVar_MonBoxPos, IN_BOX_COUNT - 1, CB2_ReturnToField); + ShowPokemonSummaryScreen(SUMMARY_MODE_SELECT_MOVE, gPlayerParty, gSpecialVar_0x8004, gPlayerPartyCount - 1, CB2_ReturnToField); gFieldCallback = FieldCB_ContinueScriptHandleMusic; } void GetNumMovesSelectedMonHas(void) { - u8 i; + u32 i; + struct BoxPokemon *boxmon = GetSelectedBoxMonFromPcOrParty(); gSpecialVar_Result = 0; for (i = 0; i < MAX_MON_MOVES; i++) { - if(gSpecialVar_MonBoxId == 0xFF){ - if (GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_MOVE1 + i) != MOVE_NONE) - gSpecialVar_Result++; - } - else{ - if (GetBoxMonDataAt(gSpecialVar_MonBoxId,gSpecialVar_MonBoxPos, MON_DATA_MOVE1 + i) != MOVE_NONE) - gSpecialVar_Result++; - } + if (GetBoxMonData(boxmon , MON_DATA_MOVE1 + i) != MOVE_NONE) + gSpecialVar_Result++; } } void BufferMoveDeleterNicknameAndMove(void) { enum Move move = 0; - if(gSpecialVar_MonBoxId == 0xFF){ - struct Pokemon *mon = &gPlayerParty[gSpecialVar_0x8004]; - move = GetMonData(mon, MON_DATA_MOVE1 + gSpecialVar_0x8005); - - GetMonNickname(mon, gStringVar1); - } - else{ - move = GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_MOVE1 + gSpecialVar_0x8005); - - GetBoxMonNickAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, gStringVar1); - } - + struct BoxPokemon *boxmon = GetSelectedBoxMonFromPcOrParty(); + move = GetBoxMonData(boxmon, MON_DATA_MOVE1 + gSpecialVar_0x8005); + GetBoxMonData(boxmon, MON_DATA_NICKNAME, gStringVar1); StringCopy(gStringVar2, GetMoveName(move)); } void MoveDeleterForgetMove(void) { - u16 i; - - if(gSpecialVar_MonBoxId == 0xFF) - { - SetMonMoveSlot(&gPlayerParty[gSpecialVar_0x8004], MOVE_NONE, gSpecialVar_0x8005); - RemoveMonPPBonus(&gPlayerParty[gSpecialVar_0x8004], gSpecialVar_0x8005); - for (i = gSpecialVar_0x8005; i < MAX_MON_MOVES - 1; i++) - ShiftMoveSlot(&gPlayerParty[gSpecialVar_0x8004], i, i + 1); - } - else - { - i = MOVE_NONE; - SetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_MOVE1 + gSpecialVar_0x8005, &i); - SetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_PP1 + gSpecialVar_0x8005, &gMovesInfo[MOVE_NONE].pp); - u8 ppBonuses = GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_PP_BONUSES); - ppBonuses &= gPPUpClearMask[gSpecialVar_0x8005]; - SetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_PP_BONUSES, &ppBonuses); - for (i = gSpecialVar_0x8005; i < MAX_MON_MOVES - 1; i++) - ShiftMoveSlotBoxMon(i, i + 1); - } + enum Move move = MOVE_NONE; + struct BoxPokemon *boxmon = GetSelectedBoxMonFromPcOrParty(); + SetBoxMonData(boxmon, MON_DATA_MOVE1 + gSpecialVar_0x8005, &move); + SetBoxMonData(boxmon, MON_DATA_PP1 + gSpecialVar_0x8005, &gMovesInfo[MOVE_NONE].pp); + u8 ppBonuses = GetBoxMonData(boxmon, MON_DATA_PP_BONUSES); + ppBonuses &= gPPUpClearMask[gSpecialVar_0x8005]; + SetBoxMonData(boxmon, MON_DATA_PP_BONUSES, &ppBonuses); + for (u32 i = gSpecialVar_0x8005; i < MAX_MON_MOVES - 1; i++) + ShiftMoveSlot(boxmon, i, i + 1); } -static void ShiftMoveSlot(struct Pokemon *mon, u8 slotTo, u8 slotFrom) +static void ShiftMoveSlot(struct BoxPokemon *mon, u8 slotTo, u8 slotFrom) { - enum Move move1 = GetMonData(mon, MON_DATA_MOVE1 + slotTo); - enum Move move0 = GetMonData(mon, MON_DATA_MOVE1 + slotFrom); - u8 pp1 = GetMonData(mon, MON_DATA_PP1 + slotTo); - u8 pp0 = GetMonData(mon, MON_DATA_PP1 + slotFrom); - u8 ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES); + enum Move move1 = GetBoxMonData(mon, MON_DATA_MOVE1 + slotTo); + enum Move move0 = GetBoxMonData(mon, MON_DATA_MOVE1 + slotFrom); + u8 pp1 = GetBoxMonData(mon, MON_DATA_PP1 + slotTo); + u8 pp0 = GetBoxMonData(mon, MON_DATA_PP1 + slotFrom); + u8 ppBonuses = GetBoxMonData(mon, MON_DATA_PP_BONUSES); u8 ppBonusMask1 = gPPUpGetMask[slotTo]; u8 ppBonusMove1 = (ppBonuses & ppBonusMask1) >> (slotTo * 2); u8 ppBonusMask2 = gPPUpGetMask[slotFrom]; @@ -8108,49 +8027,20 @@ static void ShiftMoveSlot(struct Pokemon *mon, u8 slotTo, u8 slotFrom) ppBonuses &= ~ppBonusMask1; ppBonuses &= ~ppBonusMask2; ppBonuses |= (ppBonusMove1 << (slotFrom * 2)) + (ppBonusMove2 << (slotTo * 2)); - SetMonData(mon, MON_DATA_MOVE1 + slotTo, &move0); - SetMonData(mon, MON_DATA_MOVE1 + slotFrom, &move1); - SetMonData(mon, MON_DATA_PP1 + slotTo, &pp0); - SetMonData(mon, MON_DATA_PP1 + slotFrom, &pp1); - SetMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses); -} - -static void ShiftMoveSlotBoxMon( u8 slotTo, u8 slotFrom) -{ - enum Move move1 = GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_MOVE1 + slotTo); - enum Move move0 = GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_MOVE1 + slotFrom); - u8 pp1 = GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_PP1 + slotTo); - u8 pp0 = GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_PP1 + slotFrom); - u8 ppBonuses = GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_PP_BONUSES); - u8 ppBonusMask1 = gPPUpGetMask[slotTo]; - u8 ppBonusMove1 = (ppBonuses & ppBonusMask1) >> (slotTo * 2); - u8 ppBonusMask2 = gPPUpGetMask[slotFrom]; - u8 ppBonusMove2 = (ppBonuses & ppBonusMask2) >> (slotFrom * 2); - ppBonuses &= ~ppBonusMask1; - ppBonuses &= ~ppBonusMask2; - ppBonuses |= (ppBonusMove1 << (slotFrom * 2)) + (ppBonusMove2 << (slotTo * 2)); - SetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_MOVE1 + slotTo, &move0); - SetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_MOVE1 + slotFrom, &move1); - SetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_PP1 + slotTo, &pp0); - SetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_PP1 + slotFrom, &pp1); - SetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_PP_BONUSES, &ppBonuses); + SetBoxMonData(mon, MON_DATA_MOVE1 + slotTo, &move0); + SetBoxMonData(mon, MON_DATA_MOVE1 + slotFrom, &move1); + SetBoxMonData(mon, MON_DATA_PP1 + slotTo, &pp0); + SetBoxMonData(mon, MON_DATA_PP1 + slotFrom, &pp1); + SetBoxMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses); } void IsSelectedMonEgg(void) { - if(gSpecialVar_MonBoxId == 0xFF) - { - if (GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_IS_EGG)) - gSpecialVar_Result = TRUE; - else - gSpecialVar_Result = FALSE; - } - else{ - if (GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_0x8004, MON_DATA_IS_EGG)) - gSpecialVar_Result = TRUE; - else - gSpecialVar_Result = FALSE; - } + struct BoxPokemon *boxmon = GetSelectedBoxMonFromPcOrParty(); + if (GetBoxMonData(boxmon, MON_DATA_IS_EGG)) + gSpecialVar_Result = TRUE; + else + gSpecialVar_Result = FALSE; } void IsLastMonThatKnowsSurf(void) @@ -8159,11 +8049,10 @@ void IsLastMonThatKnowsSurf(void) u32 i, j; gSpecialVar_Result = FALSE; - if(gSpecialVar_MonBoxId == 0xFF) - move = GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_MOVE1 + gSpecialVar_0x8005); - else - move = GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_MOVE1 + gSpecialVar_0x8005); + if (gSpecialVar_0x8004 == PC_MON_CHOSEN) + return; + move = GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_MOVE1 + gSpecialVar_0x8005); if (move == MOVE_SURF) { for (i = 0; i < CalculatePlayerPartyCount(); i++) diff --git a/src/pokemon.c b/src/pokemon.c index e0cf96bdd4..95ee08693e 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -30,6 +30,7 @@ #include "m4a.h" #include "main.h" #include "move_relearner.h" +#include "naming_screen.h" #include "overworld.h" #include "party_menu.h" #include "pokedex.h" @@ -65,6 +66,7 @@ #include "constants/items.h" #include "constants/layouts.h" #include "constants/moves.h" +#include "constants/party_menu.h" #include "constants/regions.h" #include "constants/songs.h" #include "constants/trainers.h" @@ -99,7 +101,6 @@ EWRAM_DATA static u8 sTriedEvolving = 0; EWRAM_DATA u16 gFollowerSteps = 0; #include "data/abilities.h" -#include "data/tutor_moves.h" // Used in an unreferenced function in RS. // Unreferenced here and in FRLG. @@ -1689,9 +1690,14 @@ u16 GiveMoveToBattleMon(struct BattlePokemon *mon, enum Move move) void SetMonMoveSlot(struct Pokemon *mon, enum Move move, u8 slot) { - SetMonData(mon, MON_DATA_MOVE1 + slot, &move); + SetBoxMonMoveSlot(&mon->box, move, slot); +} + +void SetBoxMonMoveSlot(struct BoxPokemon *mon, enum Move move, u8 slot) +{ + SetBoxMonData(mon, MON_DATA_MOVE1 + slot, &move); u32 pp = GetMovePP(move); - SetMonData(mon, MON_DATA_PP1 + slot, &pp); + SetBoxMonData(mon, MON_DATA_PP1 + slot, &pp); } static void SetMonMoveSlot_KeepPP(struct Pokemon *mon, enum Move move, u8 slot) @@ -3530,9 +3536,14 @@ u8 CalculatePPWithBonus(enum Move move, u8 ppBonuses, u8 moveIndex) void RemoveMonPPBonus(struct Pokemon *mon, u8 moveIndex) { - u8 ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES); + RemoveBoxMonPPBonus(&mon->box, moveIndex); +} + +void RemoveBoxMonPPBonus(struct BoxPokemon *mon, u8 moveIndex) +{ + u8 ppBonuses = GetBoxMonData(mon, MON_DATA_PP_BONUSES); ppBonuses &= gPPUpClearMask[moveIndex]; - SetMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses); + SetBoxMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses); } void RemoveBattleMonPPBonus(struct BattlePokemon *mon, u8 moveIndex) @@ -5360,321 +5371,6 @@ u8 CanLearnTeachableMove(u16 species, enum Move move) return FALSE; } -static void QuickSortMoves(u16 *moves, s32 left, s32 right) -{ - if (left >= right) - return; - - u16 pivot = moves[(left + right) / 2]; - s32 i = left, j = right; - - while (i <= j) - { - while (moves[i] != MOVE_NONE && StringCompare(GetMoveName(moves[i]), GetMoveName(pivot)) < 0) - i++; - while (moves[j] != MOVE_NONE && StringCompare(GetMoveName(moves[j]), GetMoveName(pivot)) > 0) - j--; - - if (i <= j) - { - u16 temp = moves[i]; - moves[i] = moves[j]; - moves[j] = temp; - i++; - j--; - } - } - - QuickSortMoves(moves, left, j); - QuickSortMoves(moves, i, right); -} - -static void SortMovesAlphabetically(u16 *moves, u32 numMoves) -{ - if (numMoves > 1) - QuickSortMoves(moves, 0, numMoves - 1); -} - -u32 GetRelearnerLevelUpMovesBox(struct BoxPokemon *boxMon, u16 *moves) -{ - u32 species = GetBoxMonData(boxMon, MON_DATA_SPECIES_OR_EGG); - - if (species == SPECIES_EGG) - return 0; - - u32 numMoves = 0; - u32 level = (P_ENABLE_ALL_LEVEL_UP_MOVES == TRUE) ? MAX_LEVEL : GetLevelFromBoxMonExp(boxMon); - - do - { - const struct LevelUpMove *learnset = GetSpeciesLevelUpLearnset(species); - - for (u32 i = 0; i < MAX_LEVEL_UP_MOVES && learnset[i].move != LEVEL_UP_MOVE_END; i++) - { - if (learnset[i].level > level) - break; - - if (!BoxMonKnowsMove(boxMon, learnset[i].move)) - moves[numMoves++] = learnset[i].move; - } - - species = (P_PRE_EVO_MOVES ? GetSpeciesPreEvolution(species) : SPECIES_NONE); - } while (species != SPECIES_NONE); - - if (P_SORT_MOVES) - SortMovesAlphabetically(moves, numMoves); - - return numMoves; -} - -u32 GetRelearnerLevelUpMoves(struct Pokemon *mon, u16 *moves) -{ - return GetRelearnerLevelUpMovesBox(&mon->box, moves); -} - -u32 GetRelearnerEggMovesBox(struct BoxPokemon *boxMon, u16 *moves) -{ - if (!FlagGet(P_FLAG_EGG_MOVES) && !P_ENABLE_MOVE_RELEARNERS) - return 0; - - u32 species = GetBoxMonData(boxMon, MON_DATA_SPECIES_OR_EGG); - - if (species == SPECIES_EGG) - return 0; - - u32 numMoves = 0; - - while (GetSpeciesPreEvolution(species) != SPECIES_NONE) - species = GetSpeciesPreEvolution(species); - - const u16 *eggMoves = GetSpeciesEggMoves(species); - - if (eggMoves == sNoneEggMoveLearnset) - return 0; - - for (u32 i = 0; eggMoves[i] != MOVE_UNAVAILABLE; i++) - { - if (!BoxMonKnowsMove(boxMon, eggMoves[i])) - moves[numMoves++] = eggMoves[i]; - } - - if (P_SORT_MOVES) - SortMovesAlphabetically(moves, numMoves); - - return numMoves; -} - -u32 GetRelearnerEggMoves(struct Pokemon *mon, u16 *moves) -{ - return GetRelearnerEggMovesBox(&mon->box, moves); -} - -u32 GetRelearnerTMMovesBox(struct BoxPokemon *boxMon, u16 *moves) -{ - if (!P_TM_MOVES_RELEARNER && !P_ENABLE_MOVE_RELEARNERS) - return 0; - - u32 species = GetBoxMonData(boxMon, MON_DATA_SPECIES_OR_EGG); - - if (species == SPECIES_EGG) - return 0; - - u32 numMoves = 0; - - for (u32 i = 0; i < NUM_ALL_MACHINES; i++) - { - enum Item item = GetTMHMItemId(i + 1); - enum Move move = GetTMHMMoveId(i + 1); - - if (move == MOVE_NONE) - continue; - - if (!P_ENABLE_ALL_TM_MOVES && !CheckBagHasItem(item, 1)) - continue; - - if (!CanLearnTeachableMove(species, move)) - continue; - - if (!BoxMonKnowsMove(boxMon, move)) - moves[numMoves++] = move; - } - - if (P_SORT_MOVES) - SortMovesAlphabetically(moves, numMoves); - - return numMoves; -} - -u32 GetRelearnerTMMoves(struct Pokemon *mon, u16 *moves) -{ - return GetRelearnerTMMovesBox(&mon->box, moves); -} - -u32 GetRelearnerTutorMovesBox(struct BoxPokemon *boxMon, u16 *moves) -{ - if (!FlagGet(P_FLAG_TUTOR_MOVES) && !P_ENABLE_MOVE_RELEARNERS) - return 0; - - u32 species = GetBoxMonData(boxMon, MON_DATA_SPECIES_OR_EGG); - - if (species == SPECIES_EGG) - return 0; - - u32 numMoves = 0; - - for (u32 i = 0; gTutorMoves[i] != MOVE_UNAVAILABLE; i++) - { - enum Move move = gTutorMoves[i]; - - if (!CanLearnTeachableMove(species, move)) - continue; - - if (!BoxMonKnowsMove(boxMon, move)) - moves[numMoves++] = move; - } - - if (P_SORT_MOVES) - SortMovesAlphabetically(moves, numMoves); - - return numMoves; -} - -u32 GetRelearnerTutorMoves(struct Pokemon *mon, u16 *moves) -{ - return GetRelearnerTutorMovesBox(&mon->box, moves); -} - -bool32 HasRelearnerLevelUpMovesBox(struct BoxPokemon *boxMon) -{ - u32 species = GetBoxMonData(boxMon, MON_DATA_SPECIES_OR_EGG); - - if (species == SPECIES_EGG) - return FALSE; - - u32 level = (P_ENABLE_ALL_LEVEL_UP_MOVES == TRUE) ? MAX_LEVEL : GetLevelFromBoxMonExp(boxMon); - - do - { - const struct LevelUpMove *learnset = GetSpeciesLevelUpLearnset(species); - - for (u32 i = 0; i < MAX_LEVEL_UP_MOVES && learnset[i].move != LEVEL_UP_MOVE_END; i++) - { - if (learnset[i].level > level) - break; - - if (!BoxMonKnowsMove(boxMon, learnset[i].move)) - return TRUE; - } - - species = (P_PRE_EVO_MOVES ? GetSpeciesPreEvolution(species) : SPECIES_NONE); - - } while (species != SPECIES_NONE); - - return FALSE; -} - -bool32 HasRelearnerLevelUpMoves(struct Pokemon *mon) -{ - return HasRelearnerLevelUpMovesBox(&mon->box); -} - -bool32 HasRelearnerEggMovesBox(struct BoxPokemon *boxMon) -{ - if (!FlagGet(P_FLAG_EGG_MOVES) && !P_ENABLE_MOVE_RELEARNERS) - return FALSE; - - u32 species = GetBoxMonData(boxMon, MON_DATA_SPECIES_OR_EGG); - - if (species == SPECIES_EGG) - return FALSE; - - while (GetSpeciesPreEvolution(species) != SPECIES_NONE) - species = GetSpeciesPreEvolution(species); - - const u16 *eggMoves = GetSpeciesEggMoves(species); - - if (eggMoves == sNoneEggMoveLearnset) - return FALSE; - - for (u32 i = 0; eggMoves[i] != MOVE_UNAVAILABLE; i++) - { - if (!BoxMonKnowsMove(boxMon, eggMoves[i])) - return TRUE; - } - - return FALSE; -} - -bool32 HasRelearnerEggMoves(struct Pokemon *mon) -{ - return HasRelearnerEggMovesBox(&mon->box); -} - -bool32 HasRelearnerTMMovesBox(struct BoxPokemon *boxMon) -{ - if (!P_TM_MOVES_RELEARNER && !P_ENABLE_MOVE_RELEARNERS) - return FALSE; - - u32 species = GetBoxMonData(boxMon, MON_DATA_SPECIES_OR_EGG); - - if (species == SPECIES_EGG) - return FALSE; - - for (u32 i = 0; i < NUM_ALL_MACHINES; i++) - { - enum Item item = GetTMHMItemId(i + 1); - enum Move move = GetTMHMMoveId(i + 1); - - if (move == MOVE_NONE) - continue; - - if (!P_ENABLE_ALL_TM_MOVES && !CheckBagHasItem(item, 1)) - continue; - - if (!CanLearnTeachableMove(species, move)) - continue; - - if (!BoxMonKnowsMove(boxMon, move)) - return TRUE; - } - - return FALSE; -} - -bool32 HasRelearnerTMMoves(struct Pokemon *mon) -{ - return HasRelearnerTMMovesBox(&mon->box); -} - -bool32 HasRelearnerTutorMovesBox(struct BoxPokemon *boxMon) -{ - if (!FlagGet(P_FLAG_TUTOR_MOVES) && !P_ENABLE_MOVE_RELEARNERS) - return FALSE; - - u32 species = GetBoxMonData(boxMon, MON_DATA_SPECIES_OR_EGG); - - if (species == SPECIES_EGG) - return FALSE; - - for (u32 i = 0; gTutorMoves[i] != MOVE_UNAVAILABLE; i++) - { - enum Move move = gTutorMoves[i]; - - if (!CanLearnTeachableMove(species, move)) - continue; - - if (!BoxMonKnowsMove(boxMon, move)) - return TRUE; - } - - return FALSE; -} - -bool32 HasRelearnerTutorMoves(struct Pokemon *mon) -{ - return HasRelearnerTutorMovesBox(&mon->box); -} - u8 GetLevelUpMovesBySpecies(u16 species, u16 *moves) { u8 numMoves = 0; @@ -5687,66 +5383,6 @@ u8 GetLevelUpMovesBySpecies(u16 species, u16 *moves) return numMoves; } -u8 GetNumberOfRelearnableMoves(struct Pokemon *mon) -{ - enum Move learnedMoves[MAX_MON_MOVES]; - enum Move moves[MAX_LEVEL_UP_MOVES]; - u8 numMoves = 0; - u16 species; - u8 level; - if(gSpecialVar_MonBoxId == 0xFF) - { - species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG, 0); - level = GetMonData(mon, MON_DATA_LEVEL, 0); - } - else - { - species = GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_SPECIES_OR_EGG); - level = GetBoxMonLevelAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos); - } - - const struct LevelUpMove *learnset = GetSpeciesLevelUpLearnset(species); - int i, j, k; - - if (species == SPECIES_EGG) - return 0; - - for (i = 0; i < MAX_MON_MOVES; i++) - { - if(gSpecialVar_MonBoxId == 0xFF) - learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0); - else - learnedMoves[i] = GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_MOVE1 + i); - } - - for (i = 0; i < MAX_LEVEL_UP_MOVES; i++) - { - u16 moveLevel; - - if (learnset[i].move == LEVEL_UP_MOVE_END) - break; - - moveLevel = learnset[i].level; - - if (moveLevel <= level) - { - for (j = 0; j < MAX_MON_MOVES && learnedMoves[j] != learnset[i].move; j++) - ; - - if (j == MAX_MON_MOVES) - { - for (k = 0; k < numMoves && moves[k] != learnset[i].move; k++) - ; - - if (k == numMoves) - moves[numMoves++] = learnset[i].move; - } - } - } - - return numMoves; -} - u16 SpeciesToPokedexNum(u16 species) { if (IsNationalPokedexEnabled()) @@ -7223,6 +6859,16 @@ bool32 IsSpeciesOfType(u32 species, enum Type type) return FALSE; } +struct BoxPokemon *GetSelectedBoxMonFromPcOrParty(void) +{ + struct BoxPokemon *boxmon; + if (gSpecialVar_0x8004 == PC_MON_CHOSEN) + boxmon = GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos); + else + boxmon = &(gPlayerParty[gSpecialVar_0x8004].box); + return boxmon; +} + u32 GiveScriptedMonToPlayer(struct Pokemon *mon, u8 slot) { u32 sentToPc; @@ -7257,3 +6903,11 @@ u32 GiveScriptedMonToPlayer(struct Pokemon *mon, u8 slot) } return sentToPc; } + +void ChangePokemonNicknameWithCallback(void (*callback)(void)) +{ + struct BoxPokemon *boxMon = GetSelectedBoxMonFromPcOrParty(); + GetBoxMonData(boxMon, MON_DATA_NICKNAME, gStringVar3); + GetBoxMonData(boxMon, MON_DATA_NICKNAME, gStringVar2); + DoNamingScreen(NAMING_SCREEN_NICKNAME, gStringVar2, GetBoxMonData(boxMon, MON_DATA_SPECIES), GetBoxMonGender(boxMon), GetBoxMonData(boxMon, MON_DATA_PERSONALITY), callback); +} diff --git a/src/pokemon_size_record.c b/src/pokemon_size_record.c index 96c19948b4..2aa438244a 100644 --- a/src/pokemon_size_record.c +++ b/src/pokemon_size_record.c @@ -57,21 +57,6 @@ enum extern const u8 gText_DecimalPoint[]; extern const u8 gText_Marco[]; -static u32 GetMonSizeHash(struct Pokemon *pkmn) -{ - u16 personality = GetMonData(pkmn, MON_DATA_PERSONALITY); - u16 hpIV = GetMonData(pkmn, MON_DATA_HP_IV) & 0xF; - u16 attackIV = GetMonData(pkmn, MON_DATA_ATK_IV) & 0xF; - u16 defenseIV = GetMonData(pkmn, MON_DATA_DEF_IV) & 0xF; - u16 speedIV = GetMonData(pkmn, MON_DATA_SPEED_IV) & 0xF; - u16 spAtkIV = GetMonData(pkmn, MON_DATA_SPATK_IV) & 0xF; - u16 spDefIV = GetMonData(pkmn, MON_DATA_SPDEF_IV) & 0xF; - u32 hibyte = ((attackIV ^ defenseIV) * hpIV) ^ (personality & 0xFF); - u32 lobyte = ((spAtkIV ^ spDefIV) * speedIV) ^ (personality >> 8); - - return (hibyte << 8) + lobyte; -} - static u32 GetBoxMonSizeHash(struct BoxPokemon *pkmn) { u16 personality = GetBoxMonData(pkmn, MON_DATA_PERSONALITY); @@ -144,62 +129,30 @@ static u8 CompareMonSize(u16 species, u16 *sizeRecord) { return POKEMON_NONE; } - else if(gSpecialVar_MonBoxId == 0xFF) + + struct BoxPokemon *boxmon = GetSelectedBoxMonFromPcOrParty(); + if (GetBoxMonData(boxmon, MON_DATA_IS_EGG) == TRUE || GetBoxMonData(boxmon, MON_DATA_SPECIES) != species) { - struct Pokemon *pkmn = &gPlayerParty[gSpecialVar_Result]; - - if (GetMonData(pkmn, MON_DATA_IS_EGG) == TRUE || GetMonData(pkmn, MON_DATA_SPECIES) != species) - { - return POKEMON_INCORRECT_SPECIES; - } - else - { - u32 oldSize; - u32 newSize; - u16 sizeParams; - - *(&sizeParams) = GetMonSizeHash(pkmn); - newSize = GetMonSize(species, sizeParams); - oldSize = GetMonSize(species, *sizeRecord); - FormatMonSizeRecord(gStringVar2, newSize); - if (newSize <= oldSize) - { - return POKEMON_SIZE_SMALLER; - } - else - { - *sizeRecord = sizeParams; - return POKEMON_SIZE_LARGER; - } - } + return POKEMON_INCORRECT_SPECIES; } else { - struct BoxPokemon *pkmn = GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos); + u32 oldSize; + u32 newSize; + u16 sizeParams; - if (GetBoxMonData(pkmn, MON_DATA_IS_EGG) == TRUE || GetBoxMonData(pkmn, MON_DATA_SPECIES) != species) + *(&sizeParams) = GetBoxMonSizeHash(boxmon); + newSize = GetMonSize(species, sizeParams); + oldSize = GetMonSize(species, *sizeRecord); + FormatMonSizeRecord(gStringVar2, newSize); + if (newSize <= oldSize) { - return POKEMON_INCORRECT_SPECIES; + return POKEMON_SIZE_SMALLER; } else { - u32 oldSize; - u32 newSize; - u16 sizeParams; - - *(&sizeParams) = GetBoxMonSizeHash(pkmn); - newSize = GetMonSize(species, sizeParams); - oldSize = GetMonSize(species, *sizeRecord); - FormatMonSizeRecord(gStringVar2, newSize); - if (newSize <= oldSize) - { - return POKEMON_SIZE_SMALLER; - } - else - { - *sizeRecord = sizeParams; - return POKEMON_SIZE_LARGER; - } + *sizeRecord = sizeParams; + return POKEMON_SIZE_LARGER; } } } diff --git a/src/pokemon_storage_system.c b/src/pokemon_storage_system.c index 1c66afceb9..fafc76a74d 100644 --- a/src/pokemon_storage_system.c +++ b/src/pokemon_storage_system.c @@ -39,10 +39,13 @@ #include "window.h" #include "constants/form_change_types.h" #include "constants/items.h" +#include "constants/party_menu.h" #include "constants/moves.h" #include "constants/rgb.h" #include "constants/songs.h" #include "constants/pokemon_icon.h" +#include "chooseboxmon.h" +#include "party_menu.h" /* NOTE: This file is large. Some general groups of functions have @@ -795,9 +798,11 @@ static void SetUpScrollToBox(u8); static bool8 ScrollToBox(void); static s8 DetermineBoxScrollDirection(u8); static void SetCurrentBox(u8); +static struct BoxPokemon *GetCursorBoxMon(void); // Misc static void CreateMainMenu(u8, s16 *); +static void EnterPokeStorage(u8 boxOption); static u8 GetCurrentBoxOption(void); static void ScrollBackground(void); static void UpdateCloseBoxButtonFlash(void); @@ -1962,7 +1967,7 @@ static void CB2_PokeStorage(void) BuildOamBuffer(); } -void EnterPokeStorage(u8 boxOption) +static void EnterPokeStorage(u8 boxOption) { ResetTasks(); sCurrentBoxOption = boxOption; @@ -2681,20 +2686,21 @@ static void Task_OnSelectedMon(u8 taskId) break; case MENU_SELECT: PlaySE(SE_SELECT); + struct BoxPokemon *boxmon = GetCursorBoxMon(); if (sInPartyMenu) { - gSpecialVar_Result = GetBoxMonData(&gPlayerParty[sCursorPosition].box, MON_DATA_SPECIES); - gSpecialVar_MonBoxId = TOTAL_BOXES_COUNT; - gSpecialVar_0x8005 = GetNumberOfRelearnableMoves(&gPlayerParty[sCursorPosition]); + gSpecialVar_0x8004 = sCursorPosition; } else { - gSpecialVar_Result = GetBoxMonDataAt(StorageGetCurrentBox(), sCursorPosition, MON_DATA_SPECIES); + gSpecialVar_0x8004 = PC_MON_CHOSEN; + gSpecialVar_MonBoxPos = sCursorPosition; gSpecialVar_MonBoxId = StorageGetCurrentBox(); - gSpecialVar_0x8005 = GetNumberOfRelearnableMoves(&gPlayerParty[0]); } - gSpecialVar_MonBoxPos = sCursorPosition; - gSpecialVar_0x8004 = sCursorPosition; + if (IsBoxMonExcluded(boxmon)) + gSpecialVar_Result = FALSE; + else + gSpecialVar_Result = TRUE; sStorage->screenChangeType = SCREEN_CHANGE_EXIT_BOX; SetPokeStorageTask(Task_ChangeScreen); break; @@ -3654,7 +3660,10 @@ static void Task_OnCloseBoxPressed(u8 taskId) UpdateBoxToSendMons(); gPlayerPartyCount = CalculatePlayerPartyCount(); if (sStorage->boxOption == OPTION_SELECT_MON) - gSpecialVar_0x8004 = 0xFF; + { + gSpecialVar_0x8004 = PARTY_NOTHING_CHOSEN; + gSpecialVar_Result = FALSE; + } sStorage->screenChangeType = SCREEN_CHANGE_EXIT_BOX; SetPokeStorageTask(Task_ChangeScreen); } @@ -3729,7 +3738,10 @@ static void Task_OnBPressed(u8 taskId) UpdateBoxToSendMons(); gPlayerPartyCount = CalculatePlayerPartyCount(); if (sStorage->boxOption == OPTION_SELECT_MON) - gSpecialVar_0x8004 = 0xFF; + { + gSpecialVar_0x8004 = PARTY_NOTHING_CHOSEN; + gSpecialVar_Result = FALSE; + } sStorage->screenChangeType = SCREEN_CHANGE_EXIT_BOX; SetPokeStorageTask(Task_ChangeScreen); } @@ -4448,6 +4460,17 @@ static void CreateMovingMonIcon(void) sStorage->movingMonSprite->callback = SpriteCB_HeldMon; } +static bool32 ShouldBoxmonSpriteBeTransparent(u32 boxId, u32 boxPosition) +{ + if (sStorage->boxOption == OPTION_MOVE_ITEMS + && GetBoxMonDataAt(boxId, boxPosition, MON_DATA_HELD_ITEM) == ITEM_NONE) + return TRUE; + if (sStorage->boxOption == OPTION_SELECT_MON + && IsBoxMonExcluded(GetBoxedMonPtr(boxId, boxPosition))) + return TRUE; + return FALSE; +} + static void InitBoxMonSprites(u8 boxId) { u8 boxPosition; @@ -4469,6 +4492,9 @@ static void InitBoxMonSprites(u8 boxId) { personality = GetBoxMonDataAt(boxId, boxPosition, MON_DATA_PERSONALITY); sStorage->boxMonsSprites[count] = CreateMonIconSprite(species, personality, 8 * (3 * j) + 100, 8 * (3 * i) + 44, 2, 19 - j, isEgg); + + if (ShouldBoxmonSpriteBeTransparent(boxId, boxPosition)) + sStorage->boxMonsSprites[boxPosition]->oam.objMode = ST_OAM_OBJ_BLEND; } else { @@ -4478,16 +4504,6 @@ static void InitBoxMonSprites(u8 boxId) count++; } } - - // If in item mode, set all Pokémon icons with no item to be transparent - if (sStorage->boxOption == OPTION_MOVE_ITEMS) - { - for (boxPosition = 0; boxPosition < IN_BOX_COUNT; boxPosition++) - { - if (GetBoxMonDataAt(boxId, boxPosition, MON_DATA_HELD_ITEM) == ITEM_NONE) - sStorage->boxMonsSprites[boxPosition]->oam.objMode = ST_OAM_OBJ_BLEND; - } - } } static void CreateBoxMonIconAtPos(u8 boxPosition) @@ -4502,7 +4518,7 @@ static void CreateBoxMonIconAtPos(u8 boxPosition) u32 personality = GetCurrentBoxMonData(boxPosition, MON_DATA_PERSONALITY); sStorage->boxMonsSprites[boxPosition] = CreateMonIconSprite(species, personality, x, y, 2, 19 - (boxPosition % IN_BOX_COLUMNS), isEgg); - if (sStorage->boxOption == OPTION_MOVE_ITEMS) + if (ShouldBoxmonSpriteBeTransparent(StorageGetCurrentBox(), boxPosition)) sStorage->boxMonsSprites[boxPosition]->oam.objMode = ST_OAM_OBJ_BLEND; } } @@ -4592,55 +4608,27 @@ static u8 CreateBoxMonIconsInColumn(u8 column, u16 distance, s16 speed) u8 iconsCreated = 0; u8 boxPosition = column; - if (sStorage->boxOption != OPTION_MOVE_ITEMS) + for (i = 0; i < IN_BOX_ROWS; i++) { - for (i = 0; i < IN_BOX_ROWS; i++) + if (sStorage->boxSpecies[boxPosition] != SPECIES_NONE) { - if (sStorage->boxSpecies[boxPosition] != SPECIES_NONE) + sStorage->boxMonsSprites[boxPosition] = CreateMonIconSprite(sStorage->boxSpecies[boxPosition], + sStorage->boxPersonalities[boxPosition], + x, y, 2, subpriority, + sStorage->boxIsEgg[boxPosition]); + if (sStorage->boxMonsSprites[boxPosition] != NULL) { - sStorage->boxMonsSprites[boxPosition] = CreateMonIconSprite(sStorage->boxSpecies[boxPosition], - sStorage->boxPersonalities[boxPosition], - x, y, 2, subpriority, - sStorage->boxIsEgg[boxPosition]); - if (sStorage->boxMonsSprites[boxPosition] != NULL) - { - sStorage->boxMonsSprites[boxPosition]->sDistance = distance; - sStorage->boxMonsSprites[boxPosition]->sSpeed = speed; - sStorage->boxMonsSprites[boxPosition]->sScrollInDestX = xDest; - sStorage->boxMonsSprites[boxPosition]->callback = SpriteCB_BoxMonIconScrollIn; - iconsCreated++; - } + sStorage->boxMonsSprites[boxPosition]->sDistance = distance; + sStorage->boxMonsSprites[boxPosition]->sSpeed = speed; + sStorage->boxMonsSprites[boxPosition]->sScrollInDestX = xDest; + sStorage->boxMonsSprites[boxPosition]->callback = SpriteCB_BoxMonIconScrollIn; + if (ShouldBoxmonSpriteBeTransparent(sStorage->incomingBoxId, boxPosition)) + sStorage->boxMonsSprites[boxPosition]->oam.objMode = ST_OAM_OBJ_BLEND; + iconsCreated++; } - boxPosition += IN_BOX_COLUMNS; - y += 24; - } - } - else - { - // Separate case for Move Items mode is used - // to create the icons with the proper blend - for (i = 0; i < IN_BOX_ROWS; i++) - { - if (sStorage->boxSpecies[boxPosition] != SPECIES_NONE) - { - sStorage->boxMonsSprites[boxPosition] = CreateMonIconSprite(sStorage->boxSpecies[boxPosition], - sStorage->boxPersonalities[boxPosition], - x, y, 2, subpriority, - sStorage->boxIsEgg[boxPosition]); - if (sStorage->boxMonsSprites[boxPosition] != NULL) - { - sStorage->boxMonsSprites[boxPosition]->sDistance = distance; - sStorage->boxMonsSprites[boxPosition]->sSpeed = speed; - sStorage->boxMonsSprites[boxPosition]->sScrollInDestX = xDest; - sStorage->boxMonsSprites[boxPosition]->callback = SpriteCB_BoxMonIconScrollIn; - if (GetBoxMonDataAt(sStorage->incomingBoxId, boxPosition, MON_DATA_HELD_ITEM) == ITEM_NONE) - sStorage->boxMonsSprites[boxPosition]->oam.objMode = ST_OAM_OBJ_BLEND; - iconsCreated++; - } - } - boxPosition += IN_BOX_COLUMNS; - y += 24; } + boxPosition += IN_BOX_COLUMNS; + y += 24; } return iconsCreated; @@ -4796,6 +4784,15 @@ static void CreatePartyMonsSprites(bool8 visible) sStorage->partySprites[i]->oam.objMode = ST_OAM_OBJ_BLEND; } } + + if (sStorage->boxOption == OPTION_SELECT_MON) + { + for (i = 0; i < PARTY_SIZE; i++) + { + if (sStorage->partySprites[i] != NULL && IsBoxMonExcluded(&(gPlayerParty[i].box))) + sStorage->partySprites[i]->oam.objMode = ST_OAM_OBJ_BLEND; + } + } } static void CompactPartySprites(void) @@ -7757,7 +7754,7 @@ static bool8 SetMenuTexts_Mon(void) } break; case OPTION_SELECT_MON: - if (species != SPECIES_NONE) + if (species != SPECIES_NONE && CanBoxMonBeSelected(GetCursorBoxMon())) SetMenuText(MENU_SELECT); else return FALSE; @@ -9528,6 +9525,16 @@ static void SetCurrentBox(u8 boxId) gPokemonStoragePtr->currentBox = boxId; } +static struct BoxPokemon *GetCursorBoxMon(void) +{ + struct BoxPokemon *boxmon; + if (sInPartyMenu) + boxmon = &(gPlayerParty[sCursorPosition].box); + else + boxmon = GetBoxedMonPtr(StorageGetCurrentBox(), sCursorPosition); + return boxmon; +} + u32 GetBoxMonDataAt(u8 boxId, u8 boxPosition, s32 request) { if (boxId < TOTAL_BOXES_COUNT && boxPosition < IN_BOX_COUNT) @@ -9552,34 +9559,6 @@ void SetCurrentBoxMonData(u8 boxPosition, s32 request, const void *value) SetBoxMonDataAt(gPokemonStoragePtr->currentBox, boxPosition, request, value); } -void GetBoxMonNickAt(u8 boxId, u8 boxPosition, u8 *dst) -{ - if (boxId < TOTAL_BOXES_COUNT && boxPosition < IN_BOX_COUNT) - GetBoxMonData(&gPokemonStoragePtr->boxes[boxId][boxPosition], MON_DATA_NICKNAME, dst); - else - *dst = EOS; -} - -u32 GetBoxMonLevelAt(u8 boxId, u8 boxPosition) -{ - u32 lvl; - - if (boxId < TOTAL_BOXES_COUNT && boxPosition < IN_BOX_COUNT && GetBoxMonData(&gPokemonStoragePtr->boxes[boxId][boxPosition], MON_DATA_SANITY_HAS_SPECIES)) - lvl = GetLevelFromBoxMonExp(&gPokemonStoragePtr->boxes[boxId][boxPosition]); -#ifdef BUGFIX - else -#endif - lvl = 0; - - return lvl; -} - -void SetBoxMonNickAt(u8 boxId, u8 boxPosition, const u8 *nick) -{ - if (boxId < TOTAL_BOXES_COUNT && boxPosition < IN_BOX_COUNT) - SetBoxMonData(&gPokemonStoragePtr->boxes[boxId][boxPosition], MON_DATA_NICKNAME, nick); -} - u32 GetAndCopyBoxMonDataAt(u8 boxId, u8 boxPosition, s32 request, void *dst) { if (boxId < TOTAL_BOXES_COUNT && boxPosition < IN_BOX_COUNT) @@ -10109,16 +10088,19 @@ void UpdateSpeciesSpritePSS(struct BoxPokemon *boxMon) { DestroyBoxMonIconAtPosition(sCursorPosition); CreateBoxMonIconAtPos(sCursorPosition); - if (sStorage->boxOption == OPTION_MOVE_ITEMS) - SetBoxMonIconObjMode(sCursorPosition, (GetBoxMonData(boxMon, MON_DATA_HELD_ITEM) == ITEM_NONE ? ST_OAM_OBJ_BLEND : ST_OAM_OBJ_NORMAL)); } } sJustOpenedBag = FALSE; } -// Used as a script special for showing a box mon to various npcs (e.g. in-game trades, move deleter) -void ChooseBoxMon(void) +void ChooseMonFromStorage(void) { - gSpecialVar_MonBoxId = 0xFF; EnterPokeStorage(OPTION_SELECT_MON); } + +void RemoveSelectedPcMon(struct Pokemon *mon) +{ + struct BoxPokemon *boxmon = GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos); + BoxMonToMon(boxmon, mon); + ZeroBoxMonData(boxmon); +} diff --git a/src/pokemon_summary_screen.c b/src/pokemon_summary_screen.c index 19fd04294d..9499b6c7b6 100644 --- a/src/pokemon_summary_screen.c +++ b/src/pokemon_summary_screen.c @@ -320,9 +320,7 @@ static bool32 ShouldShowRename(void); static bool32 ShouldShowIvEvPrompt(void); static void BufferLeftColumnIvEvStats(void); static void CB2_ReturnToSummaryScreenFromNamingScreen(void); -static void CB2_ReturnToSummaryScreenFromNamingScreenBox(void); static void CB2_PssChangePokemonNickname(void); -static void CB2_PssChangeBoxPokemonNickname(void); static void ShowUtilityPrompt(s16 mode); static void ShowMonSkillsInfo(u8 taskId, s16 mode); static void WriteToStatsTilemapBuffer(u32 length, u32 block, u32 statsCoordX, u32 statsCoordY); @@ -338,6 +336,7 @@ static void ClearStatLabel(u32 length, u32 statsCoordX, u32 statsCoordY); u32 GetAdjustedIvData(struct Pokemon *mon, u32 stat); static void TryUpdateRelearnType(enum IncrDecrUpdateValues delta); static void ShowRelearnPrompt(void); +static struct BoxPokemon *GetCurrentBoxmon(void); static const struct BgTemplate sBgTemplates[] = { @@ -1195,14 +1194,23 @@ void ShowPokemonSummaryScreen(u8 mode, void *mons, u8 monIndex, u8 maxMonIndex, { sMonSummaryScreen = AllocZeroed(sizeof(*sMonSummaryScreen)); sMonSummaryScreen->mode = mode; - sMonSummaryScreen->monList.mons = mons; - sMonSummaryScreen->curMonIndex = monIndex; - sMonSummaryScreen->maxMonIndex = maxMonIndex; + if (monIndex == PC_MON_CHOSEN) + { + sMonSummaryScreen->monList.boxMons = GetBoxedMonPtr(gSpecialVar_MonBoxId, 0); + sMonSummaryScreen->curMonIndex = gSpecialVar_MonBoxPos; + sMonSummaryScreen->maxMonIndex = IN_BOX_COUNT - 1; + } + else + { + sMonSummaryScreen->monList.mons = mons; + sMonSummaryScreen->curMonIndex = monIndex; + sMonSummaryScreen->maxMonIndex = maxMonIndex; + } sMonSummaryScreen->callback = callback; if (gInitialSummaryScreenCallback == NULL) gInitialSummaryScreenCallback = callback; - if (mode == SUMMARY_MODE_BOX || mode == SUMMARY_MODE_BOX_SELECT_MOVE || mode == SUMMARY_MODE_BOX_RELEARNER_BATTLE || mode == SUMMARY_MODE_BOX_RELEARNER_CONTEST) + if (mode == SUMMARY_MODE_BOX || monIndex == PC_MON_CHOSEN) sMonSummaryScreen->isBoxMon = TRUE; else sMonSummaryScreen->isBoxMon = FALSE; @@ -1214,8 +1222,6 @@ void ShowPokemonSummaryScreen(u8 mode, void *mons, u8 monIndex, u8 maxMonIndex, case SUMMARY_MODE_BOX_CURSOR: case SUMMARY_MODE_RELEARNER_BATTLE: case SUMMARY_MODE_RELEARNER_CONTEST: - case SUMMARY_MODE_BOX_RELEARNER_BATTLE: - case SUMMARY_MODE_BOX_RELEARNER_CONTEST: sMonSummaryScreen->minPageIndex = 0; sMonSummaryScreen->maxPageIndex = PSS_PAGE_COUNT - 1; break; @@ -1229,16 +1235,11 @@ void ShowPokemonSummaryScreen(u8 mode, void *mons, u8 monIndex, u8 maxMonIndex, sMonSummaryScreen->maxPageIndex = PSS_PAGE_COUNT - 1; sMonSummaryScreen->lockMonFlag = TRUE; break; - case SUMMARY_MODE_BOX_SELECT_MOVE: - sMonSummaryScreen->minPageIndex = PSS_PAGE_BATTLE_MOVES; - sMonSummaryScreen->maxPageIndex = PSS_PAGE_COUNT - 1; - sMonSummaryScreen->lockMonFlag = TRUE; - break; } - if (mode == SUMMARY_MODE_RELEARNER_BATTLE || mode == SUMMARY_MODE_BOX_RELEARNER_BATTLE) + if (mode == SUMMARY_MODE_RELEARNER_BATTLE) sMonSummaryScreen->currPageIndex = PSS_PAGE_BATTLE_MOVES; - else if (mode == SUMMARY_MODE_RELEARNER_CONTEST || mode == SUMMARY_MODE_BOX_RELEARNER_CONTEST) + else if (mode == SUMMARY_MODE_RELEARNER_CONTEST) sMonSummaryScreen->currPageIndex = PSS_PAGE_CONTEST_MOVES; else sMonSummaryScreen->currPageIndex = sMonSummaryScreen->minPageIndex; @@ -1255,15 +1256,9 @@ void ShowPokemonSummaryScreen(u8 mode, void *mons, u8 monIndex, u8 maxMonIndex, SetMainCallback2(CB2_InitSummaryScreen); } -void ShowSelectMovePokemonSummaryScreen(struct Pokemon *mons, u8 monIndex, u8 maxMonIndex, void (*callback)(void), u16 newMove) +void ShowSelectMovePokemonSummaryScreen(struct Pokemon *mons, u8 monIndex, void (*callback)(void), u16 newMove) { - ShowPokemonSummaryScreen(SUMMARY_MODE_SELECT_MOVE, mons, monIndex, maxMonIndex, callback); - sMonSummaryScreen->newMove = newMove; -} - -void ShowSelectMoveBoxPokemonSummaryScreen(struct BoxPokemon *mons, u8 monIndex, u8 maxMonIndex, void (*callback)(void), u16 newMove) -{ - ShowPokemonSummaryScreen(SUMMARY_MODE_BOX_SELECT_MOVE, mons, monIndex, maxMonIndex, callback); + ShowPokemonSummaryScreen(SUMMARY_MODE_SELECT_MOVE, mons, monIndex, gPlayerPartyCount - 1, callback); sMonSummaryScreen->newMove = newMove; } @@ -1392,7 +1387,7 @@ static bool8 LoadGraphics(void) gMain.state++; break; case 22: - if (sMonSummaryScreen->mode != SUMMARY_MODE_SELECT_MOVE && sMonSummaryScreen->mode != SUMMARY_MODE_BOX_SELECT_MOVE) + if (sMonSummaryScreen->mode != SUMMARY_MODE_SELECT_MOVE) CreateTask(Task_HandleInput, 0); else CreateTask(Task_SetHandleReplaceMoveInput, 0); @@ -1501,6 +1496,13 @@ static bool8 DecompressGraphics(void) return FALSE; } +static struct BoxPokemon *GetCurrentBoxmon(void) +{ + if (sMonSummaryScreen->isBoxMon) + return &sMonSummaryScreen->monList.boxMons[sMonSummaryScreen->curMonIndex]; + return &sMonSummaryScreen->monList.mons[sMonSummaryScreen->curMonIndex].box; +} + static void CopyMonToSummaryStruct(struct Pokemon *mon) { if (!sMonSummaryScreen->isBoxMon) @@ -1573,8 +1575,8 @@ static bool8 ExtractMonDataToSummaryStruct(struct Pokemon *mon) static void SetDefaultTilemaps(void) { if ((sMonSummaryScreen->currPageIndex != PSS_PAGE_BATTLE_MOVES && sMonSummaryScreen->currPageIndex != PSS_PAGE_CONTEST_MOVES) - || sMonSummaryScreen->mode == SUMMARY_MODE_RELEARNER_BATTLE || sMonSummaryScreen->mode == SUMMARY_MODE_BOX_RELEARNER_BATTLE - || sMonSummaryScreen->mode == SUMMARY_MODE_RELEARNER_CONTEST || sMonSummaryScreen->mode == SUMMARY_MODE_BOX_RELEARNER_CONTEST) + || sMonSummaryScreen->mode == SUMMARY_MODE_RELEARNER_BATTLE + || sMonSummaryScreen->mode == SUMMARY_MODE_RELEARNER_CONTEST) { PositionPowerAccSlidingWindow(0, 0xFF); PositionAppealJamSlidingWindow(0, 0xFF, 0); @@ -1592,7 +1594,7 @@ static void SetDefaultTilemaps(void) } // these blocks handle preparing the gfx to return straight to the respective move info screens - if (sMonSummaryScreen->mode == SUMMARY_MODE_RELEARNER_BATTLE || sMonSummaryScreen->mode == SUMMARY_MODE_BOX_RELEARNER_BATTLE) + if (sMonSummaryScreen->mode == SUMMARY_MODE_RELEARNER_BATTLE) { SetBgTilemapBuffer(1, sMonSummaryScreen->bgTilemapBuffers[PSS_PAGE_SKILLS][0]); SetBgTilemapBuffer(2, sMonSummaryScreen->bgTilemapBuffers[PSS_PAGE_BATTLE_MOVES][0]); @@ -1603,7 +1605,7 @@ static void SetDefaultTilemaps(void) ShowBg(1); ShowBg(2); } - else if (sMonSummaryScreen->mode == SUMMARY_MODE_RELEARNER_CONTEST || sMonSummaryScreen->mode == SUMMARY_MODE_BOX_RELEARNER_CONTEST) + else if (sMonSummaryScreen->mode == SUMMARY_MODE_RELEARNER_CONTEST) { sMonSummaryScreen->bgDisplayOrder = 1; SetBgTilemapBuffer(1, sMonSummaryScreen->bgTilemapBuffers[PSS_PAGE_CONTEST_MOVES][0]); @@ -1739,18 +1741,16 @@ static void Task_HandleInput(u8 taskId) { if (ShouldShowRename()) { - if (!sMonSummaryScreen->isBoxMon) + if (sMonSummaryScreen->isBoxMon) { - sMonSummaryScreen->callback = CB2_PssChangePokemonNickname; - gSpecialVar_MonBoxId = 0xFF; + gSpecialVar_0x8004 = PC_MON_CHOSEN; + gSpecialVar_MonBoxPos = sMonSummaryScreen->curMonIndex; } else { - sMonSummaryScreen->callback = CB2_PssChangeBoxPokemonNickname; - gSpecialVar_MonBoxId = StorageGetCurrentBox(); + gSpecialVar_0x8004 = sMonSummaryScreen->curMonIndex; } - gSpecialVar_0x8004 = sMonSummaryScreen->curMonIndex; - gSpecialVar_MonBoxPos = sMonSummaryScreen->curMonIndex; + sMonSummaryScreen->callback = CB2_PssChangePokemonNickname; } StopPokemonAnimations(); @@ -1784,17 +1784,16 @@ static void Task_HandleInput(u8 taskId) && (sMonSummaryScreen->currPageIndex == PSS_PAGE_BATTLE_MOVES || sMonSummaryScreen->currPageIndex == PSS_PAGE_CONTEST_MOVES)) { sMonSummaryScreen->callback = CB2_InitLearnMove; - gSpecialVar_0x8004 = sMonSummaryScreen->curMonIndex; + gRelearnMode = sMonSummaryScreen->currPageIndex; gSpecialVar_MonBoxPos = sMonSummaryScreen->curMonIndex; - if (!sMonSummaryScreen->isBoxMon) + if (sMonSummaryScreen->isBoxMon) { - gRelearnMode = sMonSummaryScreen->currPageIndex; - gSpecialVar_MonBoxId = 0xFF; + gSpecialVar_0x8004 = PC_MON_CHOSEN; + gSpecialVar_MonBoxPos = sMonSummaryScreen->curMonIndex; } else { - gRelearnMode = sMonSummaryScreen->currPageIndex + 3; - gSpecialVar_MonBoxId = StorageGetCurrentBox(); + gSpecialVar_0x8004 = sMonSummaryScreen->curMonIndex; } StopPokemonAnimations(); PlaySE(SE_SELECT); @@ -1934,21 +1933,7 @@ void ExtractMonSkillEvData(struct Pokemon *mon, struct PokeSummary *sum) bool32 HasAnyRelearnableMoves(enum MoveRelearnerStates state) { - struct Pokemon *mon = &sMonSummaryScreen->currentMon; - - switch (state) - { - case MOVE_RELEARNER_EGG_MOVES: - return HasRelearnerEggMoves(mon); - case MOVE_RELEARNER_TM_MOVES: - return HasRelearnerTMMoves(mon); - case MOVE_RELEARNER_TUTOR_MOVES: - return HasRelearnerTutorMoves(mon); - case MOVE_RELEARNER_LEVEL_UP_MOVES: - return HasRelearnerLevelUpMoves(mon); - default: - return FALSE; - } + return CanBoxMonRelearnMoves(GetCurrentBoxmon(), state); } bool32 NoMovesAvailableToRelearn(void) @@ -2764,6 +2749,7 @@ static void Task_HandleReplaceMoveInput(u8 taskId) PlaySE(SE_SELECT); sMoveSlotToReplace = sMonSummaryScreen->firstMoveIndex; gSpecialVar_0x8005 = sMoveSlotToReplace; + gSpecialVar_Result = TRUE; BeginCloseSummaryScreen(taskId); } else @@ -2778,6 +2764,7 @@ static void Task_HandleReplaceMoveInput(u8 taskId) PlaySE(SE_SELECT); sMoveSlotToReplace = MAX_MON_MOVES; gSpecialVar_0x8005 = MAX_MON_MOVES; + gSpecialVar_Result = FALSE; BeginCloseSummaryScreen(taskId); } } @@ -3456,7 +3443,7 @@ static void PutPageWindowTilemaps(u8 page) case PSS_PAGE_BATTLE_MOVES: PutWindowTilemap(PSS_LABEL_WINDOW_BATTLE_MOVES_TITLE); PutWindowTilemap(PSS_LABEL_WINDOW_PROMPT_UTILITY); - if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE || sMonSummaryScreen->mode == SUMMARY_MODE_BOX_SELECT_MOVE) + if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE) { if (sMonSummaryScreen->newMove != MOVE_NONE || sMonSummaryScreen->firstMoveIndex != MAX_MON_MOVES) PutWindowTilemap(PSS_LABEL_WINDOW_MOVES_POWER_ACC); @@ -3470,7 +3457,7 @@ static void PutPageWindowTilemaps(u8 page) case PSS_PAGE_CONTEST_MOVES: PutWindowTilemap(PSS_LABEL_WINDOW_CONTEST_MOVES_TITLE); PutWindowTilemap(PSS_LABEL_WINDOW_PROMPT_UTILITY); - if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE || sMonSummaryScreen->mode == SUMMARY_MODE_BOX_SELECT_MOVE) + if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE) { if (sMonSummaryScreen->newMove != MOVE_NONE || sMonSummaryScreen->firstMoveIndex != MAX_MON_MOVES) PutWindowTilemap(PSS_LABEL_WINDOW_MOVES_APPEAL_JAM); @@ -3511,7 +3498,7 @@ static void ClearPageWindowTilemaps(u8 page) ClearWindowTilemap(PSS_LABEL_WINDOW_PROMPT_RELEARN); break; case PSS_PAGE_BATTLE_MOVES: - if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE || sMonSummaryScreen->mode == SUMMARY_MODE_BOX_SELECT_MOVE) + if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE) { if (sMonSummaryScreen->newMove != MOVE_NONE || sMonSummaryScreen->firstMoveIndex != MAX_MON_MOVES) { @@ -3523,7 +3510,7 @@ static void ClearPageWindowTilemaps(u8 page) ClearWindowTilemap(PSS_LABEL_WINDOW_PROMPT_RELEARN); break; case PSS_PAGE_CONTEST_MOVES: - if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE || sMonSummaryScreen->mode == SUMMARY_MODE_BOX_SELECT_MOVE) + if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE) { if (sMonSummaryScreen->newMove != MOVE_NONE || sMonSummaryScreen->firstMoveIndex != MAX_MON_MOVES) ClearWindowTilemap(PSS_LABEL_WINDOW_MOVES_APPEAL_JAM); @@ -4098,7 +4085,7 @@ static void PrintBattleMoves(void) PrintMoveNameAndPP(1); PrintMoveNameAndPP(2); PrintMoveNameAndPP(3); - if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE || sMonSummaryScreen->mode == SUMMARY_MODE_BOX_SELECT_MOVE) + if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE) { PrintNewMoveDetailsOrCancelText(); if (sMonSummaryScreen->firstMoveIndex == MAX_MON_MOVES) @@ -4132,11 +4119,11 @@ static void Task_PrintBattleMoves(u8 taskId) PrintMoveNameAndPP(3); break; case 5: - if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE || sMonSummaryScreen->mode == SUMMARY_MODE_BOX_SELECT_MOVE) + if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE) PrintNewMoveDetailsOrCancelText(); break; case 6: - if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE || sMonSummaryScreen->mode == SUMMARY_MODE_BOX_SELECT_MOVE) + if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE) { if (sMonSummaryScreen->firstMoveIndex == MAX_MON_MOVES) data[1] = sMonSummaryScreen->newMove; @@ -4145,7 +4132,7 @@ static void Task_PrintBattleMoves(u8 taskId) } break; case 7: - if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE || sMonSummaryScreen->mode == SUMMARY_MODE_BOX_SELECT_MOVE) + if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE) { if (sMonSummaryScreen->newMove != MOVE_NONE || sMonSummaryScreen->firstMoveIndex != MAX_MON_MOVES) PrintMoveDetails(data[1]); @@ -4235,7 +4222,7 @@ static void PrintContestMoves(void) PrintMoveNameAndPP(2); PrintMoveNameAndPP(3); - if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE || sMonSummaryScreen->mode == SUMMARY_MODE_BOX_SELECT_MOVE) + if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE) { PrintNewMoveDetailsOrCancelText(); PrintContestMoveDescription(sMonSummaryScreen->firstMoveIndex); @@ -4261,11 +4248,11 @@ static void Task_PrintContestMoves(u8 taskId) PrintMoveNameAndPP(3); break; case 5: - if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE || sMonSummaryScreen->mode == SUMMARY_MODE_BOX_SELECT_MOVE) + if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE) PrintNewMoveDetailsOrCancelText(); break; case 6: - if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE || sMonSummaryScreen->mode == SUMMARY_MODE_BOX_SELECT_MOVE) + if (sMonSummaryScreen->mode == SUMMARY_MODE_SELECT_MOVE) { if (sMonSummaryScreen->newMove != MOVE_NONE || sMonSummaryScreen->firstMoveIndex != MAX_MON_MOVES) PrintContestMoveDescription(sMonSummaryScreen->firstMoveIndex); @@ -4864,8 +4851,7 @@ static inline bool32 ShouldShowIvEvPrompt(void) if (P_SUMMARY_SCREEN_IV_EV_BOX_ONLY) { return (P_SUMMARY_SCREEN_IV_EV_INFO || FlagGet(P_FLAG_SUMMARY_SCREEN_IV_EV_INFO)) - && (sMonSummaryScreen->mode == SUMMARY_MODE_BOX || sMonSummaryScreen->mode == SUMMARY_MODE_BOX_CURSOR - || sMonSummaryScreen->mode == SUMMARY_MODE_BOX_RELEARNER_BATTLE || sMonSummaryScreen->mode == SUMMARY_MODE_BOX_RELEARNER_CONTEST); + && (sMonSummaryScreen->mode == SUMMARY_MODE_BOX || sMonSummaryScreen->mode == SUMMARY_MODE_BOX_CURSOR); } else if (!P_SUMMARY_SCREEN_IV_EV_BOX_ONLY) { @@ -4993,33 +4979,11 @@ static void ShowRelearnPrompt(void) static void CB2_ReturnToSummaryScreenFromNamingScreen(void) { - SetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar2); + SetBoxMonData(GetSelectedBoxMonFromPcOrParty(), MON_DATA_NICKNAME, gStringVar2); ShowPokemonSummaryScreen(SUMMARY_MODE_NORMAL, gPlayerParty, gSpecialVar_0x8004, gPlayerPartyCount - 1, gInitialSummaryScreenCallback); } -static void CB2_ReturnToSummaryScreenFromNamingScreenBox(void) -{ - SetBoxMonNickAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, gStringVar2); - ShowPokemonSummaryScreen(SUMMARY_MODE_BOX, GetBoxedMonPtr(gSpecialVar_MonBoxId, 0), gSpecialVar_MonBoxPos, IN_BOX_COUNT - 1, gInitialSummaryScreenCallback); -} - static void CB2_PssChangePokemonNickname(void) { - GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar3); - GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar2); - DoNamingScreen(NAMING_SCREEN_NICKNAME, gStringVar2, GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPECIES, NULL), - GetMonGender(&gPlayerParty[gSpecialVar_0x8004]), GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_PERSONALITY, NULL), - CB2_ReturnToSummaryScreenFromNamingScreen); -} - -static void CB2_PssChangeBoxPokemonNickname(void) -{ - struct BoxPokemon *boxMon; - boxMon = GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos); - GetBoxMonData(boxMon, MON_DATA_NICKNAME, gStringVar3); - GetBoxMonData(boxMon, MON_DATA_NICKNAME, gStringVar2); - DoNamingScreen(NAMING_SCREEN_NICKNAME, gStringVar2, GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL), - GetBoxMonGender(boxMon), GetBoxMonData(boxMon, MON_DATA_PERSONALITY, NULL), - CB2_ReturnToSummaryScreenFromNamingScreenBox); - + ChangePokemonNicknameWithCallback(CB2_ReturnToSummaryScreenFromNamingScreen); } diff --git a/src/trade.c b/src/trade.c index f9f71ff304..a4e4ebb048 100644 --- a/src/trade.c +++ b/src/trade.c @@ -46,6 +46,7 @@ #include "constants/contest.h" #include "constants/items.h" #include "constants/moves.h" +#include "constants/party_menu.h" #include "constants/region_map_sections.h" #include "constants/rgb.h" #include "constants/songs.h" @@ -2763,30 +2764,12 @@ static u32 TradeGetMultiplayerId(void) return 0; } -static void LoadTradeMonPic(u8 whichParty, u8 state) +static void LoadTradeMonPic(struct Pokemon *mon, u8 state) { - int pos = 0; - struct Pokemon *mon = NULL; - u16 species = SPECIES_NONE; - u32 personality; - - if (whichParty == TRADE_PLAYER) - { - if(gSpecialVar_MonBoxId == 0xFF) - mon = &gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]]; - else - mon = &gEnemyParty[gSelectedTradeMonPositions[TRADE_PLAYER]]; - pos = B_POSITION_OPPONENT_LEFT; - } - - if (whichParty == TRADE_PARTNER) - { - mon = &gEnemyParty[gSelectedTradeMonPositions[TRADE_PARTNER] % PARTY_SIZE]; - pos = B_POSITION_OPPONENT_RIGHT; - } + u32 species, personality; + u32 whichParty = state / 2; species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG); - - switch (state) + switch (state % 2) { case 0: personality = GetMonData(mon, MON_DATA_PERSONALITY); @@ -2798,12 +2781,13 @@ static void LoadTradeMonPic(u8 whichParty, u8 state) sTradeAnim->monPersonalities[whichParty] = personality; break; case 1: - SetMultiuseSpriteTemplateToPokemon(species, pos); + SetMultiuseSpriteTemplateToPokemon(species, whichParty * 2 + B_POSITION_OPPONENT_LEFT); sTradeAnim->monSpriteIds[whichParty] = CreateSprite(&gMultiuseSpriteTemplate, 120, 60, 6); gSprites[sTradeAnim->monSpriteIds[whichParty]].invisible = TRUE; gSprites[sTradeAnim->monSpriteIds[whichParty]].callback = SpriteCallbackDummy; break; } + } void CB2_LinkTrade(void) @@ -2887,19 +2871,19 @@ void CB2_LinkTrade(void) sTradeAnim->playerFinishStatus = 0; sTradeAnim->partnerFinishStatus = 0; sTradeAnim->scheduleLinkTransfer = 0; - LoadTradeMonPic(TRADE_PLAYER, 0); + LoadTradeMonPic(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], 0); gMain.state++; break; case 6: - LoadTradeMonPic(TRADE_PLAYER, 1); + LoadTradeMonPic(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], 1); gMain.state++; break; case 7: - LoadTradeMonPic(TRADE_PARTNER, 0); + LoadTradeMonPic(&gEnemyParty[gSelectedTradeMonPositions[TRADE_PARTNER] % PARTY_SIZE], 2); gMain.state++; break; case 8: - LoadTradeMonPic(TRADE_PARTNER, 1); + LoadTradeMonPic(&gEnemyParty[gSelectedTradeMonPositions[TRADE_PARTNER] % PARTY_SIZE], 3); LinkTradeDrawWindow(); gMain.state++; break; @@ -2973,17 +2957,24 @@ static void CB2_InitInGameTrade(void) { u8 otName[11]; + struct Pokemon *playerMon; + if (gSpecialVar_0x8004 == PC_MON_CHOSEN) + playerMon = &gEnemyParty[TRADEMON_FROM_PC]; + else + playerMon = &gPlayerParty[gSpecialVar_0x8004]; + switch (gMain.state) { case 0: - //If not in the party then we're using ChooseBoxMon, a bit easier to chnage it into a Mon now and store in gEnemyParty - if(gSpecialVar_MonBoxId == 0xFF) - gSelectedTradeMonPositions[TRADE_PLAYER] = gSpecialVar_0x8005; + //If ChooseBoxMon points to a pc mon, we store it into gEnemyParty + if(gSpecialVar_0x8004 == PC_MON_CHOSEN) + { + gSelectedTradeMonPositions[TRADE_PLAYER] = TRADEMON_FROM_PC; + RemoveSelectedPcMon(&gEnemyParty[TRADEMON_FROM_PC]); + } else { - gSelectedTradeMonPositions[TRADE_PLAYER] = 1; - BoxMonToMon(&gPokemonStoragePtr->boxes[gSpecialVar_MonBoxId][gSpecialVar_0x8005], &gEnemyParty[1]); - ZeroBoxMonData(&gPokemonStoragePtr->boxes[gSpecialVar_MonBoxId][gSpecialVar_0x8005]); + gSelectedTradeMonPositions[TRADE_PLAYER] = gSpecialVar_0x8004; } gSelectedTradeMonPositions[TRADE_PARTNER] = PARTY_SIZE; StringCopy(gLinkPlayers[0].name, gSaveBlock2Ptr->playerName); @@ -3013,20 +3004,20 @@ static void CB2_InitInGameTrade(void) gMain.state = 5; break; case 5: - LoadTradeMonPic(TRADE_PLAYER, 0); + LoadTradeMonPic(playerMon, 0); gMain.state++; break; case 6: - LoadTradeMonPic(TRADE_PLAYER, 1); + LoadTradeMonPic(playerMon, 1); gMain.state++; break; case 7: - LoadTradeMonPic(TRADE_PARTNER, 0); + LoadTradeMonPic(&gEnemyParty[0], 2); ShowBg(0); gMain.state++; break; case 8: - LoadTradeMonPic(TRADE_PARTNER, 1); + LoadTradeMonPic(&gEnemyParty[0], 3); FillWindowPixelBuffer(0, PIXEL_FILL(15)); PutWindowTilemap(0); CopyWindowToVram(0, COPYWIN_FULL); @@ -3062,7 +3053,11 @@ static void CB2_InitInGameTrade(void) static void UpdatePokedexForReceivedMon(u8 partyIdx) { - struct Pokemon *mon = &gPlayerParty[partyIdx]; + struct Pokemon *mon; + if (partyIdx == PC_MON_CHOSEN) + mon = &gEnemyParty[TRADEMON_FROM_PC]; + else + mon = &gPlayerParty[partyIdx]; if (!GetMonData(mon, MON_DATA_IS_EGG)) { @@ -3086,11 +3081,14 @@ static void TryEnableNationalDexFromLinkPartner(void) static void TradeMons(u8 playerPartyIdx, u8 partnerPartyIdx) { u8 friendship; + struct Pokemon *playerMon, *partnerMon; + if (playerPartyIdx == PC_MON_CHOSEN) + playerMon = &gEnemyParty[TRADEMON_FROM_PC]; + else + playerMon = &gPlayerParty[playerPartyIdx]; - struct Pokemon *playerMon = &gPlayerParty[playerPartyIdx]; u16 playerMail = GetMonData(playerMon, MON_DATA_MAIL); - - struct Pokemon *partnerMon = &gEnemyParty[partnerPartyIdx]; + partnerMon = &gEnemyParty[partnerPartyIdx]; u16 partnerMail = GetMonData(partnerMon, MON_DATA_MAIL); // The mail attached to the sent Pokémon no longer exists in your file. @@ -3106,9 +3104,21 @@ static void TradeMons(u8 playerPartyIdx, u8 partnerPartyIdx) SetMonData(playerMon, MON_DATA_FRIENDSHIP, &friendship); if (partnerMail != MAIL_NONE) - GiveMailToMon(playerMon, &gTradeMail[partnerMail]); - + { + if (playerPartyIdx == PC_MON_CHOSEN) + { + //TODO: add message explaining mail has been send to PC OR couldn't be saved + SaveMailToPC(&gTradeMail[partnerMail]); + TakeMailFromMon(playerMon); + } + else + { + GiveMailToMon(playerMon, &gTradeMail[partnerMail]); + } + } UpdatePokedexForReceivedMon(playerPartyIdx); + if (playerPartyIdx == PC_MON_CHOSEN) + CopyMonToPC(playerMon); if (gReceivedRemoteLinkPlayers) TryEnableNationalDexFromLinkPartner(); } @@ -3328,13 +3338,13 @@ static void BufferTradeSceneStrings(void) } else { - ingameTrade = &sIngameTrades[gSpecialVar_0x8004]; + ingameTrade = &sIngameTrades[gSpecialVar_0x8005]; StringCopy(gStringVar1, ingameTrade->otName); StringCopy_Nickname(gStringVar3, ingameTrade->nickname); - if(gSpecialVar_MonBoxId == 0xFF) - GetMonData(&gPlayerParty[gSpecialVar_0x8005], MON_DATA_NICKNAME, name); + if(gSpecialVar_0x8004 == PC_MON_CHOSEN) + GetMonData(&gEnemyParty[TRADEMON_FROM_PC], MON_DATA_NICKNAME, name); else - GetMonData(&gEnemyParty[1], MON_DATA_NICKNAME, name); + GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, name); StringCopy_Nickname(gStringVar2, name); } } @@ -4358,23 +4368,19 @@ static bool8 DoTradeAnim_Wireless(void) sTradeAnim->state++; break; case STATE_TRY_EVOLUTION: // Only if in-game trade, link trades use CB2_TryLinkTradeEvolution - if(gSpecialVar_MonBoxId == 0xFF) - TradeMons(gSpecialVar_0x8005, 0); - else - { - if(CalculatePartyCount(gPlayerParty) < PARTY_SIZE) - CopyMon(&gPlayerParty[CalculatePartyCount(gPlayerParty)],&gEnemyParty[0],100); - else - CopyMonToPC(&gEnemyParty[0]); - } + TradeMons(gSpecialVar_0x8004, 0); gCB2_AfterEvolution = CB2_InGameTrade; - evoTarget = GetEvolutionTargetSpecies(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], EVO_MODE_TRADE, ITEM_NONE, &gEnemyParty[0], NULL, CHECK_EVO); + struct Pokemon *canEvolveMon; + if (gSpecialVar_0x8004 == PC_MON_CHOSEN) + canEvolveMon = &gEnemyParty[TRADEMON_FROM_PC]; + else + canEvolveMon = &gPlayerParty[gSpecialVar_0x8004]; + evoTarget = GetEvolutionTargetSpecies(canEvolveMon, EVO_MODE_TRADE, ITEM_NONE, &gEnemyParty[0], NULL, CHECK_EVO); if (evoTarget != SPECIES_NONE) { - GetEvolutionTargetSpecies(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], EVO_MODE_TRADE, ITEM_NONE, &gEnemyParty[0], NULL, DO_EVO); - TradeEvolutionScene(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], evoTarget, sTradeAnim->monSpriteIds[TRADE_PARTNER], gSelectedTradeMonPositions[TRADE_PLAYER]); + GetEvolutionTargetSpecies(canEvolveMon, EVO_MODE_TRADE, ITEM_NONE, &gEnemyParty[0], NULL, DO_EVO); + TradeEvolutionScene(canEvolveMon, evoTarget, sTradeAnim->monSpriteIds[TRADE_PARTNER], gSpecialVar_0x8004); } - sTradeAnim->state++; break; case STATE_FADE_OUT_END: @@ -4536,7 +4542,7 @@ static void SpriteCB_BouncingPokeballArrive(struct Sprite *sprite) u16 GetInGameTradeSpeciesInfo(void) { - const struct InGameTrade *inGameTrade = &sIngameTrades[gSpecialVar_0x8004]; + const struct InGameTrade *inGameTrade = &sIngameTrades[gSpecialVar_0x8005]; StringCopy(gStringVar1, GetSpeciesName(inGameTrade->requestedSpecies)); StringCopy(gStringVar2, GetSpeciesName(inGameTrade->species)); return inGameTrade->requestedSpecies; @@ -4545,7 +4551,7 @@ u16 GetInGameTradeSpeciesInfo(void) static void BufferInGameTradeMonName(void) { u8 nickname[max(32, POKEMON_NAME_BUFFER_SIZE)]; - const struct InGameTrade *inGameTrade = &sIngameTrades[gSpecialVar_0x8004]; + const struct InGameTrade *inGameTrade = &sIngameTrades[gSpecialVar_0x8005]; GetMonData(&gPlayerParty[gSpecialVar_0x8005], MON_DATA_NICKNAME, nickname); StringCopy_Nickname(gStringVar1, nickname); StringCopy(gStringVar2, GetSpeciesName(inGameTrade->species)); @@ -4554,11 +4560,8 @@ static void BufferInGameTradeMonName(void) static void CreateInGameTradePokemonInternal(u8 whichPlayerMon, u8 whichInGameTrade) { const struct InGameTrade *inGameTrade = &sIngameTrades[whichInGameTrade]; - u8 level; - if(gSpecialVar_MonBoxId == 0xFF) - level = GetMonData(&gPlayerParty[whichPlayerMon], MON_DATA_LEVEL); - else - level = GetBoxMonLevelAt(gSpecialVar_MonBoxId, whichPlayerMon); + struct BoxPokemon *boxmon = GetSelectedBoxMonFromPcOrParty(); + u32 level = GetLevelFromBoxMonExp(boxmon); struct Mail mail; metloc_u8_t metLocation = METLOC_IN_GAME_TRADE; @@ -4624,23 +4627,16 @@ static void GetInGameTradeMail(struct Mail *mail, const struct InGameTrade *trad u16 GetTradeSpecies(void) { - if(gSpecialVar_MonBoxId == 0xFF) - { - if (GetMonData(&gPlayerParty[gSpecialVar_0x8005], MON_DATA_IS_EGG)) - return SPECIES_NONE; - return GetMonData(&gPlayerParty[gSpecialVar_0x8005], MON_DATA_SPECIES); - } - else - { - if (GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_0x8005, MON_DATA_IS_EGG)) - return SPECIES_NONE; - return GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_0x8005, MON_DATA_SPECIES); - } + struct BoxPokemon *boxmon = GetSelectedBoxMonFromPcOrParty(); + if (GetBoxMonData(boxmon, MON_DATA_IS_EGG)) + return SPECIES_NONE; + u32 species = GetBoxMonData(boxmon, MON_DATA_SPECIES); + return species; } void CreateInGameTradePokemon(void) { - CreateInGameTradePokemonInternal(gSpecialVar_0x8005, gSpecialVar_0x8004); + CreateInGameTradePokemonInternal(gSpecialVar_0x8004, gSpecialVar_0x8005); } static void CB2_UpdateLinkTrade(void) diff --git a/src/tv.c b/src/tv.c index af8a44eeb5..1a508de813 100644 --- a/src/tv.c +++ b/src/tv.c @@ -1534,26 +1534,28 @@ void TryPutSmartShopperOnAir(void) void PutNameRaterShowOnTheAir(void) { TVShow *show; + struct BoxPokemon *boxmon; InterviewBefore_NameRater(); if (gSpecialVar_Result != 1) { - GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar1); + boxmon = GetSelectedBoxMonFromPcOrParty(); + GetBoxMonData(boxmon, MON_DATA_NICKNAME, gStringVar1); if (StringLength(gSaveBlock2Ptr->playerName) > 1 && StringLength(gStringVar1) > 1) { show = &gSaveBlock1Ptr->tvShows[sCurTVShowSlot]; show->nameRaterShow.kind = TVSHOW_NAME_RATER_SHOW; show->nameRaterShow.active = TRUE; - show->nameRaterShow.species = GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPECIES); + show->nameRaterShow.species = GetBoxMonData(boxmon, MON_DATA_SPECIES); show->nameRaterShow.random = Random() % 3; show->nameRaterShow.random2 = Random() % 2; show->nameRaterShow.randomSpecies = GetRandomDifferentSpeciesSeenByPlayer(show->nameRaterShow.species); StringCopy(show->nameRaterShow.trainerName, gSaveBlock2Ptr->playerName); - GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME10, show->nameRaterShow.pokemonName); + GetBoxMonData(boxmon, MON_DATA_NICKNAME10, show->nameRaterShow.pokemonName); StripExtCtrlCodes(show->nameRaterShow.pokemonName); StorePlayerIdInNormalShow(show); show->nameRaterShow.language = gGameLanguage; - show->nameRaterShow.pokemonNameLanguage = GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_LANGUAGE); + show->nameRaterShow.pokemonNameLanguage = GetBoxMonData(boxmon, MON_DATA_LANGUAGE); } } } @@ -3262,7 +3264,7 @@ bool8 IsTVShowAlreadyInQueue(void) bool8 TryPutNameRaterShowOnTheAir(void) { - GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar1); + GetBoxMonData(GetSelectedBoxMonFromPcOrParty(), MON_DATA_NICKNAME, gStringVar1); // Nickname wasnt changed if (!StringCompare(gStringVar3, gStringVar1)) @@ -3272,61 +3274,31 @@ bool8 TryPutNameRaterShowOnTheAir(void) return TRUE; } -void ChangePokemonNickname(void) -{ - void ChangePokemonNickname_CB(void); - - GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar3); - GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar2); - DoNamingScreen(NAMING_SCREEN_NICKNAME, gStringVar2, GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPECIES), GetMonGender(&gPlayerParty[gSpecialVar_0x8004]), GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_PERSONALITY), ChangePokemonNickname_CB); -} - -void ChangePokemonNickname_CB(void) -{ - SetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar2); - CB2_ReturnToFieldContinueScriptPlayMapMusic(); -} - -void ChangeBoxPokemonNickname(void) -{ - struct BoxPokemon *boxMon; - - boxMon = GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos); - GetBoxMonData(boxMon, MON_DATA_NICKNAME, gStringVar3); - GetBoxMonData(boxMon, MON_DATA_NICKNAME, gStringVar2); - DoNamingScreen(NAMING_SCREEN_NICKNAME, gStringVar2, GetBoxMonData(boxMon, MON_DATA_SPECIES), GetBoxMonGender(boxMon), GetBoxMonData(boxMon, MON_DATA_PERSONALITY), ChangeBoxPokemonNickname_CB); -} - static void ChangeBoxPokemonNickname_CB(void) { - SetBoxMonNickAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, gStringVar2); + SetBoxMonData(GetSelectedBoxMonFromPcOrParty(), MON_DATA_NICKNAME, gStringVar2); CB2_ReturnToFieldContinueScriptPlayMapMusic(); } +void ChangePokemonNickname(void) +{ + ChangePokemonNicknameWithCallback(ChangeBoxPokemonNickname_CB); +} + void BufferMonNickname(void) { - if(gSpecialVar_MonBoxId == 0xFF) - GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar1); - else - GetBoxMonNickAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, gStringVar1); - StringGet_Nickname(gStringVar1); + struct BoxPokemon *boxmon = GetSelectedBoxMonFromPcOrParty(); + GetBoxMonData(boxmon, MON_DATA_NICKNAME, gStringVar1); + //StringGet_Nickname(gStringVar1); } void IsMonOTIDNotPlayers(void) { - if(gSpecialVar_MonBoxId == 0xFF){ - if (GetPlayerIDAsU32() == GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_OT_ID)) - gSpecialVar_Result = FALSE; - else - gSpecialVar_Result = TRUE; - } - else{ - if (GetPlayerIDAsU32() == GetBoxMonDataAt(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, MON_DATA_OT_ID)) - gSpecialVar_Result = FALSE; - else - gSpecialVar_Result = TRUE; - } - + struct BoxPokemon *boxmon = GetSelectedBoxMonFromPcOrParty(); + if (GetPlayerIDAsU32() == GetBoxMonData(boxmon, MON_DATA_OT_ID)) + gSpecialVar_Result = FALSE; + else + gSpecialVar_Result = TRUE; } static u8 GetTVGroupByShowId(u8 kind) diff --git a/tools/learnset_helpers/make_teachables.py b/tools/learnset_helpers/make_teachables.py index fa0253071e..d95502b662 100644 --- a/tools/learnset_helpers/make_teachables.py +++ b/tools/learnset_helpers/make_teachables.py @@ -121,8 +121,6 @@ def prepare_output(all_learnables: dict[str, set[str]], tms: list[str], tutors: return new - - def prepare_header(h_align: int, tmshms: list[str], tutors: list[str], universals: list[str]) -> str: universals_title = "Near-universal moves found in data/special_movesets.json:" tmhm_title = "TM/HM moves found in \"include/constants/tms_hms.h\":" diff --git a/tools/learnset_helpers/make_tutors.py b/tools/learnset_helpers/make_tutors.py index fc9ad3fc2d..e9167a4e11 100644 --- a/tools/learnset_helpers/make_tutors.py +++ b/tools/learnset_helpers/make_tutors.py @@ -10,7 +10,9 @@ import typing CONFIG_ENABLED_PAT = re.compile(r"#define P_LEARNSET_HELPER_TEACHABLE\s+(?P[^ ]*)") INCFILE_HAS_TUTOR_PAT = re.compile(r"special ChooseMonForMoveTutor") -INCFILE_MOVE_PAT = re.compile(r"setvar VAR_ITEM_ID, (MOVE_.*)") +INCFILE_HAS_TUTOR_PAT2 = re.compile(r"chooseboxmon SELECT_PC_MON_MOVE_TUTOR") +INCFILE_MOVE_PAT = re.compile(r"setvar VAR_0x8005, (MOVE_[A-Z_]*)") +INCFILE_MOVE_PAT2 = re.compile(r"move_tutor (MOVE_[A-Z_]*)") def enabled() -> bool: """ @@ -29,12 +31,15 @@ def extract_repo_tutors() -> typing.Generator[str, None, None]: for inc_fname in chain(glob.glob("./data/scripts/*.inc"), glob.glob("./data/maps/*/scripts.inc")): with open(inc_fname, "r") as inc_fp: incfile = inc_fp.read() - if not INCFILE_HAS_TUTOR_PAT.search(incfile): + if not INCFILE_HAS_TUTOR_PAT.search(incfile) and not INCFILE_HAS_TUTOR_PAT2.search(incfile): continue for move in INCFILE_MOVE_PAT.finditer(incfile): yield move.group(1) + for move in INCFILE_MOVE_PAT2.finditer(incfile): + yield move.group(1) + def dump_output(file, data): with open(file, "w") as fp: fp.write(data)