Merge branch 'followers-expanded-id' into lighting-expanded-id

This commit is contained in:
Ariel A 2023-01-12 21:58:39 -05:00
commit 244f3ceb15
25 changed files with 185 additions and 168 deletions

View File

@ -21,10 +21,9 @@
@ Defines an object event template for map data. Mirrors the struct layout of ObjectEventTemplate in include/global.fieldmap.h
.macro object_event index:req, gfx:req, inConnection:req, x:req, y:req, elevation:req, movement_type:req, x_radius:req, y_radius:req, trainer_type:req, sight_radius_tree_etc:req, script:req, event_flag:req
.byte \index
.byte \gfx
.byte \index
.2byte \gfx
.byte \inConnection
.space 1 @ Padding
.2byte \x, \y
.byte \elevation
.byte \movement_type

View File

@ -12,10 +12,10 @@
#include "constants/trainer_hill.h"
#include "constants/trainer_types.h"
#include "constants/berry.h"
#include "constants/species.h"
.include "asm/macros.inc"
.include "constants/constants.inc"
.section .rodata
.include "data/maps/events.inc"

View File

@ -15,7 +15,7 @@
"connections": 0,
"object_events": [
{
"graphics_id": "OBJ_EVENT_GFX_OW_MON",
"graphics_id": "OBJ_EVENT_GFX_MON_BASE+SPECIES_REGISTEEL",
"x": 8,
"y": 7,
"elevation": 3,

View File

@ -15,7 +15,7 @@
"connections": null,
"object_events": [
{
"graphics_id": "OBJ_EVENT_GFX_OW_MON",
"graphics_id": "OBJ_EVENT_GFX_MON_BASE+SPECIES_REGIROCK",
"x": 8,
"y": 7,
"elevation": 3,

View File

@ -15,7 +15,7 @@
"connections": 0,
"object_events": [
{
"graphics_id": "OBJ_EVENT_GFX_OW_MON",
"graphics_id": "OBJ_EVENT_GFX_MON_BASE+SPECIES_REGICE",
"x": 8,
"y": 7,
"elevation": 3,

View File

@ -54,7 +54,7 @@ void CallBattleTowerFunc(void);
u16 GetRandomScaledFrontierTrainerId(u8 challengeNum, u8 battleNum);
void SetBattleFacilityTrainerGfxId(u16 trainerId, u8 tempVarId);
void SetEReaderTrainerGfxId(void);
u8 GetBattleFacilityTrainerGfxId(u16 trainerId);
u16 GetBattleFacilityTrainerGfxId(u16 trainerId);
void PutNewBattleTowerRecord(struct EmeraldBattleTowerRecord *newRecordEm);
u8 GetFrontierTrainerFrontSpriteId(u16 trainerId);
u8 GetFrontierOpponentClass(u16 trainerId);
@ -81,7 +81,7 @@ void GetBattleTowerTrainerLanguage(u8 *dst, u16 trainerId);
u8 SetFacilityPtrsGetLevel(void);
u8 GetFrontierEnemyMonLevel(u8 lvlMode);
s32 GetHighestLevelInPlayerParty(void);
u8 FacilityClassToGraphicsId(u8 facilityClass);
u16 FacilityClassToGraphicsId(u8 facilityClass);
bool32 ValidateBattleTowerRecord(u8 recordId); // unused
void TrySetLinkBattleTowerEnemyPartyLevel(void);

View File

@ -277,6 +277,13 @@
#define OBJ_EVENT_GFX_VAR_E (OBJ_EVENT_GFX_VARS + 0xE)
#define OBJ_EVENT_GFX_VAR_F (OBJ_EVENT_GFX_VARS + 0xF) // 255
#define OBJ_EVENT_GFX_MON_BASE 0x200 // 512
#define OBJ_EVENT_GFX_SPECIES_BITS 11
#define OBJ_EVENT_GFX_SPECIES_MASK ((1 << OBJ_EVENT_GFX_SPECIES_BITS) - 1)
#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 SHADOW_SIZE_S 0
#define SHADOW_SIZE_M 1
#define SHADOW_SIZE_L 2

View File

@ -21,7 +21,7 @@ bool32 CanResetRTC(void);
u16 *GetVarPointer(u16 id);
u16 VarGet(u16 id);
bool8 VarSet(u16 id, u16 value);
u8 VarGetObjectEventGraphicsId(u8 id);
u16 VarGetObjectEventGraphicsId(u8 id);
u8 *GetFlagPointer(u16 id);
u8 FlagSet(u16 id);
u8 FlagClear(u16 id);

View File

@ -133,16 +133,16 @@ void UpdateLightSprite(struct Sprite *);
void TrySpawnObjectEvents(s16 cameraX, s16 cameraY);
u8 CreateObjectGraphicsSprite(u16, void (*)(struct Sprite *), s16 x, s16 y, u8 subpriority);
u8 TrySpawnObjectEvent(u8 localId, u8 mapNum, u8 mapGroup);
u8 SpawnSpecialObjectEventParameterized(u8 graphicsId, u8 movementBehavior, u8 localId, s16 x, s16 y, u8 elevation);
u8 SpawnSpecialObjectEventParameterized(u16 graphicsId, u8 movementBehavior, u8 localId, s16 x, s16 y, u8 elevation);
u8 SpawnSpecialObjectEvent(struct ObjectEventTemplate *);
void SetSpritePosToMapCoords(s16 mapX, s16 mapY, s16 *destX, s16 *destY);
void CameraObjectReset1(void);
u8 LoadObjectEventPalette(u16);
u8 UpdateSpritePaletteByTemplate(const struct SpriteTemplate *, struct Sprite *);
void ObjectEventSetGraphicsId(struct ObjectEvent *, u8 graphicsId);
void ObjectEventSetGraphicsId(struct ObjectEvent *, u16 graphicsId);
void ObjectEventTurn(struct ObjectEvent *, u8 direction);
void ObjectEventTurnByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup, u8 direction);
const struct ObjectEventGraphicsInfo *GetObjectEventGraphicsInfo(u8 graphicsId);
const struct ObjectEventGraphicsInfo *GetObjectEventGraphicsInfo(u16 graphicsId);
void SetObjectInvisibility(u8 localId, u8 mapNum, u8 mapGroup, bool8 invisible);
void FreeAndReserveObjectSpritePalettes(void);
u8 LoadObjectEventPalette(u16 paletteTag);
@ -464,9 +464,9 @@ u8 MovementType_Invisible_Step0(struct ObjectEvent *, struct Sprite *);
u8 MovementType_Invisible_Step1(struct ObjectEvent *, struct Sprite *);
u8 MovementType_Invisible_Step2(struct ObjectEvent *, struct Sprite *);
u8 CreateVirtualObject(u8 graphicsId, u8 virtualObjId, s16 x, s16 y, u8 elevation, u8 direction);
u8 CreateVirtualObject(u16 graphicsId, u8 virtualObjId, s16 x, s16 y, u8 elevation, u8 direction);
void TurnVirtualObject(u8 virtualObjId, u8 direction);
void SetVirtualObjectGraphics(u8 virtualObjId, u8 graphicsId);
void SetVirtualObjectGraphics(u8 virtualObjId, u16 graphicsId);
void SetVirtualObjectInvisibility(u8 virtualObjId, bool32 invisible);
bool32 IsVirtualObjectInvisible(u8 virtualObjId);
void SetVirtualObjectSpriteAnim(u8 virtualObjId, u8 animNum);

View File

@ -3,8 +3,8 @@
void PlayerStep(u8 direction, u16 newKeys, u16 heldKeys);
void ClearPlayerAvatarInfo(void);
void SetPlayerAvatarExtraStateTransition(u8, u8);
u8 GetPlayerAvatarGenderByGraphicsId(u8);
void SetPlayerAvatarExtraStateTransition(u16, u8);
u16 GetPlayerAvatarGenderByGraphicsId(u16);
bool8 TestPlayerAvatarFlags(u8);
u8 GetPlayerAvatarSpriteId(void);
void PlayerGetDestCoords(s16 *, s16 *);
@ -38,11 +38,11 @@ void PlayerFreeze(void);
void StopPlayerAvatar(void);
void SetSpinStartFacingDir(u8);
void GetXYCoordsOneStepInFrontOfPlayer(s16 *xPtr, s16 *yPtr);
u8 GetRivalAvatarGraphicsIdByStateIdAndGender(u8 state, u8 gender);
u16 GetRivalAvatarGraphicsIdByStateIdAndGender(u8 state, u8 gender);
void SetPlayerAvatarFieldMove(void);
u8 GetPlayerAvatarGraphicsIdByCurrentState(void);
u16 GetPlayerAvatarGraphicsIdByCurrentState(void);
void SetPlayerAvatarStateMask(u8 flags);
u8 GetPlayerAvatarGraphicsIdByStateId(u8 state);
u16 GetPlayerAvatarGraphicsIdByStateId(u8 state);
u8 GetJumpSpecialMovementAction(u32);
bool8 PartyHasMonWithSurf(void);
bool8 IsPlayerFacingSurfableFishableWater(void);
@ -50,8 +50,8 @@ bool8 IsPlayerSurfingNorth(void);
void SetPlayerAvatarWatering(u8 direction);
u8 GetPlayerAvatarFlags(void);
void UpdatePlayerAvatarTransitionState(void);
u8 GetFRLGAvatarGraphicsIdByGender(u8);
u8 GetRSAvatarGraphicsIdByGender(u8);
u16 GetFRLGAvatarGraphicsIdByGender(u8);
u16 GetRSAvatarGraphicsIdByGender(u8);
void PlayerWheelieInPlace(u8 direction);
void PlayerWheelieMove(u8 direction);
void PlayerPopWheelieWhileMoving(u8 direction);

View File

@ -45,7 +45,7 @@ bool8 SetUpFieldMove_Dig(void);
bool8 FldEff_UseDig(void);
// rock smash
bool8 CheckObjectGraphicsInFrontOfPlayer(u8 graphicsId);
bool8 CheckObjectGraphicsInFrontOfPlayer(u16 graphicsId);
u8 CreateFieldMoveTask(void);
bool8 SetUpFieldMove_RockSmash(void);
bool8 FldEff_UseRockSmash(void);

View File

@ -66,22 +66,24 @@ struct BackupMapLayout
u16 *map;
};
struct ObjectEventTemplate
struct __attribute__((packed)) ObjectEventTemplate
{
/*0x00*/ u8 localId;
/*0x01*/ u8 graphicsId;
/*0x02*/ u8 inConnection; // Leftover from FRLG
/*0x01*/ u16 graphicsId;
/*0x03*/ u8 inConnection; // Leftover from FRLG
/*0x04*/ s16 x;
/*0x06*/ s16 y;
/*0x08*/ u8 elevation;
/*0x09*/ u8 movementType;
/*0x0A*/ u16 movementRangeX:4;
u16 movementRangeY:4;
u16 unused:8;
/*0x0C*/ u16 trainerType;
/*0x0E*/ u16 trainerRange_berryTreeId;
/*0x10*/ const u8 *script;
/*0x14*/ u16 flagId;
};
/*0x16*/ u16 filler;
}; // size = 0x18
struct WarpEvent
{
@ -195,8 +197,9 @@ struct ObjectEvent
u32 disableJumpLandingGroundEffect:1;
u32 fixedPriority:1;
u32 hideReflection:1;
/*0x04*/ u8 spriteId;
/*0x05*/ u8 graphicsId;
u32 shiny:1; // OW mon shininess
u32 expanded:1; // 0 for vanilla, 1 for expanded OWs
/*0x04*/ u16 graphicsId; // 11 bits for species; high 5 bits for form
/*0x06*/ u8 movementType;
/*0x07*/ u8 trainerType;
/*0x08*/ u8 localId;
@ -219,15 +222,8 @@ struct ObjectEvent
/*0x1F*/ u8 previousMetatileBehavior;
/*0x20*/ u8 previousMovementDirection;
/*0x21*/ u8 directionSequenceIndex;
/*0x22*/ union __attribute__((packed)) {
u8 playerCopyableMovement; // COPY_MOVE_*
struct __attribute__((packed)) {
u16 species:10; // 11 bits; 1024 species
u16 form:5; // Used for Deoxys, Unown, etc
u16 shiny:1;
} mon;
u16 asU16;
} extra;
/*0x22*/ u8 playerCopyableMovement; // COPY_MOVE_*
/*0x23*/ u8 spriteId;
/*size = 0x24*/
};

View File

@ -1256,11 +1256,11 @@ void SetEReaderTrainerGfxId(void)
SetBattleFacilityTrainerGfxId(TRAINER_EREADER, 0);
}
u8 GetBattleFacilityTrainerGfxId(u16 trainerId)
u16 GetBattleFacilityTrainerGfxId(u16 trainerId)
{
u32 i;
u8 facilityClass;
u8 trainerObjectGfxId;
u16 trainerObjectGfxId;
SetFacilityPtrsGetLevel();
if (trainerId == TRAINER_EREADER)
@ -3466,7 +3466,7 @@ static void FillTentTrainerParty_(u16 trainerId, u8 firstMonId, u8 monCount)
}
}
u8 FacilityClassToGraphicsId(u8 facilityClass)
u16 FacilityClassToGraphicsId(u8 facilityClass)
{
u8 trainerObjectGfxId;
u8 i;

View File

@ -801,12 +801,12 @@ static void CreateCableCarSprites(void)
u8 spriteId;
u8 i;
u8 playerGraphicsIds[2] = {
u16 playerGraphicsIds[2] = {
[MALE] = OBJ_EVENT_GFX_RIVAL_BRENDAN_NORMAL,
[FEMALE] = OBJ_EVENT_GFX_RIVAL_MAY_NORMAL
};
u16 rval = Random();
u8 hikerGraphicsIds[4] = {
u16 hikerGraphicsIds[4] = {
OBJ_EVENT_GFX_HIKER,
OBJ_EVENT_GFX_CAMPER,
OBJ_EVENT_GFX_PICNICKER,
@ -1069,4 +1069,3 @@ static void InitGroundTilemapData(bool8 goingDown)
sCableCar->groundTimer = 0;
}

View File

@ -193,7 +193,7 @@ bool8 VarSet(u16 id, u16 value)
return TRUE;
}
u8 VarGetObjectEventGraphicsId(u8 id)
u16 VarGetObjectEventGraphicsId(u8 id)
{
return VarGet(VAR_OBJ_GFX_ID_0 + id);
}

View File

@ -192,6 +192,8 @@ 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[];
@ -1306,7 +1308,7 @@ static u8 GetObjectEventIdByLocalId(u8 localId)
return OBJECT_EVENTS_COUNT;
}
static u8 InitObjectEventStateFromTemplate(struct ObjectEventTemplate *template, u8 mapNum, u8 mapGroup)
static u8 InitObjectEventStateFromTemplate(const struct ObjectEventTemplate *template, u8 mapNum, u8 mapGroup)
{
struct ObjectEvent *objectEvent;
u8 objectEventId;
@ -1321,7 +1323,14 @@ static u8 InitObjectEventStateFromTemplate(struct ObjectEventTemplate *template,
y = template->y + MAP_OFFSET;
objectEvent->active = TRUE;
objectEvent->triggerGroundEffectsOnMove = TRUE;
objectEvent->graphicsId = template->graphicsId;
objectEvent->expanded = TRUE;
objectEvent->graphicsId = PackGraphicsId(template);
if (objectEvent->graphicsId >= OBJ_EVENT_GFX_MON_BASE) {
if (template->script && template->script[0] == 0x7d)
objectEvent->shiny = T1_READ_16(&template->script[2]) >> 15;
else if (template->trainerRange_berryTreeId)
objectEvent->shiny = template->trainerRange_berryTreeId >> 5;
}
objectEvent->movementType = template->movementType;
objectEvent->localId = template->localId;
objectEvent->mapNum = mapNum;
@ -1405,8 +1414,9 @@ static bool8 GetAvailableObjectEventId(u16 localId, u8 mapNum, u8 mapGroup, u8 *
static void RemoveObjectEvent(struct ObjectEvent *objectEvent)
{
objectEvent->active = FALSE;
objectEvent->extra.asU16 = 0; // zero potential species info
RemoveObjectEventInternal(objectEvent);
// zero potential species info
objectEvent->graphicsId = objectEvent->shiny = 0;
}
void RemoveObjectEventByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup)
@ -1449,7 +1459,7 @@ void RemoveAllObjectEventsExceptPlayer(void)
}
}
static u8 TrySetupObjectEventSprite(struct ObjectEventTemplate *objectEventTemplate, struct SpriteTemplate *spriteTemplate, u8 mapNum, u8 mapGroup, s16 cameraX, s16 cameraY)
static u8 TrySetupObjectEventSprite(const struct ObjectEventTemplate *objectEventTemplate, struct SpriteTemplate *spriteTemplate, u8 mapNum, u8 mapGroup, s16 cameraX, s16 cameraY)
{
u8 spriteId;
u8 objectEventId;
@ -1463,7 +1473,7 @@ static u8 TrySetupObjectEventSprite(struct ObjectEventTemplate *objectEventTempl
objectEvent = &gObjectEvents[objectEventId];
graphicsInfo = GetObjectEventGraphicsInfo(objectEvent->graphicsId);
if (spriteTemplate->paletteTag != TAG_NONE) {
if (spriteTemplate->paletteTag != TAG_NONE && spriteTemplate->paletteTag != OBJ_EVENT_PAL_TAG_DYNAMIC) {
LoadObjectEventPalette(spriteTemplate->paletteTag);
}
@ -1478,6 +1488,10 @@ static u8 TrySetupObjectEventSprite(struct ObjectEventTemplate *objectEventTempl
}
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);
}
GetMapCoordsFromSpritePos(objectEvent->currentCoords.x + cameraX, objectEvent->currentCoords.y + cameraY, &sprite->x, &sprite->y);
sprite->centerToCornerVecX = -(graphicsInfo->width >> 1);
sprite->centerToCornerVecY = -(graphicsInfo->height >> 1);
@ -1495,17 +1509,39 @@ static u8 TrySetupObjectEventSprite(struct ObjectEventTemplate *objectEventTempl
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 (graphicsId >= OBJ_EVENT_GFX_MON_BASE) {
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(struct ObjectEventTemplate *objectEventTemplate,
TrySpawnObjectEventTemplate(const struct ObjectEventTemplate *objectEventTemplate,
u8 mapNum, u8 mapGroup, s16 cameraX, s16 cameraY) {
u8 objectEventId;
u16 graphicsId = PackGraphicsId(objectEventTemplate);
struct SpriteTemplate spriteTemplate;
struct SpriteFrameImage spriteFrameImage;
const struct ObjectEventGraphicsInfo *graphicsInfo;
const struct SubspriteTable *subspriteTables = NULL;
u16 species;
u8 form = 0;
bool8 shiny = FALSE;
graphicsInfo = GetObjectEventGraphicsInfo(objectEventTemplate->graphicsId);
MakeSpriteTemplateFromObjectEventTemplate(objectEventTemplate, &spriteTemplate, &subspriteTables);
graphicsInfo = GetObjectEventGraphicsInfo(graphicsId);
CopyObjectGraphicsInfoToSpriteTemplate_WithMovementType(graphicsId, objectEventTemplate->movementType, &spriteTemplate, &subspriteTables);
spriteFrameImage.size = graphicsInfo->size;
spriteTemplate.images = &spriteFrameImage;
objectEventId = TrySetupObjectEventSprite(objectEventTemplate, &spriteTemplate, mapNum, mapGroup, cameraX, cameraY);
@ -1516,28 +1552,6 @@ TrySpawnObjectEventTemplate(struct ObjectEventTemplate *objectEventTemplate,
if (subspriteTables)
SetSubspriteTables(&gSprites[gObjectEvents[objectEventId].spriteId], subspriteTables);
// Set species based on script header
if (objectEventTemplate->graphicsId == OBJ_EVENT_GFX_OW_MON && objectEventTemplate->script) {
const u8 *script = objectEventTemplate->script;
if (script[0] == 0x7d) { // bufferspeciesname
u16 species;
u8 form;
bool8 shiny;
gObjectEvents[objectEventId].extra.asU16 = script[2] | script[3] << 8;
species = gObjectEvents[objectEventId].extra.mon.species;
form = gObjectEvents[objectEventId].extra.mon.form;
shiny = gObjectEvents[objectEventId].extra.mon.shiny;
FollowerSetGraphics(&gObjectEvents[objectEventId], species, form, shiny, TRUE);
}
// Set runtime species based on VAR_TEMP_4, if template has a dynamic graphics ID
} else if (objectEventTemplate->graphicsId >= OBJ_EVENT_GFX_VARS && VarGetObjectEventGraphicsId(objectEventTemplate->graphicsId - OBJ_EVENT_GFX_VARS) == OBJ_EVENT_GFX_OW_MON) {
gObjectEvents[objectEventId].extra.asU16 = VarGet(VAR_TEMP_4);
FollowerSetGraphics(&gObjectEvents[objectEventId],
gObjectEvents[objectEventId].extra.mon.species,
gObjectEvents[objectEventId].extra.mon.form,
gObjectEvents[objectEventId].extra.mon.form, TRUE);
}
return objectEventId;
}
@ -1550,7 +1564,7 @@ u8 SpawnSpecialObjectEvent(struct ObjectEventTemplate *objectEventTemplate)
return TrySpawnObjectEventTemplate(objectEventTemplate, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, cameraX, cameraY);
}
u8 SpawnSpecialObjectEventParameterized(u8 graphicsId, u8 movementBehavior, u8 localId, s16 x, s16 y, u8 elevation)
u8 SpawnSpecialObjectEventParameterized(u16 graphicsId, u8 movementBehavior, u8 localId, s16 x, s16 y, u8 elevation)
{
struct ObjectEventTemplate objectEventTemplate;
@ -1558,7 +1572,7 @@ u8 SpawnSpecialObjectEventParameterized(u8 graphicsId, u8 movementBehavior, u8 l
y -= MAP_OFFSET;
objectEventTemplate.localId = localId;
objectEventTemplate.graphicsId = graphicsId;
objectEventTemplate.inConnection = 0;
// objectEventTemplate.inConnection = 0;
objectEventTemplate.x = x;
objectEventTemplate.y = y;
objectEventTemplate.elevation = elevation;
@ -1620,7 +1634,7 @@ u8 CreateObjectGraphicsSprite(u16 graphicsId, void (*callback)(struct Sprite *),
u8 paletteNum;
spriteTemplate = Alloc(sizeof(struct SpriteTemplate));
if (graphicsId == OBJ_EVENT_GFX_OW_MON && GetFollowerInfo(&species, &form, &shiny)) {
if (graphicsId >= OBJ_EVENT_GFX_MON_BASE && GetFollowerInfo(&species, &form, &shiny)) {
const struct ObjectEventGraphicsInfo *graphicsInfo = SpeciesToGraphicsInfo(species, form);
spriteTemplate->tileTag = graphicsInfo->tileTag;
spriteTemplate->paletteTag = graphicsInfo->paletteTag;
@ -1660,7 +1674,7 @@ u8 CreateObjectGraphicsSprite(u16 graphicsId, void (*callback)(struct Sprite *),
// A unique id is given as an argument and stored in the sprite data to allow referring back to the same virtual object.
// They can be turned (and, in the case of the Union Room, animated teleporting in and out) but do not have movement types
// or any of the other data normally associated with object events.
u8 CreateVirtualObject(u8 graphicsId, u8 virtualObjId, s16 x, s16 y, u8 elevation, u8 direction)
u8 CreateVirtualObject(u16 graphicsId, u8 virtualObjId, s16 x, s16 y, u8 elevation, u8 direction)
{
u8 spriteId;
struct Sprite *sprite;
@ -1733,7 +1747,7 @@ static const struct ObjectEventGraphicsInfo * SpeciesToGraphicsInfo(u16 species,
graphicsInfo = &gPokemonObjectGraphics[species];
break;
}
return graphicsInfo->tileTag == 0xFFFF ? graphicsInfo : &gPokemonObjectGraphics[SPECIES_PORYGON]; // avoid OOB access
return graphicsInfo->tileTag == TAG_NONE ? graphicsInfo : &gPokemonObjectGraphics[SPECIES_PORYGON]; // avoid OOB access
}
// Find, or load, the palette for the specified pokemon info
@ -1760,12 +1774,10 @@ static u8 LoadDynamicFollowerPalette(u16 species, u8 form, bool8 shiny) {
// Set graphics & sprite for a follower object event by species & shininess.
static void FollowerSetGraphics(struct ObjectEvent *objEvent, u16 species, u8 form, bool8 shiny, bool8 doPalette) {
const struct ObjectEventGraphicsInfo *graphicsInfo = SpeciesToGraphicsInfo(species, form);
objEvent->graphicsId = OBJ_EVENT_GFX_OW_MON;
ObjectEventSetGraphics(objEvent, graphicsInfo);
objEvent->graphicsId = OBJ_EVENT_GFX_OW_MON;
objEvent->extra.mon.species = species;
objEvent->extra.mon.form = form;
objEvent->extra.mon.shiny = shiny;
objEvent->graphicsId = (OBJ_EVENT_GFX_MON_BASE + species) & OBJ_EVENT_GFX_SPECIES_MASK;
objEvent->graphicsId |= form << OBJ_EVENT_GFX_SPECIES_BITS;
objEvent->shiny = shiny;
if (graphicsInfo->paletteTag == OBJ_EVENT_PAL_TAG_DYNAMIC && doPalette) { // Use palette from species palette table
struct Sprite *sprite = &gSprites[objEvent->spriteId];
// Free palette if otherwise unused
@ -1779,9 +1791,9 @@ static void FollowerSetGraphics(struct ObjectEvent *objEvent, u16 species, u8 fo
// Like FollowerSetGraphics, but does not reposition sprite; intended to be used for mid-movement form changes, etc.
// TODO: Reposition sprite if size changes
static void RefreshFollowerGraphics(struct ObjectEvent *objEvent) {
u16 species = objEvent->extra.mon.species;
u8 form = objEvent->extra.mon.form;
u8 shiny = objEvent->extra.mon.shiny;
u16 species = OW_SPECIES(objEvent);
u8 form = OW_FORM(objEvent);
u8 shiny = objEvent->shiny;
const struct ObjectEventGraphicsInfo *graphicsInfo = SpeciesToGraphicsInfo(species, form);
struct Sprite *sprite = &gSprites[objEvent->spriteId];
u8 i = FindObjectEventPaletteIndexByTag(graphicsInfo->paletteTag);
@ -1857,28 +1869,27 @@ void UpdateFollowingPokemon(void) { // Update following pokemon if any
if (objEvent == NULL) { // Spawn follower
struct ObjectEventTemplate template = {
.localId = OBJ_EVENT_ID_FOLLOWER,
.graphicsId = OBJ_EVENT_GFX_OW_MON,
.graphicsId = OBJ_EVENT_GFX_MON_BASE + species,
.flagId = 0,
.x = gSaveBlock1Ptr->pos.x,
.y = gSaveBlock1Ptr->pos.y,
// If player active, copy player elevation
.elevation = gObjectEvents[gPlayerAvatar.objectEventId].active ? gObjectEvents[gPlayerAvatar.objectEventId].currentElevation : 3,
.movementType = MOVEMENT_TYPE_FOLLOW_PLAYER,
// store form info in template
.trainerRange_berryTreeId = (form & 0x1F) | (shiny << 5),
};
objEvent = &gObjectEvents[SpawnSpecialObjectEvent(&template)];
objEvent->invisible = TRUE;
}
sprite = &gSprites[objEvent->spriteId];
// 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) {
if (species != OW_SPECIES(objEvent) || shiny != objEvent->shiny || form != OW_FORM(objEvent)) {
MoveObjectEventToMapCoords(objEvent, gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.x, gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.y);
FollowerSetGraphics(objEvent, species, form, shiny, TRUE);
objEvent->invisible = TRUE;
}
FollowerSetGraphics(objEvent, species, form, shiny, TRUE);
sprite->data[6] = 0; // set animation data
objEvent->extra.mon.species = species;
objEvent->extra.mon.shiny = shiny;
objEvent->extra.mon.form = form;
} else {
RemoveFollowingPokemon();
}
@ -2393,13 +2404,16 @@ static void SpawnObjectEventOnReturnToField(u8 objectEventId, s16 x, s16 y)
spriteFrameImage.size = graphicsInfo->size;
CopyObjectGraphicsInfoToSpriteTemplate_WithMovementType(objectEvent->graphicsId, objectEvent->movementType, &spriteTemplate, &subspriteTables);
spriteTemplate.images = &spriteFrameImage;
if (spriteTemplate.paletteTag != TAG_NONE) {
if (spriteTemplate.paletteTag != TAG_NONE && spriteTemplate.paletteTag != OBJ_EVENT_PAL_TAG_DYNAMIC) {
LoadObjectEventPalette(spriteTemplate.paletteTag);
}
i = CreateSprite(&spriteTemplate, 0, 0, 0);
if (i != MAX_SPRITES)
{
sprite = &gSprites[i];
// 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);
GetMapCoordsFromSpritePos(x + objectEvent->currentCoords.x, y + objectEvent->currentCoords.y, &sprite->x, &sprite->y);
sprite->centerToCornerVecX = -(graphicsInfo->width >> 1);
sprite->centerToCornerVecY = -(graphicsInfo->height >> 1);
@ -2417,9 +2431,6 @@ static void SpawnObjectEventOnReturnToField(u8 objectEventId, s16 x, s16 y)
sprite->coordOffsetEnabled = TRUE;
sprite->sObjEventId = objectEventId;
objectEvent->spriteId = i;
if (objectEvent->graphicsId == OBJ_EVENT_GFX_OW_MON) { // Set pokemon graphics
FollowerSetGraphics(objectEvent, objectEvent->extra.mon.species, objectEvent->extra.mon.form, objectEvent->extra.mon.shiny, TRUE);
}
if (!objectEvent->inanimate && objectEvent->movementType != MOVEMENT_TYPE_PLAYER)
StartSpriteAnim(sprite, GetFaceDirectionAnimNum(objectEvent->facingDirection));
@ -2497,14 +2508,14 @@ static void ObjectEventSetGraphics(struct ObjectEvent *objectEvent, const struct
}
}
void ObjectEventSetGraphicsId(struct ObjectEvent *objectEvent, u8 graphicsId)
void ObjectEventSetGraphicsId(struct ObjectEvent *objectEvent, u16 graphicsId)
{
objectEvent->graphicsId = graphicsId;
ObjectEventSetGraphics(objectEvent, GetObjectEventGraphicsInfo(graphicsId));
objectEvent->graphicsId = graphicsId;
}
void ObjectEventSetGraphicsIdByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup, u8 graphicsId)
void ObjectEventSetGraphicsIdByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup, u16 graphicsId)
{
u8 objectEventId;
@ -2536,7 +2547,7 @@ void PlayerObjectTurn(struct PlayerAvatar *playerAvatar, u8 direction)
}
static void SetBerryTreeGraphics(struct ObjectEvent *objectEvent, u8 berryId, u8 berryStage) {
const u8 graphicsId = gBerryTreeObjectEventGraphicsIdTablePointers[berryId][berryStage];
const u16 graphicsId = gBerryTreeObjectEventGraphicsIdTablePointers[berryId][berryStage];
const struct ObjectEventGraphicsInfo *graphicsInfo = GetObjectEventGraphicsInfo(graphicsId);
struct Sprite *sprite = &gSprites[objectEvent->spriteId];
UpdateSpritePalette(&sObjectEventSpritePalettes[gBerryTreePaletteSlotTablePointers[berryId][berryStage]-2], sprite);
@ -2580,19 +2591,26 @@ static void get_berry_tree_graphics(struct ObjectEvent *objectEvent, struct Spri
}
}
const struct ObjectEventGraphicsInfo *GetObjectEventGraphicsInfo(u8 graphicsId)
const struct ObjectEventGraphicsInfo *GetObjectEventGraphicsInfo(u16 graphicsId)
{
u8 bard;
u32 form = 0;
if (graphicsId >= OBJ_EVENT_GFX_VARS)
if (graphicsId >= OBJ_EVENT_GFX_VARS && graphicsId <= OBJ_EVENT_GFX_VAR_F)
graphicsId = VarGetObjectEventGraphicsId(graphicsId - OBJ_EVENT_GFX_VARS);
if (graphicsId == OBJ_EVENT_GFX_BARD)
{
bard = GetCurrentMauvilleOldMan();
return gMauvilleOldManGraphicsInfoPointers[bard];
// graphicsId may contain mon form info
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 >= NUM_OBJ_EVENT_GFX)
graphicsId = OBJ_EVENT_GFX_NINJA_BOY;
@ -2601,7 +2619,7 @@ const struct ObjectEventGraphicsInfo *GetObjectEventGraphicsInfo(u8 graphicsId)
static void SetObjectEventDynamicGraphicsId(struct ObjectEvent *objectEvent)
{
if (objectEvent->graphicsId >= OBJ_EVENT_GFX_VARS)
if (objectEvent->graphicsId >= OBJ_EVENT_GFX_VARS && objectEvent->graphicsId <= OBJ_EVENT_GFX_VAR_F)
objectEvent->graphicsId = VarGetObjectEventGraphicsId(objectEvent->graphicsId - OBJ_EVENT_GFX_VARS);
}
@ -5035,12 +5053,13 @@ static bool8 EndFollowerTransformEffect(struct ObjectEvent *objectEvent, struct
static bool8 TryStartFollowerTransformEffect(struct ObjectEvent *objectEvent, struct Sprite *sprite) {
u32 multi;
if (objectEvent->extra.mon.species == SPECIES_CASTFORM && objectEvent->extra.mon.form != (multi = GetOverworldCastformForm())) {
if (OW_SPECIES(objectEvent) == SPECIES_CASTFORM && OW_FORM(objectEvent) != (multi = GetOverworldCastformForm())) {
sprite->data[7] = TRANSFORM_TYPE_PERMANENT << 8;
objectEvent->extra.mon.form = multi;
objectEvent->graphicsId &= OBJ_EVENT_GFX_SPECIES_MASK;
objectEvent->graphicsId |= multi << OBJ_EVENT_GFX_SPECIES_BITS;
return TRUE;
} else if ((gRngValue >> 16) < 18 && GetLocalWildMon(FALSE)
&& (objectEvent->extra.mon.species == SPECIES_MEW || objectEvent->extra.mon.species == SPECIES_DITTO)) {
&& (OW_SPECIES(objectEvent) == SPECIES_MEW || OW_SPECIES(objectEvent) == SPECIES_DITTO)) {
sprite->data[7] = TRANSFORM_TYPE_RANDOM_WILD << 8;
PlaySE(SE_M_MINIMIZE);
return TRUE;
@ -5070,15 +5089,15 @@ static bool8 UpdateFollowerTransformEffect(struct ObjectEvent *objectEvent, stru
RefreshFollowerGraphics(objectEvent);
break;
case TRANSFORM_TYPE_RANDOM_WILD:
multi = objectEvent->extra.asU16;
objectEvent->extra.mon.species = GetLocalWildMon(FALSE);
if (!objectEvent->extra.mon.species) {
objectEvent->extra.asU16 = multi;
multi = objectEvent->graphicsId;
objectEvent->graphicsId = GetLocalWildMon(FALSE);
if (!objectEvent->graphicsId) {
objectEvent->graphicsId = multi;
break;
}
objectEvent->extra.mon.form = 0;
objectEvent->graphicsId += OBJ_EVENT_GFX_MON_BASE;
RefreshFollowerGraphics(objectEvent);
objectEvent->extra.asU16 = multi;
objectEvent->graphicsId = multi;
break;
}
}
@ -5671,7 +5690,7 @@ void SetTrainerMovementType(struct ObjectEvent *objectEvent, u8 movementType)
{
objectEvent->movementType = movementType;
objectEvent->directionSequenceIndex = 0;
objectEvent->extra.playerCopyableMovement = 0;
objectEvent->playerCopyableMovement = 0;
gSprites[objectEvent->spriteId].callback = sMovementTypeCallbacks[movementType];
gSprites[objectEvent->spriteId].sTypeFuncId = 0;
}
@ -6792,6 +6811,7 @@ static u8 LoadWhiteFlashPalette(struct ObjectEvent *objectEvent, struct Sprite *
bool8 MovementAction_ExitPokeball_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) {
u8 direction = gObjectEvents[gPlayerAvatar.objectEventId].facingDirection;
u16 graphicsId = objectEvent->graphicsId;
objectEvent->invisible = FALSE;
if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_DASH)) { // If player is dashing, the pokemon must come out faster
StartSpriteAnimInDirection(objectEvent, sprite, direction, GetMoveDirectionFastestAnimNum(direction) + 4);
@ -6804,6 +6824,7 @@ bool8 MovementAction_ExitPokeball_Step0(struct ObjectEvent *objectEvent, struct
}
sprite->data[6] |= (direction == DIR_EAST ? 1 : 0) << 4;
ObjectEventSetGraphicsId(objectEvent, OBJ_EVENT_GFX_ANIMATED_BALL);
objectEvent->graphicsId = graphicsId;
objectEvent->inanimate = FALSE;
return MovementAction_ExitPokeball_Step1(objectEvent, sprite);
}
@ -6864,7 +6885,7 @@ bool8 MovementAction_ExitPokeball_Step1(struct ObjectEvent *objectEvent, struct
return TRUE;
// Set graphics, palette, and affine animation
} else if ((duration == 0 && sprite->data[3] == 3) || (duration == 1 && sprite->data[3] == 7)) {
FollowerSetGraphics(objectEvent, objectEvent->extra.mon.species, objectEvent->extra.mon.form, objectEvent->extra.mon.shiny, FALSE);
FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), OW_FORM(objectEvent), objectEvent->shiny, FALSE);
LoadWhiteFlashPalette(objectEvent, sprite);
// Initialize affine animation
sprite->affineAnims = sAffineAnims_PokeballFollower;
@ -6876,7 +6897,7 @@ bool8 MovementAction_ExitPokeball_Step1(struct ObjectEvent *objectEvent, struct
sprite->affineAnimEnded = TRUE;
FreeSpriteOamMatrix(sprite);
sprite->oam.affineMode = ST_OAM_AFFINE_OFF;
FollowerSetGraphics(objectEvent, objectEvent->extra.mon.species, objectEvent->extra.mon.form, objectEvent->extra.mon.shiny, TRUE);
FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), OW_FORM(objectEvent), objectEvent->shiny, TRUE);
}
return FALSE;
}
@ -6892,6 +6913,7 @@ bool8 MovementAction_EnterPokeball_Step0(struct ObjectEvent *objectEvent, struct
bool8 MovementAction_EnterPokeball_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite)
{
u16 graphicsId = objectEvent->graphicsId;
sprite->data[3]--;
if (sprite->data[3] == 0) {
sprite->data[2] = 2;
@ -6907,6 +6929,7 @@ bool8 MovementAction_EnterPokeball_Step1(struct ObjectEvent *objectEvent, struct
FreeSpriteOamMatrix(sprite);
sprite->oam.affineMode = ST_OAM_AFFINE_OFF;
ObjectEventSetGraphicsId(objectEvent, OBJ_EVENT_GFX_ANIMATED_BALL);
objectEvent->graphicsId = graphicsId;
objectEvent->inanimate = FALSE;
}
return FALSE;
@ -6914,7 +6937,7 @@ bool8 MovementAction_EnterPokeball_Step1(struct ObjectEvent *objectEvent, struct
bool8 MovementAction_EnterPokeball_Step2(struct ObjectEvent *objectEvent, struct Sprite *sprite)
{
FollowerSetGraphics(objectEvent, objectEvent->extra.mon.species, objectEvent->extra.mon.form, objectEvent->extra.mon.shiny, FALSE);
FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), OW_FORM(objectEvent), objectEvent->shiny, FALSE);
objectEvent->invisible = TRUE;
sprite->data[1] = 0;
sprite->data[6] = 0;
@ -9065,13 +9088,13 @@ static void (*const sGroundEffectTracksFuncs[])(struct ObjectEvent *objEvent, st
void GroundEffect_SandTracks(struct ObjectEvent *objEvent, struct Sprite *sprite)
{
const struct ObjectEventGraphicsInfo *info = objEvent->graphicsId == OBJ_EVENT_GFX_OW_MON ? SpeciesToGraphicsInfo(objEvent->extra.mon.species, 0) : GetObjectEventGraphicsInfo(objEvent->graphicsId);
const struct ObjectEventGraphicsInfo *info = GetObjectEventGraphicsInfo(objEvent->graphicsId);
sGroundEffectTracksFuncs[objEvent->invisible ? TRACKS_NONE : info->tracks](objEvent, sprite, FALSE);
}
void GroundEffect_DeepSandTracks(struct ObjectEvent *objEvent, struct Sprite *sprite)
{
const struct ObjectEventGraphicsInfo *info = objEvent->graphicsId == OBJ_EVENT_GFX_OW_MON ? SpeciesToGraphicsInfo(objEvent->extra.mon.species, 0) : GetObjectEventGraphicsInfo(objEvent->graphicsId);
const struct ObjectEventGraphicsInfo *info = GetObjectEventGraphicsInfo(objEvent->graphicsId);
sGroundEffectTracksFuncs[objEvent->invisible ? TRACKS_NONE : info->tracks](objEvent, sprite, TRUE);
}
@ -9886,7 +9909,7 @@ void TurnVirtualObject(u8 virtualObjId, u8 direction)
StartSpriteAnim(&gSprites[spriteId], GetFaceDirectionAnimNum(direction));
}
void SetVirtualObjectGraphics(u8 virtualObjId, u8 graphicsId)
void SetVirtualObjectGraphics(u8 virtualObjId, u16 graphicsId)
{
int spriteId = GetVirtualObjectSpriteId(virtualObjId);

View File

@ -929,12 +929,12 @@ static bool8 PlayerCheckIfAnimFinishedOrInactive(void)
static void PlayerSetCopyableMovement(u8 movement)
{
gObjectEvents[gPlayerAvatar.objectEventId].extra.playerCopyableMovement = movement;
gObjectEvents[gPlayerAvatar.objectEventId].playerCopyableMovement = movement;
}
u8 PlayerGetCopyableMovement(void)
{
return gObjectEvents[gPlayerAvatar.objectEventId].extra.playerCopyableMovement;
return gObjectEvents[gPlayerAvatar.objectEventId].playerCopyableMovement;
}
static void PlayerForceSetHeldMovement(u8 movementActionId)
@ -1212,50 +1212,32 @@ void StopPlayerAvatar(void)
}
}
u8 GetRivalAvatarGraphicsIdByStateIdAndGender(u8 state, u8 gender)
u16 GetRivalAvatarGraphicsIdByStateIdAndGender(u8 state, u8 gender)
{
return sRivalAvatarGfxIds[state][gender];
}
u8 GetPlayerAvatarGraphicsIdByStateIdAndGender(u8 state, u8 gender)
u16 GetPlayerAvatarGraphicsIdByStateIdAndGender(u8 state, u8 gender)
{
return sPlayerAvatarGfxIds[state][gender];
}
u8 GetFRLGAvatarGraphicsIdByGender(u8 gender)
u16 GetFRLGAvatarGraphicsIdByGender(u8 gender)
{
return sFRLGAvatarGfxIds[gender];
}
u8 GetRSAvatarGraphicsIdByGender(u8 gender)
u16 GetRSAvatarGraphicsIdByGender(u8 gender)
{
return sRSAvatarGfxIds[gender];
}
u8 GetPlayerAvatarGraphicsIdByStateId(u8 state)
u16 GetPlayerAvatarGraphicsIdByStateId(u8 state)
{
return GetPlayerAvatarGraphicsIdByStateIdAndGender(state, gPlayerAvatar.gender);
}
u8 unref_GetRivalAvatarGenderByGraphicsId(u8 gfxId)
{
switch (gfxId)
{
case OBJ_EVENT_GFX_RIVAL_MAY_NORMAL:
case OBJ_EVENT_GFX_RIVAL_MAY_MACH_BIKE:
case OBJ_EVENT_GFX_RIVAL_MAY_ACRO_BIKE:
case OBJ_EVENT_GFX_RIVAL_MAY_SURFING:
case OBJ_EVENT_GFX_RIVAL_MAY_FIELD_MOVE:
case OBJ_EVENT_GFX_MAY_UNDERWATER:
case OBJ_EVENT_GFX_MAY_FISHING:
case OBJ_EVENT_GFX_MAY_WATERING:
return FEMALE;
default:
return MALE;
}
}
u8 GetPlayerAvatarGenderByGraphicsId(u8 gfxId)
u16 GetPlayerAvatarGenderByGraphicsId(u16 gfxId)
{
switch (gfxId)
{
@ -1324,7 +1306,7 @@ void SetPlayerAvatarStateMask(u8 flags)
gPlayerAvatar.flags |= flags;
}
static u8 GetPlayerAvatarStateTransitionByGraphicsId(u8 graphicsId, u8 gender)
static u8 GetPlayerAvatarStateTransitionByGraphicsId(u16 graphicsId, u8 gender)
{
u8 i;
@ -1336,7 +1318,7 @@ static u8 GetPlayerAvatarStateTransitionByGraphicsId(u8 graphicsId, u8 gender)
return PLAYER_AVATAR_FLAG_ON_FOOT;
}
u8 GetPlayerAvatarGraphicsIdByCurrentState(void)
u16 GetPlayerAvatarGraphicsIdByCurrentState(void)
{
u8 i;
u8 flags = gPlayerAvatar.flags;
@ -1349,7 +1331,7 @@ u8 GetPlayerAvatarGraphicsIdByCurrentState(void)
return 0;
}
void SetPlayerAvatarExtraStateTransition(u8 graphicsId, u8 transitionFlag)
void SetPlayerAvatarExtraStateTransition(u16 graphicsId, u8 transitionFlag)
{
u8 stateFlag = GetPlayerAvatarStateTransitionByGraphicsId(graphicsId, gPlayerAvatar.gender);

View File

@ -90,7 +90,7 @@ void SetPlayerGotFirstFans(void);
u16 GetNumFansOfPlayerInTrainerFanClub(void);
static void RecordCyclingRoadResults(u32, u8);
static void LoadLinkPartnerObjectEventSpritePalette(u8, u8, u8);
static void LoadLinkPartnerObjectEventSpritePalette(u16, u8, u8);
static void Task_PetalburgGymSlideOpenRoomDoors(u8);
static void PetalburgGymSetDoorMetatiles(u8, u16);
static void Task_PCTurnOnEffect(u8);
@ -563,7 +563,7 @@ void SpawnLinkPartnerObjectEvent(void)
}
}
static void LoadLinkPartnerObjectEventSpritePalette(u8 graphicsId, u8 localEventId, u8 paletteNum)
static void LoadLinkPartnerObjectEventSpritePalette(u16 graphicsId, u8 localEventId, u8 paletteNum)
{
u8 adjustedPaletteNum;
// Note: This temp var is necessary; paletteNum += 6 doesn't match.

View File

@ -27,7 +27,7 @@ static void Task_DoFieldMove_RunFunc(u8 taskId);
static void FieldCallback_RockSmash(void);
static void FieldMove_RockSmash(void);
bool8 CheckObjectGraphicsInFrontOfPlayer(u8 graphicsId)
bool8 CheckObjectGraphicsInFrontOfPlayer(u16 graphicsId)
{
u8 objEventId;

View File

@ -181,9 +181,15 @@ void LoadPlayerParty(void)
void SaveObjectEvents(void)
{
int i;
u16 graphicsId;
for (i = 0; i < OBJECT_EVENTS_COUNT; i++) {
gSaveBlock1Ptr->objectEvents[i] = gObjectEvents[i];
// Swap graphicsId bytes when saving and loading
// This keeps compatibility with vanilla,
// since the lower graphicsIds will be in the same place as vanilla
graphicsId = gObjectEvents[i].graphicsId;
gSaveBlock1Ptr->objectEvents[i].graphicsId = (graphicsId >> 8) | (graphicsId << 8);
// To avoid crash on vanilla, save follower as inactive
if (gObjectEvents[i].localId == OBJ_EVENT_ID_FOLLOWER)
gSaveBlock1Ptr->objectEvents[i].active = FALSE;
@ -193,13 +199,21 @@ void SaveObjectEvents(void)
void LoadObjectEvents(void)
{
int i;
u16 graphicsId;
for (i = 0; i < OBJECT_EVENTS_COUNT; i++) {
gObjectEvents[i] = gSaveBlock1Ptr->objectEvents[i];
// Swap graphicsId bytes when saving and loading
// This keeps compatibility with vanilla,
// since the lower graphicsIds will be in the same place as vanilla
graphicsId = gObjectEvents[i].graphicsId;
gObjectEvents[i].graphicsId = (graphicsId >> 8) | (graphicsId << 8);
if (!gObjectEvents[i].expanded)
gObjectEvents[i].graphicsId &= 0xFF;
// Try to restore saved inactive follower
if (gObjectEvents[i].localId == OBJ_EVENT_ID_FOLLOWER &&
!gObjectEvents[i].active &&
gObjectEvents[i].extra.asU16)
gObjectEvents[i].graphicsId >= OBJ_EVENT_GFX_MON_BASE)
gObjectEvents[i].active = TRUE;
}
}

View File

@ -1395,7 +1395,7 @@ static void NamingScreen_NoIcon(void)
static void NamingScreen_CreatePlayerIcon(void)
{
u8 rivalGfxId;
u16 rivalGfxId;
u8 spriteId;
rivalGfxId = GetRivalAvatarGraphicsIdByStateIdAndGender(PLAYER_AVATAR_STATE_NORMAL, sNamingScreen->monSpecies);
@ -2584,5 +2584,3 @@ static const struct SpritePalette sSpritePalettes[] =
{gNamingScreenMenu_Pal[4], PALTAG_OK_BUTTON},
{}
};

View File

@ -1215,7 +1215,7 @@ bool8 ScrCmd_setobjectmovementtype(struct ScriptContext *ctx)
bool8 ScrCmd_createvobject(struct ScriptContext *ctx)
{
u8 graphicsId = ScriptReadByte(ctx);
u16 graphicsId = ScriptReadByte(ctx); // Support u16 in createvobject
u8 virtualObjId = ScriptReadByte(ctx);
u16 x = VarGet(ScriptReadHalfword(ctx));
u32 y = VarGet(ScriptReadHalfword(ctx));

View File

@ -157,7 +157,7 @@ static const struct YesNoFuncTable sDeleteRegistryYesNoFuncs =
.noFunc = DeleteRegistry_No,
};
static const u8 sSecretBaseOwnerGfxIds[10] =
static const u16 sSecretBaseOwnerGfxIds[10] =
{
// Male
OBJ_EVENT_GFX_YOUNGSTER,

View File

@ -867,7 +867,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_OW_MON && gObjectEvents[objEventId].localId != OBJ_EVENT_ID_FOLLOWER))
if (objEventId != OBJECT_EVENTS_COUNT && !(gObjectEvents[objEventId].active && gObjectEvents[objEventId].graphicsId >= OBJ_EVENT_GFX_MON_BASE && gObjectEvents[objEventId].localId != OBJ_EVENT_ID_FOLLOWER))
{
sShopData->viewportObjects[numObjects][OBJ_EVENT_ID] = objEventId;
sShopData->viewportObjects[numObjects][X_COORD] = x;

View File

@ -23,9 +23,8 @@ static u8 CreateTask_AnimateUnionRoomPlayers(void);
static u32 IsUnionRoomPlayerInvisible(u32, u32);
static void SetUnionRoomObjectFacingDirection(s32, s32, u8);
// + 2 is just to match, those elements are empty and never read
// Graphics ids should correspond with the classes in gUnionRoomFacilityClasses
static const u8 sUnionRoomObjGfxIds[GENDER_COUNT][NUM_UNION_ROOM_CLASSES + 2] = {
static const u16 sUnionRoomObjGfxIds[GENDER_COUNT][NUM_UNION_ROOM_CLASSES] = {
[MALE] = {
OBJ_EVENT_GFX_MAN_3,
OBJ_EVENT_GFX_BLACK_BELT,
@ -131,7 +130,7 @@ static bool32 IsPlayerStandingStill(void)
}
// Gender and trainer id are used to determine which sprite a player appears as
static u8 GetUnionRoomPlayerGraphicsId(u32 gender, u32 id)
static u16 GetUnionRoomPlayerGraphicsId(u32 gender, u32 id)
{
return sUnionRoomObjGfxIds[gender][id % NUM_UNION_ROOM_CLASSES];
}
@ -442,7 +441,7 @@ static bool32 IsUnionRoomPlayerInvisible(u32 leaderId, u32 memberId)
return IsVirtualObjectInvisible(UR_PLAYER_SPRITE_ID(leaderId, memberId) - UR_SPRITE_START_ID);
}
static void SpawnGroupMember(u32 leaderId, u32 memberId, u8 graphicsId, struct RfuGameData * gameData)
static void SpawnGroupMember(u32 leaderId, u32 memberId, u16 graphicsId, struct RfuGameData * gameData)
{
s32 x, y;
s32 id = UR_PLAYER_SPRITE_ID(leaderId, memberId);