mirror of
https://github.com/resetes12/pokeemerald
synced 2025-10-06 00:12:45 +02:00
Followers 4056804
&& d73167e: improved follower handling during scripted movements (DISABLED)
This commit is contained in:
@@ -2023,3 +2023,11 @@
|
|||||||
setvar VAR_0x8001, \stringvarnumber
|
setvar VAR_0x8001, \stringvarnumber
|
||||||
special BufferUnitSystemText
|
special BufferUnitSystemText
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
@ hide any follower pokemon if present,
|
||||||
|
@ putting them into their pokeball;
|
||||||
|
@ by default waits for their movement to finish
|
||||||
|
.macro hidefollower wait=1
|
||||||
|
callfunc ScrFunc_hidefollower
|
||||||
|
.2byte \wait
|
||||||
|
.endm
|
||||||
|
@@ -56,6 +56,7 @@ EventScript_PkmnCenterNurse_IllTakeYourPkmn2::
|
|||||||
return
|
return
|
||||||
|
|
||||||
EventScript_PkmnCenterNurse_TakeAndHealPkmn::
|
EventScript_PkmnCenterNurse_TakeAndHealPkmn::
|
||||||
|
hidefollower 0
|
||||||
applymovement VAR_0x800B, Movement_PkmnCenterNurse_Turn
|
applymovement VAR_0x800B, Movement_PkmnCenterNurse_Turn
|
||||||
waitmovement 0
|
waitmovement 0
|
||||||
dofieldeffect FLDEFF_POKECENTER_HEAL
|
dofieldeffect FLDEFF_POKECENTER_HEAL
|
||||||
|
@@ -332,6 +332,12 @@
|
|||||||
// instead of a normal pokeball
|
// instead of a normal pokeball
|
||||||
#define OW_MON_POKEBALLS TRUE
|
#define OW_MON_POKEBALLS TRUE
|
||||||
|
|
||||||
|
// New/old handling for followers during scripts;
|
||||||
|
// TRUE: Script collisions hide follower, FLAG_SAFE_FOLLOWER_MOVEMENT on by default
|
||||||
|
// (scripted player movement moves follower too!)
|
||||||
|
// FALSE: Script collisions unhandled, FLAG_SAFE_FOLLOWER_MOVEMENT off by default
|
||||||
|
#define OW_MON_SCRIPT_MOVEMENT FALSE
|
||||||
|
|
||||||
#define SHADOW_SIZE_S 0
|
#define SHADOW_SIZE_S 0
|
||||||
#define SHADOW_SIZE_M 1
|
#define SHADOW_SIZE_M 1
|
||||||
#define SHADOW_SIZE_L 2
|
#define SHADOW_SIZE_L 2
|
||||||
|
@@ -1644,7 +1644,9 @@
|
|||||||
#define FLAG_ENABLE_MULTI_CORRIDOR_DOOR (SPECIAL_FLAGS_START + 0x2)
|
#define FLAG_ENABLE_MULTI_CORRIDOR_DOOR (SPECIAL_FLAGS_START + 0x2)
|
||||||
#define FLAG_SPECIAL_FLAG_UNUSED_0x4003 (SPECIAL_FLAGS_START + 0x3) // Unused Flag
|
#define FLAG_SPECIAL_FLAG_UNUSED_0x4003 (SPECIAL_FLAGS_START + 0x3) // Unused Flag
|
||||||
#define FLAG_STORING_ITEMS_IN_PYRAMID_BAG (SPECIAL_FLAGS_START + 0x4)
|
#define FLAG_STORING_ITEMS_IN_PYRAMID_BAG (SPECIAL_FLAGS_START + 0x4)
|
||||||
#define FLAG_SAFE_FOLLOWER_MOVEMENT (SPECIAL_FLAGS_START + 0x5) // When set, applymovement does not put the follower inside a pokeball
|
// When set, `applymovement` does not hide follower pokemon;
|
||||||
|
// Also, scripted movements on the player will move follower(s), too
|
||||||
|
#define FLAG_SAFE_FOLLOWER_MOVEMENT (SPECIAL_FLAGS_START + 0x5)
|
||||||
// FLAG_SPECIAL_FLAG_0x4005 - 0x407F also exist and are unused
|
// FLAG_SPECIAL_FLAG_0x4005 - 0x407F also exist and are unused
|
||||||
#define SPECIAL_FLAGS_END (SPECIAL_FLAGS_START + 0x7F)
|
#define SPECIAL_FLAGS_END (SPECIAL_FLAGS_START + 0x7F)
|
||||||
#define NUM_SPECIAL_FLAGS (SPECIAL_FLAGS_END - SPECIAL_FLAGS_START + 1)
|
#define NUM_SPECIAL_FLAGS (SPECIAL_FLAGS_END - SPECIAL_FLAGS_START + 1)
|
||||||
|
@@ -164,6 +164,7 @@ u8 GetWalkInPlaceFastMovementAction(u32);
|
|||||||
u8 GetWalkInPlaceNormalMovementAction(u32);
|
u8 GetWalkInPlaceNormalMovementAction(u32);
|
||||||
u8 GetWalkInPlaceSlowMovementAction(u32);
|
u8 GetWalkInPlaceSlowMovementAction(u32);
|
||||||
u8 GetCollisionAtCoords(struct ObjectEvent *, s16 x, s16 y, u32 dir);
|
u8 GetCollisionAtCoords(struct ObjectEvent *, s16 x, s16 y, u32 dir);
|
||||||
|
u32 GetObjectObjectCollidesWith(struct ObjectEvent *objectEvent, s16 x, s16 y, bool32 addCoords);
|
||||||
void MoveCoords(u8 direction, s16 *x, s16 *y);
|
void MoveCoords(u8 direction, s16 *x, s16 *y);
|
||||||
bool8 ObjectEventIsHeldMovementActive(struct ObjectEvent *);
|
bool8 ObjectEventIsHeldMovementActive(struct ObjectEvent *);
|
||||||
u8 ObjectEventClearHeldMovementIfFinished(struct ObjectEvent *);
|
u8 ObjectEventClearHeldMovementIfFinished(struct ObjectEvent *);
|
||||||
|
@@ -25,7 +25,8 @@ git push build --force-with-lease
|
|||||||
if [[ $retVal -eq 0 ]]; then
|
if [[ $retVal -eq 0 ]]; then
|
||||||
commit_msg=$(git log -1 --pretty=%B)
|
commit_msg=$(git log -1 --pretty=%B)
|
||||||
if [[ "$commit_msg" == "$temp_commit_msg" ]]; then
|
if [[ "$commit_msg" == "$temp_commit_msg" ]]; then
|
||||||
git reset "$old_head" &>/dev/null
|
# Keep i(N)tent to add
|
||||||
|
git reset --mixed -N "$old_head" &>/dev/null
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
set -x
|
set -x
|
||||||
|
@@ -5603,9 +5603,7 @@ bool8 FollowablePlayerMovement_Step(struct ObjectEvent *objectEvent, struct Spri
|
|||||||
s16 y;
|
s16 y;
|
||||||
s16 targetX;
|
s16 targetX;
|
||||||
s16 targetY;
|
s16 targetY;
|
||||||
#ifdef MB_SIDEWAYS_STAIRS_RIGHT_SIDE
|
|
||||||
u32 playerAction = gObjectEvents[gPlayerAvatar.objectEventId].movementActionId;
|
u32 playerAction = gObjectEvents[gPlayerAvatar.objectEventId].movementActionId;
|
||||||
#endif
|
|
||||||
|
|
||||||
targetX = gObjectEvents[gPlayerAvatar.objectEventId].previousCoords.x;
|
targetX = gObjectEvents[gPlayerAvatar.objectEventId].previousCoords.x;
|
||||||
targetY = gObjectEvents[gPlayerAvatar.objectEventId].previousCoords.y;
|
targetY = gObjectEvents[gPlayerAvatar.objectEventId].previousCoords.y;
|
||||||
@@ -5621,8 +5619,8 @@ bool8 FollowablePlayerMovement_Step(struct ObjectEvent *objectEvent, struct Spri
|
|||||||
|
|
||||||
if (objectEvent->invisible) {
|
if (objectEvent->invisible) {
|
||||||
// Animate exiting pokeball
|
// Animate exiting pokeball
|
||||||
// Player is jumping, but follower is invisible
|
// don't emerge if player is jumping or moving via script
|
||||||
if (PlayerGetCopyableMovement() == COPY_MOVE_JUMP2) {
|
if (PlayerGetCopyableMovement() == COPY_MOVE_JUMP2 || ArePlayerFieldControlsLocked()) {
|
||||||
sprite->sTypeFuncId = 0; // return to shadowing state
|
sprite->sTypeFuncId = 0; // return to shadowing state
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -5651,44 +5649,26 @@ bool8 FollowablePlayerMovement_Step(struct ObjectEvent *objectEvent, struct Spri
|
|||||||
MoveCoords(direction, &x, &y);
|
MoveCoords(direction, &x, &y);
|
||||||
#ifdef MB_SIDEWAYS_STAIRS_RIGHT_SIDE // https://github.com/ghoulslash/pokeemerald/tree/sideways_stairs
|
#ifdef MB_SIDEWAYS_STAIRS_RIGHT_SIDE // https://github.com/ghoulslash/pokeemerald/tree/sideways_stairs
|
||||||
GetCollisionAtCoords(objectEvent, x, y, direction); // Sets directionOverwrite for stairs
|
GetCollisionAtCoords(objectEvent, x, y, direction); // Sets directionOverwrite for stairs
|
||||||
if (GetLedgeJumpDirection(x, y, direction) != DIR_NONE) {
|
#endif
|
||||||
|
if (GetLedgeJumpDirection(x, y, direction) != DIR_NONE)
|
||||||
// InitJumpRegular will set the proper speed
|
// InitJumpRegular will set the proper speed
|
||||||
ObjectEventSetSingleMovement(objectEvent, sprite, GetJump2MovementAction(direction));
|
ObjectEventSetSingleMovement(objectEvent, sprite, GetJump2MovementAction(direction));
|
||||||
} else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_DASH)) {
|
else if (playerAction >= MOVEMENT_ACTION_WALK_SLOW_DOWN && playerAction <= MOVEMENT_ACTION_WALK_SLOW_RIGHT) {
|
||||||
// Set follow speed according to player's speed
|
if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_DASH)) // on sideways stairs
|
||||||
if (playerAction >= MOVEMENT_ACTION_RUN_DOWN_SLOW && playerAction <= MOVEMENT_ACTION_RUN_RIGHT_SLOW)
|
|
||||||
objectEvent->movementActionId = GetWalkNormalMovementAction(direction);
|
objectEvent->movementActionId = GetWalkNormalMovementAction(direction);
|
||||||
else
|
else
|
||||||
objectEvent->movementActionId = GetWalkFastMovementAction(direction);
|
|
||||||
} else if (PlayerGetCopyableMovement() == COPY_MOVE_JUMP2) {
|
|
||||||
ObjectEventSetSingleMovement(objectEvent, sprite, GetWalkSlowMovementAction(direction));
|
|
||||||
} else {
|
|
||||||
if (playerAction >= MOVEMENT_ACTION_WALK_SLOW_DOWN && playerAction <= MOVEMENT_ACTION_WALK_SLOW_RIGHT) {
|
|
||||||
ObjectEventSetSingleMovement(objectEvent, sprite, GetWalkSlowMovementAction(direction));
|
ObjectEventSetSingleMovement(objectEvent, sprite, GetWalkSlowMovementAction(direction));
|
||||||
} else {
|
|
||||||
objectEvent->movementActionId = GetWalkNormalMovementAction(direction);
|
|
||||||
if (OW_MON_BOBBING == TRUE)
|
|
||||||
sprite->y2 = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sprite->sActionFuncId = 0;
|
|
||||||
#else
|
|
||||||
if (GetLedgeJumpDirection(x, y, direction) != DIR_NONE) {
|
|
||||||
// InitJumpRegular will set the proper speed
|
|
||||||
ObjectEventSetSingleMovement(objectEvent, sprite, GetJump2MovementAction(direction));
|
|
||||||
} else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_DASH)) {
|
|
||||||
// Set follow speed according to player's speed
|
|
||||||
ObjectEventSetSingleMovement(objectEvent, sprite, GetWalkFastMovementAction(direction));
|
|
||||||
} else if (PlayerGetCopyableMovement() == COPY_MOVE_JUMP2) {
|
} else if (PlayerGetCopyableMovement() == COPY_MOVE_JUMP2) {
|
||||||
// If *player* jumps, make step take twice as long
|
|
||||||
ObjectEventSetSingleMovement(objectEvent, sprite, GetWalkSlowMovementAction(direction));
|
ObjectEventSetSingleMovement(objectEvent, sprite, GetWalkSlowMovementAction(direction));
|
||||||
|
} else if (gSprites[gPlayerAvatar.spriteId].data[4] == MOVE_SPEED_FAST_1) {
|
||||||
|
objectEvent->movementActionId = GetWalkFastMovementAction(direction);
|
||||||
} else {
|
} else {
|
||||||
ObjectEventSetSingleMovement(objectEvent, sprite, GetWalkNormalMovementAction(direction));
|
objectEvent->movementActionId = GetWalkNormalMovementAction(direction);
|
||||||
if (OW_MON_BOBBING == TRUE)
|
if (OW_MON_BOBBING == TRUE)
|
||||||
sprite->y2 = -1;
|
sprite->y2 = -1;
|
||||||
}
|
}
|
||||||
#endif
|
sprite->sActionFuncId = 0;
|
||||||
objectEvent->singleMovementActive = TRUE;
|
objectEvent->singleMovementActive = 1;
|
||||||
sprite->sTypeFuncId = 2;
|
sprite->sTypeFuncId = 2;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -6347,13 +6327,17 @@ static bool8 IsMetatileDirectionallyImpassable(struct ObjectEvent *objectEvent,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool8 DoesObjectCollideWithObjectAt(struct ObjectEvent *objectEvent, s16 x, s16 y)
|
u32 GetObjectObjectCollidesWith(struct ObjectEvent *objectEvent, s16 x, s16 y, bool32 addCoords) {
|
||||||
{
|
|
||||||
u8 i;
|
u8 i;
|
||||||
struct ObjectEvent *curObject;
|
struct ObjectEvent *curObject;
|
||||||
|
|
||||||
if (objectEvent->localId == OBJ_EVENT_ID_FOLLOWER)
|
if (objectEvent->localId == OBJ_EVENT_ID_FOLLOWER)
|
||||||
return FALSE; // follower cannot collide with other objects, but they can collide with it
|
return OBJECT_EVENTS_COUNT; // follower cannot collide with other objects, but they can collide with it
|
||||||
|
|
||||||
|
if (addCoords) {
|
||||||
|
x += objectEvent->currentCoords.x;
|
||||||
|
y += objectEvent->currentCoords.y;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < OBJECT_EVENTS_COUNT; i++)
|
for (i = 0; i < OBJECT_EVENTS_COUNT; i++)
|
||||||
{
|
{
|
||||||
@@ -6363,11 +6347,16 @@ static bool8 DoesObjectCollideWithObjectAt(struct ObjectEvent *objectEvent, s16
|
|||||||
if ((curObject->currentCoords.x == x && curObject->currentCoords.y == y) || (curObject->previousCoords.x == x && curObject->previousCoords.y == y))
|
if ((curObject->currentCoords.x == x && curObject->currentCoords.y == y) || (curObject->previousCoords.x == x && curObject->previousCoords.y == y))
|
||||||
{
|
{
|
||||||
if (AreElevationsCompatible(objectEvent->currentElevation, curObject->currentElevation))
|
if (AreElevationsCompatible(objectEvent->currentElevation, curObject->currentElevation))
|
||||||
return TRUE;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FALSE;
|
return OBJECT_EVENTS_COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool8 DoesObjectCollideWithObjectAt(struct ObjectEvent *objectEvent, s16 x, s16 y)
|
||||||
|
{
|
||||||
|
return (GetObjectObjectCollidesWith(objectEvent, x, y, FALSE) < OBJECT_EVENTS_COUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool8 IsBerryTreeSparkling(u8 localId, u8 mapNum, u8 mapGroup)
|
bool8 IsBerryTreeSparkling(u8 localId, u8 mapNum, u8 mapGroup)
|
||||||
@@ -6524,6 +6513,18 @@ static u8 TryUpdateMovementActionOnStairs(struct ObjectEvent *objectEvent, u8 mo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const u8 sActionIdToCopyableMovement[] = {
|
||||||
|
[MOVEMENT_ACTION_FACE_DOWN ... MOVEMENT_ACTION_FACE_RIGHT] = COPY_MOVE_FACE,
|
||||||
|
[MOVEMENT_ACTION_WALK_SLOW_DOWN ... MOVEMENT_ACTION_WALK_NORMAL_RIGHT] = COPY_MOVE_WALK,
|
||||||
|
[MOVEMENT_ACTION_JUMP_2_DOWN ... MOVEMENT_ACTION_JUMP_2_RIGHT] = COPY_MOVE_JUMP2,
|
||||||
|
[MOVEMENT_ACTION_WALK_FAST_DOWN ... MOVEMENT_ACTION_WALK_FAST_RIGHT] = COPY_MOVE_WALK,
|
||||||
|
[MOVEMENT_ACTION_RIDE_WATER_CURRENT_DOWN ... MOVEMENT_ACTION_PLAYER_RUN_RIGHT] = COPY_MOVE_WALK,
|
||||||
|
// Not a typo; follower needs to take an action with a duration == JUMP's,
|
||||||
|
// and JUMP2 here will lead to WALK_SLOW later
|
||||||
|
[MOVEMENT_ACTION_JUMP_DOWN ... MOVEMENT_ACTION_JUMP_RIGHT] = COPY_MOVE_JUMP2,
|
||||||
|
[MOVEMENT_ACTION_NONE] = COPY_MOVE_NONE,
|
||||||
|
};
|
||||||
|
|
||||||
bool8 ObjectEventSetHeldMovement(struct ObjectEvent *objectEvent, u8 movementActionId)
|
bool8 ObjectEventSetHeldMovement(struct ObjectEvent *objectEvent, u8 movementActionId)
|
||||||
{
|
{
|
||||||
if (ObjectEventIsMovementOverridden(objectEvent))
|
if (ObjectEventIsMovementOverridden(objectEvent))
|
||||||
@@ -6536,6 +6537,16 @@ bool8 ObjectEventSetHeldMovement(struct ObjectEvent *objectEvent, u8 movementAct
|
|||||||
objectEvent->heldMovementActive = TRUE;
|
objectEvent->heldMovementActive = TRUE;
|
||||||
objectEvent->heldMovementFinished = FALSE;
|
objectEvent->heldMovementFinished = FALSE;
|
||||||
gSprites[objectEvent->spriteId].sActionFuncId = 0;
|
gSprites[objectEvent->spriteId].sActionFuncId = 0;
|
||||||
|
|
||||||
|
// When player is moved via script, set copyable movement
|
||||||
|
// for any followers via a lookup table
|
||||||
|
if (ArePlayerFieldControlsLocked() &&
|
||||||
|
objectEvent->isPlayer &&
|
||||||
|
FlagGet(FLAG_SAFE_FOLLOWER_MOVEMENT))
|
||||||
|
{
|
||||||
|
objectEvent->playerCopyableMovement = sActionIdToCopyableMovement[objectEvent->movementActionId];
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6559,6 +6570,15 @@ void ObjectEventClearHeldMovement(struct ObjectEvent *objectEvent)
|
|||||||
objectEvent->heldMovementFinished = FALSE;
|
objectEvent->heldMovementFinished = FALSE;
|
||||||
gSprites[objectEvent->spriteId].sTypeFuncId = 0;
|
gSprites[objectEvent->spriteId].sTypeFuncId = 0;
|
||||||
gSprites[objectEvent->spriteId].sActionFuncId = 0;
|
gSprites[objectEvent->spriteId].sActionFuncId = 0;
|
||||||
|
|
||||||
|
// When player is moved via script, set copyable movement
|
||||||
|
// for any followers via a lookup table
|
||||||
|
if (ArePlayerFieldControlsLocked() &&
|
||||||
|
objectEvent->isPlayer &&
|
||||||
|
FlagGet(FLAG_SAFE_FOLLOWER_MOVEMENT))
|
||||||
|
{
|
||||||
|
objectEvent->playerCopyableMovement = sActionIdToCopyableMovement[objectEvent->movementActionId];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 ObjectEventCheckHeldMovementStatus(struct ObjectEvent *objectEvent)
|
u8 ObjectEventCheckHeldMovementStatus(struct ObjectEvent *objectEvent)
|
||||||
|
48
src/scrcmd.c
48
src/scrcmd.c
@@ -1021,6 +1021,20 @@ bool8 ScrCmd_fadeinbgm(struct ScriptContext *ctx)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ObjectEvent * ScriptHideFollower(void) {
|
||||||
|
struct ObjectEvent *obj = GetFollowerObject();
|
||||||
|
|
||||||
|
if (obj == NULL || obj->invisible)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ClearObjectEventMovement(obj, &gSprites[obj->spriteId]);
|
||||||
|
gSprites[obj->spriteId].animCmdIndex = 0; // Reset start frame of animation
|
||||||
|
// Note: ScriptMovement_ returns TRUE on error
|
||||||
|
if (ScriptMovement_StartObjectMovementScript(obj->localId, obj->mapGroup, obj->mapNum, EnterPokeballMovement))
|
||||||
|
return NULL;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
bool8 ScrCmd_applymovement(struct ScriptContext *ctx)
|
bool8 ScrCmd_applymovement(struct ScriptContext *ctx)
|
||||||
{
|
{
|
||||||
u16 localId = VarGet(ScriptReadHalfword(ctx));
|
u16 localId = VarGet(ScriptReadHalfword(ctx));
|
||||||
@@ -1035,17 +1049,11 @@ bool8 ScrCmd_applymovement(struct ScriptContext *ctx)
|
|||||||
gObjectEvents[GetObjectEventIdByLocalId(localId)].directionOverwrite = DIR_NONE;
|
gObjectEvents[GetObjectEventIdByLocalId(localId)].directionOverwrite = DIR_NONE;
|
||||||
ScriptMovement_StartObjectMovementScript(localId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, movementScript);
|
ScriptMovement_StartObjectMovementScript(localId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, movementScript);
|
||||||
sMovingNpcId = localId;
|
sMovingNpcId = localId;
|
||||||
objEvent = GetFollowerObject();
|
if (localId != OBJ_EVENT_ID_FOLLOWER &&
|
||||||
// Force follower into pokeball
|
!FlagGet(FLAG_SAFE_FOLLOWER_MOVEMENT)
|
||||||
if (localId != OBJ_EVENT_ID_FOLLOWER
|
&& (movementScript < Common_Movement_FollowerSafeStart || movementScript > Common_Movement_FollowerSafeEnd))
|
||||||
&& !FlagGet(FLAG_SAFE_FOLLOWER_MOVEMENT)
|
|
||||||
&& (movementScript < Common_Movement_FollowerSafeStart || movementScript > Common_Movement_FollowerSafeEnd)
|
|
||||||
&& (objEvent = GetFollowerObject())
|
|
||||||
&& !objEvent->invisible)
|
|
||||||
{
|
{
|
||||||
ClearObjectEventMovement(objEvent, &gSprites[objEvent->spriteId]);
|
ScriptHideFollower();
|
||||||
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -2549,3 +2557,23 @@ bool8 ScrCmd_deleteparty(void)
|
|||||||
for (i = 0; i < PARTY_SIZE; i++)
|
for (i = 0; i < PARTY_SIZE; i++)
|
||||||
ZeroMonData(&gPlayerParty[i]);
|
ZeroMonData(&gPlayerParty[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool8 ScrFunc_hidefollower(struct ScriptContext *ctx) {
|
||||||
|
bool16 wait = VarGet(ScriptReadHalfword(ctx));
|
||||||
|
struct ObjectEvent *obj;
|
||||||
|
|
||||||
|
if ((obj = ScriptHideFollower()) != NULL && wait) {
|
||||||
|
sMovingNpcId = obj->localId;
|
||||||
|
sMovingNpcMapGroup = obj->mapGroup;
|
||||||
|
sMovingNpcMapNum = obj->mapNum;
|
||||||
|
SetupNativeScript(ctx, WaitForMovementFinish);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just in case, prevent `applymovement`
|
||||||
|
// from hiding the follower again
|
||||||
|
if (obj)
|
||||||
|
FlagSet(FLAG_SAFE_FOLLOWER_MOVEMENT);
|
||||||
|
|
||||||
|
// execute next script command with no delay
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
#include "mystery_gift.h"
|
#include "mystery_gift.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "constants/event_objects.h"
|
#include "constants/event_objects.h"
|
||||||
|
#include "constants/flags.h"
|
||||||
#include "constants/map_scripts.h"
|
#include "constants/map_scripts.h"
|
||||||
#include "rtc.h"
|
#include "rtc.h"
|
||||||
|
|
||||||
@@ -263,6 +264,8 @@ void ScriptContext_SetupScript(const u8 *ptr)
|
|||||||
InitScriptContext(&sGlobalScriptContext, gScriptCmdTable, gScriptCmdTableEnd);
|
InitScriptContext(&sGlobalScriptContext, gScriptCmdTable, gScriptCmdTableEnd);
|
||||||
SetupBytecodeScript(&sGlobalScriptContext, ptr);
|
SetupBytecodeScript(&sGlobalScriptContext, ptr);
|
||||||
LockPlayerFieldControls();
|
LockPlayerFieldControls();
|
||||||
|
if (OW_MON_SCRIPT_MOVEMENT)
|
||||||
|
FlagSet(FLAG_SAFE_FOLLOWER_MOVEMENT);
|
||||||
sGlobalScriptContextStatus = CONTEXT_RUNNING;
|
sGlobalScriptContextStatus = CONTEXT_RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "script_movement.h"
|
#include "script_movement.h"
|
||||||
#include "event_object_movement.h"
|
#include "event_object_movement.h"
|
||||||
|
#include "event_scripts.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "constants/event_objects.h"
|
#include "constants/event_objects.h"
|
||||||
@@ -205,13 +206,34 @@ static void ScriptMovement_MoveObjects(u8 taskId)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// from event_object_movement
|
||||||
|
#define sTypeFuncId data[1]
|
||||||
|
#define sTimer data[5]
|
||||||
|
|
||||||
static void ScriptMovement_TakeStep(u8 taskId, u8 moveScrId, u8 objEventId, const u8 *movementScript)
|
static void ScriptMovement_TakeStep(u8 taskId, u8 moveScrId, u8 objEventId, const u8 *movementScript)
|
||||||
{
|
{
|
||||||
u8 nextMoveActionId;
|
u8 nextMoveActionId;
|
||||||
|
struct ObjectEvent *obj = &gObjectEvents[objEventId];
|
||||||
|
|
||||||
if (ObjectEventIsHeldMovementActive(&gObjectEvents[objEventId])
|
if (ObjectEventIsHeldMovementActive(obj) &&
|
||||||
&& !ObjectEventClearHeldMovementIfFinished(&gObjectEvents[objEventId]))
|
!ObjectEventClearHeldMovementIfFinished(obj))
|
||||||
|
{
|
||||||
|
// If, while undergoing scripted movement,
|
||||||
|
// a non-player object collides with an active follower pokemon,
|
||||||
|
// put that follower into a pokeball
|
||||||
|
// (sTimer helps limit this expensive check to once per step)
|
||||||
|
if (OW_MON_SCRIPT_MOVEMENT &&
|
||||||
|
gSprites[obj->spriteId].sTimer == 1 &&
|
||||||
|
(objEventId = GetObjectObjectCollidesWith(obj, 0, 0, TRUE)) < OBJECT_EVENTS_COUNT &&
|
||||||
|
// switch `obj` to follower
|
||||||
|
((obj = &gObjectEvents[objEventId])->movementType == MOVEMENT_TYPE_FOLLOW_PLAYER) &&
|
||||||
|
gSprites[obj->spriteId].sTypeFuncId != 0)
|
||||||
|
{
|
||||||
|
ClearObjectEventMovement(obj, &gSprites[obj->spriteId]);
|
||||||
|
ScriptMovement_StartObjectMovementScript(obj->localId, obj->mapNum, obj->mapGroup, EnterPokeballMovement);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nextMoveActionId = *movementScript;
|
nextMoveActionId = *movementScript;
|
||||||
if (nextMoveActionId == MOVEMENT_ACTION_STEP_END)
|
if (nextMoveActionId == MOVEMENT_ACTION_STEP_END)
|
||||||
@@ -229,3 +251,5 @@ static void ScriptMovement_TakeStep(u8 taskId, u8 moveScrId, u8 objEventId, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef sTypeFuncId
|
||||||
|
#undef sTimer
|
||||||
|
Reference in New Issue
Block a user