From 72851fb047f3f4d95a80ad73670da98023ebd2c1 Mon Sep 17 00:00:00 2001 From: darsh Date: Mon, 29 Sep 2025 23:39:07 -0400 Subject: [PATCH 1/5] update member names of FloorProperties struct --- include/structs/str_dungeon.h | 25 +++++++++++++------------ src/dungeon_generation.c | 2 +- src/dungeon_items.c | 2 +- src/dungeon_tilemap.c | 2 +- src/run_dungeon.c | 6 +++--- src/unk_dungeon_load_maybe.c | 2 +- src/weather.c | 2 +- 7 files changed, 21 insertions(+), 20 deletions(-) diff --git a/include/structs/str_dungeon.h b/include/structs/str_dungeon.h index a18972e69..f57bc9024 100644 --- a/include/structs/str_dungeon.h +++ b/include/structs/str_dungeon.h @@ -121,9 +121,9 @@ typedef struct FloorProperties { u8 layout; s8 roomDensity; - u8 unk2; - u8 unk3; - u8 unk4; + u8 tileset; + u8 bgMusic; + u8 weather; // See include/constants/weather.h u8 floorConnectivity; u8 enemyDensity; u8 kecleonShopChance; // Percentage chance 0-100% @@ -133,19 +133,20 @@ typedef struct FloorProperties bool8 allowDeadEnds; u8 secondaryStructuresBudget; // Maximum number of secondary structures that can be generated u8 roomFlags; // See ROOM_FLAG_ - u8 unkE; + bool8 unkE; // Unreferenced flag u8 itemDensity; u8 trapDensity; - u8 unk11; - u8 unk12; + u8 floorNumber; // Unreferenced + u8 fixedRoomNumber; u8 numExtraHallways; u8 buriedItemDensity; // Density of buried items (in walls) - u8 unk15; - u8 unk16; - u8 unk17; - u8 unk18; - u8 itemlessMonsterHouseChance; // Chance that a monster house will be itemless - u8 unk1A; + u8 unk15; // Unreferenced + u8 visibilityRange; + u8 moneyUpperBound; // Generated money stacks cannot exceed this amount (multiplied by 40) + u8 kecleonShopLayout; + u8 itemlessMonsterHouseChance; // Chance that a monster house will be itemless (always 0) + u8 unk1A; // Unreferenced (always 0) + u8 unk1B; // Unreferenced (always 0) } FloorProperties; enum { diff --git a/src/dungeon_generation.c b/src/dungeon_generation.c index 75eb3b7a2..da85bac45 100644 --- a/src/dungeon_generation.c +++ b/src/dungeon_generation.c @@ -6097,7 +6097,7 @@ static void sub_8051654(FloorProperties *floorProps) if ((tile->terrainFlags & TERRAIN_TYPE_NATURAL_JUNCTION)) continue; - if (sKecleonShopItemSpawnChances[floorProps->unk18][yIndex][xIndex] > DungeonRandInt(100)) { + if (sKecleonShopItemSpawnChances[floorProps->kecleonShopLayout][yIndex][xIndex] > DungeonRandInt(100)) { tile->spawnOrVisibilityFlags.spawn |= SPAWN_FLAG_ITEM; } } diff --git a/src/dungeon_items.c b/src/dungeon_items.c index 7b72e5d24..4121ba661 100644 --- a/src/dungeon_items.c +++ b/src/dungeon_items.c @@ -83,7 +83,7 @@ void CreateItemWithStickyChance(Item *item, u8 itemID, u32 forceSticky) } if (GetItemCategory(itemID) == CATEGORY_POKE) { - sub_8046CE4(item, gDungeon->floorProperties.unk17 * 40); + sub_8046CE4(item, gDungeon->floorProperties.moneyUpperBound * 40); } } diff --git a/src/dungeon_tilemap.c b/src/dungeon_tilemap.c index 75cf06e8a..86e993ce7 100644 --- a/src/dungeon_tilemap.c +++ b/src/dungeon_tilemap.c @@ -88,7 +88,7 @@ void sub_803F27C(bool8 a0) gUnknown_202EDFC = 0xFFFF; if (!a0) { - strPtr->visibilityRange = gDungeon->floorProperties.unk16 & 3; + strPtr->visibilityRange = gDungeon->floorProperties.visibilityRange & 3; if (strPtr->visibilityRange == 0) { strPtr->unk1820C = 1; } diff --git a/src/run_dungeon.c b/src/run_dungeon.c index eec8be2ec..94d289148 100644 --- a/src/run_dungeon.c +++ b/src/run_dungeon.c @@ -309,9 +309,9 @@ void RunDungeon_Async(DungeonSetupStruct *setupPtr) gDungeon->unk644.unk40 = 99; gDungeon->unk644.unk42 = 99; gDungeon->weather.weather = 0; - gDungeon->tileset = gDungeon->floorProperties.unk2; - gDungeon->unk3A10 = gDungeon->floorProperties.unk3; - gDungeon->fixedRoomNumber = gDungeon->floorProperties.unk12; + gDungeon->tileset = gDungeon->floorProperties.tileset; + gDungeon->unk3A10 = gDungeon->floorProperties.bgMusic; + gDungeon->fixedRoomNumber = gDungeon->floorProperties.fixedRoomNumber; sub_807E5E4(0); sub_80842F0(); } diff --git a/src/unk_dungeon_load_maybe.c b/src/unk_dungeon_load_maybe.c index e1a92d80b..0f3d7d633 100644 --- a/src/unk_dungeon_load_maybe.c +++ b/src/unk_dungeon_load_maybe.c @@ -42,7 +42,7 @@ void sub_80ADD9C(OpenedFile **a0, OpenedFile **a1, u32 *a2, void *a3, u16 *a4, c } strPtr = &((struct DungeonMapParam2 *)(mapParamFile->data))->unk0[dungId][dungFloor]; - r8 = ((struct DungeonMapParam2 *)(mapParamFile->data))->floorProperties[strPtr->unk0].unk2; + r8 = ((struct DungeonMapParam2 *)(mapParamFile->data))->floorProperties[strPtr->unk0].tileset; CloseFile(mapParamFile); diff --git a/src/weather.c b/src/weather.c index a4d4b1a69..809d8d8d3 100644 --- a/src/weather.c +++ b/src/weather.c @@ -51,7 +51,7 @@ u8 GetApparentWeather(Entity *pokemon) void sub_807E5AC(void) { u8 weather; - weather = gDungeon->floorProperties.unk4; + weather = gDungeon->floorProperties.weather; if(weather == WEATHER_COUNT) weather = DungeonRandInt(WEATHER_COUNT); sub_807E5E4(weather); From 5c07eed98f57e47b5a672667d5d3cc67f90d3c28 Mon Sep 17 00:00:00 2001 From: darsh Date: Mon, 29 Sep 2025 23:52:41 -0400 Subject: [PATCH 2/5] update comment --- include/structs/str_dungeon.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/structs/str_dungeon.h b/include/structs/str_dungeon.h index f57bc9024..f866ffe34 100644 --- a/include/structs/str_dungeon.h +++ b/include/structs/str_dungeon.h @@ -25,7 +25,7 @@ typedef struct Weather // 0xE264 { /* 0x0 */ u8 weather; // Uses the weather constants in weather.h. - /* 0x1 */ u8 unkE265; // Uses the weather constants in weather.h + /* 0x1 */ u8 unkE265; // Uses the weather constants in weather.h. /* 0x2 */ u8 weatherDamageCounter; // Timer for applying sandstorm/hail damage periodically. /* 0x3 */ u8 unkE267[8]; /* 0xB */ u8 naturalWeather[8]; // The weather at the start of the floor. If the weather changes, then expires, revert back to the starting weather. @@ -123,7 +123,7 @@ typedef struct FloorProperties s8 roomDensity; u8 tileset; u8 bgMusic; - u8 weather; // See include/constants/weather.h + u8 weather; // Uses the weather constants in weather.h. u8 floorConnectivity; u8 enemyDensity; u8 kecleonShopChance; // Percentage chance 0-100% From b37884cd229332160b896da1a3cff70586902ce6 Mon Sep 17 00:00:00 2001 From: darsh Date: Tue, 30 Sep 2025 00:16:11 -0400 Subject: [PATCH 3/5] update another comment --- src/dungeon_config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dungeon_config.c b/src/dungeon_config.c index 827588d16..39a44040e 100644 --- a/src/dungeon_config.c +++ b/src/dungeon_config.c @@ -597,7 +597,7 @@ const s16 gMoltresConfigLevel = 20; const s16 gArticunoConfigLevel = 20; const s16 gGroudonConfigLevel = 10; -// Dimensions are [floorProperty unk18][y][x] See sub_8051654 +// Dimensions are [floorProperty kecleonShopLayout][y][x] See sub_8051654 const s16 sKecleonShopItemSpawnChances[16][3][3] = { [0] = { {57, 57, 57}, From 9201177a942613f9862e0585bb4e5901c3f98982 Mon Sep 17 00:00:00 2001 From: darsh Date: Tue, 30 Sep 2025 12:39:10 -0400 Subject: [PATCH 4/5] unk15 -> standaloneLakeDensity --- include/structs/str_dungeon.h | 2 +- src/dungeon_generation.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/structs/str_dungeon.h b/include/structs/str_dungeon.h index f866ffe34..e28d7f172 100644 --- a/include/structs/str_dungeon.h +++ b/include/structs/str_dungeon.h @@ -140,7 +140,7 @@ typedef struct FloorProperties u8 fixedRoomNumber; u8 numExtraHallways; u8 buriedItemDensity; // Density of buried items (in walls) - u8 unk15; // Unreferenced + u8 standaloneLakeDensity; // Density of a mass of secondary tiles replacing a wall (i.e. a lake) u8 visibilityRange; u8 moneyUpperBound; // Generated money stacks cannot exceed this amount (multiplied by 40) u8 kecleonShopLayout; diff --git a/src/dungeon_generation.c b/src/dungeon_generation.c index da85bac45..8e5a6d298 100644 --- a/src/dungeon_generation.c +++ b/src/dungeon_generation.c @@ -4600,7 +4600,7 @@ static const s32 sNumToGenTable[8] = {1, 1, 1, 2, 2, 2, 3, 3}; * when a lake is generated. * * Lakes are a large collection of secondary terrain generated around a central point. - * Standalone lakes are generated based on secondary_terrain_density + * Standalone lakes are generated based on floorProps->standaloneLakeDensity * * The formations will never cut into room tiles, but can pass through to the other side. */ @@ -4779,8 +4779,8 @@ static void GenerateSecondaryTerrainFormations(u32 flag, FloorProperties *floorP } } - // Generate standalone lakes secondary_terrain_density # of times - for (densityN = 0; densityN < floorProps->unk15; densityN++) { + // Generate standalone lakes floorProps->standaloneLakeDensity # of times + for (densityN = 0; densityN < floorProps->standaloneLakeDensity; densityN++) { s32 x, y; bool8 table[10][10]; // Try to pick a random tile in the interior to seed the "lake" From 9b3eff484793bcdf8b28bc445ef37a7c713b375d Mon Sep 17 00:00:00 2001 From: darsh Date: Tue, 30 Sep 2025 13:41:30 -0400 Subject: [PATCH 5/5] Document floorProps->enemyDensity bug --- include/structs/str_dungeon.h | 4 ++-- src/dungeon_generation.c | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/structs/str_dungeon.h b/include/structs/str_dungeon.h index e28d7f172..4cc3e1232 100644 --- a/include/structs/str_dungeon.h +++ b/include/structs/str_dungeon.h @@ -120,12 +120,12 @@ typedef struct UnkDungeonGlobal_unk181E8_sub typedef struct FloorProperties { u8 layout; - s8 roomDensity; + s8 roomDensity; // If positive, allow variance. If negative, use exact value of abs(roomDensity). u8 tileset; u8 bgMusic; u8 weather; // Uses the weather constants in weather.h. u8 floorConnectivity; - u8 enemyDensity; + u8 enemyDensity; // Game treats this as signed. See SpawnEnemies in src/dungeon_generation.asm for details. u8 kecleonShopChance; // Percentage chance 0-100% u8 monsterHouseChance; // Percentage chance 0-100% u8 mazeRoomChance; // Percentage chance 0-100% diff --git a/src/dungeon_generation.c b/src/dungeon_generation.c index 8e5a6d298..8e36ec2e1 100644 --- a/src/dungeon_generation.c +++ b/src/dungeon_generation.c @@ -4423,6 +4423,9 @@ static void SpawnEnemies(FloorProperties *floorProps, bool8 isEmptyMonsterHouse) s32 numEnemies, numMonsterHouseEnemies; s32 enemyDensity = floorProps->enemyDensity; + // BUG: Game assumes floorProps->enemyDensity is a signed byte, but in reality it's unsigned. + // Attempting to use a negative density will instead produce a very large positive density up to 255. + // This only matters for unused dungeons, as Deoxys has its own logic despite Meteor Cave having an effective enemy density of 255. if (enemyDensity > 0) { // Positive means value with variance numEnemies = DungeonRandRange(enemyDensity / 2, enemyDensity);