IsNextToHallway

This commit is contained in:
DizzyEggg 2024-11-12 10:14:06 +01:00
parent 366690ced9
commit f97df99fdf
2 changed files with 356 additions and 798 deletions

View File

@ -5,792 +5,7 @@
.text
thumb_func_start GenerateMazeRoom
GenerateMazeRoom:
push {r4-r7,lr}
mov r7, r10
mov r6, r9
mov r5, r8
push {r5-r7}
sub sp, 0x104
str r0, [sp, 0x100]
mov r10, r1
mov r9, r2
adds r4, r3, 0
ldr r0, _0804F244
ldr r5, [r0]
cmp r4, 0
bne _0804F0EE
b _0804F266
_0804F0EE:
movs r0, 0x64
bl DungeonRandInt
cmp r4, r0
bgt _0804F0FA
b _0804F266
_0804F0FA:
ldr r1, _0804F248
adds r0, r5, r1
movs r3, 0
ldrsh r0, [r0, r3]
cmp r0, 0
blt _0804F108
b _0804F266
_0804F108:
movs r5, 0
movs r6, 0
cmp r6, r10
bge _0804F184
_0804F110:
adds r7, r6, 0x1
mov r4, r9
cmp r4, 0
ble _0804F17E
lsls r0, r6, 4
subs r0, r6
lsls r0, 5
ldr r6, [sp, 0x100]
adds r2, r0, r6
_0804F122:
ldrb r0, [r2, 0x8]
cmp r0, 0
bne _0804F176
ldrb r0, [r2, 0x11]
cmp r0, 0
bne _0804F176
ldrb r0, [r2, 0xB]
cmp r0, 0
beq _0804F176
ldrb r0, [r2, 0xA]
cmp r0, 0
beq _0804F176
ldrb r0, [r2, 0xC]
cmp r0, 0
bne _0804F176
ldrb r0, [r2, 0xF]
cmp r0, 0
bne _0804F176
ldrb r0, [r2, 0xE]
cmp r0, 0
bne _0804F176
ldrb r0, [r2, 0x9]
cmp r0, 0
bne _0804F176
movs r1, 0x4
ldrsh r0, [r2, r1]
movs r3, 0
ldrsh r1, [r2, r3]
subs r0, r1
movs r3, 0x1
ands r0, r3
cmp r0, 0
beq _0804F176
movs r6, 0x6
ldrsh r0, [r2, r6]
movs r6, 0x2
ldrsh r1, [r2, r6]
subs r0, r1
ands r0, r3
cmp r0, 0
beq _0804F176
adds r5, 0x1
_0804F176:
adds r2, 0x20
subs r4, 0x1
cmp r4, 0
bne _0804F122
_0804F17E:
adds r6, r7, 0
cmp r6, r10
blt _0804F110
_0804F184:
cmp r5, 0
beq _0804F266
movs r1, 0
mov r0, sp
adds r0, 0xFF
_0804F18E:
strb r1, [r0]
subs r0, 0x1
cmp r0, sp
bge _0804F18E
mov r1, sp
movs r0, 0x1
strb r0, [r1]
movs r7, 0x3F
mov r8, r7
_0804F1A0:
adds r0, r5, 0
bl DungeonRandInt
adds r4, r0, 0
adds r0, r5, 0
bl DungeonRandInt
mov r1, sp
adds r2, r1, r4
ldrb r3, [r2]
adds r1, r0
ldrb r0, [r1]
strb r0, [r2]
strb r3, [r1]
movs r3, 0x1
negs r3, r3
add r8, r3
mov r4, r8
cmp r4, 0
bge _0804F1A0
movs r6, 0
mov r8, r6
cmp r6, r10
bge _0804F266
ldr r7, [sp, 0x100]
mov r12, r7
_0804F1D4:
movs r4, 0
cmp r4, r9
bge _0804F25A
mov r2, r12
mov r5, r12
_0804F1DE:
ldrb r0, [r2, 0x8]
cmp r0, 0
bne _0804F250
ldrb r0, [r2, 0x11]
cmp r0, 0
bne _0804F250
ldrb r0, [r2, 0xB]
cmp r0, 0
beq _0804F250
ldrb r0, [r2, 0xA]
cmp r0, 0
beq _0804F250
ldrb r0, [r2, 0xC]
cmp r0, 0
bne _0804F250
ldrb r0, [r2, 0xF]
cmp r0, 0
bne _0804F250
ldrb r0, [r2, 0xE]
cmp r0, 0
bne _0804F250
ldrb r0, [r2, 0x9]
cmp r0, 0
bne _0804F250
movs r1, 0x4
ldrsh r0, [r2, r1]
movs r3, 0
ldrsh r1, [r2, r3]
subs r0, r1
movs r3, 0x1
ands r0, r3
cmp r0, 0
beq _0804F250
movs r7, 0x6
ldrsh r0, [r2, r7]
movs r7, 0x2
ldrsh r1, [r2, r7]
subs r0, r1
ands r0, r3
cmp r0, 0
beq _0804F250
mov r0, sp
add r0, r8
ldrb r0, [r0]
cmp r0, 0
beq _0804F24C
adds r0, r5, 0
movs r1, 0
bl sub_804F278
b _0804F266
.align 2, 0
_0804F244: .4byte gDungeon
_0804F248: .4byte 0x00003a16
_0804F24C:
movs r0, 0x1
add r8, r0
_0804F250:
adds r2, 0x20
adds r5, 0x20
adds r4, 0x1
cmp r4, r9
blt _0804F1DE
_0804F25A:
movs r1, 0xF0
lsls r1, 1
add r12, r1
adds r6, 0x1
cmp r6, r10
blt _0804F1D4
_0804F266:
add sp, 0x104
pop {r3-r5}
mov r8, r3
mov r9, r4
mov r10, r5
pop {r4-r7}
pop {r0}
bx r0
thumb_func_end GenerateMazeRoom
thumb_func_start sub_804F278
sub_804F278:
push {r4-r7,lr}
mov r7, r10
mov r6, r9
mov r5, r8
push {r5-r7}
sub sp, 0x10
adds r4, r0, 0
lsls r1, 24
lsrs r1, 24
mov r8, r1
ldr r1, _0804F2B0
movs r0, 0x1
strb r0, [r1]
movs r0, 0x1
strb r0, [r4, 0x10]
movs r1, 0
ldrsh r0, [r4, r1]
movs r2, 0x2
ldrsh r1, [r4, r2]
bl GetTile
ldrb r0, [r0, 0x9]
mov r9, r0
movs r5, 0
ldrsh r0, [r4, r5]
adds r6, r0, 0x1
b _0804F2F0
.align 2, 0
_0804F2B0: .4byte gUnknown_202F1AC
_0804F2B4:
movs r2, 0x2
ldrsh r1, [r4, r2]
subs r1, 0x1
adds r0, r6, 0
bl GetTile
ldrh r1, [r0]
movs r0, 0x3
ands r0, r1
cmp r0, 0x1
beq _0804F2EE
movs r5, 0x2
ldrsh r3, [r4, r5]
subs r1, r3, 0x1
movs r0, 0
ldrsh r2, [r4, r0]
movs r5, 0x4
ldrsh r0, [r4, r5]
str r0, [sp]
movs r5, 0x6
ldrsh r0, [r4, r5]
str r0, [sp, 0x4]
mov r0, r8
str r0, [sp, 0x8]
mov r5, r9
str r5, [sp, 0xC]
adds r0, r6, 0
bl sub_804F494
_0804F2EE:
adds r6, 0x2
_0804F2F0:
movs r1, 0x4
ldrsh r0, [r4, r1]
subs r0, 0x1
cmp r6, r0
blt _0804F2B4
movs r2, 0x2
ldrsh r0, [r4, r2]
adds r5, r0, 0x1
movs r6, 0x6
ldrsh r0, [r4, r6]
b _0804F342
_0804F306:
movs r1, 0x4
ldrsh r0, [r4, r1]
adds r1, r5, 0
bl GetTile
ldrh r1, [r0]
movs r0, 0x3
ands r0, r1
cmp r0, 0x1
beq _0804F33C
movs r2, 0x4
ldrsh r0, [r4, r2]
movs r6, 0
ldrsh r2, [r4, r6]
movs r1, 0x2
ldrsh r3, [r4, r1]
str r0, [sp]
movs r6, 0x6
ldrsh r1, [r4, r6]
str r1, [sp, 0x4]
mov r1, r8
str r1, [sp, 0x8]
mov r6, r9
str r6, [sp, 0xC]
adds r1, r5, 0
bl sub_804F494
_0804F33C:
adds r5, 0x2
movs r1, 0x6
ldrsh r0, [r4, r1]
_0804F342:
subs r0, 0x1
cmp r5, r0
blt _0804F306
movs r2, 0
ldrsh r0, [r4, r2]
adds r6, r0, 0x1
movs r5, 0x4
ldrsh r0, [r4, r5]
b _0804F392
_0804F354:
movs r0, 0x6
ldrsh r1, [r4, r0]
adds r0, r6, 0
bl GetTile
ldrh r1, [r0]
movs r0, 0x3
ands r0, r1
cmp r0, 0x1
beq _0804F38C
movs r2, 0x6
ldrsh r1, [r4, r2]
movs r5, 0
ldrsh r2, [r4, r5]
movs r0, 0x2
ldrsh r3, [r4, r0]
movs r5, 0x4
ldrsh r0, [r4, r5]
str r0, [sp]
adds r0, r1, 0
str r0, [sp, 0x4]
mov r0, r8
str r0, [sp, 0x8]
mov r5, r9
str r5, [sp, 0xC]
adds r0, r6, 0
bl sub_804F494
_0804F38C:
adds r6, 0x2
movs r1, 0x4
ldrsh r0, [r4, r1]
_0804F392:
subs r0, 0x1
cmp r6, r0
blt _0804F354
movs r2, 0x2
ldrsh r0, [r4, r2]
adds r5, r0, 0x1
movs r6, 0x6
ldrsh r0, [r4, r6]
b _0804F3E4
_0804F3A4:
movs r1, 0
ldrsh r0, [r4, r1]
subs r0, 0x1
adds r1, r5, 0
bl GetTile
ldrh r1, [r0]
movs r0, 0x3
ands r0, r1
cmp r0, 0x1
beq _0804F3DE
movs r6, 0
ldrsh r2, [r4, r6]
subs r0, r2, 0x1
movs r1, 0x2
ldrsh r3, [r4, r1]
movs r6, 0x4
ldrsh r1, [r4, r6]
str r1, [sp]
movs r6, 0x6
ldrsh r1, [r4, r6]
str r1, [sp, 0x4]
mov r1, r8
str r1, [sp, 0x8]
mov r6, r9
str r6, [sp, 0xC]
adds r1, r5, 0
bl sub_804F494
_0804F3DE:
adds r5, 0x2
movs r1, 0x6
ldrsh r0, [r4, r1]
_0804F3E4:
subs r0, 0x1
cmp r5, r0
blt _0804F3A4
movs r2, 0
ldrsh r0, [r4, r2]
adds r6, r0, 0x3
b _0804F478
_0804F3F2:
movs r1, 0x2
ldrsh r0, [r4, r1]
adds r5, r0, 0x3
movs r2, 0x6
ldrsh r0, [r4, r2]
subs r0, 0x3
adds r1, r6, 0x2
mov r10, r1
cmp r5, r0
bge _0804F476
ldr r2, _0804F434
adds r7, r2, 0
_0804F40A:
adds r0, r6, 0
adds r1, r5, 0
bl GetTile
ldrh r1, [r0]
movs r0, 0x3
ands r0, r1
cmp r0, 0x1
bne _0804F46A
mov r0, r8
cmp r0, 0
beq _0804F438
subs r0, r6, 0x1
adds r1, r5, 0
bl GetTileSafe
ldrh r1, [r0]
ands r1, r7
movs r2, 0x2
orrs r1, r2
b _0804F444
.align 2, 0
_0804F434: .4byte 0x0000fffc
_0804F438:
subs r0, r6, 0x1
adds r1, r5, 0
bl GetTileSafe
ldrh r1, [r0]
ands r1, r7
_0804F444:
strh r1, [r0]
movs r1, 0
ldrsh r2, [r4, r1]
movs r0, 0x2
ldrsh r3, [r4, r0]
movs r1, 0x4
ldrsh r0, [r4, r1]
str r0, [sp]
movs r1, 0x6
ldrsh r0, [r4, r1]
str r0, [sp, 0x4]
mov r0, r8
str r0, [sp, 0x8]
mov r1, r9
str r1, [sp, 0xC]
adds r0, r6, 0
adds r1, r5, 0
bl sub_804F494
_0804F46A:
adds r5, 0x2
movs r2, 0x6
ldrsh r0, [r4, r2]
subs r0, 0x3
cmp r5, r0
blt _0804F40A
_0804F476:
mov r6, r10
_0804F478:
movs r5, 0x4
ldrsh r0, [r4, r5]
subs r0, 0x3
cmp r6, r0
blt _0804F3F2
add sp, 0x10
pop {r3-r5}
mov r8, r3
mov r9, r4
mov r10, r5
pop {r4-r7}
pop {r0}
bx r0
thumb_func_end sub_804F278
thumb_func_start sub_804F494
sub_804F494:
push {r4-r7,lr}
mov r7, r10
mov r6, r9
mov r5, r8
push {r5-r7}
sub sp, 0x8
adds r5, r0, 0
adds r4, r1, 0
str r2, [sp]
str r3, [sp, 0x4]
ldr r0, [sp, 0x30]
ldr r1, [sp, 0x34]
lsls r0, 24
lsrs r0, 24
mov r9, r0
lsls r1, 24
mov r8, r1
movs r0, 0x3
mov r10, r0
_0804F4BA:
movs r0, 0x4
bl DungeonRandInt
adds r6, r0, 0
movs r7, 0
adds r0, r5, 0
adds r1, r4, 0
bl GetTileSafe
mov r1, r9
mov r3, r8
lsrs r2, r3, 24
bl SetTerrainObstacleChecked
_0804F4D6:
adds r0, r6, 0
mov r1, r10
ands r0, r1
cmp r0, 0x1
beq _0804F4F6
cmp r0, 0x1
bgt _0804F4EA
cmp r0, 0
beq _0804F4F0
b _0804F506
_0804F4EA:
cmp r0, 0x2
beq _0804F4FE
b _0804F506
_0804F4F0:
movs r0, 0x2
movs r1, 0
b _0804F50A
_0804F4F6:
movs r0, 0
movs r1, 0x2
negs r1, r1
b _0804F50A
_0804F4FE:
movs r0, 0x2
negs r0, r0
movs r1, 0
b _0804F50A
_0804F506:
movs r0, 0
movs r1, 0x2
_0804F50A:
adds r0, r5, r0
ldr r2, [sp]
cmp r2, r0
bgt _0804F534
ldr r3, [sp, 0x28]
cmp r3, r0
ble _0804F534
adds r1, r4, r1
ldr r2, [sp, 0x4]
cmp r2, r1
bgt _0804F534
ldr r3, [sp, 0x2C]
cmp r3, r1
ble _0804F534
bl GetTile
ldrh r1, [r0]
mov r0, r10
ands r0, r1
cmp r0, 0x1
beq _0804F53E
_0804F534:
adds r6, 0x1
adds r7, 0x1
cmp r7, 0x3
bgt _0804F5B2
b _0804F4D6
_0804F53E:
mov r0, r10
ands r0, r6
cmp r0, 0x1
beq _0804F570
cmp r0, 0x1
bgt _0804F550
cmp r0, 0
beq _0804F55A
b _0804F4BA
_0804F550:
cmp r0, 0x2
beq _0804F586
cmp r0, 0x3
beq _0804F59C
b _0804F4BA
_0804F55A:
adds r0, r5, 0x1
adds r1, r4, 0
bl GetTileSafe
mov r1, r9
mov r3, r8
lsrs r2, r3, 24
bl SetTerrainObstacleChecked
adds r5, 0x2
b _0804F4BA
_0804F570:
subs r1, r4, 0x1
adds r0, r5, 0
bl GetTileSafe
mov r1, r9
mov r3, r8
lsrs r2, r3, 24
bl SetTerrainObstacleChecked
subs r4, 0x2
b _0804F4BA
_0804F586:
subs r0, r5, 0x1
adds r1, r4, 0
bl GetTileSafe
mov r1, r9
mov r3, r8
lsrs r2, r3, 24
bl SetTerrainObstacleChecked
subs r5, 0x2
b _0804F4BA
_0804F59C:
adds r1, r4, 0x1
adds r0, r5, 0
bl GetTileSafe
mov r1, r9
mov r3, r8
lsrs r2, r3, 24
bl SetTerrainObstacleChecked
adds r4, 0x2
b _0804F4BA
_0804F5B2:
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 sub_804F494
thumb_func_start sub_804F5C4
sub_804F5C4:
ldrh r3, [r0]
ldr r2, _0804F5D4
ands r2, r3
movs r3, 0x2
orrs r2, r3
orrs r2, r1
strh r2, [r0]
bx lr
.align 2, 0
_0804F5D4: .4byte 0x0000fffc
thumb_func_end sub_804F5C4
thumb_func_start sub_804F5D8
sub_804F5D8:
push {r4-r7,lr}
adds r5, r0, 0
movs r0, 0
ldrsh r6, [r5, r0]
b _0804F60C
_0804F5E2:
movs r0, 0x2
ldrsh r4, [r5, r0]
movs r1, 0x6
ldrsh r0, [r5, r1]
adds r7, r6, 0x1
cmp r4, r0
bge _0804F60A
_0804F5F0:
adds r0, r6, 0
adds r1, r4, 0
bl GetTileSafe
ldrh r2, [r0, 0x4]
movs r1, 0x20
orrs r1, r2
strh r1, [r0, 0x4]
adds r4, 0x1
movs r1, 0x6
ldrsh r0, [r5, r1]
cmp r4, r0
blt _0804F5F0
_0804F60A:
adds r6, r7, 0
_0804F60C:
movs r1, 0x4
ldrsh r0, [r5, r1]
cmp r6, r0
blt _0804F5E2
pop {r4-r7}
pop {r0}
bx r0
thumb_func_end sub_804F5D8
thumb_func_start sub_804F61C
sub_804F61C:
push {r4-r7,lr}
mov r7, r9
mov r6, r8
push {r6,r7}
mov r9, r0
mov r8, r1
movs r7, 0x1
negs r7, r7
b _0804F67A
_0804F62E:
movs r5, 0x1
negs r5, r5
b _0804F666
_0804F634:
cmp r7, 0
beq _0804F63C
cmp r5, 0
bne _0804F660
_0804F63C:
adds r0, r6, 0
adds r1, r4, 0
bl GetTile
ldrh r1, [r0]
movs r0, 0x3
ands r0, r1
cmp r0, 0x1
bne _0804F660
adds r0, r6, 0
adds r1, r4, 0
bl GetTile
ldrb r0, [r0, 0x9]
cmp r0, 0xFF
bne _0804F660
movs r0, 0x1
b _0804F686
_0804F660:
adds r5, 0x1
cmp r5, 0x1
bgt _0804F672
_0804F666:
mov r0, r8
adds r4, r0, r5
cmp r4, 0
blt _0804F660
cmp r4, 0x1F
ble _0804F634
_0804F672:
adds r7, 0x1
cmp r7, 0x1
bgt _0804F684
mov r0, r9
_0804F67A:
adds r6, r0, r7
cmp r6, 0
blt _0804F672
cmp r6, 0x37
ble _0804F62E
_0804F684:
movs r0, 0
_0804F686:
pop {r3,r4}
mov r8, r3
mov r9, r4
pop {r4-r7}
pop {r1}
bx r1
thumb_func_end sub_804F61C
thumb_func_start GenerateSecondaryStructure
GenerateSecondaryStructure:
@ -832,7 +47,7 @@ _0804F6DE:
subs r0, 0x1
str r0, [r1]
adds r0, r7, 0
bl sub_804F5D8
bl SetSpawnFlag5
movs r0, 0x2
bl DungeonRandInt
cmp r0, 0
@ -861,7 +76,7 @@ _0804F712:
bge _0804F72A
mov r0, r8
adds r1, r4, 0
bl sub_804F61C
bl IsNextToHallway
lsls r0, 24
cmp r0, 0
beq _0804F710
@ -943,7 +158,7 @@ _0804F7AA:
bge _0804F7C2
adds r0, r4, 0
mov r1, r8
bl sub_804F61C
bl IsNextToHallway
lsls r0, 24
cmp r0, 0
beq _0804F7A8
@ -1040,7 +255,7 @@ _0804F864:
subs r0, 0x1
str r0, [r1]
adds r0, r7, 0
bl sub_804F5D8
bl SetSpawnFlag5
ldr r5, [sp]
subs r5, 0x2
ldr r0, [sp, 0x4]
@ -1243,7 +458,7 @@ _0804FA46:
subs r0, 0x1
str r0, [r1]
adds r0, r7, 0
bl sub_804F5D8
bl SetSpawnFlag5
cmp r4, r9
ble _0804FA5A
adds r0, r4, 0
@ -1313,7 +528,7 @@ _0804FAC8:
subs r0, 0x1
str r0, [r1]
adds r0, r7, 0
bl sub_804F5D8
bl SetSpawnFlag5
movs r6, 0x3F
_0804FAD4:
movs r4, 0x4
@ -1426,10 +641,10 @@ _0804FBAE:
_0804FBC0: .4byte gUnknown_202F1C8
_0804FBC4:
adds r0, r7, 0
bl sub_804F5D8
bl SetSpawnFlag5
adds r0, r7, 0
movs r1, 0x1
bl sub_804F278
bl GenerateMaze
_0804FBD2:
movs r0, 0x1
strb r0, [r7, 0x9]

View File

@ -13,7 +13,7 @@ extern struct FileArchive gDungeonFileArchive;
extern bool8 gUnknown_202F1AA;
extern u8 gUnknown_202F1AB;
extern u8 gUnknown_202F1AC;
extern bool8 gUnknown_202F1AC;
extern u8 gUnknown_202F1A8;
extern u8 gUnknown_202F1B4;
extern u8 gUnknown_202F1AE;
@ -103,7 +103,7 @@ void sub_804AFAC(void)
gDungeon->unk13568 = OpenFileAndGetFileDataPtr(gUnknown_80F6DCC, &gDungeonFileArchive);
gUnknown_202F1AA = FALSE;
gUnknown_202F1AB = 0;
gUnknown_202F1AC = 0;
gUnknown_202F1AC = FALSE;
gUnknown_202F1A8 = (gDungeonWaterType[gDungeon->tileset] == DUNGEON_WATER_TYPE_WATER);
gUnknown_202F1B4 = 0xFF;
gUnknown_202F1AE = 0;
@ -1035,11 +1035,12 @@ struct GridCell
void sub_804C790(s32 gridSizeX, s32 gridSizeY, s32 x2, s32 y2, s32 a4, UnkDungeonGlobal_unk1C574 *unkPtr);
void sub_8050F90(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, s32 *listX, s32 *listY, s32 a5, s32 x2, s32 y2);
void sub_8051438(struct GridCell *cell, s32 a1);
void sub_8051438(struct GridCell *gridCell, s32 a1);
extern void sub_8051288(s32 a0);
void GetGridPositions(s32 *listX, s32 *listY, s32 gridSizeX, s32 gridSizeY);
void InitDungeonGrid(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY);
void GenerateRoomImperfections(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY);
void GenerateSecondaryStructure(struct GridCell *gridCell);
void GenerateSecondaryStructures(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY);
void AssignRooms(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, s32 roomsNumber);
void CreateRoomsAndAnchors(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, s32 *listX, s32 *listY, u32 roomFlags);
@ -1048,6 +1049,8 @@ void EnsureConnectedGrid(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32
static void AssignRandomGridCellConnections(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, UnkDungeonGlobal_unk1C574 *unkPtr);
void AssignGridCellConnections(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, s32 cursorX, s32 cursorY, UnkDungeonGlobal_unk1C574 *unkPtr);
void GenerateMazeRoom(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, s32 chance);
void GenerateMaze(struct GridCell *gridCell, bool8 useSecondaryTerrain);
void GenerateMazeLine(s32 x0, s32 y0, s32 xMin, s32 yMin, s32 xMax, s32 yMax, bool8 useSecondaryTerrain, u32 roomIndex);
void GenerateKecleonShop(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, s32 chance);
void GenerateMonsterHouse(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, s32 chance);
void GenerateExtraHallways(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, s32 numExtraHallways);
@ -2312,8 +2315,6 @@ void CreateRoomsAndAnchors(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s
}
}
void GenerateSecondaryStructure(struct GridCell *cell);
void GenerateSecondaryStructures(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY)
{
s32 x, y;
@ -3885,4 +3886,346 @@ void GenerateMonsterHouse(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s3
}
}
/*
* GenerateMazeRoom - Determines and calls for whether to generate a maze room on the floor.
*
* A maze room can be generated by the probability specified in the maze_chance parameter, usually in vanilla
* this parameter is set to either 0 or 1, giving a 0-1% chance for trying to spawn a maze room.
*
* Then, a strange check occurs for whether the floor_generation_attempts is < 0, which will always fail, resulting
* in no maze rooms ever being generated under normal conditions.
*
* Candidate maze rooms have to be valid, connected, have odd dimensions, and not have any other features.
* If any candidates are found, the game will select one of these rooms and call GenerateMaze.
*/
void GenerateMazeRoom(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, s32 chance)
{
bool8 values[256];
s32 i;
s32 x, y;
s32 numValid;
Dungeon *dungeon = gDungeon;
if (chance == 0) // No chance for maze, stop
return;
if (chance <= DungeonRandInt(100)) // Need to roll the probability chance (which is usually 0-1%...)
return;
if (dungeon->unk3A16 >= 0) // This bizarre check prevents maze rooms from ever being created
return;
// Count the number of rooms that can be mazified:
// - Valid
// - Not a Merged Room
// - Connected
// - Not a Monster House
// - Both Dimensions are Odd
numValid = 0;
for (x = 0; x < gridSizeX; x++) {
for (y = 0; y < gridSizeY; y++) {
if (grid[x][y].isInvalid)
continue;
if (grid[x][y].hasBeenMerged)
continue;
if (!grid[x][y].isConnected)
continue;
if (!grid[x][y].isRoom)
continue;
if (grid[x][y].isKecleonShop)
continue;
if (grid[x][y].unk15)
continue;
if (grid[x][y].isMonsterHouse)
continue;
if (grid[x][y].hasSecondaryStructure)
continue;
if ((grid[x][y].end.x - grid[x][y].start.x) % 2 != 0 && (grid[x][y].end.y - grid[x][y].start.y) % 2 != 0) {
numValid++;
}
}
}
if (numValid == 0)
return;
// Have a single 1, the rest as 0's
for (i = 0; i < 256; i++) {
values[i] = FALSE;
}
values[0] = TRUE;
// Shuffle values
for (i = 0; i < 64; i++) {
s32 temp;
s32 a = DungeonRandInt(numValid);
s32 b = DungeonRandInt(numValid);
SWAP(values[a], values[b], temp);
}
// Counter
i = 0;
for (x = 0; x < gridSizeX; x++) {
for (y = 0; y < gridSizeY; y++) {
if (grid[x][y].isInvalid)
continue;
if (grid[x][y].hasBeenMerged)
continue;
if (!grid[x][y].isConnected)
continue;
if (!grid[x][y].isRoom)
continue;
if (grid[x][y].isKecleonShop)
continue;
if (grid[x][y].unk15)
continue;
if (grid[x][y].isMonsterHouse)
continue;
if (grid[x][y].hasSecondaryStructure)
continue;
if ((grid[x][y].end.x - grid[x][y].start.x) % 2 != 0 && (grid[x][y].end.y - grid[x][y].start.y) % 2 != 0) {
// This room can be mazified
if (values[i]) {
GenerateMaze(&grid[x][y], FALSE);
return;
}
i++;
}
}
}
}
/*
* GenerateMaze - Generate a maze room within the given grid cell.
*
* A "maze" is generated using a series of random walks whiich place obstacle terrain (walls / secondary terrain)
* in a maze-like arrangement. "Maze lines" (see: GenerateMazeLine) are generated using every other tile around the
* room's border, and every other interior tile as a starting point, ensuring there are stripes of walkable open terrain
* surrounded by striples of obstacles (maze walls).
*
*/
void GenerateMaze(struct GridCell *gridCell, bool8 useSecondaryTerrain)
{
s32 curX, curY;
u8 roomIndex;
gUnknown_202F1AC = TRUE;
gridCell->isMazeRoom = TRUE;
roomIndex = GetTile(gridCell->start.x, gridCell->start.y)->room;
// Random walks from upper border
for (curX = gridCell->start.x + 1; curX < gridCell->end.x - 1; curX += 2) {
if (GetTerrainType(GetTile(curX, gridCell->start.y - 1)) != TERRAIN_TYPE_NORMAL) {
GenerateMazeLine(curX,
gridCell->start.y - 1,
gridCell->start.x,
gridCell->start.y,
gridCell->end.x,
gridCell->end.y,
useSecondaryTerrain,
roomIndex
);
}
}
// Random walks from right border
for (curY = gridCell->start.y + 1; curY < gridCell->end.y - 1; curY += 2) {
if (GetTerrainType(GetTile(gridCell->end.x, curY)) != TERRAIN_TYPE_NORMAL) {
GenerateMazeLine(gridCell->end.x, curY, gridCell->start.x, gridCell->start.y, gridCell->end.x, gridCell->end.y, useSecondaryTerrain, roomIndex);
}
}
// Random walks from lower border
for (curX = gridCell->start.x + 1; curX < gridCell->end.x - 1; curX += 2) {
if (GetTerrainType(GetTile(curX, gridCell->end.y)) != TERRAIN_TYPE_NORMAL) {
GenerateMazeLine(curX, gridCell->end.y, gridCell->start.x, gridCell->start.y, gridCell->end.x, gridCell->end.y, useSecondaryTerrain, roomIndex);
}
}
// Random walks from left border
for (curY = gridCell->start.y + 1; curY < gridCell->end.y - 1; curY += 2) {
if (GetTerrainType(GetTile(gridCell->start.x - 1, curY)) != TERRAIN_TYPE_NORMAL) {
GenerateMazeLine(gridCell->start.x - 1,
curY,
gridCell->start.x,
gridCell->start.y,
gridCell->end.x,
gridCell->end.y,
useSecondaryTerrain,
roomIndex);
}
}
// Fill in all the inner tiles with a stride of 2
for (curX = gridCell->start.x + 3; curX < gridCell->end.x - 3; curX += 2) {
for (curY = gridCell->start.y + 3; curY < gridCell->end.y - 3; curY += 2) {
if (GetTerrainType(GetTile(curX, curY)) == TERRAIN_TYPE_NORMAL) {
if (useSecondaryTerrain) {
SetTerrainSecondary(GetTileSafe(curX - 1, curY));
}
else {
SetTerrainWall(GetTileSafe(curX - 1, curY));
}
// More random walks
GenerateMazeLine(curX, curY, gridCell->start.x, gridCell->start.y, gridCell->end.x, gridCell->end.y, useSecondaryTerrain, roomIndex);
}
}
}
}
/*
* GenerateMazeLine - Generates a "maze line" from the given start point, within the given bounds.
*
* A "maze line" is a random walk starting from (x0, y0). The random walk moves in strides of 2
* in a random direction, placing down obstacles as it goes.
*
* The walk will terminate when the random walk has no available open tiles it can walk to.
*
* [ ^ ] [ ] [ ] [ o ] [ - ] [ > ]
* [ | ] [ ] [ ] => [ W ] [ ] [ ] => etc.
* [ o ] [ ] [ W ] [ W ] [ ] [ W ]
*
* First, an obstacle is placed at the given position (see: SetTerrainObstacleChecked)
*
* Then, a random direction is selected, searching for an open tile distance 2 away from (x0, y0).
* Each direction is attempted rotating counter-clockwise until an open tile is found or all directions are exhausted.
*
* If an open tile is found, an obstacle is placed between the two tiles, and (x0, y0) moves to the new open tile.
* This process continues until no valid open tile can be found.
*/
void GenerateMazeLine(s32 x0, s32 y0, s32 xMin, s32 yMin, s32 xMax, s32 yMax, bool8 useSecondaryTerrain, u32 roomIndex)
{
while (1) {
s32 direction = DungeonRandInt(NUM_CARDINAL_DIRECTIONS);
s32 i = 0;
SetTerrainObstacleChecked(GetTileSafe(x0, y0), useSecondaryTerrain, roomIndex);
while (1) {
s32 offsetX, offsetY;
s32 posX, posY;
// Offset from our current position to look 2 tiles in a given direction
switch (direction & CARDINAL_DIRECTION_MASK) {
case CARDINAL_DIR_RIGHT:
offsetX = 2;
offsetY = 0;
break;
case CARDINAL_DIR_UP:
offsetX = 0;
offsetY = -2;
break;
case CARDINAL_DIR_LEFT:
offsetX = -2;
offsetY = 0;
break;
default:
case CARDINAL_DIR_DOWN:
offsetX = 0;
offsetY = 2;
break;
}
posX = x0 + offsetX;
// Check that this position is in-bounds
if (xMin <= posX && xMax > posX) {
posY = y0 + offsetY;
if (yMin <= posY && yMax > posY) {
// Check that this tile is open ground
if (GetTerrainType(GetTile(posX, posY)) == TERRAIN_TYPE_NORMAL) {
// We found open ground, we're done!
break;
}
}
}
// We didn't find any, try a different direction
direction++;
if (++i >= 4)
return;
}
// If we found some open terrain, set an obstacle for the terrain in between those two,
// then move to the open terrain we found.
switch (direction & CARDINAL_DIRECTION_MASK) {
case CARDINAL_DIR_RIGHT:
SetTerrainObstacleChecked(GetTileSafe(x0 + 1, y0), useSecondaryTerrain, roomIndex);
x0 += 2;
break;
case CARDINAL_DIR_UP:
SetTerrainObstacleChecked(GetTileSafe(x0, y0 - 1), useSecondaryTerrain, roomIndex);
y0 -= 2;
break;
case CARDINAL_DIR_LEFT:
SetTerrainObstacleChecked(GetTileSafe(x0 - 1, y0), useSecondaryTerrain, roomIndex);
x0 -= 2;
break;
case CARDINAL_DIR_DOWN:
SetTerrainObstacleChecked(GetTileSafe(x0, y0 + 1), useSecondaryTerrain, roomIndex);
y0 += 2;
break;
}
}
}
void sub_804F5C4(Tile *tile, u32 terrainFlag)
{
SetTerrainSecondary(tile);
tile->terrainType |= terrainFlag;
}
/*
* SetSpawnFlag5 - Sets unknown spawn flag 0x5 on all tiles in a room
*/
void SetSpawnFlag5(struct GridCell *gridCell) {
s32 x, y;
for (x = gridCell->start.x; x < gridCell->end.x; x++) {
for (y = gridCell->start.y; y < gridCell->end.y; y++) {
GetTileSafe(x, y)->unk4 |= 0x20;
}
}
}
/*
* IsNextToHallway - Checks if a tile position is either in a hallway or next to one.
*/
bool8 IsNextToHallway(s32 x, s32 y)
{
s32 offsetX, offsetY;
s32 posX, posY;
for (offsetX = -1; offsetX <= 1; offsetX++) {
posX = x + offsetX;
if (posX < 0)
continue;
if (posX >= DUNGEON_MAX_SIZE_X)
break;
for (offsetY = -1; offsetY <= 1; offsetY++) {
posY = y + offsetY;
if (posY < 0)
continue;
if (posY >= DUNGEON_MAX_SIZE_Y)
break;
if (offsetX != 0 && offsetY != 0)
continue;
if (GetTerrainType(GetTile(posX, posY)) == TERRAIN_TYPE_NORMAL && GetTile(posX, posY)->room == CORRIDOR_ROOM)
return TRUE;
}
}
return FALSE;
}
//