From 2447a0200d004d9ceca4b80ecea0ab4951fabd1b Mon Sep 17 00:00:00 2001 From: cecilarmitais Date: Tue, 8 Sep 2026 16:39:41 -0700 Subject: [PATCH] Decompile GenerateMission (0x0205D224) 864 instructions, a 19-step pipeline with five jump tables. No region preprocessor directives -- all three regions assemble identical text, so one source serves US/EU/JP. asm/main_0205D1F4.s is split: GenerateMission merges into src/main_0205D11C.c and the remainder becomes asm/main_0205DFAC.s. main.lsf swaps the object in place. include/main_0205D11C.h gains struct unk_0205DFAC (the 6-byte record), struct unk_0205D224 (the 0x22-byte template) and the prototype; CheckItemForMissionType's second parameter is corrected to union mission_subtype *. Authored by Claude (Opus 4.8) under human direction. Confirmed by a matching build: build/pmdsky.us/pmdsky.us.nds: OK. Co-Authored-By: Claude Opus 4.8 --- asm/include/main_0205D1F4.inc | 37 -- asm/include/main_0205DFAC.inc | 4 + asm/main_0205D1F4.s | 1005 --------------------------------- asm/main_0205DFAC.s | 38 ++ include/main_0205D11C.h | 16 +- main.lsf | 2 +- src/main_0205D11C.c | 618 +++++++++++++++++++- 7 files changed, 675 insertions(+), 1045 deletions(-) delete mode 100644 asm/include/main_0205D1F4.inc create mode 100644 asm/include/main_0205DFAC.inc delete mode 100644 asm/main_0205D1F4.s create mode 100644 asm/main_0205DFAC.s diff --git a/asm/include/main_0205D1F4.inc b/asm/include/main_0205D1F4.inc deleted file mode 100644 index 1a7b3d87..00000000 --- a/asm/include/main_0205D1F4.inc +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -.public CanDungeonBeUsedForMission -.public CanMonsterBeUsedForMission -.public CanMonsterBeUsedForMissionWrapper -.public CheckItemForMissionType -.public CheckMonsterForMissionType -.public ClearMissionData -.public GetAllPossibleMonsters -.public GetMaxItemsAllowed -.public GetMaxMembersAllowed -.public GetMissionSpecificFixedRoom -.public GetSecondFormIfValid -.public IsAvailableItem -.public IsForbiddenFloor -.public IsMissionValid -.public IsStorableItem -.public IsThrownItem -.public LoadMissionTemplates -.public MemAlloc -.public MemFree -.public MISSION_DELIVER_LIST_PTR -.public MtNext -.public RandInt -.public RandIntSafe -.public RollRandomItemReward -.public sub_0205CF58 -.public sub_0205E090 -.public sub_0205E1E8 -.public sub_0205E258 -.public sub_020627F4 -.public sub_02062814 -.public sub_0206282C -.public sub_02062900 -.public sub_02062AD0 -.public sub_02062C4C -.public sub_02062D40 -.public sub_02063424 diff --git a/asm/include/main_0205DFAC.inc b/asm/include/main_0205DFAC.inc new file mode 100644 index 00000000..db34afbd --- /dev/null +++ b/asm/include/main_0205DFAC.inc @@ -0,0 +1,4 @@ +#pragma once +.public CanMonsterBeUsedForMissionWrapper +.public MemAlloc +.public sub_020627F4 diff --git a/asm/main_0205D1F4.s b/asm/main_0205D1F4.s deleted file mode 100644 index d1e66812..00000000 --- a/asm/main_0205D1F4.s +++ /dev/null @@ -1,1005 +0,0 @@ - .include "asm/macros.inc" - .include "main_0205D1F4.inc" - - .text - - arm_func_start GenerateMission -GenerateMission: ; 0x0205D224 - stmdb sp!, {r4, r5, r6, r7, r8, sb, sl, fp, lr} - sub sp, sp, #0x14 - mov sb, r0 - add r0, sp, #0x10 - mov r8, r1 - bl GetAllPossibleMonsters - str r0, [sp] - cmp r0, #0 - bne _0205D258 - mov r0, r8 - bl ClearMissionData - mov r0, #2 - b _0205DF9C -_0205D258: - mov r0, #4 - strb r0, [r8] - ldrb r0, [sb, #0x20] - strb r0, [r8, #1] - ldrb r0, [sb, #0x21] - strb r0, [r8, #2] - ldrh r0, [sb, #8] - cmp r0, #5 - addls pc, pc, r0, lsl #2 - b _0205D414 -_0205D280: ; jump table - b _0205D298 ; case 0 - b _0205D298 ; case 1 - b _0205D414 ; case 2 - b _0205D414 ; case 3 - b _0205D414 ; case 4 - b _0205D338 ; case 5 -_0205D298: - ldrh r0, [sb, #0xc] - and r1, r0, #0xff - strb r0, [sp, #4] - strb r1, [sp, #5] - ldrh r0, [sb, #8] - cmp r0, #0 - bne _0205D2C8 - and r0, r1, #0xff - bl CanDungeonBeUsedForMission - cmp r0, #0 - moveq r5, #1 - beq _0205D51C -_0205D2C8: - mov r0, r8 - bl sub_0205E258 - mov r3, r0 - add r1, sp, #4 - add r2, sp, #5 - mov r0, #1 - bl sub_02062C4C - cmp r0, #0 - bne _0205D304 - mov r0, r8 - bl sub_0205E258 - cmp r0, #0 - movne r5, #1 - moveq r5, #2 - b _0205D51C -_0205D304: - ldrb r0, [sb, #0x20] - add r2, sp, #5 - add r1, sb, #0x21 - bl sub_0205CF58 - cmp r0, #0 - moveq r5, #1 - beq _0205D51C - ldrb r0, [sp, #5] - mov r5, #0 - strb r0, [r8, #4] - ldrb r0, [sp, #6] - strb r0, [r8, #5] - b _0205D51C -_0205D338: - add r0, sp, #0xc - bl sub_02062814 - ldrb r1, [sb, #0x20] - cmp r1, #3 - ldreqb r1, [sb, #0x21] - cmpeq r1, #3 - movne r5, #1 - bne _0205D51C - mov r1, #0xf - bl MemAlloc - mov r7, r0 - bl sub_0206282C - movs r5, r0 - bne _0205D380 - mov r0, r7 - bl MemFree - mov r5, #1 - b _0205D51C -_0205D380: - mov r0, r8 - bl sub_0205E258 - mov r3, r0 - add r2, sp, #5 - mov r0, r5 - mov r1, r7 - bl sub_02062C4C - mov r6, r0 - ldrb r0, [r8, #1] - ldrb r2, [sp, #5] - add r1, r8, #2 - bl sub_02063424 - strb r0, [sp, #6] - add r5, sp, #5 - b _0205D3D8 -_0205D3BC: - mov r0, r5 - bl IsForbiddenFloor - cmp r0, #0 - beq _0205D3E4 - ldrb r0, [sp, #6] - sub r0, r0, #1 - strb r0, [sp, #6] -_0205D3D8: - ldrb r0, [sp, #6] - cmp r0, #0 - bne _0205D3BC -_0205D3E4: - mov r0, r7 - bl MemFree - cmp r6, #0 - ldrneb r0, [sp, #6] - cmpne r0, #0 - beq _0205D518 - ldrb r0, [sp, #5] - mov r5, #0 - strb r0, [r8, #4] - ldrb r0, [sp, #6] - strb r0, [r8, #5] - b _0205D51C -_0205D414: - ldr r0, _0205DFA4 ; =MISSION_DELIVER_LIST_PTR - mov r5, #1 - ldr r6, [r0, #0xc] - ldr r7, [r0, #8] - cmp r6, #0 - moveq r5, #2 - beq _0205D51C - mov r0, r8 - bl sub_0205E258 - mov r3, r0 - add r2, sp, #5 - mov r0, r6 - mov r1, r7 - bl sub_02062C4C - cmp r0, #0 - bne _0205D468 - mov r0, r8 - bl sub_0205E258 - cmp r0, #0 - moveq r5, #2 - b _0205D51C -_0205D468: - ldrb r0, [r8, #1] - cmp r0, #0xa - addls pc, pc, r0, lsl #2 - b _0205D4F8 -_0205D478: ; jump table - b _0205D4F8 ; case 0 - b _0205D4F8 ; case 1 - b _0205D4A4 ; case 2 - b _0205D4A4 ; case 3 - b _0205D4A4 ; case 4 - b _0205D4A4 ; case 5 - b _0205D4C8 ; case 6 - b _0205D4B8 ; case 7 - b _0205D4F8 ; case 8 - b _0205D4F8 ; case 9 - b _0205D4DC ; case 10 -_0205D4A4: - ldrb r0, [sp, #5] - bl GetMaxMembersAllowed - cmp r0, #4 - movlt r5, #0 - b _0205D4F8 -_0205D4B8: - ldrb r0, [sp, #5] - bl GetMaxItemsAllowed - cmp r0, #0 - moveq r5, #0 -_0205D4C8: - add r0, sp, #5 - bl sub_02062D40 - cmp r0, #0 - moveq r5, #0 - b _0205D4F8 -_0205D4DC: - ldrb r0, [r8, #2] - cmp r0, #4 - bne _0205D4F8 - ldrb r0, [sp, #5] - bl GetMaxMembersAllowed - cmp r0, #4 - movlt r5, #0 -_0205D4F8: - cmp r5, #0 - beq _0205D518 - ldrb r0, [sp, #5] - mov r5, #0 - strb r0, [r8, #4] - ldrb r0, [sp, #6] - strb r0, [r8, #5] - b _0205D51C -_0205D518: - mov r5, #1 -_0205D51C: - cmp r5, #0 - beq _0205D534 - mov r0, r8 - bl ClearMissionData - mov r0, r5 - b _0205DF9C -_0205D534: - bl MtNext - bic r0, r0, #0xff000000 - str r0, [r8, #8] - mov r0, #0 - str r0, [sp, #8] - ldrh r0, [sb, #0xe] - cmp r0, #4 - addls pc, pc, r0, lsl #2 - b _0205D7E4 -_0205D558: ; jump table - b _0205D56C ; case 0 - b _0205D56C ; case 1 - b _0205D62C ; case 2 - b _0205D6F8 ; case 3 - b _0205D77C ; case 4 -_0205D56C: - ldrsh r5, [sb, #0x12] - ldrb r0, [sb, #0x20] - add r1, sb, #0x21 - mov r2, r5 - mov r3, #1 - bl CheckMonsterForMissionType - cmp r0, #0 - moveq r4, #1 - beq _0205DB40 - ldrb r0, [sb, #0x20] - cmp r0, #0xb - ldreqb r0, [sb, #0x21] - cmpeq r0, #0 - bne _0205D5F0 - ldr r0, _0205DFA8 ; =0x000001EA - cmp r5, r0 - addne r0, r0, #0x258 - cmpne r5, r0 - movne r1, #1 - moveq r1, #0 - mov r0, r5 - and r1, r1, #0xff - bl CanMonsterBeUsedForMission - cmp r0, #0 - moveq r4, #1 - beq _0205DB40 - strh r5, [r8, #0xe] - ldrh r0, [sb, #0x18] - mov r4, #0 - strh r0, [r8, #0x10] - ldrh r0, [sb, #0x1e] - strh r0, [r8, #0x12] - b _0205DB40 -_0205D5F0: - ldrh r0, [sb, #0xe] - cmp r0, #0 - mov r0, r5 - bne _0205D614 - bl CanMonsterBeUsedForMissionWrapper - cmp r0, #0 - bne _0205D624 - mov r4, #1 - b _0205DB40 -_0205D614: - bl sub_02062AD0 - cmp r0, #0 - moveq r4, #1 - beq _0205DB40 -_0205D624: - strh r5, [r8, #0xe] - b _0205D7E4 -_0205D62C: - add r0, sp, #8 - add r1, sb, #0xe - bl CountAndPopulateValidMissionTableMonsters - movs r4, r0 - bne _0205D658 - ldr r0, [sp, #8] - bl MemFree - mov r0, #0 - str r0, [sp, #8] - mov r4, #1 - b _0205DB40 -_0205D658: - bl RandInt - mov r1, r0, lsl #1 - ldr r2, [sp, #8] - ldrb r0, [sb, #0x20] - ldrsh r5, [r2, r1] - add r1, sb, #0x21 - mov r3, #1 - mov r2, r5 - bl CheckMonsterForMissionType - cmp r0, #0 - bne _0205D69C - ldr r0, [sp, #8] - bl MemFree - mov r0, #0 - str r0, [sp, #8] - mov r4, #1 - b _0205DB40 -_0205D69C: - ldrh r1, [sb, #0xe] - ldrh r0, [sb, #0x14] - cmp r1, r0 - ldreqh r1, [sb, #0x10] - ldreqh r0, [sb, #0x16] - cmpeq r1, r0 - ldreqh r1, [sb, #0x12] - ldreqh r0, [sb, #0x18] - cmpeq r1, r0 - beq _0205D6D8 - ldr r0, [sp, #8] - mov r4, #0 - bl MemFree - mov r0, r4 - str r0, [sp, #8] -_0205D6D8: - strh r5, [r8, #0xe] - ldrb r0, [r8, #5] - tst r0, #1 - bne _0205D7E4 - ldrsh r0, [r8, #0xe] - bl GetSecondFormIfValid - strh r0, [r8, #0xe] - b _0205D7E4 -_0205D6F8: - ldrh r4, [sb, #0x10] - bl sub_020627F4 - ldrh r1, [sb, #0x12] - add r1, r0, r1, lsl #1 - mov r0, r4 - str r1, [sp, #8] - bl RandInt - mov r1, r0, lsl #1 - ldr r2, [sp, #8] - ldrb r0, [sb, #0x20] - ldrsh r4, [r2, r1] - add r1, sb, #0x21 - mov r3, #1 - mov r2, r4 - bl CheckMonsterForMissionType - cmp r0, #0 - moveq r4, #1 - beq _0205DB40 - mov r0, r4 - bl sub_02062AD0 - cmp r0, #0 - moveq r4, #1 - beq _0205DB40 - strh r4, [r8, #0xe] - ldrb r0, [r8, #5] - tst r0, #1 - bne _0205D770 - ldrsh r0, [r8, #0xe] - bl GetSecondFormIfValid - strh r0, [r8, #0xe] -_0205D770: - mov r4, #0 - str r4, [sp, #8] - b _0205D7E4 -_0205D77C: - add r0, sp, #8 - bl GetAllPossibleMonsters - cmp r0, #0 - moveq r4, #2 - beq _0205DB40 - bl RandIntSafe - mov r1, r0, lsl #1 - ldr r2, [sp, #8] - ldrb r0, [sb, #0x20] - ldrsh r4, [r2, r1] - add r1, sb, #0x21 - mov r3, #1 - mov r2, r4 - bl CheckMonsterForMissionType - cmp r0, #0 - moveq r4, #1 - beq _0205DB40 - strh r4, [r8, #0xe] - ldrb r0, [r8, #5] - tst r0, #1 - bne _0205D7DC - ldrsh r0, [r8, #0xe] - bl GetSecondFormIfValid - strh r0, [r8, #0xe] -_0205D7DC: - mov r4, #0 - str r4, [sp, #8] -_0205D7E4: - mov r0, r8 - bl sub_0205E1E8 - cmp r0, #0 - beq _0205D820 - ldr r0, [sp, #8] - cmp r0, #0 - beq _0205D80C - bl MemFree - mov r0, #0 - str r0, [sp, #8] -_0205D80C: - ldrsh r0, [r8, #0xe] - mov r4, #0 - strh r0, [r8, #0x10] - strh r4, [r8, #0x12] - b _0205DB40 -_0205D820: - ldrb r1, [r8, #1] - cmp r1, #0xa - ldreqb r0, [r8, #2] - cmpeq r0, #6 - beq _0205D844 - cmp r1, #0xb - ldreqb r0, [r8, #2] - cmpeq r0, #0 - bne _0205D84C -_0205D844: - mov sl, #2 - b _0205D858 -_0205D84C: - mov r0, #0 - strh r0, [r8, #0x12] - mov sl, #1 -_0205D858: - mov r6, #0 - add fp, sb, #0x14 - b _0205DB34 -_0205D864: - mov r0, #6 - mul r1, r6, r0 - add r5, sb, r1 - ldrh r0, [r5, #0x14] - cmp r0, #6 - addls pc, pc, r0, lsl #2 - b _0205DB30 -_0205D880: ; jump table - b _0205D89C ; case 0 - b _0205D89C ; case 1 - b _0205D938 ; case 2 - b _0205DA30 ; case 3 - b _0205DAC0 ; case 4 - b _0205DB30 ; case 5 - b _0205DAC0 ; case 6 -_0205D89C: - ldrsh r7, [r5, #0x18] - ldrb r0, [sb, #0x20] - add r1, sb, #0x21 - mov r2, r7 - mov r3, #0 - bl CheckMonsterForMissionType - cmp r0, #0 - moveq r4, #1 - beq _0205DB40 - ldrb r0, [sb, #0x20] - cmp r0, #0xa - ldreqb r0, [sb, #0x21] - cmpeq r0, #6 - bne _0205D8F8 - mov r0, r7 - bl CanMonsterBeUsedForMissionWrapper - cmp r0, #0 - strneh r7, [r8, #0x10] - ldrneh r0, [sb, #0x1e] - moveq r4, #1 - movne r4, #0 - strneh r0, [r8, #0x12] - b _0205DB40 -_0205D8F8: - ldrh r0, [r5, #0x14] - cmp r0, #0 - mov r0, r7 - bne _0205D91C - bl CanMonsterBeUsedForMissionWrapper - cmp r0, #0 - bne _0205D92C - mov r4, #1 - b _0205DB40 -_0205D91C: - bl sub_02062AD0 - cmp r0, #0 - moveq r4, #1 - beq _0205DB40 -_0205D92C: - add r0, r8, r6, lsl #1 - strh r7, [r0, #0x10] - b _0205DB30 -_0205D938: - ldr r0, [sp, #8] - cmp r0, #0 - bne _0205D970 - add r1, fp, r1 - add r0, sp, #8 - bl CountAndPopulateValidMissionTableMonsters - movs r4, r0 - bne _0205D970 - ldr r0, [sp, #8] - bl MemFree - mov r0, #0 - str r0, [sp, #8] - mov r4, #1 - b _0205DB40 -_0205D970: - mov r0, r4 - bl RandInt - ldr r1, [sp, #8] - mov r0, r0, lsl #1 - ldrsh r5, [r1, r0] - ldrb r0, [sb, #0x20] - add r1, sb, #0x21 - mov r2, r5 - mov r3, #0 - bl CheckMonsterForMissionType - cmp r0, #0 - bne _0205D9B8 - ldr r0, [sp, #8] - bl MemFree - mov r0, #0 - str r0, [sp, #8] - mov r4, #1 - b _0205DB40 -_0205D9B8: - add r0, r6, #1 - cmp r0, sl - bge _0205D9F4 - mov r0, #6 - mla r0, r6, r0, sb - ldrh r2, [r0, #0x14] - ldrh r1, [r0, #0x1a] - cmp r2, r1 - ldreqh r2, [r0, #0x16] - ldreqh r1, [r0, #0x1c] - cmpeq r2, r1 - ldreqh r1, [r0, #0x18] - ldreqh r0, [r0, #0x1e] - cmpeq r1, r0 - beq _0205DA08 -_0205D9F4: - ldr r0, [sp, #8] - mov r4, #0 - bl MemFree - mov r0, r4 - str r0, [sp, #8] -_0205DA08: - add r1, r8, r6, lsl #1 - strh r5, [r1, #0x10] - ldrb r0, [r8, #5] - tst r0, #1 - bne _0205DB30 - ldrsh r0, [r1, #0x10] - bl GetSecondFormIfValid - add r1, r8, r6, lsl #1 - strh r0, [r1, #0x10] - b _0205DB30 -_0205DA30: - ldrh r4, [r5, #0x16] - bl sub_020627F4 - ldrh r1, [r5, #0x18] - add r0, r0, r1, lsl #1 - str r0, [sp, #8] - mov r0, r4 - bl RandInt - ldr r1, [sp, #8] - mov r0, r0, lsl #1 - ldrsh r4, [r1, r0] - ldrb r0, [sb, #0x20] - add r1, sb, #0x21 - mov r2, r4 - mov r3, #0 - bl CheckMonsterForMissionType - cmp r0, #0 - moveq r4, #1 - beq _0205DB40 - mov r0, r4 - bl sub_02062AD0 - cmp r0, #0 - moveq r4, #1 - beq _0205DB40 - add r1, r8, r6, lsl #1 - strh r4, [r1, #0x10] - ldrb r0, [r8, #5] - tst r0, #1 - bne _0205DAB0 - ldrsh r0, [r1, #0x10] - bl GetSecondFormIfValid - add r1, r8, r6, lsl #1 - strh r0, [r1, #0x10] -_0205DAB0: - mov r0, #0 - str r0, [sp, #8] - mov r4, r0 - b _0205DB30 -_0205DAC0: - add r0, sp, #8 - bl GetAllPossibleMonsters - cmp r0, #0 - moveq r4, #2 - beq _0205DB40 - bl RandIntSafe - ldr r1, [sp, #8] - mov r0, r0, lsl #1 - ldrsh r5, [r1, r0] - ldrb r0, [sb, #0x20] - add r1, sb, #0x21 - mov r2, r5 - mov r3, #0 - bl CheckMonsterForMissionType - cmp r0, #0 - moveq r4, #1 - beq _0205DB40 - add r1, r8, r6, lsl #1 - strh r5, [r1, #0x10] - ldrb r0, [r8, #5] - tst r0, #1 - bne _0205DB28 - ldrsh r0, [r1, #0x10] - bl GetSecondFormIfValid - add r1, r8, r6, lsl #1 - strh r0, [r1, #0x10] -_0205DB28: - mov r0, #0 - str r0, [sp, #8] -_0205DB30: - add r6, r6, #1 -_0205DB34: - cmp r6, sl - blt _0205D864 - mov r4, #0 -_0205DB40: - cmp r4, #0 - beq _0205DB58 - mov r0, r8 - bl ClearMissionData - mov r0, r4 - b _0205DF9C -_0205DB58: - ldrh r0, [sb, #2] - cmp r0, #4 - addls pc, pc, r0, lsl #2 - b _0205DD34 -_0205DB68: ; jump table - b _0205DB7C ; case 0 - b _0205DB7C ; case 1 - b _0205DBC4 ; case 2 - b _0205DC74 ; case 3 - b _0205DCB8 ; case 4 -_0205DB7C: - ldrsh r4, [sb, #6] - ldrb r0, [sb, #0x20] - add r1, sb, #0x21 - mov r2, r4 - bl CheckItemForMissionType - cmp r0, #0 - moveq r4, #1 - beq _0205DD38 - ldrh r0, [sb, #2] - cmp r0, #0 - bne _0205DBBC - mov r0, r4 - bl IsAvailableItem - cmp r0, #0 - moveq r4, #1 - beq _0205DD38 -_0205DBBC: - strh r4, [r8, #0x14] - b _0205DD34 -_0205DBC4: - ldrh r7, [sb, #4] - ldrh sl, [sb, #6] - mov r5, #0 - bl LoadMissionTemplates - mov fp, r0 - mov r0, r7, lsl #1 - mov r1, #0xf - bl MemAlloc - mov r4, r0 - mov r6, r5 - add sl, fp, sl, lsl #1 - b _0205DC18 -_0205DBF4: - mov r0, r6, lsl #1 - ldrsh fp, [r0, sl] - mov r0, fp - bl IsAvailableItem - cmp r0, #0 - movne r0, r5, lsl #1 - strneh fp, [r4, r0] - addne r5, r5, #1 - add r6, r6, #1 -_0205DC18: - cmp r6, r7 - blt _0205DBF4 - cmp r5, #0 - bne _0205DC38 - mov r0, r4 - bl MemFree - mov r4, #1 - b _0205DD38 -_0205DC38: - mov r0, r5 - bl RandIntSafe - mov r1, r0, lsl #1 - mov r0, r4 - ldrsh r4, [r4, r1] - bl MemFree - ldrb r0, [sb, #0x20] - mov r2, r4 - add r1, sb, #0x21 - bl CheckItemForMissionType - cmp r0, #0 - moveq r4, #1 - beq _0205DD38 - strh r4, [r8, #0x14] - b _0205DD34 -_0205DC74: - ldrh r5, [sb, #4] - ldrh r4, [sb, #6] - bl LoadMissionTemplates - add r4, r0, r4, lsl #1 - mov r0, r5 - bl RandIntSafe - mov r0, r0, lsl #1 - ldrsh r4, [r4, r0] - ldrb r0, [sb, #0x20] - add r1, sb, #0x21 - mov r2, r4 - bl CheckItemForMissionType - cmp r0, #0 - moveq r4, #1 - beq _0205DD38 - strh r4, [r8, #0x14] - b _0205DD34 -_0205DCB8: - ldr r1, _0205DFA4 ; =MISSION_DELIVER_LIST_PTR - ldr r0, [r1, #4] - ldr r4, [r1] - cmp r0, #0 - moveq r0, #0x46 - beq _0205DCDC - bl RandIntSafe - mov r0, r0, lsl #1 - ldrsh r0, [r4, r0] -_0205DCDC: - strh r0, [r8, #0x14] - ldrsh r0, [r8, #0x14] - cmp r0, #0 - bne _0205DD34 - ldrb r0, [r8, #1] - add r0, r0, #0xfa - and r0, r0, #0xff - cmp r0, #1 - movls r4, #1 - bls _0205DD38 -_0205DD04: - ldrb r1, [r8, #1] - add r0, r8, #4 - add r2, r8, #0x14 - bl RollRandomItemReward - ldrsh r0, [r8, #0x14] - bl IsThrownItem - cmp r0, #0 - bne _0205DD04 - ldrsh r0, [r8, #0x14] - bl IsStorableItem - cmp r0, #0 - beq _0205DD04 -_0205DD34: - mov r4, #0 -_0205DD38: - cmp r4, #0 - beq _0205DD50 - mov r0, r8 - bl ClearMissionData - mov r0, r4 - b _0205DF9C -_0205DD50: - ldrb r0, [r8, #4] - cmp r0, #0x26 - cmpne r0, #0x29 - beq _0205DD70 - ldrb r0, [r8, #4] - bl GetMaxMembersAllowed - cmp r0, #4 - bge _0205DD80 -_0205DD70: - mov r0, #0 - strb r0, [r8, #0x1a] - strh r0, [r8, #0x1c] - b _0205DD98 -_0205DD80: - ldr r0, [sp] - ldr r1, [sp, #0x10] - mov r0, r0, lsl #0x10 - mov r0, r0, lsr #0x10 - add r2, r8, #0x1a - bl sub_02062900 -_0205DD98: - mov r4, #0 - strb r4, [r8, #0xc] - ldrb r0, [r8, #1] - cmp r0, #0xe - addls pc, pc, r0, lsl #2 - b _0205DF84 -_0205DDB0: ; jump table - b _0205DF84 ; case 0 - b _0205DF84 ; case 1 - b _0205DF84 ; case 2 - b _0205DDEC ; case 3 - b _0205DF84 ; case 4 - b _0205DF84 ; case 5 - b _0205DE20 ; case 6 - b _0205DF84 ; case 7 - b _0205DF84 ; case 8 - b _0205DE7C ; case 9 - b _0205DE98 ; case 10 - b _0205DED4 ; case 11 - b _0205DF48 ; case 12 - b _0205DF84 ; case 13 - b _0205DF64 ; case 14 -_0205DDEC: - ldrb r1, [r8, #2] - cmp r1, #1 - beq _0205DE08 - cmp r1, #2 - beq _0205DE14 - cmp r1, #3 - b _0205DF84 -_0205DE08: - bl GetMissionSpecificFixedRoom - strb r0, [r8, #0xc] - b _0205DF84 -_0205DE14: - bl GetMissionSpecificFixedRoom - strb r0, [r8, #0xc] - b _0205DF84 -_0205DE20: - ldrb r0, [r8, #2] - cmp r0, #4 - addls pc, pc, r0, lsl #2 - b _0205DF84 -_0205DE30: ; jump table - b _0205DF84 ; case 0 - b _0205DF84 ; case 1 - b _0205DF84 ; case 2 - b _0205DF84 ; case 3 - b _0205DE44 ; case 4 -_0205DE44: - ldrb r6, [r8, #4] - ldrb r0, [r8, #1] - add r1, r8, #2 - mov r2, r6 - bl sub_02063424 - mov r5, r0 - mov r0, r6 - mov r1, r5 - mov r2, #1 - bl sub_0205E090 - cmp r0, #0 - movne r4, #1 - streqb r5, [r8, #5] - b _0205DF84 -_0205DE7C: - ldrsh r0, [r8, #0x14] - cmp r0, #0x49 - ldrnesh r1, [r8, #0xe] - ldrnesh r0, [r8, #0x10] - cmpne r1, r0 - moveq r4, #1 - b _0205DF84 -_0205DE98: - ldrb r1, [r8, #2] - cmp r1, #7 - addls pc, pc, r1, lsl #2 - b _0205DF84 -_0205DEA8: ; jump table - b _0205DF84 ; case 0 - b _0205DF84 ; case 1 - b _0205DF84 ; case 2 - b _0205DF84 ; case 3 - b _0205DF84 ; case 4 - b _0205DF84 ; case 5 - b _0205DEC8 ; case 6 - b _0205DF84 ; case 7 -_0205DEC8: - bl GetMissionSpecificFixedRoom - strb r0, [r8, #0xc] - b _0205DF84 -_0205DED4: - ldrb r0, [r8, #2] - cmp r0, #5 - addls pc, pc, r0, lsl #2 - b _0205DF34 -_0205DEE4: ; jump table - b _0205DF34 ; case 0 - b _0205DF34 ; case 1 - b _0205DF34 ; case 2 - b _0205DF34 ; case 3 - b _0205DF34 ; case 4 - b _0205DEFC ; case 5 -_0205DEFC: - ldrb r6, [r8, #4] - ldrb r0, [r8, #1] - add r1, r8, #2 - mov r2, r6 - bl sub_02063424 - mov r5, r0 - mov r0, r6 - mov r1, r5 - mov r2, #1 - bl sub_0205E090 - cmp r0, #0 - movne r4, #1 - bne _0205DF84 - strb r5, [r8, #5] -_0205DF34: - ldrb r0, [r8, #1] - ldrb r1, [r8, #2] - bl GetMissionSpecificFixedRoom - strb r0, [r8, #0xc] - b _0205DF84 -_0205DF48: - ldrb r1, [r8, #2] - bl GetMissionSpecificFixedRoom - strb r0, [r8, #0xc] - mov r0, r4 - strb r0, [r8, #0x1a] - strh r0, [r8, #0x1c] - b _0205DF84 -_0205DF64: - ldrb r0, [r8, #2] - cmp r0, #1 - beq _0205DF7C - cmp r0, #2 - moveq r4, #1 - b _0205DF84 -_0205DF7C: - strb r4, [r8, #0x1a] - strh r4, [r8, #0x1c] -_0205DF84: - cmp r4, #0 - moveq r0, #0 - beq _0205DF9C - mov r0, r8 - bl ClearMissionData - mov r0, r4 -_0205DF9C: - add sp, sp, #0x14 - ldmia sp!, {r4, r5, r6, r7, r8, sb, sl, fp, pc} - .align 2, 0 -_0205DFA4: .word MISSION_DELIVER_LIST_PTR -_0205DFA8: .word 0x000001EA - arm_func_end GenerateMission - - arm_func_start CountAndPopulateValidMissionTableMonsters -CountAndPopulateValidMissionTableMonsters: ; 0x0205DFAC - stmdb sp!, {r4, r5, r6, r7, r8, sb, sl, lr} - ldrh r6, [r1, #2] - ldrh r8, [r1, #4] - mov sl, r0 - mov r7, #0 - bl sub_020627F4 - mov r4, r0 - mov r0, r6, lsl #1 - mov r1, #0xf - bl MemAlloc - mov sb, r0 - mov r5, r7 - add r4, r4, r8, lsl #1 - b _0205E008 -_0205DFE4: - mov r0, r5, lsl #1 - ldrsh r8, [r0, r4] - mov r0, r8 - bl CanMonsterBeUsedForMissionWrapper - cmp r0, #0 - movne r0, r7, lsl #1 - strneh r8, [sb, r0] - addne r7, r7, #1 - add r5, r5, #1 -_0205E008: - cmp r5, r6 - blt _0205DFE4 - mov r0, r7 - str sb, [sl] - ldmia sp!, {r4, r5, r6, r7, r8, sb, sl, pc} - arm_func_end CountAndPopulateValidMissionTableMonsters diff --git a/asm/main_0205DFAC.s b/asm/main_0205DFAC.s new file mode 100644 index 00000000..31d1e7e8 --- /dev/null +++ b/asm/main_0205DFAC.s @@ -0,0 +1,38 @@ + .include "asm/macros.inc" + .include "main_0205DFAC.inc" + + .text + + arm_func_start CountAndPopulateValidMissionTableMonsters +CountAndPopulateValidMissionTableMonsters: ; 0x0205DFAC + stmdb sp!, {r4, r5, r6, r7, r8, sb, sl, lr} + ldrh r6, [r1, #2] + ldrh r8, [r1, #4] + mov sl, r0 + mov r7, #0 + bl sub_020627F4 + mov r4, r0 + mov r0, r6, lsl #1 + mov r1, #0xf + bl MemAlloc + mov sb, r0 + mov r5, r7 + add r4, r4, r8, lsl #1 + b _0205E008 +_0205DFE4: + mov r0, r5, lsl #1 + ldrsh r8, [r0, r4] + mov r0, r8 + bl CanMonsterBeUsedForMissionWrapper + cmp r0, #0 + movne r0, r7, lsl #1 + strneh r8, [sb, r0] + addne r7, r7, #1 + add r5, r5, #1 +_0205E008: + cmp r5, r6 + blt _0205DFE4 + mov r0, r7 + str sb, [sl] + ldmia sp!, {r4, r5, r6, r7, r8, sb, sl, pc} + arm_func_end CountAndPopulateValidMissionTableMonsters diff --git a/include/main_0205D11C.h b/include/main_0205D11C.h index ed751c11..44868f67 100644 --- a/include/main_0205D11C.h +++ b/include/main_0205D11C.h @@ -5,9 +5,23 @@ #include "util.h" #include "mission.h" +struct unk_0205DFAC { + u16 field_0x0; + u16 field_0x2; + s16 field_0x4; +}; + +struct unk_0205D224 { + u16 field_0x0; + struct unk_0205DFAC field_0x2[5]; + enum mission_type field_0x20; + union mission_subtype field_0x21; +}; + bool8 sub_0205CF58(enum mission_type type, union mission_subtype* subtype, struct dungeon_floor_pair* df_pair); bool8 CheckMonsterForMissionType(enum mission_type type, union mission_subtype* subtype, enum monster_id outlaw_backup_species, bool8 arg3); -bool8 CheckItemForMissionType(u32 r0, u32 r1, s16 r2); +bool8 CheckItemForMissionType(u32 r0, union mission_subtype *r1, s16 r2); bool8 sub_0205D1F4(struct mission *mission); +s32 GenerateMission(struct unk_0205D224 *tmpl, struct mission *mission); #endif //PMDSKY_MAIN_0205D11C_H diff --git a/main.lsf b/main.lsf index d2b2016e..946bcbc4 100644 --- a/main.lsf +++ b/main.lsf @@ -348,7 +348,7 @@ Static main Object src/main_0205C73C.o Object asm/main_0205CA40.o Object src/main_0205D11C.o - Object asm/main_0205D1F4.o + Object asm/main_0205DFAC.o Object src/main_0205E01C.o Object src/main_0205E288.o Object asm/main_0205E48C.o diff --git a/src/main_0205D11C.c b/src/main_0205D11C.c index 087067e5..a5ce1bb0 100644 --- a/src/main_0205D11C.c +++ b/src/main_0205D11C.c @@ -5,6 +5,14 @@ #include "item_util.h" #include "item_util_4.h" #include "mission.h" +#include "item_util.h" +#include "main_02001188.h" +#include "main_0200224C.h" +#include "main_02054BE0.h" +#include "main_02062A58.h" +#include "main_0205E01C.h" +#include "main_0205E288.h" +#include "dungeon_recruitment_2.h" extern u8 _020A39C0; extern u8 _020A39D4; @@ -18,6 +26,26 @@ extern const char _020A3AD4[]; extern const char _020A3AF4[]; extern const char _020A3B18[]; +extern s32 RandIntSafe(s32 n); +extern void ClearMissionData(struct mission *mission); +extern void *MemAlloc(u32 len, u32 flags); +extern struct mission_deliver_list MISSION_DELIVER_LIST_PTR; +extern s32 CanDungeonBeUsedForMission(enum dungeon_id); +extern s32 CountAndPopulateValidMissionTableMonsters(s16 **out, struct unk_0205DFAC *spec); +extern s32 GetAllPossibleMonsters(s16 **out); +extern u8 GetMissionSpecificFixedRoom(enum mission_type, u32); +extern bool8 IsAvailableItem(s16 item_id); +extern void *LoadMissionTemplates(void); +extern s32 MtNext(void); +extern void RollRandomItemReward(struct dungeon_floor_pair *, enum mission_type, s16 *out); +extern void sub_02062900(u16, s16 *, void *out); +extern bool8 sub_02062AD0(enum monster_id); +extern bool8 sub_02062C4C(s32, u8 *, struct dungeon_floor_pair *, s32); +extern s32 sub_02062814(void **out); +extern s32 sub_0206282C(u8 *out); +extern bool8 sub_02062D40(struct dungeon_floor_pair *); +extern s16 *sub_020627F4(void); + extern enum monster_id GetBaseForm(enum monster_id); extern s32 GetBodySize(enum monster_id); extern bool8 IsForbiddenFloor(struct dungeon_floor_pair*); @@ -93,7 +121,7 @@ bool8 CheckMonsterForMissionType(enum mission_type type, union mission_subtype* return TRUE; } -bool8 CheckItemForMissionType(u32 r0, u32 r1, s16 r2) +bool8 CheckItemForMissionType(u32 r0, union mission_subtype *r1, s16 r2) { if (r2 == 0) { Debug_Print0(_020A3AD4, r2); @@ -129,3 +157,591 @@ bool8 sub_0205D1F4(struct mission *mission) { } return TRUE; } + +s32 GenerateMission(struct unk_0205D224 *tmpl, struct mission *mission) +{ + s16 *sp10; + void *sp0c; + s16 *sp08; + struct { u8 list[1]; struct dungeon_floor_pair df; } x; + s32 count; + s32 err; + + s16 m; + + count = GetAllPossibleMonsters(&sp10); + if (count == 0) { + ClearMissionData(mission); + return 2; + } + mission->status = MISSION_STATUS_SUSPENDED; + mission->type = tmpl->field_0x20; + mission->subtype = tmpl->field_0x21; + { + s32 e; + + do { + switch (tmpl->field_0x2[1].field_0x0) { + case 0: + case 1: + x.list[0] = *(u16 *)&tmpl->field_0x2[1].field_0x4; + x.df.dungeon_id = (enum dungeon_id)x.list[0]; + if (tmpl->field_0x2[1].field_0x0 == 0 && CanDungeonBeUsedForMission(x.df.dungeon_id) == 0) { + e = 1; + } else if (!sub_02062C4C(1, x.list, &x.df, sub_0205E258(mission))) { + e = sub_0205E258(mission) ? 1 : 2; + } else if (!sub_0205CF58(tmpl->field_0x20, &tmpl->field_0x21, &x.df)) { + e = 1; + } else { + e = 0; + mission->dungeon_id = x.df.dungeon_id; + mission->floor = x.df.floor_id; + } + continue; + case 5: + { + s32 n; + s32 ok; + u8 *p; + n = sub_02062814(&sp0c); + if (tmpl->field_0x20 != 3 || tmpl->field_0x21.other != 3) { + e = 1; + continue; + } + p = MemAlloc(n, 0xf); + n = sub_0206282C(p); + if (n == 0) { + MemFree(p); + e = 1; + continue; + } + ok = sub_02062C4C(n, p, &x.df, sub_0205E258(mission)); + x.df.floor_id = sub_02063424(mission->type, &mission->subtype, x.df.dungeon_id); + while (x.df.floor_id != 0) { + if (!IsForbiddenFloor(&x.df)) { + break; + } + x.df.floor_id--; + } + MemFree(p); + if (ok && x.df.floor_id != 0) { + e = 0; + mission->dungeon_id = x.df.dungeon_id; + mission->floor = x.df.floor_id; + continue; + } + } + break; + case 2: + case 3: + case 4: + default: + { + s32 n; + u8 *p; + e = 1; + n = *(s32 *)&MISSION_DELIVER_LIST_PTR.unk0[0xc]; + p = *(u8 **)&MISSION_DELIVER_LIST_PTR.unk0[8]; + if (n == 0) { + e = 2; + continue; + } + if (!sub_02062C4C(n, p, &x.df, sub_0205E258(mission))) { + if (sub_0205E258(mission) == 0) { + e = 2; + } + continue; + } + switch (mission->type) { + case 2: + case 3: + case 4: + case 5: + if (GetMaxMembersAllowed(x.df.dungeon_id) < 4) { + e = 0; + } + break; + case 7: + if (GetMaxItemsAllowed(x.df.dungeon_id) == 0) { + e = 0; + } + case 6: + if (!sub_02062D40(&x.df)) { + e = 0; + } + break; + case 10: + if (mission->subtype.other == 4 && GetMaxMembersAllowed(x.df.dungeon_id) < 4) { + e = 0; + } + break; + default: + break; + } + if (e != 0) { + e = 0; + mission->dungeon_id = x.df.dungeon_id; + mission->floor = x.df.floor_id; + continue; + } + } + break; + } + e = 1; + } while (0); + if (e) { + ClearMissionData(mission); + return e; + } + mission->description_id = MtNext() & 0xFFFFFF; + sp08 = NULL; + } + do { + switch (tmpl->field_0x2[2].field_0x0) { + case 0: + case 1: { + m = tmpl->field_0x2[2].field_0x4; + if (!CheckMonsterForMissionType(tmpl->field_0x20, &tmpl->field_0x21, (enum monster_id)m, TRUE)) { + err = 1; + } else if (tmpl->field_0x20 == MISSION_CHALLENGE_REQUEST && tmpl->field_0x21.other == 0) { + if (CanMonsterBeUsedForMission(m, m != MONSTER_LUCARIO && m != MONSTER_LUCARIO_SECONDARY)) { + mission->client = (enum monster_id)m; + mission->target = (enum monster_id)*(u16 *)&tmpl->field_0x2[3].field_0x4; + mission->outlaw_backup_species = (enum monster_id)*(u16 *)&tmpl->field_0x2[4].field_0x4; + err = 0; + } else { + err = 1; + } + } else { + if (tmpl->field_0x2[2].field_0x0 == 0) { + if (!CanMonsterBeUsedForMissionWrapper(m)) { + err = 1; + continue; + } + } else if (!sub_02062AD0((enum monster_id)m)) { + err = 1; + continue; + } + mission->client = (enum monster_id)m; + break; + } + continue; + } + case 2: { + err = CountAndPopulateValidMissionTableMonsters(&sp08, &tmpl->field_0x2[2]); + if (err == 0) { + MemFree(sp08); + sp08 = NULL; + err = 1; + } else { + m = sp08[RandInt(err)]; + if (!CheckMonsterForMissionType(tmpl->field_0x20, &tmpl->field_0x21, (enum monster_id)m, TRUE)) { + MemFree(sp08); + sp08 = NULL; + err = 1; + } else { + if (!(tmpl->field_0x2[2].field_0x0 == tmpl->field_0x2[3].field_0x0 + && tmpl->field_0x2[2].field_0x2 == tmpl->field_0x2[3].field_0x2 + && (u16)tmpl->field_0x2[2].field_0x4 == (u16)tmpl->field_0x2[3].field_0x4)) { + err = 0; + MemFree(sp08); + sp08 = NULL; + } + mission->client = (enum monster_id)m; + if (!(mission->floor & 1)) { + mission->client = (enum monster_id)GetSecondFormIfValid((enum monster_id)mission->client); + } + break; + } + } + continue; + } + case 3: { + u16 n = tmpl->field_0x2[2].field_0x2; + sp08 = sub_020627F4() + (u16)tmpl->field_0x2[2].field_0x4; + m = sp08[RandInt(n)]; + if (!CheckMonsterForMissionType(tmpl->field_0x20, &tmpl->field_0x21, (enum monster_id)m, TRUE)) { + err = 1; + } else if (!sub_02062AD0((enum monster_id)m)) { + err = 1; + } else { + mission->client = (enum monster_id)m; + if (!(mission->floor & 1)) { + mission->client = (enum monster_id)GetSecondFormIfValid((enum monster_id)mission->client); + } + err = 0; + sp08 = NULL; + break; + } + continue; + } + case 4: { + s32 n = GetAllPossibleMonsters(&sp08); + if (n == 0) { + err = 2; + } else { + m = sp08[RandIntSafe(n)]; + if (!CheckMonsterForMissionType(tmpl->field_0x20, &tmpl->field_0x21, (enum monster_id)m, TRUE)) { + err = 1; + } else { + mission->client = (enum monster_id)m; + if (!(mission->floor & 1)) { + mission->client = (enum monster_id)GetSecondFormIfValid((enum monster_id)mission->client); + } + err = 0; + sp08 = NULL; + break; + } + } + continue; + } + } + if (sub_0205E1E8(mission)) { + if (sp08 != NULL) { + MemFree(sp08); + sp08 = NULL; + } + mission->target = (enum monster_id)mission->client; + mission->outlaw_backup_species = (enum monster_id)0; + err = 0; + } else { + int i; + s32 sl; + + if ((mission->type == MISSION_ARREST_OUTLAW && mission->subtype.outlaw == MISSION_OUTLAW_HIDEOUT) || + (mission->type == MISSION_CHALLENGE_REQUEST && mission->subtype.challenge == MISSION_CHALLENGE_NORMAL)) { + sl = 2; + } else { + mission->outlaw_backup_species = (enum monster_id)0; + sl = 1; + } + for (i = 0; i < sl || (err = 0); i++) { + switch (tmpl->field_0x2[i + 3].field_0x0) { + case 0: + case 1: { + m = tmpl->field_0x2[i + 3].field_0x4; + if (!CheckMonsterForMissionType(tmpl->field_0x20, &tmpl->field_0x21, (enum monster_id)m, 0)) { + err = 1; + break; + } else if (tmpl->field_0x20 == MISSION_ARREST_OUTLAW && + tmpl->field_0x21.outlaw == MISSION_OUTLAW_HIDEOUT) { + if (!CanMonsterBeUsedForMissionWrapper(m)) { + err = 1; + } else { + mission->target = (enum monster_id)m; + mission->outlaw_backup_species = (enum monster_id)*(u16 *)&tmpl->field_0x2[4].field_0x4; + err = 0; + } + break; + } else if (tmpl->field_0x2[i + 3].field_0x0 == 0) { + if (!CanMonsterBeUsedForMissionWrapper(m)) { + err = 1; + break; + } + } else { + if (!sub_02062AD0((enum monster_id)m)) { + err = 1; + break; + } + } + ((s16 *)&mission->target)[i] = m; + continue; + } + case 2: { + s16 id; + if (sp08 == NULL) { + err = CountAndPopulateValidMissionTableMonsters(&sp08, &tmpl->field_0x2[3] + i); + if (err == 0) { + MemFree(sp08); + sp08 = NULL; + err = 1; + break; + } + } + id = sp08[RandInt(err)]; + if (!CheckMonsterForMissionType(tmpl->field_0x20, &tmpl->field_0x21, (enum monster_id)id, 0)) { + MemFree(sp08); + sp08 = NULL; + err = 1; + } else { + if (i + 1 >= sl || + tmpl->field_0x2[(u32)i + 3].field_0x0 != tmpl->field_0x2[(u32)i + 4].field_0x0 || + tmpl->field_0x2[(u32)i + 3].field_0x2 != tmpl->field_0x2[(u32)i + 4].field_0x2 || + (u16)tmpl->field_0x2[(u32)i + 3].field_0x4 != (u16)tmpl->field_0x2[(u32)i + 4].field_0x4) { + err = 0; + MemFree(sp08); + sp08 = NULL; + } + ((s16 *)&mission->target)[i] = id; + if (!(mission->floor & 1)) { + ((s16 *)&mission->target)[i] = GetSecondFormIfValid(((s16 *)&mission->target)[i]); + } + continue; + } + break; + } + case 3: { + s16 id; + s32 m = tmpl->field_0x2[i + 3].field_0x2; + sp08 = sub_020627F4() + (u16)tmpl->field_0x2[i + 3].field_0x4; + id = sp08[RandInt(m)]; + if (!CheckMonsterForMissionType(tmpl->field_0x20, &tmpl->field_0x21, (enum monster_id)id, 0)) { + err = 1; + } else if (!sub_02062AD0((enum monster_id)id)) { + err = 1; + } else { + ((s16 *)&mission->target)[i] = id; + if (!(mission->floor & 1)) { + ((s16 *)&mission->target)[i] = GetSecondFormIfValid(((s16 *)&mission->target)[i]); + } + sp08 = NULL; + err = 0; + continue; + } + break; + } + case 4: + case 6: { + s16 id; + s32 m = GetAllPossibleMonsters(&sp08); + if (m == 0) { + err = 2; + } else { + id = sp08[RandIntSafe(m)]; + if (!CheckMonsterForMissionType(tmpl->field_0x20, &tmpl->field_0x21, (enum monster_id)id, 0)) { + err = 1; + } else { + ((s16 *)&mission->target)[i] = id; + if (!(mission->floor & 1)) { + ((s16 *)&mission->target)[i] = GetSecondFormIfValid(((s16 *)&mission->target)[i]); + } + sp08 = NULL; + continue; + } + } + break; + } + default: + continue; + } + break; + } + } + } while (0); + if (err != 0) { + ClearMissionData(mission); + return err; + } + do { + s16 item; + + switch (tmpl->field_0x2[0].field_0x0) { + case 0: + case 1: + item = tmpl->field_0x2[0].field_0x4; + if (CheckItemForMissionType(tmpl->field_0x20, &tmpl->field_0x21, item) == 0) { + err = 1; + } else if (tmpl->field_0x2[0].field_0x0 == 0 && IsAvailableItem(item) == 0) { + err = 1; + } else { + mission->item_wanted = (enum item_id)item; + break; + } + continue; + case 2: { + s16 *buf; + s32 k; + s32 i; + s32 n; + s32 off; + s16 v; + s16 *base; + + n = tmpl->field_0x2[0].field_0x2; + off = (u16)tmpl->field_0x2[0].field_0x4; + k = 0; + base = (s16 *)LoadMissionTemplates(); + buf = (s16 *)MemAlloc(n * 2, 0xf); + for (i = 0; i < n; i++) { + v = base[off + i]; + if (IsAvailableItem(v) != 0) { + buf[k] = v; + k++; + } + } + if (k == 0) { + MemFree(buf); + err = 1; + } else { + item = buf[RandIntSafe(k)]; + MemFree(buf); + if (CheckItemForMissionType(tmpl->field_0x20, &tmpl->field_0x21, item) == 0) { + err = 1; + } else { + mission->item_wanted = (enum item_id)item; + break; + } + } + continue; + } + case 3: { + s32 off; + s32 n; + s16 *p; + + n = tmpl->field_0x2[0].field_0x2; + off = (u16)tmpl->field_0x2[0].field_0x4; + p = (s16 *)LoadMissionTemplates() + off; + item = p[RandIntSafe(n)]; + if (CheckItemForMissionType(tmpl->field_0x20, &tmpl->field_0x21, item) == 0) { + err = 1; + } else { + mission->item_wanted = (enum item_id)item; + break; + } + continue; + } + case 4: { + s32 cnt; + s16 *lst; + s16 v; + + cnt = *(s32 *)&MISSION_DELIVER_LIST_PTR.unk0[4]; + lst = *(s16 **)&MISSION_DELIVER_LIST_PTR.unk0[0]; + if (cnt == 0) + v = 0x46; + else + v = lst[RandIntSafe(cnt)]; + mission->item_wanted = (enum item_id)v; + if (*(s16 *)&mission->item_wanted == 0) { + if (mission->type == 6 || mission->type == 7) { + err = 1; + continue; + } else { + do { + RollRandomItemReward((struct dungeon_floor_pair *)&mission->dungeon_id, + mission->type, + (s16 *)&mission->item_wanted); + } while (IsThrownItem(*(s16 *)&mission->item_wanted) + || !IsStorableItem(*(s16 *)&mission->item_wanted)); + } + } + break; + } + default: + break; + } + err = 0; + } while (0); + if (err != 0) { + ClearMissionData(mission); + return err; + } + if (mission->dungeon_id == 0x26 || mission->dungeon_id == 0x29 || + GetMaxMembersAllowed(*(volatile enum dungeon_id *)&mission->dungeon_id) < 4) { + mission->restriction_type = (enum mission_restriction_type)0; + mission->restriction.monster_id = (enum monster_id)0; + } else { + sub_02062900((u16)count, sp10, &mission->restriction_type); + } + err = 0; + mission->unique_map_id = 0; + switch (mission->type) { + case 3: + switch (mission->subtype.other) { + case 1: + mission->unique_map_id = GetMissionSpecificFixedRoom(mission->type, mission->subtype.other); + break; + case 2: + mission->unique_map_id = GetMissionSpecificFixedRoom(mission->type, mission->subtype.other); + break; + case 3: + break; + } + break; + case 6: + switch (mission->subtype.other) { + case 0: + case 1: + case 2: + case 3: + break; + case 4: + { + enum dungeon_id dn = mission->dungeon_id; + s32 v = sub_02063424(*(volatile enum mission_type *)&mission->type, &mission->subtype, dn); + if (sub_0205E090(dn, v, 1)) { + err = 1; + } else { + mission->floor = v; + } + break; + } + } + break; + case 9: + if (*(s16 *)&mission->item_wanted == 0x49 || mission->client == mission->target) { + err = 1; + } + break; + case 10: + switch (mission->subtype.other) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 7: + break; + case 6: + mission->unique_map_id = GetMissionSpecificFixedRoom(mission->type, mission->subtype.other); + break; + } + break; + case 11: + switch (mission->subtype.other) { + case 5: + { + enum dungeon_id dn = mission->dungeon_id; + s32 v = sub_02063424(*(volatile enum mission_type *)&mission->type, &mission->subtype, dn); + if (sub_0205E090(dn, v, 1)) { + err = 1; + break; + } + mission->floor = v; + } + case 0: + case 1: + case 2: + case 3: + case 4: + default: + mission->unique_map_id = GetMissionSpecificFixedRoom(mission->type, mission->subtype.other); + break; + } + break; + case 12: + mission->unique_map_id = GetMissionSpecificFixedRoom(mission->type, mission->subtype.other); + mission->restriction_type = (enum mission_restriction_type)0; + mission->restriction.monster_id = (enum monster_id)0; + break; + case 14: + switch (mission->subtype.other) { + case 1: + mission->restriction_type = (enum mission_restriction_type)0; + mission->restriction.monster_id = (enum monster_id)0; + break; + case 2: + err = 1; + break; + } + break; + } + if (err) { + ClearMissionData(mission); + return err; + } + + return 0; +}