diff --git a/graphics/object_events/pics/pokemon/togetic.png b/graphics/object_events/pics/pokemon/togetic.png index 74f8346b6a..a7da7b76af 100644 Binary files a/graphics/object_events/pics/pokemon/togetic.png and b/graphics/object_events/pics/pokemon/togetic.png differ diff --git a/include/constants/event_objects.h b/include/constants/event_objects.h index 33b352350c..b9f1aad78d 100644 --- a/include/constants/event_objects.h +++ b/include/constants/event_objects.h @@ -276,6 +276,10 @@ #define OBJ_EVENT_GFX_VAR_E (OBJ_EVENT_GFX_VARS + 0xE) #define OBJ_EVENT_GFX_VAR_F (OBJ_EVENT_GFX_VARS + 0xF) // 255 +// If true, follower pokemon will bob up and down +// during their idle & walking animations +#define OW_MON_BOBBING TRUE + #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 de70311b25..4a0f4f3e58 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -4973,19 +4973,17 @@ bool8 MovementType_FollowPlayer_Shadow(struct ObjectEvent *objectEvent, struct S bool8 MovementType_FollowPlayer_Active(struct ObjectEvent *objectEvent, struct Sprite *sprite) { - if (gPlayerAvatar.tileTransitionState == T_NOT_MOVING && !gObjectEvents[gPlayerAvatar.objectEventId].heldMovementActive ) { // do nothing if player is stationary - return FALSE; - } else if (!IsFollowerVisible()) { - if (objectEvent->invisible) { // Return to shadowing state - sprite->sTypeFuncId = 0; - return FALSE; - } - // Animate entering pokeball - ClearObjectEventMovement(objectEvent, sprite); - ObjectEventSetSingleMovement(objectEvent, sprite, MOVEMENT_ACTION_ENTER_POKEBALL); - objectEvent->singleMovementActive = 1; - sprite->sTypeFuncId = 2; // movement action sets state to 0 - return TRUE; + if (!IsFollowerVisible()) { + if (objectEvent->invisible) { // Return to shadowing state + sprite->sTypeFuncId = 0; + return FALSE; + } + // Animate entering pokeball + ClearObjectEventMovement(objectEvent, sprite); + ObjectEventSetSingleMovement(objectEvent, sprite, MOVEMENT_ACTION_ENTER_POKEBALL); + objectEvent->singleMovementActive = 1; + sprite->sTypeFuncId = 2; // movement action sets state to 0 + return TRUE; } // TODO: Remove dependence on PlayerGetCopyableMovement return gFollowPlayerMovementFuncs[PlayerGetCopyableMovement()](objectEvent, sprite, GetPlayerMovementDirection(), NULL); @@ -5005,23 +5003,33 @@ bool8 MovementType_FollowPlayer_Moving(struct ObjectEvent *objectEvent, struct S if (sprite->sTypeFuncId) { // restore nonzero state sprite->sTypeFuncId = 1; } - } else if (objectEvent->movementActionId != MOVEMENT_ACTION_EXIT_POKEBALL) { + } else if (objectEvent->movementActionId < MOVEMENT_ACTION_EXIT_POKEBALL) { UpdateFollowerTransformEffect(objectEvent, sprite); + #if OW_MON_BOBBING == TRUE + if ((sprite->data[5] & 7) == 2) + sprite->y2 ^= -1; + #endif } return FALSE; } bool8 FollowablePlayerMovement_Idle(struct ObjectEvent *objectEvent, struct Sprite *sprite, u8 playerDirection, bool8 tileCallback(u8)) { - u8 direction; - if (!objectEvent->singleMovementActive) { // walk in place + if (!objectEvent->singleMovementActive) + { // walk in place ObjectEventSetSingleMovement(objectEvent, sprite, GetWalkInPlaceNormalMovementAction(objectEvent->facingDirection)); sprite->sTypeFuncId = 1; objectEvent->singleMovementActive = 1; return TRUE; - } else if (ObjectEventExecSingleMovementAction(objectEvent, sprite)) { // finish movement action + } + else if (ObjectEventExecSingleMovementAction(objectEvent, sprite)) + { // finish movement action objectEvent->singleMovementActive = 0; } + #if OW_MON_BOBBING == TRUE + else if ((sprite->data[3] & 7) == 2) + sprite->y2 ^= -1; + #endif UpdateFollowerTransformEffect(objectEvent, sprite); return FALSE; } @@ -5034,7 +5042,7 @@ bool8 FollowablePlayerMovement_Step(struct ObjectEvent *objectEvent, struct Spri s16 targetX; s16 targetY; #ifdef MB_SIDEWAYS_STAIRS_RIGHT_SIDE - u8 playerAction = gObjectEvents[gPlayerAvatar.objectEventId].movementActionId; + u32 playerAction = gObjectEvents[gPlayerAvatar.objectEventId].movementActionId; #endif targetX = gObjectEvents[gPlayerAvatar.objectEventId].previousCoords.x; @@ -5059,6 +5067,9 @@ bool8 FollowablePlayerMovement_Step(struct ObjectEvent *objectEvent, struct Spri ObjectEventSetSingleMovement(objectEvent, sprite, MOVEMENT_ACTION_EXIT_POKEBALL); objectEvent->singleMovementActive = 1; sprite->sTypeFuncId = 2; + #if OW_MON_BOBBING == TRUE + sprite->y2 = 0; + #endif return TRUE; } else if (x == targetX && y == targetY) { // don't move if already in the player's last position return FALSE; @@ -5082,8 +5093,12 @@ bool8 FollowablePlayerMovement_Step(struct ObjectEvent *objectEvent, struct Spri } else { if (playerAction >= MOVEMENT_ACTION_WALK_SLOW_DOWN && playerAction <= MOVEMENT_ACTION_WALK_SLOW_RIGHT) ObjectEventSetSingleMovement(objectEvent, sprite, GetWalkSlowMovementAction(direction)); - else + else { objectEvent->movementActionId = GetWalkNormalMovementAction(direction); + #if OW_MON_BOBBING == TRUE + sprite->y2 = -1; + #endif + } } sprite->sActionFuncId = 0; #else @@ -5094,8 +5109,12 @@ bool8 FollowablePlayerMovement_Step(struct ObjectEvent *objectEvent, struct Spri // If *player* jumps, make step take twice as long else if (PlayerGetCopyableMovement() == COPY_MOVE_JUMP2) ObjectEventSetSingleMovement(objectEvent, sprite, GetWalkSlowMovementAction(direction)); - else + else { ObjectEventSetSingleMovement(objectEvent, sprite, GetWalkNormalMovementAction(direction)); + #if OW_MON_BOBBING == TRUE + sprite->y2 = -1; + #endif + } #endif objectEvent->singleMovementActive = 1; sprite->sTypeFuncId = 2;