From 72e723df6589d11a2feb39b8770b4a755bfff5ff Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Sat, 7 Jan 2023 17:54:21 -0500 Subject: [PATCH 1/5] Expanded graphicsId field. --- asm/macros/map.inc | 6 +- include/constants/event_objects.h | 4 ++ include/global.fieldmap.h | 20 ++---- src/event_object_movement.c | 114 ++++++++++++++++-------------- src/field_player_avatar.c | 4 +- src/load_save.c | 2 +- src/shop.c | 2 +- 7 files changed, 78 insertions(+), 74 deletions(-) diff --git a/asm/macros/map.inc b/asm/macros/map.inc index 662257e416..c588962467 100644 --- a/asm/macros/map.inc +++ b/asm/macros/map.inc @@ -21,10 +21,8 @@ @ 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 \inConnection - .space 1 @ Padding + .byte \index, \inConnection + .2byte \gfx .2byte \x, \y .byte \elevation .byte \movement_type diff --git a/include/constants/event_objects.h b/include/constants/event_objects.h index 1d3d7a7013..442d096cc0 100644 --- a/include/constants/event_objects.h +++ b/include/constants/event_objects.h @@ -276,6 +276,10 @@ #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 OW_SPECIES(x) (x->graphicsId - OBJ_EVENT_GFX_MON_BASE) + #define SHADOW_SIZE_S 0 #define SHADOW_SIZE_M 1 #define SHADOW_SIZE_L 2 diff --git a/include/global.fieldmap.h b/include/global.fieldmap.h index 601656f894..9b5eb89003 100644 --- a/include/global.fieldmap.h +++ b/include/global.fieldmap.h @@ -66,8 +66,8 @@ struct BackupMapLayout struct ObjectEventTemplate { /*0x00*/ u8 localId; - /*0x01*/ u8 graphicsId; - /*0x02*/ u8 inConnection; // Leftover from FRLG + /*0x02*/ u16 graphicsId; + // /*0x02*/ u8 inConnection; // Leftover from FRLG /*0x04*/ s16 x; /*0x06*/ s16 y; /*0x08*/ u8 elevation; @@ -192,8 +192,9 @@ struct ObjectEvent u32 disableJumpLandingGroundEffect:1; u32 fixedPriority:1; u32 hideReflection:1; - /*0x04*/ u8 spriteId; - /*0x05*/ u8 graphicsId; + u32 shiny:1; // OW mon shininess + /*0x04*/ u16 graphicsId:11; // 11 bits; 2048 entries + /*0x05*/ u16 form:5; /*0x06*/ u8 movementType; /*0x07*/ u8 trainerType; /*0x08*/ u8 localId; @@ -216,15 +217,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*/ }; diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 265918d653..cf3cc5e719 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -1399,8 +1399,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->form = objectEvent->shiny = 0; } void RemoveObjectEventByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup) @@ -1497,6 +1498,9 @@ TrySpawnObjectEventTemplate(struct ObjectEventTemplate *objectEventTemplate, struct SpriteFrameImage spriteFrameImage; const struct ObjectEventGraphicsInfo *graphicsInfo; const struct SubspriteTable *subspriteTables = NULL; + u16 species; + u8 form; + bool8 shiny; graphicsInfo = GetObjectEventGraphicsInfo(objectEventTemplate->graphicsId); MakeSpriteTemplateFromObjectEventTemplate(objectEventTemplate, &spriteTemplate, &subspriteTables); @@ -1510,26 +1514,25 @@ 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) { + // Set form & shininess based on script header + if (objectEventTemplate->graphicsId >= OBJ_EVENT_GFX_MON_BASE && 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; + species = script[2] | script[3] << 8; + form = (species >> 10) & 0x1F; + shiny = species >> 15; + gObjectEvents[objectEventId].form = form; + gObjectEvents[objectEventId].shiny = shiny; + species = OW_SPECIES(objectEventTemplate); FollowerSetGraphics(&gObjectEvents[objectEventId], species, form, shiny); } // 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); + } else if (objectEventTemplate->graphicsId >= OBJ_EVENT_GFX_VARS && VarGetObjectEventGraphicsId(objectEventTemplate->graphicsId - OBJ_EVENT_GFX_VARS) >= OBJ_EVENT_GFX_MON_BASE) { + species = VarGet(VAR_TEMP_4); + gObjectEvents[objectEventId].form = form = (species >> 10) & 0x1F; + gObjectEvents[objectEventId].shiny = shiny = species >> 15; + species = OW_SPECIES(objectEventTemplate); + FollowerSetGraphics(&gObjectEvents[objectEventId], species, form, shiny); } return objectEventId; @@ -1552,7 +1555,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; @@ -1614,7 +1617,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; @@ -1748,12 +1751,11 @@ 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) { const struct ObjectEventGraphicsInfo *graphicsInfo = SpeciesToGraphicsInfo(species, form); - objEvent->graphicsId = OBJ_EVENT_GFX_OW_MON; + objEvent->graphicsId = OBJ_EVENT_GFX_MON_BASE + species; 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; + objEvent->form = form; + objEvent->shiny = shiny; if (graphicsInfo->paletteTag == OBJ_EVENT_PAL_TAG_DYNAMIC) { // Use palette from species palette table struct Sprite *sprite = &gSprites[objEvent->spriteId]; // Free palette if otherwise unused @@ -1768,9 +1770,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 = objEvent->form; + u8 shiny = objEvent->shiny; const struct ObjectEventGraphicsInfo *graphicsInfo = SpeciesToGraphicsInfo(species, form); struct Sprite *sprite = &gSprites[objEvent->spriteId]; u8 i = FindObjectEventPaletteIndexByTag(graphicsInfo->paletteTag); @@ -1844,11 +1846,11 @@ void UpdateFollowingPokemon(void) { // Update following pokemon if any bool8 shiny; u8 form; // Avoid spawning large (64x64) follower pokemon inside buildings - if (GetFollowerInfo(&species, &form, &shiny) && !(gMapHeader.mapType == MAP_TYPE_INDOOR && SpeciesToGraphicsInfo(species, 0)->height == 64) && !FlagGet(FLAG_TEMP_HIDE_FOLLOWER)) { + if (GetFollowerInfo(&species, &form, &shiny) && !(gMapHeader.mapType == MAP_TYPE_INDOOR && SpeciesToGraphicsInfo(species, 0)->height == 64) && !FlagGet(FLAG_TEMP_HIDE_FOLLOWER) && FALSE) { // TODO 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, @@ -1861,15 +1863,12 @@ void UpdateFollowingPokemon(void) { // Update following pokemon if any } 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 != objEvent->form) { MoveObjectEventToMapCoords(objEvent, gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.x, gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.y); objEvent->invisible = TRUE; } 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(); } @@ -2285,8 +2284,8 @@ 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); + if (objectEvent->graphicsId >= OBJ_EVENT_GFX_MON_BASE) { // Set pokemon graphics + FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), objectEvent->form, objectEvent->shiny); } if (!objectEvent->inanimate && objectEvent->movementType != MOVEMENT_TYPE_PLAYER) StartSpriteAnim(sprite, GetFaceDirectionAnimNum(objectEvent->facingDirection)); @@ -2445,15 +2444,17 @@ const struct ObjectEventGraphicsInfo *GetObjectEventGraphicsInfo(u8 graphicsId) { u8 bard; - 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) - { + if (graphicsId == OBJ_EVENT_GFX_BARD) { bard = GetCurrentMauvilleOldMan(); return gMauvilleOldManGraphicsInfoPointers[bard]; } + if (graphicsId >= OBJ_EVENT_GFX_MON_BASE) + return SpeciesToGraphicsInfo(graphicsId - OBJ_EVENT_GFX_MON_BASE, 0); + if (graphicsId >= NUM_OBJ_EVENT_GFX) graphicsId = OBJ_EVENT_GFX_NINJA_BOY; @@ -4893,12 +4894,12 @@ 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 && objectEvent->form != (multi = GetOverworldCastformForm())) { sprite->data[7] = TRANSFORM_TYPE_PERMANENT << 8; - objectEvent->extra.mon.form = multi; + objectEvent->form = multi; 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; @@ -4910,7 +4911,7 @@ static bool8 UpdateFollowerTransformEffect(struct ObjectEvent *objectEvent, stru u8 type = sprite->data[7] >> 8; u8 frames = sprite->data[7] & 0xFF; u8 stretch; - u32 multi; + u32 multi, multi2; if (!type) return TryStartFollowerTransformEffect(objectEvent, sprite); sprite->oam.mosaic = TRUE; @@ -4928,15 +4929,18 @@ 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; + multi2 = objectEvent->form; + objectEvent->form = 0; RefreshFollowerGraphics(objectEvent); - objectEvent->extra.asU16 = multi; + objectEvent->graphicsId = multi; + objectEvent->form = multi2; break; } } @@ -5529,7 +5533,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; } @@ -6650,6 +6654,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); @@ -6662,6 +6667,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); } @@ -6722,7 +6728,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); + FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), objectEvent->form, objectEvent->shiny); LoadWhiteFlashPalette(objectEvent, sprite); // Initialize affine animation sprite->affineAnims = sAffineAnims_PokeballFollower; @@ -6734,7 +6740,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); + FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), objectEvent->form, objectEvent->shiny); } return FALSE; } @@ -6750,6 +6756,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; @@ -6765,6 +6772,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; @@ -6772,7 +6780,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); + FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), objectEvent->form, objectEvent->shiny); objectEvent->invisible = TRUE; sprite->data[1] = 0; sprite->data[6] = 0; @@ -8923,13 +8931,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); } diff --git a/src/field_player_avatar.c b/src/field_player_avatar.c index 0afe31ecbf..5f4573c533 100644 --- a/src/field_player_avatar.c +++ b/src/field_player_avatar.c @@ -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) diff --git a/src/load_save.c b/src/load_save.c index 9c10b4b10e..da6997de01 100644 --- a/src/load_save.c +++ b/src/load_save.c @@ -199,7 +199,7 @@ void LoadObjectEvents(void) // 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; } } diff --git a/src/shop.c b/src/shop.c index d246fea6f0..3fcebd319d 100644 --- a/src/shop.c +++ b/src/shop.c @@ -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; From 5d5d97b46a90af1bb74cf38b07cda2e4f48f89da Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Sat, 7 Jan 2023 20:35:36 -0500 Subject: [PATCH 2/5] Fixed most functions that take/return graphicsIds to accept u16s. --- include/battle_tower.h | 4 ++-- include/event_data.h | 2 +- include/event_object_movement.h | 10 ++++----- include/field_player_avatar.h | 14 ++++++------- include/fldeff.h | 2 +- src/battle_tower.c | 6 +++--- src/cable_car.c | 5 ++--- src/event_data.c | 2 +- src/event_object_movement.c | 16 +++++++-------- src/field_player_avatar.c | 36 +++++++++------------------------ src/field_specials.c | 4 ++-- src/fldeff_rocksmash.c | 2 +- src/naming_screen.c | 4 +--- src/scrcmd.c | 2 +- src/secret_base.c | 2 +- src/union_room_player_avatar.c | 7 +++---- 16 files changed, 48 insertions(+), 70 deletions(-) diff --git a/include/battle_tower.h b/include/battle_tower.h index a803145927..8288ffb7ea 100644 --- a/include/battle_tower.h +++ b/include/battle_tower.h @@ -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); diff --git a/include/event_data.h b/include/event_data.h index b1fa694601..86b7afea8a 100644 --- a/include/event_data.h +++ b/include/event_data.h @@ -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); diff --git a/include/event_object_movement.h b/include/event_object_movement.h index f2383272fc..9249cc6a94 100644 --- a/include/event_object_movement.h +++ b/include/event_object_movement.h @@ -132,15 +132,15 @@ u8 GetDirectionToFace(s16, s16, s16, s16); 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 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); @@ -462,9 +462,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); diff --git a/include/field_player_avatar.h b/include/field_player_avatar.h index 39fc886af8..dae0f6c0db 100644 --- a/include/field_player_avatar.h +++ b/include/field_player_avatar.h @@ -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); diff --git a/include/fldeff.h b/include/fldeff.h index 0ad0e3d606..836a795a00 100644 --- a/include/fldeff.h +++ b/include/fldeff.h @@ -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); diff --git a/src/battle_tower.c b/src/battle_tower.c index 1e134b8fa1..1ae587af12 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -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; diff --git a/src/cable_car.c b/src/cable_car.c index dd1da31762..a95e391c61 100644 --- a/src/cable_car.c +++ b/src/cable_car.c @@ -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; } - diff --git a/src/event_data.c b/src/event_data.c index 22ebdb0d1d..561cd3edd8 100644 --- a/src/event_data.c +++ b/src/event_data.c @@ -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); } diff --git a/src/event_object_movement.c b/src/event_object_movement.c index cf3cc5e719..077052f2df 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -1547,7 +1547,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; @@ -1657,7 +1657,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; @@ -1846,7 +1846,7 @@ void UpdateFollowingPokemon(void) { // Update following pokemon if any bool8 shiny; u8 form; // Avoid spawning large (64x64) follower pokemon inside buildings - if (GetFollowerInfo(&species, &form, &shiny) && !(gMapHeader.mapType == MAP_TYPE_INDOOR && SpeciesToGraphicsInfo(species, 0)->height == 64) && !FlagGet(FLAG_TEMP_HIDE_FOLLOWER) && FALSE) { // TODO + if (GetFollowerInfo(&species, &form, &shiny) && !(gMapHeader.mapType == MAP_TYPE_INDOOR && SpeciesToGraphicsInfo(species, 0)->height == 64) && !FlagGet(FLAG_TEMP_HIDE_FOLLOWER)) { if (objEvent == NULL) { // Spawn follower struct ObjectEventTemplate template = { .localId = OBJ_EVENT_ID_FOLLOWER, @@ -2357,14 +2357,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; @@ -2396,7 +2396,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); @@ -2440,7 +2440,7 @@ 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; @@ -9751,7 +9751,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); diff --git a/src/field_player_avatar.c b/src/field_player_avatar.c index 5f4573c533..a6d775bc59 100644 --- a/src/field_player_avatar.c +++ b/src/field_player_avatar.c @@ -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); diff --git a/src/field_specials.c b/src/field_specials.c index 652cb434bc..b62414fb84 100644 --- a/src/field_specials.c +++ b/src/field_specials.c @@ -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. diff --git a/src/fldeff_rocksmash.c b/src/fldeff_rocksmash.c index 71044aa30a..39f64adb87 100644 --- a/src/fldeff_rocksmash.c +++ b/src/fldeff_rocksmash.c @@ -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; diff --git a/src/naming_screen.c b/src/naming_screen.c index da9aa6988a..b044cc20d7 100644 --- a/src/naming_screen.c +++ b/src/naming_screen.c @@ -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}, {} }; - - diff --git a/src/scrcmd.c b/src/scrcmd.c index 8e278bb153..be26df9631 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -1206,7 +1206,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)); diff --git a/src/secret_base.c b/src/secret_base.c index 1a4a0ac9cd..836cf1b3d0 100644 --- a/src/secret_base.c +++ b/src/secret_base.c @@ -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, diff --git a/src/union_room_player_avatar.c b/src/union_room_player_avatar.c index a7d5045b38..d8d1da49c8 100644 --- a/src/union_room_player_avatar.c +++ b/src/union_room_player_avatar.c @@ -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); From 3a0dc0f4f60b902b4b91f86ff314d24533cd2d1f Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Tue, 10 Jan 2023 20:23:53 -0500 Subject: [PATCH 3/5] Reworked how OW pokemon's graphics are loaded. --- include/constants/event_objects.h | 5 +- include/global.fieldmap.h | 3 +- src/event_object_movement.c | 128 +++++++++++++++++------------- 3 files changed, 77 insertions(+), 59 deletions(-) diff --git a/include/constants/event_objects.h b/include/constants/event_objects.h index 442d096cc0..cd2de8e31a 100644 --- a/include/constants/event_objects.h +++ b/include/constants/event_objects.h @@ -277,8 +277,11 @@ #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_MON_BASE) +#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 diff --git a/include/global.fieldmap.h b/include/global.fieldmap.h index 9b5eb89003..56c8c19f78 100644 --- a/include/global.fieldmap.h +++ b/include/global.fieldmap.h @@ -193,8 +193,7 @@ struct ObjectEvent u32 fixedPriority:1; u32 hideReflection:1; u32 shiny:1; // OW mon shininess - /*0x04*/ u16 graphicsId:11; // 11 bits; 2048 entries - /*0x05*/ u16 form:5; + /*0x04*/ u16 graphicsId; // 11 bits for species; high 5 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 077052f2df..432599373f 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -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[]; @@ -1300,7 +1302,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; @@ -1315,7 +1317,13 @@ static u8 InitObjectEventStateFromTemplate(struct ObjectEventTemplate *template, y = template->y + MAP_OFFSET; objectEvent->active = TRUE; objectEvent->triggerGroundEffectsOnMove = TRUE; - objectEvent->graphicsId = template->graphicsId; + 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; @@ -1401,7 +1409,7 @@ static void RemoveObjectEvent(struct ObjectEvent *objectEvent) objectEvent->active = FALSE; RemoveObjectEventInternal(objectEvent); // zero potential species info - objectEvent->graphicsId = objectEvent->form = objectEvent->shiny = 0; + objectEvent->graphicsId = objectEvent->shiny = 0; } void RemoveObjectEventByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup) @@ -1444,7 +1452,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; @@ -1458,7 +1466,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); } @@ -1473,6 +1481,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); @@ -1490,20 +1502,41 @@ 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; + if (!template) + return 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; - bool8 shiny; + 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); @@ -1514,27 +1547,6 @@ TrySpawnObjectEventTemplate(struct ObjectEventTemplate *objectEventTemplate, if (subspriteTables) SetSubspriteTables(&gSprites[gObjectEvents[objectEventId].spriteId], subspriteTables); - // Set form & shininess based on script header - if (objectEventTemplate->graphicsId >= OBJ_EVENT_GFX_MON_BASE && objectEventTemplate->script) { - const u8 *script = objectEventTemplate->script; - if (script[0] == 0x7d) { // bufferspeciesname - species = script[2] | script[3] << 8; - form = (species >> 10) & 0x1F; - shiny = species >> 15; - gObjectEvents[objectEventId].form = form; - gObjectEvents[objectEventId].shiny = shiny; - species = OW_SPECIES(objectEventTemplate); - FollowerSetGraphics(&gObjectEvents[objectEventId], species, form, shiny); - } - // 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_MON_BASE) { - species = VarGet(VAR_TEMP_4); - gObjectEvents[objectEventId].form = form = (species >> 10) & 0x1F; - gObjectEvents[objectEventId].shiny = shiny = species >> 15; - species = OW_SPECIES(objectEventTemplate); - FollowerSetGraphics(&gObjectEvents[objectEventId], species, form, shiny); - } - return objectEventId; } @@ -1730,7 +1742,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 @@ -1751,10 +1763,9 @@ 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) { const struct ObjectEventGraphicsInfo *graphicsInfo = SpeciesToGraphicsInfo(species, form); - objEvent->graphicsId = OBJ_EVENT_GFX_MON_BASE + species; ObjectEventSetGraphics(objEvent, graphicsInfo); - objEvent->graphicsId = OBJ_EVENT_GFX_MON_BASE + species; - objEvent->form = form; + 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) { // Use palette from species palette table struct Sprite *sprite = &gSprites[objEvent->spriteId]; @@ -1771,7 +1782,7 @@ static void FollowerSetGraphics(struct ObjectEvent *objEvent, u16 species, u8 fo // TODO: Reposition sprite if size changes static void RefreshFollowerGraphics(struct ObjectEvent *objEvent) { u16 species = OW_SPECIES(objEvent); - u8 form = objEvent->form; + u8 form = OW_FORM(objEvent); u8 shiny = objEvent->shiny; const struct ObjectEventGraphicsInfo *graphicsInfo = SpeciesToGraphicsInfo(species, form); struct Sprite *sprite = &gSprites[objEvent->spriteId]; @@ -1857,17 +1868,19 @@ void UpdateFollowingPokemon(void) { // Update following pokemon if any // 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 != OW_SPECIES(objEvent) || shiny != objEvent->shiny || form != objEvent->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); objEvent->invisible = TRUE; } - FollowerSetGraphics(objEvent, species, form, shiny); sprite->data[6] = 0; // set animation data } else { RemoveFollowingPokemon(); @@ -2260,13 +2273,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); @@ -2284,9 +2300,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_MON_BASE) { // Set pokemon graphics - FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), objectEvent->form, objectEvent->shiny); - } if (!objectEvent->inanimate && objectEvent->movementType != MOVEMENT_TYPE_PLAYER) StartSpriteAnim(sprite, GetFaceDirectionAnimNum(objectEvent->facingDirection)); @@ -2442,18 +2455,23 @@ static void get_berry_tree_graphics(struct ObjectEvent *objectEvent, struct Spri const struct ObjectEventGraphicsInfo *GetObjectEventGraphicsInfo(u16 graphicsId) { - u8 bard; + u32 form = 0; if (graphicsId >= OBJ_EVENT_GFX_VARS && graphicsId <= OBJ_EVENT_GFX_VAR_F) graphicsId = VarGetObjectEventGraphicsId(graphicsId - OBJ_EVENT_GFX_VARS); + // 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) { - bard = GetCurrentMauvilleOldMan(); - return gMauvilleOldManGraphicsInfoPointers[bard]; + return gMauvilleOldManGraphicsInfoPointers[GetCurrentMauvilleOldMan()]; } if (graphicsId >= OBJ_EVENT_GFX_MON_BASE) - return SpeciesToGraphicsInfo(graphicsId - OBJ_EVENT_GFX_MON_BASE, 0); + return SpeciesToGraphicsInfo(graphicsId - OBJ_EVENT_GFX_MON_BASE, form); if (graphicsId >= NUM_OBJ_EVENT_GFX) graphicsId = OBJ_EVENT_GFX_NINJA_BOY; @@ -2463,7 +2481,7 @@ const struct ObjectEventGraphicsInfo *GetObjectEventGraphicsInfo(u16 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); } @@ -4894,9 +4912,10 @@ static bool8 EndFollowerTransformEffect(struct ObjectEvent *objectEvent, struct static bool8 TryStartFollowerTransformEffect(struct ObjectEvent *objectEvent, struct Sprite *sprite) { u32 multi; - if (OW_SPECIES(objectEvent) == SPECIES_CASTFORM && objectEvent->form != (multi = GetOverworldCastformForm())) { + if (OW_SPECIES(objectEvent) == SPECIES_CASTFORM && OW_FORM(objectEvent) != (multi = GetOverworldCastformForm())) { sprite->data[7] = TRANSFORM_TYPE_PERMANENT << 8; - objectEvent->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) && (OW_SPECIES(objectEvent) == SPECIES_MEW || OW_SPECIES(objectEvent) == SPECIES_DITTO)) { @@ -4911,7 +4930,7 @@ static bool8 UpdateFollowerTransformEffect(struct ObjectEvent *objectEvent, stru u8 type = sprite->data[7] >> 8; u8 frames = sprite->data[7] & 0xFF; u8 stretch; - u32 multi, multi2; + u32 multi; if (!type) return TryStartFollowerTransformEffect(objectEvent, sprite); sprite->oam.mosaic = TRUE; @@ -4936,11 +4955,8 @@ static bool8 UpdateFollowerTransformEffect(struct ObjectEvent *objectEvent, stru break; } objectEvent->graphicsId += OBJ_EVENT_GFX_MON_BASE; - multi2 = objectEvent->form; - objectEvent->form = 0; RefreshFollowerGraphics(objectEvent); objectEvent->graphicsId = multi; - objectEvent->form = multi2; break; } } @@ -6728,7 +6744,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, OW_SPECIES(objectEvent), objectEvent->form, objectEvent->shiny); + FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), OW_FORM(objectEvent), objectEvent->shiny); LoadWhiteFlashPalette(objectEvent, sprite); // Initialize affine animation sprite->affineAnims = sAffineAnims_PokeballFollower; @@ -6740,7 +6756,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), objectEvent->form, objectEvent->shiny); + FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), OW_FORM(objectEvent), objectEvent->shiny); } return FALSE; } @@ -6780,7 +6796,7 @@ bool8 MovementAction_EnterPokeball_Step1(struct ObjectEvent *objectEvent, struct bool8 MovementAction_EnterPokeball_Step2(struct ObjectEvent *objectEvent, struct Sprite *sprite) { - FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), objectEvent->form, objectEvent->shiny); + FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), OW_FORM(objectEvent), objectEvent->shiny); objectEvent->invisible = TRUE; sprite->data[1] = 0; sprite->data[6] = 0; From 7b40e481ce1a42786bf8354374e24ee1171595b7 Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Wed, 11 Jan 2023 21:55:39 -0500 Subject: [PATCH 4/5] Improved saving & loading expanded OWs. --- asm/macros/map.inc | 3 ++- include/global.fieldmap.h | 11 +++++++---- src/event_object_movement.c | 3 +-- src/load_save.c | 14 ++++++++++++++ 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/asm/macros/map.inc b/asm/macros/map.inc index c588962467..9678311a4d 100644 --- a/asm/macros/map.inc +++ b/asm/macros/map.inc @@ -21,8 +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, \inConnection + .byte \index .2byte \gfx + .byte \inConnection .2byte \x, \y .byte \elevation .byte \movement_type diff --git a/include/global.fieldmap.h b/include/global.fieldmap.h index 56c8c19f78..22a4bc9a55 100644 --- a/include/global.fieldmap.h +++ b/include/global.fieldmap.h @@ -63,22 +63,24 @@ struct BackupMapLayout u16 *map; }; -struct ObjectEventTemplate +struct __attribute__((packed)) ObjectEventTemplate { /*0x00*/ u8 localId; - /*0x02*/ u16 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 { @@ -193,6 +195,7 @@ struct ObjectEvent u32 fixedPriority:1; u32 hideReflection:1; 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; diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 432599373f..2595448808 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -1317,6 +1317,7 @@ static u8 InitObjectEventStateFromTemplate(const struct ObjectEventTemplate *tem y = template->y + MAP_OFFSET; objectEvent->active = TRUE; objectEvent->triggerGroundEffectsOnMove = TRUE; + objectEvent->expanded = TRUE; objectEvent->graphicsId = PackGraphicsId(template); if (objectEvent->graphicsId >= OBJ_EVENT_GFX_MON_BASE) { if (template->script && template->script[0] == 0x7d) @@ -1506,8 +1507,6 @@ static u8 TrySetupObjectEventSprite(const struct ObjectEventTemplate *objectEven static u16 PackGraphicsId(const struct ObjectEventTemplate *template) { u16 graphicsId = template->graphicsId; u32 form = 0; - if (!template) - return 0; // set form based on template's script, // if first command is bufferspeciesname if (graphicsId >= OBJ_EVENT_GFX_MON_BASE) { diff --git a/src/load_save.c b/src/load_save.c index da6997de01..07da625014 100644 --- a/src/load_save.c +++ b/src/load_save.c @@ -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,9 +199,17 @@ 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 && From 95b98efc30f85cc86c0f71a79f9a65cf3daf18c3 Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Thu, 12 Jan 2023 21:40:05 -0500 Subject: [PATCH 5/5] Updated existing OW pokemon events with new system. --- data/map_events.s | 2 +- data/maps/AncientTomb/map.json | 2 +- data/maps/DesertRuins/map.json | 2 +- data/maps/IslandCave/map.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/map_events.s b/data/map_events.s index cfa5799d37..729f9725df 100644 --- a/data/map_events.s +++ b/data/map_events.s @@ -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" - diff --git a/data/maps/AncientTomb/map.json b/data/maps/AncientTomb/map.json index 16df613a49..98089d7aea 100644 --- a/data/maps/AncientTomb/map.json +++ b/data/maps/AncientTomb/map.json @@ -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, diff --git a/data/maps/DesertRuins/map.json b/data/maps/DesertRuins/map.json index 933d5d2272..80c8f6a483 100644 --- a/data/maps/DesertRuins/map.json +++ b/data/maps/DesertRuins/map.json @@ -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, diff --git a/data/maps/IslandCave/map.json b/data/maps/IslandCave/map.json index 24c6e0cd27..c6204ff1c5 100644 --- a/data/maps/IslandCave/map.json +++ b/data/maps/IslandCave/map.json @@ -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,