diff --git a/include/global.fieldmap.h b/include/global.fieldmap.h index 0e65cc844c..3e250c217d 100644 --- a/include/global.fieldmap.h +++ b/include/global.fieldmap.h @@ -213,8 +213,8 @@ struct ObjectEvent /*0x22*/ union __attribute__((packed)) { u8 playerCopyableMovement; struct __attribute__((packed)) { - u16 species:11; // 11 bits; 2048 species - u16 form:4; + u16 species:10; // 11 bits; 1024 species + u16 form:5; // Used for Deoxys, Unown, etc u16 shiny:1; } mon; u16 asU16; diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 6fab120d76..b75b0912b0 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -1645,10 +1645,19 @@ struct ObjectEvent * GetFollowerObject(void) { // Return follower ObjectEvent or return NULL; } -// Return graphicsInfo for a pokemon species +// Return graphicsInfo for a pokemon species & form static const struct ObjectEventGraphicsInfo * SpeciesToGraphicsInfo(u16 species, u8 form) { - const struct ObjectEventGraphicsInfo *graphicsInfo = &gPokemonObjectGraphics[species]; - return graphicsInfo->tileTag == 0xFFFF ? graphicsInfo : &gPokemonObjectGraphics[SPECIES_PORYGON]; + const struct ObjectEventGraphicsInfo *graphicsInfo; + switch (species) { + case SPECIES_UNOWN: // Letters >A are defined as species >= NUM_SPECIES, so are not contiguous with A + form %= NUM_UNOWN_FORMS; + graphicsInfo = &gPokemonObjectGraphics[form ? SPECIES_UNOWN_B + form - 1 : species]; + break; + default: + graphicsInfo = &gPokemonObjectGraphics[species]; + break; + } + return graphicsInfo->tileTag == 0xFFFF ? graphicsInfo : &gPokemonObjectGraphics[SPECIES_PORYGON]; // avoid OOB access } // Set graphics & sprite for a follower object event by species & shininess. @@ -1684,6 +1693,7 @@ void UpdateFollowingPokemon(void) { // Update following pokemon if any struct Sprite *sprite; u16 species; bool8 shiny; + u8 form; // Avoid spawning large (64x64) follower pokemon inside buildings if (mon && !(gMapHeader.mapType == MAP_TYPE_INDOOR && SpeciesToGraphicsInfo(GetMonData(mon, MON_DATA_SPECIES), 0)->width == 64)) { if (objEvent == NULL) { // Spawn follower @@ -1701,14 +1711,17 @@ void UpdateFollowingPokemon(void) { // Update following pokemon if any sprite = &gSprites[objEvent->spriteId]; species = GetMonData(mon, MON_DATA_SPECIES); shiny = IsMonShiny(mon); - if (species != objEvent->extra.mon.species || shiny != objEvent->extra.mon.shiny) { // Move to player and set invisible + form = species == SPECIES_UNOWN ? GET_UNOWN_LETTER(mon->box.personality) : 0; + // Follower appearance changed; move to player and set invisible + if (species != objEvent->extra.mon.species || shiny != objEvent->extra.mon.shiny || form != objEvent->extra.mon.form) { MoveObjectEventToMapCoords(objEvent, gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.x, gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.y); objEvent->invisible = TRUE; } - FollowerSetGraphics(objEvent, species, 0, shiny); + FollowerSetGraphics(objEvent, species, form, shiny); sprite->data[6] = 0; // set animation data objEvent->extra.mon.species = species; objEvent->extra.mon.shiny = shiny; + objEvent->extra.mon.form = form; } else { RemoveFollowingPokemon(); }