decompile dungeon_generation

This commit is contained in:
DizzyEggg 2024-11-12 12:30:12 +01:00
parent f97df99fdf
commit 102403cd9a
5 changed files with 226 additions and 667 deletions

View File

@ -1,662 +0,0 @@
#include "asm/constants/gba_constants.inc"
#include "asm/macros.inc"
.syntax unified
.text
thumb_func_start GenerateSecondaryStructure
GenerateSecondaryStructure:
push {r4-r7,lr}
mov r7, r10
mov r6, r9
mov r5, r8
push {r5-r7}
sub sp, 0x8
adds r7, r0, 0
movs r0, 0x6
bl DungeonRandInt
subs r0, 0x1
cmp r0, 0x4
bls _0804F6B0
b _0804FBD6
_0804F6B0:
lsls r0, 2
ldr r1, _0804F6BC
adds r0, r1
ldr r0, [r0]
mov pc, r0
.align 2, 0
_0804F6BC: .4byte _0804F6C0
.align 2, 0
_0804F6C0:
.4byte _0804FB24
.4byte _0804FA98
.4byte _0804F9DC
.4byte _0804F826
.4byte _0804F6D4
_0804F6D4:
ldr r1, _0804F70C
ldr r0, [r1]
cmp r0, 0
bne _0804F6DE
b _0804FBD6
_0804F6DE:
subs r0, 0x1
str r0, [r1]
adds r0, r7, 0
bl SetSpawnFlag5
movs r0, 0x2
bl DungeonRandInt
cmp r0, 0
beq _0804F78E
movs r5, 0
movs r1, 0
ldrsh r0, [r7, r1]
movs r2, 0x4
ldrsh r1, [r7, r2]
adds r0, r1
lsrs r1, r0, 31
adds r0, r1
asrs r0, 1
mov r8, r0
movs r3, 0x2
ldrsh r4, [r7, r3]
b _0804F712
.align 2, 0
_0804F70C: .4byte gUnknown_202F1C8
_0804F710:
adds r4, 0x1
_0804F712:
movs r1, 0x6
ldrsh r0, [r7, r1]
cmp r4, r0
bge _0804F72A
mov r0, r8
adds r1, r4, 0
bl IsNextToHallway
lsls r0, 24
cmp r0, 0
beq _0804F710
movs r5, 0x1
_0804F72A:
cmp r5, 0
beq _0804F730
b _0804FBD6
_0804F730:
movs r2, 0x2
ldrsh r4, [r7, r2]
movs r3, 0x6
ldrsh r0, [r7, r3]
cmp r4, r0
bge _0804F754
_0804F73C:
mov r0, r8
adds r1, r4, 0
bl GetTileSafe
movs r1, 0
bl sub_804F5C4
adds r4, 0x1
movs r5, 0x6
ldrsh r0, [r7, r5]
cmp r4, r0
blt _0804F73C
_0804F754:
movs r0, 0
ldrsh r5, [r7, r0]
cmp r5, r8
blt _0804F75E
b _0804FBD2
_0804F75E:
movs r1, 0x2
ldrsh r4, [r7, r1]
movs r2, 0x6
ldrsh r0, [r7, r2]
adds r6, r5, 0x1
cmp r4, r0
bge _0804F786
_0804F76C:
adds r0, r5, 0
adds r1, r4, 0
bl GetTileSafe
ldrh r2, [r0]
movs r1, 0x80
orrs r1, r2
strh r1, [r0]
adds r4, 0x1
movs r3, 0x6
ldrsh r0, [r7, r3]
cmp r4, r0
blt _0804F76C
_0804F786:
adds r5, r6, 0
cmp r5, r8
blt _0804F75E
b _0804FBD2
_0804F78E:
movs r5, 0
movs r4, 0x2
ldrsh r0, [r7, r4]
movs r2, 0x6
ldrsh r1, [r7, r2]
adds r0, r1
lsrs r1, r0, 31
adds r0, r1
asrs r0, 1
mov r8, r0
movs r3, 0
ldrsh r4, [r7, r3]
b _0804F7AA
_0804F7A8:
adds r4, 0x1
_0804F7AA:
movs r1, 0x4
ldrsh r0, [r7, r1]
cmp r4, r0
bge _0804F7C2
adds r0, r4, 0
mov r1, r8
bl IsNextToHallway
lsls r0, 24
cmp r0, 0
beq _0804F7A8
movs r5, 0x1
_0804F7C2:
cmp r5, 0
beq _0804F7C8
b _0804FBD6
_0804F7C8:
movs r2, 0
ldrsh r4, [r7, r2]
movs r3, 0x4
ldrsh r0, [r7, r3]
cmp r4, r0
bge _0804F7EC
_0804F7D4:
adds r0, r4, 0
mov r1, r8
bl GetTileSafe
movs r1, 0
bl sub_804F5C4
adds r4, 0x1
movs r5, 0x4
ldrsh r0, [r7, r5]
cmp r4, r0
blt _0804F7D4
_0804F7EC:
movs r0, 0x2
ldrsh r5, [r7, r0]
cmp r5, r8
blt _0804F7F6
b _0804FBD2
_0804F7F6:
movs r1, 0
ldrsh r4, [r7, r1]
movs r2, 0x4
ldrsh r0, [r7, r2]
adds r6, r5, 0x1
cmp r4, r0
bge _0804F81E
_0804F804:
adds r0, r4, 0
adds r1, r5, 0
bl GetTileSafe
ldrh r2, [r0]
movs r1, 0x80
orrs r1, r2
strh r1, [r0]
adds r4, 0x1
movs r3, 0x4
ldrsh r0, [r7, r3]
cmp r4, r0
blt _0804F804
_0804F81E:
adds r5, r6, 0
cmp r5, r8
blt _0804F7F6
b _0804FBD2
_0804F826:
movs r4, 0x4
ldrsh r3, [r7, r4]
movs r5, 0
ldrsh r1, [r7, r5]
subs r0, r3, r1
cmp r0, 0x5
bgt _0804F836
b _0804FBD6
_0804F836:
movs r0, 0x6
ldrsh r4, [r7, r0]
movs r5, 0x2
ldrsh r2, [r7, r5]
subs r0, r4, r2
cmp r0, 0x5
bgt _0804F846
b _0804FBD6
_0804F846:
adds r0, r1, r3
lsrs r1, r0, 31
adds r0, r1
asrs r0, 1
str r0, [sp]
adds r0, r2, r4
lsrs r1, r0, 31
adds r0, r1
asrs r0, 1
str r0, [sp, 0x4]
ldr r1, _0804F9D8
ldr r0, [r1]
cmp r0, 0
bne _0804F864
b _0804FBD6
_0804F864:
subs r0, 0x1
str r0, [r1]
adds r0, r7, 0
bl SetSpawnFlag5
ldr r5, [sp]
subs r5, 0x2
ldr r0, [sp, 0x4]
subs r0, 0x2
mov r10, r0
adds r0, r5, 0
mov r1, r10
bl GetTileSafe
movs r1, 0x4
bl sub_804F5C4
ldr r1, [sp]
subs r1, 0x1
mov r9, r1
mov r0, r9
mov r1, r10
bl GetTileSafe
movs r1, 0x4
bl sub_804F5C4
ldr r0, [sp]
mov r1, r10
bl GetTileSafe
movs r1, 0x4
bl sub_804F5C4
ldr r2, [sp]
adds r2, 0x1
mov r8, r2
mov r0, r8
mov r1, r10
bl GetTileSafe
movs r1, 0x4
bl sub_804F5C4
ldr r6, [sp, 0x4]
subs r6, 0x1
adds r0, r5, 0
adds r1, r6, 0
bl GetTileSafe
movs r1, 0x4
bl sub_804F5C4
adds r0, r5, 0
ldr r1, [sp, 0x4]
bl GetTileSafe
movs r1, 0x4
bl sub_804F5C4
ldr r4, [sp, 0x4]
adds r4, 0x1
adds r0, r5, 0
adds r1, r4, 0
bl GetTileSafe
movs r1, 0x4
bl sub_804F5C4
adds r0, r5, 0
adds r1, r4, 0
bl GetTileSafe
movs r1, 0x4
bl sub_804F5C4
mov r0, r9
adds r1, r4, 0
bl GetTileSafe
movs r1, 0x4
bl sub_804F5C4
ldr r0, [sp]
adds r1, r4, 0
bl GetTileSafe
movs r1, 0x4
bl sub_804F5C4
mov r0, r8
mov r1, r10
bl GetTileSafe
movs r1, 0x4
bl sub_804F5C4
mov r0, r8
adds r1, r6, 0
bl GetTileSafe
movs r1, 0x4
bl sub_804F5C4
mov r0, r8
ldr r1, [sp, 0x4]
bl GetTileSafe
movs r1, 0x4
bl sub_804F5C4
mov r0, r8
adds r1, r4, 0
bl GetTileSafe
movs r1, 0x4
bl sub_804F5C4
mov r0, r9
adds r1, r6, 0
bl GetTileSafe
ldrh r2, [r0, 0x4]
movs r1, 0x4
orrs r1, r2
strh r1, [r0, 0x4]
mov r0, r9
adds r1, r6, 0
bl GetTileSafe
ldrh r1, [r0, 0x4]
movs r2, 0x40
orrs r1, r2
strh r1, [r0, 0x4]
ldr r0, [sp]
adds r1, r6, 0
bl GetTileSafe
ldrh r1, [r0, 0x4]
movs r4, 0x2
orrs r1, r4
strh r1, [r0, 0x4]
mov r0, r9
ldr r1, [sp, 0x4]
bl GetTileSafe
ldrh r1, [r0, 0x4]
orrs r1, r4
strh r1, [r0, 0x4]
ldr r0, [sp]
ldr r1, [sp, 0x4]
bl GetTileSafe
ldrh r1, [r0, 0x4]
orrs r1, r4
strh r1, [r0, 0x4]
mov r0, r9
adds r1, r6, 0
bl GetTileSafe
ldrh r1, [r0, 0x4]
movs r4, 0x10
orrs r1, r4
strh r1, [r0, 0x4]
ldr r0, [sp]
adds r1, r6, 0
bl GetTileSafe
ldrh r1, [r0, 0x4]
orrs r1, r4
strh r1, [r0, 0x4]
mov r0, r9
ldr r1, [sp, 0x4]
bl GetTileSafe
ldrh r1, [r0, 0x4]
orrs r1, r4
strh r1, [r0, 0x4]
ldr r0, [sp]
ldr r1, [sp, 0x4]
bl GetTileSafe
ldrh r1, [r0, 0x4]
orrs r4, r1
strh r4, [r0, 0x4]
b _0804FBD2
.align 2, 0
_0804F9D8: .4byte gUnknown_202F1C8
_0804F9DC:
movs r4, 0x4
ldrsh r3, [r7, r4]
movs r5, 0
ldrsh r2, [r7, r5]
subs r0, r3, r2
cmp r0, 0x4
bgt _0804F9EC
b _0804FBD6
_0804F9EC:
movs r1, 0x6
ldrsh r0, [r7, r1]
movs r4, 0x2
ldrsh r1, [r7, r4]
subs r0, r1
cmp r0, 0x4
bgt _0804F9FC
b _0804FBD6
_0804F9FC:
adds r0, r2, 0x2
subs r1, r3, 0x3
bl DungeonRandRange
adds r4, r0, 0
movs r5, 0x2
ldrsh r0, [r7, r5]
adds r0, 0x2
movs r2, 0x6
ldrsh r1, [r7, r2]
subs r1, 0x3
bl DungeonRandRange
mov r10, r0
movs r3, 0
ldrsh r0, [r7, r3]
adds r0, 0x2
movs r5, 0x4
ldrsh r1, [r7, r5]
subs r1, 0x3
bl DungeonRandRange
mov r9, r0
movs r1, 0x2
ldrsh r0, [r7, r1]
adds r0, 0x2
movs r2, 0x6
ldrsh r1, [r7, r2]
subs r1, 0x3
bl DungeonRandRange
adds r6, r0, 0
ldr r1, _0804FA94
ldr r0, [r1]
cmp r0, 0
bne _0804FA46
b _0804FBD6
_0804FA46:
subs r0, 0x1
str r0, [r1]
adds r0, r7, 0
bl SetSpawnFlag5
cmp r4, r9
ble _0804FA5A
adds r0, r4, 0
mov r4, r9
mov r9, r0
_0804FA5A:
cmp r10, r6
ble _0804FA64
mov r0, r10
mov r10, r6
adds r6, r0, 0
_0804FA64:
adds r5, r4, 0
cmp r5, r9
ble _0804FA6C
b _0804FBD2
_0804FA6C:
mov r4, r10
adds r3, r5, 0x1
mov r8, r3
cmp r4, r6
bgt _0804FA8A
_0804FA76:
adds r0, r5, 0
adds r1, r4, 0
bl GetTileSafe
movs r1, 0
bl sub_804F5C4
adds r4, 0x1
cmp r4, r6
ble _0804FA76
_0804FA8A:
mov r5, r8
cmp r5, r9
ble _0804FA6C
b _0804FBD2
.align 2, 0
_0804FA94: .4byte gUnknown_202F1C8
_0804FA98:
movs r4, 0x4
ldrsh r0, [r7, r4]
movs r5, 0
ldrsh r1, [r7, r5]
subs r0, r1
movs r2, 0x1
ands r0, r2
cmp r0, 0
bne _0804FAAC
b _0804FBD6
_0804FAAC:
movs r1, 0x6
ldrsh r0, [r7, r1]
movs r3, 0x2
ldrsh r1, [r7, r3]
subs r0, r1
ands r0, r2
cmp r0, 0
bne _0804FABE
b _0804FBD6
_0804FABE:
ldr r1, _0804FB20
ldr r0, [r1]
cmp r0, 0
bne _0804FAC8
b _0804FBD6
_0804FAC8:
subs r0, 0x1
str r0, [r1]
adds r0, r7, 0
bl SetSpawnFlag5
movs r6, 0x3F
_0804FAD4:
movs r4, 0x4
ldrsh r0, [r7, r4]
movs r5, 0
ldrsh r1, [r7, r5]
subs r0, r1
bl DungeonRandInt
adds r4, r0, 0
movs r1, 0x6
ldrsh r0, [r7, r1]
movs r2, 0x2
ldrsh r1, [r7, r2]
subs r0, r1
bl DungeonRandInt
adds r2, r0, 0
adds r0, r4, r2
movs r5, 0x1
ands r0, r5
cmp r0, 0
beq _0804FB14
movs r3, 0
ldrsh r0, [r7, r3]
adds r0, r4
movs r4, 0x2
ldrsh r1, [r7, r4]
adds r1, r2
bl GetTileSafe
movs r1, 0
bl sub_804F5C4
_0804FB14:
subs r6, 0x1
cmp r6, 0
bge _0804FAD4
strb r5, [r7, 0x9]
b _0804FBD6
.align 2, 0
_0804FB20: .4byte gUnknown_202F1C8
_0804FB24:
ldr r1, _0804FBC0
ldr r0, [r1]
cmp r0, 0
beq _0804FBD6
subs r0, 0x1
str r0, [r1]
movs r5, 0x4
ldrsh r3, [r7, r5]
movs r0, 0
ldrsh r2, [r7, r0]
subs r6, r3, r2
movs r4, 0x1
adds r0, r6, 0
ands r0, r4
cmp r0, 0
beq _0804FB54
movs r1, 0x6
ldrsh r0, [r7, r1]
movs r5, 0x2
ldrsh r1, [r7, r5]
subs r0, r1
ands r0, r4
cmp r0, 0
bne _0804FBC4
_0804FB54:
adds r0, r2, r3
lsrs r1, r0, 31
adds r0, r1
asrs r5, r0, 1
movs r0, 0x2
ldrsh r3, [r7, r0]
movs r1, 0x6
ldrsh r2, [r7, r1]
adds r0, r3, r2
lsrs r1, r0, 31
adds r0, r1
asrs r4, r0, 1
cmp r6, 0x4
ble _0804FBAE
subs r0, r2, r3
cmp r0, 0x4
ble _0804FBAE
adds r0, r5, 0x1
adds r1, r4, 0
bl GetTileSafe
movs r1, 0
bl sub_804F5C4
adds r1, r4, 0x1
adds r0, r5, 0
bl GetTileSafe
movs r1, 0
bl sub_804F5C4
subs r0, r5, 0x1
adds r1, r4, 0
bl GetTileSafe
movs r1, 0
bl sub_804F5C4
subs r1, r4, 0x1
adds r0, r5, 0
bl GetTileSafe
movs r1, 0
bl sub_804F5C4
_0804FBAE:
adds r0, r5, 0
adds r1, r4, 0
bl GetTileSafe
movs r1, 0
bl sub_804F5C4
b _0804FBD2
.align 2, 0
_0804FBC0: .4byte gUnknown_202F1C8
_0804FBC4:
adds r0, r7, 0
bl SetSpawnFlag5
adds r0, r7, 0
movs r1, 0x1
bl GenerateMaze
_0804FBD2:
movs r0, 0x1
strb r0, [r7, 0x9]
_0804FBD6:
add sp, 0x8
pop {r3-r5}
mov r8, r3
mov r9, r4
mov r10, r5
pop {r4-r7}
pop {r0}
bx r0
thumb_func_end GenerateSecondaryStructure
.align 2,0

View File

@ -15,4 +15,15 @@ enum FloorType {
FLOOR_TYPE_RESCUE, // Rescuing another player
};
// Helper type used to make explicit the possible secondary structures which can be randomly rolled to generate in the dungeon algorithm.
enum SecondaryStructureType {
SECONDARY_STRUCTURE_NONE, // No secondary structure will be generated.
SECONDARY_STRUCTURE_MAZE_PLUS_DOT, // One of 3 secondary structures depending on the dimensions of the room. If the room has odd dimensions, the result is a maze room. Otherwise, if the room has dimensions of at least `5x5`, a cross or plus pattern is made instead. If both fail, a single tile of secondary terrain will be placed in the center of the room.
SECONDARY_STRUCTURE_CHECKERBOARD, // If the room has odd dimensions, a checkerboard pattern made of randomly placed diagonal stripes of secondary terrain will be generated. If not, no secondary structure will be generated.
SECONDARY_STRUCTURE_POOL, // If the room has dimensions of at least `5x5`, a rectangular pool of secondary terrain will be generated. If not, no secondary structure will be generated.
SECONDARY_STRUCTURE_ISLAND, // If the room has dimensions of at least `6x6`, an island of items and a warp tile surrounded by secondary terrain will be generated. If not, no secondary structure will be generated.
SECONDARY_STRUCTURE_DIVIDER, // A "divider" of secondary terrain will split the room in half randomly either horizontally or vertically.
};
#endif

View File

@ -18,6 +18,7 @@ enum TerrainType
TERRAIN_TYPE_IMPASSABLE_WALL = 1 << 4, // x10
TERRAIN_TYPE_SHOP = 1 << 5, // x20
TERRAIN_TYPE_IN_MONSTER_HOUSE = 1 << 6, // x40
TERRAIN_TYPE_UNK_7 = 1 << 7, // x80
TERRAIN_TYPE_UNK_8 = 1 << 8, // x100
TERRAIN_TYPE_STAIRS = 1 << 9, // x200
TERRAIN_TYPE_UNK_x400 = 1 << 10,

View File

@ -228,8 +228,7 @@ SECTIONS {
src/dungeon_ai_item_weight.o(.text);
src/dungeon_map_access.o(.text);
src/tile_types.o(.text);
src/code_804AFAC_1.o(.text);
asm/code_804AFAC.o(.text);
src/dungeon_generation.o(.text);
src/code_804AFAC.o(.text);
asm/code_804FD30.o(.text);
src/dungeon_message.o(.text);

View File

@ -2315,6 +2315,19 @@ void CreateRoomsAndAnchors(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s
}
}
/*
* GenerateSecondaryStructures - Attempt to generate secondary structures in flagged rooms.
*
* For a valid flagged room with no extra features, one of the following will attempt to generate:
* 0. No Secondary Structure
* 1. A maze (made of water/lava walls), or a "plus" sign fallback, or a single dot in the center fallback
* 2. Checkerboard pattern of water/lava
* 3. A central pool in the room made of water/lava
* 4. A central island with items and a warp tile, surrounded by water/lava
* 5. A horizontal or vertical line of water/lava splitting the room in two.
*
* If a room doesn't meet the conditions for the secondary structure chosen, it will be left unchanged.
*/
void GenerateSecondaryStructures(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY)
{
s32 x, y;
@ -4177,16 +4190,17 @@ void GenerateMazeLine(s32 x0, s32 y0, s32 xMin, s32 yMin, s32 xMax, s32 yMax, bo
}
}
void sub_804F5C4(Tile *tile, u32 terrainFlag)
void SetTerrainSecondaryWithFlag(Tile *tile, u32 additionalFlag)
{
SetTerrainSecondary(tile);
tile->terrainType |= terrainFlag;
tile->terrainType |= additionalFlag;
}
/*
* SetSpawnFlag5 - Sets unknown spawn flag 0x5 on all tiles in a room
*/
void SetSpawnFlag5(struct GridCell *gridCell) {
void SetSpawnFlag5(struct GridCell *gridCell)
{
s32 x, y;
for (x = gridCell->start.x; x < gridCell->end.x; x++) {
@ -4228,4 +4242,200 @@ bool8 IsNextToHallway(s32 x, s32 y)
return FALSE;
}
// See GenerateSecondaryStructures for more information.
void GenerateSecondaryStructure(struct GridCell *gridCell)
{
switch (DungeonRandInt(6)) {
// Generate a "split room" with two sides separated by a line of water/lava
case SECONDARY_STRUCTURE_DIVIDER:
if (gUnknown_202F1C8 != 0) {
s32 i;
gUnknown_202F1C8--;
SetSpawnFlag5(gridCell);
if (DungeonRandInt(2) != 0) {
// Split the room with a vertical line
s32 curX, curY;
bool8 invalid = FALSE;
s32 middleX = (gridCell->start.x + gridCell->end.x) / 2;
for (i = gridCell->start.y; i < gridCell->end.y; i++) {
if (IsNextToHallway(middleX, i)) {
invalid = TRUE;
break;
}
}
if (!invalid) {
for (i = gridCell->start.y; i < gridCell->end.y; i++) {
SetTerrainSecondaryWithFlag(GetTileSafe(middleX, i), 0);
}
for (curX = gridCell->start.x; curX < middleX; curX++) {
for (curY = gridCell->start.y; curY < gridCell->end.y; curY++) {
GetTileSafe(curX, curY)->terrainType |= TERRAIN_TYPE_UNK_7;
}
}
gridCell->hasSecondaryStructure = TRUE;
}
}
else {
// Split the room with a horizontal line
s32 curX, curY;
bool8 invalid = FALSE;
s32 middleY = (gridCell->start.y + gridCell->end.y) / 2;
for (i = gridCell->start.x; i < gridCell->end.x; i++) {
if (IsNextToHallway(i, middleY)) {
invalid = TRUE;
break;
}
}
if (!invalid) {
for (i = gridCell->start.x; i < gridCell->end.x; i++) {
SetTerrainSecondaryWithFlag(GetTileSafe(i, middleY), 0);
}
for (curY = gridCell->start.y; curY < middleY; curY++) {
for (curX = gridCell->start.x; curX < gridCell->end.x; curX++) {
GetTileSafe(curX, curY)->terrainType |= TERRAIN_TYPE_UNK_7;
}
}
gridCell->hasSecondaryStructure = TRUE;
}
}
}
break;
case SECONDARY_STRUCTURE_ISLAND:
if ((gridCell->end.x - gridCell->start.x) >= 6 && (gridCell->end.y - gridCell->start.y) >= 6) {
s32 middleX = (gridCell->start.x + gridCell->end.x) / 2;
s32 middleY = (gridCell->start.y + gridCell->end.y) / 2;
// Both dimensions are at least 6. Generate an "island" with lava, items, and a Warp Tile at the center
if (gUnknown_202F1C8 != 0) {
gUnknown_202F1C8--;
SetSpawnFlag5(gridCell);
// Water "Moat"
SetTerrainSecondaryWithFlag(GetTileSafe(middleX - 2, middleY - 2), TERRAIN_TYPE_UNK_2);
SetTerrainSecondaryWithFlag(GetTileSafe(middleX - 1, middleY - 2), TERRAIN_TYPE_UNK_2);
SetTerrainSecondaryWithFlag(GetTileSafe(middleX, middleY - 2), TERRAIN_TYPE_UNK_2);
SetTerrainSecondaryWithFlag(GetTileSafe(middleX + 1, middleY - 2), TERRAIN_TYPE_UNK_2);
SetTerrainSecondaryWithFlag(GetTileSafe(middleX - 2, middleY - 1), TERRAIN_TYPE_UNK_2);
SetTerrainSecondaryWithFlag(GetTileSafe(middleX - 2, middleY), TERRAIN_TYPE_UNK_2);
SetTerrainSecondaryWithFlag(GetTileSafe(middleX - 2, middleY + 1), TERRAIN_TYPE_UNK_2);
SetTerrainSecondaryWithFlag(GetTileSafe(middleX - 2, middleY + 1), TERRAIN_TYPE_UNK_2);
SetTerrainSecondaryWithFlag(GetTileSafe(middleX - 1, middleY + 1), TERRAIN_TYPE_UNK_2);
SetTerrainSecondaryWithFlag(GetTileSafe(middleX, middleY + 1), TERRAIN_TYPE_UNK_2);
SetTerrainSecondaryWithFlag(GetTileSafe(middleX + 1, middleY - 2), TERRAIN_TYPE_UNK_2);
SetTerrainSecondaryWithFlag(GetTileSafe(middleX + 1, middleY - 1), TERRAIN_TYPE_UNK_2);
SetTerrainSecondaryWithFlag(GetTileSafe(middleX + 1, middleY), TERRAIN_TYPE_UNK_2);
SetTerrainSecondaryWithFlag(GetTileSafe(middleX + 1, middleY + 1), TERRAIN_TYPE_UNK_2);
// Warp Tile ?
GetTileSafe(middleX - 1, middleY - 1)->unk4 |= 0x4;
GetTileSafe(middleX - 1, middleY - 1)->unk4 |= 0x40;
// Items ?
GetTileSafe(middleX, middleY - 1)->unk4 |= 0x2;
GetTileSafe(middleX - 1, middleY)->unk4 |= 0x2;
GetTileSafe(middleX, middleY)->unk4 |= 0x2;
GetTileSafe(middleX - 1, middleY - 1)->unk4 |= 0x10;
GetTileSafe(middleX, middleY - 1)->unk4 |= 0x10;
GetTileSafe(middleX - 1, middleY)->unk4 |= 0x10;
GetTileSafe(middleX, middleY)->unk4 |= 0x10;
gridCell->hasSecondaryStructure = TRUE;
}
}
break;
case SECONDARY_STRUCTURE_POOL:
if ((gridCell->end.x - gridCell->start.x) >= 5 && (gridCell->end.y - gridCell->start.y) >= 5) {
s32 curX, curY;
// Both dimensions are at least 5, generate a "pool" of water/lava
s32 randX1 = DungeonRandRange(gridCell->start.x + 2, gridCell->end.x - 3);
s32 randY1 = DungeonRandRange(gridCell->start.y + 2, gridCell->end.y - 3);
s32 randX2 = DungeonRandRange(gridCell->start.x + 2, gridCell->end.x - 3);
s32 randY2 = DungeonRandRange(gridCell->start.y + 2, gridCell->end.y - 3);
if (gUnknown_202F1C8 != 0) {
gUnknown_202F1C8--;
SetSpawnFlag5(gridCell);
if (randX1 > randX2) {
s32 temp;
SWAP(randX1, randX2, temp);
}
if (randY1 > randY2) {
s32 temp;
SWAP(randY1, randY2, temp);
}
for (curX = randX1; curX <= randX2; curX++) {
for (curY = randY1; curY <= randY2; curY++) {
SetTerrainSecondaryWithFlag(GetTileSafe(curX, curY), 0);
}
}
gridCell->hasSecondaryStructure = TRUE;
}
}
break;
case SECONDARY_STRUCTURE_CHECKERBOARD:
if ((gridCell->end.x - gridCell->start.x) % 2 != 0 && (gridCell->end.y - gridCell->start.y) % 2 != 0 && gUnknown_202F1C8 != 0) {
s32 i;
// Dimensions are odd, generate diagonal stripes/checkerboard of water/lava
gUnknown_202F1C8--;
SetSpawnFlag5(gridCell);
for (i = 0; i < 64; i++) {
s32 randX = DungeonRandInt(gridCell->end.x - gridCell->start.x);
s32 randY = DungeonRandInt(gridCell->end.y - gridCell->start.y);
if ((randX + randY) % 2 != 0) {
SetTerrainSecondaryWithFlag(GetTileSafe(gridCell->start.x + randX, gridCell->start.y + randY), 0);
}
}
gridCell->hasSecondaryStructure = TRUE;
}
break;
case SECONDARY_STRUCTURE_MAZE_PLUS_DOT:
if (gUnknown_202F1C8 != 0) {
gUnknown_202F1C8--;
// If the dimensions are odd, generate a maze room
if ((gridCell->end.x - gridCell->start.x) % 2 == 0 || (gridCell->end.y - gridCell->start.y) % 2 == 0) {
s32 middleX = (gridCell->start.x + gridCell->end.x) / 2;
s32 middleY = (gridCell->start.y + gridCell->end.y) / 2;
if ((gridCell->end.x - gridCell->start.x) >= 5 && (gridCell->end.y - gridCell->start.y) >= 5) {
// Both dimensions are at least 5, generate a water/lava cross in the center
SetTerrainSecondaryWithFlag(GetTileSafe(middleX + 1, middleY), 0);
SetTerrainSecondaryWithFlag(GetTileSafe(middleX, middleY + 1), 0);
SetTerrainSecondaryWithFlag(GetTileSafe(middleX - 1, middleY), 0);
SetTerrainSecondaryWithFlag(GetTileSafe(middleX, middleY - 1), 0);
}
// Generate a single water/lava spot in the center
SetTerrainSecondaryWithFlag(GetTileSafe(middleX, middleY), 0);
}
else {
// Both dimensions are odd. Generate a maze room
SetSpawnFlag5(gridCell);
GenerateMaze(gridCell, TRUE);
}
gridCell->hasSecondaryStructure = TRUE;
}
break;
}
}
//