diff --git a/data/scripts/movement.inc b/data/scripts/movement.inc index 383c014130..a5ebc0ae7f 100644 --- a/data/scripts/movement.inc +++ b/data/scripts/movement.inc @@ -1,3 +1,6 @@ +@ Starting from here, these movements are considered +@ 'safe' (won't put follower into a Pokeball) +Common_Movement_FollowerSafeStart:: Common_Movement_QuestionMark: emote_question_mark step_end @@ -68,6 +71,10 @@ Common_Movement_WalkInPlaceRight: walk_in_place_right step_end +@ End of follower-safe movements +Common_Movement_FollowerSafeEnd:: + step_end + Common_Movement_WalkUp6: walk_up walk_up diff --git a/graphics/object_events/pics/pokemon/wailord.png b/graphics/object_events/pics/pokemon/wailord.png index a7032a856a..a1fc3a087a 100644 Binary files a/graphics/object_events/pics/pokemon/wailord.png and b/graphics/object_events/pics/pokemon/wailord.png differ diff --git a/include/event_scripts.h b/include/event_scripts.h index a64b8ffc4c..2fa4468c74 100644 --- a/include/event_scripts.h +++ b/include/event_scripts.h @@ -639,4 +639,7 @@ extern const u8 EventScript_TradeCenter_Chair0[]; extern const u8 EventScript_ConfirmLeaveCableClubRoom[]; extern const u8 EventScript_TerminateLink[]; +extern const u8 Common_Movement_FollowerSafeStart[]; +extern const u8 Common_Movement_FollowerSafeEnd[]; + #endif // GUARD_EVENT_SCRIPTS_H diff --git a/src/data/object_events/object_event_graphics.h b/src/data/object_events/object_event_graphics.h index b687a4855e..23aee5b37e 100755 --- a/src/data/object_events/object_event_graphics.h +++ b/src/data/object_events/object_event_graphics.h @@ -701,7 +701,7 @@ const u32 gObjectEventPic_Swalot[] = INCBIN_COMP("graphics/object_events/pics/po const u32 gObjectEventPic_Carvanha[] = INCBIN_COMP("graphics/object_events/pics/pokemon/carvanha.4bpp"); const u32 gObjectEventPic_Sharpedo[] = INCBIN_COMP("graphics/object_events/pics/pokemon/sharpedo.4bpp"); const u32 gObjectEventPic_Wailmer[] = INCBIN_COMP("graphics/object_events/pics/pokemon/wailmer.4bpp"); -const u32 gObjectEventPic_Wailord[] = INCBIN_U32("graphics/object_events/pics/pokemon/wailord.4bpp"); +const u32 gObjectEventPic_Wailord[] = INCBIN_COMP("graphics/object_events/pics/pokemon/wailord.4bpp"); const u32 gObjectEventPic_Numel[] = INCBIN_COMP("graphics/object_events/pics/pokemon/numel.4bpp"); const u32 gObjectEventPic_Camerupt[] = INCBIN_COMP("graphics/object_events/pics/pokemon/camerupt.4bpp"); const u32 gObjectEventPic_Torkoal[] = INCBIN_COMP("graphics/object_events/pics/pokemon/torkoal.4bpp"); diff --git a/src/scrcmd.c b/src/scrcmd.c index 6e199a25fa..c8f50a3a7a 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -1009,23 +1009,26 @@ bool8 ScrCmd_fadeinbgm(struct ScriptContext *ctx) bool8 ScrCmd_applymovement(struct ScriptContext *ctx) { u16 localId = VarGet(ScriptReadHalfword(ctx)); - const void *movementScript = (const void *)ScriptReadWord(ctx); + const u8 *movementScript = (const u8 *)ScriptReadWord(ctx); struct ObjectEvent *objEvent; // When applying script movements to follower, it may have frozen animation that must be cleared if (localId == OBJ_EVENT_ID_FOLLOWER && (objEvent = GetFollowerObject()) && objEvent->frozen) { ClearObjectEventMovement(objEvent, &gSprites[objEvent->spriteId]); - gSprites[objEvent->spriteId].animCmdIndex = 0; // Needed to set start frame of animation + gSprites[objEvent->spriteId].animCmdIndex = 0; // Reset start frame of animation } ScriptMovement_StartObjectMovementScript(localId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, movementScript); sMovingNpcId = localId; + objEvent = GetFollowerObject(); // Force follower into pokeball - if (localId != OBJ_EVENT_ID_FOLLOWER && !FlagGet(FLAG_SAFE_FOLLOWER_MOVEMENT)) { - objEvent = GetFollowerObject(); - // return early if no follower or in shadowing state - if (objEvent == NULL || gSprites[objEvent->spriteId].data[1] == 0) - return FALSE; + if (localId != OBJ_EVENT_ID_FOLLOWER + && !FlagGet(FLAG_SAFE_FOLLOWER_MOVEMENT) + && (movementScript < Common_Movement_FollowerSafeStart || movementScript > Common_Movement_FollowerSafeEnd) + && (objEvent = GetFollowerObject()) + && !objEvent->invisible) + { ClearObjectEventMovement(objEvent, &gSprites[objEvent->spriteId]); + gSprites[objEvent->spriteId].animCmdIndex = 0; // Reset start frame of animation ScriptMovement_StartObjectMovementScript(OBJ_EVENT_ID_FOLLOWER, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, EnterPokeballMovement); } return FALSE; @@ -1252,7 +1255,7 @@ bool8 ScrCmd_lockall(struct ScriptContext *ctx) } } -// lock freezes all object events except the player and the selected object immediately. +// lock freezes all object events except the player, follower, and the selected object immediately. // The player and selected object are frozen after waiting for their current movement to finish. bool8 ScrCmd_lock(struct ScriptContext *ctx) { @@ -1262,16 +1265,22 @@ bool8 ScrCmd_lock(struct ScriptContext *ctx) } else { + struct ObjectEvent *followerObj = GetFollowerObject(); if (gObjectEvents[gSelectedObjectEvent].active) { FreezeObjects_WaitForPlayerAndSelected(); SetupNativeScript(ctx, IsFreezeSelectedObjectAndPlayerFinished); + // follower is being talked to; keep it frozen + if (gObjectEvents[gSelectedObjectEvent].localId == OBJ_EVENT_ID_FOLLOWER) + followerObj = NULL; } else { FreezeObjects_WaitForPlayer(); SetupNativeScript(ctx, IsFreezePlayerFinished); } + if (followerObj) // Unfreeze follower object + UnfreezeObjectEvent(followerObj); return TRUE; } }