#include "ac_quest_manager.h" #include "m_common_data.h" #include "m_msg.h" #include "m_melody.h" #include "ac_quest_talk_greeting.h" #include "ac_quest_talk_init.h" #include "ac_quest_talk_fj_init.h" #include "ac_quest_talk_normal_init.h" #include "ac_quest_talk_island.h" #include "m_soncho.h" #include "gfxalloc.h" #include "m_player_lib.h" #include "libultra/libultra.h" #include "m_malloc.h" #include "zurumode.h" enum { aQMgr_MODE_NORMAL, aQMgr_MODE_SELECT_TALK, aQMgr_MODE_MOVE_TALK, aQMgr_MODE_TALK_FIN, aQMgr_MODE_TALK_START_KAMAKURA_HELLO, aQMgr_MODE_TALK_START_KAMAKURA, aQMgr_MODE_TALK_START_SUMMERCAMP_HELLO, aQMgr_MODE_TALK_START_SUMMERCAMP, aQMgr_MODE_NUM }; static ACTOR* l_client_p = NULL; static u8 l_quest_manager_mode = aQMgr_MODE_NORMAL; static Anmmem_c* l_quest_memory_p = NULL; static QUEST_MANAGER_ACTOR* l_quest_actor_p = NULL; static int l_quest_manager_hello = FALSE; static int l_aQMgr_hand_start = FALSE; // clang-format off static aQMgr_set_data_c l_set_delivery_data[] = { { aQMgr_QUEST_TARGET_RANDOM, 2, 0, TRUE, aQMgr_QUEST_ITEM_CLOTH, EMPTY_NO, 40, 0, 0, 0, 0, 30, 30, 0, 200, 0x0151, 0x024C, 0x0163, 0x025E, 0x0175, 0x0294, 0x0187, 0x02B8, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, { aQMgr_QUEST_TARGET_FOREIGN, 2, 0, TRUE, aQMgr_QUEST_ITEM_RANDOM, EMPTY_NO, 40, 0, 0, 10, 10, 40, 0, 0, 1000, 0x0199, 0x024C, 0x01AB, 0x025E, 0x01BD, 0x0294, 0x01CF, 0x02CA, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, { aQMgr_QUEST_TARGET_LAST_REMOVE, 2, 0, TRUE, aQMgr_QUEST_ITEM_RANDOM, EMPTY_NO, 20, 0, 0, 20, 20, 40, 0, 0, 1000, 0x0205, 0x024C, 0x0217, 0x025E, 0x10BF, 0x0294, 0x023A, 0x02CA, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, { aQMgr_QUEST_TARGET_RANDOM, 2, 0, TRUE, aQMgr_QUEST_ITEM_RANDOM, EMPTY_NO, 40, 0, 40, 10, 10, 0, 0, 0, 0, 0x0A74, 0x024C, 0x0A86, 0x025E, 0x0A98, 0x0294, 0x0AAA, 0x02B8, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, }; static aQMgr_set_data_c l_set_errand_data[] = { { aQMgr_QUEST_TARGET_RANDOM_EXCLUDED, 2, 4, FALSE, aQMgr_QUEST_ITEM_RANDOM, EMPTY_NO, 50, 0, 0, 0, 0, 0, 0, 0, 500, 0x038C, 0x024C, 0x03D4, 0x025E, 0x03F8, 0x0294, 0x2B73, 0x02CA, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, { aQMgr_QUEST_TARGET_RANDOM_EXCLUDED, 2, 1, FALSE, aQMgr_QUEST_ITEM_CURRENT_ITEM, EMPTY_NO, 50, 0, 0, 0, 0, 0, 0, 0, 500, 0x03B0, 0x024C, 0x03E6, 0x025E, 0x03F8, 0x0294, 0x041C, 0x02CA, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, { aQMgr_QUEST_TARGET_ORIGINAL_TARGET, 2, 0, TRUE, aQMgr_QUEST_ITEM_CURRENT_ITEM, EMPTY_NO, 50, 0, 0, 0, 0, 0, 0, 0, 500, 0x039E, 0x024C, 0x03C2, 0x025E, 0x03F8, 0x0294, 0x040A, 0x0452, 0x17B8, 0x035E, 0x034C, 0x0370, 0x033A }, { aQMgr_QUEST_TARGET_CLIENT, 0, 0, FALSE, aQMgr_QUEST_ITEM_CURRENT_ITEM, EMPTY_NO, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, { aQMgr_QUEST_TARGET_CLIENT, 0, 0, FALSE, aQMgr_QUEST_ITEM_CURRENT_ITEM, EMPTY_NO, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, { aQMgr_QUEST_TARGET_CLIENT, 0, 0, FALSE, aQMgr_QUEST_ITEM_CURRENT_ITEM, EMPTY_NO, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0x0000, 0x0000, 0x0000, 0x0000, 0x08EF, 0x08F0, 0x0000, 0x0000, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, { aQMgr_QUEST_TARGET_CLIENT, 0, 0, FALSE, aQMgr_QUEST_ITEM_CURRENT_ITEM, EMPTY_NO, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, { aQMgr_QUEST_TARGET_CLIENT, 0, 0, FALSE, aQMgr_QUEST_ITEM_CURRENT_ITEM, EMPTY_NO, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0x0000, 0x0000, 0x0000, 0x0000, 0x08FB, 0x08FC, 0x0000, 0x0000, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, { aQMgr_QUEST_TARGET_CLIENT, 0, 0, FALSE, aQMgr_QUEST_ITEM_CURRENT_ITEM, EMPTY_NO, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0907, 0x0908, 0x0000, 0x0000, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, { aQMgr_QUEST_TARGET_CLIENT, 0, 0, FALSE, aQMgr_QUEST_ITEM_CURRENT_ITEM, EMPTY_NO, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, { aQMgr_QUEST_TARGET_CLIENT, 0, 0, FALSE, aQMgr_QUEST_ITEM_CURRENT_ITEM, EMPTY_NO, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, { aQMgr_QUEST_TARGET_CLIENT, 0, 0, FALSE, aQMgr_QUEST_ITEM_CURRENT_ITEM, EMPTY_NO, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0907, 0x0908, 0x0000, 0x0000, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, { aQMgr_QUEST_TARGET_CLIENT, 0, 0, FALSE, aQMgr_QUEST_ITEM_CURRENT_ITEM, EMPTY_NO, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, { aQMgr_QUEST_TARGET_CLIENT, 0, 0, FALSE, aQMgr_QUEST_ITEM_CURRENT_ITEM, EMPTY_NO, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, { aQMgr_QUEST_TARGET_CLIENT, 0, 0, FALSE, aQMgr_QUEST_ITEM_CURRENT_ITEM, EMPTY_NO, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, }; static aQMgr_set_data_c l_set_contest_data[] = { { aQMgr_QUEST_TARGET_CLIENT, 1, 1, FALSE, aQMgr_QUEST_ITEM_FRUIT, EMPTY_NO, 0, 0, 0, 30, 30, 40, 0, 0, 500, 0x01E1, 0x0000, 0x01E1, 0x025E, 0x01F3, 0x117C, 0x0000, 0x02CA, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, { aQMgr_QUEST_TARGET_CLIENT, 1, 2, FALSE, aQMgr_QUEST_ITEM_NONE, EMPTY_NO, 40, 0, 0, 30, 30, 0, 0, 0, 0, 0x0D79, 0x0000, 0x0D79, 0x025E, 0x0D91, 0x0DD9, 0x0000, 0x02CA, 0x0440, 0x0DFD, 0x0DD9, 0x0DEB, 0x0E0F }, { aQMgr_QUEST_TARGET_CLIENT, 1, 1, FALSE, aQMgr_QUEST_ITEM_NONE, EMPTY_NO, 60, 0, 0, 20, 20, 0, 0, 0, 0, 0x0E33, 0x0000, 0x0E33, 0x025E, 0x0E45, 0x0E8D, 0x0000, 0x02CA, 0x0440, 0x0EB1, 0x0E8D, 0x0E9F, 0x0EC3 }, { aQMgr_QUEST_TARGET_CLIENT, 3, 1, FALSE, aQMgr_QUEST_ITEM_NONE, EMPTY_NO, 60, 0, 0, 20, 20, 0, 0, 0, 0, 0x0FB5, 0x0000, 0x0FB5, 0x025E, 0x0FC7, 0x100F, 0x0000, 0x02CA, 0x0440, 0x1033, 0x100F, 0x1021, 0x1045 }, { aQMgr_QUEST_TARGET_CLIENT, 3, 1, FALSE, aQMgr_QUEST_ITEM_NONE, EMPTY_NO, 80, 0, 0, 10, 10, 0, 0, 0, 0, 0x158C, 0x0000, 0x158C, 0x025E, 0x159E, 0x15B0, 0x0000, 0x02CA, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, { aQMgr_QUEST_TARGET_CLIENT, 3, 1, FALSE, aQMgr_QUEST_ITEM_NONE, EMPTY_NO, 80, 0, 0, 10, 10, 0, 0, 0, 0, 0x160A, 0x0000, 0x160A, 0x025E, 0x161C, 0x162E, 0x0000, 0x02CA, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, { aQMgr_QUEST_TARGET_CLIENT, 2, 2, FALSE, aQMgr_QUEST_ITEM_NONE, EMPTY_NO, 80, 0, 0, 10, 10, 0, 0, 0, 0, 0x1AE1, 0x0000, 0x1AE1, 0x025E, 0x1B17, 0x0294, 0x0000, 0x02CA, 0x0440, 0x035E, 0x034C, 0x0370, 0x033A }, }; //clang-format on static aQMgr_set_data_c* l_set_data[mQst_QUEST_TYPE_NUM] = { l_set_delivery_data, l_set_errand_data, l_set_contest_data }; static void aQMgr_move_own_errand_cloth(QUEST_MANAGER_ACTOR* manager, aQMgr_regist_c* regist); static void aQMgr_move_own_errand_seed(QUEST_MANAGER_ACTOR* manager, aQMgr_regist_c* regist); static void aQMgr_move_own_errand_letter(QUEST_MANAGER_ACTOR* manager, aQMgr_regist_c* regist); static void aQMgr_move_own_errand_hello(QUEST_MANAGER_ACTOR* manager, aQMgr_regist_c* regist); static void aQMgr_contest_check_limit(QUEST_MANAGER_ACTOR* manager, aQMgr_regist_c* regist) ; static int aQMgr_actor_check_fin_fruit(mQst_base_c* quest_info, Animal_c* animal); static int aQMgr_actor_check_fin_soccer(mQst_base_c* quest_info, Animal_c* animal); static void aQMgr_actor_contest_snowman_clear(QUEST_MANAGER_ACTOR* manager, aQMgr_regist_c* regist); static int aQMgr_actor_check_fin_snowman(mQst_base_c* quest_info, Animal_c* animal); static void aQMgr_actor_contest_flower_clear(QUEST_MANAGER_ACTOR* manager, aQMgr_regist_c* regist); static int aQMgr_actor_check_flower(mQst_contest_c* contest, int bx, int bz); static int aQMgr_actor_check_fin_flower(mQst_base_c* quest_info, Animal_c* animal); static int aQMgr_actor_check_fin_fish(mQst_base_c* quest_info, Animal_c* animal); static void aQMgr_actor_contest_insect_clear(QUEST_MANAGER_ACTOR* manager, aQMgr_regist_c* regist); static int aQMgr_actor_check_fin_insect(mQst_base_c* quest_info, Animal_c* animal); static int aQMgr_actor_check_fin_contest_letter(mQst_base_c* quest_info, Animal_c* animal); static void aQMgr_save_contest_flower(aQMgr_regist_c* regist); static void aQMgr_save_contest(aQMgr_regist_c* regist); static aQMgr_CHECK_LIMIT_PROC l_errand_proc[mQst_ERRAND_NUM] = { (aQMgr_CHECK_LIMIT_PROC)&none_proc1, (aQMgr_CHECK_LIMIT_PROC)&none_proc1, (aQMgr_CHECK_LIMIT_PROC)&none_proc1, &aQMgr_move_own_errand_cloth, &aQMgr_move_own_errand_seed, (aQMgr_CHECK_LIMIT_PROC)&none_proc1, &aQMgr_move_own_errand_letter, (aQMgr_CHECK_LIMIT_PROC)&none_proc1, (aQMgr_CHECK_LIMIT_PROC)&none_proc1, (aQMgr_CHECK_LIMIT_PROC)&none_proc1, &aQMgr_move_own_errand_letter, (aQMgr_CHECK_LIMIT_PROC)&none_proc1, &aQMgr_move_own_errand_hello, (aQMgr_CHECK_LIMIT_PROC)&none_proc1, (aQMgr_CHECK_LIMIT_PROC)&none_proc1 }; static aQMgr_CHECK_LIMIT_PROC l_contest_proc[mQst_CONTEST_KIND_NUM] = { &aQMgr_contest_check_limit, &aQMgr_contest_check_limit, &aQMgr_actor_contest_snowman_clear, &aQMgr_actor_contest_flower_clear, &aQMgr_contest_check_limit, &aQMgr_actor_contest_insect_clear, &aQMgr_contest_check_limit }; static aQMgr_CHECK_FINISH_PROC l_contest_check[mQst_CONTEST_KIND_NUM] = { &aQMgr_actor_check_fin_fruit, &aQMgr_actor_check_fin_soccer, &aQMgr_actor_check_fin_snowman, &aQMgr_actor_check_fin_flower, &aQMgr_actor_check_fin_fish, &aQMgr_actor_check_fin_insect, &aQMgr_actor_check_fin_contest_letter }; static int l_proc_max[mQst_QUEST_TYPE_NUM] = { mQst_DELIVERY_KIND_NUM, mQst_ERRAND_NUM, mQst_CONTEST_KIND_NUM }; static void aQMgr_actor_set_memory(ACTOR* client) { Animal_c* animal; if (client != NULL && client->part == ACTOR_PART_NPC) { animal = ((NPC_ACTOR*)client)->npc_info.animal; } else { animal = NULL; } if (animal != NULL) { Anmmem_c* memory = animal->memories; int memory_idx = mNpc_GetAnimalMemoryIdx(&Common_Get(now_private)->player_ID, memory, ANIMAL_MEMORY_NUM); if (memory_idx != -1) { memory += memory_idx; l_quest_memory_p = memory; } else { l_quest_memory_p = NULL; } } } static void aQMgr_actor_set_hello_free_str(Animal_c* animal) { int mem_idx = mNpc_GetAnimalMemoryIdx(&Common_Get(now_private)->player_ID, animal->memories, ANIMAL_MEMORY_NUM); if (mem_idx != -1 && mNpc_CheckIslandAnimal(animal) == FALSE) { mLd_SetFreeStrLandMuraName(animal->memories[mem_idx].memuni.land.name, mMsg_FREE_STR6); } if (mNpc_CheckIslandAnimal(animal) == FALSE) { mLd_SetFreeStrLandMuraName(animal->anmuni.previous_land_name, mMsg_FREE_STR10); } mLd_SetFreeStrLandMuraName(animal->id.land_name, mMsg_FREE_STR11); } static int aQMgr_take_hello_msg_no(QUEST_MANAGER_ACTOR* manager) { ACTOR* client = *manager->client; Animal_c* animal = ((NPC_ACTOR*)client)->npc_info.animal; PersonalID_c* pid = &Common_Get(now_private)->player_ID; if (animal != NULL) { if (mNpc_GetAnimalMemoryIdx(pid, animal->memories, ANIMAL_MEMORY_NUM) == -1) { l_quest_manager_hello = TRUE; } else { l_quest_manager_hello = FALSE; } } else { l_quest_manager_hello = TRUE; } return aQMgr_get_hello_msg_no(client, manager->get_time_kind_proc, manager->give_item); } static void aQMgr_set_talk_info(ACTOR* client) { QUEST_MANAGER_ACTOR* manager = l_quest_actor_p; Animal_c* animal = ((NPC_ACTOR*)client)->npc_info.animal; int msg_no; l_client_p = client; msg_no = aQMgr_take_hello_msg_no(manager); mDemo_Set_msg_num(msg_no); if (animal->mood == mNpc_FEEL_SLEEPY) { animal->mood = mNpc_FEEL_NORMAL; ((NPC_ACTOR*)client)->condition_info.feel_tim = 0; } ((NPC_ACTOR*)client)->talk_info.feel = animal->mood; aQMgr_actor_set_hello_free_str(animal); if (animal != NULL) { manager->cloth = animal->cloth; } if (ZURUMODE2_ENABLED()) { mNpc_SetTalkAnimalIdx_fdebug(&animal->id); } } static int aQMgr_actor_talk_request(ACTOR* client) { int res = FALSE; if (client != NULL && l_quest_manager_mode == aQMgr_MODE_NORMAL) { if (mDemo_Check(mDemo_TYPE_TALK, client) == FALSE) { mDemo_Request(mDemo_TYPE_TALK, client, &aQMgr_set_talk_info); } else if (mDemo_Check_ListenAble() == FALSE) { res = TRUE; } } return res; } static int aQMgr_actor_talk_start(ACTOR* client) { int res = FALSE; if (client != NULL && l_quest_manager_mode == aQMgr_MODE_NORMAL && mDemo_Check(mDemo_TYPE_TALK, client) == TRUE && mDemo_Check_ListenAble() == FALSE && mDemo_Check_SpeakerAble() == TRUE && client == l_client_p) { mDemo_Set_ListenAble(); if (client->npc_id == SP_NPC_EV_KAMAKURA_0) { if (l_quest_manager_hello == TRUE) { l_quest_manager_mode = aQMgr_MODE_TALK_START_KAMAKURA_HELLO; } else { l_quest_manager_mode = aQMgr_MODE_TALK_START_KAMAKURA; } } else if (client->npc_id == SP_NPC_EV_SUMMERCAMP_0) { if (l_quest_manager_hello == TRUE) { l_quest_manager_mode = aQMgr_MODE_TALK_START_SUMMERCAMP_HELLO; Common_Set(npc_is_summercamper, TRUE); } else { l_quest_manager_mode = aQMgr_MODE_TALK_START_SUMMERCAMP; } } else { l_quest_manager_mode = aQMgr_MODE_SELECT_TALK; } aQMgr_actor_set_memory(client); mMld_ActorMakeMelody(client); res = TRUE; } return res; } static int aQMgr_actor_talk_check(ACTOR* client) { int res = FALSE; if (client != NULL && l_client_p == client && l_quest_manager_mode == aQMgr_MODE_TALK_FIN && mDemo_Get_talk_actor() != client) { l_client_p = NULL; l_quest_manager_mode = aQMgr_MODE_NORMAL; res = TRUE; } return res; } static int aQMgr_get_time_kind(int hour) { int res = aQMgr_TIME_MORNING; if (hour >= 12 && hour < 17) { res = aQMgr_TIME_DAY; } else if (hour >= 17 && hour < 24) { res = aQMgr_TIME_EVENING; } else if (hour >= 0 && hour < 5) { res = aQMgr_TIME_NIGHT; } return res; } static void aQMgr_clear_talk_init_ovl(QUEST_MANAGER_ACTOR* manager) { manager->talk_init_proc = NULL; } static int aQMgr_talk_common_talk_init_ovl(QUEST_MANAGER_ACTOR* manager) { static aQMgr_TALK_INIT_PROC talk_init_table[aQMgr_TALK_KIND_NUM] = { &aQMgr_actor_move_talk_init, &aQMgr_talk_first_job_init, &aQMgr_talk_normal_init, &aQMgr_talk_island_init }; int type = manager->talk_type; if (type < 0 || type >= aQMgr_TALK_KIND_NUM) { type = aQMgr_TALK_KIND_QUEST; } manager->talk_init_proc = talk_init_table[type]; return TRUE; } static void aQMgr_actor_change_talk_init_ovl(QUEST_MANAGER_ACTOR* manager) { if (manager->talk_change_type < aQMgr_TALK_KIND_NUM) { manager->talk_type = manager->talk_change_type; if ((*manager->talk_common_proc)(manager, aQMgr_TALK_COMMON_TALK_INIT_OVL) == TRUE) { manager->talk_change_type = aQMgr_TALK_KIND_NUM; manager->sub_talk_state = aQMgr_TALK_SUB_STATE_NO_WAIT; } } } static void aQMgr_actor_clear_regist(aQMgr_regist_c* regist, int count) { for (count; count != 0; count--) { regist->check_limit_proc = (aQMgr_CHECK_LIMIT_PROC)&none_proc1; regist->check_finish_proc = NULL; regist->quest_info = NULL; regist->pid = NULL; mNpc_ClearAnimalPersonalID(®ist->from_id); mNpc_ClearAnimalPersonalID(®ist->to_id); regist->animal_idx = -1; regist++; } } static int aQMgr_actor_check_fin_item(mQst_base_c* quest_info, Animal_c* animal) { mQst_contest_c* contest = (mQst_contest_c*)quest_info; int res = FALSE; if (mPr_GetPossessionItemIdx(Common_Get(now_private), contest->requested_item) != -1) { res = TRUE; } return res; } static int aQMgr_actor_free_regist(QUEST_MANAGER_ACTOR* manager, int start_idx) { aQMgr_regist_c* regist = &manager->regist[start_idx]; int idx = -1; if (manager->regist_use_no < aQMgr_REGIST_NUM) { int i; for (i = start_idx; i < aQMgr_REGIST_NUM; i++) { if (regist->quest_info == NULL) { idx = i; break; } regist++; } } return idx; } static void aQMgr_actor_regist_quest(QUEST_MANAGER_ACTOR* manager, int* idx, aQMgr_quest_c* quest, int animal_idx) { mQst_base_c* quest_info = &quest->base; u32 type = quest_info->quest_type; if (type < mQst_QUEST_TYPE_NUM) { *idx = aQMgr_actor_free_regist(manager, *idx); if (*idx != -1) { int kind = quest_info->quest_kind; int max_kind = l_proc_max[type]; if (kind >= 0 && kind < max_kind) { aQMgr_regist_c* regist = &manager->regist[*idx]; AnmPersonalID_c* from_id; AnmPersonalID_c* to_id; Animal_c* animal; if (type == mQst_QUEST_TYPE_CONTEST) { animal = &Save_Get(animals[animal_idx]); regist->pid = &quest->contest.player_id; regist->check_limit_proc = l_contest_proc[kind]; regist->check_finish_proc = l_contest_check[kind]; from_id = &animal->id; to_id = &animal->id; } else { if (type == mQst_QUEST_TYPE_ERRAND) { regist->check_limit_proc = l_errand_proc[kind]; } from_id = &quest->delivery.sender; to_id = &quest->delivery.recipient; regist->pid = &Common_Get(now_private)->player_ID; } mNpc_CopyAnimalPersonalID(®ist->from_id, from_id); mNpc_CopyAnimalPersonalID(®ist->to_id, to_id); regist->quest_info = quest_info; switch (type) { case mQst_QUEST_TYPE_DELIVERY: regist->item = Common_Get(now_private)->inventory.pockets[animal_idx]; break; case mQst_QUEST_TYPE_ERRAND: regist->item = quest->errand.item; break; case mQst_QUEST_TYPE_CONTEST: regist->item = quest->contest.requested_item; break; } regist->animal_idx = animal_idx; manager->regist_use_no++; } } } } static void aQMgr_talk_clear_talk_order(aQMgr_order_c* demo_order) { demo_order->type = mDemo_TYPE_NONE; demo_order->value = 0; } static int aQMgr_talk_common_clear_talk_info(QUEST_MANAGER_ACTOR* manager) { aQMgr_target_c* target_p = &manager->target; aQMgr_choice_c* choice_p = &manager->choice; int i; *manager->memory = NULL; manager->talk_step = 0; manager->sub_talk_state = aQMgr_TALK_SUB_STATE_WAIT; manager->handover_item = EMPTY_NO; manager->msg_no = 0; manager->category_msg_no_start = 0; manager->msg_category = aQMgr_MSG_KIND_NONE; mQst_ClearQuestInfo(&target_p->quest_info); target_p->from_id = NULL; target_p->to_id = NULL; target_p->quest_inv_item_idx = -1; target_p->quest_item = EMPTY_NO; target_p->reward_kind = -1; target_p->reward_item = EMPTY_NO; target_p->pay = 0; target_p->set_data_p = NULL; target_p->free_data_idx = -1; target_p->free_data_p = NULL; target_p->errand_type = mQst_ERRAND_TYPE_NONE; bzero(&target_p->work, sizeof(target_p->work)); choice_p->choice_num = 0; choice_p->talk_action = -1; for (i = 0; i < mChoice_CHOICE_NUM; i++) { choice_p->choice_ids[i] = -1; } manager->regist_idx = -1; manager->talk_type = aQMgr_TALK_KIND_QUEST; manager->talk_change_type = aQMgr_TALK_KIND_NUM; aQMgr_talk_clear_talk_order(&manager->demo_order); return TRUE; } static int aQMgr_talk_common_get_item_idx(QUEST_MANAGER_ACTOR* manager) { int regist_idx = manager->regist_idx; aQMgr_regist_c* regist = &manager->regist[regist_idx]; mQst_base_c* quest_info = regist->quest_info; int idx = -1; if (quest_info != NULL) { int type = quest_info->quest_type; int kind = quest_info->quest_kind; if (type == mQst_QUEST_TYPE_DELIVERY) { idx = regist->animal_idx; // reused here I guess } else if (type == mQst_QUEST_TYPE_ERRAND) { idx = ((mQst_errand_c*)quest_info)->pockets_idx; } else if (type == mQst_QUEST_TYPE_CONTEST) { mActor_name_t item = ((mQst_contest_c*)quest_info)->requested_item; Private_c* priv = Common_Get(now_private); switch (kind) { case mQst_CONTEST_KIND_FISH: idx = mPr_GetPossessionItemIdxItem1Category(priv, ITEM1_CAT_FISH); break; case mQst_CONTEST_KIND_INSECT: idx = mPr_GetPossessionItemIdxItem1Category(priv, ITEM1_CAT_INSECT); break; default: idx = mPr_GetPossessionItemIdx(priv, item); break; } } } return idx; } static int aQMgr_talk_common_set_choice_str(QUEST_MANAGER_ACTOR* manager) { u8 str[mChoice_CHOICE_NUM][mChoice_CHOICE_STRING_LEN]; u8* str_p_tbl[mChoice_CHOICE_NUM]; aQMgr_choice_c* choice_p = &manager->choice; int i; for (i = 0; i < mChoice_CHOICE_NUM; i++) { str_p_tbl[i] = NULL; } for (i = 0; i < choice_p->choice_num; i++) { if (i >= mChoice_CHOICE_NUM) { break; } mChoice_Load_ChoseStringFromRom(mChoice_Get_base_window_p(), str[i], choice_p->choice_ids[i], NULL); str_p_tbl[i] = str[i]; } //clang-format off mChoice_Set_choice_data( mChoice_Get_base_window_p(), str_p_tbl[0], mChoice_CHOICE_STRING_LEN, str_p_tbl[1], mChoice_CHOICE_STRING_LEN, str_p_tbl[2], mChoice_CHOICE_STRING_LEN, str_p_tbl[3], mChoice_CHOICE_STRING_LEN, NULL, mChoice_CHOICE_STRING_LEN, NULL, mChoice_CHOICE_STRING_LEN ); //clang-format on return TRUE; } static int aQMgr_talk_common_get_set_data_p(QUEST_MANAGER_ACTOR* manager) { aQMgr_target_c* target = &manager->target; mQst_base_c* quest_info = &target->quest_info; aQMgr_set_data_c* set_data_p = NULL; if (quest_info != NULL) { int type = quest_info->quest_type; int kind = quest_info->quest_kind; set_data_p = &l_set_data[type][kind]; } target->set_data_p = set_data_p; return TRUE; } static void aQMgr_actor_init_quest(QUEST_MANAGER_ACTOR* manager) { mQst_delivery_c* delivery = Common_Get(now_private)->deliveries; mQst_errand_c* errand = Common_Get(now_private)->errands; Animal_c* animal = Save_Get(animals); int free_idx = 0; int i; for (i = 0; i < mPr_DELIVERY_QUEST_NUM; i++) { if (free_idx == -1) { break; } aQMgr_actor_regist_quest(manager, &free_idx, (aQMgr_quest_c*)delivery, i); delivery++; } for (i = 0; i < mPr_ERRAND_QUEST_NUM; i++) { if (free_idx == -1) { break; } aQMgr_actor_regist_quest(manager, &free_idx, (aQMgr_quest_c*)errand, i); errand++; } for (i = 0; i < ANIMAL_NUM_MAX; i++) { if (free_idx == -1) { break; } aQMgr_actor_regist_quest(manager, &free_idx, (aQMgr_quest_c*)&animal->contest_quest, i); animal++; } } static void aQMgr_actor_regist_quest_move(QUEST_MANAGER_ACTOR* manager) { aQMgr_regist_c* regist = manager->regist; int i; for (i = aQMgr_REGIST_NUM; i != 0; i--) { if (regist->quest_info != NULL) { if (regist->check_limit_proc != NULL) { (*regist->check_limit_proc)(manager, regist); } } regist++; } } static void aQMgr_actor_move_wait(QUEST_MANAGER_ACTOR* manager) { aQMgr_actor_init_quest(manager); aQMgr_actor_regist_quest_move(manager); (*manager->clear_regist_proc)(manager->regist, aQMgr_REGIST_NUM); manager->regist_idx = -1; manager->regist_use_no = 0; mNpc_TalkInfoMove(); } static void aQMgr_actor_move_talk_fin(QUEST_MANAGER_ACTOR* manager) { aQMgr_actor_init_quest(manager); aQMgr_actor_regist_quest_move(manager); (*manager->clear_regist_proc)(manager->regist, aQMgr_REGIST_NUM); manager->regist_idx = -1; manager->regist_use_no = 0; } static int aQMgr_actor_get_my_msg(int base_msg, int looks) { int msg_no = base_msg + looks * 3; msg_no += mQst_GetRandom(3); return msg_no; } static int aQMgr_actor_decide_quest_message_no(aQMgr_target_c* target, int msg_type) { aQMgr_set_data_c* set_data_p = target->set_data_p; return set_data_p->msg_start[msg_type]; } static int aQMgr_talk_common_set_msg_no(QUEST_MANAGER_ACTOR* manager) { int base_msg; int msg_no; if (manager->msg_category != aQMgr_MSG_KIND_NONE) { manager->category_msg_no_start = aQMgr_actor_decide_quest_message_no(&manager->target, manager->msg_category); } base_msg = manager->category_msg_no_start; if (base_msg != 15 && base_msg != 0) { int looks = mNpc_GetNpcLooks(*manager->client); msg_no = aQMgr_actor_get_my_msg(base_msg, looks); } else { msg_no = base_msg; } manager->msg_no = msg_no; manager->msg_category = aQMgr_MSG_KIND_NONE; manager->category_msg_no_start = 0; return TRUE; } static int aQMgr_talk_common_regist_set_target(QUEST_MANAGER_ACTOR* manager) { aQMgr_target_c* target = &manager->target; aQMgr_regist_c* regist = &manager->regist[manager->regist_idx]; mQst_base_c* quest_info = &target->quest_info; mQst_base_c* src_info = regist->quest_info; quest_info->quest_type = src_info->quest_type; quest_info->quest_kind = src_info->quest_kind; (*manager->talk_common_proc)(manager, aQMgr_TALK_COMMON_GET_SET_DATA); target->quest_item = regist->item; target->to_id = ®ist->to_id; target->from_id = ®ist->from_id; return TRUE; } static int aQMgr_talk_common_change_talk_normal(QUEST_MANAGER_ACTOR* manager) { manager->talk_state = aQMgr_TALK_STATE_INIT; manager->talk_change_type = aQMgr_TALK_KIND_NORMAL; manager->talk_step = 0; manager->choice.talk_action = -1; mMsg_Set_LockContinue(mMsg_Get_base_window_p()); return TRUE; } static int aQMgr_talk_common_change_talk_island(QUEST_MANAGER_ACTOR* manager) { manager->talk_state = aQMgr_TALK_STATE_INIT; manager->talk_change_type = aQMgr_TALK_KIND_ISLAND; manager->talk_step = 0; manager->choice.talk_action = -1; mMsg_Set_LockContinue(mMsg_Get_base_window_p()); return TRUE; } static int aQMgr_set_npc_putaway() { int res = FALSE; if (Common_Get(clip).handOverItem_clip->request_mode == aHOI_REQUEST_TRANS_WAIT) { mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 3, 3); res = TRUE; } return res; } static int aQMgr_talk_common_set_npc_takeout(mActor_name_t item) { mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 3, 2); mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 0, item); mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 1, 7); mDemo_Set_OrderValue(mDemo_ORDER_NPC1, 2, 0); return TRUE; } static int aQMgr_talk_common_set_npc_takeout_item(QUEST_MANAGER_ACTOR* manager) { aQMgr_talk_common_set_npc_takeout(manager->target.quest_item); return TRUE; } static int aQMgr_talk_common_set_npc_takeout_reward(QUEST_MANAGER_ACTOR* manager) { aQMgr_talk_common_set_npc_takeout(manager->target.reward_item); return TRUE; } static int aQMgr_check_npc_hand_item() { int res = FALSE; if (l_aQMgr_hand_start == FALSE && Common_Get(clip).handOverItem_clip->master_actor != NULL) { l_aQMgr_hand_start = TRUE; } if (l_aQMgr_hand_start && Common_Get(clip).handOverItem_clip->master_actor == NULL) { mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); l_aQMgr_hand_start = FALSE; res = TRUE; } return res; } typedef int (*aQMgr_COMMON_PROC)(QUEST_MANAGER_ACTOR*); static int aQMgr_talk_common_proc(QUEST_MANAGER_ACTOR* manager, int proc) { static aQMgr_COMMON_PROC common_proc[aQMgr_TALK_COMMON_NUM] = { &aQMgr_talk_common_regist_set_target, &aQMgr_talk_common_get_item_idx, &aQMgr_talk_common_set_msg_no, &aQMgr_talk_common_clear_talk_info, &aQMgr_talk_common_set_choice_str, &aQMgr_talk_common_get_set_data_p, &aQMgr_talk_common_set_npc_takeout_item, &aQMgr_talk_common_set_npc_takeout_reward, &aQMgr_talk_common_talk_init_ovl, &aQMgr_talk_common_change_talk_normal, &aQMgr_talk_common_change_talk_island }; return (*common_proc[proc])(manager); } #include "../src/ac_quest_errand.c_inc" #include "../src/ac_quest_contest.c_inc" static void aQMgr_clear_talk_wait_info(aQMgr_talk_wait_info_c* wait_info) { bzero(wait_info, sizeof(aQMgr_talk_wait_info_c)); } static int aQMgr_actor_move_talk_sub_no_wait(QUEST_MANAGER_ACTOR* manager) { return TRUE; } static int aQMgr_actor_move_talk_sub_wait(QUEST_MANAGER_ACTOR* manager) { int res = FALSE; if (mMsg_Check_MainNormalContinue(mMsg_Get_base_window_p()) == TRUE) { if (manager->wait_info.flags[2] == FALSE) { manager->wait_info.flags[2] = TRUE; res = TRUE; } } else { manager->wait_info.flags[2] = FALSE; } return res; } static int aQMgr_actor_move_talk_sub_msg_disappear_wait(QUEST_MANAGER_ACTOR* manager) { int res = FALSE; if (mMsg_Check_main_wait(mMsg_Get_base_window_p()) == TRUE) { res = TRUE; } return res; } static int aQMgr_actor_move_talk_sub_msg_appear_wait(QUEST_MANAGER_ACTOR* manager) { int res = FALSE; if (mMsg_Check_not_series_main_wait(mMsg_Get_base_window_p()) == TRUE) { res = TRUE; } return res; } static int aQMgr_actor_move_talk_sub_check_button(QUEST_MANAGER_ACTOR* manager) { int res = FALSE; if (mMsg_Check_MainNormal(mMsg_Get_base_window_p()) == FALSE) { res = TRUE; } return res; } static int aQMgr_actor_move_talk_sub_hand_item_wait(QUEST_MANAGER_ACTOR* manager) { Submenu* submenu = manager->submenu; int res = FALSE; if (submenu->open_flag == FALSE) { manager->handover_item = submenu->item_p->item; res = TRUE; if (manager->mail_memory != NULL) { mNpc_Mail2AnimalMail(&manager->mail_memory->letter, &manager->mail); manager->mail_memory->letter_info.exists = TRUE; } } return res; } static int aQMgr_actor_move_talk_sub_npc_hand_wait(QUEST_MANAGER_ACTOR* manager) { return aQMgr_set_npc_putaway(); } static int aQMgr_actor_move_talk_sub_item_wait(QUEST_MANAGER_ACTOR* manager) { return aQMgr_check_npc_hand_item(); } static int aQMgr_actor_move_talk_sub_demo_order_wait(QUEST_MANAGER_ACTOR* manager) { aQMgr_order_c* order = &manager->demo_order; int res = FALSE; int i; for (i = 0; i < mDemo_ORDER_VALUE_MAX; i++) { u16 value = mDemo_Get_OrderValue(mDemo_ORDER_QUEST, i); if (value != 0) { order->type = i; order->value = value; mDemo_Set_OrderValue(mDemo_ORDER_QUEST, i, 0); res = TRUE; break; } } return res; } static int aQMgr_actor_move_talk_sub_npc_hand_wait_msg_wait(QUEST_MANAGER_ACTOR* manager) { int res = FALSE; if (manager->wait_info.flags[0] == FALSE) { manager->wait_info.flags[0] = aQMgr_set_npc_putaway(); mMsg_Set_LockContinue(mMsg_Get_base_window_p()); } if (manager->wait_info.flags[1] == FALSE) { if (mMsg_Check_MainNormalContinue(mMsg_Get_base_window_p()) == TRUE) { manager->wait_info.flags[1] = TRUE; } } if (manager->wait_info.flags[0] == TRUE && manager->wait_info.flags[1] == TRUE) { manager->wait_info.flags[0] = FALSE; manager->wait_info.flags[1] = FALSE; res = TRUE; } return res; } static int aQMgr_actor_move_talk_sub_item_wait_end(QUEST_MANAGER_ACTOR* manager) { int res = FALSE; if (manager->wait_info.flags[0] == FALSE) { manager->wait_info.flags[0] = aQMgr_set_npc_putaway(); } if (manager->wait_info.flags[0] == TRUE) { manager->wait_info.flags[1] = aQMgr_check_npc_hand_item(); } if (manager->wait_info.flags[0] == TRUE && manager->wait_info.flags[1] == TRUE) { manager->wait_info.flags[0] = FALSE; manager->wait_info.flags[1] = FALSE; res = TRUE; } return res; } static int aQMgr_actor_move_talk_sub_item_player_wait(QUEST_MANAGER_ACTOR* manager) { int res = FALSE; if (manager->wait_info.flags[0] == FALSE) { manager->wait_info.flags[0] = aQMgr_check_npc_hand_item(); } mMsg_Set_LockContinue(mMsg_Get_base_window_p()); if (manager->wait_info.flags[0] == TRUE && mPlib_check_player_actor_main_index_RecieveMove(gamePT) == FALSE) { mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); manager->wait_info.flags[0] = FALSE; res = TRUE; } return res; } static void aQMgr_select_talk(QUEST_MANAGER_ACTOR* manager) { u32 event_id; Animal_c* animal = ((NPC_ACTOR*)*manager->client)->npc_info.animal; event_id = mEv_SAVED_FJOPENQUEST_PLR0 + Common_Get(player_no); aQMgr_actor_init_quest(manager); aQMgr_clear_talk_wait_info(&manager->wait_info); if ((animal != NULL && mNpc_CheckIslandAnimal(animal) == TRUE) || (mLd_PlayerManKindCheck() == FALSE && mEv_CheckEvent(event_id) == TRUE)) { manager->talk_type = aQMgr_TALK_KIND_QUEST; } else if (mEv_CheckFirstJob() == TRUE) { manager->talk_type = aQMgr_TALK_KIND_FIRST_JOB; } else { manager->talk_type = aQMgr_TALK_KIND_QUEST; } *manager->mode = aQMgr_MODE_MOVE_TALK; (*manager->talk_common_proc)(manager, aQMgr_TALK_COMMON_TALK_INIT_OVL); } static int aQMgr_talk_init(QUEST_MANAGER_ACTOR* manager) { int res = FALSE; if (manager->talk_init_proc != NULL) { (*manager->talk_init_proc)(manager); res = TRUE; } return res; } typedef int (*aQMgr_TALK_SUB_PROC)(QUEST_MANAGER_ACTOR*); static int aQMgr_talk_sub(QUEST_MANAGER_ACTOR* manager) { int sub_mode = manager->sub_talk_state; static aQMgr_TALK_SUB_PROC talk_sub_proc[] = { &aQMgr_actor_move_talk_sub_wait, &aQMgr_actor_move_talk_sub_msg_disappear_wait, &aQMgr_actor_move_talk_sub_msg_appear_wait, &aQMgr_actor_move_talk_sub_check_button, &aQMgr_actor_move_talk_sub_hand_item_wait, &aQMgr_actor_move_talk_sub_npc_hand_wait, &aQMgr_actor_move_talk_sub_item_wait, &aQMgr_actor_move_talk_sub_demo_order_wait, &aQMgr_actor_move_talk_sub_no_wait, &aQMgr_actor_move_talk_sub_npc_hand_wait_msg_wait, &aQMgr_actor_move_talk_sub_item_wait_end, &aQMgr_actor_move_talk_sub_item_player_wait }; int res = (*talk_sub_proc[sub_mode])(manager); if (res == TRUE) { manager->talk_state = aQMgr_TALK_STATE_INIT; } return res; } typedef int (*aQMgr_TALK_PROC)(QUEST_MANAGER_ACTOR*); static void aQMgr_move_talk(QUEST_MANAGER_ACTOR* manager) { ACTOR* client = *manager->client; if (mDemo_Get_talk_actor() == client) { static aQMgr_TALK_PROC talk_proc[aQMgr_TALK_STATE_NUM] = { &aQMgr_talk_init, &aQMgr_talk_sub }; int sub_res; aQMgr_actor_change_talk_init_ovl(manager); sub_res = (*talk_proc[aQMgr_TALK_STATE_SUB])(manager); mDemo_Set_OrderValue(mDemo_ORDER_QUEST, 0, 0); if (sub_res == TRUE) { (*talk_proc[aQMgr_TALK_STATE_INIT])(manager); } aQMgr_talk_clear_talk_order(&manager->demo_order); } if (mDemo_CheckDemo() == FALSE || mDemo_Check(mDemo_TYPE_TALK, client) == FALSE) { (*manager->talk_common_proc)(manager, aQMgr_TALK_COMMON_CLEAR_TALK_INFO); *manager->mode = aQMgr_MODE_TALK_FIN; aQMgr_clear_talk_init_ovl(manager); if (client != NULL && client->part == ACTOR_PART_NPC) { Animal_c* animal = ((NPC_ACTOR*)client)->npc_info.animal; if (animal != NULL) { Anmmem_c* memory; int memory_idx = mNpc_GetAnimalMemoryIdx(&Common_Get(now_private)->player_ID, animal->memories, ANIMAL_MEMORY_NUM); if (memory_idx != -1) { memory = animal->memories + memory_idx; lbRTC_TimeCopy(&memory->last_speak_time, Common_GetPointer(time.rtc_time)); if (mNpc_CheckIslandAnimal(animal) == FALSE) { mLd_CopyLandName(memory->memuni.land.name, Save_Get(land_info).name); memory->memuni.land.id = Save_Get(land_info).id; } memory->saved_town_tune = Save_Get(melody); } } } { Animal_c* animal = ((NPC_ACTOR*)*manager->client)->npc_info.animal; int animal_idx = mNpc_SearchAnimalPersonalID(&animal->id); if (mNpc_CheckIslandAnimal(animal) == TRUE) { mNpc_TalkEndMove(mNpc_ISLANDER_NO, animal->id.looks); } else { mNpc_TalkEndMove(animal_idx, animal->id.looks); } } } } static void aQMgr_talk_start_kamakura_common(QUEST_MANAGER_ACTOR* manager, u8 step) { aQMgr_clear_talk_wait_info(&manager->wait_info); *manager->mode = aQMgr_MODE_MOVE_TALK; manager->talk_step = step; manager->talk_type = aQMgr_TALK_KIND_NORMAL; (*manager->talk_common_proc)(manager, aQMgr_TALK_COMMON_TALK_INIT_OVL); aQMgr_talk_init(manager); } static void aQMgr_talk_start_kamakura_hello(QUEST_MANAGER_ACTOR* manager) { aQMgr_talk_start_kamakura_common(manager, 8); } static void aQMgr_talk_start_kamakura(QUEST_MANAGER_ACTOR* manager) { aQMgr_talk_start_kamakura_common(manager, 9); } static void aQMgr_talk_start_summercamp_hello(QUEST_MANAGER_ACTOR* manager) { aQMgr_talk_start_kamakura_common(manager, 10); } static void aQMgr_talk_start_summercamp(QUEST_MANAGER_ACTOR* manager) { aQMgr_talk_start_kamakura_common(manager, 11); } typedef void (*aQMgr_MOVE_PROC)(QUEST_MANAGER_ACTOR*); static void aQMgr_actor_move_main(ACTOR* actorx, GAME* game) { QUEST_MANAGER_ACTOR* manager = (QUEST_MANAGER_ACTOR*)actorx; static aQMgr_MOVE_PROC move_proc[aQMgr_MODE_NUM] = { &aQMgr_actor_move_wait, &aQMgr_select_talk, &aQMgr_move_talk, &aQMgr_actor_move_talk_fin, &aQMgr_talk_start_kamakura_hello, &aQMgr_talk_start_kamakura, &aQMgr_talk_start_summercamp_hello, &aQMgr_talk_start_summercamp }; u8 mode = *manager->mode; if (mEv_CheckTitleDemo() <= 0) { (*move_proc[mode])(manager); } { GRAPH* graph = game->graph; gfxprint_t gfxprint; Gfx* gfx; gfxprint_t* gfxprint_p = &gfxprint; Gfx* gfx_work; if (ZURUMODE2_ENABLED()) { gfxprint_init(gfxprint_p); OPEN_DISP(graph); gfx = NOW_POLY_OPA_DISP; gfx_work = gfxopen(gfx); gSPDisplayList(NEXT_OVERLAY_DISP, gfx_work); gfxprint_open(gfxprint_p, gfx_work); gfxprint_color(gfxprint_p, 245, 50, 50, 255); gfxprint_locate8x8(gfxprint_p, 22, 3); gfxprint_printf(gfxprint_p, "msg no :"); gfxprint_locate8x8(gfxprint_p, 30, 3); gfxprint_printf(gfxprint_p, "%5d", mFRm_get_msg_idx()); { mEv_gst_common_c* ghost_common = (mEv_gst_common_c*)mEv_get_common_area(mEv_EVENT_GHOST, 55); if (ghost_common != NULL) { int i; gfxprint_color(gfxprint_p, 45, 250, 50, 255); for (i = 0; i < mEv_GHOST_HITODAMA_NUM; i++) { gfxprint_locate8x8(gfxprint_p, 30, 19 + i); gfxprint_printf(gfxprint_p, "%3d,%3d", ghost_common->hitodama_block_data.block_x[i], ghost_common->hitodama_block_data.block_z[i]); } } } gfx_work = gfxprint_close(gfxprint_p); gSPEndDisplayList(gfx_work++); gfxclose(gfx, gfx_work); SET_POLY_OPA_DISP(gfx_work); CLOSE_DISP(graph); gfxprint_cleanup(gfxprint_p); } } } static void aQMgr_actor_ct(ACTOR* actorx, GAME* game) { GAME_PLAY* play = (GAME_PLAY*)game; QUEST_MANAGER_ACTOR* manager = (QUEST_MANAGER_ACTOR*)actorx; if (Common_Get(clip).quest_manager_clip == NULL) { Common_Get(clip).quest_manager_clip = (aQMgr_Clip_c*)zelda_malloc(sizeof(aQMgr_Clip_c)); } Common_Get(clip).quest_manager_clip->talk_request_proc = &aQMgr_actor_talk_request; Common_Get(clip).quest_manager_clip->talk_start_proc = &aQMgr_actor_talk_start; Common_Get(clip).quest_manager_clip->talk_check_proc = &aQMgr_actor_talk_check; l_client_p = NULL; l_quest_manager_mode = aQMgr_MODE_NORMAL; l_quest_memory_p = NULL; l_quest_actor_p = NULL; l_quest_manager_hello = FALSE; manager->client = &l_client_p; manager->memory = &l_quest_memory_p; manager->submenu = &play->submenu; manager->mode = &l_quest_manager_mode; manager->talk_state = aQMgr_TALK_STATE_INIT; manager->sub_talk_state = aQMgr_TALK_SUB_STATE_WAIT; aQMgr_talk_common_clear_talk_info(manager); aQMgr_actor_clear_regist(manager->regist, aQMgr_REGIST_NUM); manager->regist_idx = -1; manager->regist_use_no = 0; aQMgr_actor_init_quest(manager); manager->talk_common_proc = &aQMgr_talk_common_proc; manager->clear_regist_proc = &aQMgr_actor_clear_regist; manager->regist_quest_proc = &aQMgr_actor_regist_quest; manager->get_time_kind_proc = &aQMgr_get_time_kind; bzero(manager->errand_next, sizeof(manager->errand_next)); manager->clip = NULL; aQMgr_clear_talk_init_ovl(manager); aQMgr_clear_talk_wait_info(&manager->wait_info); l_aQMgr_hand_start = FALSE; l_quest_actor_p = (QUEST_MANAGER_ACTOR*)actorx; // l_quest_actor_p is probably just ACTOR* mem_clear(manager->last_strings, 7, 0xFF); manager->give_item = EMPTY_NO; } static void aQMgr_actor_dt(ACTOR* actorx, GAME* game) { QUEST_MANAGER_ACTOR* manager = (QUEST_MANAGER_ACTOR*)actorx; if (Common_Get(clip).quest_manager_clip != NULL) { zelda_free(Common_Get(clip).quest_manager_clip); Common_Get(clip).quest_manager_clip = NULL; } if (manager->clip != NULL) { zelda_free(manager->clip); } } typedef void (*aQMgr_SAVE_PROC)(aQMgr_regist_c*); static void aQMgr_actor_save(ACTOR* actorx, GAME* game) { QUEST_MANAGER_ACTOR* manager = (QUEST_MANAGER_ACTOR*)actorx; aQMgr_regist_c* regist = manager->regist; static aQMgr_SAVE_PROC save_proc[mQst_QUEST_TYPE_NUM] = { (aQMgr_SAVE_PROC)&none_proc1, (aQMgr_SAVE_PROC)&none_proc1, &aQMgr_save_contest }; int i; aQMgr_actor_init_quest(manager); for (i = 0; i < aQMgr_REGIST_NUM; i++) { if (regist->quest_info != NULL) { int type = regist->quest_info->quest_type; if (type >= 0 && type < mQst_QUEST_TYPE_NUM) { (*save_proc[type])(regist); } } regist++; } } ACTOR_PROFILE Quest_Manager_Profile = { mAc_PROFILE_QUEST_MANAGER, ACTOR_PART_CONTROL, ACTOR_STATE_CAN_MOVE_IN_DEMO_SCENES | ACTOR_STATE_NO_DRAW_WHILE_CULLED | ACTOR_STATE_NO_MOVE_WHILE_CULLED, EMPTY_NO, ACTOR_OBJ_BANK_KEEP, sizeof(QUEST_MANAGER_ACTOR), &aQMgr_actor_ct, &aQMgr_actor_dt, &aQMgr_actor_move_main, mActor_NONE_PROC1, &aQMgr_actor_save };