From f6541395e8802b2187c95f11faed317613cd787d Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Mon, 18 Dec 2023 09:20:52 -0500 Subject: [PATCH] Implement & link ac_shrine --- config/rel_slices.yml | 5 + include/ac_shrine.h | 35 +++ include/audio.h | 2 +- include/ef_effect_control.h | 2 + include/jaudio_NES/game64.h | 2 +- include/libforest/gbi_extensions.h | 8 +- include/m_clip.h | 2 +- include/m_msg.h | 1 + include/m_name_table.h | 1 + include/m_soncho.h | 2 + include/m_submenu.h | 22 ++ include/sys_math3d.h | 2 +- src/ac_shrine.c | 120 +++++++++ src/ac_shrine_clip.c_inc | 18 ++ src/ac_shrine_draw.c_inc | 132 ++++++++++ src/ac_shrine_move.c_inc | 401 +++++++++++++++++++++++++++++ src/audio.c | 2 +- src/m_actor.c | 12 +- src/m_map_ovl.c | 4 +- src/m_submenu.c | 2 +- 20 files changed, 757 insertions(+), 18 deletions(-) create mode 100644 src/ac_shrine.c create mode 100644 src/ac_shrine_clip.c_inc create mode 100644 src/ac_shrine_draw.c_inc create mode 100644 src/ac_shrine_move.c_inc diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 6d0d5d61..e2259ad3 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -566,6 +566,11 @@ ac_radio.c: .text: [0x805B887C,0x805B8C7C] .rodata: [0x8064AB58,0x8064AB68] .data: [0x806C6558,0x806C65A0] +ac_shrine.c: + .text: [0x805BA4D8, 0x805BB8D0] + .rodata: [0x8064ABD0, 0x8064AC18] + .data: [0x806C6838, 0x806C6930] + .bss: [0x813280C0, 0x813280E8] ac_structure.c: .text: [0x805BCA00, 0x805BD06C] .rodata: [0x8064AC30, 0x8064AC38] diff --git a/include/ac_shrine.h b/include/ac_shrine.h index e7878c2c..ba256f50 100644 --- a/include/ac_shrine.h +++ b/include/ac_shrine.h @@ -2,12 +2,47 @@ #define AC_SHRINE_H #include "types.h" +#include "libultra/libultra.h" #include "m_actor.h" +#include "ac_structure.h" +#include "m_common_data.h" +#include "m_font.h" +#include "m_item_name.h" +#include "m_player_lib.h" +#include "m_rcp.h" +#include "m_soncho.h" #ifdef __cplusplus extern "C" { #endif +typedef struct ac_shrine_s SHRINE_ACTOR; + +typedef void (*aSHR_ANIME_PLAY_PROC)(); + +typedef struct ac_shrine_clip_s { + aSHR_ANIME_PLAY_PROC anime_play_proc; + int play_flag; + int hem_flag; +} aSHR_Clip_c; + +#define aSHR_GET_CLIP() ((aSHR_Clip_c*)(Common_Get(clip).shrine_clip)) +#define aSHR_SET_CLIP(v) (Common_Get(clip).shrine_clip = (v)) + +typedef struct ac_shrine_present_s aSHR_Present_c; +typedef void (*aSHR_Present_PROC)(aSHR_Present_c*); + +struct ac_shrine_present_s { + xyz_t trans; + f32 percent; + int finish_flag; + aSHR_Present_PROC move_proc; +}; + +struct ac_shrine_s { + STRUCTURE_ACTOR structure_class; +}; + extern ACTOR_PROFILE Shrine_Profile; #ifdef __cplusplus diff --git a/include/audio.h b/include/audio.h index fd0514f5..b3deef87 100644 --- a/include/audio.h +++ b/include/audio.h @@ -41,7 +41,7 @@ extern u8 sAdo_MessageSpeedGet(); extern void sAdo_SysLevStop(u8 id); extern void sAdo_SysLevStart(u8 id); -extern void sAdo_OngenPos(u8 p1, u8 p2, xyz_t* pos); +extern void sAdo_OngenPos(u32 p1, u8 p2, xyz_t* pos); extern void sAdo_OngenTrgStart(u16 id, xyz_t* pos); extern void sAdo_SetOutMode(u8 mode); diff --git a/include/ef_effect_control.h b/include/ef_effect_control.h index 2a8dfbd7..d55f4864 100644 --- a/include/ef_effect_control.h +++ b/include/ef_effect_control.h @@ -16,6 +16,8 @@ enum effect_type { eEC_EFFECT_WARAU, /* TODO: finish */ eEC_DOUZOU_LIGHT = 101, + eEC_HEM_LIGHT = 123, + eEC_EFFECT_NUM = 126 }; diff --git a/include/jaudio_NES/game64.h b/include/jaudio_NES/game64.h index 8a337092..9d9aab19 100644 --- a/include/jaudio_NES/game64.h +++ b/include/jaudio_NES/game64.h @@ -24,7 +24,7 @@ extern void Na_MessageSpeed(u8); extern u8 Na_MessageSpeedGet(); extern void Na_SysLevStart(u8); extern void Na_SysLevStop(u8); -extern void Na_OngenPos(u8,u8,u16,f32); +extern void Na_OngenPos(u32,u8,u16,f32); extern void Na_OngenTrgStart(u16,u16,f32); extern void Na_SetOutMode(u8); extern void Na_SetVoiceMode(u8); diff --git a/include/libforest/gbi_extensions.h b/include/libforest/gbi_extensions.h index 841e1f37..3586e1b0 100644 --- a/include/libforest/gbi_extensions.h +++ b/include/libforest/gbi_extensions.h @@ -581,16 +581,16 @@ do { \ (u32)(_SHIFTL(alpha, 0, 8)) \ }} -#define gDPSetTextureAdjustMode(pkt, type, mode) \ +#define gDPSetTextureAdjustMode(pkt, mode) \ do { \ Gfx* _g = (Gfx*)(pkt); \ - _g->words.w0 = (u32)(_SHIFTL(G_SPECIAL_1, 24, 8) | _SHIFTL(type, 16, 8) | _SHIFTL(mode, 0, 16)); \ + _g->words.w0 = (u32)(_SHIFTL(G_SPECIAL_1, 24, 8) | _SHIFTL(G_SPECIAL_TA_MODE, 16, 8) | _SHIFTL(mode, 0, 16)); \ _g->words.w1 = (u32)0; \ } while(0) -#define gsDPSetTextureAdjustMode(type, mode) \ +#define gsDPSetTextureAdjustMode(mode) \ {{ \ - (u32)(_SHIFTL(G_SPECIAL_1, 24, 8) | _SHIFTL(type, 16, 8) | _SHIFTL(mode, 0, 16)), \ + (u32)(_SHIFTL(G_SPECIAL_1, 24, 8) | _SHIFTL(G_SPECIAL_TA_MODE, 16, 8) | _SHIFTL(mode, 0, 16)), \ (u32)0 \ }} diff --git a/include/m_clip.h b/include/m_clip.h index bc491ac1..71f86e99 100644 --- a/include/m_clip.h +++ b/include/m_clip.h @@ -62,7 +62,7 @@ typedef struct clip_s { /* 0x0BC */ aAR_Clip_c* arrange_room_clip; /* 0x0C0 */ void* _0C0; /* 0x0C4 */ void* _0C4; - /* 0x0C8 */ void* _0C8; + /* 0x0C8 */ void* shrine_clip; /* 0x0CC */ void* _0CC; /* 0x0D0 */ void* _0D0; /* 0x0D4 */ CLIP_NONE_PROC ball_redma_proc; /* removed in DnM+ */ diff --git a/include/m_msg.h b/include/m_msg.h index b948a855..31948de9 100644 --- a/include/m_msg.h +++ b/include/m_msg.h @@ -261,6 +261,7 @@ extern int mMsg_request_main_appear(mMsg_Window_c* msg_win, ACTOR* other_actor, extern int mMsg_Check_main_hide(mMsg_Window_c* msg_win); extern int mMsg_sound_voice_get_for_editor(int code); extern int mMsg_sound_spec_change_voice(mMsg_Window_c* msg_win); +extern void mMsg_request_main_forceoff(); #ifdef __cplusplus } diff --git a/include/m_name_table.h b/include/m_name_table.h index f82cb4f2..111a6e69 100644 --- a/include/m_name_table.h +++ b/include/m_name_table.h @@ -2134,6 +2134,7 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define DUMMY_HANIWA2 (DUMMY_HANIWA1 + 1) #define DUMMY_HANIWA3 (DUMMY_HANIWA2 + 1) #define DUMMY_RESERVE 0xF102 +#define DUMMY_SHRINE 0xF103 #define DUMMY_RADIO 0xF109 #define DUMMY_TAMA 0xF110 #define DUMMY_DOUZOU 0xF11D diff --git a/include/m_soncho.h b/include/m_soncho.h index 4fd02585..012e1bb7 100644 --- a/include/m_soncho.h +++ b/include/m_soncho.h @@ -13,6 +13,8 @@ extern "C" { #define mSC_RADIO_DAYS 13 #define mSC_LIGHTHOUSE_DAYS 17 +#define mSC_TROPHY_GOLDEN_AXE 29 + enum { mSC_EVENT_NEW_YEARS_DAY, mSC_EVENT_FOUNDERS_DAY, diff --git a/include/m_submenu.h b/include/m_submenu.h index c16f0627..4a65a4ce 100644 --- a/include/m_submenu.h +++ b/include/m_submenu.h @@ -88,6 +88,28 @@ enum submenu_overlay { mSM_OVL_NUM }; +enum { + mSM_IV_OPEN_NORMAL, + mSM_IV_OPEN_MAILBOX, + mSM_IV_OPEN_HANIWA_ENTRUST, + mSM_IV_OPEN_HANIWA_TAKE, + mSM_IV_OPEN_QUEST, + mSM_IV_OPEN_SELL, + mSM_IV_OPEN_GIVE, + mSM_IV_OPEN_SEND_MAIL, + mSM_IV_OPEN_TAKE, + mSM_IV_OPEN_PUTIN_FTR, + mSM_IV_OPEN_MINIDISK, + mSM_IV_OPEN_SHRINE, + mSM_IV_OPEN_12, + mSM_IV_OPEN_EXCHANGE, + mSM_IV_OPEN_14, + mSM_IV_OPEN_CURATOR, + mSM_IV_OPEN_16, + + mSM_IV_OPEN_NUM +}; + typedef struct submenu_item_s { mActor_name_t item; u8 slot_no; diff --git a/include/sys_math3d.h b/include/sys_math3d.h index 1effe1c9..3c2d0a89 100644 --- a/include/sys_math3d.h +++ b/include/sys_math3d.h @@ -37,7 +37,7 @@ extern void sMath_RotateY(xyz_t* pos, f32 rad); extern void sMath_RotateZ(xyz_t* pos, f32 rad); extern f32 Math3d_normalizeXyz_t(xyz_t* vec); extern f32 Math3DLength(xyz_t* v0, xyz_t* v1); -extern void Math3DInDivPos2(xyz_t* v0, xyz_t* v1, xyz_t* v2, f32 percent); +extern void Math3DInDivPos2(const xyz_t* v0, const xyz_t* v1, xyz_t* v2, f32 percent); extern void Math3DPlane(xyz_t* va, xyz_t* vb, xyz_t* vc, f32* nox, f32* noy, f32* noz, f32* odist); extern int Math3D_sphereCrossSphere_cl(Math3D_sphere_c* a, Math3D_sphere_c* b, f32* in); extern int Math3D_sphereVsPipe_cl(Math3D_sphere_c* s, Math3D_pipe_c* c, f32* in); diff --git a/src/ac_shrine.c b/src/ac_shrine.c new file mode 100644 index 00000000..904a2a3f --- /dev/null +++ b/src/ac_shrine.c @@ -0,0 +1,120 @@ +#include "ac_shrine.h" + +#include "m_msg.h" +#include "m_play.h" +#include "sys_matrix.h" + +static void aSHR_actor_ct(ACTOR* actorx, GAME* game); +static void aSHR_actor_dt(ACTOR* actorx, GAME* game); +static void aSHR_actor_init(ACTOR* actorx, GAME* game); +static void aSHR_actor_draw(ACTOR* actorx, GAME* game); + +ACTOR_PROFILE Shrine_Profile = { + mAc_PROFILE_SHRINE, + ACTOR_PART_ITEM, + ACTOR_STATE_NONE, + WISHING_WELL, + ACTOR_OBJ_BANK_KEEP, + sizeof(SHRINE_ACTOR), + &aSHR_actor_ct, + &aSHR_actor_dt, + &aSHR_actor_init, + &aSHR_actor_draw, + NULL +}; + +static aSHR_Present_c aSHR_present; +static aSHR_Clip_c aSHR_clip; + +enum { + aSHR_ACTION_WAIT, + aSHR_ACTION_TALK, + aSHR_ACTION_TALK_GOMEN, + aSHR_ACTION_MAKE_HEM, + aSHR_ACTION_TALK_END, + + aSHR_ACTION_NUM +}; + +enum { + aSHR_LEAF_TYPE_SUMMER, + aSHR_LEAF_TYPE_WINTER, + aSHR_LEAF_TYPE_CHRISTMAS, + aSHR_LEAF_TYPE_CHERRY, + + aSHR_LEAF_TYPE_NUM +}; + +static u8 aSHR_shadow_vtx_fix_flg_table[16] = { + TRUE, FALSE, FALSE, TRUE, + TRUE, TRUE, FALSE, FALSE, + TRUE, TRUE, FALSE, FALSE, + TRUE, TRUE, FALSE, FALSE +}; + +extern Vtx obj_shrine_shadow_v[]; +extern Gfx obj_shrine_shadow_model[]; + +static bIT_ShadowData_c aSHR_shadow_data = { + 16, + aSHR_shadow_vtx_fix_flg_table, + 60.0f, + obj_shrine_shadow_v, + obj_shrine_shadow_model +}; + +static void aSHR_setup_action(SHRINE_ACTOR*, GAME_PLAY*, int); +static void aSHR_set_bgOffset(ACTOR*, int); +static void aSHR_Present_ct(aSHR_Present_c*); +static int aSHR_ctrl_light(); +static void aSHR_init_clip_area(); +static void aSHR_free_clip_area(); + +static int aSHR_getLeaftype(int winter) { + if (Common_Get(time).term_idx == mTM_TERM_15) { + return aSHR_LEAF_TYPE_CHRISTMAS; + } + + if (Common_Get(time).term_idx == mTM_TERM_16) { + return aSHR_LEAF_TYPE_CHRISTMAS; + } + + if (Common_Get(time).term_idx == 4) { + return aSHR_LEAF_TYPE_CHERRY; + } + + return winter; +} + +static void aSHR_actor_ct(ACTOR* actorx, GAME* game) { + SHRINE_ACTOR* shrine = (SHRINE_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + int winter; + + shrine->structure_class.season = Common_Get(time).season; + winter = shrine->structure_class.season == mTM_SEASON_WINTER; + + aSHR_init_clip_area(); + aSHR_Present_ct(&aSHR_present); + aSHR_set_bgOffset(actorx, 1); + shrine->structure_class.arg2 = mEv_check_status(mEv_EVENT_NEW_YEARS_DAY, mEv_STATUS_ACTIVE); + shrine->structure_class.arg1 = aSHR_getLeaftype(winter); + actorx->world.position.x = actorx->world.position.x + 20.0f; + actorx->world.position.z = actorx->world.position.z - 19.0f; + actorx->talk_distance = 100.0f; + aSHR_setup_action(shrine, play, aSHR_ACTION_WAIT); + actorx->cull_radius = 900.0f; + actorx->cull_height = 1400.0f; + shrine->structure_class.arg0_f = aSHR_ctrl_light() ? 1.0f : 0.0f; +} + +static void aSHR_actor_dt(ACTOR* actorx, GAME* game) { + SHRINE_ACTOR* shrine = (SHRINE_ACTOR*)actorx; + + aSHR_free_clip_area(); + cKF_SkeletonInfo_R_dt(&shrine->structure_class.keyframe); +} + +#include "../src/ac_shrine_clip.c_inc" +#include "../src/ac_shrine_move.c_inc" +#include "../src/ac_shrine_draw.c_inc" diff --git a/src/ac_shrine_clip.c_inc b/src/ac_shrine_clip.c_inc new file mode 100644 index 00000000..788c769b --- /dev/null +++ b/src/ac_shrine_clip.c_inc @@ -0,0 +1,18 @@ +static void aSHR_anime_play() { + aSHR_GET_CLIP()->play_flag = TRUE; +} + +static void aSHR_init_clip_area() { + if (aSHR_GET_CLIP() == NULL) { + aSHR_SET_CLIP(&aSHR_clip); + aSHR_GET_CLIP()->anime_play_proc = &aSHR_anime_play; + aSHR_GET_CLIP()->play_flag = FALSE; + aSHR_GET_CLIP()->hem_flag = FALSE; + } +} + +static void aSHR_free_clip_area() { + if (aSHR_GET_CLIP() != NULL) { + aSHR_SET_CLIP(NULL); + } +} diff --git a/src/ac_shrine_draw.c_inc b/src/ac_shrine_draw.c_inc new file mode 100644 index 00000000..d3b1c8e0 --- /dev/null +++ b/src/ac_shrine_draw.c_inc @@ -0,0 +1,132 @@ +static void aSHR_actor_draw_ta_set(ACTOR* actorx, GAME* game) { + GRAPH* graph = game->graph; + + OPEN_DISP(graph); + + gDPSetTextureAdjustMode(NOW_POLY_OPA_DISP++, G_TA_DOLPHIN); + gDPSetTextureAdjustMode(NOW_SHADOW_DISP++, G_TA_DOLPHIN); + gDPSetTexEdgeAlpha(NOW_POLY_OPA_DISP++, 112); + gDPSetTexEdgeAlpha(NOW_SHADOW_DISP++, 112); + + CLOSE_DISP(graph); +} + +static void aSHR_actor_draw_ta_clr(ACTOR* actorx, GAME* game) { + GRAPH* graph = game->graph; + + OPEN_DISP(graph); + + gDPSetTextureAdjustMode(NOW_POLY_OPA_DISP++, G_TA_N64); + gDPSetTextureAdjustMode(NOW_SHADOW_DISP++, G_TA_N64); + gDPSetTexEdgeAlpha(NOW_POLY_OPA_DISP++, 144); + gDPSetTexEdgeAlpha(NOW_SHADOW_DISP++, 144); + + CLOSE_DISP(graph); +} + +static Gfx* aSHR_GetTwoTileGfx(int x1, int y1, int x2, int y2, GAME* game) { + return two_tex_scroll_dolphin(game->graph, 0, x1, y1, 32, 16, 1, x2, y2, 32, 16); +} + +static Gfx* aSHR_GetTwoTileGfx2(int x, int y, GAME* game) { + return two_tex_scroll_dolphin(game->graph, 0, x, y, 16, 64, 1, 0, 0, 0, 0); +} + +extern u8 obj_s_tree3_leaf_tex[]; +extern u8 obj_w_tree_leaf_tex[]; +extern u8 obj_w_tree_leaf_tex[]; +extern u8 obj_f_tree_leaf_tex[]; + +static u8* leaf_texture_table[] = { + obj_s_tree3_leaf_tex, + obj_w_tree_leaf_tex, + obj_w_tree_leaf_tex, + obj_f_tree_leaf_tex +}; + +extern Gfx obj_w_shrine_bubble_model[]; +extern Gfx obj_w_shrine_trunk_model[]; +extern Gfx obj_w_shrine_leaf_model[]; +extern Gfx obj_w_shrine_figure_model[]; +extern Gfx obj_w_shrine_base_model[]; +extern Gfx obj_w_shrine_statue_model[]; +extern Gfx obj_w_shrine_water_model[]; +extern Gfx obj_w_shrine_sprash_model[]; + +extern Gfx obj_s_shrine_bubble_model[]; +extern Gfx obj_s_shrine_trunk_model[]; +extern Gfx obj_s_shrine_leaf_model[]; +extern Gfx obj_s_shrine_figure_model[]; +extern Gfx obj_s_shrine_base_model[]; +extern Gfx obj_s_shrine_statue_model[]; +extern Gfx obj_s_shrine_water_model[]; +extern Gfx obj_s_shrine_sprash_model[]; + +static void aSHR_actor_draw(ACTOR* actorx, GAME* game) { + SHRINE_ACTOR* shrine = (SHRINE_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + GRAPH* graph = game->graph; + u16* pal = (*Common_Get(clip).structure_clip->get_pal_segment_proc)(aSTR_PAL_SHRINE); + Gfx* two_tile0 = aSHR_GetTwoTileGfx(-(play->game_frame * 50), 0, 0, -(play->game_frame * 13), game); + Gfx* two_tile1 = aSHR_GetTwoTileGfx(0, -(play->game_frame * -5), 0, -(play->game_frame * -3), game); + Gfx* two_tile2 = aSHR_GetTwoTileGfx2(0, -(play->game_frame * 12), game); + u16* dol_pal = g_fdinfo->field_palette.cedar_tree_pal; + u8* tex = leaf_texture_table[shrine->structure_class.arg1 & 3]; + + if (Camera2_CheckCullingMode() == FALSE || Camera2_CheckEnterCullingArea(actorx->world.position.x, actorx->world.position.z, 105.0f) == FALSE) { + GRAPH* graph2; // probably from a macro + + _texture_z_light_fog_prim_npc(graph); + _texture_z_light_fog_prim_xlu(game->graph); + _texture_z_light_fog_prim_shadow(game->graph); + aSHR_actor_draw_ta_set(actorx, game); + + graph2 = game->graph; + OPEN_DISP(graph2); + + gSPMatrix(NOW_POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPMatrix(NOW_POLY_XLU_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPMatrix(NOW_SHADOW_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPSegment(NOW_POLY_XLU_DISP++, G_MWO_SEGMENT_C, two_tile0); + gSPSegment(NOW_POLY_XLU_DISP++, G_MWO_SEGMENT_D, two_tile1); + gSPSegment(NOW_POLY_XLU_DISP++, G_MWO_SEGMENT_B, two_tile2); + + gSPSegment(NOW_POLY_OPA_DISP++, G_MWO_SEGMENT_9, dol_pal); + gSPSegment(NOW_POLY_OPA_DISP++, G_MWO_SEGMENT_A, tex); + + if (shrine->structure_class.season == mTM_SEASON_WINTER) { + /* Opaque */ + gSPDisplayList(NOW_POLY_OPA_DISP++, obj_w_shrine_bubble_model); + gSPDisplayList(NOW_POLY_OPA_DISP++, obj_w_shrine_trunk_model); + gSPDisplayList(NOW_POLY_OPA_DISP++, obj_w_shrine_leaf_model); + gSPDisplayList(NOW_POLY_OPA_DISP++, obj_w_shrine_figure_model); + gSPDisplayList(NOW_POLY_OPA_DISP++, obj_w_shrine_base_model); + gSPDisplayList(NOW_POLY_OPA_DISP++, obj_w_shrine_statue_model); + + /* Translucent */ + gSPDisplayList(NOW_POLY_XLU_DISP++, obj_w_shrine_water_model); + gSPDisplayList(NOW_POLY_XLU_DISP++, obj_w_shrine_sprash_model); + gSPDisplayList(NOW_POLY_XLU_DISP++, obj_w_shrine_bubble_model); + } + else { + /* Opaque */ + gSPDisplayList(NOW_POLY_OPA_DISP++, obj_s_shrine_bubble_model); + gSPDisplayList(NOW_POLY_OPA_DISP++, obj_s_shrine_trunk_model); + gSPDisplayList(NOW_POLY_OPA_DISP++, obj_s_shrine_leaf_model); + gSPDisplayList(NOW_POLY_OPA_DISP++, obj_s_shrine_figure_model); + gSPDisplayList(NOW_POLY_OPA_DISP++, obj_s_shrine_base_model); + gSPDisplayList(NOW_POLY_OPA_DISP++, obj_s_shrine_statue_model); + + /* Translucent */ + gSPDisplayList(NOW_POLY_XLU_DISP++, obj_s_shrine_water_model); + gSPDisplayList(NOW_POLY_XLU_DISP++, obj_s_shrine_sprash_model); + gSPDisplayList(NOW_POLY_XLU_DISP++, obj_s_shrine_bubble_model); + } + + CLOSE_DISP(graph2); + + (*Common_Get(clip).bg_item_clip->draw_shadow_proc)(game, &aSHR_shadow_data, FALSE); + aSHR_actor_draw_ta_clr(actorx, game); + } +} diff --git a/src/ac_shrine_move.c_inc b/src/ac_shrine_move.c_inc new file mode 100644 index 00000000..5ec0e203 --- /dev/null +++ b/src/ac_shrine_move.c_inc @@ -0,0 +1,401 @@ +/* @unused static void aSHR_OngenTrgStart(SHRINE_ACTOR*, int?) */ + +static void aSHR_set_bgOffset(ACTOR* actorx, int table_idx) { + static mCoBG_OffsetTable_c height_table_ct[4][2] = { + { + { 100, 1, 1, 1, 1, 1, 0 }, // X + { 100, 1, 1, 1, 1, 1, 0 }, // Z + }, + { + { 100, 2, 2, 1, 1, 4, 0 }, + { 100, 2, 4, 1, 1, 2, 0 }, + }, + { + { 100, 11, 11, 11, 11, 11, 0 }, + { 100, 11, 11, 11, 11, 11, 0 }, + }, + { + { 100, 11, 11, 11, 11, 11, 0 }, + { 100, 11, 11, 11, 11, 11, 0 } + } + }; + + static mCoBG_OffsetTable_c* height_table[] = { + (mCoBG_OffsetTable_c*)height_table_ct, + (mCoBG_OffsetTable_c*)height_table_ct + }; + + static f32 addX[2] = { -20.0f, 20.0f }; + static f32 addZ[4] = { 20.0f, -20.0f, -60.0f, -100.0f }; + + mCoBG_OffsetTable_c* height_table_p = (mCoBG_OffsetTable_c*)height_table[table_idx]; + int i; + + for (i = 0; i < 4; i++) { + xyz_t pos; + + pos.z = actorx->home.position.z + addZ[i]; + pos.x = actorx->home.position.x + addX[0]; + mCoBG_SetPluss5PointOffset_file(pos, height_table_p[0], __FILE__, 238); + + pos.x = actorx->home.position.x + addX[1]; + mCoBG_SetPluss5PointOffset_file(pos, height_table_p[1], __FILE__, 242); + + height_table_p += 2; + } +} + +static int aSHR_talk_check(ACTOR* actorx, GAME_PLAY* play) { + PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play); + SHRINE_ACTOR* shrine = (SHRINE_ACTOR*)actorx; + int res = FALSE; + + if (aSHR_GET_CLIP()->hem_flag == TRUE) { + return FALSE; + } + + if (shrine->structure_class.arg2 == 0 && mDemo_Get_talk_actor() == NULL && player != NULL) { + s16 player_angle_y = search_position_angleY(&actorx->world.position, &player->actor_class.world.position); + + if (ABS(player_angle_y - actorx->shape_info.rotation.y) < DEG2SHORT_ANGLE(22.5f)) { + res = TRUE; + } + } + + return res; +} + +static void aSHR_set_talk_info(ACTOR* actorx) { + rgba_t window_color; + + mDemo_Set_msg_num(0x1124); + mDemo_Set_camera(CAMERA2_PROCESS_NORMAL); + mDemo_Set_talk_display_name(FALSE); + mDemo_Set_ListenAble(); + + window_color.r = 205; + window_color.g = 80; + window_color.b = 40; + window_color.a = 255; + mDemo_Set_talk_window_color(&window_color); +} + +static int aSHR_ctrl_light() { + int res = FALSE; + + if (Common_Get(time.now_sec) < (6 * mTM_SECONDS_IN_HOUR) || Common_Get(time.now_sec) >= (18 * mTM_SECONDS_IN_HOUR)) { + res = TRUE; + } + + return res; +} + +static void aSHR_Present_move_wait_init(aSHR_Present_c*); +static void aSHR_Present_move_wait(aSHR_Present_c*); +static void aSHR_Present_move_walk(aSHR_Present_c*); + +static void aSHR_Present_ct(aSHR_Present_c* present) { + bzero(present, sizeof(aSHR_Present_c)); + aSHR_Present_move_wait_init(present); +} + +static void aSHR_Present_move(aSHR_Present_c* present, SHRINE_ACTOR* shrine, GAME_PLAY* play) { + (*present->move_proc)(present); + + if (present->move_proc == aSHR_Present_move_walk && present->finish_flag == FALSE) { + HANDOVERITEM_ACTOR* handOverItem = (HANDOVERITEM_ACTOR*)Actor_info_name_search(&play->actor_info, mAc_PROFILE_HANDOVERITEM, ACTOR_PART_BG); + + if (handOverItem != NULL) { + /* Move the 'handOverItem' actor's position to the location of our 'present' */ + Matrix_push(); + Matrix_translate( + shrine->structure_class.actor_class.world.position.x + present->trans.x, + shrine->structure_class.actor_class.world.position.y + present->trans.y, + shrine->structure_class.actor_class.world.position.z + present->trans.z, + 0 + ); + Matrix_scale(0.01f, 0.01f, 0.01f, 1); + Matrix_get(&handOverItem->tools_class.matrix_work); + Matrix_pull(); + handOverItem->tools_class.init_matrix = TRUE; + } + } +} + +static void aSHR_Present_move_wait_init(aSHR_Present_c* present) { + present->move_proc = &aSHR_Present_move_wait; +} + +static void aSHR_Present_move_wait(aSHR_Present_c* present) { + /* Do nothing */ +} + +static const xyz_t aSHR_present_init_pos = { 2.0f, 40.0f, 10.0f }; // start +static const xyz_t aSHR_present_aim_pos = { 2.0f, 40.0f, 33.0f }; // goal + +static void aSHR_Present_move_walk(aSHR_Present_c* present) { + f32 move = get_percent_forAccelBrake(present->percent, 0.0f, 1.0f, 0.15f, 0.15f); + + present->percent += 0.012f; + Math3DInDivPos2(&aSHR_present_init_pos, &aSHR_present_aim_pos, &present->trans, move); + + if (move >= 1.0f) { + present->finish_flag = TRUE; + } +} + +static void aSHR_wait(SHRINE_ACTOR* shrine, GAME_PLAY* play) { + if (mDemo_Check(mDemo_TYPE_TALK, (ACTOR*)shrine) == TRUE) { + mDemo_Set_ListenAble(); + aSHR_setup_action(shrine, play, aSHR_ACTION_TALK); + } + else if (aSHR_talk_check((ACTOR*)shrine, play)) { + mDemo_Request(mDemo_TYPE_TALK, (ACTOR*)shrine, &aSHR_set_talk_info); + } +} + +static void aSHR_talk(SHRINE_ACTOR* shrine, GAME_PLAY* play) { + static u8 choume_str[FG_BLOCK_Z_NUM + 1] = { 'Q', 'A', 'B', 'C', 'D', 'E', 'F' }; + mMsg_Window_c* msg_p = mMsg_Get_base_window_p(); + int msg_no = 0x1128; + int action; + int condition; + int field_rank; + int bx; + int bz; + int good_field; + u8 acre_str[mIN_ITEM_NAME_LEN]; + + if (mMsg_Check_MainNormalContinue(msg_p)) { + switch (mChoice_Get_ChoseNum(mChoice_Get_base_window_p())) { + case mChoice_CHOICE0: /* How are things? */ + { + condition = mFAs_GetFieldRank_Condition(&field_rank, &bx, &bz); + good_field = mFAs_CheckGoodField(); + + if ( + field_rank == mFAs_FIELDRANK_SIX && /* Current field rank is 'perfect' */ + good_field && /* Perfect town status achieved for long enough */ + mSC_trophy_get(mSC_TROPHY_GOLDEN_AXE) == FALSE && /* Haven't already obtained the golden axe */ + mLd_PlayerManKindCheck() == FALSE && /* Must be from this town */ + mPr_GetPossessionItemIdx(Common_Get(now_private), EMPTY_NO) >= 0 && /* Must have a free inventory slot */ + mEv_CheckFirstJob() == FALSE && /* Can't be doing the part-time job */ + condition != mFAs_CONDITION_DUST_OVER /* No trash */ + ) { + msg_no = 0x2C50; + action = aSHR_ACTION_MAKE_HEM; + } + else if (condition != mFAs_CONDITION_NO_CASE) { + switch (condition) { + case mFAs_CONDITION_DUST_OVER: + msg_no = 0x2C4F; + break; + case mFAs_CONDITION_TREE_LESS: + msg_no = 0x2C45; + break; + case mFAs_CONDITION_TREE_OVER: + msg_no = 0x2C46; + break; + //case mFAs_CONDITION_GRASS_OVER: + default: + msg_no = 0x2C47; + break; + } + + mFont_UnintToString(acre_str, sizeof(acre_str), bx, sizeof(acre_str), TRUE, FALSE, TRUE); + mMsg_Set_free_str(msg_p, mMsg_FREE_STR1, acre_str, sizeof(acre_str)); + mMsg_Set_free_str(msg_p, mMsg_FREE_STR0, &choume_str[bz], 1); + action = aSHR_ACTION_TALK_END; + } + else { + msg_no = 0x2C4E - field_rank; /* Message is based on the field rank */ + action = aSHR_ACTION_TALK_END; + } + + mMsg_Set_continue_msg_num(msg_p, msg_no); + break; + } + + case mChoice_CHOICE1: /* Apologize */ + { + if (mSM_check_open_inventory_itemlist(mSM_IV_OPEN_SHRINE, 0)) { + shrine->structure_class.arg0 = 0; + action = aSHR_ACTION_TALK_GOMEN; + } + else { + msg_no = 0x1127; + action = aSHR_ACTION_TALK_END; + } + + mMsg_Set_continue_msg_num(msg_p, msg_no); + break; + } + + default: /* 'What's this?', 'Nothing...' */ + { + action = aSHR_ACTION_TALK_END; + break; + } + } + + if (action != -1) { + aSHR_setup_action(shrine, play, action); + } + } +} + +static void aSHR_talk_gomen(SHRINE_ACTOR* shrine, GAME_PLAY* play) { + mMsg_Window_c* msg_p = mMsg_Get_base_window_p(); + Submenu* submenu = &play->submenu; + int msg_no = -1; + + /* TODO: enums for whatever this is */ + switch (shrine->structure_class.arg0) { + //default: + + case 0: + { + if (mMsg_Check_MainNormalContinue(msg_p) == TRUE) { + mMsg_request_main_disappear_wait_type1(msg_p); + shrine->structure_class.arg0 = 1; + } + return; + } + + case 1: + { + if (mMsg_Check_main_wait(msg_p) == TRUE) { + mSM_open_submenu(submenu, mSM_OVL_INVENTORY, mSM_IV_OPEN_SHRINE, 0); + shrine->structure_class.arg0 = 2; + } + return; + } + + case 2: + { + u8 item_name[mIN_ITEM_NAME_LEN]; + Submenu_Item_c* sm_item; + if (submenu->flag) { + return; + } + + sm_item = submenu->item_p; + if (sm_item->item == EMPTY_NO) { + mMsg_request_main_forceoff(); + } + else if (mQst_CheckNpcExistbyItemIdx(sm_item->slot_no, mQst_CHECK_NPC_RECEIPIENT)) { + msg_no = 0x1129; + } + else if (mQst_CheckNpcExistbyItemIdx(sm_item->slot_no, mQst_CHECK_NPC_SENDER)) { + msg_no = 0x112A; + } + else if (mQst_CheckFirstJobQuestbyItemIdx(sm_item->slot_no)) { + msg_no = 0x112A; + } + else { + mIN_copy_name_str(item_name, sm_item->item); + mMsg_Set_free_str_art(msg_p, mMsg_FREE_STR0, item_name, mIN_ITEM_NAME_LEN, mIN_get_item_article(sm_item->item)); + msg_no = 0x112B; + mQst_ClearQuestbyPossessionIdx(sm_item->slot_no); + mPr_SetPossessionItem(Common_Get(now_private), sm_item->slot_no, EMPTY_NO, mPr_ITEM_COND_NORMAL); + } + + if (msg_no != -1) { + mMsg_Set_ForceNext(msg_p); + mMsg_request_main_appear_wait_type1(msg_p); + mMsg_Set_continue_msg_num(msg_p, msg_no); + } + + aSHR_setup_action(shrine, play, aSHR_ACTION_TALK_END); + shrine->structure_class.arg0 = 0; + break; + } + } +} + +static void aSHR_make_hem_init(SHRINE_ACTOR* shrine) { + mDemo_Set_talk_return_demo_wait(TRUE); + mPlib_Set_able_force_speak_label((ACTOR*)shrine); +} + +static void aSHR_make_hem(SHRINE_ACTOR* shrine, GAME_PLAY* play) { + if (shrine->structure_class.actor_class.parent_actor == NULL) { + if ( + mMsg_Check_MainDisappear(mMsg_Get_base_window_p()) && + Common_Get(clip).npc_clip != NULL && + Common_Get(clip).npc_clip->setupActor_proc != NULL + ) { + int made_hem = (*Common_Get(clip).npc_clip->setupActor_proc)(play, SP_NPC_HEM, -1, -1, -1, shrine->structure_class.actor_class.block_x, shrine->structure_class.actor_class.block_z, 7, 8); + + if (made_hem == TRUE) { + ACTOR* hem_actor = Actor_info_fgName_search(&play->actor_info, SP_NPC_HEM, ACTOR_PART_NPC); + + if (hem_actor != NULL) { + xyz_t pos = shrine->structure_class.actor_class.world.position; + + hem_actor->parent_actor = (ACTOR*)shrine; + aSHR_GET_CLIP()->hem_flag = TRUE; + Common_Set(hem_visible, FALSE); + pos.z += mFI_UT_WORLDSIZE_Z_F; + (*Common_Get(clip).effect_clip->effect_make_proc)(eEC_HEM_LIGHT, pos, 2, 0, (GAME*)play, 0xFFFF, 1, 0); + mSC_trophy_set(mSC_TROPHY_GOLDEN_AXE); + mFAs_ClearGoodField(); /* Only one player can get it at a time */ + aSHR_setup_action(shrine, play, aSHR_ACTION_TALK_END); + + if (mPlib_Check_able_force_speak_label((GAME*)play, (ACTOR*)shrine)) { + mPlib_Set_able_force_speak_label(hem_actor); + } + } + } + } + } +} + +static void aSHR_talk_end(SHRINE_ACTOR* shrine, GAME_PLAY* play) { + if (mDemo_Check(mDemo_TYPE_TALK, (ACTOR*)shrine) == FALSE) { + aSHR_setup_action(shrine, play, aSHR_ACTION_WAIT); + } +} + +typedef void (*aSHR_PROC)(SHRINE_ACTOR*, GAME_PLAY*); +typedef void (*aSHR_INIT_PROC)(SHRINE_ACTOR*); + +static void aSHR_setup_action(SHRINE_ACTOR* shrine, GAME_PLAY* play, int action) { + static aSHR_INIT_PROC init_proc[aSHR_ACTION_NUM] = { + NULL, + NULL, + NULL, + &aSHR_make_hem_init, + NULL + }; + + static aSHR_PROC process[aSHR_ACTION_NUM] = { + &aSHR_wait, + &aSHR_talk, + &aSHR_talk_gomen, + &aSHR_make_hem, + &aSHR_talk_end + }; + + if (init_proc[action] != NULL) { + (*init_proc[action])(shrine); + } + + shrine->structure_class.action_proc = (aSTR_MOVE_PROC)process[action]; + shrine->structure_class.action = action; +} + +static void aSHR_actor_move(ACTOR* actorx, GAME* game) { + GAME_PLAY* play = (GAME_PLAY*)game; + SHRINE_ACTOR* shrine = (SHRINE_ACTOR*)actorx; + + (*(aSHR_PROC)shrine->structure_class.action_proc)(shrine, play); + aSHR_Present_move(&aSHR_present, shrine, play); + sAdo_OngenPos((u32)actorx, 0x5A, &actorx->world.position); +} + +static void aSHR_actor_init(ACTOR* actorx, GAME* game) { + mFI_SetFG_common(DUMMY_SHRINE, actorx->home.position, FALSE); + aSHR_actor_move(actorx, game); + actorx->mv_proc = &aSHR_actor_move; +} diff --git a/src/audio.c b/src/audio.c index 36a9e1f3..d7922136 100644 --- a/src/audio.c +++ b/src/audio.c @@ -135,7 +135,7 @@ extern void sAdo_SysLevStop(u8 id){ Na_SysLevStop(id); } -extern void sAdo_OngenPos(u8 p1, u8 p2, xyz_t* pos){ +extern void sAdo_OngenPos(u32 p1, u8 p2, xyz_t* pos){ u16 scalc; f32 fcalc; diff --git a/src/m_actor.c b/src/m_actor.c index 655fc5ff..bbaf6544 100644 --- a/src/m_actor.c +++ b/src/m_actor.c @@ -215,9 +215,9 @@ static void Actor_draw_ta_set(ACTOR* actor, GAME_PLAY* play) { g = play->game.graph; OPEN_DISP(g); - gDPSetTextureAdjustMode(NOW_POLY_OPA_DISP++, G_SPECIAL_TA_MODE, G_TA_DOLPHIN); - gDPSetTextureAdjustMode(NOW_SHADOW_DISP++, G_SPECIAL_TA_MODE, G_TA_DOLPHIN); - gDPSetTextureAdjustMode(NOW_POLY_XLU_DISP++, G_SPECIAL_TA_MODE, G_TA_DOLPHIN); + gDPSetTextureAdjustMode(NOW_POLY_OPA_DISP++, G_TA_DOLPHIN); + gDPSetTextureAdjustMode(NOW_SHADOW_DISP++, G_TA_DOLPHIN); + gDPSetTextureAdjustMode(NOW_POLY_XLU_DISP++, G_TA_DOLPHIN); gDPSetTexEdgeAlpha(NOW_POLY_OPA_DISP++, 127); gDPSetTexEdgeAlpha(NOW_SHADOW_DISP++, 127); @@ -236,9 +236,9 @@ static void Actor_draw_ta_clr(ACTOR* actor, GAME_PLAY* play) { g = play->game.graph; OPEN_DISP(g); - gDPSetTextureAdjustMode(NOW_POLY_OPA_DISP++, G_SPECIAL_TA_MODE, G_TA_N64); - gDPSetTextureAdjustMode(NOW_SHADOW_DISP++, G_SPECIAL_TA_MODE, G_TA_N64); - gDPSetTextureAdjustMode(NOW_POLY_XLU_DISP++, G_SPECIAL_TA_MODE, G_TA_N64); + gDPSetTextureAdjustMode(NOW_POLY_OPA_DISP++, G_TA_N64); + gDPSetTextureAdjustMode(NOW_SHADOW_DISP++, G_TA_N64); + gDPSetTextureAdjustMode(NOW_POLY_XLU_DISP++, G_TA_N64); gDPSetTexEdgeAlpha(NOW_POLY_OPA_DISP++, 144); gDPSetTexEdgeAlpha(NOW_SHADOW_DISP++, 144); diff --git a/src/m_map_ovl.c b/src/m_map_ovl.c index 7bcad8a1..73fabd1c 100644 --- a/src/m_map_ovl.c +++ b/src/m_map_ovl.c @@ -1012,7 +1012,7 @@ static void mMP_set_map_dl(GRAPH* graph, mMP_Overlay_c* map_ovl) { gfx = NOW_POLY_OPA_DISP; - gDPSetTextureAdjustMode(gfx++, G_SPECIAL_TA_MODE, G_TA_DOLPHIN); + gDPSetTextureAdjustMode(gfx++, G_TA_DOLPHIN); gSPDisplayList(gfx++, kan_tizu_mode); Matrix_push(); @@ -1035,7 +1035,7 @@ static void mMP_set_map_dl(GRAPH* graph, mMP_Overlay_c* map_ovl) { } Matrix_pull(); - gDPSetTextureAdjustMode(gfx++, G_SPECIAL_TA_MODE, G_TA_N64); + gDPSetTextureAdjustMode(gfx++, G_TA_N64); SET_POLY_OPA_DISP(gfx); CLOSE_DISP(graph); diff --git a/src/m_submenu.c b/src/m_submenu.c index 752c48f1..2837d81a 100644 --- a/src/m_submenu.c +++ b/src/m_submenu.c @@ -637,7 +637,7 @@ static int mSM_check_item_for_curator(int slot_no, int param_2) { typedef int (*mSM_INVENTORY_CHECK_PROC)(int, int); extern int mSM_check_open_inventory_itemlist(int type, int param_2) { - static mSM_INVENTORY_CHECK_PROC check_process[] = { + static mSM_INVENTORY_CHECK_PROC check_process[mSM_IV_OPEN_NUM] = { NULL, NULL, &mSM_check_item_for_entrust,