From f53d79505915fbdcce2a8d8f64c50eaa2bd9ec11 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Fri, 5 Jan 2024 02:47:48 -0500 Subject: [PATCH] Implement & link ac_boat_demo --- config/assets.yml | 5 + config/rel_slices.yml | 7 +- include/ac_boat.h | 7 + include/ac_boat_demo.h | 67 ++++++ include/ac_npc.h | 2 +- include/ac_npc_sendo.h | 8 + include/ac_weather.h | 2 + include/m_event.h | 4 +- include/m_island.h | 8 +- include/m_msg.h | 2 + include/m_name_table.h | 2 +- src/ac_boat_demo.c | 70 ++++++ src/ac_boat_demo_move.c_inc | 433 ++++++++++++++++++++++++++++++++++++ src/ac_ev_castaway.c | 2 +- src/ac_weather.c | 4 +- src/m_island.c | 8 +- src/m_start_data_init.c | 4 +- 17 files changed, 617 insertions(+), 18 deletions(-) create mode 100644 src/ac_boat_demo.c create mode 100644 src/ac_boat_demo_move.c_inc diff --git a/config/assets.yml b/config/assets.yml index cc8d6a49..22b3210f 100644 --- a/config/assets.yml +++ b/config/assets.yml @@ -147,6 +147,11 @@ config/rel.yml: con_sentaku2_v: addrs: [0x80650880, 0x806508C0] type: vtx + # ac_boat_demo + aBTD_island_prg: + addrs: [0x8065FD4C, 0x80674F90] + aBTD_island_ldr: + addrs: [0x80674F90, 0x806817CC] wipe1_v: addrs: [0x80652AD0, 0x80652C60] type: vtx diff --git a/config/rel_slices.yml b/config/rel_slices.yml index d7385f58..898614d7 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -383,8 +383,13 @@ ac_animal_logo.c: .data: [0x8065FB68, 0x8065FBA8] ac_animal_logo_misc.c: .text: [0x804117D4, 0x80411A60] +ac_boat_demo.c: + .text: [0x80414EC4, 0x80415BD8] + .rodata: [0x80643B98, 0x80643BA0] + .data: [0x8065FD28, 0x806818A0] + .bss: [0x812F96E8, 0x812F96F0] ac_boxManager.c: - .text: [0x80415BD8,0x80415BE8] + .text: [0x80415BD8, 0x80415BE8] .data: [0x806818A0, 0x806818C8] ac_boxMove.c: .text: [0x80415BE8, 0x80415BF8] diff --git a/include/ac_boat.h b/include/ac_boat.h index 9912d121..485f638a 100644 --- a/include/ac_boat.h +++ b/include/ac_boat.h @@ -8,6 +8,13 @@ extern "C" { #endif +typedef struct boat_s BOAT_ACTOR; + +struct boat_s { + ACTOR actor_class; + // TODO +}; + extern ACTOR_PROFILE Boat_Profile; #ifdef __cplusplus diff --git a/include/ac_boat_demo.h b/include/ac_boat_demo.h index 55700d5f..f7bee4e5 100644 --- a/include/ac_boat_demo.h +++ b/include/ac_boat_demo.h @@ -3,11 +3,78 @@ #include "types.h" #include "m_actor.h" +#include "m_demo.h" +#include "ac_boat.h" +#include "ac_npc_sendo.h" +#include "ac_ev_castaway.h" +#include "m_common_data.h" #ifdef __cplusplus extern "C" { #endif +enum { + aBTD_ACTION_SENDO_BIRTH_WAIT, + aBTD_ACTION_PL_RIDE_ON_START_WAIT, + aBTD_ACTION_PL_RIDE_ON_END_WAIT, + aBTD_ACTION_START_CALL_END_WAIT, + aBTD_ACTION_SONG_BGM_START_WAIT, + aBTD_ACTION_SING_SENDO_START_WAIT, + aBTD_ACTION_SING_SENDO_MSG_SET_WAIT, + aBTD_ACTION_SENDO_DIALOGUE_START_WAIT, + aBTD_ACTION_SING_SENDO_START_WAIT2, + aBTD_ACTION_MOVE_BOAT_END_WAIT, + aBTD_ACTION_TOUCH_WHARF_END_WAIT, + aBTD_ACTION_PL_RIDE_OFF_START_WAIT, + aBTD_ACTION_PL_RIDE_OFF_END_WAIT, + aBTD_ACTION_ANCHOR_WAIT, + + aBTD_ACTION_NUM +}; + +enum { + aBTD_DEMO_PL_RIDE_ON_START, + aBTD_DEMO_PL_RIDE_ON_END, + aBTD_DEMO_START_CALL_END, + aBTD_DEMO_MOVE_BOAT_END, + aBTD_DEMO_TOUCH_WHARF_END, + aBTD_DEMO_PL_RIDE_OFF_START, + aBTD_DEMO_PL_RIDE_OFF_END, + aBTD_DEMO_ANCHOR, + + aBTD_DEMO_NUM +}; + +typedef struct boat_demo_s BOAT_DEMO_ACTOR; + +#define aBTD_GET_DEMO_ACTOR() (BOAT_DEMO_ACTOR*)(Common_Get(clip).demo_clip2->class) + +typedef void (*aBTD_PROC)(BOAT_DEMO_ACTOR*, GAME_PLAY*); + +struct boat_demo_s { + ACTOR actor_class; + int action; + aBTD_PROC action_proc; + int demo_act; + int song_bgm_timer; + BOAT_ACTOR* boat_actor; + NPC_SENDO_ACTOR* npc_sendo_actor; + EV_CASTAWAY_ACTOR* castaway_actor; + int at_island; + xyz_t passenger_ofs; + f32 boat_speed; + int island_npc_info_registered; + u8* island_gba_loader_p; + u8* island_gba_program_p; + u8 player_pattern; + u8 sing_dialog_ofs; + u8 sing_2nd_part; + u8 sing_2nd_part_bgm_no; + int sing_msg_no; + u16 touch_wharf_timer; + u8 touching_wharf; +}; + extern ACTOR_PROFILE Boat_Demo_Profile; #ifdef __cplusplus diff --git a/include/ac_npc.h b/include/ac_npc.h index 9cb57488..6ac75726 100644 --- a/include/ac_npc.h +++ b/include/ac_npc.h @@ -16,7 +16,7 @@ extern "C" { #define aNPC_SPNPC_BIT_CURATOR 0 #define aNPC_SPNPC_BIT_GOHOME_NPC 1 #define aNPC_SPNPC_BIT_MASK_CAT 2 -#define aNPC_SPNPC_BIT_CASTAWAY 4 +#define aNPC_SPNPC_BIT_DOZAEMON 4 #define aNPC_SPNPC_BIT_EV_SONCHO 5 #define aNPC_SPNPC_BIT_GET(field, bit) (((field) >> (bit)) & 1) diff --git a/include/ac_npc_sendo.h b/include/ac_npc_sendo.h index 01bd45b0..e6aa4ce4 100644 --- a/include/ac_npc_sendo.h +++ b/include/ac_npc_sendo.h @@ -3,11 +3,19 @@ #include "types.h" #include "m_actor.h" +#include "ac_npc.h" #ifdef __cplusplus extern "C" { #endif +typedef struct npc_sendo_s NPC_SENDO_ACTOR; + +struct npc_sendo_s { + NPC_ACTOR npc_class; + // TODO +}; + extern ACTOR_PROFILE Npc_Sendo_Profile; #ifdef __cplusplus diff --git a/include/ac_weather.h b/include/ac_weather.h index 5f11a135..7774e372 100644 --- a/include/ac_weather.h +++ b/include/ac_weather.h @@ -9,6 +9,8 @@ extern "C" { #endif extern int aWeather_ChangingWeather(); +extern void aWeather_RequestChangeWeatherToIsland(); +extern void aWeather_RequestChangeWeatherFromIsland(); extern ACTOR_PROFILE Weather_Profile; diff --git a/include/m_event.h b/include/m_event.h index 4adf8c8f..8e7c8bfb 100644 --- a/include/m_event.h +++ b/include/m_event.h @@ -377,7 +377,7 @@ typedef struct kabu_peddler_event_s { } mEv_kabu_peddler_c; typedef struct dozaemon_event_s { - u32 flags; + u16 flags; } mEv_dozaemon_c; typedef union { @@ -552,7 +552,7 @@ typedef struct event_common_save_data { } bridge_flags; u8 ghost_event_type; // 0x72 will spawn wisp, 0x77 won't? u8 soncho_event_type; // checked not equal to 0xFF for summer & fall fishing tournies - u8 current_event_state; // used to signal when you've received an item from gracie or woken gulliver up + u8 dozaemon_completed; // used to signal when you've received an item from gulliver } mEv_save_common_data_c; extern int mEv_CheckFirstJob(); diff --git a/include/m_island.h b/include/m_island.h index 3eddea0a..15e81e7f 100644 --- a/include/m_island.h +++ b/include/m_island.h @@ -44,8 +44,8 @@ typedef struct island_s { /* 0x18CA */ lbRTC_time_c renew_time; /* last time island was visited? */ /* 0x18D2 */ u8 unused_18D2[14]; /* unused */ /* 0x18E0 */ u8 grass_tex_type; /* grass type */ - /* 0x18E1 */ u8 last_song_male; /* last song kapp'n sang for a male character */ - /* 0x18E2 */ u8 last_song_female; /* last song kapp'n sang for a female character */ + /* 0x18E1 */ u8 last_song_to_island; /* last song kapp'n sang to the island */ + /* 0x18E2 */ u8 last_song_from_island; /* last song kapp'n sang leaving the island */ /* 0x18E3 */ u8 unused_18E3[29]; /* unused */ } Island_c; @@ -180,8 +180,8 @@ typedef struct island_agb_s { /* 0x3948 */ u16 npc_pal[16]; /* 0x3968 */ u8 _3968[20]; /* 0x397C */ u8 _397C; - /* 0x397D */ u8 last_song_male; /* last song kapp'n sang for a male character */ - /* 0x397E */ u8 last_song_female; /* last song kapp'n sang for a female character */ + /* 0x397D */ u8 last_song_to_island; /* last song kapp'n sang for a male character */ + /* 0x397E */ u8 last_song_from_island; /* last song kapp'n sang for a female character */ /* 0x397F */ u8 checksum; } Island_agb_c; diff --git a/include/m_msg.h b/include/m_msg.h index 9a42c3b1..53484f3b 100644 --- a/include/m_msg.h +++ b/include/m_msg.h @@ -286,6 +286,8 @@ extern int mMsg_CopyItem(mMsg_Window_c* msg_win, int item_idx, u8* data, int idx extern int mMsg_CopyMail(mMsg_Window_c* msg_win, int mail_idx, u8* data, int idx, int max_size); extern int mMsg_CopyIslandName(u8* data, int idx, int max_size, int capitalize); extern int mMsg_CopyAmPm(mMsg_Window_c* msg_win, u8* data, int idx, int max_size); +extern void mMsg_sound_set_voice_silent(mMsg_Window_c* msg_win, int update_voice_mode); +extern void mMsg_sound_unset_voice_silent(mMsg_Window_c* msg_win, int update_voice_mode); #ifdef __cplusplus } diff --git a/include/m_name_table.h b/include/m_name_table.h index aa57ad80..69db556a 100644 --- a/include/m_name_table.h +++ b/include/m_name_table.h @@ -1858,7 +1858,7 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define SP_NPC_SONCHO_D078 (SP_NPC_START + 120) // D078 #define SP_NPC_SONCHO_D079 (SP_NPC_START + 121) // D079 #define SP_NPC_SASHO (SP_NPC_START + 122) // D07A -// +#define SP_NPC_CASTAWAY (SP_NPC_START + 123) // D07B #define SP_NPC_MAJIN_D07C (SP_NPC_START + 124) // D07C #define SP_NPC_MAJIN_D07D (SP_NPC_START + 125) // D07D #define SP_NPC_MAJIN_BROTHER (SP_NPC_START + 126) // D07E diff --git a/src/ac_boat_demo.c b/src/ac_boat_demo.c new file mode 100644 index 00000000..d3675274 --- /dev/null +++ b/src/ac_boat_demo.c @@ -0,0 +1,70 @@ +#include "ac_boat_demo.h" + +#include "libultra/libultra.h" +#include "ac_weather.h" +#include "m_bg_item.h" +#include "m_bgm.h" +#include "m_msg.h" + +/* For whatever reason, this file seems to have -pool off */ +#pragma push +#pragma pool_data off + +static void aBTD_actor_ct(ACTOR* actorx, GAME* game); +static void aBTD_actor_dt(ACTOR* actorx, GAME* game); +static void aBTD_actor_move(ACTOR* actorx, GAME* game); + +ACTOR_PROFILE Boat_Demo_Profile = { + mAc_PROFILE_BOAT_DEMO, + ACTOR_PART_CONTROL, + ACTOR_STATE_CAN_MOVE_IN_DEMO_SCENES | ACTOR_STATE_NO_MOVE_WHILE_CULLED, + EMPTY_NO, + ACTOR_OBJ_BANK_KEEP, + sizeof(BOAT_DEMO_ACTOR), + &aBTD_actor_ct, + &aBTD_actor_dt, + &aBTD_actor_move, + mActor_NONE_PROC1, + NULL +}; + +static mDemo_Clip_c aBTD_clip; + +static u8 aBTD_island_prg[] = { +#include "assets/aBTD_island_prg.inc" +}; + +static u8 aBTD_island_ldr[] = { +#include "assets/aBTD_island_ldr.inc" +}; + +static void aBTD_setupAction(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play, int action); + +static void aBTD_actor_ct(ACTOR* actorx, GAME* game) { + BOAT_DEMO_ACTOR* boat_demo = (BOAT_DEMO_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + + Common_Get(clip).demo_clip2 = &aBTD_clip; + bzero(&aBTD_clip, sizeof(aBTD_clip)); + Common_Get(clip).demo_clip2->class = boat_demo; + Common_Get(clip).demo_clip2->type = mDemo_CLIP_TYPE_BOAT_DEMO; + boat_demo->island_gba_loader_p = aBTD_island_ldr; + boat_demo->island_gba_program_p = aBTD_island_prg; + + if (mFI_CheckBlockKind(play->block_table.block_x, play->block_table.block_z, mRF_BLOCKKIND_ISLAND) == TRUE) { + boat_demo->at_island = TRUE; + boat_demo->island_npc_info_registered = TRUE; + } + + aBTD_setupAction(boat_demo, play, aBTD_ACTION_SENDO_BIRTH_WAIT); +} + +static void aBTD_actor_dt(ACTOR* actorx, GAME* game) { + if (Common_Get(clip).demo_clip2 != NULL) { + Common_Get(clip).demo_clip2 = NULL; + } +} + +#include "../src/ac_boat_demo_move.c_inc" + +#pragma pop diff --git a/src/ac_boat_demo_move.c_inc b/src/ac_boat_demo_move.c_inc new file mode 100644 index 00000000..715c505a --- /dev/null +++ b/src/ac_boat_demo_move.c_inc @@ -0,0 +1,433 @@ +static int aBTD_check_sendo_and_boat(BOAT_DEMO_ACTOR* boat_demo) { + int res = TRUE; + + if (boat_demo->npc_sendo_actor == NULL) { + if (boat_demo->boat_actor != NULL) { + Actor_delete((ACTOR*)boat_demo->boat_actor); + } + + res = FALSE; + } + + if (boat_demo->boat_actor == NULL) { + if (boat_demo->npc_sendo_actor != NULL) { + Actor_delete((ACTOR*)boat_demo->npc_sendo_actor); + } + + res = FALSE; + } + + return res; +} + +static int aBTD_regist_island_npc_info() { + Island_c* island = Save_GetPointer(island); + Animal_c* animal = &island->animal; + mNpc_NpcList_c* npclist = Common_Get(island_npclist); + int res; + + mNpc_SetNpcList(npclist, animal, mISL_ISLANDER_NUM, TRUE); + + res = mFI_RegistMoveActorList( + npclist->name, + animal->home_info.block_x, animal->home_info.block_z, + animal->home_info.ut_x, animal->home_info.ut_z, + -ANIMAL_NUM_MAX, + 0 + ); + + if (res == TRUE) { + mNPS_set_island_schedule_area(&animal->id); + } + + return res; +} + +static int aBTD_unregist_island_npc_info() { + mNpc_NpcList_c* npclist = Common_Get(island_npclist); + Island_c* island = Save_GetPointer(island); + Animal_c* animal = &island->animal; + int res = mFI_UnregistMoveActorList( + npclist->name, + animal->home_info.block_x, + animal->home_info.block_z + ); + + if (res == TRUE) { + mNPS_reset_schedule_area(&Save_Get(island).animal.id); + mNpc_InitNpcList(npclist, mISL_ISLANDER_NUM); + } + + return res; +} + +static void aBTD_chg_regist_island_npc_info(BOAT_DEMO_ACTOR* boat_demo) { + if (boat_demo->at_island == FALSE) { + if (boat_demo->island_npc_info_registered == FALSE && aBTD_regist_island_npc_info() == TRUE) { + boat_demo->island_npc_info_registered = TRUE; + } + } + else { + if (boat_demo->island_npc_info_registered == TRUE && aBTD_unregist_island_npc_info() == TRUE) { + boat_demo->island_npc_info_registered = FALSE; + } + } +} + +static void aBTD_setup_castaway(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + if (boat_demo->action > aBTD_ACTION_PL_RIDE_ON_START_WAIT && boat_demo->action != aBTD_ACTION_ANCHOR_WAIT) { + if (mEv_check_status(mEv_EVENT_DOZAEMON, mEv_STATUS_RUN) && (Common_Get(spnpc_first_talk_flags) & (1 << aNPC_SPNPC_BIT_DOZAEMON)) == 0) { + mEv_dozaemon_c* dozaemon_ev = (mEv_dozaemon_c*)mEv_reserve_save_area(mEv_EVENT_DOZAEMON, 13); // Shouldn't this be mEv_get_save_area? + + if ( + (dozaemon_ev == NULL || (dozaemon_ev->flags & 1) == 0) && + Save_Get(event_save_common).dozaemon_completed != TRUE && + boat_demo->castaway_actor == NULL + ) { + int setupActor = (*Common_Get(clip).npc_clip->setupActor_proc)(play, SP_NPC_CASTAWAY, -1, -1, -1, -1 , -1, 0, 0); + + if (setupActor == TRUE) { + EV_CASTAWAY_ACTOR* castaway = (EV_CASTAWAY_ACTOR*)Actor_info_fgName_search(&play->actor_info, SP_NPC_CASTAWAY, ACTOR_PART_NPC); + + if (castaway != NULL) { + boat_demo->castaway_actor = castaway; + } + } + } + } + } +} + +static void aBTD_change_season(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + if (boat_demo->at_island == TRUE) { + mFI_SetClimate(mFI_CLIMATE_0); + mFM_returnSeason(); + aWeather_RequestChangeWeatherFromIsland(); + mNpc_ClearIslandPresentFtrInfo(); + mNpc_SetIslandGetLetter(FALSE); + mNpc_SetIslandCheckFtrMsg(FALSE); + } + else { + mFI_SetClimate(mFI_CLIMATE_ISLAND); + mFM_toSummer(); + aWeather_RequestChangeWeatherToIsland(); + mISL_ChangeBG(); + mRmTp_DecideCottageDefaultLightSwitch(); + mSP_SelectRandomItemToAGB(); + mISL_ClearNowPlayerAction(); + mNpc_SetIslandPresentFtr(); + mNpc_SetIslandRoomFtr(&Save_Get(island).animal); + mNpc_SetIslandGetLetter(FALSE); + mNpc_SetIslandCheckFtrMsg(FALSE); + } + + mBI_change_bg_item(play); +} + +static void aBTD_sendo_birth_wait(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + if (Common_Get(clip).npc_clip != NULL && Common_Get(clip).npc_clip->setupActor_proc != NULL) { + int sendo_birth = (*Common_Get(clip).npc_clip->setupActor_proc)(play, SP_NPC_SENDO, -1, -1, -1, -1, -1, 0, 0); + + if (sendo_birth == TRUE) { + NPC_SENDO_ACTOR* sendo_actor = (NPC_SENDO_ACTOR*)Actor_info_fgName_search(&play->actor_info, SP_NPC_SENDO, ACTOR_PART_NPC); + + if (sendo_actor != NULL) { + BOAT_ACTOR* boat_actor = (BOAT_ACTOR*)Actor_info_fgName_search(&play->actor_info, BOAT, ACTOR_PART_ITEM); + + boat_demo->npc_sendo_actor = sendo_actor; + boat_demo->boat_actor = boat_actor; + + sendo_actor->npc_class.actor_class.parent_actor = (ACTOR*)boat_demo; + boat_actor->actor_class.parent_actor = (ACTOR*)boat_demo; + + aBTD_setupAction(boat_demo, play, aBTD_ACTION_PL_RIDE_ON_START_WAIT); + } + } + } +} + +static void aBTD_pl_ride_on_start_wait(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + if (aBTD_check_sendo_and_boat(boat_demo) == FALSE) { + Actor_delete((ACTOR*)boat_demo); + } + else if (boat_demo->demo_act == aBTD_DEMO_PL_RIDE_ON_END) { + aBTD_setupAction(boat_demo, play, aBTD_ACTION_PL_RIDE_ON_END_WAIT); + } +} + +static void aBTD_pl_ride_on_end_wait(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + if (boat_demo->demo_act == aBTD_DEMO_START_CALL_END) { + aBTD_setupAction(boat_demo, play, aBTD_ACTION_START_CALL_END_WAIT); + } +} + +static void aBTD_start_call_end_wait(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + if (boat_demo->demo_act == aBTD_DEMO_MOVE_BOAT_END) { + aBTD_setupAction(boat_demo, play, aBTD_ACTION_SONG_BGM_START_WAIT); + } +} + +static void aBTD_song_bgm_start_wait(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + boat_demo->song_bgm_timer--; + + if (boat_demo->song_bgm_timer <= 0) { + aBTD_setupAction(boat_demo, play, aBTD_ACTION_SING_SENDO_START_WAIT); + } +} + +static void aBTD_sing_sendo_start_wait(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + boat_demo->song_bgm_timer--; + + if (boat_demo->song_bgm_timer <= 0) { + aBTD_setupAction(boat_demo, play, aBTD_ACTION_SING_SENDO_MSG_SET_WAIT); + } +} + +static void aBTD_sing_sendo_msg_set_wait(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + int msg_no = mMsg_Get_msg_num(mMsg_Get_base_window_p()); + + if (msg_no == boat_demo->sing_msg_no) { + aBTD_setupAction(boat_demo, play, aBTD_ACTION_SENDO_DIALOGUE_START_WAIT); + } +} + +static void aBTD_sendo_dialogue_start_wait(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + int msg_no = mMsg_Get_msg_num(mMsg_Get_base_window_p()); + + if (msg_no == boat_demo->sing_msg_no) { + aBTD_setupAction(boat_demo, play, aBTD_ACTION_SING_SENDO_START_WAIT2); + } +} + +static void aBTD_sing_sendo_start_wait2(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + int msg_no = mMsg_Get_msg_num(mMsg_Get_base_window_p()); + + if (msg_no == boat_demo->sing_msg_no) { + aBTD_setupAction(boat_demo, play, aBTD_ACTION_MOVE_BOAT_END_WAIT); + } + + aBTD_chg_regist_island_npc_info(boat_demo); +} + +static void aBTD_move_boat_end_wait(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + if (boat_demo->demo_act == aBTD_DEMO_TOUCH_WHARF_END) { + aBTD_setupAction(boat_demo, play, aBTD_ACTION_TOUCH_WHARF_END_WAIT); + } +} + +static void aBTD_touch_wharf_end_wait(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + if (boat_demo->touching_wharf == FALSE) { + boat_demo->touch_wharf_timer--; + + if (boat_demo->touch_wharf_timer <= 0) { + sAdo_OngenTrgStart(0x165, &boat_demo->boat_actor->actor_class.world.position); + boat_demo->touching_wharf = TRUE; + } + } + + if (boat_demo->demo_act == aBTD_DEMO_PL_RIDE_OFF_START) { + aBTD_setupAction(boat_demo, play, aBTD_ACTION_PL_RIDE_OFF_START_WAIT); + } +} + +static void aBTD_pl_ride_off_start_wait(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + if (boat_demo->demo_act == aBTD_DEMO_PL_RIDE_OFF_END) { + aBTD_setupAction(boat_demo, play, aBTD_ACTION_PL_RIDE_OFF_END_WAIT); + } +} + +static void aBTD_pl_ride_off_end_wait(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + if (boat_demo->demo_act == aBTD_DEMO_ANCHOR) { + aBTD_setupAction(boat_demo, play, aBTD_ACTION_ANCHOR_WAIT); + } +} + +static void aBTD_anchor(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + if (aBTD_check_sendo_and_boat(boat_demo) == FALSE) { + Actor_delete((ACTOR*)boat_demo); + } +} + +typedef void (*aBTD_INIT_PROC)(BOAT_DEMO_ACTOR*, GAME_PLAY*); + +static void aBTD_start_call_end_wait_init(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + mBGMPsComp_make_ps_quietField(0x168); +} + +static void aBTD_song_bgm_start_wait_init(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + boat_demo->song_bgm_timer = 0; +} + +static void aBTD_sing_sendo_start_wait_init(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + static int player_pattern_table[2][2] = { + { 0, 1 }, + { 2, 3 } + }; + + static u8 sing_1st_part_bgm_no[4][5] = { + { 0x5C, 0x5D, 0x5E, 0x5F, 0x60 }, + { 0x66, 0x67, 0x68, 0x69, 0x6A }, + { 0x61, 0x62, 0x63, 0x64, 0x65 }, + { 0x6B, 0x6C, 0x6D, 0x6E, 0x6F } + }; + + static int sing_1st_part_msg_base_no[4] = { + 0x3091, + 0x3163, + 0x3096, + 0x3168 + }; + + int at_island = boat_demo->at_island; + int gender = Common_Get(now_private)->gender; + int kappn_song; + int player_pattern; + + do { + kappn_song = RANDOM(5); + if (!at_island) { + if (kappn_song != Save_Get(island).last_song_to_island) { + Save_Get(island).last_song_to_island = kappn_song; + break; + } + } + else { + if (kappn_song != Save_Get(island).last_song_from_island) { + Save_Get(island).last_song_from_island = kappn_song; + break; + } + } + } while (TRUE); + + player_pattern = player_pattern_table[at_island][gender]; + boat_demo->player_pattern = player_pattern; + mBGMPsComp_make_ps_lost_fanfare(sing_1st_part_bgm_no[player_pattern][kappn_song], 0x168); + boat_demo->sing_msg_no = sing_1st_part_msg_base_no[player_pattern] + kappn_song; + boat_demo->sing_dialog_ofs = RANDOM(10); + boat_demo->sing_2nd_part = RANDOM(10); + boat_demo->song_bgm_timer = 930; +} + +static void aBTD_sendo_dialogue_start_wait_init(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + static int sing_dialogue_msg_base_no[4] = { + 0x309B, + 0x316D, + 0x30A5, + 0x3177 + }; + + int msg_no = sing_dialogue_msg_base_no[boat_demo->player_pattern] + boat_demo->sing_dialog_ofs; + + mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), msg_no); + boat_demo->sing_msg_no = msg_no; + mMsg_sound_set_voice_silent(mMsg_Get_base_window_p(), TRUE); + aBTD_change_season(boat_demo, play); +} + +static void aBTD_sing_sendo_start_wait2_init(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + static u8 sing_2nd_part_bgm_no[10] = { + 0x70, 0x71, 0x72, 0x73, 0x74, + 0x75, 0x76, 0x77, 0x78, 0x79 + }; + + static int sing_2nd_part_msg_base_no[4] = { + 0x30AF, + 0x3181, + 0x30AF, + 0x3181 + }; + + int song_no; + int msg_no; + + + mMsg_sound_unset_voice_silent(mMsg_Get_base_window_p(), TRUE); + + song_no = sing_2nd_part_bgm_no[boat_demo->sing_2nd_part]; + mBGMPsComp_make_ps_demo(song_no, 0x168); + boat_demo->sing_2nd_part_bgm_no = song_no; + + msg_no = sing_2nd_part_msg_base_no[boat_demo->player_pattern] + boat_demo->sing_2nd_part; + mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), msg_no); + boat_demo->sing_msg_no = msg_no; +} + +static void aBTD_move_boat_end_wait_init(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + mMsg_sound_set_voice_silent(mMsg_Get_base_window_p(), TRUE); +} + +static void aBTD_touch_wharf_end_wait_init(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + boat_demo->touching_wharf = FALSE; + boat_demo->touch_wharf_timer = 190; +} + +static void aBTD_pl_ride_off_start_wait_init(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + mBGMPsComp_delete_ps_demo(boat_demo->sing_2nd_part_bgm_no, 0x168); +} + +static void aBTD_anchor_init(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play) { + mBGMPsComp_delete_ps_quietField(); + + if (boat_demo->castaway_actor != NULL) { + Actor_delete((ACTOR*)boat_demo->castaway_actor); + } +} + +static void aBTD_init_proc(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play, int action) { + static aBTD_INIT_PROC init_proc[aBTD_ACTION_NUM] = { + (aBTD_INIT_PROC)&none_proc1, + (aBTD_INIT_PROC)&none_proc1, + (aBTD_INIT_PROC)&none_proc1, + &aBTD_start_call_end_wait_init, + &aBTD_song_bgm_start_wait_init, + &aBTD_sing_sendo_start_wait_init, + (aBTD_INIT_PROC)&none_proc1, + &aBTD_sendo_dialogue_start_wait_init, + &aBTD_sing_sendo_start_wait2_init, + &aBTD_move_boat_end_wait_init, + &aBTD_touch_wharf_end_wait_init, + &aBTD_pl_ride_off_start_wait_init, + (aBTD_INIT_PROC)&none_proc1, + &aBTD_anchor_init + }; + + (*init_proc[action])(boat_demo, play); +} + +static void aBTD_setupAction(BOAT_DEMO_ACTOR* boat_demo, GAME_PLAY* play, int action) { + static aBTD_PROC process[aBTD_ACTION_NUM] = { + &aBTD_sendo_birth_wait, + &aBTD_pl_ride_on_start_wait, + &aBTD_pl_ride_on_end_wait, + &aBTD_start_call_end_wait, + &aBTD_song_bgm_start_wait, + &aBTD_sing_sendo_start_wait, + &aBTD_sing_sendo_msg_set_wait, + &aBTD_sendo_dialogue_start_wait, + &aBTD_sing_sendo_start_wait2, + &aBTD_move_boat_end_wait, + &aBTD_touch_wharf_end_wait, + &aBTD_pl_ride_off_start_wait, + &aBTD_pl_ride_off_end_wait, + &aBTD_anchor + }; + + boat_demo->action_proc = process[action]; + boat_demo->action = action; + aBTD_init_proc(boat_demo, play, action); +} + +static void aBTD_actor_move(ACTOR* actorx, GAME* game) { + BOAT_DEMO_ACTOR* boat_demo = (BOAT_DEMO_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + BOAT_ACTOR* boat_actor = boat_demo->boat_actor; + + if (boat_actor != NULL) { + actorx->shape_info.rotation.x = boat_actor->actor_class.shape_info.rotation.x; + actorx->shape_info.rotation.y = boat_actor->actor_class.shape_info.rotation.y; + boat_demo->boat_speed = boat_actor->actor_class.speed; + } + + aBTD_setup_castaway(boat_demo, play); + (*boat_demo->action_proc)(boat_demo, play); +} diff --git a/src/ac_ev_castaway.c b/src/ac_ev_castaway.c index 2ab33b8c..28c0b9d6 100644 --- a/src/ac_ev_castaway.c +++ b/src/ac_ev_castaway.c @@ -46,7 +46,7 @@ static void aECST_actor_ct(ACTOR* actorx, GAME* game) { castaway->npc_class.condition_info.demo_flg = ~aNPC_COND_DEMO_SKIP_MOVE_Y; // is this a mistake? castaway->npc_class.condition_info.hide_request = FALSE; castaway->npc_class.palActorIgnoreTimer = -1; - aNPC_SPNPC_BIT_SET(Common_Get(spnpc_first_talk_flags), aNPC_SPNPC_BIT_CASTAWAY); + aNPC_SPNPC_BIT_SET(Common_Get(spnpc_first_talk_flags), aNPC_SPNPC_BIT_DOZAEMON); actorx->status_data.weight = 254; actorx->gravity = 0.0f; actorx->max_velocity_y = 0.0f; diff --git a/src/ac_weather.c b/src/ac_weather.c index c4dc77cc..c3041cc6 100644 --- a/src/ac_weather.c +++ b/src/ac_weather.c @@ -102,11 +102,11 @@ static void aWeather_RequestChangeWeather(ACTOR* actor, s16 status, s16 level){ } } -void aWeather_RequestChangeWeatherToIsland(){ +extern void aWeather_RequestChangeWeatherToIsland(){ aWeather_RequestChangeWeather(&Common_Get(clip.weather_clip)->actor->actor_class,Common_Get(island_weather),Common_Get(island_weather_intensity)); } -void aWeather_RequestChangeWeatherFromIsland(){ +extern void aWeather_RequestChangeWeatherFromIsland(){ aWeather_RequestChangeWeather(&Common_Get(clip.weather_clip)->actor->actor_class, mEnv_SAVE_GET_WEATHER_TYPE(Save_Get(weather)) , mEnv_SAVE_GET_WEATHER_INTENSITY(Save_Get(weather))); } diff --git a/src/m_island.c b/src/m_island.c index 98838bb8..8b140b62 100644 --- a/src/m_island.c +++ b/src/m_island.c @@ -773,8 +773,8 @@ extern void mISL_gc_to_agb(Island_agb_c* agb, Island_c* gc) { zelda_free(temp); } - agb->last_song_male = gc->last_song_male; - agb->last_song_female = gc->last_song_female; + agb->last_song_to_island = gc->last_song_to_island; + agb->last_song_from_island = gc->last_song_from_island; // remove the land info portion from the checksum as it can change agb->checksum = mISL_GetFlatCheckSum((u8*)agb, sizeof(Island_agb_c), agb->checksum, mISL_ReturnCheckSum((u8*)&agb->landinfo, 16)); } @@ -820,8 +820,8 @@ extern void mISL_agb_to_gc(Island_c* gc, Island_agb_c* agb) { mISL_short((u16*)gc->deposit, (u16*)agb->deposit, sizeof(gc->deposit) / sizeof(u16)); bcopy(agb->bg_data, gc->bg_data, sizeof(gc->bg_data)); mISL_gc_to_agb_time(&gc->renew_time, &agb->renew_time); - gc->last_song_male = agb->last_song_male; - gc->last_song_female = agb->last_song_female; + gc->last_song_to_island = agb->last_song_to_island; + gc->last_song_from_island = agb->last_song_from_island; if (mFI_CheckFieldData() == TRUE) { bzero(island_x_blocks, sizeof(island_x_blocks)); diff --git a/src/m_start_data_init.c b/src/m_start_data_init.c index 5d9177d6..c43e23aa 100644 --- a/src/m_start_data_init.c +++ b/src/m_start_data_init.c @@ -248,8 +248,8 @@ static int mSDI_StartInitNew(GAME* game, int player_no, int malloc_flag) { lbRTC_TimeCopy(Save_GetPointer(saved_auto_nwrite_time), &mTM_rtcTime_clear_code); Save_Set(station_type, RANDOM(15)); - Save_Set(island.last_song_male, -1); - Save_Set(island.last_song_female, -1); + Save_Set(island.last_song_to_island, -1); + Save_Set(island.last_song_from_island, -1); mPr_SetPossessionItem(Common_Get(now_private), 0, ITM_MONEY_1000, mPr_ITEM_COND_QUEST);