diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 802a4cef..566e5577 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -719,6 +719,9 @@ ac_radio.c: .text: [0x805B887C, 0x805B8C7C] .rodata: [0x8064AB58, 0x8064AB68] .data: [0x806C6558, 0x806C65A0] +ac_reserve.c: + .text: [0x805B8C7C, 0x805B9098] + .data: [0x806C65A0, 0x806C6608] ac_shrine.c: .text: [0x805BA4D8, 0x805BB8D0] .rodata: [0x8064ABD0, 0x8064AC18] diff --git a/include/ac_reserve.h b/include/ac_reserve.h index 0fb662fc..9a955240 100644 --- a/include/ac_reserve.h +++ b/include/ac_reserve.h @@ -1,13 +1,16 @@ #ifndef AC_RESERVE_H #define AC_RESERVE_H -#include "types.h" -#include "m_actor.h" +#include "ac_structure.h" #ifdef __cplusplus extern "C" { #endif +typedef struct actor_reserve_s { + STRUCTURE_ACTOR structure_class; +}RESERVE_ACTOR; + extern ACTOR_PROFILE Reserve_Profile; #ifdef __cplusplus diff --git a/src/ac_reserve.c b/src/ac_reserve.c new file mode 100644 index 00000000..cda8088c --- /dev/null +++ b/src/ac_reserve.c @@ -0,0 +1,45 @@ +#include "ac_reserve.h" +#include "bg_item_h.h" +#include "m_common_data.h" +#include "m_player_lib.h" +#include "sys_matrix.h" + +static void aRSV_actor_ct(ACTOR* actor, GAME* game); +static void aRSV_actor_init(ACTOR* actor, GAME* game); +static void aRSV_actor_draw(ACTOR* actor, GAME* game); + +ACTOR_PROFILE Reserve_Profile = { + mAc_PROFILE_RESERVE, + ACTOR_PART_ITEM, + ACTOR_STATE_TA_SET, + 0x5810, // include name later + ACTOR_OBJ_BANK_KEEP, + sizeof(RESERVE_ACTOR), + aRSV_actor_ct, + NONE_ACTOR_PROC, + aRSV_actor_init, + aRSV_actor_draw, +}; + +extern Gfx reserve_DL_model[]; +extern Gfx reserve_winter_DL_model[]; +extern Gfx obj_s_attentionT_model[]; +extern Gfx obj_w_attentionT_model[]; + +static void aRSV_set_bgOffset(ACTOR*, int); +static void aRSV_setup_action(ACTOR* actor, int type); + +static void aRSV_actor_ct(ACTOR* actor, GAME* game) { + RESERVE_ACTOR* reserve = (RESERVE_ACTOR*)actor; + mActor_name_t id; + + reserve->structure_class.season = Common_Get(time.season); + + reserve->structure_class.arg0 = actor->npc_id - SIGN00; + + aRSV_setup_action(actor, 0); + aRSV_set_bgOffset(actor, 1); +} + +#include "../src/ac_reserve_draw.c_inc" +#include "../src/ac_reserve_move.c_inc" \ No newline at end of file diff --git a/src/ac_reserve_draw.c_inc b/src/ac_reserve_draw.c_inc new file mode 100644 index 00000000..a927ef7f --- /dev/null +++ b/src/ac_reserve_draw.c_inc @@ -0,0 +1,57 @@ +void aRSV_actor_draw(ACTOR* actor, GAME* game) { + static Gfx* displayList[] = { + reserve_DL_model, + reserve_winter_DL_model, + }; + static Gfx* displayList_kappa[] = { + obj_s_attentionT_model, + obj_w_attentionT_model, + }; + + RESERVE_ACTOR* reserve = (RESERVE_ACTOR*)actor; + GAME_PLAY* play = (GAME_PLAY*)game; + GRAPH* graph; + int isWinter; + Gfx* gfx; + Mtx* mtx; + bIT_ShadowData_c* data; + int check; + u16* pal; + + graph = game->graph; + + isWinter = reserve->structure_class.season == mTM_SEASON_WINTER; + check = reserve->structure_class.arg0 == 0x42; + + if (check != 0) { + gfx = displayList_kappa[isWinter]; + data = &aRSV_kappa_shadow_data; + } else { + gfx = displayList[isWinter]; + data = &aRSV_shadow_data; + } + + pal = Common_Get(clip).structure_clip->get_pal_segment_proc(0x3E); + mtx = _Matrix_to_Mtx_new(graph); + + if (mtx != NULL) { + Gfx* disp; + _texture_z_light_fog_prim_npc(graph); + OPEN_DISP(graph); + disp = NOW_POLY_OPA_DISP; + + gSPSegment(disp++, 8, pal); + gSPMatrix(disp++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(disp++, gfx); + + NOW_POLY_OPA_DISP = disp; + + if (check != 0) { + Common_Get(clip).bg_item_clip->draw_shadow_proc(game, data, 1); + } else { + Common_Get(clip).bg_item_clip->draw_shadow_proc(game, data, 0); + } + + CLOSE_DISP(graph); + } +} \ No newline at end of file diff --git a/src/ac_reserve_move.c_inc b/src/ac_reserve_move.c_inc new file mode 100644 index 00000000..7ac695ee --- /dev/null +++ b/src/ac_reserve_move.c_inc @@ -0,0 +1,85 @@ +extern Vtx reserve_shadow_v[]; +extern Gfx reserve_shadow_model[]; +extern Vtx obj_attention_shadow_v[]; +extern Gfx obj_attention_shadowT_model[]; + +u8 aRSV_shadow_vtx_fix_flg_table[] = {TRUE, FALSE, FALSE, TRUE}; + +bIT_ShadowData_c aRSV_shadow_data = { + 4, aRSV_shadow_vtx_fix_flg_table, 60.0f, reserve_shadow_v, reserve_shadow_model, +}; + +bIT_ShadowData_c aRSV_kappa_shadow_data = { + 4, aRSV_shadow_vtx_fix_flg_table, 60.0f, obj_attention_shadow_v, obj_attention_shadowT_model, +}; + +static void aRSV_set_bgOffset(ACTOR*, int) {} + +static void aRSV_set_talk_info(ACTOR* actor) { + RESERVE_ACTOR* reserve = (RESERVE_ACTOR*)actor; + u8 str[8]; + int item; + u8 str2[8]; + rgba_t window_color; + + if (reserve->structure_class.arg0 == 0x42) { + mDemo_Set_msg_num(0x2B42); + } else { + if (reserve->structure_class.arg0 >= 6 && reserve->structure_class.arg0 <= 8) { + mIN_copy_name_str(str, Save_Get(fruit)); + item = mIN_get_item_article(Save_Get(fruit)); + mMsg_Set_free_str_art(mMsg_Get_base_window_p(), 0, str, 16, item); + mNpc_GetActorWorldName(str2, SP_NPC_SHOP_MASTER); + mMsg_Set_free_str(mMsg_Get_base_window_p(), 1, str2, 8); + } + mDemo_Set_msg_num(reserve->structure_class.arg0 + 0x2B2D); + } + mDemo_Set_talk_display_name(FALSE); + mDemo_Set_camera(TRUE); + mPlib_Set_able_hand_all_item_in_demo(TRUE); + mDemo_Set_ListenAble(); + window_color.r = 145; + window_color.g = 60; + window_color.b = 40; + window_color.a = 255; + + mDemo_Set_talk_window_color(&window_color); +} + +static void aRSV_wait(STRUCTURE_ACTOR* actor, GAME_PLAY* play) { + PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play); + int angle; + + if (mDemo_Check(mDemo_TYPE_TALK, &actor->actor_class) != 1 && player != NULL) { + if (player->actor_class.world.position.z >= actor->actor_class.world.position.z) { + angle = ABS(actor->actor_class.player_angle_y); + + if (angle < 0x2000) { + mDemo_Request(mDemo_TYPE_TALK, &actor->actor_class, aRSV_set_talk_info); + } + } + } +} + +static void aRSV_setup_action(ACTOR* actor, int type) { + static aSTR_MOVE_PROC process[] = { + aRSV_wait, + }; + RESERVE_ACTOR* reserve = (RESERVE_ACTOR*)actor; + + reserve->structure_class.action_proc = process[type]; + reserve->structure_class.action = type; +} + +static void aRSV_actor_move(ACTOR* actor, GAME* game) { + STRUCTURE_ACTOR* structure = (STRUCTURE_ACTOR*)actor; + GAME_PLAY* play = (GAME_PLAY*)game; + + structure->action_proc(structure, play); +} + +static void aRSV_actor_init(ACTOR* actor, GAME* game) { + mFI_SetFG_common(DUMMY_RESERVE, actor->home.position, 0); + aRSV_actor_move(actor, game); + actor->mv_proc = aRSV_actor_move; +}