From c78736c94f8879b1cddf43f998ab4d3ae3f4590e Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Tue, 15 Mar 2022 18:53:06 -0400 Subject: [PATCH 1/3] Fixed bug where decor icons cleared dynamic palettes in the Frontier Exchange Corner shop. --- include/field_effect.h | 1 + src/field_specials.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/field_effect.h b/include/field_effect.h index 073fc3b4cc..9bd76e06fc 100644 --- a/include/field_effect.h +++ b/include/field_effect.h @@ -25,6 +25,7 @@ void FieldEffectScript_LoadTiles(u8 **script); void FieldEffectScript_LoadFadedPalette(u8 **script); void FieldEffectScript_LoadPalette(u8 **script); void FieldEffectScript_CallNative(u8 **script, u32 *val); +void FieldEffectFreeGraphicsResources(struct Sprite *sprite); void FieldEffectFreeTilesIfUnused(u16 tileStart); void FieldEffectFreePaletteIfUnused(u8 paletteNum); bool8 FieldEffectCmd_loadtiles(u8 **script, u32 *val); diff --git a/src/field_specials.c b/src/field_specials.c index 96eb949e55..da17065005 100644 --- a/src/field_specials.c +++ b/src/field_specials.c @@ -3118,7 +3118,8 @@ static void HideFrontierExchangeCornerItemIcon(u16 menu, u16 unused) case SCROLL_MULTI_BF_EXCHANGE_CORNER_DECOR_VENDOR_2: case SCROLL_MULTI_BF_EXCHANGE_CORNER_VITAMIN_VENDOR: case SCROLL_MULTI_BF_EXCHANGE_CORNER_HOLD_ITEM_VENDOR: - DestroySpriteAndFreeResources(&gSprites[sScrollableMultichoice_ItemSpriteId]); + // This makes sure deleting the icon will not clear palettes in use by object events + FieldEffectFreeGraphicsResources(&gSprites[sScrollableMultichoice_ItemSpriteId]); break; } sScrollableMultichoice_ItemSpriteId = MAX_SPRITES; From 570b5927c291549a13d4e20b2601023ba1a17d5d Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Tue, 15 Mar 2022 19:20:13 -0400 Subject: [PATCH 2/3] Fixed script `release` breaking followers when called mid-movement. --- src/scrcmd.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/scrcmd.c b/src/scrcmd.c index 6ec06cced9..ae2cbfc335 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -1032,7 +1032,15 @@ bool8 ScrCmd_applymovement_at(struct ScriptContext *ctx) static bool8 WaitForMovementFinish(void) { - return ScriptMovement_IsObjectMovementFinished(sMovingNpcId, sMovingNpcMapNum, sMovingNpcMapGroup); + if (ScriptMovement_IsObjectMovementFinished(sMovingNpcId, sMovingNpcMapNum, sMovingNpcMapGroup)) { + struct ObjectEvent *objEvent = GetFollowerObject(); + // If the follower is still entering the pokeball, wait for it to finish too + // This prevents a `release` after this script command from getting the follower stuck in an intermediate state + if (sMovingNpcId != OBJ_EVENT_ID_FOLLOWER && objEvent && ObjectEventGetHeldMovementActionId(objEvent) == MOVEMENT_ACTION_ENTER_POKEBALL) + return ScriptMovement_IsObjectMovementFinished(objEvent->localId, objEvent->mapNum, objEvent->mapGroup); + return TRUE; + } + return FALSE; } bool8 ScrCmd_waitmovement(struct ScriptContext *ctx) From 6ef4e92e76bbde184394b0f30cbc5f59da043130 Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Wed, 16 Mar 2022 18:44:12 -0400 Subject: [PATCH 3/3] Fixed bug where followers could be talked to while invisible. Was caused by quick `applymovements` not giving enough time to move the follower on top of the player. --- src/event_object_movement.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/event_object_movement.c b/src/event_object_movement.c index f96adeef46..6235c1577c 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -4705,6 +4705,12 @@ bool8 MovementType_FollowPlayer_Shadow(struct ObjectEvent *objectEvent, struct S objectEvent->triggerGroundEffectsOnMove = FALSE; // Stop endless reflection spawning return FALSE; } + // Move follower to player, in case we end up in the shadowing state for only 1 frame + // This way the player cannot talk to the invisible follower before it appears + if (objectEvent->invisible) { + MoveObjectEventToMapCoords(objectEvent, gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.x, gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.y); + objectEvent->triggerGroundEffectsOnMove = FALSE; // Stop endless reflection spawning + } sprite->data[1] = 1; // Enter active state; if the player moves the follower will appear return TRUE; }