From 69ae5b18c0181bbe33410f270d6417f791e7f090 Mon Sep 17 00:00:00 2001 From: Ariel Antonitis Date: Tue, 16 Jun 2020 20:21:05 -0400 Subject: [PATCH] Made pokemon event objects dynamic. --- include/constants/event_objects.h | 7 +- include/event_object_movement.h | 1 - include/global.fieldmap.h | 1 + .../object_event_graphics_info.h | 1 + .../object_event_graphics_info_pointers.h | 6 +- src/event_object_movement.c | 123 +++++++++++------- src/overworld.c | 7 +- 7 files changed, 82 insertions(+), 64 deletions(-) diff --git a/include/constants/event_objects.h b/include/constants/event_objects.h index f664d41a83..e6a5534997 100644 --- a/include/constants/event_objects.h +++ b/include/constants/event_objects.h @@ -241,12 +241,9 @@ #define OBJ_EVENT_GFX_LUGIA 237 #define OBJ_EVENT_GFX_HOOH 238 #define OBJ_EVENT_GFX_ANIMATED_BALL 239 -#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 OBJ_EVENT_GFX_FOLLOWER 240 -#define NUM_OBJ_EVENT_GFX 244 +#define NUM_OBJ_EVENT_GFX 241 // These are dynamic object gfx ids. diff --git a/include/event_object_movement.h b/include/event_object_movement.h index 586e98bffb..4aaa066c63 100644 --- a/include/event_object_movement.h +++ b/include/event_object_movement.h @@ -93,7 +93,6 @@ u8 GetFaceDirectionAnimNum(u8); void SetSpritePosToOffsetMapCoords(s16 *, s16 *, s16, s16); void ObjectEventClearHeldMovement(struct ObjectEvent *); void ObjectEventClearHeldMovementIfActive(struct ObjectEvent *); -u8 SpeciesToGraphicsId(u16 species); struct Pokemon * GetFirstLiveMon(void); u8 SpawnFollowingPokemon(void); void UpdateFollowingPokemon(void); diff --git a/include/global.fieldmap.h b/include/global.fieldmap.h index c4d7be35da..16684758ab 100644 --- a/include/global.fieldmap.h +++ b/include/global.fieldmap.h @@ -208,6 +208,7 @@ struct ObjectEvent /*0x20*/ u8 previousMovementDirection; /*0x21*/ u8 directionSequenceIndex; /*0x22*/ u8 playerCopyableMovement; + u8 unused; /*size = 0x24*/ }; diff --git a/src/data/object_events/object_event_graphics_info.h b/src/data/object_events/object_event_graphics_info.h index 930455238c..2f22e7dbec 100755 --- a/src/data/object_events/object_event_graphics_info.h +++ b/src/data/object_events/object_event_graphics_info.h @@ -248,3 +248,4 @@ const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Marshtomp = {0xFFF 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}; +const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Follower = {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_Togetic, 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 d48615b19f..289b899a61 100755 --- a/src/data/object_events/object_event_graphics_info_pointers.h +++ b/src/data/object_events/object_event_graphics_info_pointers.h @@ -243,6 +243,7 @@ const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Marshtomp; const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Altaria; const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Togetic; const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Charizard; +const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Follower; const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Bard; const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Hipster; @@ -494,10 +495,7 @@ const struct ObjectEventGraphicsInfo *const gObjectEventGraphicsInfoPointers[NUM [OBJ_EVENT_GFX_LUGIA] = &gObjectEventGraphicsInfo_Lugia, [OBJ_EVENT_GFX_HOOH] = &gObjectEventGraphicsInfo_HoOh, [OBJ_EVENT_GFX_ANIMATED_BALL] = &gObjectEventGraphicsInfo_AnimatedBall, - [OBJ_EVENT_GFX_MARSHTOMP] = &gObjectEventGraphicsInfo_Marshtomp, - [OBJ_EVENT_GFX_ALTARIA] = &gObjectEventGraphicsInfo_Altaria, - [OBJ_EVENT_GFX_TOGETIC] = &gObjectEventGraphicsInfo_Togetic, - [OBJ_EVENT_GFX_CHARIZARD] = &gObjectEventGraphicsInfo_Charizard, + [OBJ_EVENT_GFX_FOLLOWER] = &gObjectEventGraphicsInfo_Follower, }; const struct ObjectEventGraphicsInfo *const gMauvilleOldManGraphicsInfoPointers[] = { diff --git a/src/event_object_movement.c b/src/event_object_movement.c index bc6d7aceb8..7d20a466c6 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -1580,22 +1580,6 @@ u8 CreateObjectSprite(u8 graphicsId, u8 a1, s16 x, s16 y, u8 z, u8 direction) return spriteId; } -u8 SpeciesToGraphicsId(u16 species) { // TODO: Eventually graphicsIds will have to be u16's - switch (species) { - case SPECIES_MARSHTOMP: - return OBJ_EVENT_GFX_MARSHTOMP; - break; - case SPECIES_ALTARIA: - return OBJ_EVENT_GFX_ALTARIA; - break; - case SPECIES_TOGETIC: - return OBJ_EVENT_GFX_TOGETIC; - break; - default: - return OBJ_EVENT_GFX_DUSCLOPS; // TODO: Change this - } -} - struct Pokemon * GetFirstLiveMon(void) { // Return address of first conscious party mon or NULL struct Pokemon *mon; u8 i; @@ -1608,24 +1592,21 @@ struct Pokemon * GetFirstLiveMon(void) { // Return address of first conscious pa } u8 SpawnFollowingPokemon(void) { // Spawn a following pokemon TODO: Avoid this on certain maps - struct Pokemon *mon; - u8 graphicsId; u8 objectEventId; struct ObjectEventTemplate template = {0}; template.localId = OBJ_EVENT_ID_FOLLOWER; - mon = GetFirstLiveMon(); - if (mon == NULL) { // fainted party, don't spawn a follower + if (GetFirstLiveMon() == NULL) // fainted party, don't spawn a follower return 0xFF; - } - template.graphicsId = SpeciesToGraphicsId(GetMonData(mon, MON_DATA_SPECIES)); + template.graphicsId = OBJ_EVENT_GFX_FOLLOWER; template.x = gSaveBlock1Ptr->pos.x; template.y = gSaveBlock1Ptr->pos.y; - template.elevation = 5; + template.elevation = 3; template.movementType = MOVEMENT_TYPE_FOLLOW_PLAYER; // template.script = EventScript_Follower; // This does nothing because scripts are templated objectEventId = SpawnSpecialObjectEvent(&template); gObjectEvents[objectEventId].invisible = TRUE; + UpdateFollowingPokemon(); return objectEventId; } @@ -1639,38 +1620,82 @@ struct ObjectEvent * GetFollowerObject(void) { // Return follower ObjectEvent or return NULL; } -void UpdateFollowingPokemon(void) { - u8 i; - u8 graphicsId; +// Return graphicsInfo for a pokemon species TODO: Make this into a table lookup +static const struct ObjectEventGraphicsInfo * SpeciesToGraphicsInfo(u16 species) { + switch (species) { + case SPECIES_MARSHTOMP : + return &gObjectEventGraphicsInfo_Marshtomp; + break; + case SPECIES_TOGETIC : + return &gObjectEventGraphicsInfo_Togetic; + break; + case SPECIES_ALTARIA : + return &gObjectEventGraphicsInfo_Altaria; + break; + case SPECIES_CHARIZARD : + return &gObjectEventGraphicsInfo_Charizard; + break; + default: + return &gObjectEventGraphicsInfo_Dusclops; + } +} + +// Set graphics & sprite for a follower object event by species TODO: Refactoring +static void FollowerSetGraphics(struct ObjectEvent *objectEvent, u16 species) { + const struct ObjectEventGraphicsInfo *graphicsInfo = SpeciesToGraphicsInfo(species); + struct Sprite *sprite = &gSprites[objectEvent->spriteId]; + u16 i = FindObjectEventPaletteIndexByTag(graphicsInfo->paletteTag1); + u8 paletteNum = UpdateSpritePalette((struct SpritePalette *)&sObjectEventSpritePalettes[i], sprite); + sprite->oam.paletteNum = paletteNum; + sprite->oam.shape = graphicsInfo->oam->shape; + sprite->oam.size = graphicsInfo->oam->size; + sprite->images = graphicsInfo->images; + sprite->anims = graphicsInfo->anims; + sprite->subspriteTables = graphicsInfo->subspriteTables; + objectEvent->inanimate = graphicsInfo->inanimate; + objectEvent->graphicsId = OBJ_EVENT_GFX_FOLLOWER; + SetSpritePosToMapCoords(objectEvent->currentCoords.x, objectEvent->currentCoords.y, &sprite->pos1.x, &sprite->pos1.y); + sprite->centerToCornerVecX = -(graphicsInfo->width >> 1); + sprite->centerToCornerVecY = -(graphicsInfo->height >> 1); + sprite->pos1.x += 8; + sprite->pos1.y += 16 + sprite->centerToCornerVecY; + if (objectEvent->trackedByCamera) + { + CameraObjectReset1(); + } +} + +void UpdateFollowingPokemon(void) { // Update following pokemon if any struct ObjectEvent *objectEvent = GetFollowerObject(); + struct Sprite *sprite; struct Pokemon *mon = GetFirstLiveMon(); - if (objectEvent == NULL) { + u16 species; + u16 *oldSpecies; + if (objectEvent == NULL || mon == NULL) { return; } - if (mon == NULL) { // TODO: Fainted party - return; - } - graphicsId = SpeciesToGraphicsId(GetMonData(mon, MON_DATA_SPECIES)); - if (graphicsId != objectEvent->graphicsId) { // Mark as invisible + sprite = &gSprites[objectEvent->spriteId]; + species = GetMonData(mon, MON_DATA_SPECIES); + oldSpecies = (u16*) &objectEvent->playerCopyableMovement; + if (species != *oldSpecies) { // Move to player and set 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 } + FollowerSetGraphics(objectEvent, species); // TODO: This should be done to all pokemon graphics + *oldSpecies = species; // set species + sprite->data[6] = 0; // set animation data + sprite->data[7] = species; // set species return; } -void RemoveFollowingPokemon(void) { +void RemoveFollowingPokemon(void) { // Remove follower object. Idempotent. struct ObjectEvent *objectEvent = GetFollowerObject(); - if (objectEvent == NULL) { + if (objectEvent == NULL) return; - } RemoveObjectEvent(objectEvent); } -static bool8 IsFollowerVisible(void) { // Determine whether follower should be visible +static bool8 IsFollowerVisible(void) { // Determine whether follower *should* be visible return !TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING | PLAYER_AVATAR_FLAG_ACRO_BIKE | PLAYER_AVATAR_FLAG_MACH_BIKE); } @@ -6226,19 +6251,18 @@ bool8 MovementAction_ExitPokeball_Step0(struct ObjectEvent *objectEvent, struct 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 + sprite->data[6] = 0; // fast speed } else { sub_8094554(objectEvent, sprite, DIR_SOUTH, GetMoveDirectionFastestAnimNum(DIR_SOUTH), 16); - sprite->data[7] = 1; // slow speed + sprite->data[6] = 1; // slow speed } - sprite->data[6] = objectEvent->graphicsId; ObjectEventSetGraphicsId(objectEvent, OBJ_EVENT_GFX_ANIMATED_BALL); return MovementAction_ExitPokeball_Step1(objectEvent, sprite); } bool8 MovementAction_ExitPokeball_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite) { - u8 duration = sprite->data[7] & 0xF; + u8 duration = sprite->data[6] & 0xF; sprite->data[3]--; if (sprite->data[3] == 0) { @@ -6247,13 +6271,13 @@ bool8 MovementAction_ExitPokeball_Step1(struct ObjectEvent *objectEvent, struct return TRUE; // Restore graphicsId and set palette to white } else if ((duration == 0 && sprite->data[3] == 3) || (duration == 1 && sprite->data[3] == 7)) { - ObjectEventSetGraphicsId(objectEvent, sprite->data[6]); - sprite->data[7] = (sprite->oam.paletteNum << 4) | (sprite->data[7] & 0xFF0F); // Save old paletteNum + FollowerSetGraphics(objectEvent, sprite->data[7]); + sprite->data[6] = (sprite->oam.paletteNum << 4) | (sprite->data[6] & 0xFF0F); // Save old paletteNum LoadWhiteFlashPalette(objectEvent, sprite); // Restore original palette } else if ((duration == 0 && sprite->data[3] == 1) || (duration == 1 && sprite->data[3] == 3)) { FreeSpritePaletteByTag(OBJ_EVENT_PAL_TAG_NONE-1); - sprite->oam.paletteNum = (sprite->data[7] >> 4) & 0xF; + sprite->oam.paletteNum = (sprite->data[6] >> 4) & 0xF; } return FALSE; } @@ -6261,8 +6285,7 @@ bool8 MovementAction_ExitPokeball_Step1(struct ObjectEvent *objectEvent, struct bool8 MovementAction_EnterPokeball_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) { u8 direction = objectEvent->facingDirection; sub_8094554(objectEvent, sprite, direction, GetMoveDirectionFasterAnimNum(direction), 16); - sprite->data[7] = 1; // slow speed - sprite->data[6] = objectEvent->graphicsId; + sprite->data[6] = 1; // slow speed return MovementAction_EnterPokeball_Step1(objectEvent, sprite); } @@ -6283,7 +6306,7 @@ bool8 MovementAction_EnterPokeball_Step1(struct ObjectEvent *objectEvent, struct bool8 MovementAction_EnterPokeball_Step2(struct ObjectEvent *objectEvent, struct Sprite *sprite) { - ObjectEventSetGraphicsId(objectEvent, sprite->data[6]); + FollowerSetGraphics(objectEvent, sprite->data[7]); objectEvent->invisible = TRUE; sprite->data[1] = 0; sprite->data[6] = 0; diff --git a/src/overworld.c b/src/overworld.c index 50527c50d6..d8b0284c11 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -813,7 +813,7 @@ void LoadMapFromCameraTransition(u8 mapGroup, u8 mapNum) ResetFieldTasksArgs(); RunOnResumeMapScript(); - if (gMapHeader.regionMapSectionId != MAPSEC_BATTLE_FRONTIER + if (gMapHeader.regionMapSectionId != MAPSEC_BATTLE_FRONTIER || gMapHeader.regionMapSectionId != sLastMapSectionId) ShowMapNamePopup(); } @@ -1604,10 +1604,8 @@ static void CB2_LoadMapOnReturnToFieldCableClub(void) void CB2_ReturnToField(void) { - if (gFieldCallback == FieldCallback_Fly) { + if (gFieldCallback == FieldCallback_Fly) { // Destroy follower if flying away RemoveFollowingPokemon(); - } else { - UpdateFollowingPokemon(); } if (IsUpdateLinkStateCBActive() == TRUE) { @@ -1952,6 +1950,7 @@ static bool32 ReturnToFieldLocal(u8 *state) sub_80867D8(); ResumeMap(FALSE); sub_8086A68(); + UpdateFollowingPokemon(); // TODO: Update all dynamic graphicsIds SetCameraToTrackPlayer(); (*state)++; break;