From aae583e085ca74946171f5cae6c4d2e8e73f8259 Mon Sep 17 00:00:00 2001 From: Prakxo Date: Fri, 3 Nov 2023 11:56:43 +0100 Subject: [PATCH] ac_weather work --- config/rel_slices.yml | 4 + include/ac_weather.h | 78 ++++ include/ac_weather_fine.h | 17 + include/ac_weather_leaf.h | 17 + include/ac_weather_rain.h | 17 + include/ac_weather_sakura.h | 17 + include/ac_weather_snow.h | 17 + include/m_clip.h | 3 +- include/m_common_data.h | 7 +- rel/ac_weather.c | 704 ++++++++++++++++++++++++++++++++++++ 10 files changed, 878 insertions(+), 3 deletions(-) create mode 100644 include/ac_weather_fine.h create mode 100644 include/ac_weather_leaf.h create mode 100644 include/ac_weather_rain.h create mode 100644 include/ac_weather_sakura.h create mode 100644 include/ac_weather_snow.h create mode 100644 rel/ac_weather.c diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 423e3b95..eafc26ce 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -542,6 +542,10 @@ m_map_ovl.c: .rodata: [0x8064B628, 0x8064B6B0] .data: [0x806CD9C0, 0x806CE008] .bss: [0x81340468, 0x81340488] +#ac_weather.c: +# .text: [0x8060193C, 0x80602E70] +# .rodata: [] +# .data: [] m_select.c: .text: [0x80627F88, 0x80629CA8] .rodata: [0x8064D1B0, 0x8064D1B8] diff --git a/include/ac_weather.h b/include/ac_weather.h index 940aa82b..7efd9418 100644 --- a/include/ac_weather.h +++ b/include/ac_weather.h @@ -12,6 +12,84 @@ extern int aWeather_ChangingWeather(); extern ACTOR_PROFILE Weather_Profile; +typedef struct ac_weather_priv_s{ + xyz_t pos; + xyz_t speed; + f32 unk18; + f32 unk1C; + s16 timer; + s16 work[5]; + u8 use; + s8 id; + u8 status; +}aWeather_Priv; + +typedef struct weather_actor_s WEATHER_ACTOR; + +typedef void (*CHANGE_WEATHER_PROC)(WEATHER_ACTOR* weather, s16 status, s16 level); +typedef int (*GET_WEATHER_PRV_NUM)(WEATHER_ACTOR* weather); +typedef void (*REMOVE_WEATHER_PRV)(WEATHER_ACTOR* weather, int id); +typedef aWeather_Priv* (*GET_WEATHER_PRV)(u8 status, s16 timer, xyz_t* pos, xyz_t* speed, WEATHER_ACTOR* weather, int id); +typedef int (*WEATHER_SOUND_EFFECT)(); +typedef void (*CHANGE_WEATER_INSTANCE_PROC)(WEATHER_ACTOR* weather, s16 status, s16 level); + +typedef struct ac_weather_clip_s{ + WEATHER_ACTOR* actor; + CHANGE_WEATHER_PROC change_weather; + GET_WEATHER_PRV_NUM get_priv_num; + REMOVE_WEATHER_PRV remove_priv; + GET_WEATHER_PRV get_priv; + WEATHER_SOUND_EFFECT stop_sound; + WEATHER_SOUND_EFFECT start_sound; + CHANGE_WEATER_INSTANCE_PROC change_weather_instance; +}aWeather_Clip_c; + + +typedef void (*MK_WEATHER_PROC)(ACTOR*,GAME*); +typedef void (*CT_WEATHER_PROC)(aWeather_Priv*, GAME*); +typedef void (*MV_WEATHER_PROC)(aWeather_Priv*, GAME*); +typedef void (*MT_WEATHER_PROC)(aWeather_Priv*, GAME*); +typedef void (*ST_WEATHER_PROC)(GAME*); +typedef void (*DW_WEATHER_PROC)(aWeather_Priv*, GAME*); + +typedef struct ac_weather_profile_s{ + MK_WEATHER_PROC make; + CT_WEATHER_PROC constructor; + MV_WEATHER_PROC move; + ST_WEATHER_PROC set; + DW_WEATHER_PROC draw; +}aWeather_Profile_c; + +struct weather_actor_s{ + /* 0x000 */ ACTOR actor_class; + /* 0x174 */ aWeather_Profile_c* current_profile; + /* 0x178 */ s16 current_status; + /* 0x17A */ s16 next_status; + /* 0x17C */ s16 counter; + /* 0x17E */ s16 current_level; + /* 0x180 */ s16 current_aim_level; + /* 0x182 */ s16 next_level; + /* 0x184 */ u8* ptr; + /* 0x188 */ xyz_t pos; + /* 0x194 */ aWeather_Priv* priv; + /* 0x198 */ void* t; + /* 0x19C */ u8 request_change; + /* 0x19E */ s16 unk19E; + /* 0x1A0 */ aWeather_Clip_c clip; + /* 0x1C0 */ s16 timer; + /* 0x1C2 */ s16 timer2; + /* 0x1C4 */ xyz_t wind_info; + /* 0x1D0 */ s16 lightning_timer; + /* 0x1D2 */ s16 lightning_timer2; + /* 0x1D4 */ s16 current_sound_effect; + /* 0x1D6 */ s16 umbrella_flag; + /* 0x1D8 */ s16 current_yAngle; + /* 0x1DA */ s16 sound_flag; + /* 0x1DC */ s16 start_sound_effect; + /* 0x1DE */ s16 stop_sound_effect; + /* 0x1E0 */ s16 basement_event; +}; + #ifdef __cplusplus } #endif diff --git a/include/ac_weather_fine.h b/include/ac_weather_fine.h new file mode 100644 index 00000000..8f96167c --- /dev/null +++ b/include/ac_weather_fine.h @@ -0,0 +1,17 @@ +#ifndef AC_WEATHER_FINE_H +#define AC_WEATHER_FINE_H + +#include "types.h" +#include "m_actor.h" +#include "ac_weather.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern aWeather_Profile_c iam_weather_fine; + + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/ac_weather_leaf.h b/include/ac_weather_leaf.h new file mode 100644 index 00000000..977ed91b --- /dev/null +++ b/include/ac_weather_leaf.h @@ -0,0 +1,17 @@ +#ifndef AC_WEATHER_LEAF_H +#define AC_WEATHER_LEAF_H + +#include "types.h" +#include "m_actor.h" +#include "ac_weather.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern aWeather_Profile_c iam_weather_leaf; + + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/ac_weather_rain.h b/include/ac_weather_rain.h new file mode 100644 index 00000000..0323eb11 --- /dev/null +++ b/include/ac_weather_rain.h @@ -0,0 +1,17 @@ +#ifndef AC_WEATHER_RAIN_H +#define AC_WEATHER_RAIN_H + +#include "types.h" +#include "m_actor.h" +#include "ac_weather.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern aWeather_Profile_c iam_weather_rain; + + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/ac_weather_sakura.h b/include/ac_weather_sakura.h new file mode 100644 index 00000000..dabf8133 --- /dev/null +++ b/include/ac_weather_sakura.h @@ -0,0 +1,17 @@ +#ifndef AC_WEATHER_SAKURA_H +#define AC_WEATHER_SAKURA_H + +#include "types.h" +#include "m_actor.h" +#include "ac_weather.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern aWeather_Profile_c iam_weather_sakura; + + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/ac_weather_snow.h b/include/ac_weather_snow.h new file mode 100644 index 00000000..490f1bc0 --- /dev/null +++ b/include/ac_weather_snow.h @@ -0,0 +1,17 @@ +#ifndef AC_WEATHER_SNOW_H +#define AC_WEATHER_SNOW_H + +#include "types.h" +#include "m_actor.h" +#include "ac_weather.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern aWeather_Profile_c iam_weather_snow; + + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/m_clip.h b/include/m_clip.h index 516f2e63..bc491ac1 100644 --- a/include/m_clip.h +++ b/include/m_clip.h @@ -9,6 +9,7 @@ #include "ef_effect_control.h" #include "m_demo.h" #include "bg_item_h.h" +#include "ac_weather.h" #include "ac_npc.h" #include "ac_tools.h" #include "ac_aprilfool_control.h" @@ -41,7 +42,7 @@ typedef struct clip_s { /* 0x06C */ void* _06C; /* 0x070 */ aSI_Clip_c* shop_indoor_clip; /* 0x074 */ bIT_Clip_c* bg_item_clip; - /* 0x078 */ void* _078; + /* 0x078 */ aWeather_Clip_c* weather_clip; /* 0x07C */ aINS_Clip_c* insect_clip; /* 0x080 */ aMR_Clip_c* my_room_clip; /* 0x084 */ void* _084; diff --git a/include/m_common_data.h b/include/m_common_data.h index 91d1eb56..d612fdf1 100644 --- a/include/m_common_data.h +++ b/include/m_common_data.h @@ -209,7 +209,8 @@ typedef struct common_data_s { /* 0x02666C */ s16 weather; /* 0x02666E */ s16 weather_intensity; /* 0x026670 */ lbRTC_time_c weather_time; - /* 0x026678 */ u8 _26678[0x26684 - 0x26678]; + /* 0x026678 */ s_xyz wind; + /* 0x026680 */ f32 wind_speed; /* 0x026684 */ mEv_event_common_u special_event_common; /* 0x02669C */ mQst_not_saved_c quest; /* 0x0266A4 */ int scene_from_title_demo; /* next scene to be loaded when title demo finishes */ @@ -282,7 +283,9 @@ typedef struct common_data_s { /* 0x028898 */ f32 balloon_spawn_percent; /* chance that a balloon will spawn */ /* 0x02889C */ int tanuki_shop_status; /* adjusted based on any current events happening to Nook's shop */ /* 0x0288A0 */ u8 pad_connected; /* is gamepad 0 connected? */ - /* 0x0288A1 */ u8 _288a1[0x02DB40 - 0x0288A1]; + /* 0x0288A1 */ u8 unk288A1; + /* 0x0288A2 */ s16 current_sound_effect; + /* 0x0288A4 */ u8 _288a4[0x02DB40 - 0x0288A4]; /* 0x02DB40 */ u8 auto_nwrite_set; /* when true, saved nwrite time will be utilized. Seems to be used to keep same date for fishing tourney stuff. */ /* 0x02DB42 */ u16 select_last_select_no; /* 0x02DB44 */ u16 select_last_top_no; diff --git a/rel/ac_weather.c b/rel/ac_weather.c new file mode 100644 index 00000000..3c3631ff --- /dev/null +++ b/rel/ac_weather.c @@ -0,0 +1,704 @@ +#include "ac_weather.h" + +#include "ac_weather_fine.h" +#include "ac_weather_rain.h" +#include "ac_weather_snow.h" +#include "ac_weather_sakura.h" +#include "ac_weather_leaf.h" + +#include "m_common_data.h" +#include "m_rcp.h" +#include "m_field_info.h" +#include "m_malloc.h" +#include "m_player_lib.h" + +void Weather_Actor_ct(ACTOR* actor, GAME* game); +void Weather_Actor_dt(ACTOR* actor, GAME* game); +void Weather_Actor_move(ACTOR* actor, GAME* game); +void Weather_Actor_draw(ACTOR* actor, GAME* game); + +static aWeather_Profile_c* profile_tbl[] = { + &iam_weather_fine, + &iam_weather_rain, + &iam_weather_snow, + &iam_weather_sakura, + &iam_weather_leaf, +}; + +ACTOR_PROFILE Weather_Profile = { + mAc_PROFILE_WEATHER, + ACTOR_PART_CONTROL, + ACTOR_STATE_CAN_MOVE_IN_DEMO_SCENES | ACTOR_STATE_NO_MOVE_WHILE_CULLED| ACTOR_STATE_NO_DRAW_WHILE_CULLED, + EMPTY_NO, + ACTOR_OBJ_BANK_KEEP, + sizeof(WEATHER_ACTOR), + Weather_Actor_ct, + Weather_Actor_dt, + Weather_Actor_move, + Weather_Actor_draw, + NULL, +}; + +static void aWeather_SysLevCall_MoveEnd(WEATHER_ACTOR* weather){ + + if(weather->basement_event == 1){ + weather->stop_sound_effect = 0; + weather->start_sound_effect = 0; + } + else{ + if(weather->stop_sound_effect != 0){ + sAdo_SysLevStop(weather->stop_sound_effect); + } + if(weather->start_sound_effect != 0){ + sAdo_SysLevStart(weather->start_sound_effect); + } + weather->stop_sound_effect = 0; + weather->start_sound_effect = 0; + } +} + +static void aWeather_SysLevStart(u8 flag){ + Common_Get(clip.weather_clip)->actor->start_sound_effect = flag; +} + +static void aWeather_SysLevStop(u8 flag){ + int stopFlag = flag; + WEATHER_ACTOR* weather = Common_Get(clip.weather_clip)->actor; + + if(weather->start_sound_effect == stopFlag){ + weather->start_sound_effect = 0; + } + else{ + weather->stop_sound_effect = stopFlag; + } +} + +static void aWeather_weatherinfo_CommonSet(s16 type, s16 intensity){ + + if(type >= mEnv_WEATHER_LEAVES){ + type = 0; + } + + Common_Set(weather, type); + Common_Set(weather_intensity, intensity); +} + +static void aWeather_RequestChangeWeather(WEATHER_ACTOR* weather, s16 status, s16 level){ + + if(mEnv_ReqeustChangeWeatherEnviroment(weather->current_status, status) != 0){ + if(status != weather->current_status){ + weather->next_status = status; + weather->next_level = level; + weather->request_change = TRUE; + weather->current_aim_level = 0; + } + else{ + weather->current_aim_level = level; + } + } +} + +void aWeather_RequestChangeWeatherToIsland(){ + aWeather_RequestChangeWeather(Common_Get(clip.weather_clip)->actor,Common_Get(island_weather),Common_Get(island_weather_intensity)); +} + +void aWeather_RequestChangeWeatherFromIsland(){ + aWeather_RequestChangeWeather(Common_Get(clip.weather_clip)->actor, mEnv_SAVE_GET_WEATHER_TYPE(Save_Get(weather)) , mEnv_SAVE_GET_WEATHER_INTENSITY(Save_Get(weather))); +} + +int aWeather_GetWeatherPrvNum(WEATHER_ACTOR* weather){ + aWeather_Priv* priv = weather->priv; + int i; + int num = 0; + + for(i = 100; i != 0; i--, priv++, num++){ + if(priv->use == 0){ + return num; + } + } + + return -1; +} + + +void aWeather_AbolishPrivate(WEATHER_ACTOR* weather, int num){ + aWeather_Priv* priv = weather->priv; + + if(priv != NULL){ + priv = &priv[num]; + if(priv->use != 0){ + priv->use = 0; + } + } +} + +aWeather_Priv* aWeather_GetWeatherPrv(u8 status, s16 timer, xyz_t* pos, xyz_t* speed, WEATHER_ACTOR* weather, int id){ + aWeather_Priv* priv = weather->priv; + + if((id != -1) && (id < 100)){ + if(priv[id].use == 0){ + priv[id].use = 1; + priv[id].status = status; + priv[id].timer = timer; + priv[id].id = id; + if(pos != NULL){ + priv[id].pos = *pos; + } + if(speed != NULL){ + priv[id].speed = *speed; + } + return &priv[id]; + } + return NULL; + } + return NULL; +} + +int aWeather_StopSysLevSE(){ + WEATHER_ACTOR* weather = Common_Get(clip.weather_clip)->actor; + + u8 current = weather->current_sound_effect; + + if(weather->sound_flag == 0){ + if(((u8)(current - 7) <= 2U) || (u8)(current - 18) <= 1U || + current == 20){ + aWeather_SysLevStop(current); + } + weather->sound_flag = 1; + return 1; + } + else{ + return 0; + } +} + +int aWeather_StartSysLevSE(){ + WEATHER_ACTOR* weather = Common_Get(clip.weather_clip)->actor; + + u8 current = weather->current_sound_effect; + + if(weather->sound_flag == 1){ + if(mEnv_SAVE_GET_WEATHER_TYPE(Save_Get(weather)) == 1){ + switch(mEnv_SAVE_GET_WEATHER_INTENSITY(Save_Get(weather))){ + case 1: + aWeather_SysLevStart(7); + weather->current_sound_effect = 7; + break; + + case 2: + aWeather_SysLevStart(8); + weather->current_sound_effect = 8; + break; + + case 3: + aWeather_SysLevStart(9); + weather->current_sound_effect = 9; + break; + + } + } + weather->sound_flag = 2; + } + return 0; +} + +void aWeather_ChangeWeatherInstance(WEATHER_ACTOR* weather, s16 status, s16 level){ + + weather->next_status = status; + weather->next_level = level; + weather->current_status = status; + weather->current_level = 0; + weather->request_change = TRUE; + + if(!aWeather_CountWeatherPrivate(weather)){ + weather->current_status = weather->next_status; + aWeather_SetNowProfile(weather, weather->current_status); + aWeather_weatherinfo_CommonSet(weather->current_status, weather->next_level); + weather->current_level = level; + weather->current_aim_level = weather->next_level; + weather->request_change = FALSE; + } +} + +int aWeather_IsLand_Event_Check(){ + + if(((mFI_CheckBeforeScenePerpetual() != 0) || (mFI_GetClimate() == 1)) && + (Common_Get(island_weather) != (s16)mEnv_SAVE_GET_WEATHER_TYPE(Save_Get(weather)))){ + return 1; + } + return 0; +} + +int aWeather_Basement_Event_Check(WEATHER_ACTOR* weather){ + + if((weather->basement_event == 1) || (weather->basement_event == 2)){ + return 1; + } + return 0; +} + +static void aWeather_ChangeEnvSE(WEATHER_ACTOR* weather, GAME_PLAY* play, s16 status, s16 level){ + u8 current = weather->current_sound_effect; + + if(weather->sound_flag == 1 || weather->sound_flag == 2) + return; + + if(((u8)(current - 7) <= 2U) || (u8)(current - 18) <= 1U || current == 20){ + aWeather_SysLevStop(current); + weather->current_sound_effect = -1000; + } + + if (mEv_CheckTitleDemo() <= 0) { + if (Save_Get(scene_no) == SCENE_START_DEMO || Save_Get(scene_no) == SCENE_START_DEMO2 || Save_Get(scene_no) == SCENE_START_DEMO3) { + return; + } + if((status == 1) && (weather->current_sound_effect == -1000)){ + switch (level) { + case 1: + if (mPlib_check_player_open_umbrella(play) != 0) { + aWeather_SysLevStart(0x12); + weather->current_sound_effect = 0x12; + return; + } + aWeather_SysLevStart(7); + weather->current_sound_effect = 7; + break; + case 2: + if (mPlib_check_player_open_umbrella(play) != 0) { + aWeather_SysLevStart(0x13); + weather->current_sound_effect = 0x13; + return; + } + aWeather_SysLevStart(8); + weather->current_sound_effect = 8; + break; + case 3: + if (mPlib_check_player_open_umbrella(play) != 0) { + aWeather_SysLevStart(0x14); + weather->current_sound_effect = 0x14; + return; + } + aWeather_SysLevStart(9); + weather->current_sound_effect = 9; + break; + } + } + } + +} + + +static void aWeather_EndEnvSE(ACTOR* actor){ + WEATHER_ACTOR* weather = (WEATHER_ACTOR*)actor; + u8 current = weather->current_sound_effect; + + if ((sAdo_GameframeEnd_Check() == 1) || ((sAdo_GameframeEnd_Check() == 2) && + ((aWeather_IsLand_Event_Check() != 0) || (aWeather_Basement_Event_Check(weather) != 0)))) { + if (((u8)(current - 7) <= 2) || ( (u8)(current - 0x12) <= 1) || (u8)(current == 0x14)) { + aWeather_SysLevStop(current); + weather->current_sound_effect = -1000; + Common_Set(current_sound_effect, -1000); + } + } else if (sAdo_GameframeEnd_Check() == 2) { + Common_Set(current_sound_effect, weather->current_sound_effect); + } + aWeather_SysLevCall_MoveEnd(weather); +} + +void aWeather_SetNowProfile(WEATHER_ACTOR* weather, s16 id){ + + if(!mFI_GET_TYPE(mFI_GetFieldId())){ + weather->current_profile = profile_tbl[id]; + } + else{ + weather->current_profile = NULL; + } +} + +void aWeather_SecureWeatherPrivateWork(WEATHER_ACTOR* weather){ + int i; + + weather->priv = zelda_malloc(sizeof(aWeather_Priv) * 100); + + if(weather->priv != NULL){ + for(i = 0; i < 100; i++){ + bzero(&weather->priv[i], sizeof(aWeather_Priv)); + } + } +} + +static void aWeather_SetClip(WEATHER_ACTOR* weather, int flag){ + aWeather_Clip_c* clip; + if(flag != 0){ + Common_Set(clip.weather_clip, NULL); + } + else{ + clip = &weather->clip; + + clip->actor = weather; + clip->change_weather = aWeather_RequestChangeWeather; + clip->get_priv_num = aWeather_GetWeatherPrvNum; + clip->remove_priv = aWeather_AbolishPrivate; + clip->get_priv = aWeather_GetWeatherPrv; + clip->stop_sound = aWeather_StopSysLevSE; + clip->start_sound = aWeather_StartSysLevSE; + clip->change_weather_instance = aWeather_ChangeWeatherInstance; + + Common_Set(clip.weather_clip, clip); + } +} + +void aWeather_RenewWindInfo(WEATHER_ACTOR* weather){ + s_xyz pos = Common_Get(wind); // multiply by 1 means inline ? + f32 speed = Common_Get(wind_speed) * 0.01f; + f32 factor = 1.0f; + + weather->wind_info.x = pos.x * speed * factor; + weather->wind_info.y = pos.y * speed * factor; + weather->wind_info.z = pos.z * speed * factor; +} + +void aWeather_SnowInAdvance(WEATHER_ACTOR* weather, GAME_PLAY* play, int moves){ + + int i; + + for(i = 0; i < moves; i++){ + Weather_Actor_move(&weather->actor_class, &play->game); + } +} + + +void Weather_Actor_ct(ACTOR* actor, GAME* game){ + static s16 DemoWeatherTbl[10][2] = { + + }; + WEATHER_ACTOR* weather = (WEATHER_ACTOR*)actor; + GAME_PLAY* play = (GAME_PLAY*)game; + + int cur; + xyz_t* pos = Camera2_getCenterPos_p(); + + aWeather_SetClip(weather, 0); + + if(mEv_CheckTitleDemo() > 0){ + cur = mEv_CheckTitleDemo() -1; + + weather->current_status = DemoWeatherTbl[cur][0]; + weather->next_status = DemoWeatherTbl[cur][0]; + weather->current_level = DemoWeatherTbl[cur][1]; + weather->current_aim_level = DemoWeatherTbl[cur][1]; + } + else if(mFI_GetClimate() == 1){ + weather->current_status = Common_Get(island_weather); + weather->next_status = Common_Get(island_weather); + weather->current_level = Common_Get(island_weather_intensity); + weather->current_aim_level = Common_Get(island_weather_intensity); + } + else{ + weather->current_status = mEnv_SAVE_GET_WEATHER_TYPE(Save_Get(weather)); + weather->next_status = weather->current_status; + weather->current_level = mEnv_SAVE_GET_WEATHER_INTENSITY(Save_Get(weather)); + weather->current_aim_level = Common_Get(weather_intensity); + } + + weather->ptr = NULL; + weather->priv = NULL; + weather->request_change = FALSE; + + weather->pos = *pos; + + weather->timer = 0; + weather->timer2 = 0; + weather->lightning_timer = 0; + weather->lightning_timer2 = 30; + + weather->sound_flag = 0; + aWeather_RenewWindInfo(weather); + + if(!mFI_GET_TYPE(mFI_GetFieldId())){ + aWeather_SecureWeatherPrivateWork(weather); + } + + aWeather_SetNowProfile(weather, weather->current_status); + + if((weather->current_status == 2) || (weather->current_status == 3)){ + weather->pos.y -= 50.0f; + aWeather_SnowInAdvance(weather, play, 0x28); + weather->pos.y += 50.0f; + } + + weather->stop_sound_effect = 0; + weather->start_sound_effect = 0; + + if ((Save_Get(scene_no) == SCENE_MY_ROOM_BASEMENT_S) || ( (Save_Get(scene_no) - SCENE_MY_ROOM_BASEMENT_M) <= 1U) || (Save_Get(scene_no) == SCENE_MY_ROOM_BASEMENT_LL1)) { + weather->basement_event = 1; + } else if (((Common_Get(last_scene_no) == SCENE_MY_ROOM_BASEMENT_S) || ((Common_Get(last_scene_no) - SCENE_MY_ROOM_BASEMENT_M) <= 1U) || (Common_Get(last_scene_no) == SCENE_MY_ROOM_BASEMENT_LL1)) && ( play->fb_wipe_type == 6)) { + weather->basement_event = 2; + } else { + weather->basement_event = 0; + } + if ((play->fb_wipe_type == 6) && (aWeather_IsLand_Event_Check() == 0) && (aWeather_Basement_Event_Check(weather) == 0)) { + weather->current_sound_effect = Common_Get(current_sound_effect); + } + else{ + weather->current_sound_effect = -1000; + aWeather_ChangeEnvSE(weather, play, weather->current_status, weather->current_level); + aWeather_SysLevCall_MoveEnd(weather); + } +} + +static void Weather_Actor_dt(ACTOR* actor, GAME* game){ + WEATHER_ACTOR* weather = (WEATHER_ACTOR*)actor; + + if(weather->priv != NULL){ + zelda_free(weather->priv); + } + + aWeather_SetClip(weather, 1); +} + +static void aWeather_DrawWeatherPrv(ACTOR* actor, GAME* game){ + WEATHER_ACTOR* weather = (WEATHER_ACTOR*)actor; + + aWeather_Priv* priv = weather->priv; + aWeather_Profile_c* profile; + int i; + + _texture_z_light_fog_prim_xlu(game->graph); + + if((weather->current_profile != NULL) && (priv != NULL)){ + if(weather->current_profile->set != NULL){ + weather->current_profile->set(game); + } + if(weather->current_profile->draw != NULL){ + for(i = 0; i < 100; i++, priv++){ + if(priv->use != 0){ + weather->current_profile->draw(priv, game); + } + } + } + } +} + +static void Weather_Actor_draw(ACTOR* actor, GAME* game){ + aWeather_DrawWeatherPrv(actor,game); +} + +void aWeather_MakeWeatherPrv(ACTOR* actor, GAME* game){ + WEATHER_ACTOR* weather = (WEATHER_ACTOR*)actor; + + if(weather->current_level != 0){ + if(weather->current_profile != NULL){ + if(weather->current_profile->make != NULL){ + weather->current_profile->make(actor, game); + } + } + } +} + +static void aWeather_MoveWeatherPrv(WEATHER_ACTOR* weather, GAME* game){ + aWeather_Priv* priv; + int i; + + priv = weather->priv; + + if((weather->current_profile != NULL) && (priv != NULL) && (weather->current_profile->move != NULL)) { + + for(i = 0; i < 100; i++, priv++){ + if(priv->use != 0){ + weather->current_profile->move(priv, game); + if(priv->timer != -100){ + priv->timer--; + if(priv->timer <= 0){ + aWeather_AbolishPrivate(weather, i); + } + } + } + } + } +} + +int aWeather_CountWeatherPrivate(WEATHER_ACTOR* weather){ + int i; + int count; + aWeather_Priv* priv = weather->priv; + + count = 0; + + for(i = 0; i < 100; i++, priv++){ + + if(priv->use != 0){ + count++; + } + } + + return count; +} + +static void aWeather_ChangeWeather(WEATHER_ACTOR* weather, GAME_PLAY* play){ + + if((weather->request_change == TRUE) && (weather->current_level == 0)){ + if(mFI_GET_TYPE(mFI_GetFieldId())){ + weather->current_status = weather->next_status; + aWeather_weatherinfo_CommonSet(weather->current_status, weather->next_level); + weather->current_level = 1; + weather->current_aim_level = weather->next_level; + aWeather_ChangeEnvSE(weather, play, weather->current_status, weather->current_level); + weather->request_change = FALSE; + } + else if(aWeather_CountWeatherPrivate(weather) == 0){ + weather->current_status = weather->next_status; + aWeather_SetNowProfile(weather, weather->current_status); + aWeather_weatherinfo_CommonSet(weather->current_status, weather->next_level); + weather->current_level = 1; + weather->current_aim_level = weather->next_level; + aWeather_ChangeEnvSE(weather, play, weather->current_status, weather->current_level); + weather->request_change = FALSE; + } + } +} + +void aWeather_CheckWeatherTimer(){ + s_xyz dir; + + mEnv_DecideWindDirect(&dir, 0x3000, 0x3000); +} + + +void aWeather_RenewWeatherLevel(WEATHER_ACTOR* weather, GAME_PLAY* play){ + s16 level; + + if(weather->current_level != weather->current_aim_level){ + weather->counter++; + if(weather->counter >= 180){ + weather->counter = 0; + level = weather->current_level; + if (weather->current_aim_level < level) + weather->current_level--; + else + weather->current_level++; + aWeather_ChangeEnvSE(weather, play, weather->current_status, weather->current_level); + + } + } +} + +static void aWeather_ChangeWeatherTime0(WEATHER_ACTOR* weather){ + s16 rndWeather, rndIntensity; + s16 evWeather, evIntensity; + s16 save_weather; + + if ((mEv_CheckTitleDemo() <= 0)){ + if ((Save_Get(scene_no) == SCENE_START_DEMO) || (Save_Get(scene_no) == SCENE_START_DEMO2) || Save_Get(scene_no) == SCENE_START_DEMO3) { + return; + } + if(!(mFI_CheckPlayerBlockInfo() & 0x400000) && (mTM_check_renew_time(0) != 0)){ + mEnv_RandomWeather(&rndWeather, &rndIntensity); + mEv_GetEventWeather(&evWeather, &evIntensity); + if(evWeather != -1){ + rndWeather = evWeather; + rndIntensity = evIntensity; + } + if((mEv_CheckRealArbeit() == 1) && (rndWeather == 1)){ + rndWeather = 0; + rndIntensity = 0; + } + mTM_off_renew_time(0); + + save_weather = mEnv_SAVE_GET_WEATHER_TYPE(Save_Get(weather)); + if (rndWeather == 0 || rndWeather == 3) { + if (save_weather == 2 || save_weather == 1) { + mEnv_PreRainNowFine_Init(); + } + } + Save_Set(weather, rndIntensity | (rndWeather * 16)); + + if(((mEv_CheckTitleDemo(rndIntensity) != -9) || ( weather->sound_flag != 1)) + && (mFI_CheckInIsland() == 0)){ + aWeather_RequestChangeWeather(weather, rndWeather, rndIntensity); + } + Common_Set(weather_time, Common_Get(time.rtc_time)); + } + } + } + +static void aWeather_MakeKaminari(WEATHER_ACTOR* weather){ + lbRTC_time_c time = Common_Get(time.rtc_time); + u8 month = time.month; + s16 timer; + + + if (( weather->basement_event != 1)) { + if (( Save_Get(scene_no) == SCENE_START_DEMO) || (Save_Get(scene_no) == SCENE_START_DEMO2) || Save_Get(scene_no) == SCENE_START_DEMO3) { + return; + } + if ((month >= lbRTC_JUNE) && (month <= lbRTC_AUGUST) && (weather->current_status == 1) && ( weather->current_level == 3)){ + timer = weather->lightning_timer % 1000; + if (((timer == weather->lightning_timer2) || (timer == (weather->lightning_timer2 + 20))) && + (Common_Get(clip.effect_clip) != NULL) && ( (Save_Get(scene_no) - SCENE_MY_ROOM_BASEMENT_S) > 3U) && + ( (Save_Get(scene_no) - SCENE_MUSEUM_ROOM_PAINTING) > 1U) && ( Save_Get(scene_no) != SCENE_MUSEUM_ROOM_FISH)) { + f32 effect[] = { 12712.2f }; + Common_Get(clip.effect_clip)->regist_effect_light(effect, 2, 0x23, 0); + } + if (timer == (weather->lightning_timer2 + 65)) { + sAdo_SysTrgStart(0x424); + weather->lightning_timer2 = (100.0f + (RANDOM_F(500.0f))); + } + weather->lightning_timer++; + } + } +} + + +static void Weather_Actor_move(ACTOR* actor, GAME* game){ + GAME_PLAY* play = (GAME_PLAY*)game; + WEATHER_ACTOR* weather = (WEATHER_ACTOR*)actor; + + xyz_t* pos; + Camera2* camera; + s16 angle; + s16 umbrella; + + pos = Camera2_getCenterPos_p(); + camera = &play->camera; + + angle = search_position_angleY(&camera->lookat.center, &camera->lookat.eye); + aWeather_MakeKaminari(weather); + aWeather_CheckWeatherTimer(weather); + aWeather_MakeWeatherPrv(actor, game); + aWeather_RenewWeatherLevel(weather, play); + aWeather_MoveWeatherPrv(weather,game); + aWeather_ChangeWeather(weather, play); + + weather->pos = *pos; + + aWeather_ChangeWeatherTime0(weather); + + if(Common_Get(weather) == 1){ + umbrella = mPlib_check_player_open_umbrella(play); + if(umbrella != weather->umbrella_flag){ + aWeather_ChangeEnvSE(weather, play, weather->current_status, weather->current_level); + } + + weather->umbrella_flag = umbrella; + weather->current_yAngle = angle; + } + + if(weather->sound_flag == 2){ + weather->sound_flag = 0; + } + + aWeather_EndEnvSE(actor); +} + + +extern int aWeather_ChangingWeather(){ + + if(Common_Get(clip.weather_clip) != NULL){ + if(Common_Get(clip.weather_clip->actor) != NULL){ + return Common_Get(clip.weather_clip->actor)->request_change == TRUE; + } + } + + return FALSE; +}