diff --git a/include/follower_npc.h b/include/follower_npc.h index 90941e56cf..52355a78b7 100644 --- a/include/follower_npc.h +++ b/include/follower_npc.h @@ -44,7 +44,8 @@ enum FollowerNPCSpriteTypes enum FollowerNPCDoorStairsStates { FNPC_DOOR_NONE, - FNPC_DOOR_NEEDS_TO_EXIT + FNPC_DOOR_NEEDS_TO_EXIT, + FNPC_DOOR_NO_POS_SET }; enum FollowerNPCWarpEndStates diff --git a/src/follower_npc.c b/src/follower_npc.c index 3d24cb3942..47a2a94372 100644 --- a/src/follower_npc.c +++ b/src/follower_npc.c @@ -1022,6 +1022,10 @@ void NPCFollow(struct ObjectEvent *npc, u32 state, bool32 ignoreScriptActive) else if (ArePlayerFieldControlsLocked() && !ignoreScriptActive) return; + // Restore post warp behavior after setobjectxy. + if (GetFollowerNPCData(FNPC_DATA_COME_OUT_DOOR) == FNPC_DOOR_NO_POS_SET) + SetFollowerNPCData(FNPC_DATA_COME_OUT_DOOR, FNPC_DOOR_NONE); + // Follower changes to normal sprite after getting off surf blob. if (GetFollowerNPCData(FNPC_DATA_CURRENT_SPRITE) == FOLLOWER_NPC_SPRITE_INDEX_SURF && !CheckFollowerNPCFlag(PLAYER_AVATAR_FLAG_SURFING) && follower->fieldEffectSpriteId == 0) { @@ -1250,7 +1254,6 @@ void FollowerNPC_WarpSetEnd(void) { struct ObjectEvent *player; struct ObjectEvent *follower; - u32 toY; if (!PlayerHasFollowerNPC()) return; @@ -1258,11 +1261,20 @@ void FollowerNPC_WarpSetEnd(void) player = &gObjectEvents[gPlayerAvatar.objectEventId]; follower = &gObjectEvents[GetFollowerNPCObjectId()]; - SetFollowerNPCData(FNPC_DATA_WARP_END, FNPC_WARP_REAPPEAR); PlayerLogCoordinates(player); - toY = GetFollowerNPCData(FNPC_DATA_COME_OUT_DOOR) == FNPC_DOOR_NEEDS_TO_EXIT ? (player->currentCoords.y - 1) : player->currentCoords.y; - MoveObjectEventToMapCoords(follower, player->currentCoords.x, toY); + // Skip setting position if setobjectxy was used during ON_WARP_INTO_MAP_TABLE. + if (GetFollowerNPCData(FNPC_DATA_COME_OUT_DOOR) == FNPC_DOOR_NO_POS_SET) + { + SetFollowerNPCData(FNPC_DATA_WARP_END, FNPC_WARP_NONE); + SetFollowerNPCData(FNPC_DATA_COME_OUT_DOOR, FNPC_DOOR_NONE); + } + else + { + u32 toY = GetFollowerNPCData(FNPC_DATA_COME_OUT_DOOR) == FNPC_DOOR_NEEDS_TO_EXIT ? (player->currentCoords.y - 1) : player->currentCoords.y; + MoveObjectEventToMapCoords(follower, player->currentCoords.x, toY); + SetFollowerNPCData(FNPC_DATA_WARP_END, FNPC_WARP_REAPPEAR); + } if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_ON_FOOT) SetFollowerNPCSprite(FOLLOWER_NPC_SPRITE_INDEX_NORMAL); diff --git a/src/overworld.c b/src/overworld.c index 6ffe73c6ed..65890a94fe 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -2432,9 +2432,9 @@ static void InitObjectEventsLocal(void) SetPlayerAvatarTransitionFlags(player->transitionFlags); ResetInitialPlayerAvatarState(); TrySpawnObjectEvents(0, 0); + FollowerNPC_HandleSprite(); UpdateFollowingPokemon(); TryRunOnWarpIntoMapScript(); - FollowerNPC_HandleSprite(); } static void InitObjectEventsReturnToField(void) diff --git a/src/scrcmd.c b/src/scrcmd.c index c571885946..b1fa37fe49 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -1421,6 +1421,10 @@ bool8 ScrCmd_setobjectxy(struct ScriptContext *ctx) Script_RequestEffects(SCREFF_V1 | SCREFF_HARDWARE); + // Don't do follower NPC post-warp position set after setobjectxy. + if (localId == OBJ_EVENT_ID_NPC_FOLLOWER) + SetFollowerNPCData(FNPC_DATA_COME_OUT_DOOR, FNPC_DOOR_NO_POS_SET); + TryMoveObjectEventToMapCoords(localId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, x, y); return FALSE; }