From bcfdf41078aa6725d631143f505e12c861836299 Mon Sep 17 00:00:00 2001 From: hedara90 <90hedara@gmail.com> Date: Tue, 22 Oct 2024 17:38:06 +0200 Subject: [PATCH] Follower female fix (#5475) Co-authored-by: Hedara --- include/event_object_movement.h | 8 ++++ include/global.fieldmap.h | 2 +- src/event_object_movement.c | 76 ++++++++++++++++++++------------- src/pokemon_sprite_visualizer.c | 10 +++-- 4 files changed, 63 insertions(+), 33 deletions(-) diff --git a/include/event_object_movement.h b/include/event_object_movement.h index 1dc604138b..4b1b3e1f9f 100644 --- a/include/event_object_movement.h +++ b/include/event_object_movement.h @@ -107,6 +107,13 @@ struct LockedAnimObjectEvents u8 count; }; +struct FollowerSpriteVisualizerData +{ + u16 currentmonId; + bool8 isShiny; + bool8 isFemale; +}; + extern const struct OamData gObjectEventBaseOam_32x8; extern const struct OamData gObjectEventBaseOam_32x32; extern const struct OamData gObjectEventBaseOam_64x64; @@ -146,6 +153,7 @@ void RemoveFollowingPokemon(void); struct ObjectEvent *GetFollowerObject(void); void TrySpawnObjectEvents(s16 cameraX, s16 cameraY); u8 CreateObjectGraphicsSprite(u16, void (*)(struct Sprite *), s16 x, s16 y, u8 subpriority); +u8 CreateObjectGraphicsFollowerSpriteForVisualizer(u16, void (*)(struct Sprite *), s16 x, s16 y, u8 subpriority, struct FollowerSpriteVisualizerData *data); u8 TrySpawnObjectEvent(u8 localId, u8 mapNum, u8 mapGroup); u8 SpawnSpecialObjectEventParameterized(u16 graphicsId, u8 movementBehavior, u8 localId, s16 x, s16 y, u8 elevation); u8 SpawnSpecialObjectEvent(struct ObjectEventTemplate *); diff --git a/include/global.fieldmap.h b/include/global.fieldmap.h index a9b859209b..d686a624a2 100644 --- a/include/global.fieldmap.h +++ b/include/global.fieldmap.h @@ -196,7 +196,7 @@ struct ObjectEvent u32 hideReflection:1; u32 shiny:1; // OW mon shininess u32 padding:3; - /*0x04*/ u16 graphicsId; // 11 bits for species; high 5 bits for form + /*0x04*/ u16 graphicsId; // 12 bits for species; high 4 bits for form /*0x06*/ u8 movementType; /*0x07*/ u8 trainerType; /*0x08*/ u8 localId; diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 08a5920dbf..9a4f9980f5 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -202,7 +202,6 @@ static const struct ObjectEventGraphicsInfo *SpeciesToGraphicsInfo(u16 species, static bool8 NpcTakeStep(struct Sprite *); static bool8 IsElevationMismatchAt(u8, s16, s16); static bool8 AreElevationsCompatible(u8, u8); -static u16 PackGraphicsId(const struct ObjectEventTemplate *template); static void CopyObjectGraphicsInfoToSpriteTemplate_WithMovementType(u16 graphicsId, u16 movementType, struct SpriteTemplate *spriteTemplate, const struct SubspriteTable **subspriteTables); static const struct SpriteFrameImage sPicTable_PechaBerryTree[]; @@ -1403,7 +1402,7 @@ static u8 InitObjectEventStateFromTemplate(const struct ObjectEventTemplate *tem y = template->y + MAP_OFFSET; objectEvent->active = TRUE; objectEvent->triggerGroundEffectsOnMove = TRUE; - objectEvent->graphicsId = PackGraphicsId(template); + objectEvent->graphicsId = template->graphicsId; SetObjectEventDynamicGraphicsId(objectEvent); if (IS_OW_MON_OBJ(objectEvent)) { @@ -1721,33 +1720,10 @@ static u8 TrySetupObjectEventSprite(const struct ObjectEventTemplate *objectEven return objectEventId; } -// Pack pokemon form info into a graphicsId, from a template's script -static u16 PackGraphicsId(const struct ObjectEventTemplate *template) -{ - u16 graphicsId = template->graphicsId; - u32 form = 0; - // set form based on template's script, - // if first command is bufferspeciesname - if (IS_OW_MON_OBJ(template)) - { - if (template->script && template->script[0] == 0x7d) - { - form = T1_READ_16(&template->script[2]); - form = (form >> 10) & 0x1F; - } - else if (template->trainerRange_berryTreeId) - { - form = template->trainerRange_berryTreeId & 0x1F; - } - graphicsId |= form << OBJ_EVENT_GFX_SPECIES_BITS; - } - return graphicsId; -} - static u8 TrySpawnObjectEventTemplate(const struct ObjectEventTemplate *objectEventTemplate, u8 mapNum, u8 mapGroup, s16 cameraX, s16 cameraY) { u8 objectEventId; - u16 graphicsId = PackGraphicsId(objectEventTemplate); + u16 graphicsId = objectEventTemplate->graphicsId; struct SpriteTemplate spriteTemplate; struct SpriteFrameImage spriteFrameImage; const struct ObjectEventGraphicsInfo *graphicsInfo; @@ -1894,6 +1870,51 @@ u8 CreateObjectGraphicsSprite(u16 graphicsId, void (*callback)(struct Sprite *), return spriteId; } +// Horrible workaround for sprite the visualizer, this should probably be reworked later +u8 CreateObjectGraphicsFollowerSpriteForVisualizer(u16 graphicsId, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, struct FollowerSpriteVisualizerData *data) +{ + struct SpriteTemplate *spriteTemplate; + const struct SubspriteTable *subspriteTables; + const struct ObjectEventGraphicsInfo *graphicsInfo = GetObjectEventGraphicsInfo(graphicsId); + struct Sprite *sprite; + u8 spriteId; + bool32 isShiny = data->isShiny; + + spriteTemplate = Alloc(sizeof(struct SpriteTemplate)); + CopyObjectGraphicsInfoToSpriteTemplate(graphicsId, callback, spriteTemplate, &subspriteTables); + + if (OW_GFX_COMPRESS) + { + // Checking only for compressed here so as not to mess with decorations + if (graphicsInfo->compressed) + spriteTemplate->tileTag = LoadSheetGraphicsInfo(graphicsInfo, graphicsId, NULL); + } + + if (spriteTemplate->paletteTag == OBJ_EVENT_PAL_TAG_DYNAMIC) + { + u32 paletteNum = LoadDynamicFollowerPaletteFromGraphicsId(graphicsId, isShiny, spriteTemplate); + spriteTemplate->paletteTag = GetSpritePaletteTagByPaletteNum(paletteNum); + } + else if (spriteTemplate->paletteTag != TAG_NONE) + { + LoadObjectEventPalette(spriteTemplate->paletteTag); + } + + spriteId = CreateSprite(spriteTemplate, x, y, subpriority); + + Free(spriteTemplate); + + if (spriteId != MAX_SPRITES && subspriteTables != NULL) + { + sprite = &gSprites[spriteId]; + if (OW_GFX_COMPRESS && graphicsInfo->compressed) + sprite->sheetSpan = GetSpanPerImage(sprite->oam.shape, sprite->oam.size); + SetSubspriteTables(sprite, subspriteTables); + sprite->subspriteMode = SUBSPRITES_IGNORE_PRIORITY; + } + return spriteId; +} + #define sVirtualObjId data[0] #define sVirtualObjElev data[1] @@ -2871,9 +2892,6 @@ const struct ObjectEventGraphicsInfo *GetObjectEventGraphicsInfo(u16 graphicsId) if (graphicsId >= OBJ_EVENT_GFX_VARS && graphicsId <= OBJ_EVENT_GFX_VAR_F) graphicsId = VarGetObjectEventGraphicsId(graphicsId - OBJ_EVENT_GFX_VARS); - if (graphicsId >= OBJ_EVENT_GFX_MON_BASE + SPECIES_SHINY_TAG) - graphicsId -= SPECIES_SHINY_TAG; - // graphicsId may contain mon form info if (graphicsId > OBJ_EVENT_GFX_SPECIES_MASK) { form = graphicsId >> OBJ_EVENT_GFX_SPECIES_BITS; diff --git a/src/pokemon_sprite_visualizer.c b/src/pokemon_sprite_visualizer.c index d1ec14fe0d..c6bb39faaf 100644 --- a/src/pokemon_sprite_visualizer.c +++ b/src/pokemon_sprite_visualizer.c @@ -2002,13 +2002,17 @@ static void ReloadPokemonSprites(struct PokemonSpriteVisualizer *data) //Follower Sprite u16 graphicsId = (OBJ_EVENT_GFX_MON_BASE + species) & OBJ_EVENT_GFX_SPECIES_MASK; + struct FollowerSpriteVisualizerData followerData; + followerData.currentmonId = graphicsId; + followerData.isFemale = data->isFemale; + followerData.isShiny = data->isShiny; graphicsId |= data->isFemale << OBJ_EVENT_GFX_SPECIES_BITS; - graphicsId += data->isShiny ? SPECIES_SHINY_TAG : 0; - data->followerspriteId = CreateObjectGraphicsSprite(graphicsId, + data->followerspriteId = CreateObjectGraphicsFollowerSpriteForVisualizer(graphicsId, SpriteCB_Follower, VISUALIZER_FOLLOWER_X, VISUALIZER_FOLLOWER_Y, - 0); + 0, + &followerData); gSprites[data->followerspriteId].oam.priority = 0; gSprites[data->followerspriteId].anims = sAnims_Follower;