Add debug options for follower NPCs (#7215)
This commit is contained in:
parent
4f731835b4
commit
c6221fa50e
@ -270,6 +270,24 @@ Debug_ShowExpansionVersion::
|
|||||||
Debug_ExpansionVersion:
|
Debug_ExpansionVersion:
|
||||||
.string "pokeemerald-expansion {STR_VAR_1}$"
|
.string "pokeemerald-expansion {STR_VAR_1}$"
|
||||||
|
|
||||||
|
Debug_Follower_NPC_Not_Enabled::
|
||||||
|
msgbox Debug_Enable_To_Use_Follower_NPCs, MSGBOX_DEFAULT
|
||||||
|
release
|
||||||
|
end
|
||||||
|
|
||||||
|
Debug_Enable_To_Use_Follower_NPCs:
|
||||||
|
.string "Feature unavailable.\nSet FNPC_ENABLE_NPC_FOLLOWERS to\lTRUE in 'include/config/follower_npc.h'.$"
|
||||||
|
|
||||||
|
Debug_Follower_NPC_Event_Script::
|
||||||
|
lock
|
||||||
|
facefollowernpc
|
||||||
|
msgbox Debug_Follower_NPC_Test_Message, MSGBOX_DEFAULT
|
||||||
|
releaseall
|
||||||
|
end
|
||||||
|
|
||||||
|
Debug_Follower_NPC_Test_Message:
|
||||||
|
.string "This is a Follower NPC test.$"
|
||||||
|
|
||||||
Debug_EventScript_Steven_Multi::
|
Debug_EventScript_Steven_Multi::
|
||||||
call MossdeepCity_SpaceCenter_2F_EventScript_ChoosePartyForMultiBattle
|
call MossdeepCity_SpaceCenter_2F_EventScript_ChoosePartyForMultiBattle
|
||||||
release
|
release
|
||||||
|
|||||||
@ -82,6 +82,8 @@ const u8 *GetFollowerNPCScriptPointer(void);
|
|||||||
u32 GetFollowerNPCData(enum FollowerNPCDataTypes type);
|
u32 GetFollowerNPCData(enum FollowerNPCDataTypes type);
|
||||||
void ClearFollowerNPCData(void);
|
void ClearFollowerNPCData(void);
|
||||||
|
|
||||||
|
void CreateFollowerNPC(u32 gfx, u32 followerFlags, const u8 *scriptPtr);
|
||||||
|
void DestroyFollowerNPC(void);
|
||||||
u32 DetermineFollowerNPCState(struct ObjectEvent *follower, u32 state, u32 direction);
|
u32 DetermineFollowerNPCState(struct ObjectEvent *follower, u32 state, u32 direction);
|
||||||
void SetFollowerNPCSprite(u32 spriteIndex);
|
void SetFollowerNPCSprite(u32 spriteIndex);
|
||||||
|
|
||||||
|
|||||||
108
src/debug.c
108
src/debug.c
@ -23,6 +23,7 @@
|
|||||||
#include "field_message_box.h"
|
#include "field_message_box.h"
|
||||||
#include "field_screen_effect.h"
|
#include "field_screen_effect.h"
|
||||||
#include "field_weather.h"
|
#include "field_weather.h"
|
||||||
|
#include "follower_npc.h"
|
||||||
#include "international_string_util.h"
|
#include "international_string_util.h"
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
#include "item_icon.h"
|
#include "item_icon.h"
|
||||||
@ -58,6 +59,7 @@
|
|||||||
#include "constants/battle_ai.h"
|
#include "constants/battle_ai.h"
|
||||||
#include "constants/battle_frontier.h"
|
#include "constants/battle_frontier.h"
|
||||||
#include "constants/coins.h"
|
#include "constants/coins.h"
|
||||||
|
#include "constants/event_objects.h"
|
||||||
#include "constants/expansion.h"
|
#include "constants/expansion.h"
|
||||||
#include "constants/flags.h"
|
#include "constants/flags.h"
|
||||||
#include "constants/items.h"
|
#include "constants/items.h"
|
||||||
@ -71,6 +73,17 @@
|
|||||||
#include "fake_rtc.h"
|
#include "fake_rtc.h"
|
||||||
#include "save.h"
|
#include "save.h"
|
||||||
|
|
||||||
|
enum FollowerNPCCreateDebugMenu
|
||||||
|
{
|
||||||
|
DEBUG_FNPC_BRENDAN,
|
||||||
|
DEBUG_FNPC_MAY,
|
||||||
|
DEBUG_FNPC_STEVEN,
|
||||||
|
DEBUG_FNPC_WALLY,
|
||||||
|
DEBUG_FNPC_RED,
|
||||||
|
DEBUG_FNPC_LEAF,
|
||||||
|
DEBUG_FNPC_COUNT,
|
||||||
|
};
|
||||||
|
|
||||||
enum FlagsVarsDebugMenu
|
enum FlagsVarsDebugMenu
|
||||||
{
|
{
|
||||||
DEBUG_FLAGVAR_MENU_ITEM_FLAGS,
|
DEBUG_FLAGVAR_MENU_ITEM_FLAGS,
|
||||||
@ -223,6 +236,7 @@ static void Debug_RefreshListMenu(u8 taskId);
|
|||||||
static void DebugAction_OpenSubMenu(u8 taskId, const struct DebugMenuOption *items);
|
static void DebugAction_OpenSubMenu(u8 taskId, const struct DebugMenuOption *items);
|
||||||
static void DebugAction_OpenSubMenuFlagsVars(u8 taskId);
|
static void DebugAction_OpenSubMenuFlagsVars(u8 taskId);
|
||||||
static void DebugAction_OpenSubMenuFakeRTC(u8 taskId, const struct DebugMenuOption *items);
|
static void DebugAction_OpenSubMenuFakeRTC(u8 taskId, const struct DebugMenuOption *items);
|
||||||
|
static void DebugAction_OpenSubMenuCreateFollowerNPC(u8 taskId, const struct DebugMenuOption *items);
|
||||||
static void DebugAction_ExecuteScript(u8 taskId, const u8 *script);
|
static void DebugAction_ExecuteScript(u8 taskId, const u8 *script);
|
||||||
|
|
||||||
static void DebugTask_HandleMenuInput_General(u8 taskId);
|
static void DebugTask_HandleMenuInput_General(u8 taskId);
|
||||||
@ -241,6 +255,9 @@ static void DebugAction_Util_CheatStart(u8 taskId);
|
|||||||
static void DebugAction_TimeMenu_ChangeTimeOfDay(u8 taskId);
|
static void DebugAction_TimeMenu_ChangeTimeOfDay(u8 taskId);
|
||||||
static void DebugAction_TimeMenu_ChangeWeekdays(u8 taskId);
|
static void DebugAction_TimeMenu_ChangeWeekdays(u8 taskId);
|
||||||
|
|
||||||
|
static void DebugAction_CreateFollowerNPC(u8 taskId);
|
||||||
|
static void DebugAction_DestroyFollowerNPC(u8 taskId);
|
||||||
|
|
||||||
static void DebugAction_PCBag_Fill_PCBoxes_Fast(u8 taskId);
|
static void DebugAction_PCBag_Fill_PCBoxes_Fast(u8 taskId);
|
||||||
static void DebugAction_PCBag_Fill_PCBoxes_Slow(u8 taskId);
|
static void DebugAction_PCBag_Fill_PCBoxes_Slow(u8 taskId);
|
||||||
static void DebugAction_PCBag_Fill_PCItemStorage(u8 taskId);
|
static void DebugAction_PCBag_Fill_PCItemStorage(u8 taskId);
|
||||||
@ -345,6 +362,8 @@ extern const u8 Debug_CheckROMSpace[];
|
|||||||
extern const u8 Debug_BoxFilledMessage[];
|
extern const u8 Debug_BoxFilledMessage[];
|
||||||
extern const u8 Debug_ShowExpansionVersion[];
|
extern const u8 Debug_ShowExpansionVersion[];
|
||||||
extern const u8 Debug_EventScript_EWRAMCounters[];
|
extern const u8 Debug_EventScript_EWRAMCounters[];
|
||||||
|
extern const u8 Debug_Follower_NPC_Event_Script[];
|
||||||
|
extern const u8 Debug_Follower_NPC_Not_Enabled[];
|
||||||
extern const u8 Debug_EventScript_Steven_Multi[];
|
extern const u8 Debug_EventScript_Steven_Multi[];
|
||||||
extern const u8 Debug_EventScript_PrintTimeOfDay[];
|
extern const u8 Debug_EventScript_PrintTimeOfDay[];
|
||||||
extern const u8 Debug_EventScript_TellTheTime[];
|
extern const u8 Debug_EventScript_TellTheTime[];
|
||||||
@ -393,6 +412,17 @@ static const u8 *const gTimeOfDayStringsTable[TIMES_OF_DAY_COUNT] = {
|
|||||||
COMPOUND_STRING("Night"),
|
COMPOUND_STRING("Night"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Follower NPC
|
||||||
|
|
||||||
|
static const u8 *const gFollowerNPCStringsTable[DEBUG_FNPC_COUNT] = {
|
||||||
|
COMPOUND_STRING("Brendan"),
|
||||||
|
COMPOUND_STRING("May"),
|
||||||
|
COMPOUND_STRING("Steven"),
|
||||||
|
COMPOUND_STRING("Wally"),
|
||||||
|
COMPOUND_STRING("Red"),
|
||||||
|
COMPOUND_STRING("Leaf"),
|
||||||
|
};
|
||||||
|
|
||||||
// Flags/Vars Menu
|
// Flags/Vars Menu
|
||||||
static const u8 sDebugText_FlagsVars_VariableHex[] = _("{STR_VAR_1}{CLEAR_TO 90}\n0x{STR_VAR_2}{CLEAR_TO 90}");
|
static const u8 sDebugText_FlagsVars_VariableHex[] = _("{STR_VAR_1}{CLEAR_TO 90}\n0x{STR_VAR_2}{CLEAR_TO 90}");
|
||||||
static const u8 sDebugText_FlagsVars_Variable[] = _("Var: {STR_VAR_1}{CLEAR_TO 90}\nVal: {STR_VAR_3}{CLEAR_TO 90}\n{STR_VAR_2}");
|
static const u8 sDebugText_FlagsVars_Variable[] = _("Var: {STR_VAR_1}{CLEAR_TO 90}\nVal: {STR_VAR_3}{CLEAR_TO 90}\n{STR_VAR_2}");
|
||||||
@ -454,6 +484,17 @@ static const struct DebugMenuOption sDebugMenu_Actions_TimeMenu_Weekdays[] =
|
|||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct DebugMenuOption sDebugMenu_Actions_FollowerNPCMenu_Create[] =
|
||||||
|
{
|
||||||
|
[DEBUG_FNPC_BRENDAN] = { gFollowerNPCStringsTable[DEBUG_FNPC_BRENDAN], DebugAction_CreateFollowerNPC },
|
||||||
|
[DEBUG_FNPC_MAY] = { gFollowerNPCStringsTable[DEBUG_FNPC_MAY], DebugAction_CreateFollowerNPC },
|
||||||
|
[DEBUG_FNPC_STEVEN] = { gFollowerNPCStringsTable[DEBUG_FNPC_STEVEN], DebugAction_CreateFollowerNPC },
|
||||||
|
[DEBUG_FNPC_WALLY] = { gFollowerNPCStringsTable[DEBUG_FNPC_WALLY], DebugAction_CreateFollowerNPC },
|
||||||
|
[DEBUG_FNPC_RED] = { gFollowerNPCStringsTable[DEBUG_FNPC_RED], DebugAction_CreateFollowerNPC },
|
||||||
|
[DEBUG_FNPC_LEAF] = { gFollowerNPCStringsTable[DEBUG_FNPC_LEAF], DebugAction_CreateFollowerNPC },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
static const struct DebugMenuOption sDebugMenu_Actions_TimeMenu[] =
|
static const struct DebugMenuOption sDebugMenu_Actions_TimeMenu[] =
|
||||||
{
|
{
|
||||||
{ COMPOUND_STRING("Get time…"), DebugAction_ExecuteScript, Debug_EventScript_TellTheTime },
|
{ COMPOUND_STRING("Get time…"), DebugAction_ExecuteScript, Debug_EventScript_TellTheTime },
|
||||||
@ -475,6 +516,13 @@ static const struct DebugMenuOption sDebugMenu_Actions_BerryFunctions[] =
|
|||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct DebugMenuOption sDebugMenu_Actions_FollowerNPCMenu[] =
|
||||||
|
{
|
||||||
|
{ COMPOUND_STRING("Create Follower"), DebugAction_OpenSubMenuCreateFollowerNPC, sDebugMenu_Actions_FollowerNPCMenu_Create },
|
||||||
|
{ COMPOUND_STRING("Destroy Follower"), DebugAction_DestroyFollowerNPC },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
static const struct DebugMenuOption sDebugMenu_Actions_Utilities[] =
|
static const struct DebugMenuOption sDebugMenu_Actions_Utilities[] =
|
||||||
{
|
{
|
||||||
{ COMPOUND_STRING("Fly to map…"), DebugAction_Util_Fly },
|
{ COMPOUND_STRING("Fly to map…"), DebugAction_Util_Fly },
|
||||||
@ -486,6 +534,7 @@ static const struct DebugMenuOption sDebugMenu_Actions_Utilities[] =
|
|||||||
{ COMPOUND_STRING("Cheat start"), DebugAction_Util_CheatStart },
|
{ COMPOUND_STRING("Cheat start"), DebugAction_Util_CheatStart },
|
||||||
{ COMPOUND_STRING("Berry Functions…"), DebugAction_OpenSubMenu, sDebugMenu_Actions_BerryFunctions },
|
{ COMPOUND_STRING("Berry Functions…"), DebugAction_OpenSubMenu, sDebugMenu_Actions_BerryFunctions },
|
||||||
{ COMPOUND_STRING("EWRAM Counters…"), DebugAction_ExecuteScript, Debug_EventScript_EWRAMCounters },
|
{ COMPOUND_STRING("EWRAM Counters…"), DebugAction_ExecuteScript, Debug_EventScript_EWRAMCounters },
|
||||||
|
{ COMPOUND_STRING("Follower NPC…"), DebugAction_OpenSubMenu, sDebugMenu_Actions_FollowerNPCMenu },
|
||||||
{ COMPOUND_STRING("Steven Multi"), DebugAction_ExecuteScript, Debug_EventScript_Steven_Multi },
|
{ COMPOUND_STRING("Steven Multi"), DebugAction_ExecuteScript, Debug_EventScript_Steven_Multi },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
@ -766,7 +815,8 @@ static bool32 IsSubMenuAction(const void *action)
|
|||||||
{
|
{
|
||||||
return action == DebugAction_OpenSubMenu
|
return action == DebugAction_OpenSubMenu
|
||||||
|| action == DebugAction_OpenSubMenuFlagsVars
|
|| action == DebugAction_OpenSubMenuFlagsVars
|
||||||
|| action == DebugAction_OpenSubMenuFakeRTC;
|
|| action == DebugAction_OpenSubMenuFakeRTC
|
||||||
|
|| action == DebugAction_OpenSubMenuCreateFollowerNPC;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Debug_ShowMenu(DebugFunc HandleInput, const struct DebugMenuOption *items)
|
static void Debug_ShowMenu(DebugFunc HandleInput, const struct DebugMenuOption *items)
|
||||||
@ -1206,6 +1256,19 @@ static void DebugAction_ExecuteScript(u8 taskId, const u8 *script)
|
|||||||
Debug_DestroyMenu_Full_Script(taskId, script);
|
Debug_DestroyMenu_Full_Script(taskId, script);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void DebugAction_OpenSubMenuCreateFollowerNPC(u8 taskId, const struct DebugMenuOption *items)
|
||||||
|
{
|
||||||
|
if (FNPC_ENABLE_NPC_FOLLOWERS)
|
||||||
|
{
|
||||||
|
Debug_DestroyMenu(taskId);
|
||||||
|
Debug_ShowMenu(DebugTask_HandleMenuInput_General, items);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug_DestroyMenu_Full_Script(taskId, Debug_Follower_NPC_Not_Enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// *******************************
|
// *******************************
|
||||||
// Actions Utilities
|
// Actions Utilities
|
||||||
|
|
||||||
@ -3272,6 +3335,49 @@ static void DebugAction_Sound_MUS_SelectId(u8 taskId)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const u32 gDebugFollowerNPCGraphics[] =
|
||||||
|
{
|
||||||
|
OBJ_EVENT_GFX_RIVAL_BRENDAN_NORMAL,
|
||||||
|
OBJ_EVENT_GFX_RIVAL_MAY_NORMAL,
|
||||||
|
OBJ_EVENT_GFX_STEVEN,
|
||||||
|
OBJ_EVENT_GFX_WALLY,
|
||||||
|
OBJ_EVENT_GFX_RED,
|
||||||
|
OBJ_EVENT_GFX_LEAF,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void DebugAction_CreateFollowerNPC(u8 taskId)
|
||||||
|
{
|
||||||
|
u32 input = ListMenu_ProcessInput(gTasks[taskId].tMenuTaskId);
|
||||||
|
u32 gfx = gDebugFollowerNPCGraphics[input];
|
||||||
|
|
||||||
|
Debug_DestroyMenu_Full(taskId);
|
||||||
|
LockPlayerFieldControls();
|
||||||
|
DestroyFollowerNPC();
|
||||||
|
SetFollowerNPCData(FNPC_DATA_BATTLE_PARTNER, PARTNER_STEVEN);
|
||||||
|
CreateFollowerNPC(gfx, FNPC_ALL, Debug_Follower_NPC_Event_Script);
|
||||||
|
if (gfx != OBJ_EVENT_GFX_RIVAL_BRENDAN_NORMAL && gfx != OBJ_EVENT_GFX_RIVAL_MAY_NORMAL)
|
||||||
|
{
|
||||||
|
u32 flags = GetFollowerNPCData(FNPC_DATA_FOLLOWER_FLAGS);
|
||||||
|
SetFollowerNPCData(FNPC_DATA_FOLLOWER_FLAGS, (flags &= ~FNPC_RUNNING));
|
||||||
|
}
|
||||||
|
UnlockPlayerFieldControls();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DebugAction_DestroyFollowerNPC(u8 taskId)
|
||||||
|
{
|
||||||
|
if (FNPC_ENABLE_NPC_FOLLOWERS)
|
||||||
|
{
|
||||||
|
Debug_DestroyMenu_Full(taskId);
|
||||||
|
LockPlayerFieldControls();
|
||||||
|
DestroyFollowerNPC();
|
||||||
|
UnlockPlayerFieldControls();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug_DestroyMenu_Full_Script(taskId, Debug_Follower_NPC_Not_Enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#undef tCurrentSong
|
#undef tCurrentSong
|
||||||
|
|
||||||
#undef tMenuTaskId
|
#undef tMenuTaskId
|
||||||
|
|||||||
@ -49,7 +49,6 @@
|
|||||||
static void SetFollowerNPCScriptPointer(const u8 *script);
|
static void SetFollowerNPCScriptPointer(const u8 *script);
|
||||||
static void PlayerLogCoordinates(struct ObjectEvent *player);
|
static void PlayerLogCoordinates(struct ObjectEvent *player);
|
||||||
static void TurnNPCIntoFollower(u32 localId, u32 followerFlags, u32 setScript, const u8 *script);
|
static void TurnNPCIntoFollower(u32 localId, u32 followerFlags, u32 setScript, const u8 *script);
|
||||||
static void CreateFollowerNPC(u32 gfx, u32 followerFlags, const u8 *scriptPtr);
|
|
||||||
static u32 GetFollowerNPCSprite(void);
|
static u32 GetFollowerNPCSprite(void);
|
||||||
static bool32 IsStateMovement(u32 state);
|
static bool32 IsStateMovement(u32 state);
|
||||||
static u32 GetPlayerFaceToDoorDirection(struct ObjectEvent *player, struct ObjectEvent *follower);
|
static u32 GetPlayerFaceToDoorDirection(struct ObjectEvent *player, struct ObjectEvent *follower);
|
||||||
@ -227,45 +226,6 @@ static void TurnNPCIntoFollower(u32 localId, u32 followerFlags, u32 setScript, c
|
|||||||
FollowerNPC_HandleSprite();
|
FollowerNPC_HandleSprite();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CreateFollowerNPC(u32 gfx, u32 followerFlags, const u8 *scriptPtr)
|
|
||||||
{
|
|
||||||
struct ObjectEvent *player = &gObjectEvents[gPlayerAvatar.objectEventId];
|
|
||||||
struct ObjectEvent *follower;
|
|
||||||
struct ObjectEventTemplate npc =
|
|
||||||
{
|
|
||||||
.localId = OBJ_EVENT_ID_NPC_FOLLOWER,
|
|
||||||
.graphicsId = gfx,
|
|
||||||
.x = player->currentCoords.x,
|
|
||||||
.y = player->currentCoords.y,
|
|
||||||
.elevation = PlayerGetElevation(),
|
|
||||||
.script = scriptPtr
|
|
||||||
};
|
|
||||||
|
|
||||||
SetFollowerNPCData(FNPC_DATA_OBJ_ID, TrySpawnObjectEventTemplate(&npc, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, player->currentCoords.x, player->currentCoords.y));
|
|
||||||
follower = &gObjectEvents[GetFollowerNPCData(FNPC_DATA_OBJ_ID)];
|
|
||||||
follower->movementType = MOVEMENT_TYPE_NONE;
|
|
||||||
gSprites[follower->spriteId].callback = MovementType_None;
|
|
||||||
|
|
||||||
SetFollowerNPCData(FNPC_DATA_IN_PROGRESS, TRUE);
|
|
||||||
SetFollowerNPCData(FNPC_DATA_GFX_ID, follower->graphicsId);
|
|
||||||
SetFollowerNPCData(FNPC_DATA_FOLLOWER_FLAGS, followerFlags);
|
|
||||||
SetFollowerNPCData(FNPC_DATA_SURF_BLOB, FNPC_SURF_BLOB_NONE);
|
|
||||||
SetFollowerNPCData(FNPC_DATA_COME_OUT_DOOR, FNPC_DOOR_NONE);
|
|
||||||
SetFollowerNPCScriptPointer(scriptPtr);
|
|
||||||
|
|
||||||
// If the player is biking and the follower flags prohibit biking, force the player to dismount the bike.
|
|
||||||
if (!CheckFollowerNPCFlag(FOLLOWER_NPC_FLAG_CAN_BIKE)
|
|
||||||
&& TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_BIKE))
|
|
||||||
SetPlayerAvatarTransitionFlags(PLAYER_AVATAR_FLAG_ON_FOOT);
|
|
||||||
|
|
||||||
// Set the follower sprite to match the player state.
|
|
||||||
if (!TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_ON_FOOT))
|
|
||||||
FollowerNPC_HandleSprite();
|
|
||||||
|
|
||||||
HideNPCFollower();
|
|
||||||
SetFollowerNPCData(FNPC_DATA_WARP_END, FNPC_WARP_REAPPEAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 GetFollowerNPCSprite(void)
|
static u32 GetFollowerNPCSprite(void)
|
||||||
{
|
{
|
||||||
u32 i;
|
u32 i;
|
||||||
@ -712,6 +672,58 @@ static void CalculateFollowerNPCEscalatorTrajectoryDown(struct Task *task)
|
|||||||
|
|
||||||
#undef tCounter
|
#undef tCounter
|
||||||
|
|
||||||
|
void CreateFollowerNPC(u32 gfx, u32 followerFlags, const u8 *scriptPtr)
|
||||||
|
{
|
||||||
|
if (PlayerHasFollowerNPC())
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct ObjectEvent *player = &gObjectEvents[gPlayerAvatar.objectEventId];
|
||||||
|
struct ObjectEvent *follower;
|
||||||
|
struct ObjectEventTemplate npc =
|
||||||
|
{
|
||||||
|
.localId = OBJ_EVENT_ID_NPC_FOLLOWER,
|
||||||
|
.graphicsId = gfx,
|
||||||
|
.x = player->currentCoords.x,
|
||||||
|
.y = player->currentCoords.y,
|
||||||
|
.elevation = PlayerGetElevation(),
|
||||||
|
.script = scriptPtr
|
||||||
|
};
|
||||||
|
|
||||||
|
SetFollowerNPCData(FNPC_DATA_OBJ_ID, TrySpawnObjectEventTemplate(&npc, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, player->currentCoords.x, player->currentCoords.y));
|
||||||
|
follower = &gObjectEvents[GetFollowerNPCData(FNPC_DATA_OBJ_ID)];
|
||||||
|
follower->movementType = MOVEMENT_TYPE_NONE;
|
||||||
|
gSprites[follower->spriteId].callback = MovementType_None;
|
||||||
|
|
||||||
|
SetFollowerNPCData(FNPC_DATA_IN_PROGRESS, TRUE);
|
||||||
|
SetFollowerNPCData(FNPC_DATA_GFX_ID, follower->graphicsId);
|
||||||
|
SetFollowerNPCData(FNPC_DATA_FOLLOWER_FLAGS, followerFlags);
|
||||||
|
SetFollowerNPCData(FNPC_DATA_SURF_BLOB, FNPC_SURF_BLOB_NONE);
|
||||||
|
SetFollowerNPCData(FNPC_DATA_COME_OUT_DOOR, FNPC_DOOR_NONE);
|
||||||
|
SetFollowerNPCScriptPointer(scriptPtr);
|
||||||
|
|
||||||
|
// If the player is biking and the follower flags prohibit biking, force the player to dismount the bike.
|
||||||
|
if (!CheckFollowerNPCFlag(FOLLOWER_NPC_FLAG_CAN_BIKE)
|
||||||
|
&& TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_BIKE))
|
||||||
|
SetPlayerAvatarTransitionFlags(PLAYER_AVATAR_FLAG_ON_FOOT);
|
||||||
|
|
||||||
|
// Set the follower sprite to match the player state.
|
||||||
|
if (!TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_ON_FOOT))
|
||||||
|
FollowerNPC_HandleSprite();
|
||||||
|
|
||||||
|
HideNPCFollower();
|
||||||
|
SetFollowerNPCData(FNPC_DATA_WARP_END, FNPC_WARP_REAPPEAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyFollowerNPC(void)
|
||||||
|
{
|
||||||
|
if (!PlayerHasFollowerNPC())
|
||||||
|
return;
|
||||||
|
|
||||||
|
RemoveObjectEvent(&gObjectEvents[GetFollowerNPCData(FNPC_DATA_OBJ_ID)]);
|
||||||
|
ClearFollowerNPCData();
|
||||||
|
UpdateFollowingPokemon();
|
||||||
|
}
|
||||||
|
|
||||||
#define RETURN_STATE(state, dir) return newState == MOVEMENT_INVALID ? state + (dir - 1) : ReturnFollowerNPCDelayedState(dir - 1);
|
#define RETURN_STATE(state, dir) return newState == MOVEMENT_INVALID ? state + (dir - 1) : ReturnFollowerNPCDelayedState(dir - 1);
|
||||||
u32 DetermineFollowerNPCState(struct ObjectEvent *follower, u32 state, u32 direction)
|
u32 DetermineFollowerNPCState(struct ObjectEvent *follower, u32 state, u32 direction)
|
||||||
{
|
{
|
||||||
@ -1642,7 +1654,7 @@ void ScriptCreateFollowerNPC(struct ScriptContext *ctx)
|
|||||||
const u8 *script = (const u8 *)ScriptReadWord(ctx);
|
const u8 *script = (const u8 *)ScriptReadWord(ctx);
|
||||||
u32 battlePartner = ScriptReadHalfword(ctx);
|
u32 battlePartner = ScriptReadHalfword(ctx);
|
||||||
|
|
||||||
if (PlayerHasFollowerNPC())
|
if (!FNPC_ENABLE_NPC_FOLLOWERS || PlayerHasFollowerNPC())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SetFollowerNPCData(FNPC_DATA_BATTLE_PARTNER, battlePartner);
|
SetFollowerNPCData(FNPC_DATA_BATTLE_PARTNER, battlePartner);
|
||||||
@ -1651,12 +1663,7 @@ void ScriptCreateFollowerNPC(struct ScriptContext *ctx)
|
|||||||
|
|
||||||
void ScriptDestroyFollowerNPC(struct ScriptContext *ctx)
|
void ScriptDestroyFollowerNPC(struct ScriptContext *ctx)
|
||||||
{
|
{
|
||||||
if (!PlayerHasFollowerNPC())
|
DestroyFollowerNPC();
|
||||||
return;
|
|
||||||
|
|
||||||
RemoveObjectEvent(&gObjectEvents[GetFollowerNPCData(FNPC_DATA_OBJ_ID)]);
|
|
||||||
ClearFollowerNPCData();
|
|
||||||
UpdateFollowingPokemon();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptFaceFollowerNPC(struct ScriptContext *ctx)
|
void ScriptFaceFollowerNPC(struct ScriptContext *ctx)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user