diff --git a/asm/code_804FD30.s b/asm/code_804FD30.s index 1801adf9b..6d3e82c56 100644 --- a/asm/code_804FD30.s +++ b/asm/code_804FD30.s @@ -5,1071 +5,6 @@ .text - thumb_func_start sub_8050438 -sub_8050438: - push {r4-r7,lr} - mov r7, r10 - mov r6, r9 - mov r5, r8 - push {r5-r7} - ldr r4, _08050470 - add sp, r4 - lsls r1, 24 - lsrs r1, 24 - movs r2, 0xE0 - lsls r2, 5 - add r2, sp - str r1, [r2] - ldr r1, _08050474 - ldr r1, [r1] - mov r10, r1 - ldrb r1, [r0, 0x6] - cmp r1, 0 - ble _08050478 - lsrs r0, r1, 1 - bl DungeonRandRange - adds r7, r0, 0 - cmp r7, 0 - bgt _0805047A - movs r7, 0x1 - b _0805047A - .align 2, 0 -_08050470: .4byte 0xffffe3f8 -_08050474: .4byte gDungeon -_08050478: - adds r7, r1, 0 -_0805047A: - movs r0, 0 - mov r8, r0 - movs r6, 0 -_08050480: - movs r5, 0 - adds r1, r6, 0x1 - mov r9, r1 - mov r2, r8 - lsls r0, r2, 2 - mov r1, sp - adds r4, r0, r1 -_0805048E: - adds r0, r6, 0 - adds r1, r5, 0 - bl GetTile - adds r1, r0, 0 - ldrh r3, [r1] - movs r2, 0x3 - ands r2, r3 - cmp r2, 0x1 - bne _080504F6 - ldrb r0, [r1, 0x9] - cmp r0, 0xFF - beq _080504F6 - movs r0, 0x20 - ands r0, r3 - cmp r0, 0 - bne _080504F6 - ldrh r1, [r1, 0x4] - movs r0, 0x2 - ands r0, r1 - cmp r0, 0 - bne _080504F6 - ands r2, r1 - cmp r2, 0 - bne _080504F6 - movs r0, 0x8 - ands r0, r3 - cmp r0, 0 - bne _080504F6 - movs r2, 0x80 - lsls r2, 1 - adds r0, r2, 0 - ands r0, r3 - cmp r0, 0 - bne _080504F6 - ldr r0, _080506A0 - add r0, r10 - movs r1, 0 - ldrsh r0, [r0, r1] - cmp r6, r0 - bne _080504EC - ldr r0, _080506A4 - add r0, r10 - movs r2, 0 - ldrsh r0, [r0, r2] - cmp r5, r0 - beq _080504F6 -_080504EC: - strb r6, [r4] - strb r5, [r4, 0x1] - adds r4, 0x4 - movs r0, 0x1 - add r8, r0 -_080504F6: - adds r5, 0x1 - cmp r5, 0x1F - ble _0805048E - mov r6, r9 - cmp r6, 0x37 - ble _08050480 - mov r1, r8 - cmp r1, 0 - beq _0805055E - ldr r0, _080506A8 - ldr r0, [r0] - movs r2, 0xD1 - lsls r2, 3 - adds r0, r2 - movs r1, 0 - ldrsh r0, [r0, r1] - cmp r0, 0 - beq _0805051C - adds r7, 0x1 -_0805051C: - cmp r7, 0 - beq _0805055E - mov r0, sp - mov r1, r8 - bl ShuffleSpawnPositions - mov r0, r8 - bl DungeonRandInt - adds r5, r0, 0 - cmp r7, 0 - ble _0805055E - adds r6, r7, 0 - lsls r0, r5, 2 - mov r2, sp - adds r4, r0, r2 -_0805053C: - ldrb r0, [r4] - ldrb r1, [r4, 0x1] - bl GetTileSafe - ldrh r2, [r0, 0x4] - movs r1, 0x8 - orrs r1, r2 - strh r1, [r0, 0x4] - adds r4, 0x4 - adds r5, 0x1 - cmp r5, r8 - bne _08050558 - mov r4, sp - movs r5, 0 -_08050558: - subs r6, 0x1 - cmp r6, 0 - bne _0805053C -_0805055E: - ldr r0, _080506AC - add r0, r10 - ldrb r0, [r0] - cmp r0, 0 - bne _0805056A - b _0805068C -_0805056A: - ldr r0, _080506B0 - movs r2, 0 - ldrsh r1, [r0, r2] - ldr r2, _080506B4 - add r2, sp - str r1, [r2] - movs r0, 0 - mov r8, r0 - movs r1, 0xE0 - lsls r1, 5 - add r1, sp - ldr r1, [r1] - cmp r1, 0 - beq _0805058A - movs r0, 0x3 - str r0, [r2] -_0805058A: - ldr r1, _080506B4 - add r1, sp - ldr r1, [r1] - lsls r0, r1, 1 - adds r0, r1 - lsrs r1, r0, 31 - adds r0, r1 - asrs r0, 1 - ldr r1, _080506B4 - add r1, sp - str r0, [r1] - movs r6, 0 -_080505A2: - movs r5, 0 - adds r2, r6, 0x1 - mov r9, r2 - mov r1, r8 - lsls r0, r1, 2 - mov r2, sp - adds r4, r0, r2 -_080505B0: - adds r0, r6, 0 - adds r1, r5, 0 - bl GetTile - adds r1, r0, 0 - ldrh r2, [r1] - movs r0, 0x3 - ands r0, r2 - cmp r0, 0x1 - bne _08050608 - ldrb r0, [r1, 0x9] - cmp r0, 0xFF - beq _08050608 - movs r0, 0x20 - ands r0, r2 - cmp r0, 0 - bne _08050608 - movs r1, 0x80 - lsls r1, 1 - adds r0, r1, 0 - ands r0, r2 - cmp r0, 0 - bne _08050608 - movs r0, 0x40 - ands r0, r2 - cmp r0, 0 - beq _08050608 - ldr r0, _080506A0 - add r0, r10 - movs r2, 0 - ldrsh r0, [r0, r2] - cmp r6, r0 - bne _080505FE - ldr r0, _080506A4 - add r0, r10 - movs r1, 0 - ldrsh r0, [r0, r1] - cmp r5, r0 - beq _08050608 -_080505FE: - strb r6, [r4] - strb r5, [r4, 0x1] - adds r4, 0x4 - movs r2, 0x1 - add r8, r2 -_08050608: - adds r5, 0x1 - cmp r5, 0x1F - ble _080505B0 - mov r6, r9 - cmp r6, 0x37 - ble _080505A2 - mov r0, r8 - cmp r0, 0 - beq _0805068C - lsls r4, r0, 3 - subs r0, r4, r0 - movs r1, 0xA - bl __divsi3 - adds r5, r0, 0 - adds r0, r4, 0 - movs r1, 0xA - bl __divsi3 - adds r1, r0, 0 - adds r0, r5, 0 - bl DungeonRandRange - adds r7, r0, 0 - cmp r7, 0 - bne _0805063E - movs r7, 0x1 -_0805063E: - ldr r1, _080506B4 - add r1, sp - ldr r1, [r1] - cmp r7, r1 - blt _0805064E - ldr r2, _080506B4 - add r2, sp - ldr r7, [r2] -_0805064E: - mov r0, sp - mov r1, r8 - bl ShuffleSpawnPositions - mov r0, r8 - bl DungeonRandInt - adds r5, r0, 0 - cmp r7, 0 - ble _0805068C - adds r6, r7, 0 - lsls r0, r5, 2 - mov r1, sp - adds r4, r0, r1 -_0805066A: - ldrb r0, [r4] - ldrb r1, [r4, 0x1] - bl GetTileSafe - ldrh r2, [r0, 0x4] - movs r1, 0x8 - orrs r1, r2 - strh r1, [r0, 0x4] - adds r4, 0x4 - adds r5, 0x1 - cmp r5, r8 - bne _08050686 - mov r4, sp - movs r5, 0 -_08050686: - subs r6, 0x1 - cmp r6, 0 - bne _0805066A -_0805068C: - ldr r3, _080506B8 - add sp, r3 - pop {r3-r5} - mov r8, r3 - mov r9, r4 - mov r10, r5 - pop {r4-r7} - pop {r0} - bx r0 - .align 2, 0 -_080506A0: .4byte 0x0000e218 -_080506A4: .4byte 0x0000e21a -_080506A8: .4byte gDungeon -_080506AC: .4byte 0x00003a08 -_080506B0: .4byte gUnknown_80F4DA4 -_080506B4: .4byte 0x00001c04 -_080506B8: .4byte 0x00001c08 - thumb_func_end sub_8050438 - - thumb_func_start sub_80506BC -sub_80506BC: - push {lr} - adds r3, r0, 0 - movs r2, 0x1 - ldrh r1, [r3] - movs r0, 0x3 - ands r0, r1 - cmp r0, 0 - beq _080506CE - movs r2, 0 -_080506CE: - movs r0, 0x10 - ands r0, r1 - cmp r0, 0 - beq _080506D8 - movs r2, 0 -_080506D8: - cmp r2, 0 - beq _080506E6 - ldr r0, _080506EC - ands r0, r1 - movs r1, 0x2 - orrs r0, r1 - strh r0, [r3] -_080506E6: - pop {r0} - bx r0 - .align 2, 0 -_080506EC: .4byte 0x0000fffc - thumb_func_end sub_80506BC - - thumb_func_start sub_80506F0 -sub_80506F0: - push {r4-r7,lr} - mov r7, r10 - mov r6, r9 - mov r5, r8 - push {r5-r7} - sub sp, 0xA4 - str r1, [sp, 0x64] - ldrb r1, [r1, 0xD] - ands r1, r0 - cmp r1, 0 - bne _08050708 - b _08050C20 -_08050708: - ldr r4, _08050738 - movs r0, 0x8 - bl DungeonRandInt - lsls r0, 2 - adds r0, r4 - ldr r4, [r0] - cmp r4, 0 - bne _0805071C - b _08050A7C -_0805071C: - movs r0, 0x64 - bl DungeonRandInt - cmp r0, 0x31 - bgt _0805073C - movs r0, 0x1 - str r0, [sp, 0x74] - movs r1, 0x1F - mov r10, r1 - movs r2, 0x1 - negs r2, r2 - str r2, [sp, 0x70] - b _08050746 - .align 2, 0 -_08050738: .4byte gUnknown_80F6DF8 -_0805073C: - movs r0, 0 - str r0, [sp, 0x74] - mov r10, r0 - movs r1, 0x1 - str r1, [sp, 0x70] -_08050746: - movs r0, 0x32 - bl DungeonRandInt - adds r0, 0xA - str r0, [sp, 0x78] - movs r0, 0x2 - movs r1, 0x36 - bl DungeonRandRange - mov r9, r0 - movs r2, 0 - str r2, [sp, 0x6C] - subs r4, 0x1 - str r4, [sp, 0x98] -_08050762: - movs r0, 0x6 - bl DungeonRandInt - adds r0, 0x2 - str r0, [sp, 0x68] - cmp r0, 0 - bne _08050772 - b _08050A38 -_08050772: - mov r0, r9 - cmp r0, 0x37 - bhi _080507B8 - mov r1, r10 - bl GetTile - ldrh r1, [r0] - movs r0, 0x3 - ands r0, r1 - cmp r0, 0x2 - bne _0805078A - b _08050A74 -_0805078A: - mov r1, r9 - cmp r1, 0 - blt _080507A2 - mov r2, r10 - cmp r2, 0 - blt _080507A2 - mov r0, r9 - cmp r0, 0x37 - bgt _080507A2 - mov r1, r10 - cmp r1, 0x1F - ble _080507A6 -_080507A2: - movs r0, 0x1 - b _080507A8 -_080507A6: - movs r0, 0 -_080507A8: - cmp r0, 0 - bne _080507B8 - mov r0, r9 - mov r1, r10 - bl GetTileSafe - bl sub_80506BC -_080507B8: - ldr r2, [sp, 0x68] - subs r2, 0x1 - str r2, [sp, 0x68] - ldr r0, [sp, 0x6C] - add r9, r0 - ldr r1, [sp, 0x70] - add r10, r1 - mov r2, r10 - cmp r2, 0x1F - bls _080507CE - b _08050A38 -_080507CE: - ldr r0, [sp, 0x78] - subs r0, 0x1 - str r0, [sp, 0x78] - cmp r0, 0 - beq _080507DA - b _08050A30 -_080507DA: - movs r1, 0x3F - str r1, [sp, 0x7C] -_080507DE: - movs r0, 0x7 - bl DungeonRandInt - subs r0, 0x3 - str r0, [sp, 0x84] - movs r0, 0x7 - bl DungeonRandInt - subs r1, r0, 0x3 - ldr r6, [sp, 0x84] - add r6, r9 - subs r0, r6, 0x2 - cmp r0, 0x33 - bhi _080508DA - mov r2, r10 - adds r5, r1, r2 - cmp r5, 0x1 - ble _080508DA - cmp r5, 0x1D - bgt _080508DA - adds r4, r6, 0x1 - adds r0, r5, 0x1 - mov r8, r0 - adds r0, r4, 0 - mov r1, r8 - bl GetTile - ldrh r1, [r0] - movs r2, 0x3 - adds r0, r2, 0 - ands r0, r1 - cmp r0, 0x2 - beq _080508B2 - adds r0, r4, 0 - adds r1, r5, 0 - str r2, [sp, 0x9C] - bl GetTile - ldrh r1, [r0] - ldr r2, [sp, 0x9C] - adds r0, r2, 0 - ands r0, r1 - cmp r0, 0x2 - beq _080508B2 - subs r7, r5, 0x1 - adds r0, r4, 0 - adds r1, r7, 0 - bl GetTile - ldrh r1, [r0] - ldr r2, [sp, 0x9C] - adds r0, r2, 0 - ands r0, r1 - cmp r0, 0x2 - beq _080508B2 - adds r0, r6, 0 - mov r1, r8 - bl GetTile - ldrh r1, [r0] - ldr r2, [sp, 0x9C] - adds r0, r2, 0 - ands r0, r1 - cmp r0, 0x2 - beq _080508B2 - adds r0, r6, 0 - adds r1, r7, 0 - bl GetTile - ldrh r1, [r0] - ldr r2, [sp, 0x9C] - adds r0, r2, 0 - ands r0, r1 - cmp r0, 0x2 - beq _080508B2 - subs r4, r6, 0x1 - adds r0, r4, 0 - mov r1, r8 - bl GetTile - ldrh r1, [r0] - ldr r2, [sp, 0x9C] - adds r0, r2, 0 - ands r0, r1 - cmp r0, 0x2 - beq _080508B2 - adds r0, r4, 0 - adds r1, r5, 0 - bl GetTile - ldrh r1, [r0] - ldr r2, [sp, 0x9C] - adds r0, r2, 0 - ands r0, r1 - cmp r0, 0x2 - beq _080508B2 - adds r0, r4, 0 - adds r1, r7, 0 - bl GetTile - ldrh r1, [r0] - ldr r2, [sp, 0x9C] - adds r0, r2, 0 - ands r0, r1 - cmp r0, 0x2 - bne _080508DA -_080508B2: - ldr r0, [sp, 0x84] - add r0, r9 - cmp r0, 0 - blt _080508C6 - cmp r5, 0 - blt _080508C6 - cmp r0, 0x37 - bgt _080508C6 - cmp r5, 0x1F - ble _080508CA -_080508C6: - movs r1, 0x1 - b _080508CC -_080508CA: - movs r1, 0 -_080508CC: - cmp r1, 0 - bne _080508DA - adds r1, r5, 0 - bl GetTileSafe - bl sub_80506BC -_080508DA: - ldr r1, [sp, 0x7C] - subs r1, 0x1 - str r1, [sp, 0x7C] - cmp r1, 0 - blt _080508E6 - b _080507DE -_080508E6: - movs r0, 0x3 - negs r0, r0 -_080508EA: - movs r2, 0x3 - negs r2, r2 - str r2, [sp, 0x80] - mov r1, r9 - adds r1, r0, r1 - str r1, [sp, 0x90] - adds r0, 0x1 - str r0, [sp, 0x8C] - adds r7, r1, 0 - mov r5, r10 - subs r5, 0x3 -_08050900: - movs r6, 0 - subs r0, r7, 0x2 - cmp r0, 0x33 - bls _0805090A - b _08050A1A -_0805090A: - str r5, [sp, 0x88] - str r5, [sp, 0x94] - cmp r5, 0x1 - bgt _08050914 - b _08050A1A -_08050914: - cmp r5, 0x1D - ble _0805091A - b _08050A1A -_0805091A: - adds r4, r7, 0x1 - adds r3, r5, 0x1 - adds r0, r4, 0 - adds r1, r3, 0 - str r3, [sp, 0xA0] - bl GetTile - ldrh r1, [r0] - movs r2, 0x3 - mov r8, r2 - mov r0, r8 - ands r0, r1 - ldr r3, [sp, 0xA0] - cmp r0, 0x2 - bne _0805093A - movs r6, 0x1 -_0805093A: - adds r0, r4, 0 - adds r1, r5, 0 - str r3, [sp, 0xA0] - bl GetTile - ldrh r1, [r0] - mov r0, r8 - ands r0, r1 - ldr r3, [sp, 0xA0] - cmp r0, 0x2 - bne _08050952 - adds r6, 0x1 -_08050952: - subs r2, r5, 0x1 - adds r0, r4, 0 - adds r1, r2, 0 - str r2, [sp, 0x9C] - str r3, [sp, 0xA0] - bl GetTile - ldrh r1, [r0] - mov r0, r8 - ands r0, r1 - ldr r2, [sp, 0x9C] - ldr r3, [sp, 0xA0] - cmp r0, 0x2 - bne _08050970 - adds r6, 0x1 -_08050970: - adds r0, r7, 0 - adds r1, r3, 0 - str r2, [sp, 0x9C] - str r3, [sp, 0xA0] - bl GetTile - ldrh r1, [r0] - mov r0, r8 - ands r0, r1 - ldr r2, [sp, 0x9C] - ldr r3, [sp, 0xA0] - cmp r0, 0x2 - bne _0805098C - adds r6, 0x1 -_0805098C: - adds r0, r7, 0 - adds r1, r2, 0 - str r2, [sp, 0x9C] - str r3, [sp, 0xA0] - bl GetTile - ldrh r1, [r0] - mov r0, r8 - ands r0, r1 - ldr r2, [sp, 0x9C] - ldr r3, [sp, 0xA0] - cmp r0, 0x2 - bne _080509A8 - adds r6, 0x1 -_080509A8: - subs r4, r7, 0x1 - adds r0, r4, 0 - adds r1, r3, 0 - str r2, [sp, 0x9C] - bl GetTile - ldrh r1, [r0] - mov r0, r8 - ands r0, r1 - ldr r2, [sp, 0x9C] - cmp r0, 0x2 - bne _080509C2 - adds r6, 0x1 -_080509C2: - adds r0, r4, 0 - adds r1, r5, 0 - str r2, [sp, 0x9C] - bl GetTile - ldrh r1, [r0] - mov r0, r8 - ands r0, r1 - ldr r2, [sp, 0x9C] - cmp r0, 0x2 - bne _080509DA - adds r6, 0x1 -_080509DA: - adds r0, r4, 0 - adds r1, r2, 0 - bl GetTile - ldrh r1, [r0] - mov r0, r8 - ands r0, r1 - cmp r0, 0x2 - bne _080509EE - adds r6, 0x1 -_080509EE: - cmp r6, 0x3 - ble _08050A1A - cmp r7, 0 - blt _08050A04 - cmp r5, 0 - blt _08050A04 - cmp r7, 0x37 - bgt _08050A04 - ldr r0, [sp, 0x88] - cmp r0, 0x1F - ble _08050A08 -_08050A04: - movs r0, 0x1 - b _08050A0A -_08050A08: - movs r0, 0 -_08050A0A: - cmp r0, 0 - bne _08050A1A - ldr r0, [sp, 0x90] - ldr r1, [sp, 0x94] - bl GetTileSafe - bl sub_80506BC -_08050A1A: - adds r5, 0x1 - ldr r1, [sp, 0x80] - adds r1, 0x1 - str r1, [sp, 0x80] - cmp r1, 0x3 - bgt _08050A28 - b _08050900 -_08050A28: - ldr r0, [sp, 0x8C] - cmp r0, 0x3 - bgt _08050A30 - b _080508EA -_08050A30: - ldr r2, [sp, 0x68] - cmp r2, 0 - beq _08050A38 - b _08050772 -_08050A38: - ldr r0, [sp, 0x6C] - cmp r0, 0 - beq _08050A54 - movs r1, 0x1 - str r1, [sp, 0x70] - ldr r2, [sp, 0x74] - cmp r2, 0 - beq _08050A4E - movs r0, 0x1 - negs r0, r0 - str r0, [sp, 0x70] -_08050A4E: - movs r1, 0 - str r1, [sp, 0x6C] - b _08050A6C -_08050A54: - movs r0, 0x64 - bl DungeonRandInt - movs r2, 0x1 - str r2, [sp, 0x6C] - cmp r0, 0x31 - bgt _08050A68 - movs r0, 0x1 - negs r0, r0 - str r0, [sp, 0x6C] -_08050A68: - movs r1, 0 - str r1, [sp, 0x70] -_08050A6C: - mov r2, r10 - cmp r2, 0x1F - bhi _08050A74 - b _08050762 -_08050A74: - ldr r4, [sp, 0x98] - cmp r4, 0 - beq _08050A7C - b _0805071C -_08050A7C: - movs r0, 0 - ldr r1, [sp, 0x64] - ldrb r1, [r1, 0x15] - cmp r0, r1 - blt _08050A88 - b _08050BAE -_08050A88: - movs r2, 0 - mov r8, r2 - mov r9, r2 - movs r5, 0 - adds r0, 0x1 - mov r10, r0 - b _08050A98 -_08050A96: - adds r5, 0x1 -_08050A98: - cmp r5, 0xC7 - bgt _08050AC2 - movs r0, 0 - movs r1, 0x38 - bl DungeonRandRange - mov r9, r0 - movs r0, 0 - movs r1, 0x20 - bl DungeonRandRange - mov r8, r0 - mov r0, r9 - subs r0, 0x1 - cmp r0, 0x35 - bhi _08050A96 - mov r0, r8 - cmp r0, 0 - ble _08050A96 - cmp r0, 0x1E - bgt _08050A96 -_08050AC2: - cmp r5, 0xC8 - beq _08050BA2 - movs r7, 0 - movs r3, 0x1 - movs r1, 0 -_08050ACC: - movs r2, 0 - lsls r0, r7, 2 - adds r4, r7, 0x1 - adds r0, r7 - lsls r0, 1 - add r0, sp -_08050AD8: - cmp r7, 0 - beq _08050AE8 - cmp r7, 0x9 - beq _08050AE8 - cmp r2, 0 - beq _08050AE8 - cmp r2, 0x9 - bne _08050AEC -_08050AE8: - strb r3, [r0] - b _08050AEE -_08050AEC: - strb r1, [r0] -_08050AEE: - adds r0, 0x1 - adds r2, 0x1 - cmp r2, 0x9 - ble _08050AD8 - adds r7, r4, 0 - cmp r7, 0x9 - ble _08050ACC - movs r5, 0x4F -_08050AFE: - movs r0, 0x8 - bl DungeonRandInt - adds r4, r0, 0 - adds r7, r4, 0x1 - movs r0, 0x8 - bl DungeonRandInt - adds r2, r0, 0x1 - lsls r0, r4, 2 - adds r0, r4 - lsls r0, 1 - adds r0, r2, r0 - add r0, sp - ldrb r0, [r0] - cmp r0, 0 - bne _08050B50 - adds r1, r7, 0x1 - lsls r0, r1, 2 - adds r0, r1 - lsls r0, 1 - adds r0, r2, r0 - add r0, sp - ldrb r0, [r0] - cmp r0, 0 - bne _08050B50 - lsls r0, r7, 2 - adds r0, r7 - lsls r1, r0, 1 - subs r0, r1, 0x1 - adds r0, r2, r0 - add r0, sp - ldrb r0, [r0] - cmp r0, 0 - bne _08050B50 - adds r0, r1, 0x1 - adds r0, r2, r0 - add r0, sp - ldrb r0, [r0] - cmp r0, 0 - beq _08050B60 -_08050B50: - lsls r0, r7, 2 - adds r0, r7 - lsls r0, 1 - adds r0, r2, r0 - mov r2, sp - adds r1, r2, r0 - movs r0, 0x1 - strb r0, [r1] -_08050B60: - subs r5, 0x1 - cmp r5, 0 - bge _08050AFE - movs r7, 0 -_08050B68: - lsls r0, r7, 2 - adds r4, r7, 0x1 - adds r0, r7 - lsls r0, 1 - mov r6, r8 - subs r6, 0x5 - mov r1, sp - adds r5, r0, r1 - add r7, r9 - movs r2, 0x9 -_08050B7C: - ldrb r0, [r5] - cmp r0, 0 - bne _08050B92 - subs r0, r7, 0x5 - adds r1, r6, 0 - str r2, [sp, 0x9C] - bl GetTileSafe - bl sub_80506BC - ldr r2, [sp, 0x9C] -_08050B92: - adds r6, 0x1 - adds r5, 0x1 - subs r2, 0x1 - cmp r2, 0 - bge _08050B7C - adds r7, r4, 0 - cmp r7, 0x9 - ble _08050B68 -_08050BA2: - mov r0, r10 - ldr r2, [sp, 0x64] - ldrb r2, [r2, 0x15] - cmp r0, r2 - bge _08050BAE - b _08050A88 -_08050BAE: - movs r0, 0 - mov r9, r0 - movs r6, 0x1 - ldr r1, _08050BF4 - adds r5, r1, 0 -_08050BB8: - movs r2, 0 - mov r10, r2 - mov r4, r9 - adds r4, 0x1 -_08050BC0: - mov r0, r9 - mov r1, r10 - bl GetTileSafe - adds r2, r0, 0 - ldrh r3, [r2] - movs r0, 0x3 - ands r0, r3 - cmp r0, 0x2 - bne _08050C10 - movs r1, 0xB0 - lsls r1, 1 - adds r0, r1, 0 - ands r0, r3 - cmp r0, 0 - bne _08050BEA - ldrh r1, [r2, 0x4] - adds r0, r6, 0 - ands r0, r1 - cmp r0, 0 - beq _08050BF8 -_08050BEA: - adds r0, r3, 0 - ands r0, r5 - orrs r0, r6 - b _08050C0E - .align 2, 0 -_08050BF4: .4byte 0x0000fffc -_08050BF8: - mov r0, r9 - subs r0, 0x2 - cmp r0, 0x34 - bhi _08050C0A - mov r0, r10 - cmp r0, 0x1 - ble _08050C0A - cmp r0, 0x1E - ble _08050C10 -_08050C0A: - ldrh r0, [r2] - ands r0, r5 -_08050C0E: - strh r0, [r2] -_08050C10: - movs r1, 0x1 - add r10, r1 - mov r2, r10 - cmp r2, 0x1F - ble _08050BC0 - mov r9, r4 - cmp r4, 0x37 - ble _08050BB8 -_08050C20: - add sp, 0xA4 - pop {r3-r5} - mov r8, r3 - mov r9, r4 - mov r10, r5 - pop {r4-r7} - pop {r0} - bx r0 - thumb_func_end sub_80506F0 - thumb_func_start sub_8050C30 sub_8050C30: push {r4-r7,lr} diff --git a/include/structs/str_dungeon.h b/include/structs/str_dungeon.h index e600e3d27..f6b6d769d 100644 --- a/include/structs/str_dungeon.h +++ b/include/structs/str_dungeon.h @@ -125,7 +125,7 @@ typedef struct UnkDungeonGlobal_unk1C574 u8 unk3; u8 unk4; u8 floorConnectivity; - u8 unk6; + u8 enemyDensity; u8 kecleonShopChance; // Percentage chance 0-100% u8 monsterHouseChance; // Percentage chance 0-100% u8 mazeRoomChance; // Percentage chance 0-100% @@ -347,7 +347,7 @@ typedef struct Dungeon u8 fill3802[0x3904 - 0x3802]; /* 0x3904 */ s16 numItems; u8 fill3906[0x3A08 - 0x3906]; - /* 0x3A08 */ u8 unk3A08; + /* 0x3A08 */ bool8 forceMonsterHouse; // Forces the current floor to have monster house /* 0x3A09 */ u8 unk3A09; /* 0x3A0A */ u8 unk3A0A; /* 0x3A0B */ u8 unk3A0B; diff --git a/src/code_8042B34.c b/src/code_8042B34.c index 62d442818..57e7f649e 100644 --- a/src/code_8042B34.c +++ b/src/code_8042B34.c @@ -751,7 +751,7 @@ void xxx_dungeon_8042F6C(struct UnkStruct_xxx_dungeon_8042F6C *r8) } else { sub_80427AC(); - sub_8075900(GetLeader(), gDungeon->unk3A08); + sub_8075900(GetLeader(), gDungeon->forceMonsterHouse); sub_807EAA0(1, 0); } diff --git a/src/code_8066D04.c b/src/code_8066D04.c index a618531a9..da88b04e8 100644 --- a/src/code_8066D04.c +++ b/src/code_8066D04.c @@ -182,7 +182,7 @@ void HandleGiveItemAction(Entity *param_1) if (!info2->isTeamLeader) { info2->flags = info2->flags | MOVEMENT_FLAG_UNK_14; } - sub_807AB38(param_1,gDungeon->unk3A08); + sub_807AB38(param_1,gDungeon->forceMonsterHouse); } } @@ -223,7 +223,7 @@ void HandleTakeItemAction(Entity *param_1) if (!info->isTeamLeader) { info->flags |= MOVEMENT_FLAG_UNK_14; } - sub_807AB38(param_1,gDungeon->unk3A08); + sub_807AB38(param_1,gDungeon->forceMonsterHouse); } } } @@ -267,7 +267,7 @@ void sub_8066BD4(Entity *param_1) if (!info->isTeamLeader) { info->flags = info->flags | MOVEMENT_FLAG_UNK_14; } - sub_807AB38(param_1,gDungeon->unk3A08); + sub_807AB38(param_1,gDungeon->forceMonsterHouse); } } @@ -325,7 +325,7 @@ void HandlePlaceItemAction(Entity *param_1) PlaySoundEffect(0x14d); SetMessageArgument(gFormatBuffer_Monsters[0],entity,0); TryDisplayDungeonLoggableMessage(entity,*gUnknown_80F8E28); - sub_807AB38(entity,gDungeon->unk3A08); + sub_807AB38(entity,gDungeon->forceMonsterHouse); } } else diff --git a/src/code_8073CF0.c b/src/code_8073CF0.c index 07f3b9dae..376047ef9 100644 --- a/src/code_8073CF0.c +++ b/src/code_8073CF0.c @@ -1019,7 +1019,7 @@ bool8 UseAttack(Entity *a0) sub_8071DA4(mon); sub_8046D20(); - sub_8075900(mon, gDungeon->unk3A08); + sub_8075900(mon, gDungeon->forceMonsterHouse); } if (!EntityExists(mon)) continue; diff --git a/src/code_807CD9C.c b/src/code_807CD9C.c index 19cb58310..a2e973226 100644 --- a/src/code_807CD9C.c +++ b/src/code_807CD9C.c @@ -157,7 +157,7 @@ void sub_807CD9C(Entity *pokemon, Entity *target, u32 direction) sub_807EC28(FALSE); } sub_806A5B8(target); - sub_8075900(target,gDungeon->unk3A08); + sub_8075900(target,gDungeon->forceMonsterHouse); } } } @@ -321,7 +321,7 @@ void sub_807D148(Entity *pokemon, Entity *target, u32 param_3, Position *pos) sub_807EC28(0); } sub_806A5B8(target); - sub_8075900(target,gDungeon->unk3A08); + sub_8075900(target,gDungeon->forceMonsterHouse); } void sub_807D3CC(Entity *param_1) diff --git a/src/code_807E1A0.c b/src/code_807E1A0.c index a1d17e4a3..8d1223e27 100644 --- a/src/code_807E1A0.c +++ b/src/code_807E1A0.c @@ -101,7 +101,7 @@ void sub_807E254(Entity *pokemon,Entity *target) sub_807EC28(FALSE); } sub_806A5B8(pokemon); - sub_8075900(pokemon,gDungeon->unk3A08); + sub_8075900(pokemon,gDungeon->forceMonsterHouse); } if (EntityExists(target)) { @@ -110,7 +110,7 @@ void sub_807E254(Entity *pokemon,Entity *target) sub_807EC28(FALSE); } sub_806A5B8(target); - sub_8075900(target,gDungeon->unk3A08); + sub_8075900(target,gDungeon->forceMonsterHouse); } } } diff --git a/src/dungeon_ai_attack.c b/src/dungeon_ai_attack.c index 3b9d68433..d0ad73066 100644 --- a/src/dungeon_ai_attack.c +++ b/src/dungeon_ai_attack.c @@ -1065,7 +1065,7 @@ void HandleUseOrbAction(Entity *pokemon) } sub_806A5B8(pokemon); - sub_8075900(pokemon, gDungeon->unk3A08); + sub_8075900(pokemon, gDungeon->forceMonsterHouse); } else if (r4) sub_8044D40(&act, 0); diff --git a/src/dungeon_generation.c b/src/dungeon_generation.c index c23e3dba6..8327aa8f8 100644 --- a/src/dungeon_generation.c +++ b/src/dungeon_generation.c @@ -107,9 +107,9 @@ void GenerateCrossFloor(UnkDungeonGlobal_unk1C574 *a0); void GenerateBeetleFloor(UnkDungeonGlobal_unk1C574 *a0); void GenerateOuterRoomsFloor(s32 gridSizeX_, s32 gridSizeY_, UnkDungeonGlobal_unk1C574 *unkPtr); void sub_8051654(UnkDungeonGlobal_unk1C574 *a0); -void sub_80506F0(s32 a0, UnkDungeonGlobal_unk1C574 *a1); +void GenerateSecondaryTerrainFormations(u32 flag, UnkDungeonGlobal_unk1C574 *unkPtr); void SpawnNonEnemies(UnkDungeonGlobal_unk1C574 *unkPtr, bool8 isEmptyMonsterHouse); -void sub_8050438(UnkDungeonGlobal_unk1C574 *unkPtr, bool8 isEmptyMonsterHouse); +void SpawnEnemies(UnkDungeonGlobal_unk1C574 *unkPtr, bool8 isEmptyMonsterHouse); EWRAM_DATA u8 gUnknown_202F1A8 = 0; EWRAM_DATA u8 gUnknown_202F1A9 = 0; @@ -210,7 +210,7 @@ void sub_804AFAC(void) ResetFloor(); gDungeon->playerSpawn.x = -1; gDungeon->playerSpawn.y = -1; - gDungeon->unk3A08 = 0; + gDungeon->forceMonsterHouse = 0; if (gDungeon->bossBattleIndex != 0) { if (sub_804C70C(gDungeon->bossBattleIndex, unkPtr)) { break; @@ -247,7 +247,7 @@ void sub_804AFAC(void) y = 1; } - gDungeon->unk3A08 = 0; + gDungeon->forceMonsterHouse = 0; gDungeon->monsterHouseRoom = 0xFF; gUnknown_202F1D0 = r7; switch (r7 & 0xF) { @@ -270,7 +270,7 @@ void sub_804AFAC(void) break; case 2: GenerateOneRoomMonsterHouseFloor(); - gDungeon->unk3A08 = 1; + gDungeon->forceMonsterHouse = 1; break; case 3: GenerateOuterRingFloor(unkPtr); @@ -282,7 +282,7 @@ void sub_804AFAC(void) break; case 5: GenerateTwoRoomsWithMonsterHouseFloor(); - gDungeon->unk3A08 = 1; + gDungeon->forceMonsterHouse = 1; break; case 6: GenerateLineFloor(unkPtr); @@ -342,15 +342,15 @@ void sub_804AFAC(void) gUnknown_202F1D8.x = -1; gUnknown_202F1D8.y = -1; GenerateOneRoomMonsterHouseFloor(); - gDungeon->unk3A08 = 1; + gDungeon->forceMonsterHouse = 1; } sub_804E9DC(); if (r10) { - sub_80506F0(1, unkPtr); + GenerateSecondaryTerrainFormations(1, unkPtr); } r4 = (DungeonRandInt(100) < unkPtr->connectedToTop); SpawnNonEnemies(unkPtr, r4); - sub_8050438(unkPtr, r4); + SpawnEnemies(unkPtr, r4); ResolveInvalidSpawns(); if (gDungeon->playerSpawn.x != -1 && gDungeon->playerSpawn.y != -1) { @@ -366,10 +366,10 @@ void sub_804AFAC(void) gUnknown_202F1D8.y = -1; ResetFloor(); GenerateOneRoomMonsterHouseFloor(); - gDungeon->unk3A08 = 1; + gDungeon->forceMonsterHouse = TRUE; sub_804E9DC(); SpawnNonEnemies(unkPtr, FALSE); - sub_8050438(unkPtr, FALSE); + SpawnEnemies(unkPtr, FALSE); ResolveInvalidSpawns(); } @@ -863,7 +863,7 @@ void NAKED sub_804AFAC(void) " beq _0804B3AA\n" " movs r0, 0x1\n" " mov r1, r8\n" -" bl sub_80506F0\n" +" bl GenerateSecondaryTerrainFormations\n" "_0804B3AA:\n" " movs r0, 0x64\n" " bl DungeonRandInt\n" @@ -879,7 +879,7 @@ void NAKED sub_804AFAC(void) " bl SpawnNonEnemies\n" " mov r0, r8\n" " adds r1, r4, 0\n" -" bl sub_8050438\n" +" bl SpawnEnemies\n" " bl ResolveInvalidSpawns\n" " ldr r5, _0804B4C0\n" " ldr r1, [r5]\n" @@ -955,7 +955,7 @@ void NAKED sub_804AFAC(void) " bl SpawnNonEnemies\n" " mov r0, r8\n" " movs r1, 0\n" -" bl sub_8050438\n" +" bl SpawnEnemies\n" " bl ResolveInvalidSpawns\n" "_0804B474:\n" " ldr r1, _0804B4B8\n" @@ -4607,9 +4607,10 @@ void ShuffleSpawnPositions(struct PositionU8 *spawns, s32 count) * See below for specific conditions on each type of spawn. */ extern const s16 gUnknown_80F4DA0; +extern const s16 gUnknown_80F4DA4; void SpawnNonEnemies(UnkDungeonGlobal_unk1C574 *unkPtr, bool8 isEmptyMonsterHouse) { - struct PositionU8 validSpawns[1792]; + struct PositionU8 validSpawns[DUNGEON_MAX_SIZE_X * DUNGEON_MAX_SIZE_Y]; s32 count; s32 randIndex; s32 i; @@ -4940,4 +4941,460 @@ void SpawnNonEnemies(UnkDungeonGlobal_unk1C574 *unkPtr, bool8 isEmptyMonsterHous } } +/* + * SpawnEnemies - Spawns all enemies, including those in forced monster houses + */ +void SpawnEnemies(UnkDungeonGlobal_unk1C574 *unkPtr, bool8 isEmptyMonsterHouse) +{ + struct PositionU8 validSpawns[DUNGEON_MAX_SIZE_X * DUNGEON_MAX_SIZE_Y]; + s32 count; + s32 randIndex; + s32 i; + s32 x, y; + Dungeon *dungeon = gDungeon; + s32 numEnemies, numMonsterHouseEnemies; + s32 enemyDensity = unkPtr->enemyDensity; + + if (enemyDensity > 0) { + // Positive means value with variance + numEnemies = DungeonRandRange(enemyDensity / 2, enemyDensity); + + if (numEnemies < 1) { + numEnemies = 1; + } + } + else { + // Negative means exact value. + // Bug - abs is missing, also it should be s8, not u8 + numEnemies = enemyDensity; + } + + count = 0; + for (x = 0; x < DUNGEON_MAX_SIZE_X; x++) { + for (y = 0; y < DUNGEON_MAX_SIZE_Y; y++) { + // Enemies can spawn on tiles that are: + // - Open Terrain + // - In a room + // - Not in a Kecleon Shop + // - Don't have stairs, an item + // - Not a special tile that can't be broken by Absolute Mover + // - Not where the player spawns + Tile *tile = GetTile(x, y); + if (GetTerrainType(tile) != TERRAIN_TYPE_NORMAL) + continue; + if (tile->room == CORRIDOR_ROOM) + continue; + if (tile->terrainType & TERRAIN_TYPE_SHOP) + continue; + if (tile->spawnOrVisibilityFlags & SPAWN_FLAG_ITEM) + continue; + if (tile->spawnOrVisibilityFlags & SPAWN_FLAG_STAIRS) + continue; + if (tile->terrainType & TERRAIN_TYPE_NATURAL_JUNCTION) + continue; + if (tile->terrainType & TERRAIN_TYPE_UNBREAKABLE) + continue; + if (x == dungeon->playerSpawn.x && y == dungeon->playerSpawn.y) + continue; + + validSpawns[count].x = x; + validSpawns[count].y = y; + count++; + } + } + + if (count != 0) { + // ? + if (gDungeon->unk688) { + numEnemies++; + } + if (numEnemies != 0) { + // Randomly select among the valid enemy spawn spots + ShuffleSpawnPositions(validSpawns, count); + randIndex = DungeonRandInt(count); + + for (i = 0; i < numEnemies; i++) { + Tile *tile = GetTileSafe(validSpawns[randIndex].x, validSpawns[randIndex].y); + // Spawn an enemy here + tile->spawnOrVisibilityFlags |= SPAWN_FLAG_MONSTER; + + randIndex++; + if (randIndex == count) { + // Wrap around to the start + randIndex = 0; + } + } + } + } + + if (!dungeon->forceMonsterHouse) { + return; + } + + // This floor was marked to force a monster house + // Place extra enemy spawns in the Monster House room + + numMonsterHouseEnemies = gUnknown_80F4DA4; + count = 0; + if (isEmptyMonsterHouse) { + // An "empty" monster house only spawns 3 enemies + numMonsterHouseEnemies = 3; + } + + numMonsterHouseEnemies = (numMonsterHouseEnemies * 3) / 2; + + for (x = 0; x < DUNGEON_MAX_SIZE_X; x++) { + s32 y; + for (y = 0; y < DUNGEON_MAX_SIZE_Y; y++) { + // Monster House enemies can spawn on tiles that are: + // - Open Terrain + // - In a room + // - Not in a Kecleon Shop + // - Not a special tile that can't be broken by Absolute Mover + // - Not where the player spawns + // - In the monster house room + + Tile *tile = GetTile(x, y); + if (GetTerrainType(tile) != TERRAIN_TYPE_NORMAL) + continue; + if (tile->room == CORRIDOR_ROOM) + continue; + if (tile->terrainType & TERRAIN_TYPE_SHOP) + continue; + if (tile->terrainType & TERRAIN_TYPE_UNBREAKABLE) + continue; + if (!(tile->terrainType & TERRAIN_TYPE_IN_MONSTER_HOUSE)) + continue; + if (x == dungeon->playerSpawn.x && y == dungeon->playerSpawn.y) + continue; + + validSpawns[count].x = x; + validSpawns[count].y = y; + count++; + } + } + + if (count != 0) { + numEnemies = DungeonRandRange((7 * count) / 10, (8 * count) / 10); + + if (numEnemies == 0) { + numEnemies = 1; + } + + if (numEnemies >= numMonsterHouseEnemies) { + // Don't spawn more enemies than the designated limit + numEnemies = numMonsterHouseEnemies; + } + + // Randomly select among the valid enemy spawn spots + ShuffleSpawnPositions(validSpawns, count); + randIndex = DungeonRandInt(count); + + for (i = 0; i < numEnemies; i++) { + Tile *tile = GetTileSafe(validSpawns[randIndex].x, validSpawns[randIndex].y); + // Spawn an enemy here + tile->spawnOrVisibilityFlags |= SPAWN_FLAG_MONSTER; + + randIndex++; + if (randIndex == count) { + // Wrap around to the start + randIndex = 0; + } + } + } +} + +/* + * SetSecondaryTerrainOnWall - Set a specific tile to have secondary terrain if the tile + * is a passable wall. + */ +void SetSecondaryTerrainOnWall(Tile *tile) +{ + bool8 isWall = TRUE; + if (GetTerrainType(tile) != TERRAIN_TYPE_WALL) + isWall = FALSE; + if (tile->terrainType & TERRAIN_TYPE_IMPASSABLE_WALL) + isWall = FALSE; + + if (isWall) { + SetTerrainSecondary(tile); + } +} + +/* + * GenerateSecondaryTerrainFormations - Generates secondary terrain (water/lava) formations + * + * This generation includes rivers, lakes along the river path, and standalone lakes. + * + * The river flows from top-to-bottom or bottom-to-top, using a random walk ending when the walk + * goes out of bounds or finds existing secondary terrain. Because of this, rivers can end prematurely + * when a lake is generated. + * + * Lakes are a large collection of secondary terrain generated around a central point. + * Standalone lakes are generated based on secondary_terrain_density + * + * The formations will never cut into room tiles, but can pass through to the other side. + */ +extern const s32 gUnknown_80F6DF8[8]; +void GenerateSecondaryTerrainFormations(u32 flag, UnkDungeonGlobal_unk1C574 *unkPtr) +{ + s32 num_tiles_fill; + s32 dir_x, dir_y; + bool8 dir_y_upwards; + s32 steps_until_lake; + s32 j; + s32 offsetX; + s32 offsetY; + s32 numToGen; + s32 densityN; + s32 x, y; + + if (!(unkPtr->roomFlags & flag)) + return; + + + // Generate 1-3 "river+lake" formations + numToGen = gUnknown_80F6DF8[DungeonRandInt(ARRAY_COUNT(gUnknown_80F6DF8))]; + //for (i = 0; i < numToGen; i++) { + for (;numToGen != 0; numToGen--) { + // Randomly pick between starting from the bottom going up, or from the top going down + + + if (DungeonRandInt(100) < 50) { + dir_y_upwards = TRUE; + y = DUNGEON_MAX_SIZE_Y - 1; + dir_y = -1; + } + else { + dir_y_upwards = FALSE; + y = 0; + dir_y = 1; + } + + steps_until_lake = DungeonRandInt(50) + 10; + + // Pick a random column in the interior to start the river on + x = DungeonRandRange(2, DUNGEON_MAX_SIZE_X - 2); + dir_x = 0; + + while (1) { + // Fill in tiles in chunks of size 2-7 before changing the flow direction + num_tiles_fill = DungeonRandInt(6) + 2; + //for (v = 0; v < num_tiles_fill; v++) { + while (num_tiles_fill != 0) { + if (x >= 0 && x < DUNGEON_MAX_SIZE_X) { + if (GetTerrainType(GetTile(x, y)) != TERRAIN_TYPE_SECONDARY) { + if (!PosIsOutOfBounds(x, y)) { + // Fill in secondary terrain as we go + SetSecondaryTerrainOnWall(GetTileSafe(x, y)); + } + } + else { + goto LABEL; + } + } + num_tiles_fill--; + + // Move to the next tile + x += dir_x; + y += dir_y; + + // Vertically out of bounds, stop + if (y < 0 || y >= DUNGEON_MAX_SIZE_Y) { + break; + } + + steps_until_lake--; + if (steps_until_lake != 0) + continue; + + // After we go a certain number of steps, make a "lake" + + // This loop will attempt to generate new lake tiles up to 64 times + // We select a random tile, check for space and nearby secondary terrain tiles, + // then if verified add a new lake tile. + for (j = 0; j < 64; j++) { + // Each tile is in a random location +-3 tiles from the current cursor in either direction + s32 offsetX = DungeonRandInt(7) - 3; + s32 offsetY = DungeonRandInt(7) - 3; + + // Check that there's enough space for a lake within a 2 tile margin of the map bounds + if (offsetX + x < 2 || offsetX + x >= DUNGEON_MAX_SIZE_X - 2 || offsetY + y < 2 || offsetY + y >= DUNGEON_MAX_SIZE_Y - 2) + continue; + + // Make secondary terrain here if it's within 2 tiles + // of a tile that's currently secondary terrain + // This results in a "cluster" akin to a lake + if (GetTerrainType(GetTile(offsetX + x + 1, offsetY + y + 1)) == TERRAIN_TYPE_SECONDARY || + GetTerrainType(GetTile(offsetX + x + 1, offsetY + y + 0)) == TERRAIN_TYPE_SECONDARY || + GetTerrainType(GetTile(offsetX + x + 1, offsetY + y - 1)) == TERRAIN_TYPE_SECONDARY || + GetTerrainType(GetTile(offsetX + x + 0, offsetY + y + 1)) == TERRAIN_TYPE_SECONDARY || + GetTerrainType(GetTile(offsetX + x + 0, offsetY + y - 1)) == TERRAIN_TYPE_SECONDARY || + GetTerrainType(GetTile(offsetX + x - 1, offsetY + y + 1)) == TERRAIN_TYPE_SECONDARY || + GetTerrainType(GetTile(offsetX + x - 1, offsetY + y + 0)) == TERRAIN_TYPE_SECONDARY || + GetTerrainType(GetTile(offsetX + x - 1, offsetY + y - 1)) == TERRAIN_TYPE_SECONDARY) + { + if (!PosIsOutOfBounds(x + offsetX, y + offsetY)) { + SetSecondaryTerrainOnWall(GetTileSafe(offsetX + x, offsetY + y)); + } + } + } + + // Finalization/gap-filling step because the random approach + // might leave weird gaps. Go through every tile and do an + // on line nearest-neighbor interpolation of secondary terrain + // tiles to smoothen out the "lake" + for (offsetX = -3; offsetX <= 3; offsetX++) { + for (offsetY = -3; offsetY <= 3; offsetY++) { + s32 numAdjacent = 0; + s32 xPlus1, yPlus1; + + if (offsetX + x < 2 || offsetX + x >= DUNGEON_MAX_SIZE_X - 2 || offsetY + y < 2 || offsetY + y >= DUNGEON_MAX_SIZE_Y - 2) + continue; + + // Count the number of secondary terrain tiles adjacent (all 8 directions) + xPlus1 = offsetX + x + 1; + yPlus1 = offsetY + y + 1; + + if (GetTerrainType(GetTile(xPlus1, yPlus1)) == TERRAIN_TYPE_SECONDARY) numAdjacent++; + if (GetTerrainType(GetTile(offsetX + x + 1, offsetY + y + 0)) == TERRAIN_TYPE_SECONDARY) numAdjacent++; + if (GetTerrainType(GetTile(offsetX + x + 1, offsetY + y - 1)) == TERRAIN_TYPE_SECONDARY) numAdjacent++; + if (GetTerrainType(GetTile(offsetX + x + 0, offsetY + y + 1)) == TERRAIN_TYPE_SECONDARY) numAdjacent++; + if (GetTerrainType(GetTile(offsetX + x + 0, offsetY + y - 1)) == TERRAIN_TYPE_SECONDARY) numAdjacent++; + if (GetTerrainType(GetTile(offsetX + x - 1, offsetY + y + 1)) == TERRAIN_TYPE_SECONDARY) numAdjacent++; + if (GetTerrainType(GetTile(offsetX + x - 1, offsetY + y + 0)) == TERRAIN_TYPE_SECONDARY) numAdjacent++; + if (GetTerrainType(GetTile(offsetX + x - 1, offsetY + y - 1)) == TERRAIN_TYPE_SECONDARY) numAdjacent++; + + // If at least half are secondary terrain, make this tile secondary terrain as well + if (numAdjacent >= 4 && !PosIsOutOfBounds(x + offsetX , y + offsetY)) { + SetSecondaryTerrainOnWall(GetTileSafe(offsetX + x , offsetY + y)); + } + } + } + } + + // Creating a lake doesn't mean we are done yet + // but it's likely that the next iteration will hit the tile + // stopping condition for secondary terrain, if not the river continues + + // Alternate between horizontal and vertical movement each iteration + if (dir_x != 0) { + // The y direction never reverses, ensuring the river doesn't + // double back on itself and cuts across the map only once + if (dir_y_upwards) { + dir_y = -1; + } + else { + dir_y = 1; + } + + dir_x = 0; + } + else { + //Randomly pick between left and right + if (DungeonRandInt(100) < 50) { + dir_x = -1; + } + else { + dir_x = 1; + } + + dir_y = 0; + } + + if (y < 0 || y >= DUNGEON_MAX_SIZE_Y) { + LABEL: + // Vertically out of bounds, stop + break; + } + } + } + + // Generate standalone lakes secondary_terrain_density # of times + for (densityN = 0; densityN < unkPtr->unk15; densityN++) { + s32 x, y; + bool8 table[10][10]; + // Try to pick a random tile in the interior to seed the "lake" + // Incredibly unlikely to fail + s32 rnd_y = 0; + s32 rnd_x = 0; + s32 n = 0; + + // Up to 200 attempts + while (n < 200) { + rnd_x = DungeonRandRange(0, DUNGEON_MAX_SIZE_X); + rnd_y = DungeonRandRange(0, DUNGEON_MAX_SIZE_Y); + + if (rnd_x >= 1 && rnd_x < DUNGEON_MAX_SIZE_X - 1 && rnd_y >= 1 && rnd_y < DUNGEON_MAX_SIZE_Y - 1) + break; + + n++; + } + + if (n == 200) + continue; + + // Make a 10x10 grid with TRUE on the boundary and FALSE on the interior + for (x = 0; x < 10; x++) { + for (y = 0; y < 10; y++) { + if (x == 0 || x == 9 || y == 0 || y == 9) { + table[x][y] = TRUE; + } + else { + table[x][y] = FALSE; + } + } + } + + // Generate an "inverse lake" by spreading the TRUE values inwards + for (n = 0; n < 80; n++) { + // Pick a random interior point on the 10x10 grid + x = DungeonRandInt(8) + 1; + y = DungeonRandInt(8) + 1; + + if (table[x - 1][y] || table[x + 1][y] || table[x][y - 1] || table[x][y + 1]) { + table[x][y] = TRUE; + } + } + + // Iterate through the grid, any spaces which are still FALSE form the inverse-inverse lake + // or as some may prefer to call it, just a regular lake! + for (x = 0; x < 10; x++) { + for (y = 0; y < 10; y++) { + if (!table[x][y]) { + // Shift the 0-10 random offset position into +- 5 to center around the lake seed tile + SetSecondaryTerrainOnWall(GetTileSafe(x + rnd_x - 5, y + rnd_y - 5)); + } + } + } + } + + // Clean up secondary terrain that got in places it shouldn't + for (x = 0; x < DUNGEON_MAX_SIZE_X; x++) { + for (y = 0; y < DUNGEON_MAX_SIZE_Y; y++) { + Tile *tile = GetTileSafe(x, y); + if (GetTerrainType(tile) != TERRAIN_TYPE_SECONDARY) + continue; + + // Revert tiles back to open terrain if: + // - in a kecleon shop + // - in a monster house + // - is an unbreakable tile + // - on a stairs spawn point + // This really shouldn't happen since we only place terrain on wall tiles to begin with, + // but it provides additional safety + + if (tile->terrainType & (TERRAIN_TYPE_SHOP | TERRAIN_TYPE_IN_MONSTER_HOUSE | TERRAIN_TYPE_UNBREAKABLE) || (tile->spawnOrVisibilityFlags & SPAWN_FLAG_STAIRS)) { + SetTerrainNormal(tile); + } + else { + // Revert to wall tiles if they're on the soft/hard borders + if (x <= 1 || x >= DUNGEON_MAX_SIZE_X - 1 || y <= 1 || y >= DUNGEON_MAX_SIZE_Y - 1) { + SetTerrainWall(tile); + } + } + } + } +} + // diff --git a/src/move_actions.c b/src/move_actions.c index 10e706752..b4d167359 100644 --- a/src/move_actions.c +++ b/src/move_actions.c @@ -2749,7 +2749,7 @@ _0805AA5E: sub_807EC28(FALSE); } sub_806A5B8(target); - sub_8075900(target,gDungeon->unk3A08); + sub_8075900(target,gDungeon->forceMonsterHouse); } } return TRUE; diff --git a/src/trap_1.c b/src/trap_1.c index 910ca92e6..44b6b78bb 100644 --- a/src/trap_1.c +++ b/src/trap_1.c @@ -483,7 +483,7 @@ void sub_8081454(unkStruct_8094924 *param_1) int iVar4; sub_808300C(param_1,gMisakiSan); - sub_80830B4(param_1, gDungeon->unk3A08); + sub_80830B4(param_1, gDungeon->forceMonsterHouse); sub_80830B4(param_1, gDungeon->unk3A09); sub_80830B4(param_1, gDungeon->unk3A0A); sub_80830B4(param_1, gDungeon->unk3A0B); @@ -820,7 +820,7 @@ void sub_8081C7C(unkStruct_8094924 *r0) s32 iVar7; sub_8083018(r0,gMisakiSan); - gDungeon->unk3A08 = sub_80831DC(r0); + gDungeon->forceMonsterHouse = sub_80831DC(r0); gDungeon->unk3A09 = sub_80831DC(r0); gDungeon->unk3A0A = sub_80831DC(r0); gDungeon->unk3A0B = sub_80831DC(r0);