From 10265938f76f5e08e68838aeab0cfd91e7a0f5a8 Mon Sep 17 00:00:00 2001 From: W1serV1ser <1prefertheaircauseimanairnomad@gmail.com> Date: Sun, 2 Apr 2023 18:11:18 -0700 Subject: [PATCH 1/3] Bug fixes involving warps and followers Fixes issues where follower would load in strangely after a scripted warp. Also added a macro (setfollowerwarppos) to control how the follower appears after scripted warps. --- asm/macros/event.inc | 5 ++++ src/event_object_movement.c | 22 +++++++++++++++++ src/field_control_avatar.c | 4 +++- src/field_screen_effect.c | 8 +++++-- src/follow_me.c | 4 ++++ src/overworld.c | 48 +++++++++++++++++++++++++++++++++++++ 6 files changed, 88 insertions(+), 3 deletions(-) diff --git a/asm/macros/event.inc b/asm/macros/event.inc index e0e221aa2..b021bf177 100644 --- a/asm/macros/event.inc +++ b/asm/macros/event.inc @@ -1984,3 +1984,8 @@ setvar VAR_UNUSED_0x8014, 0 callnative FollowerIntoPokeball .endm + + .macro setfollowerwarppos pos:req + setvar VAR_RESULT, \pos + callnative SetFollowerWarpPosition + .endm diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 3720c79f4..0104814b3 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -10459,6 +10459,28 @@ u8 MovementAction_FollowingPokemon_Grow_Step1(struct ObjectEvent *objectEvent, s StartFieldEffectForObjectEvent(FLDEFF_FEET_IN_FLOWING_WATER, objectEvent); } gPlayerAvatar.preventStep = FALSE; + + // Account for warps in scripts where the follower needs to pop out of a pokeball afterwards + if (gSaveBlock2Ptr->follower.createSurfBlob == 2) + { + sprite->data[7] = 0; + gSaveBlock2Ptr->follower.createSurfBlob = 0; + switch(gObjectEvents[gPlayerAvatar.objectEventId].facingDirection) + { + case DIR_SOUTH: + ObjectEventForceSetHeldMovement(objectEvent, MOVEMENT_ACTION_FOLLOWING_POKEMON_FACESOUTH); + break; + case DIR_NORTH: + ObjectEventForceSetHeldMovement(objectEvent, MOVEMENT_ACTION_FOLLOWING_POKEMON_FACENORTH); + break; + case DIR_WEST: + ObjectEventForceSetHeldMovement(objectEvent, MOVEMENT_ACTION_FOLLOWING_POKEMON_FACEWEST); + break; + case DIR_EAST: + ObjectEventForceSetHeldMovement(objectEvent, MOVEMENT_ACTION_FOLLOWING_POKEMON_FACEEAST); + break; + } + } sprite->data[2]++; } diff --git a/src/field_control_avatar.c b/src/field_control_avatar.c index 69fab048a..9ac3085ee 100644 --- a/src/field_control_avatar.c +++ b/src/field_control_avatar.c @@ -161,8 +161,10 @@ int ProcessPlayerFieldInput(struct FieldInput *input) if (TryStartStepBasedScript(&position, metatileBehavior, playerDirection) == TRUE) return TRUE; } - else if(gSaveBlock2Ptr->follower.inProgress) + else if(gSaveBlock2Ptr->follower.inProgress && gSaveBlock2Ptr->follower.createSurfBlob != 2) { + // Keep the follower bouncing, unless we're dealing with a follower coming out of a pokeball after a scripted warp. + // Need to stop bouncing to run the grow-out-of-pokeball animation ObjectEventClearHeldMovementIfFinished(&gObjectEvents[gSaveBlock2Ptr->follower.objId]); ObjectEventSetHeldMovement(&gObjectEvents[gSaveBlock2Ptr->follower.objId], 0x9E); } diff --git a/src/field_screen_effect.c b/src/field_screen_effect.c index 090f920ef..ce4d3ed2f 100644 --- a/src/field_screen_effect.c +++ b/src/field_screen_effect.c @@ -435,7 +435,11 @@ static void Task_ExitNonDoor(u8 taskId) if (WaitForWeatherFadeIn()) { UnfreezeObjectEvents(); - gSaveBlock2Ptr->follower.comeOutDoorStairs = 2; + + // Account for follower exiting pokeball after scripted warp + if (gSaveBlock2Ptr->follower.createSurfBlob != 2) + gSaveBlock2Ptr->follower.comeOutDoorStairs = 2; + UnlockPlayerFieldControls(); DestroyTask(taskId); } @@ -979,7 +983,7 @@ static void Task_SpinEnterWarp(u8 taskId) case 1: if (WaitForWeatherFadeIn() && IsPlayerSpinEntranceActive() != TRUE) { - FollowMe_WarpSetEnd(); + //FollowMe_WarpSetEnd(); UnfreezeObjectEvents(); UnlockPlayerFieldControls(); DestroyTask(taskId); diff --git a/src/follow_me.c b/src/follow_me.c index dbe0ebb2d..31af6212e 100644 --- a/src/follow_me.c +++ b/src/follow_me.c @@ -1528,3 +1528,7 @@ void ShowFollower(void) gObjectEvents[gSaveBlock2Ptr->follower.objId].invisible = FALSE; } +void SetFollowerWarpPosition(void) +{ + gSaveBlock2Ptr->follower.createSurfBlob = 1; +} diff --git a/src/overworld.c b/src/overworld.c index 5cd5b2859..4c8389826 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -1142,6 +1142,44 @@ static void SetPlayerCoordsFromWarp(void) } } +static void SetFollowerCoordsFromWarp(void) +{ + struct ObjectEvent* player = &gObjectEvents[gPlayerAvatar.objectEventId]; + struct ObjectEvent* follower = &gObjectEvents[gSaveBlock2Ptr->follower.objId]; + + gSaveBlock2Ptr->follower.warpEnd = 0; + + // Based on value passed in via setfollowerwarppos macro, place the follower relative to the player. + // If DIR_NONE, then setup for follower popping out of pokeball + switch(gSpecialVar_Result) + { + case DIR_NONE: + MoveObjectEventToMapCoords(follower, player->currentCoords.x, player->currentCoords.y); + gSaveBlock2Ptr->follower.createSurfBlob = 2; + break; + case DIR_SOUTH: + MoveObjectEventToMapCoords(follower, player->currentCoords.x, player->currentCoords.y + 1); + follower->invisible = FALSE; + gSaveBlock2Ptr->follower.createSurfBlob = 0; + break; + case DIR_NORTH: + MoveObjectEventToMapCoords(follower, player->currentCoords.x, player->currentCoords.y - 1); + follower->invisible = FALSE; + gSaveBlock2Ptr->follower.createSurfBlob = 0; + break; + case DIR_WEST: + MoveObjectEventToMapCoords(follower, player->currentCoords.x - 1, player->currentCoords.y); + follower->invisible = FALSE; + gSaveBlock2Ptr->follower.createSurfBlob = 0; + break; + case DIR_EAST: + MoveObjectEventToMapCoords(follower, player->currentCoords.x + 1, player->currentCoords.y); + follower->invisible = FALSE; + gSaveBlock2Ptr->follower.createSurfBlob = 0; + break; + } +} + void WarpIntoMap(void) { ApplyCurrentWarp(); @@ -2109,6 +2147,10 @@ static void CB2_LoadMap2(void) SetFieldVBlankCallback(); SetMainCallback1(CB1_Overworld); SetMainCallback2(CB2_Overworld); + + // Handle placing follower after warp as determined via setfollowerwarppos macro + if (gSaveBlock2Ptr->follower.inProgress && gSaveBlock2Ptr->follower.createSurfBlob == 1) + SetFollowerCoordsFromWarp(); } void CB2_ReturnToFieldContestHall(void) @@ -2497,6 +2539,12 @@ static bool32 ReturnToFieldLocal(u8 *state) break; case 1: InitViewGraphics(); + + #if FAST_FOLLOWERS == TRUE + if (FlagGet(FLAG_FOLLOWER_IN_BUILDING)) + FieldSetDoorOpened(gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.x, gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.y - 1); + #endif + TryLoadTrainerHillEReaderPalette(); (*state)++; break; From b0e907962d37992af886c0337ac1464ce5a0bc6b Mon Sep 17 00:00:00 2001 From: W1serV1ser <1prefertheaircauseimanairnomad@gmail.com> Date: Mon, 3 Apr 2023 14:27:12 -0700 Subject: [PATCH 2/3] Added missing #include --- src/overworld.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/overworld.c b/src/overworld.c index 4c8389826..8a2b43b7d 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -11,6 +11,7 @@ #include "event_scripts.h" #include "field_camera.h" #include "field_control_avatar.h" +#include "field_door.h" #include "field_effect.h" #include "field_message_box.h" #include "field_player_avatar.h" From c593ee6fac4274e1a4b459e8c8a69be99876abeb Mon Sep 17 00:00:00 2001 From: W1serV1ser <1prefertheaircauseimanairnomad@gmail.com> Date: Fri, 7 Apr 2023 12:14:09 -0700 Subject: [PATCH 3/3] Sprite priority & follower face command fixes --- src/event_object_movement.c | 9 +++++++++ src/field_effect_helpers.c | 1 + 2 files changed, 10 insertions(+) diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 0104814b3..af50c4596 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -8573,6 +8573,13 @@ void ObjectEventUpdateElevation(struct ObjectEvent *objEvent) if (curElevation == 15 || prevElevation == 15) return; + + if (gSaveBlock2Ptr->follower.inProgress && + objEvent == &gObjectEvents[gSaveBlock2Ptr->follower.objId] && + objEvent->currentCoords.y == gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.y - 1) + { + curElevation = gObjectEvents[gPlayerAvatar.objectEventId].currentElevation; + } objEvent->currentElevation = curElevation; @@ -9962,6 +9969,7 @@ u8 MovementAction_FollowingPokemon_FaceSouth_Step0(struct ObjectEvent *objectEve SetObjectEventDirection(objectEvent, DIR_SOUTH); RecreateObjectEvent(objectEvent, sprite); sprite->animNum = 0; + sprite->x2 = 0; MoveObjectEventToMapCoords(objectEvent, objectEvent->currentCoords.x, objectEvent->currentCoords.y); sprite->data[2]++; return FALSE; @@ -9972,6 +9980,7 @@ u8 MovementAction_FollowingPokemon_FaceNorth_Step0(struct ObjectEvent *objectEve SetObjectEventDirection(objectEvent, DIR_NORTH); RecreateObjectEvent(objectEvent, sprite); sprite->animNum = 1; + sprite->x2 = 0; MoveObjectEventToMapCoords(objectEvent, objectEvent->currentCoords.x, objectEvent->currentCoords.y); sprite->data[2]++; return FALSE; diff --git a/src/field_effect_helpers.c b/src/field_effect_helpers.c index e43af934e..69d3341bc 100644 --- a/src/field_effect_helpers.c +++ b/src/field_effect_helpers.c @@ -742,6 +742,7 @@ u32 FldEff_Splash(void) sprite = &gSprites[spriteId]; sprite->coordOffsetEnabled = TRUE; linkedSprite = &gSprites[objectEvent->spriteId]; + sprite->subpriority = linkedSprite->subpriority - 1; sprite->oam.priority = linkedSprite->oam.priority; sprite->data[0] = gFieldEffectArguments[0]; sprite->data[1] = gFieldEffectArguments[1];