diff --git a/asm/macros/event.inc b/asm/macros/event.inc index d3c1442f56..7ffdcccf0a 100644 --- a/asm/macros/event.inc +++ b/asm/macros/event.inc @@ -1125,12 +1125,13 @@ .2byte \move .endm - @ Checks if at least one Pokemon in the player's party knows the specified move. If so, VAR_RESULT is set to the + @ Checks if at least one Pokemon in the player's party knows the specified field move and if the field move is unlocked. If so, VAR_RESULT is set to the @ (zero-indexed) slot number of the first Pokemon that knows the move. If not, VAR_RESULT is set to PARTY_SIZE. @ VAR_0x8004 is also set to this Pokemon's species. - .macro checkpartymove move:req - .byte SCR_OP_CHECKPARTYMOVE - .2byte \move + .macro checkfieldmove fieldMove:req, checkUnlocked=FALSE + .byte SCR_OP_CHECKFIELDMOVE + .byte \fieldMove + .byte \checkUnlocked .endm @ Converts STR_VAR_1, STR_VAR_2, or STR_VAR_3 to its corresponding index into sScriptStringVars (0, 1, or 2). diff --git a/data/event_scripts.s b/data/event_scripts.s index db5d329b67..9cedbb04d7 100644 --- a/data/event_scripts.s +++ b/data/event_scripts.s @@ -25,6 +25,7 @@ #include "constants/event_objects.h" #include "constants/event_object_movement.h" #include "constants/field_effects.h" +#include "constants/field_move.h" #include "constants/field_poison.h" #include "constants/field_specials.h" #include "constants/field_tasks.h" diff --git a/data/script_cmd_table.inc b/data/script_cmd_table.inc index 457ff8f670..e05260d3d4 100644 --- a/data/script_cmd_table.inc +++ b/data/script_cmd_table.inc @@ -146,7 +146,7 @@ gScriptCmdTable:: script_cmd_table_entry SCR_OP_GIVEMON ScrCmd_nop1, requests_effects=1 @ 0x79 script_cmd_table_entry SCR_OP_GIVEEGG ScrCmd_giveegg, requests_effects=1 @ 0x7a script_cmd_table_entry SCR_OP_SETMONMOVE ScrCmd_setmonmove, requests_effects=1 @ 0x7b - script_cmd_table_entry SCR_OP_CHECKPARTYMOVE ScrCmd_checkpartymove, requests_effects=1 @ 0x7c + script_cmd_table_entry SCR_OP_CHECKFIELDMOVE ScrCmd_checkfieldmove, requests_effects=1 @ 0x7c script_cmd_table_entry SCR_OP_BUFFERSPECIESNAME ScrCmd_bufferspeciesname, requests_effects=1 @ 0x7d script_cmd_table_entry SCR_OP_BUFFERLEADMONSPECIESNAME ScrCmd_bufferleadmonspeciesname, requests_effects=1 @ 0x7e script_cmd_table_entry SCR_OP_BUFFERPARTYMONNICK ScrCmd_bufferpartymonnick, requests_effects=1 @ 0x7f diff --git a/data/scripts/field_move_scripts.inc b/data/scripts/field_move_scripts.inc index 1845e10297..bfc6958138 100644 --- a/data/scripts/field_move_scripts.inc +++ b/data/scripts/field_move_scripts.inc @@ -1,8 +1,7 @@ @ Interact with cuttable tree EventScript_CutTree:: lockall - goto_if_unset FLAG_BADGE01_GET, EventScript_CheckTreeCantCut - checkpartymove MOVE_CUT + checkfieldmove FIELD_MOVE_CUT, TRUE goto_if_eq VAR_RESULT, PARTY_SIZE, EventScript_CheckTreeCantCut setfieldeffectargument 0, VAR_RESULT bufferpartymonnick STR_VAR_1, VAR_RESULT @@ -64,8 +63,7 @@ EventScript_UseRockSmash:: @ Interact with smashable rock EventScript_RockSmash:: lockall - goto_if_unset FLAG_BADGE03_GET, EventScript_CantSmashRock - checkpartymove MOVE_ROCK_SMASH + checkfieldmove FIELD_MOVE_ROCK_SMASH, TRUE goto_if_eq VAR_RESULT, PARTY_SIZE, EventScript_CantSmashRock setfieldeffectargument 0, VAR_RESULT bufferpartymonnick STR_VAR_1, VAR_RESULT @@ -225,9 +223,8 @@ Text_CantSmash: EventScript_StrengthBoulder:: lockall - goto_if_unset FLAG_BADGE04_GET, EventScript_CantStrength goto_if_set FLAG_SYS_USE_STRENGTH, EventScript_CheckActivatedBoulder - checkpartymove MOVE_STRENGTH + checkfieldmove FIELD_MOVE_STRENGTH, TRUE goto_if_eq VAR_RESULT, PARTY_SIZE, EventScript_CantStrength setfieldeffectargument 0, VAR_RESULT msgbox Text_WantToStrength, MSGBOX_YESNO @@ -286,7 +283,7 @@ Text_StrengthActivated: EventScript_UseWaterfall:: lockall - checkpartymove MOVE_WATERFALL + checkfieldmove FIELD_MOVE_WATERFALL goto_if_eq VAR_RESULT, PARTY_SIZE, EventScript_CantWaterfall bufferpartymonnick STR_VAR_1, VAR_RESULT setfieldeffectargument 0, VAR_RESULT @@ -321,7 +318,7 @@ Text_MonUsedWaterfall: EventScript_UseDive:: lockall - checkpartymove MOVE_DIVE + checkfieldmove FIELD_MOVE_DIVE goto_if_eq VAR_RESULT, PARTY_SIZE, EventScript_CantDive copyvar 0x8004 VAR_RESULT bufferpartymonnick STR_VAR_1, VAR_RESULT @@ -348,7 +345,7 @@ EventScript_EndDive:: EventScript_UseDiveUnderwater:: lockall - checkpartymove MOVE_DIVE + checkfieldmove FIELD_MOVE_DIVE goto_if_eq VAR_RESULT, PARTY_SIZE, EventScript_CantSurface bufferpartymonnick STR_VAR_1, VAR_RESULT setfieldeffectargument 0, VAR_RESULT diff --git a/data/scripts/secret_base.inc b/data/scripts/secret_base.inc index 15faddfa9d..ed5e859409 100644 --- a/data/scripts/secret_base.inc +++ b/data/scripts/secret_base.inc @@ -28,7 +28,7 @@ SecretBase_EventScript_CheckEntrance:: special GetSecretBaseTypeInFrontOfPlayer special CheckPlayerHasSecretBase goto_if_eq VAR_RESULT, TRUE, SecretBase_EventScript_AlreadyHasSecretBase - checkpartymove MOVE_SECRET_POWER + checkfieldmove FIELD_MOVE_SECRET_POWER setfieldeffectargument 0, VAR_RESULT buffermovename STR_VAR_2, MOVE_SECRET_POWER goto_if_eq VAR_0x8007, SECRET_BASE_RED_CAVE, SecretBase_EventScript_Cave @@ -186,7 +186,7 @@ SecretBase_EventScript_EnterPlayersBase:: end SecretBase_EventScript_AlreadyHasSecretBase:: - checkpartymove MOVE_SECRET_POWER + checkfieldmove FIELD_MOVE_SECRET_POWER goto_if_eq VAR_RESULT, PARTY_SIZE, SecretBase_EventScript_NoSecretPower setfieldeffectargument 0, VAR_RESULT setorcopyvar VAR_0x8004, VAR_RESULT diff --git a/data/scripts/surf.inc b/data/scripts/surf.inc index edb116f991..630b3f9e6e 100644 --- a/data/scripts/surf.inc +++ b/data/scripts/surf.inc @@ -1,5 +1,5 @@ EventScript_UseSurf:: - checkpartymove MOVE_SURF + checkfieldmove FIELD_MOVE_SURF goto_if_eq VAR_RESULT, PARTY_SIZE, EventScript_EndUseSurf bufferpartymonnick STR_VAR_1, VAR_RESULT setfieldeffectargument 0, VAR_RESULT diff --git a/include/constants/field_move.h b/include/constants/field_move.h new file mode 100644 index 0000000000..1d0fb83977 --- /dev/null +++ b/include/constants/field_move.h @@ -0,0 +1,28 @@ +#ifndef GUARD_CONSTANTS_FIELD_MOVE_H +#define GUARD_CONSTANTS_FIELD_MOVE_H + + +enum FieldMove +{ + FIELD_MOVE_CUT, + FIELD_MOVE_FLASH, + FIELD_MOVE_ROCK_SMASH, + FIELD_MOVE_STRENGTH, + FIELD_MOVE_SURF, + FIELD_MOVE_FLY, + FIELD_MOVE_DIVE, + FIELD_MOVE_WATERFALL, + FIELD_MOVE_TELEPORT, + FIELD_MOVE_DIG, + FIELD_MOVE_SECRET_POWER, + FIELD_MOVE_MILK_DRINK, + FIELD_MOVE_SOFT_BOILED, + FIELD_MOVE_SWEET_SCENT, +#if OW_DEFOG_FIELD_MOVE == TRUE + FIELD_MOVE_DEFOG, +#endif + FIELD_MOVES_COUNT +}; + + +#endif //GUARD_CONSTANTS_FIELD_MOVE_H diff --git a/include/field_move.h b/include/field_move.h new file mode 100644 index 0000000000..1608b60bcb --- /dev/null +++ b/include/field_move.h @@ -0,0 +1,37 @@ +#ifndef GUARD_FIELD_MOVE_H +#define GUARD_FIELD_MOVE_H + +#include "global.h" +#include "constants/field_move.h" + +struct FieldMoveInfo +{ + bool32 (*fieldMoveFunc)(void); + bool32 (*isUnlockedFunc)(void); + u16 moveID; + u8 partyMsgID; +}; + +extern const struct FieldMoveInfo gFieldMoveInfo[]; + +static inline bool32 SetUpFieldMove(enum FieldMove fieldMove) +{ + return gFieldMoveInfo[fieldMove].fieldMoveFunc(); +} + +static inline bool32 IsFieldMoveUnlocked(enum FieldMove fieldMove) +{ + return gFieldMoveInfo[fieldMove].isUnlockedFunc(); +} + +static inline u32 FieldMove_GetMoveId(enum FieldMove fieldMove) +{ + return gFieldMoveInfo[fieldMove].moveID; +} + +static inline u32 FieldMove_GetPartyMsgID(enum FieldMove fieldMove) +{ + return gFieldMoveInfo[fieldMove].partyMsgID; +} + +#endif //GUARD_FIELD_MOVE_H diff --git a/include/fldeff.h b/include/fldeff.h index 9bad320c74..d1b9e279c3 100644 --- a/include/fldeff.h +++ b/include/fldeff.h @@ -2,7 +2,7 @@ #define GUARD_FLDEFF_H // cut -bool8 SetUpFieldMove_Cut(void); +bool32 SetUpFieldMove_Cut(void); bool8 FldEff_UseCutOnGrass(void); bool8 FldEff_UseCutOnTree(void); bool8 FldEff_CutGrass(void); @@ -18,41 +18,41 @@ void StopEscalator(void); bool8 IsEscalatorMoving(void); // soft-boiled -bool8 SetUpFieldMove_SoftBoiled(void); +bool32 SetUpFieldMove_SoftBoiled(void); void Task_TryUseSoftboiledOnPartyMon(u8 taskId); void ChooseMonForSoftboiled(u8 taskId); // flash -bool8 SetUpFieldMove_Flash(void); +bool32 SetUpFieldMove_Flash(void); void CB2_DoChangeMap(void); bool8 GetMapPairFadeToType(u8 _fromType, u8 _toType); bool8 GetMapPairFadeFromType(u8 _fromType, u8 _toType); // strength -bool8 SetUpFieldMove_Strength(void); +bool32 SetUpFieldMove_Strength(void); bool8 FldEff_UseStrength(void); // sweet scent -bool8 SetUpFieldMove_SweetScent(void); +bool32 SetUpFieldMove_SweetScent(void); bool8 FldEff_SweetScent(void); void StartSweetScentFieldEffect(void); // teleport -bool8 SetUpFieldMove_Teleport(void); +bool32 SetUpFieldMove_Teleport(void); bool8 FldEff_UseTeleport(void); // dig -bool8 SetUpFieldMove_Dig(void); +bool32 SetUpFieldMove_Dig(void); bool8 FldEff_UseDig(void); // rock smash bool8 CheckObjectGraphicsInFrontOfPlayer(u16 graphicsId); u8 CreateFieldMoveTask(void); -bool8 SetUpFieldMove_RockSmash(void); +bool32 SetUpFieldMove_RockSmash(void); bool8 FldEff_UseRockSmash(void); // defog -bool8 SetUpFieldMove_Defog(void); +bool32 SetUpFieldMove_Defog(void); bool8 FldEff_Defog(void); #endif // GUARD_FLDEFF_H diff --git a/include/fldeff_misc.h b/include/fldeff_misc.h index 61078466db..71fef15005 100644 --- a/include/fldeff_misc.h +++ b/include/fldeff_misc.h @@ -5,7 +5,7 @@ void ComputerScreenOpenEffect(u16 increment, u16 unused, u8 priority); void ComputerScreenCloseEffect(u16 increment, u16 unused, u8 priority); bool8 IsComputerScreenOpenEffectActive(void); bool8 IsComputerScreenCloseEffectActive(void); -bool8 SetUpFieldMove_SecretPower(void); +bool32 SetUpFieldMove_SecretPower(void); bool8 FldEff_UseSecretPowerCave(void); bool8 FldEff_SecretPowerCave(void); bool8 FldEff_UseSecretPowerTree(void); diff --git a/include/party_menu.h b/include/party_menu.h index 7c4af8c3a4..5aa9472dac 100644 --- a/include/party_menu.h +++ b/include/party_menu.h @@ -106,4 +106,9 @@ void BufferMoveDeleterNicknameAndMove(void); void GetNumMovesSelectedMonHas(void); void MoveDeleterChooseMoveToForget(void); +bool32 SetUpFieldMove_Surf(void); +bool32 SetUpFieldMove_Fly(void); +bool32 SetUpFieldMove_Waterfall(void); +bool32 SetUpFieldMove_Dive(void); + #endif // GUARD_PARTY_MENU_H diff --git a/src/data/party_menu.h b/src/data/party_menu.h index f8860ac4b0..655264f02d 100644 --- a/src/data/party_menu.h +++ b/src/data/party_menu.h @@ -785,55 +785,6 @@ static const u8 sPartyMenuActionCounts[] = [ACTIONS_ZYGARDE_CUBE] = ARRAY_COUNT(sPartyMenuAction_ZygardeCube), }; -static const u16 sFieldMoves[FIELD_MOVES_COUNT + 1] = -{ - [FIELD_MOVE_CUT] = MOVE_CUT, - [FIELD_MOVE_FLASH] = MOVE_FLASH, - [FIELD_MOVE_ROCK_SMASH] = MOVE_ROCK_SMASH, - [FIELD_MOVE_STRENGTH] = MOVE_STRENGTH, - [FIELD_MOVE_SURF] = MOVE_SURF, - [FIELD_MOVE_FLY] = MOVE_FLY, - [FIELD_MOVE_DIVE] = MOVE_DIVE, - [FIELD_MOVE_WATERFALL] = MOVE_WATERFALL, - [FIELD_MOVE_TELEPORT] = MOVE_TELEPORT, - [FIELD_MOVE_DIG] = MOVE_DIG, - [FIELD_MOVE_SECRET_POWER] = MOVE_SECRET_POWER, - [FIELD_MOVE_MILK_DRINK] = MOVE_MILK_DRINK, - [FIELD_MOVE_SOFT_BOILED] = MOVE_SOFT_BOILED, - [FIELD_MOVE_SWEET_SCENT] = MOVE_SWEET_SCENT, -#if OW_DEFOG_FIELD_MOVE == TRUE - [FIELD_MOVE_DEFOG] = MOVE_DEFOG, -#endif - // NOTE: This value is used as the terminal value for the table. There's no reason to do this, as the size of the table is known. - // Whichever move shares this value (MOVE_SWORDS_DANCE by default) if present will be treated as the end of the array rather than a field move. - [FIELD_MOVES_COUNT] = FIELD_MOVES_COUNT -}; - -struct -{ - bool8 (*fieldMoveFunc)(void); - u8 msgId; -} static const sFieldMoveCursorCallbacks[FIELD_MOVES_COUNT] = -{ - [FIELD_MOVE_CUT] = {SetUpFieldMove_Cut, PARTY_MSG_NOTHING_TO_CUT}, - [FIELD_MOVE_FLASH] = {SetUpFieldMove_Flash, PARTY_MSG_CANT_USE_HERE}, - [FIELD_MOVE_ROCK_SMASH] = {SetUpFieldMove_RockSmash, PARTY_MSG_CANT_USE_HERE}, - [FIELD_MOVE_STRENGTH] = {SetUpFieldMove_Strength, PARTY_MSG_CANT_USE_HERE}, - [FIELD_MOVE_SURF] = {SetUpFieldMove_Surf, PARTY_MSG_CANT_SURF_HERE}, - [FIELD_MOVE_FLY] = {SetUpFieldMove_Fly, PARTY_MSG_CANT_USE_HERE}, - [FIELD_MOVE_DIVE] = {SetUpFieldMove_Dive, PARTY_MSG_CANT_USE_HERE}, - [FIELD_MOVE_WATERFALL] = {SetUpFieldMove_Waterfall, PARTY_MSG_CANT_USE_HERE}, - [FIELD_MOVE_TELEPORT] = {SetUpFieldMove_Teleport, PARTY_MSG_CANT_USE_HERE}, - [FIELD_MOVE_DIG] = {SetUpFieldMove_Dig, PARTY_MSG_CANT_USE_HERE}, - [FIELD_MOVE_SECRET_POWER] = {SetUpFieldMove_SecretPower, PARTY_MSG_CANT_USE_HERE}, - [FIELD_MOVE_MILK_DRINK] = {SetUpFieldMove_SoftBoiled, PARTY_MSG_NOT_ENOUGH_HP}, - [FIELD_MOVE_SOFT_BOILED] = {SetUpFieldMove_SoftBoiled, PARTY_MSG_NOT_ENOUGH_HP}, - [FIELD_MOVE_SWEET_SCENT] = {SetUpFieldMove_SweetScent, PARTY_MSG_CANT_USE_HERE}, -#if OW_DEFOG_FIELD_MOVE == TRUE - [FIELD_MOVE_DEFOG] = {SetUpFieldMove_Defog, PARTY_MSG_CANT_USE_HERE}, -#endif -}; - static const u8 *const sUnionRoomTradeMessages[] = { [UR_TRADE_MSG_NOT_MON_PARTNER_WANTS - 1] = gText_NotPkmnOtherTrainerWants, diff --git a/src/field_control_avatar.c b/src/field_control_avatar.c index a83990cc58..1cc1f8e122 100644 --- a/src/field_control_avatar.c +++ b/src/field_control_avatar.c @@ -12,6 +12,7 @@ #include "fieldmap.h" #include "field_control_avatar.h" #include "field_message_box.h" +#include "field_move.h" #include "field_player_avatar.h" #include "field_poison.h" #include "field_screen_effect.h" @@ -560,7 +561,7 @@ static const u8 *GetInteractedMetatileScript(struct MapPosition *position, u8 me static const u8 *GetInteractedWaterScript(struct MapPosition *unused1, u8 metatileBehavior, u8 direction) { - if (FlagGet(FLAG_BADGE05_GET) == TRUE && PartyHasMonWithSurf() == TRUE && IsPlayerFacingSurfableFishableWater() == TRUE + if (IsFieldMoveUnlocked(FIELD_MOVE_SURF) && PartyHasMonWithSurf() == TRUE && IsPlayerFacingSurfableFishableWater() == TRUE && CheckFollowerNPCFlag(FOLLOWER_NPC_FLAG_CAN_SURF) ) return EventScript_UseSurf; @@ -569,7 +570,7 @@ static const u8 *GetInteractedWaterScript(struct MapPosition *unused1, u8 metati && CheckFollowerNPCFlag(FOLLOWER_NPC_FLAG_CAN_WATERFALL) ) { - if (FlagGet(FLAG_BADGE08_GET) == TRUE && IsPlayerSurfingNorth() == TRUE) + if (IsFieldMoveUnlocked(FIELD_MOVE_WATERFALL) && IsPlayerSurfingNorth() == TRUE) return EventScript_UseWaterfall; else return EventScript_CannotUseWaterfall; @@ -582,7 +583,7 @@ static bool32 TrySetupDiveDownScript(void) if (!CheckFollowerNPCFlag(FOLLOWER_NPC_FLAG_CAN_DIVE)) return FALSE; - if (FlagGet(FLAG_BADGE07_GET) && TrySetDiveWarp() == 2) + if (IsFieldMoveUnlocked(FIELD_MOVE_DIVE) && TrySetDiveWarp() == 2) { ScriptContext_SetupScript(EventScript_UseDive); return TRUE; @@ -595,7 +596,7 @@ static bool32 TrySetupDiveEmergeScript(void) if (!CheckFollowerNPCFlag(FOLLOWER_NPC_FLAG_CAN_DIVE)) return FALSE; - if (FlagGet(FLAG_BADGE07_GET) && gMapHeader.mapType == MAP_TYPE_UNDERWATER && TrySetDiveWarp() == 1) + if (IsFieldMoveUnlocked(FIELD_MOVE_DIVE) && gMapHeader.mapType == MAP_TYPE_UNDERWATER && TrySetDiveWarp() == 1) { ScriptContext_SetupScript(EventScript_UseDiveUnderwater); return TRUE; diff --git a/src/field_move.c b/src/field_move.c new file mode 100644 index 0000000000..ff9c986436 --- /dev/null +++ b/src/field_move.c @@ -0,0 +1,212 @@ +#include "global.h" +#include "event_data.h" +#include "field_move.h" +#include "fldeff.h" +#include "fldeff_misc.h" +#include "party_menu.h" +#include "constants/field_move.h" +#include "constants/moves.h" +#include "constants/party_menu.h" + +static bool32 IsFieldMoveUnlocked_Cut(void) +{ + return FlagGet(FLAG_BADGE01_GET); +} + +static bool32 IsFieldMoveUnlocked_Flash(void) +{ + return FlagGet(FLAG_BADGE02_GET); +} + +static bool32 IsFieldMoveUnlocked_RockSmash(void) +{ + return FlagGet(FLAG_BADGE03_GET); +} + +static bool32 IsFieldMoveUnlocked_Strength(void) +{ + return FlagGet(FLAG_BADGE04_GET); +} + +static bool32 IsFieldMoveUnlocked_Surf(void) +{ + return FlagGet(FLAG_BADGE05_GET); +} + +static bool32 IsFieldMoveUnlocked_Fly(void) +{ + return FlagGet(FLAG_BADGE06_GET); +} + +static bool32 IsFieldMoveUnlocked_Dive(void) +{ + return FlagGet(FLAG_BADGE07_GET); +} + +static bool32 IsFieldMoveUnlocked_Waterfall(void) +{ + return FlagGet(FLAG_BADGE08_GET); +} + +static bool32 IsFieldMoveUnlocked_Teleport(void) +{ + return TRUE; +} + +static bool32 IsFieldMoveUnlocked_Dig(void) +{ + return TRUE; +} + +static bool32 IsFieldMoveUnlocked_SecretPower(void) +{ + return TRUE; +} + +static bool32 IsFieldMoveUnlocked_MilkDrink(void) +{ + return TRUE; +} + +static bool32 IsFieldMoveUnlocked_SoftBoiled(void) +{ + return TRUE; +} + +static bool32 IsFieldMoveUnlocked_SweetScent(void) +{ + return TRUE; +} + +#if OW_DEFOG_FIELD_MOVE == TRUE +static bool32 IsFieldMoveUnlocked_Defog(void) +{ + return TRUE; +} +#endif + +const struct FieldMoveInfo gFieldMoveInfo[FIELD_MOVES_COUNT] = +{ + [FIELD_MOVE_CUT] = + { + .fieldMoveFunc = SetUpFieldMove_Cut, + .isUnlockedFunc = IsFieldMoveUnlocked_Cut, + .moveID = MOVE_CUT, + .partyMsgID = PARTY_MSG_NOTHING_TO_CUT, + }, + + [FIELD_MOVE_FLASH] = + { + .fieldMoveFunc = SetUpFieldMove_Flash, + .isUnlockedFunc = IsFieldMoveUnlocked_Flash, + .moveID = MOVE_FLASH, + .partyMsgID = PARTY_MSG_CANT_USE_HERE, + }, + + [FIELD_MOVE_ROCK_SMASH] = + { + .fieldMoveFunc = SetUpFieldMove_RockSmash, + .isUnlockedFunc = IsFieldMoveUnlocked_RockSmash, + .moveID = MOVE_ROCK_SMASH, + .partyMsgID = PARTY_MSG_CANT_USE_HERE, + }, + + [FIELD_MOVE_STRENGTH] = + { + .fieldMoveFunc = SetUpFieldMove_Strength, + .isUnlockedFunc = IsFieldMoveUnlocked_Strength, + .moveID = MOVE_STRENGTH, + .partyMsgID = PARTY_MSG_CANT_USE_HERE, + }, + + [FIELD_MOVE_SURF] = + { + .fieldMoveFunc = SetUpFieldMove_Surf, + .isUnlockedFunc = IsFieldMoveUnlocked_Surf, + .moveID = MOVE_SURF, + .partyMsgID = PARTY_MSG_CANT_SURF_HERE, + }, + + [FIELD_MOVE_FLY] = + { + .fieldMoveFunc = SetUpFieldMove_Fly, + .isUnlockedFunc = IsFieldMoveUnlocked_Fly, + .moveID = MOVE_FLY, + .partyMsgID = PARTY_MSG_CANT_USE_HERE, + }, + + [FIELD_MOVE_DIVE] = + { + .fieldMoveFunc = SetUpFieldMove_Dive, + .isUnlockedFunc = IsFieldMoveUnlocked_Dive, + .moveID = MOVE_DIVE, + .partyMsgID = PARTY_MSG_CANT_USE_HERE, + }, + + [FIELD_MOVE_WATERFALL] = + { + .fieldMoveFunc = SetUpFieldMove_Waterfall, + .isUnlockedFunc = IsFieldMoveUnlocked_Waterfall, + .moveID = MOVE_WATERFALL, + .partyMsgID = PARTY_MSG_CANT_USE_HERE, + }, + + [FIELD_MOVE_TELEPORT] = + { + .fieldMoveFunc = SetUpFieldMove_Teleport, + .isUnlockedFunc = IsFieldMoveUnlocked_Teleport, + .moveID = MOVE_TELEPORT, + .partyMsgID = PARTY_MSG_CANT_USE_HERE, + }, + + [FIELD_MOVE_DIG] = + { + .fieldMoveFunc = SetUpFieldMove_Dig, + .isUnlockedFunc = IsFieldMoveUnlocked_Dig, + .moveID = MOVE_DIG, + .partyMsgID = PARTY_MSG_CANT_USE_HERE, + }, + + [FIELD_MOVE_SECRET_POWER] = + { + .fieldMoveFunc = SetUpFieldMove_SecretPower, + .isUnlockedFunc = IsFieldMoveUnlocked_SecretPower, + .moveID = MOVE_SECRET_POWER, + .partyMsgID = PARTY_MSG_CANT_USE_HERE, + }, + + [FIELD_MOVE_MILK_DRINK] = + { + .fieldMoveFunc = SetUpFieldMove_SoftBoiled, + .isUnlockedFunc = IsFieldMoveUnlocked_MilkDrink, + .moveID = MOVE_MILK_DRINK, + .partyMsgID = PARTY_MSG_NOT_ENOUGH_HP, + }, + + [FIELD_MOVE_SOFT_BOILED] = + { + .fieldMoveFunc = SetUpFieldMove_SoftBoiled, + .isUnlockedFunc = IsFieldMoveUnlocked_SoftBoiled, + .moveID = MOVE_SOFT_BOILED, + .partyMsgID = PARTY_MSG_NOT_ENOUGH_HP, + }, + + [FIELD_MOVE_SWEET_SCENT] = + { + .fieldMoveFunc = SetUpFieldMove_SweetScent, + .isUnlockedFunc = IsFieldMoveUnlocked_SweetScent, + .moveID = MOVE_SWEET_SCENT, + .partyMsgID = PARTY_MSG_CANT_USE_HERE, + }, + +#if OW_DEFOG_FIELD_MOVE == TRUE + [FIELD_MOVE_DEFOG] = + { + .fieldMoveFunc = SetUpFieldMove_Defog, + .isUnlockedFunc = IsFieldMoveUnlocked_Defog, + .moveID = MOVE_DEFOG, + .partyMsgID = PARTY_MSG_CANT_USE_HERE, + }, +#endif + +}; diff --git a/src/fldeff_cut.c b/src/fldeff_cut.c index a7eccf651c..4344186a54 100644 --- a/src/fldeff_cut.c +++ b/src/fldeff_cut.c @@ -135,7 +135,7 @@ static const struct SpriteTemplate sSpriteTemplate_CutGrass = }; // code -bool8 SetUpFieldMove_Cut(void) +bool32 SetUpFieldMove_Cut(void) { s16 x, y; u8 i, j; diff --git a/src/fldeff_defog.c b/src/fldeff_defog.c index bccf0d65f7..42c79bad1d 100644 --- a/src/fldeff_defog.c +++ b/src/fldeff_defog.c @@ -19,7 +19,7 @@ static void FieldCallback_Defog(void); static void FieldMove_Defog(void); static void EndDefogTask(u8 taskId); -bool8 SetUpFieldMove_Defog(void) +bool32 SetUpFieldMove_Defog(void) { if (gWeather.currWeather != WEATHER_FOG_HORIZONTAL && gWeather.currWeather != WEATHER_FOG_DIAGONAL) return FALSE; diff --git a/src/fldeff_dig.c b/src/fldeff_dig.c index 63eb848bf2..646865f9c2 100644 --- a/src/fldeff_dig.c +++ b/src/fldeff_dig.c @@ -16,7 +16,7 @@ static void FieldCallback_Dig(void); static void StartDigFieldEffect(void); // text -bool8 SetUpFieldMove_Dig(void) +bool32 SetUpFieldMove_Dig(void) { if (CanUseDigOrEscapeRopeOnCurMap() == TRUE) { diff --git a/src/fldeff_flash.c b/src/fldeff_flash.c index 788d3ca0fd..249163cca7 100644 --- a/src/fldeff_flash.c +++ b/src/fldeff_flash.c @@ -70,7 +70,7 @@ static const u16 sCaveTransitionPalette_Enter[] = INCBIN_U16("graphics/cave_tran static const u32 sCaveTransitionTilemap[] = INCBIN_U32("graphics/cave_transition/tilemap.bin.lz"); static const u32 sCaveTransitionTiles[] = INCBIN_U32("graphics/cave_transition/tiles.4bpp.lz"); -bool8 SetUpFieldMove_Flash(void) +bool32 SetUpFieldMove_Flash(void) { // In Ruby and Sapphire, Registeel's tomb is opened by using Fly. In Emerald, // Flash is used instead. diff --git a/src/fldeff_misc.c b/src/fldeff_misc.c index d3e6982f29..f3d3f00a80 100644 --- a/src/fldeff_misc.c +++ b/src/fldeff_misc.c @@ -544,7 +544,7 @@ static void AdjustSecretPowerSpritePixelOffsets(void) } } -bool8 SetUpFieldMove_SecretPower(void) +bool32 SetUpFieldMove_SecretPower(void) { u8 mb; diff --git a/src/fldeff_rocksmash.c b/src/fldeff_rocksmash.c index 39f64adb87..adb1136340 100644 --- a/src/fldeff_rocksmash.c +++ b/src/fldeff_rocksmash.c @@ -120,7 +120,7 @@ static void Task_DoFieldMove_RunFunc(u8 taskId) // Called when Rock Smash is used from the party menu // For interacting with a smashable rock in the field, see EventScript_RockSmash -bool8 SetUpFieldMove_RockSmash(void) +bool32 SetUpFieldMove_RockSmash(void) { // In Ruby and Sapphire, Regirock's tomb is opened by using Strength. In Emerald, // it is opened by using Rock Smash. diff --git a/src/fldeff_softboiled.c b/src/fldeff_softboiled.c index 3a38f67f02..492577a50c 100644 --- a/src/fldeff_softboiled.c +++ b/src/fldeff_softboiled.c @@ -15,7 +15,7 @@ static void Task_DisplayHPRestoredMessage(u8 taskId); static void Task_FinishSoftboiled(u8 taskId); static void CantUseSoftboiledOnMon(u8 taskId); -bool8 SetUpFieldMove_SoftBoiled(void) +bool32 SetUpFieldMove_SoftBoiled(void) { u16 maxHp; u16 hp; diff --git a/src/fldeff_strength.c b/src/fldeff_strength.c index 9312150403..a0d278edc7 100644 --- a/src/fldeff_strength.c +++ b/src/fldeff_strength.c @@ -15,7 +15,7 @@ static void FieldCallback_Strength(void); static void StartStrengthFieldEffect(void); // text -bool8 SetUpFieldMove_Strength(void) +bool32 SetUpFieldMove_Strength(void) { if (CheckObjectGraphicsInFrontOfPlayer(OBJ_EVENT_GFX_PUSHABLE_BOULDER) == TRUE) { diff --git a/src/fldeff_sweetscent.c b/src/fldeff_sweetscent.c index 1be00baebc..bc86d683a3 100644 --- a/src/fldeff_sweetscent.c +++ b/src/fldeff_sweetscent.c @@ -25,7 +25,7 @@ static void FieldCallback_SweetScent(void); static void TrySweetScentEncounter(u8 taskId); static void FailSweetScentEncounter(u8 taskId); -bool8 SetUpFieldMove_SweetScent(void) +bool32 SetUpFieldMove_SweetScent(void) { gFieldCallback2 = FieldCallback_PrepareFadeInFromMenu; gPostMenuFieldCallback = FieldCallback_SweetScent; diff --git a/src/fldeff_teleport.c b/src/fldeff_teleport.c index 83028c3949..b76082b05f 100644 --- a/src/fldeff_teleport.c +++ b/src/fldeff_teleport.c @@ -11,7 +11,7 @@ static void FieldCallback_Teleport(void); static void StartTeleportFieldEffect(void); -bool8 SetUpFieldMove_Teleport(void) +bool32 SetUpFieldMove_Teleport(void) { if (!CheckFollowerNPCFlag(FOLLOWER_NPC_FLAG_CAN_LEAVE_ROUTE)) return FALSE; diff --git a/src/party_menu.c b/src/party_menu.c index 1fbb9e0edb..74f5531119 100644 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -18,6 +18,7 @@ #include "evolution_scene.h" #include "field_control_avatar.h" #include "field_effect.h" +#include "field_move.h" #include "field_player_avatar.h" #include "field_screen_effect.h" #include "field_specials.h" @@ -69,6 +70,7 @@ #include "constants/battle.h" #include "constants/battle_frontier.h" #include "constants/field_effects.h" +#include "constants/field_move.h" #include "constants/form_change_types.h" #include "constants/item_effects.h" #include "constants/items.h" @@ -129,29 +131,6 @@ enum { ACTIONS_ZYGARDE_CUBE, }; -// In CursorCb_FieldMove, field moves <= FIELD_MOVE_WATERFALL are assumed to line up with the badge flags. -// Badge flag names are commented here for people searching for references to remove the badge requirement. -enum { - FIELD_MOVE_CUT, // FLAG_BADGE01_GET - FIELD_MOVE_FLASH, // FLAG_BADGE02_GET - FIELD_MOVE_ROCK_SMASH, // FLAG_BADGE03_GET - FIELD_MOVE_STRENGTH, // FLAG_BADGE04_GET - FIELD_MOVE_SURF, // FLAG_BADGE05_GET - FIELD_MOVE_FLY, // FLAG_BADGE06_GET - FIELD_MOVE_DIVE, // FLAG_BADGE07_GET - FIELD_MOVE_WATERFALL, // FLAG_BADGE08_GET - FIELD_MOVE_TELEPORT, - FIELD_MOVE_DIG, - FIELD_MOVE_SECRET_POWER, - FIELD_MOVE_MILK_DRINK, - FIELD_MOVE_SOFT_BOILED, - FIELD_MOVE_SWEET_SCENT, -#if OW_DEFOG_FIELD_MOVE == TRUE - FIELD_MOVE_DEFOG, -#endif - FIELD_MOVES_COUNT -}; - enum { PARTY_BOX_LEFT_COLUMN, PARTY_BOX_RIGHT_COLUMN, @@ -514,10 +493,6 @@ static void CursorCb_CatalogFan(u8); static void CursorCb_CatalogMower(u8); static void CursorCb_ChangeForm(u8); static void CursorCb_ChangeAbility(u8); -static bool8 SetUpFieldMove_Surf(void); -static bool8 SetUpFieldMove_Fly(void); -static bool8 SetUpFieldMove_Waterfall(void); -static bool8 SetUpFieldMove_Dive(void); void TryItemHoldFormChange(struct Pokemon *mon, s8 slotId); static void ShowMoveSelectWindow(u8 slot); static void Task_HandleWhichMoveInput(u8 taskId); @@ -2808,7 +2783,7 @@ static u8 DisplaySelectionWindow(u8 windowType) const u8 *text; u8 fontColorsId = (sPartyMenuInternal->actions[i] >= MENU_FIELD_MOVES) ? 4 : 3; if (sPartyMenuInternal->actions[i] >= MENU_FIELD_MOVES) - text = GetMoveName(sFieldMoves[sPartyMenuInternal->actions[i] - MENU_FIELD_MOVES]); + text = GetMoveName(FieldMove_GetMoveId(sPartyMenuInternal->actions[i] - MENU_FIELD_MOVES)); else text = sCursorOptions[sPartyMenuInternal->actions[i]].text; @@ -2874,7 +2849,7 @@ static void SetPartyMonFieldSelectionActions(struct Pokemon *mons, u8 slotId) { for (j = 0; j != FIELD_MOVES_COUNT; j++) { - if (GetMonData(&mons[slotId], i + MON_DATA_MOVE1) == sFieldMoves[j]) + if (GetMonData(&mons[slotId], i + MON_DATA_MOVE1) == FieldMove_GetMoveId(j)) { AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, j + MENU_FIELD_MOVES); break; @@ -3975,7 +3950,7 @@ static void CursorCb_FieldMove(u8 taskId) const struct MapHeader *mapHeader; PlaySE(SE_SELECT); - if (sFieldMoveCursorCallbacks[fieldMove].fieldMoveFunc == NULL) + if (gFieldMoveInfo[fieldMove].fieldMoveFunc == NULL) return; PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]); @@ -3985,19 +3960,19 @@ static void CursorCb_FieldMove(u8 taskId) if (fieldMove == FIELD_MOVE_MILK_DRINK || fieldMove == FIELD_MOVE_SOFT_BOILED) DisplayPartyMenuStdMessage(PARTY_MSG_CANT_USE_HERE); else - DisplayPartyMenuStdMessage(sFieldMoveCursorCallbacks[fieldMove].msgId); + DisplayPartyMenuStdMessage(FieldMove_GetPartyMsgID(fieldMove)); gTasks[taskId].func = Task_CancelAfterAorBPress; } else { // All field moves before WATERFALL are HMs. - if (fieldMove <= FIELD_MOVE_WATERFALL && FlagGet(FLAG_BADGE01_GET + fieldMove) != TRUE) + if (!IsFieldMoveUnlocked(fieldMove)) { DisplayPartyMenuMessage(gText_CantUseUntilNewBadge, TRUE); gTasks[taskId].func = Task_ReturnToChooseMonAfterText; } - else if (sFieldMoveCursorCallbacks[fieldMove].fieldMoveFunc() == TRUE) + else if (SetUpFieldMove(fieldMove) == TRUE) { switch (fieldMove) { @@ -4041,7 +4016,7 @@ static void CursorCb_FieldMove(u8 taskId) DisplayCantUseFlashMessage(); break; default: - DisplayPartyMenuStdMessage(sFieldMoveCursorCallbacks[fieldMove].msgId); + DisplayPartyMenuStdMessage(FieldMove_GetPartyMsgID(fieldMove)); break; } gTasks[taskId].func = Task_CancelAfterAorBPress; @@ -4172,7 +4147,7 @@ static void FieldCallback_Surf(void) FieldEffectStart(FLDEFF_USE_SURF); } -static bool8 SetUpFieldMove_Surf(void) +bool32 SetUpFieldMove_Surf(void) { if (!CheckFollowerNPCFlag(FOLLOWER_NPC_FLAG_CAN_SURF)) return FALSE; @@ -4194,7 +4169,7 @@ static void DisplayCantUseSurfMessage(void) DisplayPartyMenuStdMessage(PARTY_MSG_CANT_SURF_HERE); } -static bool8 SetUpFieldMove_Fly(void) +bool32 SetUpFieldMove_Fly(void) { if (!CheckFollowerNPCFlag(FOLLOWER_NPC_FLAG_CAN_LEAVE_ROUTE)) return FALSE; @@ -4216,7 +4191,7 @@ static void FieldCallback_Waterfall(void) FieldEffectStart(FLDEFF_USE_WATERFALL); } -static bool8 SetUpFieldMove_Waterfall(void) +bool32 SetUpFieldMove_Waterfall(void) { s16 x, y; @@ -4239,7 +4214,7 @@ static void FieldCallback_Dive(void) FieldEffectStart(FLDEFF_USE_DIVE); } -static bool8 SetUpFieldMove_Dive(void) +bool32 SetUpFieldMove_Dive(void) { if (!CheckFollowerNPCFlag(FOLLOWER_NPC_FLAG_CAN_DIVE)) return FALSE; diff --git a/src/scrcmd.c b/src/scrcmd.c index 87bc8e6298..4e8a43f940 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -14,6 +14,7 @@ #include "event_data.h" #include "field_door.h" #include "field_effect.h" +#include "field_move.h" #include "event_object_lock.h" #include "event_object_movement.h" #include "event_scripts.h" @@ -2283,15 +2284,20 @@ bool8 ScrCmd_setmonmove(struct ScriptContext *ctx) return FALSE; } -bool8 ScrCmd_checkpartymove(struct ScriptContext *ctx) +bool8 ScrCmd_checkfieldmove(struct ScriptContext *ctx) { - u8 i; - u16 move = ScriptReadHalfword(ctx); + enum FieldMove fieldMove = ScriptReadByte(ctx); + bool32 doUnlockedCheck = ScriptReadByte(ctx); + u16 move; Script_RequestEffects(SCREFF_V1); gSpecialVar_Result = PARTY_SIZE; - for (i = 0; i < PARTY_SIZE; i++) + if (doUnlockedCheck && !IsFieldMoveUnlocked(fieldMove)) + return FALSE; + + move = FieldMove_GetMoveId(fieldMove); + for (u32 i = 0; i < PARTY_SIZE; i++) { u16 species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL); if (!species) @@ -2303,6 +2309,7 @@ bool8 ScrCmd_checkpartymove(struct ScriptContext *ctx) break; } } + return FALSE; } diff --git a/test/script.c b/test/script.c index 5f185d72cf..cf21124c95 100644 --- a/test/script.c +++ b/test/script.c @@ -3,6 +3,7 @@ #include "test/overworld_script.h" #include "script.h" #include "constants/decorations.h" +#include "constants/field_move.h" #include "constants/moves.h" TEST("Script_HasNoEffect control flow") @@ -46,7 +47,7 @@ TEST("Script_HasNoEffect variables") checkpcitem ITEM_POTION, 1; checkdecorspace DECOR_SNORLAX_DOLL; checkdecor DECOR_SNORLAX_DOLL; - checkpartymove MOVE_CELEBRATE; + checkfieldmove 0, TRUE; // doesn't work with enums currently random 2; checkmoney 5000; getpokenewsactive POKENEWS_LILYCOVE;