pmd-red/src/code_80958E8_1.c
2023-12-10 13:18:48 -08:00

736 lines
19 KiB
C

#include "constants/mailbox.h"
#include "global.h"
#include "constants/friend_area.h"
#include "constants/dungeon.h"
#include "constants/monster.h"
#include "constants/wonder_mail.h"
#include "items.h"
#include "code_80958E8.h"
#include "code_80958E8_1.h"
#include "random.h"
#include "pokemon.h"
#include "code_8096AF8.h"
#include "mailbox_8095F8C.h"
#include "event_flag.h"
#include "rescue_team_info.h"
extern u8 sub_8095E38(WonderMail *, u8, u8, bool8);
extern void sub_80965F4();
u8 sub_8097318(s16 param_1);
extern bool8 GenerateMailJobInfo(WonderMail *);
bool8 sub_803C1D0(DungeonLocation *, u8);
u8 sub_8095F28(u8);
void sub_803C37C(DungeonLocation *, u8, u8 *);
bool8 sub_8096E80(u8);
u8 sub_8095E78(void);
void sub_8096078(void);
bool8 sub_80963B4(void);
static void SortMailboxSlots(void)
{
s32 r1;
s32 r6;
WonderMail job;
for(r1 = 0; r1 < NUM_MAILBOX_SLOTS - 1; r1++)
{
for(r6 = r1 + 1; r6 < NUM_MAILBOX_SLOTS; r6++)
{
if(gUnknown_203B490->mailboxSlots[r6].mailType != 0)
{
if((gUnknown_203B490->mailboxSlots[r1].unk4.dungeon.id > gUnknown_203B490->mailboxSlots[r6].unk4.dungeon.id) ||
((gUnknown_203B490->mailboxSlots[r1].unk4.dungeon.id == gUnknown_203B490->mailboxSlots[r6].unk4.dungeon.id) &&
(gUnknown_203B490->mailboxSlots[r1].unk4.dungeon.floor > gUnknown_203B490->mailboxSlots[r6].unk4.dungeon.floor)))
{
job = gUnknown_203B490->mailboxSlots[r1];
gUnknown_203B490->mailboxSlots[r1] = gUnknown_203B490->mailboxSlots[r6];
gUnknown_203B490->mailboxSlots[r6] = job;
}
}
}
}
}
void sub_80961B4(void)
{
if (sub_8096E2C() != 0) {
gUnknown_203B490->unk328 = TRUE;
}
}
bool8 sub_80961D8(void)
{
s32 num;
s32 index;
u32 floor;
s32 friendAreaReward;
WonderMail *slot;
bool8 flag = FALSE;
num = CountFilledMailboxSlots();
index = RandRange(num, NUM_MAILBOX_SLOTS);
if(num >= NUM_MAILBOX_SLOTS) return 0;
if(!gUnknown_203B490->unk328)
return 0;
else
{
gUnknown_203B490->unk328 = flag;
}
floor = 0x38;
if(sub_8001D08(0xA, 0x31, 0x1))
{
if(!gUnknown_203B490->PKMNNewsReceived[0x35])
if(!sub_8096E80(0x35)) floor = 0x35;
}
if(sub_80023E4(0xF))
{
if(!gUnknown_203B490->PKMNNewsReceived[0x34])
if(!sub_8096E80(0x34)) floor = 0x34;
if(!gUnknown_203B490->PKMNNewsReceived[0x33])
if(!sub_8096E80(0x33)) floor = 0x33;
if(!gUnknown_203B490->PKMNNewsReceived[0x32])
if(!sub_8096E80(0x32)) floor = 0x32;
}
if(GetRescueTeamRank() == LUCARIO_RANK)
{
if(!gUnknown_203B490->PKMNNewsReceived[0x36])
if(!sub_8096E80(0x36)) floor = 0x36;
}
if(sub_80023E4(6))
{
if(!gUnknown_203B490->PKMNNewsReceived[0x37])
if(!sub_8096E80(0x37)) floor = 0x37;
}
if(floor != 0x38) goto _slot;
if(num > index) goto _08096392;
floor = sub_8096E2C();
if(!sub_80023E4(0xE) && (floor > 2)) goto _0809638E;
if (floor > 0x31) goto _0809638E;
_slot:
slot = GetMailboxSlotInfo(num);
slot->mailType = 1;
slot->unk4.dungeon.id = NUM_DUNGEONS;
slot->unk4.dungeon.floor = floor;
goto _flag;
_0809638E:
for(; num <= index; num++)
{
slot = GetMailboxSlotInfo(num);
if(GenerateMailJobInfo(slot))
{
friendAreaReward = sub_8095E78();
if(!sub_803C1D0(&slot->unk4.dungeon, slot->missionType)) friendAreaReward = FRIEND_AREA_NONE;
slot->rewardType = RandRange(MONEY1, END_REWARDS);
if(slot->rewardType == FRIEND_AREA)
{
if(friendAreaReward == FRIEND_AREA_NONE)
{
slot->rewardType = MONEY1;
flag = TRUE;
}
else
{
slot->friendAreaReward = friendAreaReward;
flag = TRUE;
}
}
else
{
_flag:
flag = TRUE;
}
} else break;
}
_08096392:
if(sub_80963B4())
flag = TRUE;
sub_8096078();
SortMailboxSlots();
return flag;
}
bool8 sub_80963B4(void)
{
u8 floor;
s32 num;
WonderMail *slot;
bool8 flag = FALSE;
floor = sub_8096E2C();
num = CountFilledMailboxSlots();
if(num >= NUM_MAILBOX_SLOTS) return FALSE;
if(sub_80023E4(0xE))
{
if(floor < 0x32)
{
slot = GetMailboxSlotInfo(num);
slot->mailType = 1;
slot->unk4.dungeon.id = NUM_DUNGEONS;
slot->unk4.dungeon.floor = floor;
flag = TRUE;
}
}
return flag;
}
void sub_80963FC(void)
{
s32 index;
WonderMail *slot;
for(index = 0; index < NUM_MAILBOX_SLOTS; index++)
{
slot = GetMailboxSlotInfo(index);
if(slot->mailType != 1)
{
ResetMailboxSlot(index);
}
}
sub_8096078();
slot = GetMailboxSlotInfo(CountFilledMailboxSlots());
slot->mailType = 5;
slot->missionType = 0;
slot->unk2 = 0;
slot->unk4.dungeon.id = DUNGEON_MT_STEEL;
slot->unk4.dungeon.floor = 3;
slot->unk4.seed = 0x00ffffff & Rand32Bit();
slot->clientSpecies = MONSTER_PIDGEY;
slot->targetSpecies = MONSTER_PIDGEY;
slot->targetItem = sub_8095F28(slot->unk4.dungeon.id);
slot->rewardType = MONEY1;
do
{
sub_803C37C(&slot->unk4.dungeon, slot->missionType, &slot->itemReward);
} while (slot->targetItem == slot->itemReward);
slot->friendAreaReward = FRIEND_AREA_NONE;
sub_8096078();
SortMailboxSlots();
}
void sub_8096488(void)
{
WonderMail *mail;
s32 index;
for(index = 0; index < NUM_MAILBOX_SLOTS; index++){
ResetMailboxSlot(index);
}
mail = GetMailboxSlotInfo(0);
mail->mailType = 1;
mail->unk4.dungeon.id = NUM_DUNGEONS;
mail->unk4.dungeon.floor = 0;
}
bool8 sub_80964B4(void)
{
if ((!gUnknown_203B490->PKMNNewsReceived[0x35]) && (sub_8096E80(0x35) == 0)) {
return FALSE;
}
else {
return TRUE;
}
}
bool8 sub_80964E4(void)
{
if ((!gUnknown_203B490->PKMNNewsReceived[0x36]) && (sub_8096E80(0x36) == 0)) {
return FALSE;
}
else {
return TRUE;
}
}
s32 CountFilledPelipperBoardSlots(void)
{
s32 index;
s32 slots;
slots = 0;
for(index = 0; index < MAX_ACCEPTED_JOBS; index++) {
if (!IsPelipperBoardSlotEmpty(index)) {
slots++;
}
}
return slots;
}
UNUSED bool8 sub_8096538(WonderMail *mail)
{
s32 index;
for(index = 0; index < MAX_ACCEPTED_JOBS; index++)
{
if(gUnknown_203B490->pelipperBoardJobs[index].mailType == 0)
{
gUnknown_203B490->pelipperBoardJobs[index] = *mail;
return FALSE;
}
}
return TRUE;
}
WonderMail *GetPelipperBoardSlotInfo(u8 index)
{
return &gUnknown_203B490->pelipperBoardJobs[index];
}
bool8 IsPelipperBoardSlotEmpty(u8 index)
{
if (gUnknown_203B490->pelipperBoardJobs[index].mailType == 0)
return TRUE;
else
return FALSE;
}
void ResetPelipperBoardSlot(u8 index)
{
gUnknown_203B490->pelipperBoardJobs[index].mailType = MAIL_TYPE_NONE;
gUnknown_203B490->pelipperBoardJobs[index].unk4.dungeon.id = 99;
gUnknown_203B490->pelipperBoardJobs[index].unk4.dungeon.floor = 0;
gUnknown_203B490->pelipperBoardJobs[index].rewardType = 0;
}
NAKED
void sub_80965F4(void)
{
asm_unified(
"\tpush {r4-r7,lr}\n"
"\tmov r7, r9\n"
"\tmov r6, r8\n"
"\tpush {r6,r7}\n"
"\tmovs r2, 0\n"
"\tmovs r3, 0\n"
"\tldr r0, _0809660C\n"
"\tmov r12, r0\n"
"\tmov r8, r3\n"
"\tmovs r4, 0\n"
"\tmov r9, r4\n"
"\tb _08096636\n"
"\t.align 2, 0\n"
"_0809660C: .4byte gUnknown_203B490\n"
"_08096610:\n"
"\tcmp r2, r3\n"
"\tble _0809662A\n"
"\tmov r1, r12\n"
"\tldr r0, [r1]\n"
"\tmov r5, r8\n"
"\tadds r1, r0, r5\n"
"\tadds r0, r4\n"
"\tadds r1, 0x50\n"
"\tadds r0, 0x50\n"
"\tldm r0!, {r5-r7}\n"
"\tstm r1!, {r5-r7}\n"
"\tldm r0!, {r6,r7}\n"
"\tstm r1!, {r6,r7}\n"
"_0809662A:\n"
"\tadds r4, 0x14\n"
"\tmovs r0, 0x14\n"
"\tadd r9, r0\n"
"\tadds r2, 0x1\n"
"\tadd r8, r0\n"
"\tadds r3, 0x1\n"
"_08096636:\n"
"\tcmp r2, 0x7\n"
"\tbgt _08096666\n"
"\tmov r1, r12\n"
"\tldr r0, [r1]\n"
"\tadds r0, r4\n"
"\tadds r0, 0x50\n"
"\tldrb r0, [r0]\n"
"\tcmp r0, 0\n"
"\tbne _08096666\n"
"\tldr r6, _08096694\n"
"\tmov r1, r9\n"
"_0809664C:\n"
"\tadds r1, 0x14\n"
"\tadds r4, 0x14\n"
"\tmovs r5, 0x14\n"
"\tadd r9, r5\n"
"\tadds r2, 0x1\n"
"\tcmp r2, 0x7\n"
"\tbgt _08096666\n"
"\tldr r0, [r6]\n"
"\tadds r0, r1\n"
"\tadds r0, 0x50\n"
"\tldrb r0, [r0]\n"
"\tcmp r0, 0\n"
"\tbeq _0809664C\n"
"_08096666:\n"
"\tcmp r2, 0x8\n"
"\tbne _08096610\n"
"\tcmp r3, 0x7\n"
"\tbgt _08096688\n"
"\tldr r4, _08096694\n"
"\tmovs r2, 0\n"
"\tlsls r0, r3, 2\n"
"\tadds r0, r3\n"
"\tlsls r1, r0, 2\n"
"_08096678:\n"
"\tldr r0, [r4]\n"
"\tadds r0, r1\n"
"\tadds r0, 0x50\n"
"\tstrb r2, [r0]\n"
"\tadds r1, 0x14\n"
"\tadds r3, 0x1\n"
"\tcmp r3, 0x7\n"
"\tble _08096678\n"
"_08096688:\n"
"\tpop {r3,r4}\n"
"\tmov r8, r3\n"
"\tmov r9, r4\n"
"\tpop {r4-r7}\n"
"\tpop {r0}\n"
"\tbx r0\n"
"\t.align 2, 0\n"
"_08096694: .4byte gUnknown_203B490");
}
void SortPelipperJobs(void)
{
s32 index1;
s32 index2;
WonderMail mail;
for(index1 = 0; index1 < MAX_ACCEPTED_JOBS - 1; index1++)
{
for(index2 = index1 + 1; index2 < MAX_ACCEPTED_JOBS; index2++)
{
if(gUnknown_203B490->pelipperBoardJobs[index2].mailType != MAIL_TYPE_NONE)
{
if((gUnknown_203B490->pelipperBoardJobs[index1].unk4.dungeon.id > gUnknown_203B490->pelipperBoardJobs[index2].unk4.dungeon.id) ||
((gUnknown_203B490->pelipperBoardJobs[index1].unk4.dungeon.id == gUnknown_203B490->pelipperBoardJobs[index2].unk4.dungeon.id) && (gUnknown_203B490->pelipperBoardJobs[index1].unk4.dungeon.floor > gUnknown_203B490->pelipperBoardJobs[index2].unk4.dungeon.floor)))
{
mail = gUnknown_203B490->pelipperBoardJobs[index1];
gUnknown_203B490->pelipperBoardJobs[index1] = gUnknown_203B490->pelipperBoardJobs[index2];
gUnknown_203B490->pelipperBoardJobs[index2] = mail;
}
}
}
}
}
void GeneratePelipperJobs(void)
{
s32 range;
WonderMail *mail;
s32 index;
range = RandRange(4,8);
for(index = 0; index < MAX_ACCEPTED_JOBS; index++)
{
gUnknown_203B490->pelipperBoardJobs[index].mailType = MAIL_TYPE_NONE;
}
index = 0;
if (sub_8097318(0xe) != 0) {
mail = GetPelipperBoardSlotInfo(0);
mail->mailType = MAIL_TYPE_UNK2;
mail->missionType = WONDER_MAIL_MISSION_TYPE_UNK6;
mail->unk2 = 1;
mail->unk4.dungeon.id = DUNGEON_UPROAR_FOREST;
mail->unk4.dungeon.floor = 10;
mail->unk4.seed = Rand32Bit() & 0xffffff;
mail->clientSpecies = MONSTER_WYNAUT;
mail->targetSpecies = MONSTER_MANKEY;
mail->targetItem = 0;
mail->rewardType = ITEM;
mail->itemReward = ITEM_REVIVER_SEED;
mail->friendAreaReward = 0;
index = 1;
}
if (sub_8097318(0xf) != 0) {
mail = GetPelipperBoardSlotInfo(index);
mail->mailType = MAIL_TYPE_UNK3;
mail->missionType = WONDER_MAIL_MISSION_TYPE_UNK6;
mail->unk2 = 2;
mail->unk4.dungeon.id = DUNGEON_HOWLING_FOREST;
mail->unk4.dungeon.floor = 15;
mail->unk4.seed = Rand32Bit() & 0xffffff;
mail->clientSpecies = MONSTER_SMEARGLE;
mail->targetSpecies = MONSTER_SMEARGLE;
mail->targetItem = 0;
mail->rewardType = ITEM;
mail->itemReward = ITEM_REVIVER_SEED;
mail->friendAreaReward = 0;
index++;
}
if (sub_8097318(0x1c) != 0) {
mail = GetPelipperBoardSlotInfo(index);
mail->mailType = MAIL_TYPE_UNK4;
mail->missionType = WONDER_MAIL_MISSION_TYPE_UNK6;
mail->unk2 = 3;
mail->unk4.dungeon.id = DUNGEON_WISH_CAVE;
mail->unk4.dungeon.floor = 20;
mail->unk4.seed = Rand32Bit() & 0xffffff;
mail->clientSpecies = MONSTER_MEDICHAM;
mail->targetSpecies = MONSTER_MEDICHAM;
mail->targetItem = 0;
mail->rewardType = ITEM;
mail->itemReward = ITEM_REVIVER_SEED;
mail->friendAreaReward = 0;
index++;
}
for (; index <= range; index++) {
if (!GenerateMailJobInfo(&gUnknown_203B490->pelipperBoardJobs[index])) break;
gUnknown_203B490->pelipperBoardJobs[index].rewardType = RandRange(MONEY, BLANK_4);
}
sub_80965F4();
SortPelipperJobs();
}
bool8 IsMailinJobSlot(WonderMail *mail)
{
WonderMail *jobSlot;
s32 index;
for(index = 0, jobSlot = &gUnknown_203B490->jobSlots[0]; index < MAX_ACCEPTED_JOBS; jobSlot++, index++)
{
if(jobSlot->mailType != MAIL_TYPE_NONE)
if(mail->missionType == jobSlot->missionType)
if(mail->unk2 == jobSlot->unk2)
if(mail->unk4.dungeon.id == jobSlot->unk4.dungeon.id)
if(mail->unk4.dungeon.floor == jobSlot->unk4.dungeon.floor)
if(mail->unk4.seed == jobSlot->unk4.seed)
if(mail->clientSpecies == jobSlot->clientSpecies)
if(mail->targetSpecies == jobSlot->targetSpecies)
if(mail->targetItem == jobSlot->targetItem)
if(mail->rewardType == jobSlot->rewardType)
if(mail->itemReward == jobSlot->itemReward)
if(mail->friendAreaReward == jobSlot->friendAreaReward)
return TRUE;
}
return FALSE;
}
bool8 sub_809693C(WonderMail *mail)
{
u8 dungeonIndex;
u8 floor;
bool8 escortMission;
s32 index;
dungeonIndex = mail->unk4.dungeon.id;
floor = mail->unk4.dungeon.floor;
escortMission = FALSE;
if (!IsValidWonderMail(mail)) {
return FALSE;
}
else
{
if(mail->missionType == WONDER_MAIL_MISSION_TYPE_ESCORT_CLIENT)
escortMission = TRUE;
for(index = 0; index < MAX_ACCEPTED_JOBS; index++)
{
if ((gUnknown_203B490->jobSlots[index].mailType == MAIL_TYPE_TAKEN_JOB) &&
(sub_8095E38(&gUnknown_203B490->jobSlots[index],dungeonIndex,floor,escortMission) != 0))
{
return TRUE;
}
}
}
return FALSE;
}
s32 GetNumAcceptedJobs(void)
{
s32 index;
s32 count;
count = 0;
for(index = 0; index < MAX_ACCEPTED_JOBS; index++)
{
if (!IsJobSlotEmpty(index)) {
count++;
}
}
return count;
}
s32 CountJobsinDungeon(u8 dungeon)
{
WonderMail *mail;
s32 index;
s32 count;
count = 0;
for(index = 0; index < MAX_ACCEPTED_JOBS; index++)
{
mail = GetJobSlotInfo(index);
if ((mail->unk4.dungeon.id == dungeon) &&
(((mail->mailType == MAIL_TYPE_TAKEN_JOB || (mail->mailType == MAIL_TYPE_UNK8)) || (mail->mailType == MAIL_TYPE_UNK9)))) {
count++;
}
}
return count;
}
bool8 sub_8096A08(u8 dungeon, PokemonStruct1 *pokemon)
{
WonderMail *mail;
s32 index;
u32 local_14;
s32 temp;
for(index = 0; index < MAX_ACCEPTED_JOBS; index++)
{
mail = GetJobSlotInfo(index);
if(mail->unk4.dungeon.id == dungeon)
if(mail->mailType == MAIL_TYPE_TAKEN_JOB)
if(mail->missionType == WONDER_MAIL_MISSION_TYPE_ESCORT_CLIENT)
{
temp = 0xffffff00;
local_14 &= temp;
temp = 0x4A;
local_14 |= temp;
temp = 0xffff00ff;
local_14 &= temp;
temp = 0x100;
local_14 |= temp;
sub_808CFD0(pokemon,mail->clientSpecies,NULL,0,(DungeonLocation *) &local_14,NULL);
return TRUE;
}
}
return FALSE;
}
bool8 AcceptJob(WonderMail *mail)
{
s32 index;
for(index = 0; index < MAX_ACCEPTED_JOBS; index++)
{
if(gUnknown_203B490->jobSlots[index].mailType == MAIL_TYPE_NONE)
{
gUnknown_203B490->jobSlots[index] = *mail;
return FALSE;
}
}
return TRUE;
}
WonderMail *GetJobSlotInfo(u8 index)
{
return &gUnknown_203B490->jobSlots[index];
}
bool8 IsJobSlotEmpty(u8 index)
{
if(gUnknown_203B490->jobSlots[index].mailType == MAIL_TYPE_NONE)
return TRUE;
else
return FALSE;
}
void sub_8096AF8(struct unkStruct_8096AF8 *param_1, u8 slotIndex,u8 dungeon)
{
WonderMail *jobSlot;
Item *item;
s32 index;
jobSlot = GetJobSlotInfo(slotIndex);
param_1->unk0 = FALSE;
param_1->clientSpecies = jobSlot->clientSpecies;
param_1->targetSpecies = MONSTER_NONE;
if (jobSlot->unk4.dungeon.id == dungeon) {
switch(jobSlot->missionType) {
case WONDER_MAIL_MISSION_TYPE_FIND_ITEM:
if (jobSlot->mailType == MAIL_TYPE_TAKEN_JOB) {
for(index = 0; index < INVENTORY_SIZE; index++)
{
item = &gTeamInventoryRef->teamItems[index];
if (((item->flags & ITEM_FLAG_EXISTS)) && (item->id == jobSlot->targetItem)) {
param_1->unk0 = TRUE;
}
}
}
break;
case WONDER_MAIL_MISSION_TYPE_RESCUE_CLIENT:
case WONDER_MAIL_MISSION_TYPE_DELIVER_ITEM:
if (jobSlot->mailType == MAIL_TYPE_UNK9) {
param_1->unk0 = TRUE;
}
break;
case WONDER_MAIL_MISSION_TYPE_RESCUE_TARGET:
case WONDER_MAIL_MISSION_TYPE_ESCORT_CLIENT:
if (jobSlot->mailType == MAIL_TYPE_UNK9) {
param_1->unk0 = TRUE;
param_1->targetSpecies = jobSlot->targetSpecies;
}
break;
}
}
}
// Unused
s16 sub_8096B98(u8 dungeon)
{
WonderMail *mail;
s32 index;
for(index = 0; index < MAX_ACCEPTED_JOBS; index++)
{
mail = GetJobSlotInfo(index);
if(mail->mailType == MAIL_TYPE_TAKEN_JOB)
if(mail->missionType == WONDER_MAIL_MISSION_TYPE_ESCORT_CLIENT)
if(mail->unk4.dungeon.id == dungeon)
return mail->targetSpecies;
}
return 0;
}
void sub_8096BD0(void)
{
s32 index;
WonderMail *mail;
for(mail = &gUnknown_203B490->jobSlots[0], index = 0; index < MAX_ACCEPTED_JOBS; mail++, index++)
{
switch(mail->mailType)
{
case MAIL_TYPE_UNK7:
case MAIL_TYPE_UNK8:
case MAIL_TYPE_UNK9:
ResetJobSlot(index);
break;
}
}
sub_8096C80();
SortJobSlots();
}
bool8 sub_8096C08(u8 *jobIndex)
{
s32 index;
WonderMail *mail;
for(mail = &gUnknown_203B490->jobSlots[0], index = 0; index < MAX_ACCEPTED_JOBS; mail++, index++)
{
if(mail->mailType > 4 && mail->unk2 == 4)
{
*jobIndex = index;
return TRUE;
}
}
return FALSE;
}
void ResetJobSlot(u8 index)
{
gUnknown_203B490->jobSlots[index].mailType = MAIL_TYPE_NONE;
gUnknown_203B490->jobSlots[index].unk4.dungeon.id = 99;
gUnknown_203B490->jobSlots[index].unk4.dungeon.floor = 0;
gUnknown_203B490->jobSlots[index].rewardType = MONEY1;
}