Refactor field moves (#6660)

This commit is contained in:
cawtds 2025-05-31 09:03:12 +02:00 committed by GitHub
parent fa342b2909
commit 21499cbee1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 349 additions and 133 deletions

View File

@ -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).

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

37
include/field_move.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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,

View File

@ -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;

212
src/field_move.c Normal file
View File

@ -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
};

View File

@ -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;

View File

@ -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;

View File

@ -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)
{

View File

@ -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.

View File

@ -544,7 +544,7 @@ static void AdjustSecretPowerSpritePixelOffsets(void)
}
}
bool8 SetUpFieldMove_SecretPower(void)
bool32 SetUpFieldMove_SecretPower(void)
{
u8 mb;

View File

@ -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.

View File

@ -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;

View File

@ -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)
{

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;