Follower Object Event refactor (#6129)
Co-authored-by: Hedara <hedara90@gmail.com>
This commit is contained in:
parent
3ba4e3c0c7
commit
f9d1fdcf4c
@ -270,19 +270,23 @@
|
||||
#define OBJ_EVENT_GFX_VAR_E (OBJ_EVENT_GFX_VARS + 0xE)
|
||||
#define OBJ_EVENT_GFX_VAR_F (OBJ_EVENT_GFX_VARS + 0xF)
|
||||
|
||||
#define OBJ_EVENT_GFX_MON_BASE 0x200 // 512
|
||||
#define OBJ_EVENT_GFX_SPECIES_BITS 12 // This will need to be updated when NUM_SPECIES is > ~3.5k
|
||||
#define OBJ_EVENT_GFX_SPECIES_MASK ((1 << OBJ_EVENT_GFX_SPECIES_BITS) - 1)
|
||||
#define OBJ_EVENT_MON (1 << 13)
|
||||
#define OBJ_EVENT_MON_SHINY (1 << 14)
|
||||
#define OBJ_EVENT_MON_FEMALE (1 << 15)
|
||||
#define OBJ_EVENT_MON_SPECIES_MASK (OBJ_EVENT_MON - 1)
|
||||
|
||||
// Used to call a specific species' follower graphics. Useful for static encounters.
|
||||
#define OBJ_EVENT_GFX_SPECIES(name) (SPECIES_##name + OBJ_EVENT_GFX_MON_BASE)
|
||||
#define OBJ_EVENT_GFX_SPECIES_SHINY(name) (SPECIES_##name + OBJ_EVENT_GFX_MON_BASE + SPECIES_SHINY_TAG)
|
||||
#define OBJ_EVENT_GFX_SPECIES(name) (SPECIES_##name + OBJ_EVENT_MON)
|
||||
#define OBJ_EVENT_GFX_SPECIES_SHINY(name) (SPECIES_##name + OBJ_EVENT_MON + OBJ_EVENT_MON_SHINY)
|
||||
#define OBJ_EVENT_GFX_SPECIES_FEMALE(name) (SPECIES_##name + OBJ_EVENT_MON + OBJ_EVENT_MON_FEMALE)
|
||||
#define OBJ_EVENT_GFX_SPECIES_SHINY_FEMALE(name) (SPECIES_##name + OBJ_EVENT_MON + OBJ_EVENT_MON_SHINY + OBJ_EVENT_MON_FEMALE)
|
||||
|
||||
#define OW_SPECIES(x) (((x)->graphicsId & OBJ_EVENT_GFX_SPECIES_MASK) - OBJ_EVENT_GFX_MON_BASE)
|
||||
#define OW_FORM(x) ((x)->graphicsId >> OBJ_EVENT_GFX_SPECIES_BITS)
|
||||
#define OW_SPECIES(x) ((x)->graphicsId & OBJ_EVENT_MON_SPECIES_MASK)
|
||||
#define OW_SHINY(x) ((x)->graphicsId & OBJ_EVENT_MON_SHINY)
|
||||
#define OW_FEMALE(x) ((x)->graphicsId & OBJ_EVENT_MON_FEMALE)
|
||||
|
||||
// Whether Object Event is an OW pokemon
|
||||
#define IS_OW_MON_OBJ(obj) ((obj)->graphicsId >= OBJ_EVENT_GFX_MON_BASE)
|
||||
#define IS_OW_MON_OBJ(obj) ((obj)->graphicsId & OBJ_EVENT_MON)
|
||||
|
||||
#define SHADOW_SIZE_S 0
|
||||
#define SHADOW_SIZE_M 1
|
||||
|
||||
@ -107,13 +107,6 @@ 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;
|
||||
@ -153,7 +146,6 @@ 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 *);
|
||||
|
||||
@ -185,7 +185,7 @@ static void SetSpriteDataForNormalStep(struct Sprite *, u8, u8);
|
||||
static void InitSpriteForFigure8Anim(struct Sprite *);
|
||||
static bool8 AnimateSpriteInFigure8(struct Sprite *);
|
||||
u8 GetDirectionToFace(s16 x1, s16 y1, s16 x2, s16 y2);
|
||||
static void FollowerSetGraphics(struct ObjectEvent *, u16, u8, bool8);
|
||||
static void FollowerSetGraphics(struct ObjectEvent * objectEvent, u32 species, bool32 shiny, bool32 female);
|
||||
static void ObjectEventSetGraphics(struct ObjectEvent *, const struct ObjectEventGraphicsInfo *);
|
||||
static void SpriteCB_VirtualObject(struct Sprite *);
|
||||
static void DoShadowFieldEffect(struct ObjectEvent *);
|
||||
@ -196,14 +196,17 @@ static u8 DoJumpSpriteMovement(struct Sprite *);
|
||||
static u8 DoJumpSpecialSpriteMovement(struct Sprite *);
|
||||
static void CreateLevitateMovementTask(struct ObjectEvent *);
|
||||
static void DestroyLevitateMovementTask(u8);
|
||||
static bool8 GetFollowerInfo(u16 *species, u8 *form, u8 *shiny);
|
||||
static u8 LoadDynamicFollowerPalette(u16 species, u8 form, bool32 shiny);
|
||||
static const struct ObjectEventGraphicsInfo *SpeciesToGraphicsInfo(u16 species, u8 form);
|
||||
static bool8 GetFollowerInfo(u32 *species, bool32 *shiny, bool32 *female);
|
||||
static u32 LoadDynamicFollowerPalette(u32 species, bool32 shiny, bool32 female);
|
||||
static const struct ObjectEventGraphicsInfo *SpeciesToGraphicsInfo(u32 species, bool32 shiny, bool32 female);
|
||||
static bool8 NpcTakeStep(struct Sprite *);
|
||||
static bool8 IsElevationMismatchAt(u8, s16, s16);
|
||||
static bool8 AreElevationsCompatible(u8, u8);
|
||||
static void CopyObjectGraphicsInfoToSpriteTemplate_WithMovementType(u16 graphicsId, u16 movementType, struct SpriteTemplate *spriteTemplate, const struct SubspriteTable **subspriteTables);
|
||||
|
||||
static u16 GetGraphicsIdForMon(u32 species, bool32 shiny, bool32 female);
|
||||
static u16 GetUnownSpecies(struct Pokemon *mon);
|
||||
|
||||
static const struct SpriteFrameImage sPicTable_PechaBerryTree[];
|
||||
|
||||
static void StartSlowRunningAnim(struct ObjectEvent *objectEvent, struct Sprite *sprite, u8 direction);
|
||||
@ -1678,17 +1681,8 @@ static u8 TrySetupObjectEventSprite(const struct ObjectEventTemplate *objectEven
|
||||
if (OW_GFX_COMPRESS)
|
||||
spriteTemplate->tileTag = LoadSheetGraphicsInfo(graphicsInfo, objectEvent->graphicsId, NULL);
|
||||
|
||||
if (objectEvent->graphicsId >= OBJ_EVENT_GFX_MON_BASE + SPECIES_SHINY_TAG)
|
||||
{
|
||||
if (objectEvent->graphicsId & OBJ_EVENT_MON && objectEvent->graphicsId & OBJ_EVENT_MON_SHINY)
|
||||
objectEvent->shiny = TRUE;
|
||||
objectEvent->graphicsId -= SPECIES_SHINY_TAG;
|
||||
}
|
||||
|
||||
if (objectEvent->graphicsId >= OBJ_EVENT_GFX_MON_BASE + SPECIES_SHINY_TAG)
|
||||
{
|
||||
objectEvent->shiny = TRUE;
|
||||
objectEvent->graphicsId -= SPECIES_SHINY_TAG;
|
||||
}
|
||||
|
||||
spriteId = CreateSprite(spriteTemplate, 0, 0, 0);
|
||||
if (spriteId == MAX_SPRITES)
|
||||
@ -1700,7 +1694,7 @@ static u8 TrySetupObjectEventSprite(const struct ObjectEventTemplate *objectEven
|
||||
sprite = &gSprites[spriteId];
|
||||
// Use palette from species palette table
|
||||
if (spriteTemplate->paletteTag == OBJ_EVENT_PAL_TAG_DYNAMIC)
|
||||
sprite->oam.paletteNum = LoadDynamicFollowerPalette(OW_SPECIES(objectEvent), OW_FORM(objectEvent), objectEvent->shiny);
|
||||
sprite->oam.paletteNum = LoadDynamicFollowerPalette(OW_SPECIES(objectEvent), OW_SHINY(objectEvent), OW_FEMALE(objectEvent));
|
||||
if (OW_GFX_COMPRESS && sprite->usingSheet)
|
||||
sprite->sheetSpan = GetSpanPerImage(sprite->oam.shape, sprite->oam.size);
|
||||
GetMapCoordsFromSpritePos(objectEvent->currentCoords.x + cameraX, objectEvent->currentCoords.y + cameraY, &sprite->x, &sprite->y);
|
||||
@ -1812,13 +1806,20 @@ static void UNUSED MakeSpriteTemplateFromObjectEventTemplate(const struct Object
|
||||
|
||||
// Loads information from graphicsId, with shininess separate
|
||||
// also can write palette tag to the template
|
||||
static u8 LoadDynamicFollowerPaletteFromGraphicsId(u16 graphicsId, bool8 shiny, struct SpriteTemplate *template)
|
||||
static u32 LoadDynamicFollowerPaletteFromGraphicsId(u16 graphicsId, struct SpriteTemplate *template)
|
||||
{
|
||||
u16 species = ((graphicsId & OBJ_EVENT_GFX_SPECIES_MASK) - OBJ_EVENT_GFX_MON_BASE);
|
||||
u8 form = (graphicsId >> OBJ_EVENT_GFX_SPECIES_BITS);
|
||||
u8 paletteNum = LoadDynamicFollowerPalette(species, form, shiny);
|
||||
u16 species = graphicsId & OBJ_EVENT_MON_SPECIES_MASK;
|
||||
bool32 shiny = graphicsId & OBJ_EVENT_MON_SHINY;
|
||||
bool32 female = graphicsId & OBJ_EVENT_MON_FEMALE;
|
||||
u8 paletteNum = LoadDynamicFollowerPalette(species, shiny, female);
|
||||
if (template)
|
||||
template->paletteTag = species;
|
||||
{
|
||||
template->paletteTag = species + OBJ_EVENT_MON;
|
||||
if (shiny)
|
||||
template->paletteTag += OBJ_EVENT_MON_SHINY;
|
||||
if (female)
|
||||
template->paletteTag += OBJ_EVENT_MON_FEMALE;
|
||||
}
|
||||
return paletteNum;
|
||||
}
|
||||
|
||||
@ -1830,7 +1831,7 @@ u8 CreateObjectGraphicsSprite(u16 graphicsId, void (*callback)(struct Sprite *),
|
||||
const struct ObjectEventGraphicsInfo *graphicsInfo = GetObjectEventGraphicsInfo(graphicsId);
|
||||
struct Sprite *sprite;
|
||||
u8 spriteId;
|
||||
bool32 isShiny = graphicsId >= SPECIES_SHINY_TAG + OBJ_EVENT_GFX_MON_BASE;
|
||||
bool32 isShiny = graphicsId & OBJ_EVENT_MON_SHINY;
|
||||
|
||||
spriteTemplate = Alloc(sizeof(struct SpriteTemplate));
|
||||
CopyObjectGraphicsInfoToSpriteTemplate(graphicsId, callback, spriteTemplate, &subspriteTables);
|
||||
@ -1847,52 +1848,7 @@ u8 CreateObjectGraphicsSprite(u16 graphicsId, void (*callback)(struct Sprite *),
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
u32 paletteNum = LoadDynamicFollowerPaletteFromGraphicsId(graphicsId, spriteTemplate);
|
||||
spriteTemplate->paletteTag = GetSpritePaletteTagByPaletteNum(paletteNum);
|
||||
}
|
||||
else if (spriteTemplate->paletteTag != TAG_NONE)
|
||||
@ -1988,19 +1944,18 @@ struct ObjectEvent *GetFollowerObject(void)
|
||||
}
|
||||
|
||||
// Return graphicsInfo for a pokemon species & form
|
||||
static const struct ObjectEventGraphicsInfo *SpeciesToGraphicsInfo(u16 species, u8 form)
|
||||
static const struct ObjectEventGraphicsInfo *SpeciesToGraphicsInfo(u32 species, bool32 shiny, bool32 female)
|
||||
{
|
||||
const struct ObjectEventGraphicsInfo *graphicsInfo = NULL;
|
||||
#if OW_POKEMON_OBJECT_EVENTS
|
||||
switch (species)
|
||||
{
|
||||
case SPECIES_UNOWN: // Letters >A are defined as species >= NUM_SPECIES, so are not contiguous with A
|
||||
form %= NUM_UNOWN_FORMS;
|
||||
graphicsInfo = &gSpeciesInfo[form ? SPECIES_UNOWN_B + form - 1 : species].overworldData;
|
||||
case SPECIES_UNOWN: // Deal with Unown forms later
|
||||
graphicsInfo = &gSpeciesInfo[species].overworldData;
|
||||
break;
|
||||
default:
|
||||
#if P_GENDER_DIFFERENCES
|
||||
if (form == 1 && gSpeciesInfo[species].overworldDataFemale.paletteTag == OBJ_EVENT_PAL_TAG_DYNAMIC)
|
||||
if (female && gSpeciesInfo[species].overworldDataFemale.paletteTag == OBJ_EVENT_PAL_TAG_DYNAMIC)
|
||||
{
|
||||
graphicsInfo = &gSpeciesInfo[species].overworldDataFemale;
|
||||
}
|
||||
@ -2024,17 +1979,18 @@ static const struct ObjectEventGraphicsInfo *SpeciesToGraphicsInfo(u16 species,
|
||||
}
|
||||
|
||||
// Find, or load, the palette for the specified pokemon info
|
||||
static u8 LoadDynamicFollowerPalette(u16 species, u8 form, bool32 shiny)
|
||||
static u32 LoadDynamicFollowerPalette(u32 species, bool32 shiny, bool32 female)
|
||||
{
|
||||
u32 paletteNum;
|
||||
bool32 female = (form == 1);
|
||||
// Use standalone palette, unless entry is OOB or NULL (fallback to front-sprite-based)
|
||||
#if OW_POKEMON_OBJECT_EVENTS == TRUE && OW_PKMN_OBJECTS_SHARE_PALETTES == FALSE
|
||||
if ((shiny && gSpeciesInfo[species].overworldPalette)
|
||||
|| (!shiny && gSpeciesInfo[species].overworldShinyPalette))
|
||||
{
|
||||
struct SpritePalette spritePalette;
|
||||
u16 palTag = shiny ? (species + SPECIES_SHINY_TAG + OBJ_EVENT_PAL_TAG_DYNAMIC) : (species + OBJ_EVENT_PAL_TAG_DYNAMIC);
|
||||
u16 palTag = species + OBJ_EVENT_MON + (shiny ? OBJ_EVENT_MON_SHINY : 0);
|
||||
if (female && gSpeciesInfo[species].overworldShinyPaletteFemale != NULL)
|
||||
palTag += OBJ_EVENT_MON_FEMALE;
|
||||
// palette already loaded
|
||||
if ((paletteNum = IndexOfSpritePaletteTag(palTag)) < 16)
|
||||
return paletteNum;
|
||||
@ -2056,7 +2012,6 @@ static u8 LoadDynamicFollowerPalette(u16 species, u8 form, bool32 shiny)
|
||||
spritePalette.data = gSpeciesInfo[species].overworldPalette;
|
||||
}
|
||||
|
||||
|
||||
// Check if pal data must be decompressed
|
||||
if (IsLZ77Data(spritePalette.data, PLTT_SIZE_4BPP, PLTT_SIZE_4BPP))
|
||||
{
|
||||
@ -2087,13 +2042,11 @@ static u8 LoadDynamicFollowerPalette(u16 species, u8 form, bool32 shiny)
|
||||
}
|
||||
|
||||
// Set graphics & sprite for a follower object event by species & shininess.
|
||||
static void FollowerSetGraphics(struct ObjectEvent *objEvent, u16 species, u8 form, bool8 shiny)
|
||||
static void FollowerSetGraphics(struct ObjectEvent *objEvent, u32 species, bool32 shiny, bool32 female)
|
||||
{
|
||||
const struct ObjectEventGraphicsInfo *graphicsInfo = SpeciesToGraphicsInfo(species, form);
|
||||
const struct ObjectEventGraphicsInfo *graphicsInfo = SpeciesToGraphicsInfo(species, shiny, female);
|
||||
ObjectEventSetGraphics(objEvent, graphicsInfo);
|
||||
objEvent->graphicsId = (OBJ_EVENT_GFX_MON_BASE + species) & OBJ_EVENT_GFX_SPECIES_MASK;
|
||||
objEvent->graphicsId |= form << OBJ_EVENT_GFX_SPECIES_BITS;
|
||||
objEvent->shiny = shiny;
|
||||
objEvent->graphicsId = GetGraphicsIdForMon(species, shiny, female);
|
||||
if (graphicsInfo->paletteTag == OBJ_EVENT_PAL_TAG_DYNAMIC) // Use palette from species palette table
|
||||
{
|
||||
struct Sprite *sprite = &gSprites[objEvent->spriteId];
|
||||
@ -2101,7 +2054,7 @@ static void FollowerSetGraphics(struct ObjectEvent *objEvent, u16 species, u8 fo
|
||||
sprite->inUse = FALSE;
|
||||
FieldEffectFreePaletteIfUnused(sprite->oam.paletteNum);
|
||||
sprite->inUse = TRUE;
|
||||
sprite->oam.paletteNum = LoadDynamicFollowerPalette(species, form, shiny);
|
||||
sprite->oam.paletteNum = LoadDynamicFollowerPalette(species, shiny, female);
|
||||
}
|
||||
else if (gWeatherPtr->currWeather != WEATHER_FOG_HORIZONTAL) // don't want to weather blend in fog
|
||||
{
|
||||
@ -2114,9 +2067,9 @@ static void FollowerSetGraphics(struct ObjectEvent *objEvent, u16 species, u8 fo
|
||||
static void RefreshFollowerGraphics(struct ObjectEvent *objEvent)
|
||||
{
|
||||
u32 species = OW_SPECIES(objEvent);
|
||||
u32 form = OW_FORM(objEvent);
|
||||
u32 shiny = objEvent->shiny;
|
||||
const struct ObjectEventGraphicsInfo *graphicsInfo = SpeciesToGraphicsInfo(species, form);
|
||||
bool32 shiny = OW_SHINY(objEvent);
|
||||
bool32 female = OW_FEMALE(objEvent);
|
||||
const struct ObjectEventGraphicsInfo *graphicsInfo = SpeciesToGraphicsInfo(species, shiny, female);
|
||||
struct Sprite *sprite = &gSprites[objEvent->spriteId];
|
||||
u32 i = FindObjectEventPaletteIndexByTag(graphicsInfo->paletteTag);
|
||||
|
||||
@ -2145,7 +2098,7 @@ static void RefreshFollowerGraphics(struct ObjectEvent *objEvent)
|
||||
sprite->inUse = FALSE;
|
||||
FieldEffectFreePaletteIfUnused(sprite->oam.paletteNum);
|
||||
sprite->inUse = TRUE;
|
||||
sprite->oam.paletteNum = LoadDynamicFollowerPalette(species, form, shiny);
|
||||
sprite->oam.paletteNum = LoadDynamicFollowerPalette(species, shiny, female);
|
||||
}
|
||||
else if (i != 0xFF)
|
||||
{
|
||||
@ -2172,23 +2125,22 @@ static u16 GetOverworldCastformSpecies(void)
|
||||
return SPECIES_CASTFORM_NORMAL;
|
||||
}
|
||||
|
||||
static bool8 GetMonInfo(struct Pokemon *mon, u16 *species, u8 *form, u8 *shiny)
|
||||
static bool8 GetMonInfo(struct Pokemon *mon, u32 *species, bool32 *shiny, bool32 *female)
|
||||
{
|
||||
*form = 0; // default
|
||||
if (!mon)
|
||||
{
|
||||
*species = SPECIES_NONE;
|
||||
*form = 0;
|
||||
*shiny = 0;
|
||||
*shiny = FALSE;
|
||||
*female = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
*species = GetMonData(mon, MON_DATA_SPECIES);
|
||||
*form = GetMonGender(mon) == MON_FEMALE;
|
||||
*shiny = IsMonShiny(mon);
|
||||
*shiny = IsMonShiny(mon) ? OBJ_EVENT_MON_SHINY : 0;
|
||||
*female = GetMonGender(mon) == MON_FEMALE ? OBJ_EVENT_MON_FEMALE : 0;
|
||||
switch (*species)
|
||||
{
|
||||
case SPECIES_UNOWN:
|
||||
*form = GET_UNOWN_LETTER(mon->box.personality);
|
||||
*species = GetUnownSpecies(mon);
|
||||
break;
|
||||
case SPECIES_CASTFORM: // form is based on overworld weather
|
||||
*species = GetOverworldCastformSpecies();
|
||||
@ -2198,9 +2150,9 @@ static bool8 GetMonInfo(struct Pokemon *mon, u16 *species, u8 *form, u8 *shiny)
|
||||
}
|
||||
|
||||
// Retrieve graphic information about the following pokemon, if any
|
||||
static bool8 GetFollowerInfo(u16 *species, u8 *form, u8 *shiny)
|
||||
static bool8 GetFollowerInfo(u32 *species, bool32 *shiny, bool32 *female)
|
||||
{
|
||||
return GetMonInfo(GetFirstLiveMon(), species, form, shiny);
|
||||
return GetMonInfo(GetFirstLiveMon(), species, shiny, female);
|
||||
}
|
||||
|
||||
// Update following pokemon if any
|
||||
@ -2208,18 +2160,18 @@ void UpdateFollowingPokemon(void)
|
||||
{
|
||||
struct ObjectEvent *objEvent = GetFollowerObject();
|
||||
struct Sprite *sprite;
|
||||
u16 species;
|
||||
bool8 shiny;
|
||||
u8 form;
|
||||
u32 species;
|
||||
bool32 shiny;
|
||||
bool32 female;
|
||||
// Don't spawn follower if:
|
||||
// 1. GetFollowerInfo returns FALSE
|
||||
// 2. Map is indoors and gfx is larger than 32x32
|
||||
// 3. flag is set
|
||||
if (OW_POKEMON_OBJECT_EVENTS == FALSE
|
||||
|| OW_FOLLOWERS_ENABLED == FALSE
|
||||
|| !GetFollowerInfo(&species, &form, &shiny)
|
||||
|| SpeciesToGraphicsInfo(species, form) == NULL
|
||||
|| (gMapHeader.mapType == MAP_TYPE_INDOOR && SpeciesToGraphicsInfo(species, form)->oam->size > ST_OAM_SIZE_2)
|
||||
|| !GetFollowerInfo(&species, &shiny, &female)
|
||||
|| SpeciesToGraphicsInfo(species, shiny, female) == NULL
|
||||
|| (gMapHeader.mapType == MAP_TYPE_INDOOR && SpeciesToGraphicsInfo(species, shiny, female)->oam->size > ST_OAM_SIZE_2)
|
||||
|| FlagGet(FLAG_TEMP_HIDE_FOLLOWER))
|
||||
{
|
||||
RemoveFollowingPokemon();
|
||||
@ -2233,7 +2185,7 @@ void UpdateFollowingPokemon(void)
|
||||
struct ObjectEventTemplate template =
|
||||
{
|
||||
.localId = OBJ_EVENT_ID_FOLLOWER,
|
||||
.graphicsId = OBJ_EVENT_GFX_MON_BASE + species,
|
||||
.graphicsId = GetGraphicsIdForMon(species, shiny, female),
|
||||
.flagId = 0,
|
||||
.x = gSaveBlock1Ptr->pos.x,
|
||||
.y = gSaveBlock1Ptr->pos.y,
|
||||
@ -2241,7 +2193,7 @@ void UpdateFollowingPokemon(void)
|
||||
.elevation = gObjectEvents[objId].active ? gObjectEvents[objId].currentElevation : 3,
|
||||
.movementType = MOVEMENT_TYPE_FOLLOW_PLAYER,
|
||||
// store form info in template
|
||||
.trainerRange_berryTreeId = (form & 0x1F) | (shiny << 5),
|
||||
//.trainerRange_berryTreeId = (form & 0x1F) | (shiny << 5), // ???? what?
|
||||
};
|
||||
if ((objId = SpawnSpecialObjectEvent(&template)) >= OBJECT_EVENTS_COUNT)
|
||||
return;
|
||||
@ -2250,12 +2202,12 @@ void UpdateFollowingPokemon(void)
|
||||
}
|
||||
sprite = &gSprites[objEvent->spriteId];
|
||||
// Follower appearance changed; move to player and set invisible
|
||||
if (species != OW_SPECIES(objEvent) || shiny != objEvent->shiny || form != OW_FORM(objEvent))
|
||||
if (species != OW_SPECIES(objEvent) || shiny != OW_SHINY(objEvent) || female != OW_FEMALE(objEvent))
|
||||
{
|
||||
MoveObjectEventToMapCoords(objEvent,
|
||||
gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.x,
|
||||
gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.y);
|
||||
FollowerSetGraphics(objEvent, species, form, shiny);
|
||||
FollowerSetGraphics(objEvent, species, shiny, female);
|
||||
objEvent->invisible = TRUE;
|
||||
}
|
||||
sprite->data[6] = 0; // set animation data
|
||||
@ -2696,7 +2648,7 @@ static void SpawnObjectEventOnReturnToField(u8 objectEventId, s16 x, s16 y)
|
||||
|
||||
if (spriteTemplate.paletteTag == OBJ_EVENT_PAL_TAG_DYNAMIC)
|
||||
{
|
||||
u32 paletteNum = LoadDynamicFollowerPalette(OW_SPECIES(objectEvent), OW_FORM(objectEvent), objectEvent->shiny);
|
||||
u32 paletteNum = LoadDynamicFollowerPalette(OW_SPECIES(objectEvent), OW_SHINY(objectEvent), OW_FEMALE(objectEvent));
|
||||
spriteTemplate.paletteTag = GetSpritePaletteTagByPaletteNum(paletteNum);
|
||||
}
|
||||
else if (spriteTemplate.paletteTag != TAG_NONE)
|
||||
@ -2891,24 +2843,14 @@ static void SetBerryTreeGraphics(struct ObjectEvent *objectEvent, struct Sprite
|
||||
|
||||
const struct ObjectEventGraphicsInfo *GetObjectEventGraphicsInfo(u16 graphicsId)
|
||||
{
|
||||
u32 form = 0;
|
||||
|
||||
if (graphicsId >= OBJ_EVENT_GFX_VARS && graphicsId <= OBJ_EVENT_GFX_VAR_F)
|
||||
graphicsId = VarGetObjectEventGraphicsId(graphicsId - OBJ_EVENT_GFX_VARS);
|
||||
|
||||
if (graphicsId > OBJ_EVENT_GFX_SPECIES_MASK)
|
||||
{
|
||||
form = graphicsId >> OBJ_EVENT_GFX_SPECIES_BITS;
|
||||
graphicsId = graphicsId & OBJ_EVENT_GFX_SPECIES_MASK;
|
||||
}
|
||||
|
||||
if (graphicsId == OBJ_EVENT_GFX_BARD)
|
||||
{
|
||||
return gMauvilleOldManGraphicsInfoPointers[GetCurrentMauvilleOldMan()];
|
||||
}
|
||||
|
||||
if (graphicsId >= OBJ_EVENT_GFX_MON_BASE)
|
||||
return SpeciesToGraphicsInfo(graphicsId - OBJ_EVENT_GFX_MON_BASE, form);
|
||||
if (graphicsId & OBJ_EVENT_MON)
|
||||
return SpeciesToGraphicsInfo(graphicsId & OBJ_EVENT_MON_SPECIES_MASK, graphicsId & OBJ_EVENT_MON_SHINY, graphicsId & OBJ_EVENT_MON_FEMALE);
|
||||
|
||||
if (graphicsId >= NUM_OBJ_EVENT_GFX)
|
||||
graphicsId = OBJ_EVENT_GFX_NINJA_BOY;
|
||||
@ -5385,7 +5327,7 @@ static bool8 UpdateFollowerTransformEffect(struct ObjectEvent *objectEvent, stru
|
||||
objectEvent->graphicsId = multi;
|
||||
break;
|
||||
}
|
||||
objectEvent->graphicsId += OBJ_EVENT_GFX_MON_BASE;
|
||||
objectEvent->graphicsId += OBJ_EVENT_MON;
|
||||
RefreshFollowerGraphics(objectEvent);
|
||||
break;
|
||||
case TRANSFORM_TYPE_RANDOM_WILD:
|
||||
@ -5396,7 +5338,7 @@ static bool8 UpdateFollowerTransformEffect(struct ObjectEvent *objectEvent, stru
|
||||
objectEvent->graphicsId = multi;
|
||||
break;
|
||||
}
|
||||
objectEvent->graphicsId += OBJ_EVENT_GFX_MON_BASE;
|
||||
objectEvent->graphicsId += OBJ_EVENT_MON;
|
||||
RefreshFollowerGraphics(objectEvent);
|
||||
objectEvent->graphicsId = multi;
|
||||
break;
|
||||
@ -7457,7 +7399,7 @@ bool8 MovementAction_ExitPokeball_Step1(struct ObjectEvent *objectEvent, struct
|
||||
// Set graphics, palette, and affine animation
|
||||
else if (sprite->sDuration == animStepFrame)
|
||||
{
|
||||
FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), OW_FORM(objectEvent), objectEvent->shiny);
|
||||
FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), OW_SHINY(objectEvent), OW_FEMALE(objectEvent));
|
||||
LoadFillColorPalette(RGB_WHITE, OBJ_EVENT_PAL_TAG_WHITE, sprite);
|
||||
// Initialize affine animation
|
||||
sprite->affineAnims = sAffineAnims_PokeballFollower;
|
||||
@ -7474,7 +7416,7 @@ bool8 MovementAction_ExitPokeball_Step1(struct ObjectEvent *objectEvent, struct
|
||||
sprite->affineAnimEnded = TRUE;
|
||||
FreeSpriteOamMatrix(sprite);
|
||||
sprite->oam.affineMode = ST_OAM_AFFINE_OFF;
|
||||
FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), OW_FORM(objectEvent), objectEvent->shiny);
|
||||
FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), OW_SHINY(objectEvent), OW_FEMALE(objectEvent));
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@ -7530,7 +7472,7 @@ bool8 MovementAction_EnterPokeball_Step1(struct ObjectEvent *objectEvent, struct
|
||||
|
||||
bool8 MovementAction_EnterPokeball_Step2(struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
||||
{
|
||||
FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), OW_FORM(objectEvent), objectEvent->shiny);
|
||||
FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), OW_SHINY(objectEvent), OW_FEMALE(objectEvent));
|
||||
objectEvent->invisible = TRUE;
|
||||
sprite->sTypeFuncId = 0;
|
||||
sprite->sSpeedFlip = 0;
|
||||
@ -10992,20 +10934,23 @@ void GetDaycareGraphics(struct ScriptContext *ctx)
|
||||
{
|
||||
u16 varGfx[] = {ScriptReadHalfword(ctx), ScriptReadHalfword(ctx)};
|
||||
u16 varForm[] = {ScriptReadHalfword(ctx), ScriptReadHalfword(ctx)};
|
||||
u16 specGfx;
|
||||
u8 form;
|
||||
u8 shiny;
|
||||
u32 specGfx;
|
||||
bool32 shiny;
|
||||
bool32 female;
|
||||
s32 i;
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
GetMonInfo((struct Pokemon *) &gSaveBlock1Ptr->daycare.mons[i].mon, &specGfx, &form, &shiny);
|
||||
GetMonInfo((struct Pokemon *) &gSaveBlock1Ptr->daycare.mons[i].mon, &specGfx, &shiny, &female);
|
||||
if (specGfx == SPECIES_NONE)
|
||||
break;
|
||||
// Assemble gfx ID like FollowerSetGraphics
|
||||
specGfx = (OBJ_EVENT_GFX_MON_BASE + specGfx) & OBJ_EVENT_GFX_SPECIES_MASK;
|
||||
specGfx |= form << OBJ_EVENT_GFX_SPECIES_BITS;
|
||||
VarSet(varGfx[i], specGfx);
|
||||
VarSet(varForm[i], form | (shiny << 5));
|
||||
specGfx = specGfx + OBJ_EVENT_MON;
|
||||
if (shiny)
|
||||
specGfx += OBJ_EVENT_MON_SHINY;
|
||||
if (female)
|
||||
specGfx += OBJ_EVENT_MON_FEMALE;
|
||||
VarSet(varGfx[i], (u16)specGfx);
|
||||
VarSet(varForm[i], 0); // This shouldn't be needed anymore, track down
|
||||
}
|
||||
gSpecialVar_Result = i;
|
||||
}
|
||||
@ -11056,3 +11001,21 @@ bool8 MovementActionFunc_RunSlow_Step1(struct ObjectEvent *objectEvent, struct S
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static u16 GetGraphicsIdForMon(u32 species, bool32 shiny, bool32 female)
|
||||
{
|
||||
u16 graphicsId = species + OBJ_EVENT_MON;
|
||||
if (shiny)
|
||||
graphicsId += OBJ_EVENT_MON_SHINY;
|
||||
if (female)
|
||||
graphicsId += OBJ_EVENT_MON_FEMALE;
|
||||
return graphicsId;
|
||||
}
|
||||
|
||||
static u16 GetUnownSpecies(struct Pokemon *mon)
|
||||
{
|
||||
u32 form = GET_UNOWN_LETTER(mon->box.personality);
|
||||
if (form == 0)
|
||||
return SPECIES_UNOWN;
|
||||
return SPECIES_UNOWN_B + form - 1;
|
||||
}
|
||||
|
||||
@ -235,7 +235,7 @@ void LoadObjectEvents(void)
|
||||
// Try to restore saved inactive follower
|
||||
if (gObjectEvents[i].localId == OBJ_EVENT_ID_FOLLOWER &&
|
||||
!gObjectEvents[i].active &&
|
||||
gObjectEvents[i].graphicsId >= OBJ_EVENT_GFX_MON_BASE)
|
||||
gObjectEvents[i].graphicsId & OBJ_EVENT_MON)
|
||||
gObjectEvents[i].active = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1310,7 +1310,7 @@ void CB2_Pokemon_Sprite_Visualizer(void)
|
||||
gSprites[data->iconspriteId].oam.priority = 0;
|
||||
|
||||
//Follower Sprite
|
||||
data->followerspriteId = CreateObjectGraphicsSprite(OBJ_EVENT_GFX_MON_BASE + species, SpriteCB_Follower, VISUALIZER_FOLLOWER_X, VISUALIZER_FOLLOWER_Y, 0);
|
||||
data->followerspriteId = CreateObjectGraphicsSprite(OBJ_EVENT_MON + species, SpriteCB_Follower, VISUALIZER_FOLLOWER_X, VISUALIZER_FOLLOWER_Y, 0);
|
||||
gSprites[data->followerspriteId].oam.priority = 0;
|
||||
gSprites[data->followerspriteId].anims = sAnims_Follower;
|
||||
|
||||
@ -2001,18 +2001,16 @@ static void ReloadPokemonSprites(struct PokemonSpriteVisualizer *data)
|
||||
gSprites[data->iconspriteId].oam.priority = 0;
|
||||
|
||||
//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;
|
||||
data->followerspriteId = CreateObjectGraphicsFollowerSpriteForVisualizer(graphicsId,
|
||||
u16 graphicsId = species + OBJ_EVENT_MON;
|
||||
if (data->isShiny)
|
||||
graphicsId += OBJ_EVENT_MON_SHINY;
|
||||
if (data->isFemale)
|
||||
graphicsId += OBJ_EVENT_MON_FEMALE;
|
||||
data->followerspriteId = CreateObjectGraphicsSprite(graphicsId,
|
||||
SpriteCB_Follower,
|
||||
VISUALIZER_FOLLOWER_X,
|
||||
VISUALIZER_FOLLOWER_Y,
|
||||
0,
|
||||
&followerData);
|
||||
0);
|
||||
gSprites[data->followerspriteId].oam.priority = 0;
|
||||
gSprites[data->followerspriteId].anims = sAnims_Follower;
|
||||
|
||||
|
||||
@ -1701,7 +1701,7 @@ bool8 ScrCmd_vmessage(struct ScriptContext *ctx)
|
||||
bool8 ScrCmd_bufferspeciesname(struct ScriptContext *ctx)
|
||||
{
|
||||
u8 stringVarIndex = ScriptReadByte(ctx);
|
||||
u16 species = VarGet(ScriptReadHalfword(ctx)) & OBJ_EVENT_GFX_SPECIES_MASK; // ignore possible shiny / form bits
|
||||
u16 species = VarGet(ScriptReadHalfword(ctx)) & OBJ_EVENT_MON_SPECIES_MASK; // ignore possible shiny / form bits
|
||||
|
||||
StringCopy(sScriptStringVars[stringVarIndex], GetSpeciesName(species));
|
||||
return FALSE;
|
||||
|
||||
@ -871,7 +871,7 @@ static void BuyMenuCollectObjectEventData(void)
|
||||
u8 objEventId = GetObjectEventIdByXY(facingX - 4 + x, facingY - 2 + y);
|
||||
|
||||
// skip if invalid or an overworld pokemon that is not following the player
|
||||
if (objEventId != OBJECT_EVENTS_COUNT && !(gObjectEvents[objEventId].active && gObjectEvents[objEventId].graphicsId >= OBJ_EVENT_GFX_MON_BASE && gObjectEvents[objEventId].localId != OBJ_EVENT_ID_FOLLOWER))
|
||||
if (objEventId != OBJECT_EVENTS_COUNT && !(gObjectEvents[objEventId].active && gObjectEvents[objEventId].graphicsId & OBJ_EVENT_MON && gObjectEvents[objEventId].localId != OBJ_EVENT_ID_FOLLOWER))
|
||||
{
|
||||
sShopData->viewportObjects[numObjects][OBJ_EVENT_ID] = objEventId;
|
||||
sShopData->viewportObjects[numObjects][X_COORD] = x;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user