From d12a24aef2f41d82288422fa3a41b18cbc2cecd4 Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Sat, 14 Dec 2024 23:07:02 -0500 Subject: [PATCH 1/6] fix: gave MOVEMENT_TYPE_FOLLOW_PLAYER an initial facing direction --- src/event_object_movement.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 26127caab9..acecd5d61d 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -362,7 +362,7 @@ static const bool8 sMovementTypeHasRange[NUM_MOVEMENT_TYPES] = { [MOVEMENT_TYPE_COPY_PLAYER_CLOCKWISE_IN_GRASS] = TRUE, }; -const u8 gInitialMovementTypeFacingDirections[] = { +const u8 gInitialMovementTypeFacingDirections[NUM_MOVEMENT_TYPES] = { [MOVEMENT_TYPE_NONE] = DIR_SOUTH, [MOVEMENT_TYPE_LOOK_AROUND] = DIR_SOUTH, [MOVEMENT_TYPE_WANDER_AROUND] = DIR_SOUTH, @@ -444,6 +444,7 @@ const u8 gInitialMovementTypeFacingDirections[] = { [MOVEMENT_TYPE_WALK_SLOWLY_IN_PLACE_UP] = DIR_NORTH, [MOVEMENT_TYPE_WALK_SLOWLY_IN_PLACE_LEFT] = DIR_WEST, [MOVEMENT_TYPE_WALK_SLOWLY_IN_PLACE_RIGHT] = DIR_EAST, + [MOVEMENT_TYPE_FOLLOW_PLAYER] = DIR_SOUTH, }; #define OBJ_EVENT_PAL_TAG_BRENDAN 0x1100 From 5536a5535c5dd958896df5204c3f98a51266ef89 Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Mon, 30 Dec 2024 20:52:05 -0500 Subject: [PATCH 2/6] fix: made slitherTracks_Transitions a proper 2D array. Credit: jaizu --- src/event_object_movement.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/event_object_movement.c b/src/event_object_movement.c index acecd5d61d..8d682bce63 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -9309,10 +9309,10 @@ static void DoTracksGroundEffect_SlitherTracks(struct ObjectEvent *objEvent, str // each byte in that row is for the next direction of the bike in the order // of down, up, left, right. static const u8 slitherTracks_Transitions[4][4] = { - 1, 2, 7, 8, - 1, 2, 6, 5, - 5, 8, 3, 4, - 6, 7, 3, 4, + {1, 2, 7, 8}, + {1, 2, 6, 5}, + {5, 8, 3, 4}, + {6, 7, 3, 4}, }; if (objEvent->currentCoords.x != objEvent->previousCoords.x || objEvent->currentCoords.y != objEvent->previousCoords.y) From 57a198bca0adb08ad0f1d7d4c520f3203f3ceb6c Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Mon, 30 Dec 2024 20:44:07 -0500 Subject: [PATCH 3/6] feat: make follower sidestep or backstep with player during scripts --- src/event_object_movement.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 8d682bce63..5f1b3eba77 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -5189,6 +5189,7 @@ bool8 MovementType_FollowPlayer_Moving(struct ObjectEvent *objectEvent, struct S if (ObjectEventExecSingleMovementAction(objectEvent, sprite)) { #endif objectEvent->singleMovementActive = 0; + objectEvent->facingDirectionLocked = FALSE; if (sprite->sTypeFuncId) // restore nonzero state sprite->sTypeFuncId = 1; } else if (objectEvent->movementActionId < MOVEMENT_ACTION_EXIT_POKEBALL) { @@ -5258,6 +5259,15 @@ bool8 FollowablePlayerMovement_Step(struct ObjectEvent *objectEvent, struct Spri // Follow player direction = GetDirectionToFace(x, y, targetX, targetY); + // During a script, if player sidesteps or backsteps, + // mirror player's direction instead + if (ArePlayerFieldControlsLocked() + && gObjectEvents[gPlayerAvatar.objectEventId].facingDirection != gObjectEvents[gPlayerAvatar.objectEventId].movementDirection + ) { + direction = gObjectEvents[gPlayerAvatar.objectEventId].movementDirection; + objectEvent->facingDirectionLocked = TRUE; + } + MoveCoords(direction, &x, &y); #ifdef MB_SIDEWAYS_STAIRS_RIGHT_SIDE // https://github.com/ghoulslash/pokeemerald/tree/sideways_stairs GetCollisionAtCoords(objectEvent, x, y, direction); // Sets directionOverwrite for stairs From 3fffb9fac6c3eb9c232609565f5e84957630a32c Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Mon, 30 Dec 2024 21:33:17 -0500 Subject: [PATCH 4/6] feat: added configuration to restrict following pokemon. Closes #42 --- include/constants/event_objects.h | 21 +++++++++++++++++++++ src/event_object_movement.c | 10 +++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/include/constants/event_objects.h b/include/constants/event_objects.h index 1d0f5a22e8..63d5f9c733 100644 --- a/include/constants/event_objects.h +++ b/include/constants/event_objects.h @@ -295,6 +295,27 @@ // FALSE: Script collisions unhandled, FLAG_SAFE_FOLLOWER_MOVEMENT off by default #define OW_MON_SCRIPT_MOVEMENT TRUE +// If set, the only pokemon allowed to follow you +// will be those matching species, met location, +// and/or met level; +// These accept vars, too: VAR_TEMP_1, etc +#define OW_MON_ALLOWED_SPECIES (0) +#define OW_MON_ALLOWED_MET_LVL (0) +#define OW_MON_ALLOWED_MET_LOC (0) +// Examples: +// Yellow Pikachu: +// #define OW_MON_ALLOWED_SPECIES (SPECIES_PIKACHU) +// #define OW_MON_ALLOWED_MET_LVL (0) +// #define OW_MON_ALLOWED_MET_LOC (MAPSEC_PALLET_TOWN) +// Hoenn Starter: +// #define OW_MON_ALLOWED_SPECIES (0) +// #define OW_MON_ALLOWED_MET_LVL (5) +// #define OW_MON_ALLOWED_MET_LOC (MAPSEC_ROUTE_101) +// Species set in VAR_XXXX: +// #define OW_MON_ALLOWED_SPECIES (VAR_XXXX) +// #define OW_MON_ALLOWED_MET_LVL (0) +// #define OW_MON_ALLOWED_MET_LOC (0) + #define SHADOW_SIZE_S 0 #define SHADOW_SIZE_M 1 #define SHADOW_SIZE_L 2 diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 5f1b3eba77..6498ceb455 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -1785,8 +1785,16 @@ u8 CreateVirtualObject(u8 graphicsId, u8 virtualObjId, s16 x, s16 y, u8 elevatio struct Pokemon *GetFirstLiveMon(void) { // Return address of first conscious party mon or NULL u32 i; for (i = 0; i < PARTY_SIZE; i++) { + struct Pokemon *mon = &gPlayerParty[i]; + if ((OW_MON_ALLOWED_SPECIES && GetMonData(mon, MON_DATA_SPECIES_OR_EGG) != VarGet(OW_MON_ALLOWED_SPECIES)) + || (OW_MON_ALLOWED_MET_LVL && GetMonData(mon, MON_DATA_MET_LEVEL) != VarGet(OW_MON_ALLOWED_MET_LVL)) + || (OW_MON_ALLOWED_MET_LOC && GetMonData(mon, MON_DATA_MET_LOCATION) != VarGet(OW_MON_ALLOWED_MET_LOC)) + ) { + continue; + } + if (gPlayerParty[i].hp > 0 && !(gPlayerParty[i].box.isEgg || gPlayerParty[i].box.isBadEgg)) - return &gPlayerParty[i]; + return &gPlayerParty[i]; } return NULL; } From 9e2057a9d473ac949f9dfde20a3df6b7a404a1c1 Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Mon, 30 Dec 2024 21:35:13 -0500 Subject: [PATCH 5/6] meta: updated README with new config settings --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 07427e2bd5..1dd20434ee 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,20 @@ A: Configuration for the follower system is mostly in [event_objects.h](include/ // Followers will emerge from the pokeball they are stored in, // instead of a normal pokeball #define OW_MON_POKEBALLS TRUE + +// New/old handling for followers during scripts; +// TRUE: Script collisions hide follower, FLAG_SAFE_FOLLOWER_MOVEMENT on by default +// (scripted player movement moves follower too!) +// FALSE: Script collisions unhandled, FLAG_SAFE_FOLLOWER_MOVEMENT off by default +#define OW_MON_SCRIPT_MOVEMENT TRUE + +// If set, the only pokemon allowed to follow you +// will be those matching species, met location, +// and/or met level; +// These accept vars, too: VAR_TEMP_1, etc +#define OW_MON_ALLOWED_SPECIES (0) +#define OW_MON_ALLOWED_MET_LVL (0) +#define OW_MON_ALLOWED_MET_LOC (0) ``` ### `(lighting)` Q: How do I mark certain colors in a palette as light-blended? From 01335fa453a90d9f48ce6d8f92a947cd1782b23c Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Thu, 23 Jun 2022 22:13:21 -0400 Subject: [PATCH 6/6] Unfreeze follower object during lockall (if safe movement flag set). MSGBOX_SIGN no longer freezes follower. --- data/scripts/std_msgbox.inc | 2 ++ src/scrcmd.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/data/scripts/std_msgbox.inc b/data/scripts/std_msgbox.inc index c46da56cbf..40026c8ea0 100644 --- a/data/scripts/std_msgbox.inc +++ b/data/scripts/std_msgbox.inc @@ -8,11 +8,13 @@ Std_MsgboxNPC: return Std_MsgboxSign: + setflag FLAG_SAFE_FOLLOWER_MOVEMENT lockall message NULL waitmessage waitbuttonpress releaseall + clearflag FLAG_SAFE_FOLLOWER_MOVEMENT return Std_MsgboxDefault: diff --git a/src/scrcmd.c b/src/scrcmd.c index 79b13534ab..a648bf105c 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -1248,8 +1248,11 @@ bool8 ScrCmd_lockall(struct ScriptContext *ctx) } else { + struct ObjectEvent *followerObj = GetFollowerObject(); FreezeObjects_WaitForPlayer(); SetupNativeScript(ctx, IsFreezePlayerFinished); + if (FlagGet(FLAG_SAFE_FOLLOWER_MOVEMENT) && followerObj) // Unfreeze follower object (conditionally) + UnfreezeObjectEvent(followerObj); return TRUE; } }