From d06e1d4af6d099458914f967b0f6298a815d6084 Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Wed, 29 Dec 2021 20:22:13 -0500 Subject: [PATCH 1/2] Added flag for safe follower movement. --- include/constants/flags.h | 1 + src/scrcmd.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/constants/flags.h b/include/constants/flags.h index 793fe11354..f76e7b232f 100644 --- a/include/constants/flags.h +++ b/include/constants/flags.h @@ -1641,6 +1641,7 @@ #define FLAG_ENABLE_MULTI_CORRIDOR_DOOR (SPECIAL_FLAGS_START + 0x2) #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_SAFE_FOLLOWER_MOVEMENT (SPECIAL_FLAGS_START + 0x5) // When set, applymovement does not put the follower inside a pokeball // FLAG_SPECIAL_FLAG_0x4005 - 0x407F also exist and are unused #define SPECIAL_FLAGS_END (SPECIAL_FLAGS_START + 0x7F) diff --git a/src/scrcmd.c b/src/scrcmd.c index 572fb7a601..6ec06cced9 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -1005,7 +1005,7 @@ bool8 ScrCmd_applymovement(struct ScriptContext *ctx) ScriptMovement_StartObjectMovementScript(localId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, movementScript); sMovingNpcId = localId; - if (localId != OBJ_EVENT_ID_FOLLOWER) { // Force follower into pokeball + if (localId != OBJ_EVENT_ID_FOLLOWER && !FlagGet(FLAG_SAFE_FOLLOWER_MOVEMENT)) { // Force follower into pokeball objEvent = GetFollowerObject(); // return early if no follower or in shadowing state if (objEvent == NULL || gSprites[objEvent->spriteId].data[1] == 0) { @@ -1262,6 +1262,7 @@ bool8 ScrCmd_releaseall(struct ScriptContext *ctx) { u8 playerObjectId; struct ObjectEvent *followerObject = GetFollowerObject(); + FlagClear(FLAG_SAFE_FOLLOWER_MOVEMENT); // Release follower from movement iff it exists and is in the shadowing state if (followerObject && gSprites[followerObject->spriteId].data[1] == 0) ClearObjectEventMovement(followerObject, &gSprites[followerObject->spriteId]); @@ -1278,6 +1279,7 @@ bool8 ScrCmd_release(struct ScriptContext *ctx) { u8 playerObjectId; struct ObjectEvent *followerObject = GetFollowerObject(); + FlagClear(FLAG_SAFE_FOLLOWER_MOVEMENT); // Release follower from movement iff it exists and is in the shadowing state if (followerObject && gSprites[followerObject->spriteId].data[1] == 0) ClearObjectEventMovement(followerObject, &gSprites[followerObject->spriteId]); From 149f4436c1f56a584dd6f453bb389cace8ce2191 Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Wed, 29 Dec 2021 20:27:54 -0500 Subject: [PATCH 2/2] Follower pokemon now emerge matching the player's direction. --- src/data/object_events/object_event_anims.h | 94 +++++++++++++++++++-- src/event_object_movement.c | 30 ++++--- 2 files changed, 106 insertions(+), 18 deletions(-) diff --git a/src/data/object_events/object_event_anims.h b/src/data/object_events/object_event_anims.h index 2914256131..b9edf35b6e 100755 --- a/src/data/object_events/object_event_anims.h +++ b/src/data/object_events/object_event_anims.h @@ -370,7 +370,7 @@ static const union AnimCmd sAnim_GoFasterSouth[] = ANIMCMD_JUMP(0), }; -static const union AnimCmd sAnim_ExitPokeball[] = +static const union AnimCmd sAnim_ExitPokeballSouth[] = { ANIMCMD_FRAME(0, 1), ANIMCMD_FRAME(0, 3), @@ -379,7 +379,46 @@ static const union AnimCmd sAnim_ExitPokeball[] = ANIMCMD_FRAME(2, 1), ANIMCMD_FRAME(3, 1), ANIMCMD_FRAME(4, 1), - ANIMCMD_FRAME(0, 6), + ANIMCMD_FRAME(0, 8), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ExitPokeballNorth[] = +{ + ANIMCMD_FRAME(0, 1), + ANIMCMD_FRAME(0, 3), + ANIMCMD_FRAME(0, 1), + ANIMCMD_FRAME(1, 1), + ANIMCMD_FRAME(2, 1), + ANIMCMD_FRAME(3, 1), + ANIMCMD_FRAME(4, 1), + ANIMCMD_FRAME(2, 8), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ExitPokeballWest[] = +{ + ANIMCMD_FRAME(0, 1), + ANIMCMD_FRAME(0, 3), + ANIMCMD_FRAME(0, 1), + ANIMCMD_FRAME(1, 1), + ANIMCMD_FRAME(2, 1), + ANIMCMD_FRAME(3, 1), + ANIMCMD_FRAME(4, 1), + ANIMCMD_FRAME(4, 8), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ExitPokeballEast[] = +{ + ANIMCMD_FRAME(0, 1, .hFlip = TRUE), + ANIMCMD_FRAME(0, 3), + ANIMCMD_FRAME(0, 1), + ANIMCMD_FRAME(1, 1), + ANIMCMD_FRAME(2, 1), + ANIMCMD_FRAME(3, 1), + ANIMCMD_FRAME(4, 1), + ANIMCMD_FRAME(4, 8, .hFlip = TRUE), ANIMCMD_JUMP(0), }; @@ -467,15 +506,51 @@ static const union AnimCmd sAnim_GoFastestSouth[] = ANIMCMD_JUMP(0), }; -static const union AnimCmd sAnim_ExitPokeballFast[] = +static const union AnimCmd sAnim_ExitPokeballFastSouth[] = { ANIMCMD_FRAME(0, 1), ANIMCMD_FRAME(1, 1), ANIMCMD_FRAME(2, 1), ANIMCMD_FRAME(3, 1), ANIMCMD_FRAME(4, 1), + ANIMCMD_FRAME(0, 2), ANIMCMD_FRAME(0, 1), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ExitPokeballFastNorth[] = +{ ANIMCMD_FRAME(0, 1), + ANIMCMD_FRAME(1, 1), + ANIMCMD_FRAME(2, 1), + ANIMCMD_FRAME(3, 1), + ANIMCMD_FRAME(4, 1), + ANIMCMD_FRAME(2, 2), + ANIMCMD_FRAME(2, 1), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ExitPokeballFastWest[] = +{ + ANIMCMD_FRAME(0, 1), + ANIMCMD_FRAME(1, 1), + ANIMCMD_FRAME(2, 1), + ANIMCMD_FRAME(3, 1), + ANIMCMD_FRAME(4, 1), + ANIMCMD_FRAME(4, 2), + ANIMCMD_FRAME(4, 1), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ExitPokeballFastEast[] = +{ + ANIMCMD_FRAME(0, 1, .hFlip = TRUE), + ANIMCMD_FRAME(1, 1), + ANIMCMD_FRAME(2, 1), + ANIMCMD_FRAME(3, 1), + ANIMCMD_FRAME(4, 1), + ANIMCMD_FRAME(4, 2, .hFlip = TRUE), + ANIMCMD_FRAME(4, 1, .hFlip = TRUE), ANIMCMD_JUMP(0), }; @@ -1025,10 +1100,15 @@ static const union AnimCmd *const sAnimTable_Following[] = { sAnim_EnterNorth, sAnim_EnterWest, sAnim_EnterEast, - sAnim_ExitPokeball, - sAnim_ExitPokeballFast, - sAnim_ExitPokeball, - sAnim_ExitPokeball, + sAnim_ExitPokeballSouth, + sAnim_ExitPokeballNorth, + sAnim_ExitPokeballWest, + sAnim_ExitPokeballEast, + // ANIM_STD_COUNT = + sAnim_ExitPokeballFastSouth, + sAnim_ExitPokeballFastNorth, + sAnim_ExitPokeballFastWest, + sAnim_ExitPokeballFastEast, }; static const union AnimCmd *const sAnimTable_HoOh[] = { diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 8405718708..f90b72e142 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -6311,26 +6311,23 @@ bool8 MovementAction_WalkInPlaceSlowDown_Step0(struct ObjectEvent *objectEvent, // Copy and load objectEvent's palette, but set all opaque colors to white static u8 LoadWhiteFlashPalette(struct ObjectEvent *objectEvent, struct Sprite *sprite) { - - u8 i; u16 paletteData[16]; struct SpritePalette dynamicPalette = {.tag = OBJ_EVENT_PAL_TAG_NONE-1, .data = paletteData}; // TODO: Use a proper palette tag here - for (i=1; i<16; i++) { - paletteData[i] = 0xFFFF; - } + CpuFill16(0xFFFF, &paletteData[1], 30); return UpdateSpritePalette(&dynamicPalette, sprite); } bool8 MovementAction_ExitPokeball_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) { - + u8 direction = gObjectEvents[gPlayerAvatar.objectEventId].facingDirection; objectEvent->invisible = FALSE; if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_DASH)) { // If player is dashing, the pokemon must come out faster - InitMoveInPlace(objectEvent, sprite, DIR_SOUTH, GetMoveDirectionFastestAnimNum(DIR_NORTH), 8); + InitMoveInPlace(objectEvent, sprite, direction, GetMoveDirectionFastestAnimNum(direction) + 4, 8); sprite->data[6] = 0; // fast speed } else { - InitMoveInPlace(objectEvent, sprite, DIR_SOUTH, GetMoveDirectionFastestAnimNum(DIR_SOUTH), 16); + InitMoveInPlace(objectEvent, sprite, direction, GetMoveDirectionFastestAnimNum(direction), 16); sprite->data[6] = 1; // slow speed } + sprite->data[6] |= (direction == DIR_EAST ? 1 : 0) << 4; ObjectEventSetGraphicsId(objectEvent, OBJ_EVENT_GFX_ANIMATED_BALL); return MovementAction_ExitPokeball_Step1(objectEvent, sprite); } @@ -6344,6 +6341,15 @@ static const union AffineAnimCmd sAffineAnim_PokeballExit[] = AFFINEANIMCMD_END, }; +static const union AffineAnimCmd sAffineAnim_PokeballExitEast[] = // sprite is h-flipped when east +{ + AFFINEANIMCMD_FRAME(0xFFC0, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(0xFF80, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(0xFF40, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(0xFF00, 0x100, 0, 0), + AFFINEANIMCMD_END, +}; + static const union AffineAnimCmd sAffineAnim_PokeballEnter[] = { AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), @@ -6365,6 +6371,7 @@ static const union AffineAnimCmd sAffineAnim_PokeballEnterEast[] = // sprtie is static const union AffineAnimCmd *const sAffineAnims_PokeballFollower[] = { sAffineAnim_PokeballExit, + sAffineAnim_PokeballExitEast, sAffineAnim_PokeballEnter, sAffineAnim_PokeballEnterEast, }; @@ -6375,7 +6382,8 @@ bool8 MovementAction_ExitPokeball_Step1(struct ObjectEvent *objectEvent, struct sprite->data[3]--; if (sprite->data[3] == 0) { - sprite->data[2] = 2; + sprite->sActionFuncId = 2; + sprite->animCmdIndex = 0; sprite->animPaused = TRUE; return TRUE; // Set graphics, palette, and affine animation @@ -6386,7 +6394,7 @@ bool8 MovementAction_ExitPokeball_Step1(struct ObjectEvent *objectEvent, struct sprite->affineAnims = sAffineAnims_PokeballFollower; sprite->oam.affineMode = ST_OAM_AFFINE_NORMAL; InitSpriteAffineAnim(sprite); - StartSpriteAffineAnim(sprite, 0); + StartSpriteAffineAnim(sprite, sprite->data[6] >> 4); // Restore original palette & disable affine } else if ((duration == 0 && sprite->data[3] == 1) || (duration == 1 && sprite->data[3] == 3)) { sprite->affineAnimEnded = TRUE; @@ -6400,7 +6408,7 @@ bool8 MovementAction_ExitPokeball_Step1(struct ObjectEvent *objectEvent, struct bool8 MovementAction_EnterPokeball_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) { u8 direction = objectEvent->facingDirection; InitMoveInPlace(objectEvent, sprite, direction, GetMoveDirectionFasterAnimNum(direction), 16); - sprite->data[6] = direction == DIR_EAST ? 2 : 1; // affine animation number + sprite->data[6] = direction == DIR_EAST ? 3 : 2; // affine animation number return MovementAction_EnterPokeball_Step1(objectEvent, sprite); }