diff --git a/include/overworld.h b/include/overworld.h index 98564f91d6..acb7e68014 100644 --- a/include/overworld.h +++ b/include/overworld.h @@ -47,6 +47,7 @@ struct LinkPlayerObjectEvent // Exported RAM declarations extern struct WarpData gLastUsedWarp; extern struct LinkPlayerObjectEvent gLinkPlayerObjectEvents[4]; +extern struct Coords16 gLightMetatiles[32]; extern u16 *gBGTilemapBuffers1; extern u16 *gBGTilemapBuffers2; diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 2c8e236c62..d05928148c 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -1775,7 +1775,7 @@ bool8 ScrFunc_followerfly(struct ScriptContext *ctx) { return FALSE; } -// Callback for light sprites +// Sprite callback for light sprites void UpdateLightSprite(struct Sprite *sprite) { s16 left = gSaveBlock1Ptr->pos.x - 2; s16 right = gSaveBlock1Ptr->pos.x + 17; @@ -1787,9 +1787,6 @@ void UpdateLightSprite(struct Sprite *sprite) { u32 paletteNum; bool8 finished = TRUE; // Ripped from RemoveObjectEventIfOutsideView - if (x >= left && x <= right - && y >= top && y <= bottom) - finished = FALSE; if (x >= left && x <= right && y >= top && y <= bottom) finished = FALSE; @@ -1803,7 +1800,7 @@ void UpdateLightSprite(struct Sprite *sprite) { return; } - if (gPlayerAvatar.tileTransitionState) { + if (gPlayerAvatar.tileTransitionState) { // As long as the second coefficient stays 12, shadows will not change Weather_SetBlendCoeffs(7, 12); sprite->invisible = FALSE; } else { @@ -1843,14 +1840,17 @@ void TrySpawnLightSprites(s16 camX, s16 camY) { s16 right = gSaveBlock1Ptr->pos.x + 17; s16 top = gSaveBlock1Ptr->pos.y; s16 bottom = gSaveBlock1Ptr->pos.y + 16; + u8 i = 0; s16 x, y; u32 behavior; if (gTimeOfDay != TIME_OF_DAY_NIGHT) return; - for (x = left; x <= right; x++) { - for (y = top; y <= bottom; y++) { + for (i = 0; gLightMetatiles[i].x > 0; i++) { + x = gLightMetatiles[i].x; + y = gLightMetatiles[i].y; + if (x >= left && x <= right && y >= top && y <= bottom) { behavior = MapGridGetMetatileBehaviorAt(x, y); - if (behavior == 0x04) // TODO: Use an actual constant + if (behavior == 0x04) // TODO: Use an actual constant for light metatiles SpawnLightSprite(x, y, camX, camY, behavior); } } diff --git a/src/overworld.c b/src/overworld.c index 32bd469cf8..f81310b703 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -201,6 +201,7 @@ EWRAM_DATA static struct InitialPlayerAvatarState sInitialPlayerAvatarState = {0 EWRAM_DATA static u16 sAmbientCrySpecies = 0; EWRAM_DATA static bool8 sIsAmbientCryWaterMon = FALSE; EWRAM_DATA struct LinkPlayerObjectEvent gLinkPlayerObjectEvents[4] = {0}; +EWRAM_DATA struct Coords16 gLightMetatiles[32] = {0}; // const rom data @@ -590,6 +591,23 @@ struct MapHeader const *const GetDestinationWarpMapHeader(void) return Overworld_GetMapHeaderByGroupAndId(sWarpDestination.mapGroup, sWarpDestination.mapNum); } +// Caches light metatile coordinates +static void CacheLightMetatiles(void) { // TODO: Better way to dynamically generate lights + u8 i = 0; + s16 x, y; + for (x = 0; x < gBackupMapLayout.width; x++) { + for (y = 0; y < gBackupMapLayout.height; y++) { + if (MapGridGetMetatileBehaviorAt(x, y) == 0x04) { + gLightMetatiles[i].x = x; + gLightMetatiles[i].y = y; + i++; + } + } + } + gLightMetatiles[i].x = -1; + gLightMetatiles[i].y = -1; +} + static void LoadCurrentMapData(void) { sLastMapSectionId = gMapHeader.regionMapSectionId; @@ -806,6 +824,7 @@ void LoadMapFromCameraTransition(u8 mapGroup, u8 mapNum) Overworld_ClearSavedMusic(); RunOnTransitionMapScript(); InitMap(); + CacheLightMetatiles(); CopySecondaryTilesetToVramUsingHeap(gMapHeader.mapLayout); LoadSecondaryTilesetPalette(gMapHeader.mapLayout); @@ -1792,6 +1811,7 @@ void CB2_ContinueSavedGame(void) } else { + CacheLightMetatiles(); TryPutTodaysRivalTrainerOnAir(); gFieldCallback = sub_8086204; SetMainCallback1(CB1_Overworld); @@ -1951,6 +1971,7 @@ static bool32 LoadMapInStepsLocal(u8 *state, bool32 a2) (*state)++; break; case 3: + CacheLightMetatiles(); InitObjectEventsLocal(); SetCameraToTrackPlayer(); (*state)++;