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 &&