From d88834dd586eef503bb677f9425f5876cfb6a05b Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Wed, 7 Aug 2024 13:42:18 -0400 Subject: [PATCH 1/4] Backported OBJ_EVENT_GFX_SPECIES macro from Expansion --- data/maps/DesertRuins/map.json | 2 +- data/maps/IslandCave/map.json | 2 +- include/constants/event_objects.h | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/data/maps/DesertRuins/map.json b/data/maps/DesertRuins/map.json index 80c8f6a483..be0a28481a 100644 --- a/data/maps/DesertRuins/map.json +++ b/data/maps/DesertRuins/map.json @@ -15,7 +15,7 @@ "connections": null, "object_events": [ { - "graphics_id": "OBJ_EVENT_GFX_MON_BASE+SPECIES_REGIROCK", + "graphics_id": "OBJ_EVENT_GFX_SPECIES(REGIROCK)", "x": 8, "y": 7, "elevation": 3, diff --git a/data/maps/IslandCave/map.json b/data/maps/IslandCave/map.json index c6204ff1c5..142ec122d6 100644 --- a/data/maps/IslandCave/map.json +++ b/data/maps/IslandCave/map.json @@ -15,7 +15,7 @@ "connections": 0, "object_events": [ { - "graphics_id": "OBJ_EVENT_GFX_MON_BASE+SPECIES_REGICE", + "graphics_id": "OBJ_EVENT_GFX_SPECIES(REGICE)", "x": 8, "y": 7, "elevation": 3, diff --git a/include/constants/event_objects.h b/include/constants/event_objects.h index dc4fdf8870..4eaa82b75d 100644 --- a/include/constants/event_objects.h +++ b/include/constants/event_objects.h @@ -280,6 +280,9 @@ #define OBJ_EVENT_GFX_SPECIES_BITS 11 #define OBJ_EVENT_GFX_SPECIES_MASK ((1 << OBJ_EVENT_GFX_SPECIES_BITS) - 1) +// Used to call a specific species' follower graphics. Useful for static encounters. +#define OBJ_EVENT_GFX_SPECIES(name) (SPECIES_##name + OBJ_EVENT_GFX_MON_BASE) + #define OW_SPECIES(x) (((x)->graphicsId & OBJ_EVENT_GFX_SPECIES_MASK) - OBJ_EVENT_GFX_MON_BASE) #define OW_FORM(x) ((x)->graphicsId >> OBJ_EVENT_GFX_SPECIES_BITS) From e6e2285c441ba0b3965365f7a9f7c1919ea53d9c Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Sun, 11 Aug 2024 14:50:38 -0400 Subject: [PATCH 2/4] Added OBJ_EVENT_GFX_SPECIES_SHINY --- include/constants/event_objects.h | 1 + include/constants/species.h | 2 ++ include/data.h | 1 - src/event_object_movement.c | 8 ++++++++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/constants/event_objects.h b/include/constants/event_objects.h index 4eaa82b75d..2e7ec7939f 100644 --- a/include/constants/event_objects.h +++ b/include/constants/event_objects.h @@ -282,6 +282,7 @@ // Used to call a specific species' follower graphics. Useful for static encounters. #define OBJ_EVENT_GFX_SPECIES(name) (SPECIES_##name + OBJ_EVENT_GFX_MON_BASE) +#define OBJ_EVENT_GFX_SPECIES_SHINY(name) (SPECIES_##name + OBJ_EVENT_GFX_MON_BASE + SPECIES_SHINY_TAG) #define OW_SPECIES(x) (((x)->graphicsId & OBJ_EVENT_GFX_SPECIES_MASK) - OBJ_EVENT_GFX_MON_BASE) #define OW_FORM(x) ((x)->graphicsId >> OBJ_EVENT_GFX_SPECIES_BITS) diff --git a/include/constants/species.h b/include/constants/species.h index ec60c142ed..e6b6120a4f 100644 --- a/include/constants/species.h +++ b/include/constants/species.h @@ -419,6 +419,8 @@ #define NUM_SPECIES SPECIES_EGG +#define SPECIES_SHINY_TAG 500 + #define SPECIES_UNOWN_B (NUM_SPECIES + 1) #define SPECIES_UNOWN_C (SPECIES_UNOWN_B + 1) #define SPECIES_UNOWN_D (SPECIES_UNOWN_B + 2) diff --git a/include/data.h b/include/data.h index 99b695d72f..ef11242801 100644 --- a/include/data.h +++ b/include/data.h @@ -3,7 +3,6 @@ #include "constants/moves.h" -#define SPECIES_SHINY_TAG 500 #define N_FOLLOWER_HAPPY_MESSAGES 31 #define N_FOLLOWER_NEUTRAL_MESSAGES 14 #define N_FOLLOWER_SAD_MESSAGES 3 diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 77aee61fc0..a19d7a5169 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -1672,6 +1672,12 @@ static u8 TrySetupObjectEventSprite(const struct ObjectEventTemplate *objectEven spriteTemplate->tileTag = LoadSheetGraphicsInfo(graphicsInfo, objectEvent->graphicsId, NULL); #endif + if (objectEvent->graphicsId >= OBJ_EVENT_GFX_MON_BASE + SPECIES_SHINY_TAG) + { + objectEvent->shiny = TRUE; + objectEvent->graphicsId -= SPECIES_SHINY_TAG; + } + spriteId = CreateSprite(spriteTemplate, 0, 0, 0); if (spriteId == MAX_SPRITES) { @@ -2749,6 +2755,8 @@ const struct ObjectEventGraphicsInfo *GetObjectEventGraphicsInfo(u16 graphicsId) if (graphicsId >= OBJ_EVENT_GFX_VARS && graphicsId <= OBJ_EVENT_GFX_VAR_F) graphicsId = VarGetObjectEventGraphicsId(graphicsId - OBJ_EVENT_GFX_VARS); + if (graphicsId >= OBJ_EVENT_GFX_MON_BASE + SPECIES_SHINY_TAG) + graphicsId -= SPECIES_SHINY_TAG; // graphicsId may contain mon form info if (graphicsId > OBJ_EVENT_GFX_SPECIES_MASK) { form = graphicsId >> OBJ_EVENT_GFX_SPECIES_BITS; From 839cf2e79012e0fc9159af5ab9e6a497e86bbfa4 Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Sun, 1 Sep 2024 15:31:12 -0400 Subject: [PATCH 3/4] feat: static OW pokemon now bob while walking in place (per `OW_MON_BOBBING`) --- include/constants/event_objects.h | 3 +++ src/event_object_movement.c | 24 ++++++++++++++++-------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/include/constants/event_objects.h b/include/constants/event_objects.h index 2e7ec7939f..9c9c1c75e2 100644 --- a/include/constants/event_objects.h +++ b/include/constants/event_objects.h @@ -287,6 +287,9 @@ #define OW_SPECIES(x) (((x)->graphicsId & OBJ_EVENT_GFX_SPECIES_MASK) - OBJ_EVENT_GFX_MON_BASE) #define OW_FORM(x) ((x)->graphicsId >> OBJ_EVENT_GFX_SPECIES_BITS) +// Whether Object Event is an OW pokemon +#define IS_OW_MON_OBJ(obj) ((obj)->graphicsId >= OBJ_EVENT_GFX_MON_BASE) + // If true, follower pokemon will bob up and down // during their idle & walking animations #define OW_MON_BOBBING TRUE diff --git a/src/event_object_movement.c b/src/event_object_movement.c index a19d7a5169..ea8a6b97a9 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -1416,7 +1416,7 @@ static u8 InitObjectEventStateFromTemplate(const struct ObjectEventTemplate *tem objectEvent->triggerGroundEffectsOnMove = TRUE; objectEvent->graphicsId = PackGraphicsId(template); SetObjectEventDynamicGraphicsId(objectEvent); - if (objectEvent->graphicsId >= OBJ_EVENT_GFX_MON_BASE) { + if (IS_OW_MON_OBJ(objectEvent)) { if (template->script && template->script[0] == 0x7d) objectEvent->shiny = T1_READ_16(&template->script[2]) >> 15; else if (template->trainerRange_berryTreeId) @@ -1715,7 +1715,7 @@ static u16 PackGraphicsId(const struct ObjectEventTemplate *template) { u32 form = 0; // set form based on template's script, // if first command is bufferspeciesname - if (graphicsId >= OBJ_EVENT_GFX_MON_BASE) { + if (IS_OW_MON_OBJ(template)) { if (template->script && template->script[0] == 0x7d) { form = T1_READ_16(&template->script[2]); form = (form >> 10) & 0x1F; @@ -5300,7 +5300,7 @@ bool8 MovementType_FollowPlayer_Active(struct ObjectEvent *objectEvent, struct S // Animate entering pokeball ClearObjectEventMovement(objectEvent, sprite); ObjectEventSetSingleMovement(objectEvent, sprite, MOVEMENT_ACTION_ENTER_POKEBALL); - objectEvent->singleMovementActive = 1; + objectEvent->singleMovementActive = TRUE; sprite->sTypeFuncId = 2; // movement action sets state to 0 return TRUE; } @@ -5317,7 +5317,7 @@ bool8 MovementType_FollowPlayer_Moving(struct ObjectEvent *objectEvent, struct S #else if (ObjectEventExecSingleMovementAction(objectEvent, sprite)) { #endif - objectEvent->singleMovementActive = 0; + objectEvent->singleMovementActive = FALSE; if (sprite->sTypeFuncId) // restore nonzero state sprite->sTypeFuncId = 1; } else if (objectEvent->movementActionId < MOVEMENT_ACTION_EXIT_POKEBALL) { @@ -5334,11 +5334,11 @@ bool8 FollowablePlayerMovement_Idle(struct ObjectEvent *objectEvent, struct Spri // walk in place ObjectEventSetSingleMovement(objectEvent, sprite, GetWalkInPlaceNormalMovementAction(objectEvent->facingDirection)); sprite->sTypeFuncId = 1; - objectEvent->singleMovementActive = 1; + objectEvent->singleMovementActive = TRUE; return TRUE; } else if (ObjectEventExecSingleMovementAction(objectEvent, sprite)) { // finish movement action - objectEvent->singleMovementActive = 0; + objectEvent->singleMovementActive = FALSE; } else if (OW_MON_BOBBING == TRUE && (sprite->data[3] & 7) == 2) sprite->y2 ^= -1; UpdateFollowerTransformEffect(objectEvent, sprite); @@ -5377,7 +5377,7 @@ bool8 FollowablePlayerMovement_Step(struct ObjectEvent *objectEvent, struct Spri } MoveObjectEventToMapCoords(objectEvent, targetX, targetY); ObjectEventSetSingleMovement(objectEvent, sprite, MOVEMENT_ACTION_EXIT_POKEBALL); - objectEvent->singleMovementActive = 1; + objectEvent->singleMovementActive = TRUE; sprite->sTypeFuncId = 2; if (OW_MON_BOBBING == TRUE) sprite->y2 = 0; @@ -5429,7 +5429,7 @@ bool8 FollowablePlayerMovement_Step(struct ObjectEvent *objectEvent, struct Spri sprite->y2 = -1; } #endif - objectEvent->singleMovementActive = 1; + objectEvent->singleMovementActive = TRUE; sprite->sTypeFuncId = 2; return TRUE; } @@ -5611,6 +5611,14 @@ bool8 MovementType_MoveInPlace_Step1(struct ObjectEvent *objectEvent, struct Spr { if (ObjectEventExecSingleMovementAction(objectEvent, sprite)) sprite->sTypeFuncId = 0; + // similar to FollowablePlayerMovement_Idle + else if ( + OW_MON_BOBBING == TRUE + && IS_OW_MON_OBJ(objectEvent) + && (sprite->data[3] & 7) == 2) + { + sprite->y2 ^= 1; + } return FALSE; } From 42d9f24c8472a67d742d9d9da106480c84514336 Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Sun, 1 Sep 2024 17:15:29 -0400 Subject: [PATCH 4/4] feat: added `OW_MON_WANDER_WALK` config option --- include/constants/event_objects.h | 3 + include/event_object_movement.h | 4 +- .../object_events/movement_type_func_tables.h | 6 +- src/event_object_movement.c | 61 +++++++++---------- 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/include/constants/event_objects.h b/include/constants/event_objects.h index 9c9c1c75e2..a6963d6247 100644 --- a/include/constants/event_objects.h +++ b/include/constants/event_objects.h @@ -293,6 +293,9 @@ // If true, follower pokemon will bob up and down // during their idle & walking animations #define OW_MON_BOBBING TRUE +// If true, OW pokemon with `MOVEMENT_TYPE_WANDER*` +// will walk-in-place in between steps +#define OW_MON_WANDER_WALK TRUE // If true, adds a small amount of overhead // to OW code so that large (48x48, 64x64) OWs diff --git a/include/event_object_movement.h b/include/event_object_movement.h index 7bd697875b..ab62ae2987 100644 --- a/include/event_object_movement.h +++ b/include/event_object_movement.h @@ -295,7 +295,7 @@ u8 CreateCopySpriteAt(struct Sprite *sprite, s16 x, s16 y, u8 subpriority); u8 MovementType_WanderAround_Step0(struct ObjectEvent *, struct Sprite *); u8 MovementType_WanderAround_Step1(struct ObjectEvent *, struct Sprite *); u8 MovementType_WanderAround_Step2(struct ObjectEvent *, struct Sprite *); -u8 MovementType_WanderAround_Step3(struct ObjectEvent *, struct Sprite *); +u8 MovementType_Wander_Step3(struct ObjectEvent *, struct Sprite *); u8 MovementType_WanderAround_Step4(struct ObjectEvent *, struct Sprite *); u8 MovementType_WanderAround_Step5(struct ObjectEvent *, struct Sprite *); u8 MovementType_WanderAround_Step6(struct ObjectEvent *, struct Sprite *); @@ -318,14 +318,12 @@ u8 MovementType_LookAround_Step4(struct ObjectEvent *, struct Sprite *); u8 MovementType_WanderUpAndDown_Step0(struct ObjectEvent *, struct Sprite *); u8 MovementType_WanderUpAndDown_Step1(struct ObjectEvent *, struct Sprite *); u8 MovementType_WanderUpAndDown_Step2(struct ObjectEvent *, struct Sprite *); -u8 MovementType_WanderUpAndDown_Step3(struct ObjectEvent *, struct Sprite *); u8 MovementType_WanderUpAndDown_Step4(struct ObjectEvent *, struct Sprite *); u8 MovementType_WanderUpAndDown_Step5(struct ObjectEvent *, struct Sprite *); u8 MovementType_WanderUpAndDown_Step6(struct ObjectEvent *, struct Sprite *); u8 MovementType_WanderLeftAndRight_Step0(struct ObjectEvent *, struct Sprite *); u8 MovementType_WanderLeftAndRight_Step1(struct ObjectEvent *, struct Sprite *); u8 MovementType_WanderLeftAndRight_Step2(struct ObjectEvent *, struct Sprite *); -u8 MovementType_WanderLeftAndRight_Step3(struct ObjectEvent *, struct Sprite *); u8 MovementType_WanderLeftAndRight_Step4(struct ObjectEvent *, struct Sprite *); u8 MovementType_WanderLeftAndRight_Step5(struct ObjectEvent *, struct Sprite *); u8 MovementType_WanderLeftAndRight_Step6(struct ObjectEvent *, struct Sprite *); diff --git a/src/data/object_events/movement_type_func_tables.h b/src/data/object_events/movement_type_func_tables.h index 749c14969c..35180f5b3c 100755 --- a/src/data/object_events/movement_type_func_tables.h +++ b/src/data/object_events/movement_type_func_tables.h @@ -2,7 +2,7 @@ u8 (*const gMovementTypeFuncs_WanderAround[])(struct ObjectEvent *, struct Sprit MovementType_WanderAround_Step0, MovementType_WanderAround_Step1, MovementType_WanderAround_Step2, - MovementType_WanderAround_Step3, + MovementType_Wander_Step3, MovementType_WanderAround_Step4, MovementType_WanderAround_Step5, MovementType_WanderAround_Step6, @@ -36,7 +36,7 @@ u8 (*const gMovementTypeFuncs_WanderUpAndDown[])(struct ObjectEvent *, struct Sp MovementType_WanderUpAndDown_Step0, MovementType_WanderUpAndDown_Step1, MovementType_WanderUpAndDown_Step2, - MovementType_WanderUpAndDown_Step3, + MovementType_Wander_Step3, MovementType_WanderUpAndDown_Step4, MovementType_WanderUpAndDown_Step5, MovementType_WanderUpAndDown_Step6, @@ -48,7 +48,7 @@ u8 (*const gMovementTypeFuncs_WanderLeftAndRight[])(struct ObjectEvent *, struct MovementType_WanderLeftAndRight_Step0, MovementType_WanderLeftAndRight_Step1, MovementType_WanderLeftAndRight_Step2, - MovementType_WanderLeftAndRight_Step3, + MovementType_Wander_Step3, MovementType_WanderLeftAndRight_Step4, MovementType_WanderLeftAndRight_Step5, MovementType_WanderLeftAndRight_Step6, diff --git a/src/event_object_movement.c b/src/event_object_movement.c index ea8a6b97a9..4f2cc94ea7 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -103,6 +103,7 @@ static EWRAM_DATA struct LockedAnimObjectEvents *sLockedAnimObjectEvents = {0}; static void MoveCoordsInDirection(u32, s16 *, s16 *, s16, s16); static bool8 ObjectEventExecSingleMovementAction(struct ObjectEvent *, struct Sprite *); +static bool32 UpdateMonMoveInPlace(struct ObjectEvent *, struct Sprite *); static void SetMovementDelay(struct Sprite *, s16); static bool8 WaitForMovementDelay(struct Sprite *); static u8 GetCollisionInDirection(struct ObjectEvent *, u8); @@ -3436,12 +3437,20 @@ bool8 MovementType_WanderAround_Step2(struct ObjectEvent *objectEvent, struct Sp return TRUE; } -bool8 MovementType_WanderAround_Step3(struct ObjectEvent *objectEvent, struct Sprite *sprite) +// common; used by all MovementType_Wander*_Step3 +bool8 MovementType_Wander_Step3(struct ObjectEvent *objectEvent, struct Sprite *sprite) { if (WaitForMovementDelay(sprite)) { + // resets a mid-movement sprite + ClearObjectEventMovement(objectEvent, sprite); sprite->sTypeFuncId = 4; return TRUE; + } else if ( + OW_MON_WANDER_WALK == TRUE + && IS_OW_MON_OBJ(objectEvent)) + { + UpdateMonMoveInPlace(objectEvent, sprite); } return FALSE; } @@ -3768,16 +3777,6 @@ bool8 MovementType_WanderUpAndDown_Step2(struct ObjectEvent *objectEvent, struct return TRUE; } -bool8 MovementType_WanderUpAndDown_Step3(struct ObjectEvent *objectEvent, struct Sprite *sprite) -{ - if (WaitForMovementDelay(sprite)) - { - sprite->sTypeFuncId = 4; - return TRUE; - } - return FALSE; -} - bool8 MovementType_WanderUpAndDown_Step4(struct ObjectEvent *objectEvent, struct Sprite *sprite) { u8 direction; @@ -3836,16 +3835,6 @@ bool8 MovementType_WanderLeftAndRight_Step2(struct ObjectEvent *objectEvent, str return TRUE; } -bool8 MovementType_WanderLeftAndRight_Step3(struct ObjectEvent *objectEvent, struct Sprite *sprite) -{ - if (WaitForMovementDelay(sprite)) - { - sprite->sTypeFuncId = 4; - return TRUE; - } - return FALSE; -} - bool8 MovementType_WanderLeftAndRight_Step4(struct ObjectEvent *objectEvent, struct Sprite *sprite) { u8 direction; @@ -5328,19 +5317,27 @@ bool8 MovementType_FollowPlayer_Moving(struct ObjectEvent *objectEvent, struct S return FALSE; } -bool8 FollowablePlayerMovement_Idle(struct ObjectEvent *objectEvent, struct Sprite *sprite, u8 playerDirection, bool8 tileCallback(u8)) -{ +// single function for updating an OW mon's walk-in-place movements +static bool32 UpdateMonMoveInPlace(struct ObjectEvent *objectEvent, struct Sprite *sprite) { if (!objectEvent->singleMovementActive) { // walk in place - ObjectEventSetSingleMovement(objectEvent, sprite, GetWalkInPlaceNormalMovementAction(objectEvent->facingDirection)); - sprite->sTypeFuncId = 1; - objectEvent->singleMovementActive = TRUE; - return TRUE; + ObjectEventSetSingleMovement(objectEvent, sprite, GetWalkInPlaceNormalMovementAction(objectEvent->facingDirection)); + objectEvent->singleMovementActive = TRUE; + return TRUE; } else if (ObjectEventExecSingleMovementAction(objectEvent, sprite)) { // finish movement action objectEvent->singleMovementActive = FALSE; } else if (OW_MON_BOBBING == TRUE && (sprite->data[3] & 7) == 2) sprite->y2 ^= -1; + return FALSE; +} + +bool8 FollowablePlayerMovement_Idle(struct ObjectEvent *objectEvent, struct Sprite *sprite, u8 playerDirection, bool8 tileCallback(u8)) +{ + if (UpdateMonMoveInPlace(objectEvent, sprite)) { + sprite->sTypeFuncId = 1; + return TRUE; + } UpdateFollowerTransformEffect(objectEvent, sprite); return FALSE; } @@ -5611,7 +5608,7 @@ bool8 MovementType_MoveInPlace_Step1(struct ObjectEvent *objectEvent, struct Spr { if (ObjectEventExecSingleMovementAction(objectEvent, sprite)) sprite->sTypeFuncId = 0; - // similar to FollowablePlayerMovement_Idle + // similar to UpdateMonMoveInPlace else if ( OW_MON_BOBBING == TRUE && IS_OW_MON_OBJ(objectEvent) @@ -10058,14 +10055,16 @@ static u8 DoJumpSpecialSpriteMovement(struct Sprite *sprite) static void SetMovementDelay(struct Sprite *sprite, s16 timer) { - sprite->data[3] = timer; + sprite->data[3] = timer; // kept for legacy reasons + sprite->data[7] = timer; // actual timer } static bool8 WaitForMovementDelay(struct Sprite *sprite) { - if (--sprite->data[3] == 0) + if (--sprite->data[7] == 0) { + sprite->data[3] = 0; // reset animation timer return TRUE; - else + } else return FALSE; }