From e4b3862bf23c84d3e0dda7c1a3c5168b4e46cd60 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Tue, 5 Mar 2024 05:58:51 -0500 Subject: [PATCH] Implement more furniture actors --- include/m_common_data.h | 2 +- src/f_furniture.c | 8 +- src/ftr/ac_nog_flower.c | 68 ++++++++++++++--- src/ftr/ac_nog_gong.c | 59 +++++++++++++-- src/ftr/ac_nog_lawnmower.c | 61 ++++++++++++++-- src/ftr/ac_nog_sprinkler.c | 146 ++++++++++++++++++++++++++++++------- 6 files changed, 288 insertions(+), 56 deletions(-) diff --git a/include/m_common_data.h b/include/m_common_data.h index d920fcdc..589853d4 100644 --- a/include/m_common_data.h +++ b/include/m_common_data.h @@ -237,7 +237,7 @@ typedef struct common_data_s { /* 0x028568 */ Door_data_c event_door_data; /* 0x02857C */ Door_data_c famicom_emu_exit_door_data; /* 0x028590 */ u8 remove_cut_tree_info_bitfield; /* resets the cut tree states for trees in a visible acre */ - /* 0x028591 */ u8 floor_idx; + /* 0x028591 */ s8 floor_idx; /* 0x028592 */ s16 demo_profiles[2]; /* demo_profiles[0] is for demo_clip, demo_profiles[1] is for demo_clip2 */ /* 0x028596 */ u16 copy_protect_code; /* 0x028598 */ int event_keep_flags[4]; diff --git a/src/f_furniture.c b/src/f_furniture.c index d8ecfcee..d9a48835 100644 --- a/src/f_furniture.c +++ b/src/f_furniture.c @@ -822,8 +822,8 @@ static Gfx* fFTR_GetTwoTileGfx(int width0, int height0, int scroll_x0, int scrol #include "../src/ftr/ac_ike_tent_sleepbag01.c" #include "../src/ftr/ac_nog_burner.c" #include "../src/ftr/ac_nog_cornucopia.c" -// #include "../src/ftr/ac_nog_flower.c" -// #include "../src/ftr/ac_nog_gong.c" -// #include "../src/ftr/ac_nog_lawnmower.c" -// #include "../src/ftr/ac_nog_sprinkler.c" +#include "../src/ftr/ac_nog_flower.c" +#include "../src/ftr/ac_nog_gong.c" +#include "../src/ftr/ac_nog_lawnmower.c" +#include "../src/ftr/ac_nog_sprinkler.c" #include "../src/ftr/ac_dummy.c" diff --git a/src/ftr/ac_nog_flower.c b/src/ftr/ac_nog_flower.c index adfb9ac2..1e7058ce 100644 --- a/src/ftr/ac_nog_flower.c +++ b/src/ftr/ac_nog_flower.c @@ -1,17 +1,66 @@ -static void fNFL_ct(FTR_ACTOR* ftr_actor, u8* data); -static void fNFL_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); -static void fNFL_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); -static void fNFL_dt(FTR_ACTOR* ftr_actor, u8* data); +static void fNFL_ct(FTR_ACTOR* ftr_actor, u8* data) { + // nothing +} + +static void fNFL_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + // nothing +} + +static void fNFL_dt(FTR_ACTOR* ftr_actor, u8* data) { + // nothing +} + +extern Gfx int_nog_pansy_model[]; +extern Gfx int_nog_pansyT_model[]; +extern Gfx int_nog_cosmos_model[]; +extern Gfx int_nog_cosmosT_model[]; +extern Gfx int_nog_turip_model[]; +extern Gfx int_nog_turipT_model[]; + +extern u16 int_nog_flower_a_pal[]; +extern u16 int_nog_flower_b_pal[]; +extern u16 int_nog_flower_c_pal[]; + +typedef struct { + Gfx* model0; + Gfx* model1; + u16* pal; +} fNLF_model_info_c; + +static fNLF_model_info_c fNFL_model_data[] = { + { int_nog_pansy_model, int_nog_pansyT_model, int_nog_flower_a_pal }, + { int_nog_pansy_model, int_nog_pansyT_model, int_nog_flower_b_pal }, + { int_nog_pansy_model, int_nog_pansyT_model, int_nog_flower_c_pal }, + { int_nog_cosmos_model, int_nog_cosmosT_model, int_nog_flower_a_pal }, + { int_nog_cosmos_model, int_nog_cosmosT_model, int_nog_flower_b_pal }, + { int_nog_cosmos_model, int_nog_cosmosT_model, int_nog_flower_c_pal }, + { int_nog_turip_model, int_nog_turipT_model, int_nog_flower_a_pal }, + { int_nog_turip_model, int_nog_turipT_model, int_nog_flower_b_pal }, + { int_nog_turip_model, int_nog_turipT_model, int_nog_flower_c_pal }, +}; + +static void fNFL_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + int idx = ftr_actor->name - 0x4DE; + Gfx* model0 = fNFL_model_data[idx].model0; + Gfx* model1 = fNFL_model_data[idx].model1; + u16* pal = fNFL_model_data[idx].pal; + + OPEN_DISP(game->graph); + + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPSegment(NEXT_POLY_OPA_DISP, G_MWO_SEGMENT_8, pal); + gSPDisplayList(NEXT_POLY_OPA_DISP, model0); + gSPDisplayList(NEXT_POLY_OPA_DISP, model1); + + CLOSE_DISP(game->graph); +} static aFTR_vtable_c fNFL_func = { - &fNFL_ct, - &fNFL_mv, - &fNFL_dw, - &fNFL_dt, - NULL, + &fNFL_ct, &fNFL_mv, &fNFL_dw, &fNFL_dt, NULL, }; aFTR_PROFILE iam_nog_flower = { + // clang-format off NULL, NULL, NULL, @@ -29,4 +78,5 @@ aFTR_PROFILE iam_nog_flower = { 0, aFTR_INTERACTION_NO_COLLISION, &fNFL_func, + // clang-format on }; diff --git a/src/ftr/ac_nog_gong.c b/src/ftr/ac_nog_gong.c index 9b05c02e..86dc5627 100644 --- a/src/ftr/ac_nog_gong.c +++ b/src/ftr/ac_nog_gong.c @@ -1,16 +1,58 @@ -static void aNogG_ct(FTR_ACTOR* ftr_actor, u8* data); -static void aNogG_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); -static void aNogG_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); +extern cKF_Skeleton_R_c cKF_bs_r_int_nog_gong; +extern cKF_Animation_R_c cKF_ba_r_int_nog_gong; + +static void aNogG_ct(FTR_ACTOR* ftr_actor, u8* data) { + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + + cKF_SkeletonInfo_R_ct(keyframe, &cKF_bs_r_int_nog_gong, &cKF_ba_r_int_nog_gong, ftr_actor->joint, ftr_actor->morph); + cKF_SkeletonInfo_R_init_standard_stop(keyframe, &cKF_ba_r_int_nog_gong, NULL); + cKF_SkeletonInfo_R_play(keyframe); + keyframe->frame_control.speed = 0.0f; +} + +static void aNogG_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + + if (cKF_SkeletonInfo_R_play(keyframe) != cKF_STATE_STOPPED) { + cKF_SkeletonInfo_R_play(keyframe); + keyframe->frame_control.speed = 0.5f; + } else if (ftr_actor->switch_changed_flag) { + if (aFTR_CAN_PLAY_SE(ftr_actor)) { + sAdo_OngenTrgStart(0x174, &ftr_actor->position); + + /* If the wall is ringside seating, play camera flashing effect */ + if (mRmTp_GetWallIdx() == WALL_NPC065) { + sAdo_SysTrgStart(SE_FLAG_15(0x17E)); + (*Common_Get(clip).effect_clip->effect_make_proc)(eEC_EFFECT_FLASHC, ftr_actor->position, 2, 0, game, + RSV_NO, 0, 0); + } + } + + keyframe->frame_control.current_frame = 1.0f; + cKF_SkeletonInfo_R_play(keyframe); + keyframe->frame_control.speed = 0.5f; + } +} + +static void aNogG_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + Mtx* mtx = ftr_actor->skeleton_mtx[game->frame_counter & 1]; + + OPEN_DISP(game->graph); + + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + CLOSE_DISP(game->graph); + + cKF_Si3_draw_R_SV(game, keyframe, mtx, NULL, NULL, NULL); +} static aFTR_vtable_c aNogG_func = { - &aNogG_ct, - &aNogG_mv, - &aNogG_dw, - NULL, - NULL, + &aNogG_ct, &aNogG_mv, &aNogG_dw, NULL, NULL, }; aFTR_PROFILE iam_nog_gong = { + // clang-format off NULL, NULL, NULL, @@ -28,4 +70,5 @@ aFTR_PROFILE iam_nog_gong = { 0, 0, &aNogG_func, + // clang-format on }; diff --git a/src/ftr/ac_nog_lawnmower.c b/src/ftr/ac_nog_lawnmower.c index e45445db..8f98f6af 100644 --- a/src/ftr/ac_nog_lawnmower.c +++ b/src/ftr/ac_nog_lawnmower.c @@ -1,16 +1,60 @@ -static void fNLM_ct(FTR_ACTOR* ftr_actor, u8* data); -static void fNLM_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); -static void fNLM_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); +static void fNLM_ct(FTR_ACTOR* ftr_actor, u8* data) { + ftr_actor->dynamic_work_f[0] = 0.0f; +} + +static void fNLM_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + aMR_contact_info_c* contact_info = aMR_GetContactInfoLayer1(); + f32 grass_alpha = 0.0f; + + /* If pushed from the back and floor is backyard lawn or daisy meadow, show grass being cut */ + if ((Common_Get(floor_idx) == FLOOR_NPC026 || Common_Get(floor_idx) == FLOOR_NPC048) && contact_info != NULL) { + switch (ftr_actor->state) { + case aFTR_STATE_WAIT_PUSH: + case aFTR_STATE_WAIT_PUSH2: + case aFTR_STATE_WAIT_PUSH3: + case aFTR_STATE_PUSH: + if (contact_info->contact_direction == aMR_CONTACT_DIR_BACK) { + grass_alpha = 1.0f; + } + break; + } + } + + if (grass_alpha != ftr_actor->dynamic_work_f[0]) { + add_calc(&ftr_actor->dynamic_work_f[0], grass_alpha, 0.04f, 0.1f, 0.001f); + } +} + +extern Gfx int_nog_lawnmower_bodyT_model[]; +extern Gfx int_nog_lawnmower_grass_model[]; + +static void fNLM_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + GAME_PLAY* play = (GAME_PLAY*)game; + Gfx* scroll_gfx; + u8 grass_alpha = (u8)(ftr_actor->dynamic_work_f[0] * 255.0f); + + scroll_gfx = fFTR_GetTwoTileGfx(16, 16, 0, 0, 16, 16, 0, 10, play, ftr_actor, 0); + + if (scroll_gfx != NULL) { + OPEN_DISP(game->graph); + + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(NEXT_POLY_OPA_DISP, int_nog_lawnmower_bodyT_model); + gSPMatrix(NEXT_POLY_XLU_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPSegment(NEXT_POLY_XLU_DISP, G_MWO_SEGMENT_8, scroll_gfx); + gDPSetPrimColor(NEXT_POLY_XLU_DISP, 0, 255, 120, 255, 180, grass_alpha); + gSPDisplayList(NEXT_POLY_XLU_DISP, int_nog_lawnmower_grass_model); + + CLOSE_DISP(game->graph); + } +} static aFTR_vtable_c fNLM_func = { - &fNLM_ct, - &fNLM_mv, - &fNLM_dw, - NULL, - NULL, + &fNLM_ct, &fNLM_mv, &fNLM_dw, NULL, NULL, }; aFTR_PROFILE iam_nog_lawnmower = { + // clang-format off NULL, NULL, NULL, @@ -28,4 +72,5 @@ aFTR_PROFILE iam_nog_lawnmower = { 0, 0, &fNLM_func, + // clang-format on }; diff --git a/src/ftr/ac_nog_sprinkler.c b/src/ftr/ac_nog_sprinkler.c index 67c0278f..ea3a9090 100644 --- a/src/ftr/ac_nog_sprinkler.c +++ b/src/ftr/ac_nog_sprinkler.c @@ -1,32 +1,126 @@ -static void fNS_ct(FTR_ACTOR* ftr_actor, u8* data); -static void fNS_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); -static void fNS_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data); -static void fNS_dt(FTR_ACTOR* ftr_actor, u8* data); +static void fNS_ct(FTR_ACTOR* ftr_actor, u8* data) { + f32 water_alpha; + + if (ftr_actor->switch_bit == TRUE) { + ftr_actor->dynamic_work_s[0] = TRUE; + } else { + ftr_actor->dynamic_work_s[0] = FALSE; + } + + if (ftr_actor->dynamic_work_s[0] == TRUE) { + water_alpha = 100.0f; + } else { + water_alpha = 0.0f; + } + + ftr_actor->dynamic_work_f[0] = water_alpha; +} + +static void fNS_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + f32 target_water_alpha; + + if (ftr_actor->dynamic_work_s[0] == TRUE) { + target_water_alpha = 100.0f; + } else { + target_water_alpha = 0.0f; + } + + if (aFTR_CAN_PLAY_SE(ftr_actor)) { + if (ftr_actor->dynamic_work_s[0] == TRUE) { + sAdo_OngenPos((u32)ftr_actor, 0x5B, &ftr_actor->position); + } + } + + if (ftr_actor->dynamic_work_f[0] > target_water_alpha) { + ftr_actor->dynamic_work_f[0] -= 4.0f; + + if (ftr_actor->dynamic_work_f[0] < target_water_alpha) { + ftr_actor->dynamic_work_f[0] = target_water_alpha; + } + } else if (ftr_actor->dynamic_work_f[0] < target_water_alpha) { + ftr_actor->dynamic_work_f[0] += 4.0f; + + if (ftr_actor->dynamic_work_f[0] > target_water_alpha) { + ftr_actor->dynamic_work_f[0] = target_water_alpha; + } + } else if (ftr_actor->switch_changed_flag) { + ftr_actor->dynamic_work_s[0] = (ftr_actor->dynamic_work_s[0] + 1) & 1; + + if (ftr_actor->dynamic_work_s[0] == TRUE) { + sAdo_OngenTrgStart(0x16, &ftr_actor->position); + } else { + sAdo_OngenTrgStart(0x17, &ftr_actor->position); + } + } +} + +static Gfx* fNS_GetTwoTileGfx(int x0, int y0, int x1, int y1, GAME* game) { + return two_tex_scroll_dolphin(game->graph, 0, x0, y0, 16, 16, 1, x1, y1, 16, 16); +} + +extern Gfx int_nog_sprinkler_bodyT_model[]; +extern Gfx int_nog_sprinkler_water_model[]; + +static void fNS_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { + GAME_PLAY* play = (GAME_PLAY*)game; + u32 ctr_ofs; + Gfx* scroll_gfx; + u8 water_alpha; + + if (ftr_actor->ctr_type == aFTR_CTR_TYPE_GAME_PLAY) { + ctr_ofs = play->game_frame; + } else { + ctr_ofs = game->frame_counter; + } + + scroll_gfx = fNS_GetTwoTileGfx(0, 0, 0, -ctr_ofs * 10, game); + + if (ftr_actor->ctr_type == aFTR_CTR_TYPE_GAME_PLAY) { + water_alpha = (u8)(int)ftr_actor->dynamic_work_f[0]; + } else { + water_alpha = 100; + } + + if (scroll_gfx != NULL) { + OPEN_DISP(game->graph); + + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPMatrix(NEXT_POLY_XLU_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(NEXT_POLY_OPA_DISP, int_nog_sprinkler_bodyT_model); + gDPSetEnvColor(NEXT_POLY_XLU_DISP, 0, 180, 255, water_alpha); + gSPSegment(NEXT_POLY_XLU_DISP, G_MWO_SEGMENT_8, scroll_gfx); + gSPDisplayList(NEXT_POLY_XLU_DISP, int_nog_sprinkler_water_model); + + CLOSE_DISP(game->graph); + } +} + +static void fNS_dt(FTR_ACTOR* ftr_actor, u8* data) { + ftr_actor->switch_bit = (u8)ftr_actor->dynamic_work_s[0]; +} static aFTR_vtable_c fNS_func = { - &fNS_ct, - &fNS_mv, - &fNS_dw, - &fNS_dt, - NULL, + &fNS_ct, &fNS_mv, &fNS_dw, &fNS_dt, NULL, }; aFTR_PROFILE iam_nog_sprinkler = { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - 18.0f, - 0.01f, - aFTR_SHAPE_TYPEA, - mCoBG_FTR_TYPEA, - 0, - 0, - 0, - aFTR_INTERACTION_START_DISABLED, - &fNS_func, + // clang-format off + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + 18.0f, + 0.01f, + aFTR_SHAPE_TYPEA, + mCoBG_FTR_TYPEA, + 0, + 0, + 0, + aFTR_INTERACTION_START_DISABLED, + &fNS_func, + // clang-format on };