diff --git a/asm/code_804AFAC.s b/asm/code_804AFAC.s index e54657da0..21d398fff 100644 --- a/asm/code_804AFAC.s +++ b/asm/code_804AFAC.s @@ -5,1330 +5,6 @@ .text - thumb_func_start GenerateRoomImperfections -GenerateRoomImperfections: - push {r4-r7,lr} - mov r7, r10 - mov r6, r9 - mov r5, r8 - push {r5-r7} - sub sp, 0x44 - str r0, [sp] - str r1, [sp, 0x4] - str r2, [sp, 0x8] - movs r0, 0 - str r0, [sp, 0xC] - cmp r0, r1 - blt _0804E058 - b _0804E318 -_0804E058: - movs r2, 0 - ldr r1, [sp, 0xC] - adds r1, 0x1 - str r1, [sp, 0x28] - ldr r3, [sp, 0x8] - cmp r2, r3 - blt _0804E068 - b _0804E30C -_0804E068: - ldr r4, [sp, 0xC] - lsls r4, 4 - str r4, [sp, 0x14] - ldr r6, [sp, 0xC] - subs r0, r4, r6 - lsls r0, 5 - ldr r1, [sp] - adds r0, r1 - str r0, [sp, 0x18] -_0804E07A: - lsls r0, r2, 5 - ldr r3, [sp, 0x18] - adds r4, r0, r3 - ldrb r1, [r4, 0x8] - str r0, [sp, 0x34] - adds r2, 0x1 - str r2, [sp, 0x2C] - cmp r1, 0 - beq _0804E08E - b _0804E302 -_0804E08E: - ldrb r0, [r4, 0x11] - cmp r0, 0 - beq _0804E096 - b _0804E302 -_0804E096: - ldrb r0, [r4, 0x12] - cmp r0, 0 - beq _0804E09E - b _0804E302 -_0804E09E: - ldrb r0, [r4, 0xB] - cmp r0, 0 - bne _0804E0A6 - b _0804E302 -_0804E0A6: - ldrb r0, [r4, 0xA] - cmp r0, 0 - bne _0804E0AE - b _0804E302 -_0804E0AE: - ldrb r0, [r4, 0x9] - cmp r0, 0 - beq _0804E0B6 - b _0804E302 -_0804E0B6: - ldrb r0, [r4, 0x10] - cmp r0, 0 - beq _0804E0BE - b _0804E302 -_0804E0BE: - ldrb r0, [r4, 0x1C] - cmp r0, 0 - bne _0804E0C6 - b _0804E302 -_0804E0C6: - movs r0, 0x64 - bl DungeonRandInt - cmp r0, 0x3B - bgt _0804E0D2 - b _0804E302 -_0804E0D2: - movs r6, 0x4 - ldrsh r2, [r4, r6] - movs r1, 0 - ldrsh r0, [r4, r1] - subs r2, r0 - movs r3, 0x6 - ldrsh r0, [r4, r3] - movs r6, 0x2 - ldrsh r1, [r4, r6] - subs r0, r1 - adds r2, r0 - str r2, [sp, 0x10] - adds r0, r2, 0 - cmp r2, 0 - bge _0804E0F2 - adds r0, 0x3 -_0804E0F2: - asrs r0, 2 - str r0, [sp, 0x10] - cmp r0, 0 - bne _0804E0FE - movs r0, 0x1 - str r0, [sp, 0x10] -_0804E0FE: - movs r1, 0 - ldr r2, [sp, 0x10] - cmp r1, r2 - blt _0804E108 - b _0804E302 -_0804E108: - ldr r3, [sp, 0x14] - ldr r4, [sp, 0xC] - subs r0, r3, r4 - lsls r0, 5 - ldr r6, [sp] - adds r0, r6 - ldr r2, [sp, 0x34] - adds r0, r2, r0 - str r0, [sp, 0x20] -_0804E11A: - movs r4, 0 - adds r1, 0x1 - str r1, [sp, 0x30] -_0804E120: - movs r0, 0x4 - bl DungeonRandInt - str r0, [sp, 0x1C] - cmp r0, 0x1 - beq _0804E14A - cmp r0, 0x1 - ble _0804E138 - cmp r0, 0x2 - beq _0804E168 - cmp r0, 0x3 - beq _0804E182 -_0804E138: - ldr r3, [sp, 0x20] - movs r6, 0 - ldrsh r7, [r3, r6] - movs r1, 0x2 - ldrsh r0, [r3, r1] - mov r8, r0 - cmp r4, 0 - bne _0804E19C - b _0804E15C -_0804E14A: - ldr r2, [sp, 0x20] - movs r3, 0x4 - ldrsh r0, [r2, r3] - subs r7, r0, 0x1 - movs r0, 0x2 - ldrsh r6, [r2, r0] - mov r8, r6 - cmp r4, 0 - beq _0804E162 -_0804E15C: - movs r3, 0 - movs r2, 0x1 - b _0804E1A0 -_0804E162: - movs r3, 0x1 - negs r3, r3 - b _0804E19E -_0804E168: - ldr r1, [sp, 0x20] - movs r2, 0x4 - ldrsh r0, [r1, r2] - subs r7, r0, 0x1 - movs r3, 0x6 - ldrsh r0, [r1, r3] - subs r0, 0x1 - mov r8, r0 - cmp r4, 0 - beq _0804E194 - movs r3, 0x1 - negs r3, r3 - b _0804E19E -_0804E182: - ldr r6, [sp, 0x20] - movs r0, 0 - ldrsh r7, [r6, r0] - movs r1, 0x6 - ldrsh r0, [r6, r1] - subs r0, 0x1 - mov r8, r0 - cmp r4, 0 - beq _0804E19C -_0804E194: - movs r3, 0 - movs r2, 0x1 - negs r2, r2 - b _0804E1A0 -_0804E19C: - movs r3, 0x1 -_0804E19E: - movs r2, 0 -_0804E1A0: - movs r6, 0 - mov r9, r6 - ldr r5, [sp, 0x34] - ldr r0, [sp, 0x14] - str r0, [sp, 0x40] - ldr r6, [sp, 0x18] - adds r1, r5, r6 - movs r6, 0 - ldrsh r0, [r1, r6] - mov r10, r0 - adds r4, 0x1 - str r4, [sp, 0x24] - cmp r7, r10 - bge _0804E1BE - b _0804E2F0 -_0804E1BE: - movs r4, 0x4 - ldrsh r0, [r1, r4] - cmp r7, r0 - blt _0804E1C8 - b _0804E2F0 -_0804E1C8: - ldr r6, [sp, 0x40] - ldr r1, [sp, 0xC] - subs r0, r6, r1 - lsls r0, 5 - ldr r4, [sp] - adds r0, r4 - adds r4, r5, r0 - movs r6, 0x2 - ldrsh r0, [r4, r6] - cmp r8, r0 - bge _0804E1E0 - b _0804E2F0 -_0804E1E0: - movs r1, 0x6 - ldrsh r0, [r4, r1] - cmp r8, r0 - blt _0804E1EA - b _0804E2F0 -_0804E1EA: - adds r0, r7, 0 - mov r1, r8 - str r2, [sp, 0x38] - str r3, [sp, 0x3C] - bl GetTile - ldrh r1, [r0] - movs r0, 0x3 - ands r0, r1 - ldr r2, [sp, 0x38] - ldr r3, [sp, 0x3C] - cmp r0, 0x1 - bne _0804E2D0 - movs r6, 0 -_0804E206: - ldr r1, _0804E228 - lsls r0, r6, 2 - adds r0, r1 - movs r2, 0 - ldrsh r1, [r0, r2] - adds r1, r7 - mov r10, r1 - movs r3, 0x2 - ldrsh r0, [r0, r3] - add r0, r8 - mov r9, r0 - movs r3, 0 - movs r5, 0x1 - negs r5, r5 -_0804E222: - movs r4, 0x1 - negs r4, r4 - b _0804E22E - .align 2, 0 -_0804E228: .4byte gAdjacentTileOffsets -_0804E22C: - adds r4, 0x1 -_0804E22E: - cmp r4, 0x1 - bgt _0804E25A - mov r1, r10 - adds r0, r1, r4 - mov r2, r9 - adds r1, r2, r5 - str r3, [sp, 0x3C] - bl GetTile - adds r2, r0, 0 - ldrh r1, [r2] - movs r0, 0x3 - ands r0, r1 - ldr r3, [sp, 0x3C] - cmp r0, 0x1 - bne _0804E22C - ldrb r0, [r2, 0x9] - cmp r0, 0xFF - bne _0804E256 - movs r3, 0x1 -_0804E256: - cmp r3, 0 - beq _0804E22C -_0804E25A: - cmp r3, 0 - bne _0804E26A - adds r5, 0x1 - cmp r5, 0x1 - ble _0804E222 - adds r6, 0x1 - cmp r6, 0x7 - ble _0804E206 -_0804E26A: - cmp r6, 0x8 - bne _0804E2F0 - movs r6, 0 - ldr r3, [sp, 0x1C] - lsls r1, r3, 3 - ldr r0, _0804E2C4 - adds r4, r1, r0 -_0804E278: - ldr r0, _0804E2C8 - lsls r1, r6, 2 - adds r1, r0 - movs r2, 0 - ldrsh r0, [r1, r2] - movs r3, 0x2 - ldrsh r1, [r1, r3] - adds r0, r7, r0 - add r1, r8 - bl GetTile - ldrh r1, [r0] - movs r0, 0x3 - ands r0, r1 - movs r1, 0 - cmp r0, 0x1 - bne _0804E29C - movs r1, 0x1 -_0804E29C: - ldrb r0, [r4] - cmp r0, r1 - bne _0804E2AA - adds r4, 0x2 - adds r6, 0x2 - cmp r6, 0x7 - ble _0804E278 -_0804E2AA: - cmp r6, 0x8 - bne _0804E2F0 - adds r0, r7, 0 - mov r1, r8 - bl GetTileSafe - ldrh r2, [r0] - ldr r4, _0804E2CC - adds r1, r4, 0 - ands r2, r1 - strh r2, [r0] - b _0804E2F0 - .align 2, 0 -_0804E2C4: .4byte gUnknown_80F6DD5 -_0804E2C8: .4byte gAdjacentTileOffsets -_0804E2CC: .4byte 0x0000fffc -_0804E2D0: - adds r7, r3 - add r8, r2 - movs r6, 0x1 - add r9, r6 - mov r0, r9 - cmp r0, 0x9 - bgt _0804E2F0 - movs r1, 0 - ldrsh r0, [r4, r1] - cmp r7, r0 - blt _0804E2F0 - movs r6, 0x4 - ldrsh r0, [r4, r6] - cmp r7, r0 - bge _0804E2F0 - b _0804E1C8 -_0804E2F0: - ldr r4, [sp, 0x24] - cmp r4, 0x1 - bgt _0804E2F8 - b _0804E120 -_0804E2F8: - ldr r1, [sp, 0x30] - ldr r0, [sp, 0x10] - cmp r1, r0 - bge _0804E302 - b _0804E11A -_0804E302: - ldr r2, [sp, 0x2C] - ldr r1, [sp, 0x8] - cmp r2, r1 - bge _0804E30C - b _0804E07A -_0804E30C: - ldr r2, [sp, 0x28] - str r2, [sp, 0xC] - ldr r3, [sp, 0x4] - cmp r2, r3 - bge _0804E318 - b _0804E058 -_0804E318: - add sp, 0x44 - pop {r3-r5} - mov r8, r3 - mov r9, r4 - mov r10, r5 - pop {r4-r7} - pop {r0} - bx r0 - thumb_func_end GenerateRoomImperfections - - thumb_func_start CreateHallway -CreateHallway: - 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, 0x28] - lsls r0, 24 - mov r10, r5 - mov r9, r4 - ldr r1, [sp, 0x2C] - mov r8, r1 - ldr r7, [sp, 0x30] - cmp r0, 0 - bne _0804E350 - b _0804E470 -_0804E350: - movs r6, 0 -_0804E352: - cmp r4, r7 - beq _0804E3A8 - adds r0, r6, 0 - adds r6, 0x1 - cmp r0, 0x37 - ble _0804E360 - b _0804E57E -_0804E360: - adds r0, r5, 0 - adds r1, r4, 0 - bl GetTile - ldrh r1, [r0] - movs r0, 0x3 - ands r0, r1 - cmp r0, 0x1 - beq _0804E390 - adds r0, r5, 0 - adds r1, r4, 0 - bl GetTileSafe - ldrh r2, [r0] - ldr r3, _0804E38C - adds r1, r3, 0 - ands r2, r1 - movs r1, 0x1 - orrs r2, r1 - strh r2, [r0] - b _0804E39C - .align 2, 0 -_0804E38C: .4byte 0x0000fffc -_0804E390: - cmp r5, r10 - beq _0804E396 - b _0804E57E -_0804E396: - cmp r4, r9 - beq _0804E39C - b _0804E57E -_0804E39C: - cmp r4, r7 - bge _0804E3A4 - adds r4, 0x1 - b _0804E352 -_0804E3A4: - subs r4, 0x1 - b _0804E352 -_0804E3A8: - movs r6, 0 - ldr r0, [sp] - cmp r5, r0 - beq _0804E40A - movs r7, 0 -_0804E3B2: - adds r0, r6, 0 - adds r6, 0x1 - cmp r0, 0x37 - ble _0804E3BC - b _0804E57E -_0804E3BC: - adds r0, r5, 0 - adds r1, r4, 0 - bl GetTile - ldrh r1, [r0] - movs r0, 0x3 - ands r0, r1 - cmp r0, 0x1 - beq _0804E3EC - adds r0, r5, 0 - adds r1, r4, 0 - bl GetTileSafe - ldrh r2, [r0] - ldr r3, _0804E3E8 - adds r1, r3, 0 - ands r2, r1 - movs r1, 0x1 - orrs r2, r1 - strh r2, [r0] - b _0804E3F8 - .align 2, 0 -_0804E3E8: .4byte 0x0000fffc -_0804E3EC: - cmp r5, r10 - beq _0804E3F2 - b _0804E57E -_0804E3F2: - cmp r4, r9 - beq _0804E3F8 - b _0804E57E -_0804E3F8: - ldr r0, [sp] - cmp r5, r0 - bge _0804E402 - adds r5, 0x1 - b _0804E404 -_0804E402: - subs r5, 0x1 -_0804E404: - ldr r1, [sp] - cmp r5, r1 - bne _0804E3B2 -_0804E40A: - movs r6, 0 - ldr r3, [sp, 0x4] - cmp r4, r3 - bne _0804E414 - b _0804E57E -_0804E414: - movs r7, 0 -_0804E416: - adds r0, r6, 0 - adds r6, 0x1 - cmp r0, 0x37 - ble _0804E420 - b _0804E57E -_0804E420: - adds r0, r5, 0 - adds r1, r4, 0 - bl GetTile - ldrh r1, [r0] - movs r0, 0x3 - ands r0, r1 - cmp r0, 0x1 - beq _0804E450 - adds r0, r5, 0 - adds r1, r4, 0 - bl GetTileSafe - ldrh r2, [r0] - ldr r3, _0804E44C - adds r1, r3, 0 - ands r2, r1 - movs r1, 0x1 - orrs r2, r1 - strh r2, [r0] - b _0804E45C - .align 2, 0 -_0804E44C: .4byte 0x0000fffc -_0804E450: - cmp r5, r10 - beq _0804E456 - b _0804E57E -_0804E456: - cmp r4, r9 - beq _0804E45C - b _0804E57E -_0804E45C: - ldr r0, [sp, 0x4] - cmp r4, r0 - bge _0804E466 - adds r4, 0x1 - b _0804E468 -_0804E466: - subs r4, 0x1 -_0804E468: - ldr r1, [sp, 0x4] - cmp r4, r1 - bne _0804E416 - b _0804E57E -_0804E470: - movs r6, 0 - cmp r5, r8 - beq _0804E4C6 - movs r7, 0 -_0804E478: - adds r0, r6, 0 - adds r6, 0x1 - cmp r0, 0x37 - ble _0804E482 - b _0804E57E -_0804E482: - adds r0, r5, 0 - adds r1, r4, 0 - bl GetTile - ldrh r1, [r0] - movs r0, 0x3 - ands r0, r1 - cmp r0, 0x1 - beq _0804E4B0 - adds r0, r5, 0 - adds r1, r4, 0 - bl GetTileSafe - ldrh r2, [r0] - ldr r3, _0804E4AC - adds r1, r3, 0 - ands r2, r1 - movs r1, 0x1 - orrs r2, r1 - strh r2, [r0] - b _0804E4B8 - .align 2, 0 -_0804E4AC: .4byte 0x0000fffc -_0804E4B0: - cmp r5, r10 - bne _0804E57E - cmp r4, r9 - bne _0804E57E -_0804E4B8: - cmp r5, r8 - bge _0804E4C0 - adds r5, 0x1 - b _0804E4C2 -_0804E4C0: - subs r5, 0x1 -_0804E4C2: - cmp r5, r8 - bne _0804E478 -_0804E4C6: - movs r6, 0 - ldr r0, [sp, 0x4] - cmp r4, r0 - beq _0804E522 - movs r7, 0 -_0804E4D0: - adds r0, r6, 0 - adds r6, 0x1 - cmp r0, 0x37 - bgt _0804E57E - adds r0, r5, 0 - adds r1, r4, 0 - bl GetTile - ldrh r1, [r0] - movs r0, 0x3 - ands r0, r1 - cmp r0, 0x1 - beq _0804E508 - adds r0, r5, 0 - adds r1, r4, 0 - bl GetTileSafe - ldrh r2, [r0] - ldr r3, _0804E504 - adds r1, r3, 0 - ands r2, r1 - movs r1, 0x1 - orrs r2, r1 - strh r2, [r0] - b _0804E510 - .align 2, 0 -_0804E504: .4byte 0x0000fffc -_0804E508: - cmp r5, r10 - bne _0804E57E - cmp r4, r9 - bne _0804E57E -_0804E510: - ldr r0, [sp, 0x4] - cmp r4, r0 - bge _0804E51A - adds r4, 0x1 - b _0804E51C -_0804E51A: - subs r4, 0x1 -_0804E51C: - ldr r1, [sp, 0x4] - cmp r4, r1 - bne _0804E4D0 -_0804E522: - movs r6, 0 - ldr r3, [sp] - cmp r5, r3 - beq _0804E57E - movs r7, 0 -_0804E52C: - adds r0, r6, 0 - adds r6, 0x1 - cmp r0, 0x37 - bgt _0804E57E - adds r0, r5, 0 - adds r1, r4, 0 - bl GetTile - ldrh r1, [r0] - movs r0, 0x3 - ands r0, r1 - cmp r0, 0x1 - beq _0804E564 - adds r0, r5, 0 - adds r1, r4, 0 - bl GetTileSafe - ldrh r2, [r0] - ldr r3, _0804E560 - adds r1, r3, 0 - ands r2, r1 - movs r1, 0x1 - orrs r2, r1 - strh r2, [r0] - b _0804E56C - .align 2, 0 -_0804E560: .4byte 0x0000fffc -_0804E564: - cmp r5, r10 - bne _0804E57E - cmp r4, r9 - bne _0804E57E -_0804E56C: - ldr r0, [sp] - cmp r5, r0 - bge _0804E576 - adds r5, 0x1 - b _0804E578 -_0804E576: - subs r5, 0x1 -_0804E578: - ldr r1, [sp] - cmp r5, r1 - bne _0804E52C -_0804E57E: - 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 CreateHallway - - thumb_func_start EnsureConnectedGrid -EnsureConnectedGrid: - push {r4-r7,lr} - mov r7, r10 - mov r6, r9 - mov r5, r8 - push {r5-r7} - sub sp, 0x40 - str r0, [sp, 0xC] - str r1, [sp, 0x10] - str r2, [sp, 0x14] - str r3, [sp, 0x18] - movs r0, 0 - str r0, [sp, 0x1C] - cmp r0, r1 - blt _0804E5AE - b _0804E8AA -_0804E5AE: - movs r1, 0x1 - mov r10, r1 -_0804E5B2: - movs r2, 0 - str r2, [sp, 0x20] - ldr r3, [sp, 0x1C] - adds r3, 0x1 - str r3, [sp, 0x2C] - ldr r4, [sp, 0x14] - cmp r2, r4 - blt _0804E5C4 - b _0804E89E -_0804E5C4: - ldr r5, [sp, 0x1C] - lsls r5, 4 - ldr r6, [sp, 0x1C] - subs r1, r5, r6 - lsls r1, 5 - ldr r2, [sp, 0xC] - movs r3, 0xF0 - lsls r3, 1 - adds r0, r2, r3 - adds r0, r1 - mov r8, r0 - adds r6, r1, r2 - ldr r4, _0804E6A4 - adds r0, r2, r4 - adds r7, r1, r0 - adds r0, r2, 0 - adds r0, 0x20 - adds r0, r1 - mov r9, r0 - ldr r5, [sp, 0x60] - str r5, [sp, 0x34] - adds r0, r2, 0 - subs r0, 0x20 - adds r1, r0 - str r1, [sp, 0x38] - movs r0, 0 - str r0, [sp, 0x3C] - ldr r1, [sp, 0x1C] - lsls r0, r1, 2 - ldr r2, [sp, 0x18] - adds r0, r2 - str r0, [sp, 0x28] -_0804E604: - ldr r3, [sp, 0x1C] - lsls r0, r3, 4 - subs r0, r3 - lsls r0, 5 - ldr r4, [sp, 0xC] - adds r0, r4 - ldr r5, [sp, 0x3C] - adds r4, r5, r0 - ldrb r0, [r4, 0x8] - cmp r0, 0 - beq _0804E61C - b _0804E874 -_0804E61C: - ldrb r0, [r4, 0x11] - cmp r0, 0 - beq _0804E624 - b _0804E874 -_0804E624: - ldrb r0, [r4, 0xB] - cmp r0, 0 - beq _0804E62C - b _0804E874 -_0804E62C: - ldrb r0, [r4, 0xA] - cmp r0, 0 - bne _0804E634 - b _0804E848 -_0804E634: - ldrb r0, [r4, 0x9] - cmp r0, 0 - beq _0804E63C - b _0804E848 -_0804E63C: - movs r1, 0 - ldrsh r0, [r4, r1] - adds r0, 0x1 - movs r2, 0x4 - ldrsh r1, [r4, r2] - subs r1, 0x1 - bl DungeonRandRange - str r0, [sp, 0x24] - movs r3, 0x2 - ldrsh r0, [r4, r3] - adds r0, 0x1 - movs r5, 0x6 - ldrsh r1, [r4, r5] - subs r1, 0x1 - bl DungeonRandRange - adds r5, r0, 0 - ldr r0, [sp, 0x20] - cmp r0, 0 - ble _0804E6DC - subs r4, 0x20 - ldrb r0, [r4, 0x8] - cmp r0, 0 - bne _0804E6DC - ldrb r0, [r4, 0x12] - cmp r0, 0 - bne _0804E6DC - ldrb r0, [r4, 0xB] - cmp r0, 0 - beq _0804E6DC - ldrb r0, [r4, 0xA] - cmp r0, 0 - beq _0804E6A8 - movs r1, 0 - ldrsh r0, [r4, r1] - adds r0, 0x1 - movs r2, 0x4 - ldrsh r1, [r4, r2] - subs r1, 0x1 - bl DungeonRandRange - adds r5, r0, 0 - movs r3, 0x2 - ldrsh r0, [r4, r3] - adds r0, 0x1 - movs r2, 0x6 - ldrsh r1, [r4, r2] - subs r1, 0x1 - bl DungeonRandRange - b _0804E6AC - .align 2, 0 -_0804E6A4: .4byte 0xfffffe20 -_0804E6A8: - movs r3, 0 - ldrsh r5, [r4, r3] -_0804E6AC: - movs r4, 0x2 - ldrsh r1, [r6, r4] - ldr r0, [sp, 0x38] - movs r2, 0x6 - ldrsh r3, [r0, r2] - subs r3, 0x1 - mov r4, r10 - str r4, [sp] - ldr r2, [sp, 0x28] - ldr r0, [r2] - str r0, [sp, 0x4] - ldr r4, [sp, 0x34] - ldr r0, [r4] - str r0, [sp, 0x8] - ldr r0, [sp, 0x24] - adds r2, r5, 0 - bl CreateHallway - mov r5, r10 - strb r5, [r6, 0xB] - strb r5, [r6, 0x13] - ldr r0, [sp, 0x38] - strb r5, [r0, 0x14] - b _0804E874 -_0804E6DC: - ldr r0, [sp, 0x14] - subs r0, 0x1 - ldr r1, [sp, 0x20] - cmp r1, r0 - bge _0804E758 - mov r2, r9 - ldrb r0, [r2, 0x8] - cmp r0, 0 - bne _0804E758 - ldrb r0, [r2, 0x12] - cmp r0, 0 - bne _0804E758 - ldrb r0, [r2, 0xB] - cmp r0, 0 - beq _0804E758 - ldrb r0, [r2, 0xA] - cmp r0, 0 - beq _0804E724 - movs r3, 0x20 - ldrsh r0, [r6, r3] - adds r0, 0x1 - movs r4, 0x24 - ldrsh r1, [r6, r4] - subs r1, 0x1 - bl DungeonRandRange - adds r5, r0, 0 - movs r1, 0x22 - ldrsh r0, [r6, r1] - adds r0, 0x1 - movs r2, 0x26 - ldrsh r1, [r6, r2] - subs r1, 0x1 - bl DungeonRandRange - b _0804E728 -_0804E724: - movs r3, 0x20 - ldrsh r5, [r6, r3] -_0804E728: - movs r4, 0x6 - ldrsh r1, [r6, r4] - subs r1, 0x1 - movs r0, 0x22 - ldrsh r3, [r6, r0] - mov r2, r10 - str r2, [sp] - ldr r4, [sp, 0x28] - ldr r0, [r4] - str r0, [sp, 0x4] - ldr r2, [sp, 0x34] - ldr r0, [r2, 0x4] - subs r0, 0x1 - str r0, [sp, 0x8] - ldr r0, [sp, 0x24] - adds r2, r5, 0 - bl CreateHallway - mov r3, r10 - strb r3, [r6, 0xB] - strb r3, [r6, 0x14] - mov r4, r9 - strb r3, [r4, 0x13] - b _0804E874 -_0804E758: - ldr r0, [sp, 0x1C] - cmp r0, 0 - ble _0804E7C8 - ldrb r0, [r7, 0x8] - cmp r0, 0 - bne _0804E7C8 - ldrb r0, [r7, 0x12] - cmp r0, 0 - bne _0804E7C8 - ldrb r0, [r7, 0xB] - cmp r0, 0 - beq _0804E7C8 - ldrb r0, [r7, 0xA] - cmp r0, 0 - beq _0804E79A - movs r1, 0 - ldrsh r0, [r7, r1] - adds r0, 0x1 - movs r2, 0x4 - ldrsh r1, [r7, r2] - subs r1, 0x1 - bl DungeonRandRange - movs r3, 0x2 - ldrsh r0, [r7, r3] - adds r0, 0x1 - movs r4, 0x6 - ldrsh r1, [r7, r4] - subs r1, 0x1 - bl DungeonRandRange - adds r3, r0, 0 - b _0804E79E -_0804E79A: - movs r0, 0x2 - ldrsh r3, [r7, r0] -_0804E79E: - movs r1, 0 - ldrsh r0, [r6, r1] - movs r4, 0 - ldrsh r2, [r7, r4] - subs r2, 0x1 - movs r1, 0 - str r1, [sp] - ldr r4, [sp, 0x28] - ldr r1, [r4] - str r1, [sp, 0x4] - ldr r4, [sp, 0x34] - ldr r1, [r4] - str r1, [sp, 0x8] - adds r1, r5, 0 - bl CreateHallway - mov r5, r10 - strb r5, [r6, 0xB] - strb r5, [r6, 0x15] - strb r5, [r7, 0x16] - b _0804E874 -_0804E7C8: - ldr r0, [sp, 0x10] - subs r0, 0x1 - ldr r1, [sp, 0x1C] - cmp r1, r0 - bge _0804E874 - mov r2, r8 - ldrb r0, [r2, 0x8] - cmp r0, 0 - bne _0804E874 - ldrb r0, [r2, 0x12] - cmp r0, 0 - bne _0804E874 - ldrb r0, [r2, 0xB] - cmp r0, 0 - beq _0804E874 - ldrb r0, [r2, 0xA] - cmp r0, 0 - beq _0804E812 - movs r3, 0 - ldrsh r0, [r2, r3] - adds r0, 0x1 - movs r4, 0x4 - ldrsh r1, [r2, r4] - subs r1, 0x1 - bl DungeonRandRange - mov r1, r8 - movs r2, 0x2 - ldrsh r0, [r1, r2] - adds r0, 0x1 - movs r3, 0x6 - ldrsh r1, [r1, r3] - subs r1, 0x1 - bl DungeonRandRange - adds r3, r0, 0 - b _0804E818 -_0804E812: - mov r4, r8 - movs r0, 0x2 - ldrsh r3, [r4, r0] -_0804E818: - movs r1, 0x4 - ldrsh r0, [r6, r1] - subs r0, 0x1 - mov r4, r8 - movs r1, 0 - ldrsh r2, [r4, r1] - movs r1, 0 - str r1, [sp] - ldr r4, [sp, 0x28] - ldr r1, [r4, 0x4] - subs r1, 0x1 - str r1, [sp, 0x4] - ldr r4, [sp, 0x34] - ldr r1, [r4] - str r1, [sp, 0x8] - adds r1, r5, 0 - bl CreateHallway - mov r5, r10 - strb r5, [r6, 0xB] - strb r5, [r6, 0x16] - mov r0, r8 - strb r5, [r0, 0x15] - b _0804E874 -_0804E848: - movs r1, 0 - ldrsh r0, [r6, r1] - movs r2, 0x2 - ldrsh r1, [r6, r2] - bl GetTileSafe - ldrh r1, [r0] - ldr r3, _0804E99C - adds r2, r3, 0 - ands r1, r2 - strh r1, [r0] - ldrh r1, [r0, 0x4] - ldr r4, _0804E9A0 - adds r2, r4, 0 - ands r1, r2 - ldr r5, _0804E9A4 - adds r2, r5, 0 - ands r1, r2 - subs r3, 0x1 - adds r2, r3, 0 - ands r1, r2 - strh r1, [r0, 0x4] -_0804E874: - movs r4, 0x20 - add r8, r4 - adds r6, 0x20 - adds r7, 0x20 - add r9, r4 - ldr r5, [sp, 0x34] - adds r5, 0x4 - str r5, [sp, 0x34] - ldr r0, [sp, 0x38] - adds r0, 0x20 - str r0, [sp, 0x38] - ldr r1, [sp, 0x3C] - adds r1, 0x20 - str r1, [sp, 0x3C] - ldr r2, [sp, 0x20] - adds r2, 0x1 - str r2, [sp, 0x20] - ldr r3, [sp, 0x14] - cmp r2, r3 - bge _0804E89E - b _0804E604 -_0804E89E: - ldr r4, [sp, 0x2C] - str r4, [sp, 0x1C] - ldr r5, [sp, 0x10] - cmp r4, r5 - bge _0804E8AA - b _0804E5B2 -_0804E8AA: - movs r6, 0 - str r6, [sp, 0x1C] - ldr r0, [sp, 0x10] - cmp r6, r0 - bge _0804E98A -_0804E8B4: - movs r1, 0 - str r1, [sp, 0x20] - ldr r2, [sp, 0x1C] - adds r2, 0x1 - str r2, [sp, 0x2C] - ldr r3, [sp, 0x14] - cmp r1, r3 - bge _0804E980 - ldr r4, [sp, 0x1C] - lsls r4, 4 - mov r9, r4 -_0804E8CA: - ldr r5, [sp, 0x20] - lsls r2, r5, 5 - ldr r6, [sp, 0x1C] - lsls r3, r6, 4 - subs r0, r3, r6 - lsls r0, 5 - ldr r1, [sp, 0xC] - adds r4, r0, r1 - adds r1, r2, r4 - ldrb r0, [r1, 0x8] - mov r8, r2 - adds r5, 0x1 - str r5, [sp, 0x30] - cmp r0, 0 - bne _0804E976 - ldrb r0, [r1, 0x11] - cmp r0, 0 - bne _0804E976 - ldrb r0, [r1, 0xB] - cmp r0, 0 - bne _0804E976 - ldrb r0, [r1, 0xF] - cmp r0, 0 - bne _0804E976 - movs r6, 0 - ldrsh r5, [r1, r6] - movs r6, 0x4 - ldrsh r0, [r1, r6] - cmp r5, r0 - bge _0804E976 - mov r10, r4 -_0804E908: - ldr r1, [sp, 0x1C] - subs r0, r3, r1 - lsls r0, 5 - ldr r3, [sp, 0xC] - adds r0, r3 - adds r0, r2, r0 - movs r6, 0x2 - ldrsh r4, [r0, r6] - movs r1, 0x6 - ldrsh r0, [r0, r1] - adds r7, r5, 0x1 - cmp r4, r0 - bge _0804E95C - mov r6, r8 - add r6, r10 -_0804E926: - adds r0, r5, 0 - adds r1, r4, 0 - bl GetTileSafe - ldrh r2, [r0] - ldr r3, _0804E99C - adds r1, r3, 0 - ands r2, r1 - strh r2, [r0] - ldrh r2, [r0, 0x4] - adds r3, 0x1 - adds r1, r3, 0 - ands r2, r1 - adds r3, 0x1 - adds r1, r3, 0 - ands r2, r1 - subs r3, 0x3 - adds r1, r3, 0 - ands r2, r1 - strh r2, [r0, 0x4] - movs r1, 0xFF - strb r1, [r0, 0x9] - adds r4, 0x1 - movs r1, 0x6 - ldrsh r0, [r6, r1] - cmp r4, r0 - blt _0804E926 -_0804E95C: - adds r5, r7, 0 - mov r2, r8 - mov r3, r9 - ldr r4, [sp, 0x1C] - subs r0, r3, r4 - lsls r0, 5 - ldr r6, [sp, 0xC] - adds r0, r6 - adds r0, r2, r0 - movs r1, 0x4 - ldrsh r0, [r0, r1] - cmp r5, r0 - blt _0804E908 -_0804E976: - ldr r2, [sp, 0x30] - str r2, [sp, 0x20] - ldr r3, [sp, 0x14] - cmp r2, r3 - blt _0804E8CA -_0804E980: - ldr r4, [sp, 0x2C] - str r4, [sp, 0x1C] - ldr r5, [sp, 0x10] - cmp r4, r5 - blt _0804E8B4 -_0804E98A: - add sp, 0x40 - pop {r3-r5} - mov r8, r3 - mov r9, r4 - mov r10, r5 - pop {r4-r7} - pop {r0} - bx r0 - .align 2, 0 -_0804E99C: .4byte 0x0000fffc -_0804E9A0: .4byte 0x0000fffe -_0804E9A4: .4byte 0x0000fffd - thumb_func_end EnsureConnectedGrid - - thumb_func_start sub_804E9A8 -sub_804E9A8: - push {r4,r5,lr} - adds r4, r0, 0 - lsls r1, 24 - lsls r2, 24 - lsrs r2, 24 - ldrh r0, [r4] - ldr r5, _0804E9D8 - adds r3, r5, 0 - ands r3, r0 - strh r3, [r4] - cmp r1, 0 - beq _0804E9D0 - ldrb r0, [r4, 0x9] - cmp r0, r2 - bne _0804E9D0 - adds r0, r3, 0 - ands r0, r5 - movs r1, 0x2 - orrs r0, r1 - strh r0, [r4] -_0804E9D0: - pop {r4,r5} - pop {r0} - bx r0 - .align 2, 0 -_0804E9D8: .4byte 0x0000fffc - thumb_func_end sub_804E9A8 thumb_func_start sub_804E9DC sub_804E9DC: @@ -2802,7 +1478,7 @@ _0804F4BA: mov r1, r9 mov r3, r8 lsrs r2, r3, 24 - bl sub_804E9A8 + bl SetTerrainObstacleChecked _0804F4D6: adds r0, r6, 0 mov r1, r10 @@ -2885,7 +1561,7 @@ _0804F55A: mov r1, r9 mov r3, r8 lsrs r2, r3, 24 - bl sub_804E9A8 + bl SetTerrainObstacleChecked adds r5, 0x2 b _0804F4BA _0804F570: @@ -2895,7 +1571,7 @@ _0804F570: mov r1, r9 mov r3, r8 lsrs r2, r3, 24 - bl sub_804E9A8 + bl SetTerrainObstacleChecked subs r4, 0x2 b _0804F4BA _0804F586: @@ -2905,7 +1581,7 @@ _0804F586: mov r1, r9 mov r3, r8 lsrs r2, r3, 24 - bl sub_804E9A8 + bl SetTerrainObstacleChecked subs r5, 0x2 b _0804F4BA _0804F59C: @@ -2915,7 +1591,7 @@ _0804F59C: mov r1, r9 mov r3, r8 lsrs r2, r3, 24 - bl sub_804E9A8 + bl SetTerrainObstacleChecked adds r4, 0x2 b _0804F4BA _0804F5B2: diff --git a/include/structs/map.h b/include/structs/map.h index cda59ded2..7e8e22a16 100644 --- a/include/structs/map.h +++ b/include/structs/map.h @@ -9,6 +9,7 @@ enum TerrainType { + TERRAIN_TYPE_WALL = 0, // x0 When neither TERRAIN_TYPE_NORMAL nor TERRAIN_TYPE_SECONDARY are set TERRAIN_TYPE_NORMAL = 1 << 0, // x1 TERRAIN_TYPE_SECONDARY = 1 << 1, // Water or lava depending on the dungeon. x2 TERRAIN_TYPE_UNK_2 = 1 << 2, // x4 diff --git a/src/code_804AFAC_1.c b/src/code_804AFAC_1.c index 83ad0a0c9..5e70d51bc 100644 --- a/src/code_804AFAC_1.c +++ b/src/code_804AFAC_1.c @@ -70,13 +70,29 @@ struct FileFixedmapPosStruct u8 y; }; -static inline void SetTerrainNormal(Tile *tile) +// Helper functions for terrain flags +static inline void SetTerrainType(Tile *tile, u32 terrainType) { tile->terrainType &= ~(TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY); - tile->terrainType |= TERRAIN_TYPE_NORMAL; + tile->terrainType |= terrainType; } -static inline u32 GetTerrain(Tile *tile) +static inline void SetTerrainNormal(Tile *tile) +{ + SetTerrainType(tile, TERRAIN_TYPE_NORMAL); +} + +static inline void SetTerrainSecondary(Tile *tile) +{ + SetTerrainType(tile, TERRAIN_TYPE_SECONDARY); +} + +static inline void SetTerrainWall(Tile *tile) +{ + SetTerrainType(tile, TERRAIN_TYPE_WALL); +} + +static inline u32 GetTerrainType(Tile *tile) { return tile->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY); } @@ -972,15 +988,15 @@ void sub_804B534(s32 xStart, s32 yStart, s32 maxX, s32 maxY) Tile *tile = GetTileSafe(x, y); tile->terrainType &= ~(TERRAIN_TYPE_UNK_2); - if (tile->room == CORRIDOR_ROOM && (GetTerrain(tile) == TERRAIN_TYPE_NORMAL)) { - if (x > 0 && (GetTerrain(GetTile(x - 1, y)) == TERRAIN_TYPE_NORMAL)) + if (tile->room == CORRIDOR_ROOM && (GetTerrainType(tile) == TERRAIN_TYPE_NORMAL)) { + if (x > 0 && (GetTerrainType(GetTile(x - 1, y)) == TERRAIN_TYPE_NORMAL)) unkCount++; - if (y > 0 && (GetTerrain(GetTile(x, y - 1)) == TERRAIN_TYPE_NORMAL)) + if (y > 0 && (GetTerrainType(GetTile(x, y - 1)) == TERRAIN_TYPE_NORMAL)) unkCount++; - if (x < DUNGEON_MAX_SIZE_X - 2 && (GetTerrain(GetTile(x + 1, y)) == TERRAIN_TYPE_NORMAL)) + if (x < DUNGEON_MAX_SIZE_X - 2 && (GetTerrainType(GetTile(x + 1, y)) == TERRAIN_TYPE_NORMAL)) unkCount++; // BUG: It should check for y and not x. Not sure if it has any effect, because this function is called only once with maxY equal to DUNGEON_MAX_SIZE_Y - if (x < DUNGEON_MAX_SIZE_Y - 2 && (GetTerrain(GetTile(x, y + 1)) == TERRAIN_TYPE_NORMAL)) + if (x < DUNGEON_MAX_SIZE_Y - 2 && (GetTerrainType(GetTile(x, y + 1)) == TERRAIN_TYPE_NORMAL)) unkCount++; if (unkCount > 2) { @@ -1858,7 +1874,7 @@ void GenerateExtraHallways(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s // Keep walking until an obstacle is encountered while (1) { - if (GetTerrain(GetTile(currX, currY)) != TERRAIN_TYPE_NORMAL) + if (GetTerrainType(GetTile(currX, currY)) != TERRAIN_TYPE_NORMAL) break; currX += gAdjacentTileOffsets[direction].x; @@ -1866,7 +1882,7 @@ void GenerateExtraHallways(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s } // Abort if we reached secondary terrain - if (GetTerrain(GetTile(currX, currY)) == TERRAIN_TYPE_SECONDARY) + if (GetTerrainType(GetTile(currX, currY)) == TERRAIN_TYPE_SECONDARY) continue; // Check that the current tile is at least 2 away from the map border @@ -1887,13 +1903,13 @@ void GenerateExtraHallways(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s // 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 (GetTerrain(GetTile(currX + checkX, currY + checkY)) == TERRAIN_TYPE_NORMAL) + if (GetTerrainType(GetTile(currX + checkX, currY + checkY)) == 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 (GetTerrain(GetTile(currX + checkX2, currY + checkY2)) == TERRAIN_TYPE_NORMAL) + if (GetTerrainType(GetTile(currX + checkX2, currY + checkY2)) == TERRAIN_TYPE_NORMAL) continue; // Number of steps to walk in one direction before turning @@ -1909,7 +1925,7 @@ void GenerateExtraHallways(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s if (currX <= 1 || currY <= 1 || currX >= DUNGEON_MAX_SIZE_X - 1 || currY >= DUNGEON_MAX_SIZE_Y - 1) break; - if (GetTerrain(GetTile(currX, currY)) == TERRAIN_TYPE_NORMAL) + if (GetTerrainType(GetTile(currX, currY)) == TERRAIN_TYPE_NORMAL) break; if (GetTile(currX, currY)->terrainType & TERRAIN_TYPE_IMPASSABLE_WALL) break; @@ -1917,33 +1933,33 @@ void GenerateExtraHallways(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s willNotMakeSquare = TRUE; // Check Bottom to Right - if ((GetTerrain(GetTile(currX + 1, currY)) == TERRAIN_TYPE_NORMAL) && - (GetTerrain(GetTile(currX + 1, currY + 1)) == TERRAIN_TYPE_NORMAL) && - (GetTerrain(GetTile(currX, currY + 1)) == TERRAIN_TYPE_NORMAL)) + if ((GetTerrainType(GetTile(currX + 1, currY)) == TERRAIN_TYPE_NORMAL) && + (GetTerrainType(GetTile(currX + 1, currY + 1)) == TERRAIN_TYPE_NORMAL) && + (GetTerrainType(GetTile(currX, currY + 1)) == TERRAIN_TYPE_NORMAL)) { willNotMakeSquare = FALSE; } // Check Top to Right - if ((GetTerrain(GetTile(currX + 1, currY)) == TERRAIN_TYPE_NORMAL) && - (GetTerrain(GetTile(currX + 1, currY - 1)) == TERRAIN_TYPE_NORMAL) && - (GetTerrain(GetTile(currX, currY - 1)) == TERRAIN_TYPE_NORMAL)) + if ((GetTerrainType(GetTile(currX + 1, currY)) == TERRAIN_TYPE_NORMAL) && + (GetTerrainType(GetTile(currX + 1, currY - 1)) == TERRAIN_TYPE_NORMAL) && + (GetTerrainType(GetTile(currX, currY - 1)) == TERRAIN_TYPE_NORMAL)) { willNotMakeSquare = FALSE; } // Check Bottom to Left - if ((GetTerrain(GetTile(currX - 1, currY)) == TERRAIN_TYPE_NORMAL) && - (GetTerrain(GetTile(currX - 1, currY + 1)) == TERRAIN_TYPE_NORMAL) && - (GetTerrain(GetTile(currX, currY + 1)) == TERRAIN_TYPE_NORMAL)) + if ((GetTerrainType(GetTile(currX - 1, currY)) == TERRAIN_TYPE_NORMAL) && + (GetTerrainType(GetTile(currX - 1, currY + 1)) == TERRAIN_TYPE_NORMAL) && + (GetTerrainType(GetTile(currX, currY + 1)) == TERRAIN_TYPE_NORMAL)) { willNotMakeSquare = FALSE; } // Check Top to Left - if ((GetTerrain(GetTile(currX - 1, currY)) == TERRAIN_TYPE_NORMAL) && - (GetTerrain(GetTile(currX - 1, currY - 1)) == TERRAIN_TYPE_NORMAL) && - (GetTerrain(GetTile(currX, currY - 1)) == TERRAIN_TYPE_NORMAL)) + if ((GetTerrainType(GetTile(currX - 1, currY)) == TERRAIN_TYPE_NORMAL) && + (GetTerrainType(GetTile(currX - 1, currY - 1)) == TERRAIN_TYPE_NORMAL) && + (GetTerrainType(GetTile(currX, currY - 1)) == TERRAIN_TYPE_NORMAL)) { willNotMakeSquare = FALSE; } @@ -1957,13 +1973,13 @@ void GenerateExtraHallways(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s // 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 (GetTerrain(GetTile(currX + checkX, currY + checkY)) == TERRAIN_TYPE_NORMAL) + if (GetTerrainType(GetTile(currX + checkX, currY + checkY)) == 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 (GetTerrain(GetTile(currX + checkX2, currY + checkY2)) == TERRAIN_TYPE_NORMAL) + if (GetTerrainType(GetTile(currX + checkX2, currY + checkY2)) == TERRAIN_TYPE_NORMAL) break; j--; @@ -2163,8 +2179,10 @@ void AssignRooms(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSiz gUnknown_202F1AD = FALSE; } -#define GENERATION_CONSTANT_SECONDARY_STRUCTURE_FLAG_CHANCE 80 -#define GENERATION_CONSTANT_MERGE_ROOMS_CHANCE 5 +// Todo: move to header +#define GENERATION_CONSTANT_MERGE_ROOMS_CHANCE 5 // (0 to 100) probability to merge two rooms together +#define GENERATION_CONSTANT_NO_IMPERFECTIONS_CHANCE 60 // (0 to 100) probability that a room will not have imperfections, if it was already flagged for them +#define GENERATION_CONSTANT_SECONDARY_STRUCTURE_FLAG_CHANCE 80 // (0 to 100) probability that a room will be flagged to have a secondary structure. /* * CreateRoomsAndAnchors - Creates the rectangle regions of open terrain for each room @@ -2963,4 +2981,549 @@ void CreateGridCellConnections(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN } } +extern const bool8 gUnknown_80F6DD5[][NUM_DIRECTIONS]; + +/* + * GenerateRoomImperfections - Attempt to generate room imperfections for each room, if flagged to do so. + * + * Rooms are flagged for whether to allow imperfections in CreateRoomsAndAnchors. + * Each qualifying flagged room has a 40% chance to generate imperfections in the room. + * + * Imperfections are generated by randomly growing walls of the room inwards + * for a certain number of iterations, depending on the average length of the room. + * + * Each iteration will go in both a counterclockwise and clockwise generation movement (not necessarily for the same corner though) + * + * We pick a random corner, derive our direction from the movement being used, then seek up to 10 tiles for one to replace. + * We avoid getting too close to hallways and ensure our cardinal neighbor tiles match what we expect for open terrain. + */ +void GenerateRoomImperfections(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY) +{ + s32 x, y; + + for (x = 0; x < gridSizeX; x++) { + for (y = 0; y < gridSizeY; y++) { + s32 counter, length; + // To have imperfections a room must: + // - be valid + // - not have been merged + // - be a room + // - be connected + // - not have a secondary structure + // - not be a maze room + // - be flagged to be made imperfect + if (grid[x][y].isInvalid) + continue; + if (grid[x][y].hasBeenMerged) + continue; + if (grid[x][y].isMerged) + continue; + if (!grid[x][y].isConnected) + continue; + if (!grid[x][y].isRoom) + continue; + if (grid[x][y].hasSecondaryStructure) + continue; + if (grid[x][y].isMazeRoom) + continue; + if (!grid[x][y].flagImperfect) + continue; + + // Roll for imperfections + // By default, is a 40% chance that the room will still have imperfections + if (DungeonRandInt(100) < GENERATION_CONSTANT_NO_IMPERFECTIONS_CHANCE) + continue; + + length = grid[x][y].end.x - grid[x][y].start.x + (grid[x][y].end.y - grid[x][y].start.y); + length /= 4; + if (length == 0) + length = 1; + + // Shrink the room from its corners either in the x or y direction + // Repeat the number of times equal to the average room length + for (counter = 0; counter < length; counter++) { + s32 i, v; + for (i = 0; i < 2; i++) { + // Start from one of four corners + // i == 0 => fill in walls counterclockwise + // i == 1 => fill in walls clockwise + s32 pt_x, pt_y; + s32 moveX, moveY; + s32 startingCorner = DungeonRandInt(4); + + switch (startingCorner) { + // Top-left corner + case 0: + default: + pt_x = grid[x][y].start.x; + pt_y = grid[x][y].start.y; + if (i != 0) { + moveX = 1; + moveY = 0; + } + else { + moveX = 0; + moveY = 1; + } + break; + // Top-right corner + case 1: + pt_x = grid[x][y].end.x - 1; + pt_y = grid[x][y].start.y; + if (i != 0) { + moveX = 0; + moveY = 1; + } + else { + moveX = -1; + moveY = 0; + } + break; + // Bottom-right corner + case 2: + pt_x = grid[x][y].end.x - 1; + pt_y = grid[x][y].end.y - 1; + + if (i != 0) { + moveX = -1; + moveY = 0; + } + else { + moveX = 0; + moveY = -1; + } + break; + // Bottom-left corner + case 3: + pt_x = grid[x][y].start.x; + pt_y = grid[x][y].end.y - 1; + + if (i != 0) { + moveX = 0; + moveY = -1; + } + else { + moveX = 1; + moveY = 0; + } + break; + } + + // Search up to 10 tiles for a new tile to replace + // from the selected starting corner and direction + for (v = 0; v < 10; v++) { + // Make sure we're still in bounds + if (pt_x < grid[x][y].start.x || pt_x >= grid[x][y].end.x) + break; + if (pt_y < grid[x][y].start.y || pt_y >= grid[x][y].end.y) + break; + + if (GetTerrainType(GetTile(pt_x, pt_y)) == TERRAIN_TYPE_NORMAL) { + // Make sure there aren't any hallways within 2 spaces from the current tile + // If there are, skip filling it in + + s32 direction = DIRECTION_SOUTH; + while (direction < NUM_DIRECTIONS) { + s32 offsetX, offsetY; + s32 nextX = pt_x + gAdjacentTileOffsets[direction].x; + s32 nextY = pt_y + gAdjacentTileOffsets[direction].y; + + bool8 found = FALSE; + for (offsetY = -1; offsetY <= 1; offsetY++) { + for (offsetX = -1; offsetX <= 1; offsetX++) { + // Search for open terrain which is not a part of a room (a hallway) + Tile *tile = GetTile(nextX + offsetX, nextY + offsetY); + + if (GetTerrainType(tile) != TERRAIN_TYPE_NORMAL) + continue; + if (tile->room == CORRIDOR_ROOM) { + found = TRUE; + } + + if (found) + break; + } + + if (found) + break; + } + + if (found) + break; + + direction++; + } + + // If direction == NUM_DIRECTIONS, we didn't find any hallways and are good to proceed + if (direction == NUM_DIRECTIONS) { + // Check that our cardinal neighbors' terrain types match what we expect for generating new tiles in this direction + // For example, if we're generating from the top-left corner, we should only expect tiles + // below us or to our right to have open terrain. If another tile does, we should stop + // because the resulting room may look strange otherwise + + direction = DIRECTION_SOUTH; + while (direction < NUM_DIRECTIONS) { + s32 nextX = gAdjacentTileOffsets[direction].x; + s32 nextY = gAdjacentTileOffsets[direction].y; + bool8 isOpen = (GetTerrainType(GetTile(pt_x + nextX, pt_y + nextY)) == TERRAIN_TYPE_NORMAL); + + if (gUnknown_80F6DD5[startingCorner][direction] != isOpen) + break; + + // Advance by 2 to only check cardinal directions + direction += 2; + } + + // If direction == NUM_DIRECTIONS, the neighbors match what we expect + if (direction == NUM_DIRECTIONS) { + // Fill in the current open floor tile with a wall + SetTerrainWall(GetTileSafe(pt_x, pt_y)); + } + } + + break; + } + else { + // The terrain is filled or already a wall, move to the next tile + pt_x += moveX; + pt_y += moveY; + } + } + } + } + } + } +} + +/* + * CreateHallway - Creates a hallway between two points. + * + * |---------B + * | + * A------| + * + * The hallway generated consists of two parallel paths connected by a perpendicular "kink" in the path + * The "kink" in a path occurs along (turn_x, turnY), which in practice is the grid cell boundary + * If the paths trace same line, no "kink" will be generated + * + * If generation runs into an existing open tile, creation stops prematurely (such as another hallway). + * + * The vertical flag specifies whether the hallway is being generated horizontally or vertically + */ +void CreateHallway(s32 x, s32 y, s32 endX, s32 endY, bool8 vertical, s32 turnX_, s32 turnY_) +{ + s32 startX = x; + s32 startY = y; + s32 turnX = turnX_; + s32 turnY = turnY_; + s32 counter; + + if (vertical) { + // Vertical hallway + + counter = 0; + // Create the vertical line between the starting point and the grid cell boundary + while (y != turnY) { + if (counter++ >= DUNGEON_MAX_SIZE_X) + return; // Sanity check! + + if (GetTerrainType(GetTile(x, y)) != TERRAIN_TYPE_NORMAL) { + SetTerrainNormal(GetTileSafe(x, y)); + } + else { + // If we find open floor, stop here + // The hall has connected up to an existing hall + if (x != startX || y != startY) + return; + } + + if (y < turnY) { + y++; + } + else { + y--; + } + } + + counter = 0; + // Create the horizontal line to connect the horizontal lines at two different x values + while (x != endX) { + if (counter++ >= DUNGEON_MAX_SIZE_X) + return; // Sanity check! + + if (GetTerrainType(GetTile(x, y)) != TERRAIN_TYPE_NORMAL) { + SetTerrainNormal(GetTileSafe(x, y)); + } + else { + if (x != startX || y != startY) + return; + } + + if (x < endX) { + x++; + } + else { + x--; + } + } + + counter = 0; + // Create the vertical line between the end point and the grid cell + while (y != endY) { + if (counter++ >= DUNGEON_MAX_SIZE_X) + return; + + if (GetTerrainType(GetTile(x, y)) != TERRAIN_TYPE_NORMAL) { + SetTerrainNormal(GetTileSafe(x, y)); + } + else { + if (x != startX || y != startY) + return; + } + + if (y < endY) { + y++; + } + else { + y--; + } + } + } + else { + // Horizontal hallway + + counter = 0; + // Create the horizontal line between the starting point and the grid cell boundary + while (x != turnX) { + if (counter++ >= DUNGEON_MAX_SIZE_X) + return; // Sanity check! + + if (GetTerrainType(GetTile(x, y)) != TERRAIN_TYPE_NORMAL) { + SetTerrainNormal(GetTileSafe(x, y)); + } + else { + // If we find open floor, stop here + // The hall has connected up to an existing hall + if (x != startX || y != startY) + return; + } + + if (x < turnX) { + x++; + } + else { + x--; + } + } + + counter = 0; + // Create the vertical line to connect the horizontal lines at two different y values + while (y != endY) { + if (counter++ >= DUNGEON_MAX_SIZE_X) + return; + + if (GetTerrainType(GetTile(x, y)) != TERRAIN_TYPE_NORMAL) { + SetTerrainNormal(GetTileSafe(x, y)); + } + else { + if (x != startX || y != startY) + return; + } + + if (y < endY) { + y++; + } + else { + y--; + } + } + + counter = 0; + // Create the horizontal line between the end point and the grid cell + while (x != endX) { + if (counter++ >= DUNGEON_MAX_SIZE_X) + return; + + if (GetTerrainType(GetTile(x, y)) != TERRAIN_TYPE_NORMAL) { + SetTerrainNormal(GetTileSafe(x, y)); + } + else { + if (x != startX || y != startY) + return; + } + + if (x < endX) { + x++; + } + else { + x--; + } + } + } +} + +/* + * EnsureConnectedGrid - Ensure the grid forms a connected graph (all valid cells are reachable) by adding hallways to unreachable cells + * + * If the unconnected cell is a hallway anchor, it will be ignored and filled in. + * If the unconnected cell is a room, it will check all adjacent directions for a connected room, then add a hallway between if found. + * + * If no eligible room is found, the room will be removed and filled back in. + */ +void EnsureConnectedGrid(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, s32 *listX, s32 *listY) +{ + s32 x, y; + + for (x = 0; x < gridSizeX; x++) { + for (y = 0; y < gridSizeY; y++) { + // If any of these is TRUE, this cell is fine and we don't need to worry about it + if (grid[x][y].isInvalid) + continue; + if (grid[x][y].hasBeenMerged) + continue; + if (grid[x][y].isConnected) + continue; + + if (grid[x][y].isRoom && !grid[x][y].hasSecondaryStructure) { + // Unconnected room + s32 pt_x, pt_y; + s32 rnd_x = DungeonRandRange(grid[x][y].start.x + 1, grid[x][y].end.x - 1); + s32 rnd_y = DungeonRandRange(grid[x][y].start.y + 1, grid[x][y].end.y - 1); + + if (y > 0 && !grid[x][y - 1].isInvalid && !grid[x][y - 1].isMerged && grid[x][y - 1].isConnected) { + // Attempt to connect to the grid cell above if it's connected + if (grid[x][y - 1].isRoom) { + // Room, take random interior x coordinate + pt_x = DungeonRandRange(grid[x][y - 1].start.x + 1, grid[x][y - 1].end.x - 1); + pt_y = DungeonRandRange(grid[x][y - 1].start.y + 1, grid[x][y - 1].end.y - 1); // Unused + } + else { + // Anchor, take center x + pt_x = grid[x][y - 1].start.x; + pt_y = grid[x][y - 1].start.y; // Unused + } + + CreateHallway(rnd_x, grid[x][y].start.y, pt_x, grid[x][y - 1].end.y - 1, TRUE, listX[x], listY[y]); + + grid[x][y].isConnected = TRUE; + grid[x][y].connectedToTop = TRUE; + grid[x][y - 1].connectedToBottom = TRUE; + } + else if (y < gridSizeY - 1 && !grid[x][y + 1].isInvalid && !grid[x][y + 1].isMerged && grid[x][y + 1].isConnected) { + // Attempt to connect to the grid cell below if it's connected + if (grid[x][y + 1].isRoom) { + // Room, take random interior x coordinate + pt_x = DungeonRandRange(grid[x][y + 1].start.x + 1, grid[x][y + 1].end.x - 1); + pt_y = DungeonRandRange(grid[x][y + 1].start.y + 1, grid[x][y + 1].end.y - 1); // Unused + } + else { + // Anchor, take center x + pt_x = grid[x][y + 1].start.x; + pt_y = grid[x][y + 1].start.y; // Unused + } + + CreateHallway(rnd_x, grid[x][y].end.y - 1, pt_x, grid[x][y + 1].start.y, TRUE, listX[x], listY[y + 1] - 1); + + grid[x][y].isConnected = TRUE; + grid[x][y].connectedToBottom = TRUE; + grid[x][y + 1].connectedToTop = TRUE; + } + else if (x > 0 && !grid[x - 1][y].isInvalid && !grid[x - 1][y].isMerged && grid[x - 1][y].isConnected) { + // Attempt to connect to the grid cell left if it's connected + if (grid[x - 1][y].isRoom) { + // Room, take random interior y coordinate + pt_x = DungeonRandRange(grid[x - 1][y].start.x + 1, grid[x - 1][y].end.x - 1); //Unused + pt_y = DungeonRandRange(grid[x - 1][y].start.y + 1, grid[x - 1][y].end.y - 1); + } + else { + // Anchor, take center y + pt_x = grid[x - 1][y].start.x; // Unused + pt_y = grid[x - 1][y].start.y; + } + + // Typo? Would expect grid[x - 1][y].end.x - 1 for 3rd parameter + CreateHallway(grid[x][y].start.x, rnd_y, grid[x - 1][y].start.x - 1, pt_y, FALSE, listX[x], listY[y]); + + grid[x][y].isConnected = TRUE; + grid[x][y].connectedToLeft = TRUE; + grid[x - 1][y].connectedToRight = TRUE; + } + else if (x < gridSizeX - 1 && !grid[x + 1][y].isInvalid && !grid[x + 1][y].isMerged && grid[x + 1][y].isConnected) { + // Attempt to connect to the grid cell right if it's connected + if (grid[x + 1][y].isRoom) { + // Room, take random interior y coordinate + pt_x = DungeonRandRange(grid[x + 1][y].start.x + 1, grid[x + 1][y].end.x - 1); // Unused + pt_y = DungeonRandRange(grid[x + 1][y].start.y + 1, grid[x + 1][y].end.y - 1); + } + else { + // Anchor, take center y + pt_x = grid[x + 1][y].start.x; // Unused + pt_y = grid[x + 1][y].start.y; + } + + CreateHallway(grid[x][y].end.x - 1, rnd_y, grid[x + 1][y].start.x, pt_y, FALSE, listX[x + 1] - 1, listY[y]); + + grid[x][y].isConnected = TRUE; + grid[x][y].connectedToRight = TRUE; + grid[x + 1][y].connectedToLeft = TRUE; + } + } + else { + // Unconnected anchor, don't bother trying. + + // Just fill it in with wall tiles + Tile *tile = GetTileSafe(grid[x][y].start.x, grid[x][y].start.y); + SetTerrainWall(tile); + + // Also remove any spawn flags + // TODO: rename to spawn_or_visibility_flags stairs/item/trap + tile->unk4 &= ~(0x1); + tile->unk4 &= ~(0x2); + tile->unk4 &= ~(0x4); + } + } + } + + // If any rooms are still unconnected (meaning attempts to connect failed) + // Fill in the rooms + for (x = 0; x < gridSizeX; x++) { + for (y = 0; y < gridSizeY; y++) { + s32 curX, curY; + if (grid[x][y].isInvalid || grid[x][y].hasBeenMerged || grid[x][y].isConnected || grid[x][y].unk15) + continue; + + for (curX = grid[x][y].start.x; curX < grid[x][y].end.x; curX++) { + for (curY = grid[x][y].start.y; curY < grid[x][y].end.y; curY++) { + Tile *tile = GetTileSafe(curX, curY); + // Set it to wall terrain + SetTerrainWall(tile); + + // Remove any spawn flags + tile->unk4 &= ~(0x2); + tile->unk4 &= ~(0x1); + tile->unk4 &= ~(0x4); + + // Set room index to 0xFF (not a room) + tile->room = CORRIDOR_ROOM; + } + } + } + } +} + +/* + * SetTerrainObstacleChecked - Sets terrain on a specific tile as an obstacle (either a wall or secondary terrain) + * + * If secondary terrain is requested and the room indices match, secondary terrain (water/lava) will be placed for the tile. + * + * Otherwise, the tile will be a wall. + */ +void SetTerrainObstacleChecked(Tile *tile, bool8 useSecondaryTerrain, u8 roomIndex) +{ + SetTerrainWall(tile); + if (useSecondaryTerrain && tile->room == roomIndex) { + SetTerrainSecondary(tile); + } +} + //