diff --git a/data/scripts/follower.inc b/data/scripts/follower.inc index 2b782d4799..bc4d2f4d34 100644 --- a/data/scripts/follower.inc +++ b/data/scripts/follower.inc @@ -1,6 +1,18 @@ -gText_Follower:: +gText_FollowerLovesYou:: .string "{STR_VAR_1} loves you!$" +gText_FollowerLostInThought:: + .string "{STR_VAR_1} seems lost in thought.$" + +gText_FollowerDefault:: + .string "ERROR 404: Script not found.$" + +gText_FollowerHasWetFeet:: + .string "{STR_VAR_1} seems unhappy about getting\nits feet wet.$" + +gText_FollowerSplashesAround:: + .string "{STR_VAR_1} splashes around happily!$" + .macro playfirstmoncry callfunc ScrFunc_playfirstmoncry .endm @@ -14,10 +26,44 @@ callfunc ScrFunc_bufferlivemonspeciesname EventScript_Follower:: lock faceplayer - playfirstmoncry - applymovement 0xFE ContestHall_Movement_Heart - waitmoncry - bufferlivemonspeciesname 0 - msgbox gText_Follower, MSGBOX_DEFAULT + callfunc ScrFunc_getfolloweraction + msgbox gText_FollowerDefault, MSGBOX_DEFAULT + release + end + +EventScript_FollowerHasWetFeet:: + bufferlivemonspeciesname 0 + playfirstmoncry + msgbox gText_FollowerHasWetFeet, MSGBOX_DEFAULT + waitmoncry + release + end + +EventScript_FollowerSplashesAbout:: + bufferlivemonspeciesname 0 + playfirstmoncry + applymovement 0xFE FollowerSplashMovement + waitmovement 0xFE + msgbox gText_FollowerSplashesAround, MSGBOX_DEFAULT + release + end + +EnterPokeballMovement:: + .byte 0x9F @ EnterPokeball + step_end + +FollowerSplashMovement:: + jump_in_place_left_right + jump_in_place_left_right + face_player + step_end + +EventScript_FollowerLovesYou:: + playfirstmoncry + applymovement 0xFE ContestHall_Movement_Heart + waitmovement 0xFE + waitmoncry + bufferlivemonspeciesname 0 + msgbox gText_FollowerLovesYou, MSGBOX_DEFAULT release end diff --git a/graphics/object_events/palettes/charizard.pal b/graphics/object_events/palettes/charizard.pal new file mode 100644 index 0000000000..274fd57f8c --- /dev/null +++ b/graphics/object_events/palettes/charizard.pal @@ -0,0 +1,19 @@ +JASC-PAL +0100 +16 +160 176 128 +0 0 0 +96 48 0 +192 16 32 +40 72 88 +96 64 0 +144 64 32 +200 88 40 +64 128 128 +248 120 56 +160 160 160 +216 168 48 +248 184 16 +240 208 112 +216 216 248 +0 0 0 diff --git a/graphics/object_events/pics/pokemon/charizard.png b/graphics/object_events/pics/pokemon/charizard.png new file mode 100644 index 0000000000..62a369dbc3 Binary files /dev/null and b/graphics/object_events/pics/pokemon/charizard.png differ diff --git a/graphics/pokemon/togetic/anim_front.png b/graphics/pokemon/togetic/anim_front.png index e233ea9409..ce187e23bc 100644 Binary files a/graphics/pokemon/togetic/anim_front.png and b/graphics/pokemon/togetic/anim_front.png differ diff --git a/include/constants/event_objects.h b/include/constants/event_objects.h index ba53c13fe5..f664d41a83 100644 --- a/include/constants/event_objects.h +++ b/include/constants/event_objects.h @@ -244,8 +244,9 @@ #define OBJ_EVENT_GFX_MARSHTOMP 240 #define OBJ_EVENT_GFX_ALTARIA 241 #define OBJ_EVENT_GFX_TOGETIC 242 +#define OBJ_EVENT_GFX_CHARIZARD 243 -#define NUM_OBJ_EVENT_GFX 243 +#define NUM_OBJ_EVENT_GFX 244 // These are dynamic object gfx ids. diff --git a/include/event_object_movement.h b/include/event_object_movement.h index 8f7b0ed82e..f7366de8ea 100644 --- a/include/event_object_movement.h +++ b/include/event_object_movement.h @@ -99,6 +99,7 @@ struct Pokemon * GetFirstLiveMon(void); u8 SpawnFollowingPokemon(void); void UpdateFollowingPokemon(void); void RemoveFollowingPokemon(void); +struct ObjectEvent * GetFollowerObject(void); void TrySpawnObjectEvents(s16, s16); u8 CreateObjectSprite(u8 graphicsId, u8 a1, s16 x, s16 y, u8 z, u8 direction); u8 AddPseudoObjectEvent(u16, void (*)(struct Sprite *), s16 x, s16 y, u8 subpriority); @@ -419,9 +420,9 @@ bool8 cph_IM_DIFFERENT(struct ObjectEvent *, struct Sprite *, u8, bool8(u8)); bool8 CopyablePlayerMovement_GoSpeed4(struct ObjectEvent *, struct Sprite *, u8, bool8(u8)); bool8 CopyablePlayerMovement_Jump(struct ObjectEvent *, struct Sprite *, u8, bool8(u8)); -u8 MovementType_FollowPlayer_Step0(struct ObjectEvent *, struct Sprite *); -u8 MovementType_FollowPlayer_Step1(struct ObjectEvent *, struct Sprite *); -u8 MovementType_FollowPlayer_Step2(struct ObjectEvent *, struct Sprite *); +u8 MovementType_FollowPlayer_Shadow(struct ObjectEvent *, struct Sprite *); +u8 MovementType_FollowPlayer_Active(struct ObjectEvent *, struct Sprite *); +u8 MovementType_FollowPlayer_Moving(struct ObjectEvent *, struct Sprite *); bool8 FollowablePlayerMovement_Idle(struct ObjectEvent *, struct Sprite *, u8, bool8(u8)); bool8 FollowablePlayerMovement_FaceDirection(struct ObjectEvent *, struct Sprite *, u8, bool8(u8)); diff --git a/include/event_scripts.h b/include/event_scripts.h index 395bdb0bff..5640830293 100644 --- a/include/event_scripts.h +++ b/include/event_scripts.h @@ -2,6 +2,10 @@ #define GUARD_EVENT_SCRIPTS_H extern const u8 EventScript_Follower[]; +extern const u8 EventScript_FollowerHasWetFeet[]; +extern const u8 EventScript_FollowerSplashesAbout[]; +extern const u8 EventScript_FollowerLovesYou[]; +extern const u8 EnterPokeballMovement[]; extern const u8 EventScript_TestSignpostMsg[]; extern const u8 EventScript_TryGetTrainerScript[]; diff --git a/spritesheet_rules.mk b/spritesheet_rules.mk index 48ff32db28..869a9bd1f2 100644 --- a/spritesheet_rules.mk +++ b/spritesheet_rules.mk @@ -480,6 +480,9 @@ $(OBJEVENTGFXDIR)/pokemon/altaria.4bpp: %.4bpp: %.png $(OBJEVENTGFXDIR)/pokemon/togetic.4bpp: %.4bpp: %.png $(GFX) $< $@ -mwidth 4 -mheight 4 +$(OBJEVENTGFXDIR)/pokemon/charizard.4bpp: %.4bpp: %.png + $(GFX) $< $@ -mwidth 4 -mheight 4 + $(OBJEVENTGFXDIR)/berry_trees/aguav.4bpp: %.4bpp: %.png $(GFX) $< $@ -mwidth 2 -mheight 4 diff --git a/src/data/object_events/movement_action_func_tables.h b/src/data/object_events/movement_action_func_tables.h index 5b3dfcb733..6598fd5379 100755 --- a/src/data/object_events/movement_action_func_tables.h +++ b/src/data/object_events/movement_action_func_tables.h @@ -68,6 +68,7 @@ u8 MovementAction_WalkInPlaceNormalDown_Step0(struct ObjectEvent *, struct Sprit u8 MovementAction_WalkInPlace_Step1(struct ObjectEvent *, struct Sprite *); u8 MovementAction_ExitPokeball_Step1(struct ObjectEvent *, struct Sprite *); u8 MovementAction_EnterPokeball_Step1(struct ObjectEvent *, struct Sprite *); +u8 MovementAction_EnterPokeball_Step2(struct ObjectEvent *, struct Sprite *); u8 MovementAction_WalkInPlaceNormalUp_Step0(struct ObjectEvent *, struct Sprite *); u8 MovementAction_WalkInPlaceNormalLeft_Step0(struct ObjectEvent *, struct Sprite *); u8 MovementAction_WalkInPlaceNormalRight_Step0(struct ObjectEvent *, struct Sprite *); @@ -76,8 +77,8 @@ u8 MovementAction_WalkInPlaceFastUp_Step0(struct ObjectEvent *, struct Sprite *) u8 MovementAction_WalkInPlaceFastLeft_Step0(struct ObjectEvent *, struct Sprite *); u8 MovementAction_WalkInPlaceFastRight_Step0(struct ObjectEvent *, struct Sprite *); u8 MovementAction_WalkInPlaceFastestDown_Step0(struct ObjectEvent *, struct Sprite *); -u8 MovementAction_ExitPokeball_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite); -u8 MovementAction_EnterPokeball_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite); +u8 MovementAction_ExitPokeball_Step0(struct ObjectEvent *, struct Sprite *); +u8 MovementAction_EnterPokeball_Step0(struct ObjectEvent *, struct Sprite *); u8 MovementAction_WalkInPlaceFastestUp_Step0(struct ObjectEvent *, struct Sprite *); u8 MovementAction_WalkInPlaceFastestLeft_Step0(struct ObjectEvent *, struct Sprite *); u8 MovementAction_WalkInPlaceFastestRight_Step0(struct ObjectEvent *, struct Sprite *); @@ -882,7 +883,7 @@ u8 (*const gMovementActionFuncs_ExitPokeball[])(struct ObjectEvent *, struct Spr u8 (*const gMovementActionFuncs_EnterPokeball[])(struct ObjectEvent *, struct Sprite *) = { MovementAction_EnterPokeball_Step0, MovementAction_EnterPokeball_Step1, - MovementAction_PauseSpriteAnim, + MovementAction_EnterPokeball_Step2, }; u8 (*const gMovementActionFuncs_WalkInPlaceFastestUp[])(struct ObjectEvent *, struct Sprite *) = { diff --git a/src/data/object_events/movement_type_func_tables.h b/src/data/object_events/movement_type_func_tables.h index 0fe364afe1..2bba66b07d 100755 --- a/src/data/object_events/movement_type_func_tables.h +++ b/src/data/object_events/movement_type_func_tables.h @@ -402,9 +402,9 @@ bool8 (*const gCopyPlayerMovementFuncs[])(struct ObjectEvent *, struct Sprite *, }; u8 (*const gMovementTypeFuncs_FollowPlayer[])(struct ObjectEvent *, struct Sprite *) = { - MovementType_FollowPlayer_Step0, - MovementType_FollowPlayer_Step1, - MovementType_FollowPlayer_Step2, + MovementType_FollowPlayer_Shadow, + MovementType_FollowPlayer_Active, + MovementType_FollowPlayer_Moving, }; bool8 (*const gFollowPlayerMovementFuncs[])(struct ObjectEvent *, struct Sprite *, u8, bool8(u8)) = { diff --git a/src/data/object_events/object_event_graphics.h b/src/data/object_events/object_event_graphics.h index 3c04b78deb..137065c07b 100755 --- a/src/data/object_events/object_event_graphics.h +++ b/src/data/object_events/object_event_graphics.h @@ -71,6 +71,7 @@ const u16 gObjectEventPal_Npc4Reflection[] = INCBIN_U16("graphics/object_events/ const u16 gObjectEventPaletteMarshtomp[] = INCBIN_U16("graphics/object_events/palettes/marshtomp.gbapal"); const u16 gObjectEventPaletteAltaria[] = INCBIN_U16("graphics/object_events/palettes/altaria.gbapal"); const u16 gObjectEventPaletteTogetic[] = INCBIN_U16("graphics/object_events/palettes/togetic.gbapal"); +const u16 gObjectEventPaletteCharizard[] = INCBIN_U16("graphics/object_events/palettes/charizard.gbapal"); const u32 gObjectEventPic_NinjaBoy[] = INCBIN_U32("graphics/object_events/pics/people/ninja_boy.4bpp"); const u32 gObjectEventPic_Twin[] = INCBIN_U32("graphics/object_events/pics/people/twin.4bpp"); const u32 gObjectEventPic_Boy1[] = INCBIN_U32("graphics/object_events/pics/people/boy_1.4bpp"); @@ -367,4 +368,5 @@ const u32 gObjectEventPic_AnimatedBall[] = INCBIN_U32("graphics/object_events/pi const u32 gObjectEventPic_Marshtomp[] = INCBIN_U32("graphics/object_events/pics/pokemon/marshtomp.4bpp"); const u32 gObjectEventPic_Altaria[] = INCBIN_U32("graphics/object_events/pics/pokemon/altaria.4bpp"); const u32 gObjectEventPic_Togetic[] = INCBIN_U32("graphics/object_events/pics/pokemon/togetic.4bpp"); +const u32 gObjectEventPic_Charizard[] = INCBIN_U32("graphics/object_events/pics/pokemon/charizard.4bpp"); const u16 gObjectEventPalette31[] = INCBIN_U16("graphics/object_events/palettes/31.gbapal"); diff --git a/src/data/object_events/object_event_graphics_info.h b/src/data/object_events/object_event_graphics_info.h index a97f143574..930455238c 100755 --- a/src/data/object_events/object_event_graphics_info.h +++ b/src/data/object_events/object_event_graphics_info.h @@ -247,3 +247,4 @@ const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_AnimatedBall = {0x const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Marshtomp = {0xFFFF, OBJ_EVENT_PAL_TAG_MARSHTOMP, OBJ_EVENT_PAL_TAG_NONE, 256, 16, 32, 2, SHADOW_SIZE_M, FALSE, FALSE, TRACKS_FOOT, &gObjectEventBaseOam_16x32, gObjectEventSpriteOamTables_16x32, gObjectEventImageAnimTable_Following, gObjectEventPicTable_Marshtomp, gDummySpriteAffineAnimTable}; const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Altaria = {0xFFFF, OBJ_EVENT_PAL_TAG_ALTARIA, OBJ_EVENT_PAL_TAG_NONE, 512, 32, 32, 2, SHADOW_SIZE_M, FALSE, FALSE, TRACKS_FOOT, &gObjectEventBaseOam_32x32, gObjectEventSpriteOamTables_32x32, gObjectEventImageAnimTable_Standard, gObjectEventPicTable_Altaria, gDummySpriteAffineAnimTable}; const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Togetic = {0xFFFF, OBJ_EVENT_PAL_TAG_TOGETIC, OBJ_EVENT_PAL_TAG_NONE, 512, 32, 32, 2, SHADOW_SIZE_M, FALSE, FALSE, TRACKS_NONE, &gObjectEventBaseOam_32x32, gObjectEventSpriteOamTables_32x32, gObjectEventImageAnimTable_Following, gObjectEventPicTable_Togetic, gDummySpriteAffineAnimTable}; +const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Charizard = {0xFFFF, OBJ_EVENT_PAL_TAG_CHARIZARD, OBJ_EVENT_PAL_TAG_NONE, 512, 32, 32, 2, SHADOW_SIZE_M, FALSE, FALSE, TRACKS_FOOT, &gObjectEventBaseOam_32x32, gObjectEventSpriteOamTables_32x32, gObjectEventImageAnimTable_Following, gObjectEventPicTable_Charizard, gDummySpriteAffineAnimTable}; diff --git a/src/data/object_events/object_event_graphics_info_pointers.h b/src/data/object_events/object_event_graphics_info_pointers.h index 61d8c0e7d5..d48615b19f 100755 --- a/src/data/object_events/object_event_graphics_info_pointers.h +++ b/src/data/object_events/object_event_graphics_info_pointers.h @@ -237,10 +237,12 @@ const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_RubySapphireBrenda const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_RubySapphireMay; const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Lugia; const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_HoOh; +// Begin pokemon event objects const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_AnimatedBall; const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Marshtomp; const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Altaria; const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Togetic; +const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Charizard; const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Bard; const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Hipster; @@ -495,6 +497,7 @@ const struct ObjectEventGraphicsInfo *const gObjectEventGraphicsInfoPointers[NUM [OBJ_EVENT_GFX_MARSHTOMP] = &gObjectEventGraphicsInfo_Marshtomp, [OBJ_EVENT_GFX_ALTARIA] = &gObjectEventGraphicsInfo_Altaria, [OBJ_EVENT_GFX_TOGETIC] = &gObjectEventGraphicsInfo_Togetic, + [OBJ_EVENT_GFX_CHARIZARD] = &gObjectEventGraphicsInfo_Charizard, }; const struct ObjectEventGraphicsInfo *const gMauvilleOldManGraphicsInfoPointers[] = { diff --git a/src/data/object_events/object_event_pic_tables.h b/src/data/object_events/object_event_pic_tables.h index 8ddd851780..ccfaa376ef 100755 --- a/src/data/object_events/object_event_pic_tables.h +++ b/src/data/object_events/object_event_pic_tables.h @@ -2188,6 +2188,15 @@ const struct SpriteFrameImage gObjectEventPicTable_Togetic[] = { overworld_frame(gObjectEventPic_Togetic, 4, 4, 5), }; +const struct SpriteFrameImage gObjectEventPicTable_Charizard[] = { + overworld_frame(gObjectEventPic_Charizard, 4, 4, 0), + overworld_frame(gObjectEventPic_Charizard, 4, 4, 1), + overworld_frame(gObjectEventPic_Charizard, 4, 4, 2), + overworld_frame(gObjectEventPic_Charizard, 4, 4, 3), + overworld_frame(gObjectEventPic_Charizard, 4, 4, 4), + overworld_frame(gObjectEventPic_Charizard, 4, 4, 5), +}; + const struct SpriteFrameImage gObjectEventPicTable_RubySapphireBrendan[] = { overworld_frame(gObjectEventPic_RubySapphireBrendanNormal, 2, 4, 0), overworld_frame(gObjectEventPic_RubySapphireBrendanNormal, 2, 4, 1), diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 69b6008150..84d4f4aa37 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -11,6 +11,7 @@ #include "field_effect.h" #include "field_effect_helpers.h" #include "field_player_avatar.h" +#include "field_weather.h" #include "fieldmap.h" #include "mauville_old_man.h" #include "metatile_behavior.h" @@ -18,6 +19,7 @@ #include "palette.h" #include "pokemon.h" #include "random.h" +#include "script.h" #include "sprite.h" #include "task.h" #include "trainer_see.h" @@ -31,6 +33,7 @@ #include "constants/species.h" #include "constants/trainer_types.h" #include "constants/union_room.h" +#include "constants/weather.h" // this file was known as evobjmv.c in Game Freak's original source @@ -444,6 +447,7 @@ const u8 gInitialMovementTypeFacingDirections[] = { #define OBJ_EVENT_PAL_TAG_MARSHTOMP 0x1124 #define OBJ_EVENT_PAL_TAG_ALTARIA 0x1125 #define OBJ_EVENT_PAL_TAG_TOGETIC 0x1126 +#define OBJ_EVENT_PAL_TAG_CHARIZARD 0x1127 #define OBJ_EVENT_PAL_TAG_NONE 0x11FF #include "data/object_events/object_event_graphics_info_pointers.h" @@ -493,6 +497,7 @@ static const struct SpritePalette sObjectEventSpritePalettes[] = { {gObjectEventPaletteMarshtomp, OBJ_EVENT_PAL_TAG_MARSHTOMP}, {gObjectEventPaletteAltaria, OBJ_EVENT_PAL_TAG_ALTARIA}, {gObjectEventPaletteTogetic, OBJ_EVENT_PAL_TAG_TOGETIC}, + {gObjectEventPaletteCharizard, OBJ_EVENT_PAL_TAG_CHARIZARD}, {NULL, 0x0000}, }; @@ -1163,7 +1168,7 @@ u8 GetFirstInactiveObjectEventId(void) u8 GetObjectEventIdByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroupId) { - if (localId < OBJ_EVENT_ID_PLAYER) + if (localId < OBJ_EVENT_ID_FOLLOWER) { return GetObjectEventIdByLocalIdAndMapInternal(localId, mapNum, mapGroupId); } @@ -1610,8 +1615,8 @@ u8 SpawnFollowingPokemon(void) { // Spawn a following pokemon TODO: Avoid this o template.localId = OBJ_EVENT_ID_FOLLOWER; mon = GetFirstLiveMon(); - if (mon == NULL) { // fainted party, don't spawn an object TODO - return 0; + if (mon == NULL) { // fainted party, don't spawn a follower + return 0xFF; } template.graphicsId = SpeciesToGraphicsId(GetMonData(mon, MON_DATA_SPECIES)); template.x = gSaveBlock1Ptr->pos.x; @@ -1621,51 +1626,44 @@ u8 SpawnFollowingPokemon(void) { // Spawn a following pokemon TODO: Avoid this o // template.script = EventScript_Follower; // This does nothing because scripts are templated objectEventId = SpawnSpecialObjectEvent(&template); gObjectEvents[objectEventId].invisible = TRUE; - gObjectEvents[objectEventId].hasShadow = TRUE; return objectEventId; } +struct ObjectEvent * GetFollowerObject(void) { // Return follower ObjectEvent or NULL + u8 i; + for (i=0; i < OBJECT_EVENTS_COUNT; i++) { + if (gObjectEvents[i].localId == OBJ_EVENT_ID_FOLLOWER) { + return &gObjectEvents[i]; + } + } + return NULL; +} + void UpdateFollowingPokemon(void) { u8 i; u8 graphicsId; - struct ObjectEvent *objectEvent = NULL; - struct Pokemon *mon; - - // TODO: Improve finding player following pokemon - for (i=0; i < OBJECT_EVENTS_COUNT; i++) { - if (gObjectEvents[i].localId == 0xFE) { - objectEvent = &gObjectEvents[i]; - break; - } - } + struct ObjectEvent *objectEvent = GetFollowerObject(); + struct Pokemon *mon = GetFirstLiveMon(); if (objectEvent == NULL) { return; } - mon = GetFirstLiveMon(); if (mon == NULL) { // TODO: Fainted party return; } graphicsId = SpeciesToGraphicsId(GetMonData(mon, MON_DATA_SPECIES)); if (graphicsId != objectEvent->graphicsId) { // Mark as invisible MoveObjectEventToMapCoords(objectEvent, gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.x, gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.y); + objectEvent->graphicsId = graphicsId; objectEvent->invisible = TRUE; gSprites[objectEvent->spriteId].data[1] = 0; // set state gSprites[objectEvent->spriteId].data[6] = 0; // set graphicsId gSprites[objectEvent->spriteId].data[7] = 0; // set animation data } - objectEvent->graphicsId = graphicsId; return; } void RemoveFollowingPokemon(void) { - struct ObjectEvent *objectEvent = NULL; - u8 i; - for (i=0; i < OBJECT_EVENTS_COUNT; i++) { - if (gObjectEvents[i].localId == 0xFE) { - objectEvent = &gObjectEvents[i]; - break; - } - } + struct ObjectEvent *objectEvent = GetFollowerObject(); if (objectEvent == NULL) { return; } @@ -1676,6 +1674,34 @@ static bool8 IsFollowerVisible(void) { // Determine whether follower should be v return !TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING | PLAYER_AVATAR_FLAG_ACRO_BIKE | PLAYER_AVATAR_FLAG_MACH_BIKE); } +bool8 ScrFunc_getfolloweraction(struct ScriptContext *ctx) +{ + u16 value; + u16 species; + u32 behavior; + struct ObjectEvent *objEvent = &gObjectEvents[GetObjectEventIdByLocalIdAndMap(OBJ_EVENT_ID_FOLLOWER, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup)]; + struct Pokemon *follower = GetFirstLiveMon(); + if (follower == NULL) { + return FALSE; + } + behavior = MapGridGetMetatileBehaviorAt(objEvent->currentCoords.x, objEvent->currentCoords.y); + species = GetMonData(follower, MON_DATA_SPECIES); + if (MetatileBehavior_IsPuddle(behavior) || MetatileBehavior_IsShallowFlowingWater(behavior)) { + if (gBaseStats[species].type1 == TYPE_FIRE || gBaseStats[species].type2 == TYPE_FIRE) { + ScriptJump(ctx, EventScript_FollowerHasWetFeet); + return FALSE; + } else if (GetObjectEventGraphicsInfo(objEvent->graphicsId)->tracks) { // if follower leaves tracks + ScriptJump(ctx, EventScript_FollowerSplashesAbout); + return FALSE; + } + } + if (GetCurrentWeather() == WEATHER_RAIN || GetCurrentWeather() == WEATHER_RAIN_THUNDERSTORM) { + ScriptJump(ctx, EventScript_FollowerLovesYou); + } + ScriptJump(ctx, EventScript_FollowerLovesYou); + return FALSE; +} + void TrySpawnObjectEvents(s16 cameraX, s16 cameraY) { u8 i; @@ -4525,23 +4551,19 @@ bool8 CopyablePlayerMovement_Jump(struct ObjectEvent *objectEvent, struct Sprite movement_type_def(MovementType_FollowPlayer, gMovementTypeFuncs_FollowPlayer) -bool8 MovementType_FollowPlayer_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +bool8 MovementType_FollowPlayer_Shadow(struct ObjectEvent *objectEvent, struct Sprite *sprite) { ClearObjectEventMovement(objectEvent, sprite); - if (sprite->data[6]) { // Restore graphicsId TODO: Change this hack - ObjectEventSetGraphicsId(objectEvent, sprite->data[6]); - sprite->data[6] = 0; - } if (!IsFollowerVisible()) { // Shadow player's position - objectEvent->invisible = TRUE; MoveObjectEventToMapCoords(objectEvent, gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.x, gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.y); return FALSE; } - sprite->data[1] = 1; + // __asm__(".2byte 0xBE00"); + sprite->data[1] = 1; // Enter idle state return TRUE; } -bool8 MovementType_FollowPlayer_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite) +bool8 MovementType_FollowPlayer_Active(struct ObjectEvent *objectEvent, struct Sprite *sprite) { if (gObjectEvents[gPlayerAvatar.objectEventId].movementActionId == 0xFF || gPlayerAvatar.tileTransitionState == T_TILE_CENTER) { // do nothing if player is stationary return FALSE; @@ -4550,32 +4572,36 @@ bool8 MovementType_FollowPlayer_Step1(struct ObjectEvent *objectEvent, struct Sp return gFollowPlayerMovementFuncs[PlayerGetCopyableMovement()](objectEvent, sprite, GetPlayerMovementDirection(), NULL); } -bool8 MovementType_FollowPlayer_Step2(struct ObjectEvent *objectEvent, struct Sprite *sprite) +bool8 MovementType_FollowPlayer_Moving(struct ObjectEvent *objectEvent, struct Sprite *sprite) { if (ObjectEventExecSingleMovementAction(objectEvent, sprite)) { objectEvent->singleMovementActive = 0; - sprite->data[1] = 1; + if (sprite->data[1]) { // restore nonzero state + sprite->data[1] = 1; + } } - objectEvent->invisible = FALSE; return FALSE; } bool8 FollowablePlayerMovement_Idle(struct ObjectEvent *objectEvent, struct Sprite *sprite, u8 playerDirection, bool8 tileCallback(u8)) { u8 direction; - if (!IsFollowerVisible()) { // Animate entering pokeball - if (objectEvent->invisible) { + if (!IsFollowerVisible()) { + if (objectEvent->invisible) { // Return to shadowing state + sprite->data[1] = 0; return FALSE; } + // Animate entering pokeball ClearObjectEventMovement(objectEvent, sprite); ObjectEventSetSingleMovement(objectEvent, sprite, MOVEMENT_ACTION_ENTER_POKEBALL); objectEvent->singleMovementActive = 1; sprite->animCmdIndex = 0; // Needed because of weird animCmdIndex stuff - sprite->data[1] = 2; // movement action sets state to 0 later + sprite->data[1] = 2; // movement action sets state to 0 return TRUE; } else if (!objectEvent->singleMovementActive) { // walk in place ObjectEventSetSingleMovement(objectEvent, sprite, GetWalkInPlaceNormalMovementAction(objectEvent->facingDirection)); + sprite->data[1] = 1; objectEvent->singleMovementActive = 1; return TRUE; } else if (ObjectEventExecSingleMovementAction(objectEvent, sprite)) { // finish movement action @@ -6168,7 +6194,7 @@ static u8 LoadWhiteFlashPalette(struct ObjectEvent *objectEvent, struct Sprite * bool8 MovementAction_ExitPokeball_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) { - + objectEvent->invisible = FALSE; if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_DASH)) { sub_8094554(objectEvent, sprite, DIR_SOUTH, GetMoveDirectionFastestAnimNum(DIR_NORTH), 8); sprite->data[7] = 0; // fast speed @@ -6214,13 +6240,9 @@ bool8 MovementAction_EnterPokeball_Step0(struct ObjectEvent *objectEvent, struct bool8 MovementAction_EnterPokeball_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite) { sprite->data[3]--; - if (sprite->data[3] == 0) - { + if (sprite->data[3] == 0) { sprite->data[2] = 2; - sprite->animPaused = TRUE; - return TRUE; - } else if (sprite->data[3] == 1) { // Change state - sprite->data[1] = 0; + return FALSE; } else if (sprite->data[3] == 11) { // Set palette to white LoadWhiteFlashPalette(objectEvent, sprite); } else if (sprite->data[3] == 7) { // Free white palette and change to pokeball @@ -6230,6 +6252,16 @@ bool8 MovementAction_EnterPokeball_Step1(struct ObjectEvent *objectEvent, struct return FALSE; } +bool8 MovementAction_EnterPokeball_Step2(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + ObjectEventSetGraphicsId(objectEvent, sprite->data[6]); + objectEvent->invisible = TRUE; + sprite->data[1] = 0; + sprite->data[6] = 0; + sprite->animPaused = TRUE; + return TRUE; +} + bool8 MovementAction_WalkInPlaceSlowUp_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) { sub_8094554(objectEvent, sprite, DIR_NORTH, GetMoveDirectionAnimNum(DIR_NORTH), 32); @@ -8386,13 +8418,13 @@ static void (*const sGroundEffectTracksFuncs[])(struct ObjectEvent *objEvent, st void GroundEffect_SandTracks(struct ObjectEvent *objEvent, struct Sprite *sprite) { const struct ObjectEventGraphicsInfo *info = GetObjectEventGraphicsInfo(objEvent->graphicsId); - sGroundEffectTracksFuncs[info->tracks](objEvent, sprite, 0); + sGroundEffectTracksFuncs[objEvent->invisible ? TRACKS_NONE : info->tracks](objEvent, sprite, 0); } void GroundEffect_DeepSandTracks(struct ObjectEvent *objEvent, struct Sprite *sprite) { const struct ObjectEventGraphicsInfo *info = GetObjectEventGraphicsInfo(objEvent->graphicsId); - sGroundEffectTracksFuncs[info->tracks](objEvent, sprite, 1); + sGroundEffectTracksFuncs[objEvent->invisible ? TRACKS_NONE : info->tracks](objEvent, sprite, 1); } static void DoTracksGroundEffect_None(struct ObjectEvent *objEvent, struct Sprite *sprite, u8 a) diff --git a/src/scrcmd.c b/src/scrcmd.c index 825c3d0f87..537233abd8 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -15,6 +15,7 @@ #include "field_effect.h" #include "event_object_lock.h" #include "event_object_movement.h" +#include "event_scripts.h" #include "field_message_box.h" #include "field_player_avatar.h" #include "field_screen_effect.h" @@ -1003,9 +1004,27 @@ bool8 ScrCmd_applymovement(struct ScriptContext *ctx) { u16 localId = VarGet(ScriptReadHalfword(ctx)); const void *movementScript = (const void *)ScriptReadWord(ctx); + struct ObjectEvent *objEvent; + ScriptMovement_StartObjectMovementScript(localId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, movementScript); sMovingNpcId = localId; + if (localId != OBJ_EVENT_ID_FOLLOWER) { // Force follower into pokeball + objEvent = GetFollowerObject(); + // return early if no follower or in shadowing state + if (objEvent == NULL || gSprites[objEvent->spriteId].data[1] == 0) { + return FALSE; + } + // ClearEventObjectMovement( + objEvent->singleMovementActive = 0; + objEvent->heldMovementActive = FALSE; + objEvent->heldMovementFinished = FALSE; + objEvent->movementActionId = 0xFF; + gSprites[objEvent->spriteId].data[1] = 0; + // ) + gSprites[objEvent->spriteId].animCmdIndex = 0; // Needed because of weird animCmdIndex stuff + ScriptMovement_StartObjectMovementScript(OBJ_EVENT_ID_FOLLOWER, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, EnterPokeballMovement); + } return FALSE; }