diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 5d4f889a..1e3ebd8a 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -549,6 +549,10 @@ ac_weather.c: .text: [0x8060193C, 0x80602E70] .rodata: [0x8064BAE8, 0x8064BB08] .data: [0x806D1D50, 0x806D1DA0] +ac_weather_rain.c: + .text: [0x80602E70, 0x80603494] + .rodata: [0x8064BB08,0x8064BB30] + .data: [0x806D1DB8, 0x806D1DF8] m_select.c: .text: [0x80627F88, 0x80629CA8] .rodata: [0x8064D1B0, 0x8064D1B8] diff --git a/include/ac_weather.h b/include/ac_weather.h index 7efd9418..fdd3e0aa 100644 --- a/include/ac_weather.h +++ b/include/ac_weather.h @@ -20,7 +20,7 @@ typedef struct ac_weather_priv_s{ s16 timer; s16 work[5]; u8 use; - s8 id; + u8 id; u8 status; }aWeather_Priv; diff --git a/rel/ac_weather_rain.c b/rel/ac_weather_rain.c new file mode 100644 index 00000000..77b312b0 --- /dev/null +++ b/rel/ac_weather_rain.c @@ -0,0 +1,214 @@ +#include "ac_weather_rain.h" + +#include "m_common_data.h" +#include "m_rcp.h" +#include "m_field_info.h" +#include "m_malloc.h" +#include "m_player_lib.h" + +extern Gfx ef_ame02_setmode[]; + +extern Gfx ef_ame02_00_modelT[]; +extern Gfx ef_ame02_01_modelT[]; +extern Gfx ef_ame02_02_modelT[]; +extern Gfx ef_ame02_03_modelT[]; +extern Gfx ef_ame02_04_modelT[]; + +static Gfx* aWeather_rain_picha_disp[] = { + ef_ame02_00_modelT, + ef_ame02_01_modelT, + ef_ame02_02_modelT, + ef_ame02_03_modelT, +}; + +static void aWeatherRain_make(ACTOR*, GAME*); +static void aWeatherRain_ct(aWeather_Priv*, GAME*); +static void aWeatherRain_move(aWeather_Priv*, GAME*); +static void aWeatherRain_set(GAME*); +static void aWeatherRain_draw(aWeather_Priv*, GAME*); + +aWeather_Profile_c iam_weather_rain = { + aWeatherRain_make, + aWeatherRain_ct, + aWeatherRain_move, + aWeatherRain_set, + aWeatherRain_draw, +}; + +static int aWeatherRain_DecideMakeRainCount(WEATHER_ACTOR* weather){ + + if(weather->current_level == 1){ + return 1; + } + + return( weather->current_level -2 ? 0 : -1) + 3; +} + +static void aWeatherRain_make(ACTOR* actor, GAME* game){ + int i; + int priv_num; + GAME_PLAY* play = (GAME_PLAY*)game; + WEATHER_ACTOR* weather = (WEATHER_ACTOR*)actor; + + aWeather_Priv* priv; + xyz_t pos; + xyz_t pos_mod; + xyz_t speed; + int count; + f32 x,y,z; + + count = aWeatherRain_DecideMakeRainCount(weather); + pos = weather->pos; + + for(i = 0; i < count; i++){ + + priv_num = Common_Get(clip.weather_clip)->get_priv_num(weather); + if (priv_num != -1){ + x = -130.0f + (RANDOM_F(260.0f)); + z = -200.0f + (RANDOM_F(360.0f)); + + pos_mod = pos; + speed = ZeroVec; + + speed.y = -9.5f + (RANDOM_F(-2.5f)); + speed.y += -2.0f; + + pos_mod.x += x; + pos_mod.z += z; + + if(mEv_CheckTitleDemo() == -9){ + PLAYER_ACTOR* player = get_player_actor_withoutCheck(play); + + pos_mod.y = 70.0f + (120.0f + player->actor_class.world.position.y); + } + else{ + pos_mod.y = 70.0f + (120.0f + mCoBG_GetBgY_OnlyCenter_FromWpos(pos_mod, 0.0f)); + } + + priv = Common_Get(clip.weather_clip)->get_priv(1, 1000, &pos_mod, &speed, (WEATHER_ACTOR*)actor, priv_num); + if(priv != NULL){ + aWeatherRain_ct(priv,game); + priv->work[0] = 0; + } + } + } +} + +static void aWeatherRain_ct(aWeather_Priv*, GAME*){ + +} + + +static void aWeatherRain_MoveRain(aWeather_Priv* priv){ + + priv->pos.x += priv->speed.x; + priv->pos.y += priv->speed.y; + priv->pos.z += priv->speed.z; +} + + +static void aWeatherRain_MakePicha(WEATHER_ACTOR* weather, GAME* game, xyz_t pos){ + int priv_num = Common_Get(clip.weather_clip)->get_priv_num(weather); + GAME_PLAY* play = (GAME_PLAY*)game; + aWeather_Priv* priv; + f32 y; + + if(priv_num != -1){ + if(mEv_CheckTitleDemo() == -9){ + PLAYER_ACTOR* player = get_player_actor_withoutCheck(play); + + y = player->actor_class.world.position.y; + pos.y = y; + } + else{ + y = mCoBG_GetBgY_OnlyCenter_FromWpos(pos, 0.0f); + pos.y = y; + } + priv = Common_Get(clip.weather_clip)->get_priv(1, 8, &pos, NULL, weather,priv_num); + if(priv != NULL){ + aWeatherRain_ct(priv,game); + priv->work[0] = 1; + } + } +} + +static void aWeatherRain_set(GAME* game){ + + _texture_z_light_fog_prim_xlu(game->graph); + + OPEN_DISP(game->graph); + + gSPDisplayList(NEXT_POLY_XLU_DISP, ef_ame02_setmode); + + + CLOSE_DISP(game->graph); +} + + +static void aWeatherRain_move(aWeather_Priv* priv, GAME* game){ + WEATHER_ACTOR* weather; + s16 timer = (1000 - priv->timer); + + if(priv->work[0] == 0){ + aWeatherRain_MoveRain(priv); + if((timer >= 10) && (Common_Get(clip.weather_clip) != NULL)){ + weather = Common_Get(clip.weather_clip)->actor; + if(weather != NULL){ + (Common_Get(clip.weather_clip)->remove_priv(weather, priv->id)); + aWeatherRain_MakePicha(weather, game, priv->pos); + } + } + } +} + +void aWeatherRain_draw(aWeather_Priv* priv, GAME* game){ + static f32 rain_scale[] = { + 0.000299999985145f, 0.035f, 0.01f, + }; + static f32 picha_scale[] = { + 0.0033f,0.0033f,0.0033f, + }; + + GAME_PLAY* play = (GAME_PLAY*)game; + + s16 disp; + xyz_t pos; + s16 angle; + GRAPH* graph; + Mtx* work; + + angle = Common_Get(clip.weather_clip)->actor->current_yAngle; + disp = 8 - priv->timer; + pos = priv->pos; + + if(priv->work[0] == 1){ + graph = play->game.graph; + + disp = disp >> 1; + + Matrix_translate(pos.x,pos.y,pos.z, FALSE); + Matrix_mult(&play->billboard_matrix, 1); + Matrix_scale(picha_scale[0], picha_scale[1], picha_scale[2], TRUE); + + OPEN_DISP(graph); + + gSPMatrix(NEXT_POLY_XLU_DISP, _Matrix_to_Mtx_new(play->game.graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(NEXT_POLY_XLU_DISP, aWeather_rain_picha_disp[(disp)]); + + CLOSE_DISP(graph); + } + else if(priv->work[0] == 0){ + work = GRAPH_ALLOC_TYPE(game->graph, Mtx, 1); + + OPEN_DISP( play->game.graph); + + suMtxMakeSRT(work, rain_scale[0], rain_scale[1], rain_scale[2], 0, angle, 0, pos.x, pos.y, pos.z); + + gSPMatrix(NEXT_POLY_XLU_DISP, work, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(NEXT_POLY_XLU_DISP, ef_ame02_04_modelT); + + CLOSE_DISP( play->game.graph); + } +}