mirror of
https://github.com/pret/pmd-red.git
synced 2026-04-24 15:07:09 -05:00
GenerateExtraHallways
This commit is contained in:
parent
2a678ca06c
commit
cf6e42ae19
|
|
@ -6,556 +6,8 @@
|
|||
.text
|
||||
|
||||
|
||||
thumb_func_start GenerateExtraHallways
|
||||
GenerateExtraHallways:
|
||||
push {r4-r7,lr}
|
||||
mov r7, r10
|
||||
mov r6, r9
|
||||
mov r5, r8
|
||||
push {r5-r7}
|
||||
sub sp, 0x20
|
||||
str r0, [sp]
|
||||
str r1, [sp, 0x4]
|
||||
str r2, [sp, 0x8]
|
||||
str r3, [sp, 0xC]
|
||||
cmp r3, 0
|
||||
bne _0804CC06
|
||||
b _0804D006
|
||||
_0804CC06:
|
||||
movs r5, 0
|
||||
cmp r5, r3
|
||||
blt _0804CC0E
|
||||
b _0804D006
|
||||
_0804CC0E:
|
||||
ldr r0, [sp, 0x4]
|
||||
bl DungeonRandInt
|
||||
mov r9, r0
|
||||
ldr r0, [sp, 0x8]
|
||||
bl DungeonRandInt
|
||||
mov r10, r0
|
||||
lsls r0, 5
|
||||
mov r2, r9
|
||||
lsls r1, r2, 4
|
||||
subs r1, r2
|
||||
lsls r1, 5
|
||||
ldr r3, [sp]
|
||||
adds r1, r3
|
||||
adds r4, r0, r1
|
||||
ldrb r0, [r4, 0xA]
|
||||
adds r5, 0x1
|
||||
str r5, [sp, 0x18]
|
||||
cmp r0, 0
|
||||
bne _0804CC3A
|
||||
b _0804CFFC
|
||||
_0804CC3A:
|
||||
ldrb r0, [r4, 0xB]
|
||||
cmp r0, 0
|
||||
bne _0804CC42
|
||||
b _0804CFFC
|
||||
_0804CC42:
|
||||
ldrb r0, [r4, 0x8]
|
||||
cmp r0, 0
|
||||
beq _0804CC4A
|
||||
b _0804CFFC
|
||||
_0804CC4A:
|
||||
ldrb r0, [r4, 0x10]
|
||||
cmp r0, 0
|
||||
beq _0804CC52
|
||||
b _0804CFFC
|
||||
_0804CC52:
|
||||
movs r1, 0
|
||||
ldrsh r0, [r4, r1]
|
||||
movs r2, 0x4
|
||||
ldrsh r1, [r4, r2]
|
||||
bl DungeonRandRange
|
||||
adds r7, r0, 0
|
||||
movs r3, 0x2
|
||||
ldrsh r0, [r4, r3]
|
||||
movs r2, 0x6
|
||||
ldrsh r1, [r4, r2]
|
||||
bl DungeonRandRange
|
||||
adds r6, r0, 0
|
||||
movs r0, 0x4
|
||||
bl DungeonRandInt
|
||||
lsls r0, 1
|
||||
mov r8, r0
|
||||
ldr r1, [sp, 0x8]
|
||||
subs r1, 0x1
|
||||
movs r3, 0x2
|
||||
str r3, [sp, 0x10]
|
||||
ldr r0, [sp, 0x4]
|
||||
subs r0, 0x1
|
||||
_0804CC84:
|
||||
mov r2, r8
|
||||
cmp r2, 0
|
||||
bne _0804CC92
|
||||
cmp r10, r1
|
||||
blt _0804CC92
|
||||
movs r3, 0x2
|
||||
mov r8, r3
|
||||
_0804CC92:
|
||||
mov r2, r8
|
||||
cmp r2, 0x2
|
||||
bne _0804CCA0
|
||||
cmp r9, r0
|
||||
blt _0804CCA0
|
||||
movs r3, 0x4
|
||||
mov r8, r3
|
||||
_0804CCA0:
|
||||
mov r2, r8
|
||||
cmp r2, 0x4
|
||||
bne _0804CCB0
|
||||
mov r3, r10
|
||||
cmp r3, 0
|
||||
bgt _0804CCB0
|
||||
movs r2, 0x6
|
||||
mov r8, r2
|
||||
_0804CCB0:
|
||||
mov r3, r8
|
||||
cmp r3, 0x6
|
||||
bne _0804CCC0
|
||||
mov r2, r9
|
||||
cmp r2, 0
|
||||
bgt _0804CCC0
|
||||
movs r3, 0
|
||||
mov r8, r3
|
||||
_0804CCC0:
|
||||
ldr r2, [sp, 0x10]
|
||||
subs r2, 0x1
|
||||
str r2, [sp, 0x10]
|
||||
cmp r2, 0
|
||||
bge _0804CC84
|
||||
adds r0, r7, 0
|
||||
adds r1, r6, 0
|
||||
bl GetTile
|
||||
ldrb r5, [r0, 0x9]
|
||||
ldr r1, _0804CCE0
|
||||
mov r3, r8
|
||||
lsls r0, r3, 2
|
||||
adds r4, r0, r1
|
||||
b _0804CCF0
|
||||
.align 2, 0
|
||||
_0804CCE0: .4byte gAdjacentTileOffsets
|
||||
_0804CCE4:
|
||||
movs r1, 0
|
||||
ldrsh r0, [r4, r1]
|
||||
adds r7, r0
|
||||
movs r2, 0x2
|
||||
ldrsh r0, [r4, r2]
|
||||
adds r6, r0
|
||||
_0804CCF0:
|
||||
adds r0, r7, 0
|
||||
adds r1, r6, 0
|
||||
bl GetTile
|
||||
ldrb r0, [r0, 0x9]
|
||||
cmp r5, r0
|
||||
beq _0804CCE4
|
||||
ldr r1, _0804CD08
|
||||
mov r3, r8
|
||||
lsls r0, r3, 2
|
||||
adds r4, r0, r1
|
||||
b _0804CD18
|
||||
.align 2, 0
|
||||
_0804CD08: .4byte gAdjacentTileOffsets
|
||||
_0804CD0C:
|
||||
movs r1, 0
|
||||
ldrsh r0, [r4, r1]
|
||||
adds r7, r0
|
||||
movs r2, 0x2
|
||||
ldrsh r0, [r4, r2]
|
||||
adds r6, r0
|
||||
_0804CD18:
|
||||
adds r0, r7, 0
|
||||
adds r1, r6, 0
|
||||
bl GetTile
|
||||
ldrh r1, [r0]
|
||||
movs r5, 0x3
|
||||
adds r0, r5, 0
|
||||
ands r0, r1
|
||||
cmp r0, 0x1
|
||||
beq _0804CD0C
|
||||
adds r0, r7, 0
|
||||
adds r1, r6, 0
|
||||
bl GetTile
|
||||
ldrh r1, [r0]
|
||||
adds r0, r5, 0
|
||||
ands r0, r1
|
||||
cmp r0, 0x2
|
||||
bne _0804CD40
|
||||
b _0804CFFC
|
||||
_0804CD40:
|
||||
movs r3, 0
|
||||
subs r2, r7, 0x2
|
||||
adds r4, r7, 0x2
|
||||
b _0804CD4A
|
||||
_0804CD48:
|
||||
adds r2, 0x1
|
||||
_0804CD4A:
|
||||
cmp r2, r4
|
||||
bgt _0804CD6C
|
||||
subs r0, r6, 0x2
|
||||
adds r1, r6, 0x2
|
||||
b _0804CD56
|
||||
_0804CD54:
|
||||
adds r0, 0x1
|
||||
_0804CD56:
|
||||
cmp r0, r1
|
||||
bgt _0804CD68
|
||||
cmp r2, 0x37
|
||||
bhi _0804CD66
|
||||
cmp r0, 0
|
||||
blt _0804CD66
|
||||
cmp r0, 0x1F
|
||||
ble _0804CD54
|
||||
_0804CD66:
|
||||
movs r3, 0x1
|
||||
_0804CD68:
|
||||
cmp r3, 0
|
||||
beq _0804CD48
|
||||
_0804CD6C:
|
||||
cmp r3, 0
|
||||
beq _0804CD72
|
||||
b _0804CFFC
|
||||
_0804CD72:
|
||||
ldr r2, _0804CDD4
|
||||
mov r1, r8
|
||||
adds r1, 0x2
|
||||
movs r4, 0x6
|
||||
ands r1, r4
|
||||
lsls r1, 2
|
||||
adds r1, r2
|
||||
movs r3, 0
|
||||
ldrsh r0, [r1, r3]
|
||||
movs r3, 0x2
|
||||
ldrsh r1, [r1, r3]
|
||||
adds r0, r7, r0
|
||||
adds r1, r6, r1
|
||||
str r2, [sp, 0x1C]
|
||||
bl GetTile
|
||||
ldrh r1, [r0]
|
||||
movs r5, 0x3
|
||||
adds r0, r5, 0
|
||||
ands r0, r1
|
||||
ldr r2, [sp, 0x1C]
|
||||
cmp r0, 0x1
|
||||
bne _0804CDA2
|
||||
b _0804CFFC
|
||||
_0804CDA2:
|
||||
mov r1, r8
|
||||
subs r1, 0x2
|
||||
ands r1, r4
|
||||
lsls r1, 2
|
||||
adds r1, r2
|
||||
movs r2, 0
|
||||
ldrsh r0, [r1, r2]
|
||||
movs r3, 0x2
|
||||
ldrsh r1, [r1, r3]
|
||||
adds r0, r7, r0
|
||||
adds r1, r6, r1
|
||||
bl GetTile
|
||||
ldrh r1, [r0]
|
||||
adds r0, r5, 0
|
||||
ands r0, r1
|
||||
cmp r0, 0x1
|
||||
bne _0804CDC8
|
||||
b _0804CFFC
|
||||
_0804CDC8:
|
||||
movs r0, 0x3
|
||||
bl DungeonRandInt
|
||||
adds r0, 0x3
|
||||
str r0, [sp, 0x10]
|
||||
b _0804CFD4
|
||||
.align 2, 0
|
||||
_0804CDD4: .4byte gAdjacentTileOffsets
|
||||
_0804CDD8:
|
||||
adds r0, r7, 0
|
||||
adds r1, r6, 0
|
||||
bl GetTile
|
||||
ldrh r1, [r0]
|
||||
movs r0, 0x10
|
||||
ands r0, r1
|
||||
cmp r0, 0
|
||||
beq _0804CDEC
|
||||
b _0804CFFC
|
||||
_0804CDEC:
|
||||
movs r0, 0x1
|
||||
str r0, [sp, 0x14]
|
||||
adds r4, r7, 0x1
|
||||
adds r0, r4, 0
|
||||
adds r1, r6, 0
|
||||
bl GetTile
|
||||
ldrh r1, [r0]
|
||||
mov r0, r10
|
||||
ands r0, r1
|
||||
mov r9, r4
|
||||
cmp r0, 0x1
|
||||
bne _0804CE32
|
||||
adds r5, r6, 0x1
|
||||
adds r0, r4, 0
|
||||
adds r1, r5, 0
|
||||
bl GetTile
|
||||
ldrh r0, [r0]
|
||||
mov r4, r10
|
||||
ands r4, r0
|
||||
cmp r4, 0x1
|
||||
bne _0804CE32
|
||||
adds r0, r7, 0
|
||||
adds r1, r5, 0
|
||||
bl GetTile
|
||||
ldrh r0, [r0]
|
||||
mov r1, r10
|
||||
ands r0, r1
|
||||
eors r0, r4
|
||||
negs r1, r0
|
||||
orrs r1, r0
|
||||
lsrs r1, 31
|
||||
str r1, [sp, 0x14]
|
||||
_0804CE32:
|
||||
mov r0, r9
|
||||
adds r1, r6, 0
|
||||
bl GetTile
|
||||
ldrh r1, [r0]
|
||||
movs r5, 0x3
|
||||
adds r0, r5, 0
|
||||
ands r0, r1
|
||||
cmp r0, 0x1
|
||||
bne _0804CE70
|
||||
subs r4, r6, 0x1
|
||||
mov r0, r9
|
||||
adds r1, r4, 0
|
||||
bl GetTile
|
||||
ldrh r1, [r0]
|
||||
adds r0, r5, 0
|
||||
ands r0, r1
|
||||
cmp r0, 0x1
|
||||
bne _0804CE70
|
||||
adds r0, r7, 0
|
||||
adds r1, r4, 0
|
||||
bl GetTile
|
||||
ldrh r1, [r0]
|
||||
adds r0, r5, 0
|
||||
ands r0, r1
|
||||
cmp r0, 0x1
|
||||
bne _0804CE70
|
||||
movs r2, 0
|
||||
str r2, [sp, 0x14]
|
||||
_0804CE70:
|
||||
subs r4, r7, 0x1
|
||||
adds r0, r4, 0
|
||||
adds r1, r6, 0
|
||||
bl GetTile
|
||||
ldrh r1, [r0]
|
||||
movs r2, 0x3
|
||||
adds r0, r2, 0
|
||||
ands r0, r1
|
||||
cmp r0, 0x1
|
||||
bne _0804CEB6
|
||||
adds r5, r6, 0x1
|
||||
adds r0, r4, 0
|
||||
adds r1, r5, 0
|
||||
str r2, [sp, 0x1C]
|
||||
bl GetTile
|
||||
ldrh r1, [r0]
|
||||
ldr r2, [sp, 0x1C]
|
||||
adds r0, r2, 0
|
||||
ands r0, r1
|
||||
cmp r0, 0x1
|
||||
bne _0804CEB6
|
||||
adds r0, r7, 0
|
||||
adds r1, r5, 0
|
||||
bl GetTile
|
||||
ldrh r1, [r0]
|
||||
ldr r2, [sp, 0x1C]
|
||||
adds r0, r2, 0
|
||||
ands r0, r1
|
||||
cmp r0, 0x1
|
||||
bne _0804CEB6
|
||||
movs r3, 0
|
||||
str r3, [sp, 0x14]
|
||||
_0804CEB6:
|
||||
adds r0, r4, 0
|
||||
adds r1, r6, 0
|
||||
bl GetTile
|
||||
ldrh r1, [r0]
|
||||
movs r2, 0x3
|
||||
adds r0, r2, 0
|
||||
ands r0, r1
|
||||
cmp r0, 0x1
|
||||
bne _0804CEFA
|
||||
subs r5, r6, 0x1
|
||||
adds r0, r4, 0
|
||||
adds r1, r5, 0
|
||||
str r2, [sp, 0x1C]
|
||||
bl GetTile
|
||||
ldrh r1, [r0]
|
||||
ldr r2, [sp, 0x1C]
|
||||
adds r0, r2, 0
|
||||
ands r0, r1
|
||||
cmp r0, 0x1
|
||||
bne _0804CEFA
|
||||
adds r0, r7, 0
|
||||
adds r1, r5, 0
|
||||
bl GetTile
|
||||
ldrh r1, [r0]
|
||||
ldr r2, [sp, 0x1C]
|
||||
adds r0, r2, 0
|
||||
ands r0, r1
|
||||
cmp r0, 0x1
|
||||
bne _0804CEFA
|
||||
movs r0, 0
|
||||
str r0, [sp, 0x14]
|
||||
_0804CEFA:
|
||||
ldr r1, [sp, 0x14]
|
||||
cmp r1, 0
|
||||
beq _0804CF16
|
||||
adds r0, r7, 0
|
||||
adds r1, r6, 0
|
||||
bl GetTileSafe
|
||||
ldrh r1, [r0]
|
||||
ldr r3, _0804D018
|
||||
adds r2, r3, 0
|
||||
ands r1, r2
|
||||
movs r2, 0x1
|
||||
orrs r1, r2
|
||||
strh r1, [r0]
|
||||
_0804CF16:
|
||||
ldr r2, _0804D01C
|
||||
movs r0, 0x2
|
||||
add r0, r8
|
||||
mov r9, r0
|
||||
movs r1, 0x6
|
||||
mov r10, r1
|
||||
mov r1, r9
|
||||
mov r3, r10
|
||||
ands r1, r3
|
||||
lsls r1, 2
|
||||
adds r1, r2
|
||||
movs r3, 0
|
||||
ldrsh r0, [r1, r3]
|
||||
movs r3, 0x2
|
||||
ldrsh r1, [r1, r3]
|
||||
adds r0, r7, r0
|
||||
adds r1, r6, r1
|
||||
str r2, [sp, 0x1C]
|
||||
bl GetTile
|
||||
ldrh r1, [r0]
|
||||
movs r5, 0x3
|
||||
adds r0, r5, 0
|
||||
ands r0, r1
|
||||
ldr r2, [sp, 0x1C]
|
||||
cmp r0, 0x1
|
||||
beq _0804CFFC
|
||||
mov r4, r8
|
||||
subs r4, 0x2
|
||||
adds r1, r4, 0
|
||||
mov r0, r10
|
||||
ands r1, r0
|
||||
lsls r1, 2
|
||||
adds r1, r2
|
||||
movs r2, 0
|
||||
ldrsh r0, [r1, r2]
|
||||
movs r3, 0x2
|
||||
ldrsh r1, [r1, r3]
|
||||
adds r0, r7, r0
|
||||
adds r1, r6, r1
|
||||
bl GetTile
|
||||
ldrh r1, [r0]
|
||||
adds r0, r5, 0
|
||||
ands r0, r1
|
||||
cmp r0, 0x1
|
||||
beq _0804CFFC
|
||||
ldr r0, [sp, 0x10]
|
||||
subs r0, 0x1
|
||||
str r0, [sp, 0x10]
|
||||
cmp r0, 0
|
||||
bne _0804CFC0
|
||||
movs r0, 0x3
|
||||
bl DungeonRandInt
|
||||
adds r0, 0x3
|
||||
str r0, [sp, 0x10]
|
||||
movs r0, 0x64
|
||||
bl DungeonRandInt
|
||||
mov r8, r4
|
||||
cmp r0, 0x31
|
||||
bgt _0804CF96
|
||||
mov r8, r9
|
||||
_0804CF96:
|
||||
mov r1, r8
|
||||
mov r2, r10
|
||||
ands r1, r2
|
||||
mov r8, r1
|
||||
cmp r7, 0x1F
|
||||
ble _0804CFAE
|
||||
ldr r0, _0804D020
|
||||
ldrb r0, [r0]
|
||||
cmp r0, 0x1
|
||||
bne _0804CFAE
|
||||
cmp r1, 0x2
|
||||
beq _0804CFFC
|
||||
_0804CFAE:
|
||||
cmp r7, 0x2F
|
||||
ble _0804CFC0
|
||||
ldr r0, _0804D020
|
||||
ldrb r0, [r0]
|
||||
cmp r0, 0x2
|
||||
bne _0804CFC0
|
||||
mov r3, r8
|
||||
cmp r3, 0x2
|
||||
beq _0804CFFC
|
||||
_0804CFC0:
|
||||
ldr r0, _0804D01C
|
||||
mov r2, r8
|
||||
lsls r1, r2, 2
|
||||
adds r1, r0
|
||||
movs r3, 0
|
||||
ldrsh r0, [r1, r3]
|
||||
adds r7, r0
|
||||
movs r2, 0x2
|
||||
ldrsh r0, [r1, r2]
|
||||
adds r6, r0
|
||||
_0804CFD4:
|
||||
cmp r7, 0x1
|
||||
ble _0804CFFC
|
||||
cmp r6, 0x1
|
||||
ble _0804CFFC
|
||||
cmp r7, 0x36
|
||||
bgt _0804CFFC
|
||||
cmp r6, 0x1E
|
||||
bgt _0804CFFC
|
||||
adds r0, r7, 0
|
||||
adds r1, r6, 0
|
||||
bl GetTile
|
||||
ldrh r1, [r0]
|
||||
movs r3, 0x3
|
||||
mov r10, r3
|
||||
mov r0, r10
|
||||
ands r0, r1
|
||||
cmp r0, 0x1
|
||||
beq _0804CFFC
|
||||
b _0804CDD8
|
||||
_0804CFFC:
|
||||
ldr r5, [sp, 0x18]
|
||||
ldr r0, [sp, 0xC]
|
||||
cmp r5, r0
|
||||
bge _0804D006
|
||||
b _0804CC0E
|
||||
_0804D006:
|
||||
add sp, 0x20
|
||||
pop {r3-r5}
|
||||
mov r8, r3
|
||||
mov r9, r4
|
||||
mov r10, r5
|
||||
pop {r4-r7}
|
||||
pop {r0}
|
||||
bx r0
|
||||
.align 2, 0
|
||||
_0804D018: .4byte 0x0000fffc
|
||||
_0804D01C: .4byte gAdjacentTileOffsets
|
||||
_0804D020: .4byte gUnknown_202F1AE
|
||||
thumb_func_end GenerateExtraHallways
|
||||
|
||||
thumb_func_start sub_804D024
|
||||
sub_804D024:
|
||||
thumb_func_start GetGridPositions
|
||||
GetGridPositions:
|
||||
push {r4-r7,lr}
|
||||
mov r7, r8
|
||||
push {r7}
|
||||
|
|
@ -605,7 +57,7 @@ _0804D072:
|
|||
pop {r4-r7}
|
||||
pop {r0}
|
||||
bx r0
|
||||
thumb_func_end sub_804D024
|
||||
thumb_func_end GetGridPositions
|
||||
|
||||
thumb_func_start InitDungeonGrid
|
||||
InitDungeonGrid:
|
||||
|
|
@ -1259,8 +711,8 @@ _0804D520:
|
|||
_0804D530: .4byte 0x0000fffc
|
||||
thumb_func_end CreateRoomsAndAnchors
|
||||
|
||||
thumb_func_start sub_804D534
|
||||
sub_804D534:
|
||||
thumb_func_start GenerateSecondaryStructures
|
||||
GenerateSecondaryStructures:
|
||||
push {r4-r7,lr}
|
||||
mov r7, r9
|
||||
mov r6, r8
|
||||
|
|
@ -1326,7 +778,7 @@ _0804D5A0:
|
|||
pop {r4-r7}
|
||||
pop {r0}
|
||||
bx r0
|
||||
thumb_func_end sub_804D534
|
||||
thumb_func_end GenerateSecondaryStructures
|
||||
|
||||
thumb_func_start sub_804D5B0
|
||||
sub_804D5B0:
|
||||
|
|
@ -5064,8 +4516,8 @@ _0804F0C0:
|
|||
bx r0
|
||||
thumb_func_end GenerateMonsterHouse
|
||||
|
||||
thumb_func_start sub_804F0D0
|
||||
sub_804F0D0:
|
||||
thumb_func_start GenerateMazeRoom
|
||||
GenerateMazeRoom:
|
||||
push {r4-r7,lr}
|
||||
mov r7, r10
|
||||
mov r6, r9
|
||||
|
|
@ -5288,7 +4740,7 @@ _0804F266:
|
|||
pop {r4-r7}
|
||||
pop {r0}
|
||||
bx r0
|
||||
thumb_func_end sub_804F0D0
|
||||
thumb_func_end GenerateMazeRoom
|
||||
|
||||
thumb_func_start sub_804F278
|
||||
sub_804F278:
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#define GUARD_CONSTANTS_DIRECTION_H
|
||||
|
||||
#define DIRECTION_MASK 7
|
||||
#define DIRECTION_MASK_CARDINAL 6 // Only South, Easy, North and West
|
||||
|
||||
enum Direction
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "tile_types.h"
|
||||
#include "dungeon_map_access.h"
|
||||
#include "dungeon_random.h"
|
||||
#include "constants/direction.h"
|
||||
#include "structs/str_dungeon.h"
|
||||
#include "structs/map.h"
|
||||
|
||||
|
|
@ -37,23 +38,26 @@ extern void sub_804FD30(void);
|
|||
extern void sub_804FD30(void);
|
||||
extern void sub_80518F0(void);
|
||||
extern void sub_804FCCC(void);
|
||||
extern void sub_804C918(void);
|
||||
extern void GenerateOneRoomMonsterHouseFloor(void);
|
||||
extern void sub_804FBE8(void);
|
||||
extern void sub_804FC74(void);
|
||||
extern void sub_804E9DC(void);
|
||||
extern void sub_804C9D0(void);
|
||||
extern void GenerateTwoRoomsWithMonsterHouseFloor(void);
|
||||
extern u8 sub_8043D10();
|
||||
extern bool8 sub_8050C30(s32 a0, s32 a1, u8 a2);
|
||||
extern void sub_806C330(s32 a0, s32 a1, s16 a2, u8 a3);
|
||||
|
||||
extern const Position gAdjacentTileOffsets[];
|
||||
|
||||
void sub_804B534(s32 a0, s32 a1, s32 a2, s32 a3);
|
||||
bool8 sub_804C70C(s32, UnkDungeonGlobal_unk1C574 *);
|
||||
void sub_804B634(s32 a0, s32 a1, UnkDungeonGlobal_unk1C574 *a2);
|
||||
void GenerateStandardFloor(s32 a0, s32 a1, UnkDungeonGlobal_unk1C574 *a2);
|
||||
void sub_804B72C(UnkDungeonGlobal_unk1C574 *a0);
|
||||
void sub_804BC80(UnkDungeonGlobal_unk1C574 *a0);
|
||||
void GenerateLineFloor(UnkDungeonGlobal_unk1C574 *a0);
|
||||
void GenerateCrossFloor(UnkDungeonGlobal_unk1C574 *a0);
|
||||
void GenerateBeetleFloor(UnkDungeonGlobal_unk1C574 *a0);
|
||||
void GenerateOuterRoomsFloor(s32 sizeX_, s32 sizeY_, UnkDungeonGlobal_unk1C574 *unkPtr);
|
||||
void sub_8051654(UnkDungeonGlobal_unk1C574 *a0);
|
||||
void sub_80506F0(s32 a0, UnkDungeonGlobal_unk1C574 *a1);
|
||||
void sub_804FF08(UnkDungeonGlobal_unk1C574 *a0, bool8 a1);
|
||||
|
|
@ -160,22 +164,22 @@ void sub_804AFAC(void)
|
|||
case 1:
|
||||
y = DungeonRandInt(2) + 2;
|
||||
gUnknown_202F1AE = 1;
|
||||
sub_804B634(4, y, unkPtr);
|
||||
GenerateStandardFloor(4, y, unkPtr);
|
||||
r10 = TRUE;
|
||||
break;
|
||||
case 11:
|
||||
y = DungeonRandInt(2) + 2;
|
||||
gUnknown_202F1AE = 2;
|
||||
sub_804B634(4, y, unkPtr);
|
||||
GenerateStandardFloor(4, y, unkPtr);
|
||||
r10 = TRUE;
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
sub_804B634(x, y, unkPtr);
|
||||
GenerateStandardFloor(x, y, unkPtr);
|
||||
r10 = TRUE;
|
||||
break;
|
||||
case 2:
|
||||
sub_804C918();
|
||||
GenerateOneRoomMonsterHouseFloor();
|
||||
gDungeon->unk3A08 = 1;
|
||||
break;
|
||||
case 3:
|
||||
|
|
@ -187,7 +191,7 @@ void sub_804AFAC(void)
|
|||
r10 = TRUE;
|
||||
break;
|
||||
case 5:
|
||||
sub_804C9D0();
|
||||
GenerateTwoRoomsWithMonsterHouseFloor();
|
||||
gDungeon->unk3A08 = 1;
|
||||
break;
|
||||
case 6:
|
||||
|
|
@ -201,7 +205,7 @@ void sub_804AFAC(void)
|
|||
GenerateBeetleFloor(unkPtr);
|
||||
break;
|
||||
case 10:
|
||||
sub_804B634(x, y, unkPtr);
|
||||
GenerateOuterRoomsFloor(x, y, unkPtr);
|
||||
r10 = TRUE;
|
||||
break;
|
||||
}
|
||||
|
|
@ -247,7 +251,7 @@ void sub_804AFAC(void)
|
|||
if (j == 10) {
|
||||
gUnknown_202F1D8.x = -1;
|
||||
gUnknown_202F1D8.y = -1;
|
||||
sub_804C918();
|
||||
GenerateOneRoomMonsterHouseFloor();
|
||||
gDungeon->unk3A08 = 1;
|
||||
}
|
||||
sub_804E9DC();
|
||||
|
|
@ -271,7 +275,7 @@ void sub_804AFAC(void)
|
|||
gUnknown_202F1D8.x = -1;
|
||||
gUnknown_202F1D8.y = -1;
|
||||
sub_804FD30();
|
||||
sub_804C918();
|
||||
GenerateOneRoomMonsterHouseFloor();
|
||||
gDungeon->unk3A08 = 1;
|
||||
sub_804E9DC();
|
||||
sub_804FF08(unkPtr, FALSE);
|
||||
|
|
@ -592,7 +596,7 @@ void NAKED sub_804AFAC(void)
|
|||
" movs r0, 0x4\n"
|
||||
" adds r1, r4, 0\n"
|
||||
" mov r2, r8\n"
|
||||
" bl sub_804B634\n"
|
||||
" bl GenerateStandardFloor\n"
|
||||
" b _0804B2AA\n"
|
||||
" .align 2, 0\n"
|
||||
"_0804B24C: .4byte gUnknown_202F1AE\n"
|
||||
|
|
@ -606,7 +610,7 @@ void NAKED sub_804AFAC(void)
|
|||
" movs r0, 0x4\n"
|
||||
" adds r1, r4, 0\n"
|
||||
" mov r2, r8\n"
|
||||
" bl sub_804B634\n"
|
||||
" bl GenerateStandardFloor\n"
|
||||
" movs r6, 0x1\n"
|
||||
" mov r10, r6\n"
|
||||
" b _0804B2F6\n"
|
||||
|
|
@ -616,10 +620,10 @@ void NAKED sub_804AFAC(void)
|
|||
" adds r0, r5, 0\n"
|
||||
" adds r1, r4, 0\n"
|
||||
" mov r2, r8\n"
|
||||
" bl sub_804B634\n"
|
||||
" bl GenerateStandardFloor\n"
|
||||
" b _0804B2D2\n"
|
||||
"_0804B280:\n"
|
||||
" bl sub_804C918\n"
|
||||
" bl GenerateOneRoomMonsterHouseFloor\n"
|
||||
" ldr r0, _0804B290\n"
|
||||
" ldr r0, [r0]\n"
|
||||
" ldr r1, _0804B294\n"
|
||||
|
|
@ -642,7 +646,7 @@ void NAKED sub_804AFAC(void)
|
|||
" mov r10, r3\n"
|
||||
" b _0804B2F6\n"
|
||||
"_0804B2B0:\n"
|
||||
" bl sub_804C9D0\n"
|
||||
" bl GenerateTwoRoomsWithMonsterHouseFloor\n"
|
||||
" ldr r0, _0804B2C4\n"
|
||||
" ldr r0, [r0]\n"
|
||||
" ldr r6, _0804B2C8\n"
|
||||
|
|
@ -673,7 +677,7 @@ void NAKED sub_804AFAC(void)
|
|||
" adds r0, r5, 0\n"
|
||||
" adds r1, r4, 0\n"
|
||||
" mov r2, r8\n"
|
||||
" bl sub_804C53C\n"
|
||||
" bl GenerateOuterRoomsFloor\n"
|
||||
" movs r1, 0x1\n"
|
||||
" mov r10, r1\n"
|
||||
"_0804B2F6:\n"
|
||||
|
|
@ -755,7 +759,7 @@ void NAKED sub_804AFAC(void)
|
|||
" movs r0, 0x1\n"
|
||||
" negs r0, r0\n"
|
||||
" strh r0, [r1, 0x2]\n"
|
||||
" bl sub_804C918\n"
|
||||
" bl GenerateOneRoomMonsterHouseFloor\n"
|
||||
" ldr r0, _0804B4C0\n"
|
||||
" ldr r0, [r0]\n"
|
||||
" ldr r1, _0804B4C4\n"
|
||||
|
|
@ -848,7 +852,7 @@ void NAKED sub_804AFAC(void)
|
|||
" negs r0, r0\n"
|
||||
" strh r0, [r1, 0x2]\n"
|
||||
" bl sub_804FD30\n"
|
||||
" bl sub_804C918\n"
|
||||
" bl GenerateOneRoomMonsterHouseFloor\n"
|
||||
" ldr r0, _0804B4C0\n"
|
||||
" ldr r0, [r0]\n"
|
||||
" ldr r1, _0804B4C4\n"
|
||||
|
|
@ -977,8 +981,8 @@ void sub_804B534(s32 xStart, s32 yStart, s32 maxX, s32 maxY)
|
|||
|
||||
struct GridCell
|
||||
{
|
||||
Position unk0;
|
||||
Position unk4;
|
||||
Position start;
|
||||
Position end;
|
||||
u8 unk8;
|
||||
u8 unk9;
|
||||
u8 unk10;
|
||||
|
|
@ -1007,40 +1011,59 @@ struct GridCell
|
|||
|
||||
#define GRID_CELL_LEN 15
|
||||
|
||||
void sub_804D024(s32 *a0, s32 *a1, s32 x, s32 y);
|
||||
void GetGridPositions(s32 *listX, s32 *listY, s32 sizeX, s32 sizeY);
|
||||
void InitDungeonGrid(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY);
|
||||
void GenerateRoomImperfections(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY);
|
||||
void sub_804D534(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 x, s32 y);
|
||||
void GenerateSecondaryStructures(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY);
|
||||
void AssignRooms(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY, s32 roomsNumber);
|
||||
void CreateRoomsAndAnchors(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY, s32 *listX, s32 *listY, u32 roomFlags);
|
||||
void CreateGridCellConnections(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY, s32 *listX, s32 *listY, bool8 disableRoomMerging);
|
||||
void EnsureConnectedGrid(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY, s32 *listX, s32 *listY);
|
||||
void sub_804D5B0(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 x, s32 y, UnkDungeonGlobal_unk1C574 *unkPtr);
|
||||
void sub_804F0D0(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 x, s32 y, s32 a3);
|
||||
void GenerateMazeRoom(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY, s32 chance);
|
||||
void GenerateKecleonShop(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY, s32 chance);
|
||||
void GenerateMonsterHouse(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY, s32 chance);
|
||||
void GenerateExtraHallways(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY, s32 numExtraHallways);
|
||||
static void MergeRoomsVertically(s32 roomX, s32 room_y1, s32 room_dy, struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN]);
|
||||
|
||||
void sub_804B634(s32 sizeX, s32 sizeY, UnkDungeonGlobal_unk1C574 *unkPtr)
|
||||
/*
|
||||
* GenerateStandardFloor - Generates a standard, typical floor layout.
|
||||
*
|
||||
* Overview:
|
||||
* 1. Determine the grid based on sizeX, sizeY
|
||||
* 2. Assign and create rooms and hallway anchors to each grid cell
|
||||
* 3. Assign and create connections between grid cells (these are traditional hallways connecting the map together)
|
||||
* 4. Fix any unconnected grid cells by adding more connections or removing their rooms/hallway anchors
|
||||
* 5. Generate special rooms like a Maze Room (unused in vanilla?), Kecleon Shop, or Monster House
|
||||
* 6. Create additional "extra hallways" with random walks outside of existing rooms
|
||||
* 7. Finalize extra room details with imperfections (unused in vanilla?), and structures with secondary terrain
|
||||
*/
|
||||
void GenerateStandardFloor(s32 sizeX, s32 sizeY, UnkDungeonGlobal_unk1C574 *unkPtr)
|
||||
{
|
||||
struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN];
|
||||
s32 listX[GRID_CELL_LEN];
|
||||
s32 listY[GRID_CELL_LEN];
|
||||
|
||||
sub_804D024(listX, listY, sizeX, sizeY);
|
||||
GetGridPositions(listX, listY, sizeX, sizeY);
|
||||
|
||||
InitDungeonGrid(grid, sizeX, sizeY);
|
||||
|
||||
AssignRooms(grid, sizeX, sizeY, unkPtr->unk1);
|
||||
|
||||
CreateRoomsAndAnchors(grid, sizeX, sizeY, listX, listY, unkPtr->unkD);
|
||||
|
||||
sub_804D5B0(grid, sizeX, sizeY, unkPtr);
|
||||
CreateGridCellConnections(grid, sizeX, sizeY, listX, listY, FALSE);
|
||||
|
||||
EnsureConnectedGrid(grid, sizeX, sizeY, listX, listY);
|
||||
sub_804F0D0(grid, sizeX, sizeY, unkPtr->unk9);
|
||||
|
||||
GenerateMazeRoom(grid, sizeX, sizeY, unkPtr->unk9);
|
||||
GenerateKecleonShop(grid, sizeX, sizeY, gUnknown_202F1B0);
|
||||
GenerateMonsterHouse(grid, sizeX, sizeY, gUnknown_202F1B2);
|
||||
|
||||
GenerateExtraHallways(grid, sizeX, sizeY, unkPtr->unk13);
|
||||
GenerateRoomImperfections(grid, sizeX, sizeY);
|
||||
sub_804D534(grid, sizeX, sizeY);
|
||||
GenerateSecondaryStructures(grid, sizeX, sizeY);
|
||||
}
|
||||
|
||||
// Decompile once data structure is better understood
|
||||
|
|
@ -2379,13 +2402,13 @@ void GenerateBeetleFloor(UnkDungeonGlobal_unk1C574 *unkPtr)
|
|||
static void MergeRoomsVertically(s32 roomX, s32 room_y1, s32 room_dy, struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN])
|
||||
{
|
||||
s32 x, y;
|
||||
s32 xStart = min(grid[roomX][room_y1].unk0.x, grid[roomX][room_y1+room_dy].unk0.x);
|
||||
s32 yStart = grid[roomX][room_y1].unk0.y;
|
||||
s32 xEnd = max(grid[roomX][room_y1].unk4.x, grid[roomX][room_y1+room_dy].unk4.x);
|
||||
s32 yEnd = grid[roomX][room_y1 + room_dy].unk4.y;
|
||||
s32 xStart = min(grid[roomX][room_y1].start.x, grid[roomX][room_y1+room_dy].start.x);
|
||||
s32 yStart = grid[roomX][room_y1].start.y;
|
||||
s32 xEnd = max(grid[roomX][room_y1].end.x, grid[roomX][room_y1+room_dy].end.x);
|
||||
s32 yEnd = grid[roomX][room_y1 + room_dy].end.y;
|
||||
|
||||
// Carve out the new larger room, retaining the index of the first room
|
||||
u8 roomId = GetTile(grid[roomX][room_y1].unk0.x, grid[roomX][room_y1].unk0.y)->room;
|
||||
u8 roomId = GetTile(grid[roomX][room_y1].start.x, grid[roomX][room_y1].start.y)->room;
|
||||
|
||||
for (x = xStart; x < xEnd; x++) {
|
||||
for (y = yStart; y < yEnd; y++) {
|
||||
|
|
@ -2396,70 +2419,94 @@ static void MergeRoomsVertically(s32 roomX, s32 room_y1, s32 room_dy, struct Gri
|
|||
}
|
||||
}
|
||||
|
||||
grid[roomX][room_y1].unk0.x = xStart;
|
||||
grid[roomX][room_y1].unk4.x = xEnd;
|
||||
grid[roomX][room_y1].unk0.y = yStart;
|
||||
grid[roomX][room_y1].unk4.y = yEnd;
|
||||
grid[roomX][room_y1].start.x = xStart;
|
||||
grid[roomX][room_y1].end.x = xEnd;
|
||||
grid[roomX][room_y1].start.y = yStart;
|
||||
grid[roomX][room_y1].end.y = yEnd;
|
||||
grid[roomX][room_y1 + room_dy].unk18 = TRUE;
|
||||
grid[roomX][room_y1].unk18 = TRUE;
|
||||
grid[roomX][room_y1 + room_dy].unk11 = FALSE;
|
||||
grid[roomX][room_y1 + room_dy].unk17 = TRUE;
|
||||
}
|
||||
|
||||
void sub_804C53C(s32 x_, s32 y_, UnkDungeonGlobal_unk1C574 *unkPtr)
|
||||
// GenerateOuterRoomsFloor - Generates a floor layout with a ring of rooms and nothing on the interior.
|
||||
// This layout is bugged and will not properly connect rooms for sizeX < 3.
|
||||
void GenerateOuterRoomsFloor(s32 sizeX_, s32 sizeY_, UnkDungeonGlobal_unk1C574 *unkPtr)
|
||||
{
|
||||
struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN];
|
||||
s32 listX[GRID_CELL_LEN];
|
||||
s32 listY[GRID_CELL_LEN];
|
||||
s32 i, j;
|
||||
s32 x = x_;
|
||||
s32 y = y_;
|
||||
s32 x, y;
|
||||
s32 sizeX = sizeX_;
|
||||
s32 sizeY = sizeY_;
|
||||
|
||||
sub_804D024(listX, listY, x, y);
|
||||
InitDungeonGrid(grid, x, y);
|
||||
for (i = 0; i < x; i++) {
|
||||
for (j = 0; j < y; j++) {
|
||||
grid[i][j].unk10 = 1;
|
||||
GetGridPositions(listX, listY, sizeX, sizeY);
|
||||
InitDungeonGrid(grid, sizeX, sizeY);
|
||||
|
||||
// Make all cells rooms
|
||||
for (x = 0; x < sizeX; x++) {
|
||||
for (y = 0; y < sizeY; y++) {
|
||||
grid[x][y].unk10 = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 1; i < x - 1; i++) {
|
||||
for (j = 1; j < y - 1; j++) {
|
||||
grid[i][j].unk8 = 1;
|
||||
// Invalidate all interior cells
|
||||
for (x = 1; x < sizeX - 1; x++) {
|
||||
for (y = 1; y < sizeY - 1; y++) {
|
||||
grid[x][y].unk8 = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
CreateRoomsAndAnchors(grid, x, y, listX, listY, unkPtr->unkD);
|
||||
for (i = 0; i < x - 1; i++) {
|
||||
if (i != 0) {
|
||||
grid[i][0].unk22 = 1;
|
||||
grid[i][y-1].unk22 = 1;
|
||||
CreateRoomsAndAnchors(grid, sizeX, sizeY, listX, listY, unkPtr->unkD);
|
||||
|
||||
// Maybe Todo: Add EpicYoshiMaster's fixed implementation of this function
|
||||
|
||||
// The original implementation fails for sizeX <= 2, as one of the branches
|
||||
// is never taken, and the other branch does not provide a backup connection, leaving the two sides unconnected.
|
||||
// Additionally, there is a minor issue for top/bottom connections which results in hallways being connected from the bottom
|
||||
// instead of from the top, but this does not affect the connectivity of the map.
|
||||
for (x = 0; x < sizeX - 1; x++) {
|
||||
if (x != 0) {
|
||||
grid[x][0].unk22 = TRUE;
|
||||
grid[x][sizeY-1].unk22 = TRUE;
|
||||
}
|
||||
if (i < x - 2) {
|
||||
grid[i+1][0].unk21 = 1;
|
||||
grid[i+1][y-1].unk21 = 1;
|
||||
|
||||
// Bug: if sizeX <= 2, this branch will never be run.
|
||||
// Additionally, because the branch above this has no meaningful hallways produced for
|
||||
// sizeX == 1, no connections will be made between columns here.
|
||||
// This results in an unconnected map for sizeX <= 2.
|
||||
if (x < sizeX - 2) {
|
||||
grid[x+1][0].unk21 = TRUE;
|
||||
grid[x+1][sizeY-1].unk21 = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < y - 1; j++) {
|
||||
if (j != 0) {
|
||||
grid[0][j].unk19 = 1;
|
||||
grid[x-1][j].unk19 = 1;
|
||||
for (y = 0; y < sizeY - 1; y++) {
|
||||
if (y != 0) {
|
||||
grid[0][y].unk19 = TRUE;
|
||||
grid[sizeX-1][y].unk19 = TRUE;
|
||||
}
|
||||
if (j < y - 2) {
|
||||
grid[0][j].unk20 = 1;
|
||||
grid[x-1][j].unk20 = 1;
|
||||
|
||||
// This connection ends up not being set for the bottom row, but this is fine because the other
|
||||
// connection to this room is still correct. The result is that hallways here will be using the opposing end
|
||||
// of the grid cell boundary for their turns compared to top/bottom hallways between other rows.
|
||||
if (y < sizeY - 2) {
|
||||
grid[0][y].unk20 = TRUE;
|
||||
grid[sizeX-1][y].unk20 = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
CreateGridCellConnections(grid, x, y, listX, listY, FALSE);
|
||||
EnsureConnectedGrid(grid, x, y, listX, listY);
|
||||
sub_804F0D0(grid, x, y, unkPtr->unk9);
|
||||
GenerateKecleonShop(grid, x, y, gUnknown_202F1B0);
|
||||
GenerateMonsterHouse(grid, x, y, gUnknown_202F1B2);
|
||||
GenerateExtraHallways(grid, x, y, unkPtr->unk13);
|
||||
GenerateRoomImperfections(grid, x, y);
|
||||
sub_804D534(grid, x, y);
|
||||
CreateGridCellConnections(grid, sizeX, sizeY, listX, listY, FALSE);
|
||||
|
||||
EnsureConnectedGrid(grid, sizeX, sizeY, listX, listY);
|
||||
|
||||
GenerateMazeRoom(grid, sizeX, sizeY, unkPtr->unk9);
|
||||
GenerateKecleonShop(grid, sizeX, sizeY, gUnknown_202F1B0);
|
||||
GenerateMonsterHouse(grid, sizeX, sizeY, gUnknown_202F1B2);
|
||||
|
||||
GenerateExtraHallways(grid, sizeX, sizeY, unkPtr->unk13);
|
||||
GenerateRoomImperfections(grid, sizeX, sizeY);
|
||||
GenerateSecondaryStructures(grid, sizeX, sizeY);
|
||||
}
|
||||
|
||||
void sub_804C790(s32 x1, s32 y1, s32 x2, s32 y2, s32 a4, UnkDungeonGlobal_unk1C574 *unkPtr);
|
||||
|
|
@ -2473,7 +2520,7 @@ bool8 sub_804C70C(s32 a0, UnkDungeonGlobal_unk1C574 *unkPtr)
|
|||
s32 x2, y2;
|
||||
|
||||
if (x1 == 0 || y1 == 0) {
|
||||
sub_804C918();
|
||||
GenerateOneRoomMonsterHouseFloor();
|
||||
return FALSE;
|
||||
}
|
||||
else if (a0 < 50) {
|
||||
|
|
@ -2505,7 +2552,7 @@ void sub_804C790(s32 x1, s32 y1, s32 x2, s32 y2, s32 a4, UnkDungeonGlobal_unk1C5
|
|||
s32 r10 = 0;
|
||||
s32 x3 = 0, y3 = 0;
|
||||
|
||||
sub_804D024(listX, listY, x1, y1);
|
||||
GetGridPositions(listX, listY, x1, y1);
|
||||
InitDungeonGrid(grid, x1, y1);
|
||||
AssignRooms(grid, x1, y1, unkPtr->unk1);
|
||||
for (x3 = 0; x3 < x1; x3++) {
|
||||
|
|
@ -2530,36 +2577,45 @@ void sub_804C790(s32 x1, s32 y1, s32 x2, s32 y2, s32 a4, UnkDungeonGlobal_unk1C5
|
|||
sub_8051438(&grid[x3][y3], a4);
|
||||
}
|
||||
|
||||
void sub_804C918(void)
|
||||
/*
|
||||
* GenerateOneRoomMonsterHouseFloor - Generates a floor layout with just one large room which is a Monster House.
|
||||
* This generator is used as a fallback in the event generation fails too many times.
|
||||
*/
|
||||
void GenerateOneRoomMonsterHouseFloor(void)
|
||||
{
|
||||
s32 i, j;
|
||||
s32 x, y;
|
||||
struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN];
|
||||
|
||||
InitDungeonGrid(grid, 1, 1);
|
||||
grid[0][0].unk0.x = 2;
|
||||
grid[0][0].unk4.x = DUNGEON_MAX_SIZE_X - 2;
|
||||
grid[0][0].unk0.y = 2;
|
||||
grid[0][0].unk4.y = DUNGEON_MAX_SIZE_Y - 2;
|
||||
grid[0][0].unk10 = 1;
|
||||
grid[0][0].unk11 = 1;
|
||||
grid[0][0].unk8 = 0;
|
||||
for (i = grid[0][0].unk0.x; i < grid[0][0].unk4.x; i++) {
|
||||
for (j = grid[0][0].unk0.y; j < grid[0][0].unk4.y; j++) {
|
||||
Tile *tile = GetTileSafe(i, j);
|
||||
|
||||
grid[0][0].start.x = 2;
|
||||
grid[0][0].end.x = DUNGEON_MAX_SIZE_X - 2;
|
||||
grid[0][0].start.y = 2;
|
||||
grid[0][0].end.y = DUNGEON_MAX_SIZE_Y - 2;
|
||||
grid[0][0].unk10 = TRUE;
|
||||
grid[0][0].unk11 = TRUE;
|
||||
grid[0][0].unk8 = FALSE;
|
||||
|
||||
for (x = grid[0][0].start.x; x < grid[0][0].end.x; x++) {
|
||||
for (y = grid[0][0].start.y; y < grid[0][0].end.y; y++) {
|
||||
Tile *tile = GetTileSafe(x, y);
|
||||
tile->terrainType &= ~(TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY);
|
||||
tile->terrainType |= TERRAIN_TYPE_NORMAL;
|
||||
// Unnecessary call again
|
||||
GetTileSafe(i, j)->room = 0;
|
||||
GetTileSafe(x, y)->room = 0;
|
||||
}
|
||||
}
|
||||
GenerateMonsterHouse(grid, 1, 1, 999);
|
||||
}
|
||||
|
||||
void sub_804C9D0(void)
|
||||
// GenerateTwoRoomsWithMonsterHouseFloor - Generates a floor layout with two rooms (left and right), with one being a Monster House.
|
||||
void GenerateTwoRoomsWithMonsterHouseFloor(void)
|
||||
{
|
||||
struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN];
|
||||
s32 listX[GRID_CELL_LEN];
|
||||
s32 listY[GRID_CELL_LEN];
|
||||
const s32 sizeX = 2;
|
||||
const s32 sizeY = 1;
|
||||
s32 currRoomId = 0;
|
||||
s32 x, y;
|
||||
|
||||
|
|
@ -2568,10 +2624,10 @@ void sub_804C9D0(void)
|
|||
listX[2] = 54;
|
||||
listY[0] = 2;
|
||||
listY[1] = 30;
|
||||
InitDungeonGrid(grid, 2, 1);
|
||||
InitDungeonGrid(grid, sizeX, sizeY);
|
||||
|
||||
for (y = 0; y < 1; y++) {
|
||||
for (x = 0; x < 2; x++) {
|
||||
for (y = 0; y < sizeY; y++) {
|
||||
for (x = 0; x < sizeX; x++) {
|
||||
s32 currX, currY;
|
||||
s32 minX = listX[x] + 1;
|
||||
s32 minY = listY[y] + 1;
|
||||
|
|
@ -2585,10 +2641,10 @@ void sub_804C9D0(void)
|
|||
s32 endY = startY + roomSizeY;
|
||||
|
||||
grid[x][y].unk10 = 1;
|
||||
grid[x][y].unk0.x = startX;
|
||||
grid[x][y].unk4.x = endX;
|
||||
grid[x][y].unk0.y = startY;
|
||||
grid[x][y].unk4.y = endY;
|
||||
grid[x][y].start.x = startX;
|
||||
grid[x][y].end.x = endX;
|
||||
grid[x][y].start.y = startY;
|
||||
grid[x][y].end.y = endY;
|
||||
|
||||
for (currX = startX; currX < endX; currX++) {
|
||||
for (currY = startY; currY < endY; currY++) {
|
||||
|
|
@ -2603,10 +2659,237 @@ void sub_804C9D0(void)
|
|||
}
|
||||
}
|
||||
|
||||
grid[0][0].unk22 = 1;
|
||||
grid[1][0].unk21 = 1;
|
||||
CreateGridCellConnections(grid, 2, 1, listX, listY, FALSE);
|
||||
GenerateMonsterHouse(grid, 2, 1, 999);
|
||||
grid[0][0].unk22 = TRUE;
|
||||
grid[1][0].unk21 = TRUE;
|
||||
|
||||
CreateGridCellConnections(grid, sizeX, sizeY, listX, listY, FALSE);
|
||||
GenerateMonsterHouse(grid, sizeX, sizeY, 999);
|
||||
}
|
||||
|
||||
/*
|
||||
* GenerateExtraHallways - Generate extra hallways on the floor via a series of random walks.
|
||||
*
|
||||
* These paths are often visibly dead-end hallways, or hallways which loop on themselves.
|
||||
*
|
||||
* Each walk begin at a random tile in a random room, leaving in a random cardinal direction, tunneling
|
||||
* through obstacles until it reaches open terrain, is out of bounds, or reaches an impassable obstruction.
|
||||
*
|
||||
* For each hallway the following steps are done:
|
||||
*
|
||||
* 1. Select a room, tile, and cardinal direction (specific conditions documented below)
|
||||
*
|
||||
* 2. Walk from the tile in that direction until we are out of the room, and reach an obstacle (could traverse hallways on the way)
|
||||
*
|
||||
* 3. Check we're safe to proceed (not at map borders, counterclockwise/clockwise tiles are not open)
|
||||
*
|
||||
* Begin our random-length walk strides:
|
||||
*
|
||||
* 4. Check we're safe to proceed (not at borders, not open tile, not impassable wall, will not make a 2x2 open square)
|
||||
*
|
||||
* 5. Place Open Terrain at this tile
|
||||
*
|
||||
* 6. Check we're safe to proceed (counterclockwise/clockwise tiles are not open)
|
||||
*
|
||||
* 7. Check if we've reached the end of the current stride (steps at 0), if so, turn left or right at random and start a new stride.
|
||||
*
|
||||
* 8. Move in the current direction.
|
||||
*
|
||||
* Repeat 4-8 until a check fails.
|
||||
*/
|
||||
void GenerateExtraHallways(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY, s32 numExtraHallways)
|
||||
{
|
||||
s32 i, j;
|
||||
|
||||
if (numExtraHallways == 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < numExtraHallways; i++) {
|
||||
s32 currX, currY;
|
||||
s32 direction;
|
||||
u8 roomId;
|
||||
bool8 invalid;
|
||||
s32 checkX, checkY, checkX2, checkY2;
|
||||
s32 xLoop, yLoop;
|
||||
// Select a random grid cell
|
||||
s32 x = DungeonRandInt(sizeX);
|
||||
s32 y = DungeonRandInt(sizeY);
|
||||
|
||||
// To generate extra hallways the cell must be:
|
||||
// - a room
|
||||
// - connected
|
||||
// - valid
|
||||
// - not a maze room
|
||||
if (!grid[x][y].unk10 || !grid[x][y].unk11 || grid[x][y].unk8 || grid[x][y].unk16) continue;
|
||||
|
||||
// Choose a random tile in the room
|
||||
currX = DungeonRandRange(grid[x][y].start.x, grid[x][y].end.x);
|
||||
currY = DungeonRandRange(grid[x][y].start.y, grid[x][y].end.y);
|
||||
|
||||
// Choose a random cardinal direction
|
||||
direction = DungeonRandInt(4) * 2;
|
||||
|
||||
// If invalid, rotate counter-clockwise until one works
|
||||
for (j = 0; j < 3; j++) {
|
||||
if (direction == DIRECTION_SOUTH && y >= sizeY - 1) {
|
||||
direction = DIRECTION_EAST;
|
||||
}
|
||||
|
||||
if (direction == DIRECTION_EAST && x >= sizeX - 1) {
|
||||
direction = DIRECTION_NORTH;
|
||||
}
|
||||
|
||||
if (direction == DIRECTION_NORTH && y <= 0) {
|
||||
direction = DIRECTION_WEST;
|
||||
}
|
||||
|
||||
if (direction == DIRECTION_WEST && x <= 0) {
|
||||
direction = DIRECTION_SOUTH;
|
||||
}
|
||||
}
|
||||
|
||||
roomId = GetTile(currX, currY)->room;
|
||||
// Walk in the random direction until out of the room
|
||||
while (1) {
|
||||
if (roomId != GetTile(currX, currY)->room)
|
||||
break;
|
||||
// gAdjacentTileOffsets gives us the proper (x,y) offset to move one tile in the given direction.
|
||||
currX += gAdjacentTileOffsets[direction].x;
|
||||
currY += gAdjacentTileOffsets[direction].y;
|
||||
}
|
||||
|
||||
// Keep walking until an obstacle is encountered
|
||||
while (1) {
|
||||
if ((GetTile(currX, currY)->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) != TERRAIN_TYPE_NORMAL)
|
||||
break;
|
||||
|
||||
currX += gAdjacentTileOffsets[direction].x;
|
||||
currY += gAdjacentTileOffsets[direction].y;
|
||||
}
|
||||
|
||||
// Abort if we reached secondary terrain
|
||||
if ((GetTile(currX, currY)->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) == TERRAIN_TYPE_SECONDARY)
|
||||
continue;
|
||||
|
||||
// Check that the current tile is at least 2 away from the map border
|
||||
invalid = FALSE;
|
||||
for (xLoop = currX - 2; xLoop <= currX + 2; xLoop++) {
|
||||
for (yLoop = currY - 2; yLoop <= currY + 2; yLoop++) {
|
||||
if (xLoop < 0 || xLoop >= DUNGEON_MAX_SIZE_X || yLoop < 0 || yLoop >= DUNGEON_MAX_SIZE_Y) {
|
||||
invalid = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (invalid) break;
|
||||
}
|
||||
|
||||
if (invalid) continue;
|
||||
|
||||
// Make sure the direction 90 degrees counterclockwise isn't an open tile
|
||||
checkX = gAdjacentTileOffsets[(direction + 2) & DIRECTION_MASK_CARDINAL].x;
|
||||
checkY = gAdjacentTileOffsets[(direction + 2) & DIRECTION_MASK_CARDINAL].y;
|
||||
if ((GetTile(currX + checkX, currY + checkY)->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) == TERRAIN_TYPE_NORMAL)
|
||||
continue;
|
||||
|
||||
// Do the same for 90 degrees clockwise (or 270 counterclockwise) and make sure it's not an open tile
|
||||
checkX2 = gAdjacentTileOffsets[(direction - 2) & DIRECTION_MASK_CARDINAL].x;
|
||||
checkY2 = gAdjacentTileOffsets[(direction - 2) & DIRECTION_MASK_CARDINAL].y;
|
||||
if ((GetTile(currX + checkX2, currY + checkY2)->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) == TERRAIN_TYPE_NORMAL)
|
||||
continue;
|
||||
|
||||
// Number of steps to walk in one direction before turning
|
||||
j = DungeonRandInt(3) + 3;
|
||||
while (TRUE) {
|
||||
s32 checkX, checkY, checkX2, checkY2;
|
||||
bool8 willNotMakeSquare;
|
||||
// Check for stopping conditions:
|
||||
// - Out of bounds or on the 1-tile border of impassable walls
|
||||
// - Reached an open tile
|
||||
// - Reached an impassable wall
|
||||
// - Would result in carving out a 2x2 square (not a hallway at that point)
|
||||
|
||||
if (currX <= 1 || currY <= 1 || currX >= DUNGEON_MAX_SIZE_X - 1 || currY >= DUNGEON_MAX_SIZE_Y - 1) break;
|
||||
if ((GetTile(currX, currY)->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) == TERRAIN_TYPE_NORMAL) break;
|
||||
if (GetTile(currX, currY)->terrainType & TERRAIN_TYPE_IMPASSABLE_WALL) break;
|
||||
|
||||
willNotMakeSquare = TRUE;
|
||||
|
||||
// Check Bottom to Right
|
||||
if (((GetTile(currX + 1, currY)->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) == TERRAIN_TYPE_NORMAL) &&
|
||||
((GetTile(currX + 1, currY + 1)->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) == TERRAIN_TYPE_NORMAL) &&
|
||||
((GetTile(currX, currY + 1)->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) == TERRAIN_TYPE_NORMAL))
|
||||
{
|
||||
willNotMakeSquare = FALSE;
|
||||
}
|
||||
|
||||
// Check Top to Right
|
||||
if (((GetTile(currX + 1, currY)->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) == TERRAIN_TYPE_NORMAL) &&
|
||||
((GetTile(currX + 1, currY - 1)->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) == TERRAIN_TYPE_NORMAL) &&
|
||||
((GetTile(currX, currY - 1)->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) == TERRAIN_TYPE_NORMAL))
|
||||
{
|
||||
willNotMakeSquare = FALSE;
|
||||
}
|
||||
|
||||
// Check Bottom to Left
|
||||
if (((GetTile(currX - 1, currY)->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) == TERRAIN_TYPE_NORMAL) &&
|
||||
((GetTile(currX - 1, currY + 1)->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) == TERRAIN_TYPE_NORMAL) &&
|
||||
((GetTile(currX, currY + 1)->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) == TERRAIN_TYPE_NORMAL))
|
||||
{
|
||||
willNotMakeSquare = FALSE;
|
||||
}
|
||||
|
||||
// Check Top to Left
|
||||
if (((GetTile(currX - 1, currY)->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) == TERRAIN_TYPE_NORMAL) &&
|
||||
((GetTile(currX - 1, currY - 1)->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) == TERRAIN_TYPE_NORMAL) &&
|
||||
((GetTile(currX, currY - 1)->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) == TERRAIN_TYPE_NORMAL))
|
||||
{
|
||||
willNotMakeSquare = FALSE;
|
||||
}
|
||||
|
||||
// If TRUE, make the tile open, it will not produce a 2x2 opening
|
||||
// If FALSE, it will abort from neighbor checks so we don't break here
|
||||
if (willNotMakeSquare) {
|
||||
Tile *tile = GetTileSafe(currX, currY);
|
||||
tile->terrainType &= ~(TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY);
|
||||
tile->terrainType |= TERRAIN_TYPE_NORMAL;
|
||||
}
|
||||
|
||||
// Make sure the direction 90 degrees counterclockwise isn't an open tile
|
||||
checkX = gAdjacentTileOffsets[(direction + 2) & DIRECTION_MASK_CARDINAL].x;
|
||||
checkY = gAdjacentTileOffsets[(direction + 2) & DIRECTION_MASK_CARDINAL].y;
|
||||
if ((GetTile(currX + checkX, currY + checkY)->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) == TERRAIN_TYPE_NORMAL)
|
||||
break;
|
||||
|
||||
// Do the same for 90 degrees clockwise (or 270 counterclockwise) and make sure it's not an open tile
|
||||
checkX2 = gAdjacentTileOffsets[(direction - 2) & DIRECTION_MASK_CARDINAL].x;
|
||||
checkY2 = gAdjacentTileOffsets[(direction - 2) & DIRECTION_MASK_CARDINAL].y;
|
||||
if ((GetTile(currX + checkX2, currY + checkY2)->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) == TERRAIN_TYPE_NORMAL)
|
||||
break;
|
||||
|
||||
j--;
|
||||
if (j == 0) {
|
||||
j = DungeonRandInt(3) + 3;
|
||||
|
||||
// Turn left or right with an equal chance
|
||||
if (DungeonRandInt(100) < 50) {
|
||||
direction += 2;
|
||||
}
|
||||
else {
|
||||
direction -= 2;
|
||||
}
|
||||
|
||||
// If we'd step into an invalid grid cell, stop
|
||||
// (We don't always utilize the entire floor space)
|
||||
direction &= DIRECTION_MASK_CARDINAL;
|
||||
if (currX >= 32 && gUnknown_202F1AE == 1 && direction == DIRECTION_EAST) break;
|
||||
if (currX >= 48 && gUnknown_202F1AE == 2 && direction == DIRECTION_EAST) break;
|
||||
}
|
||||
|
||||
// Move in the current direction
|
||||
currX += gAdjacentTileOffsets[direction].x;
|
||||
currY += gAdjacentTileOffsets[direction].y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user