diff --git a/configure.py b/configure.py index e1095f8f..647cdaa8 100644 --- a/configure.py +++ b/configure.py @@ -1078,7 +1078,7 @@ config.libs = [ Object(Matching, "actor/ac_train_door.c"), Object(Matching, "actor/ac_train_window.c"), Object(Matching, "actor/ac_tukimi.c"), - Object(NonMatching, "actor/ac_tunahiki_control.c"), + Object(Matching, "actor/ac_tunahiki_control.c"), Object(Matching, "actor/ac_turi.c"), Object(Matching, "actor/ac_uki.c"), Object(Matching, "actor/ac_weather.c"), diff --git a/include/ac_tunahiki_control.h b/include/ac_tunahiki_control.h index 38896f35..1124e2ad 100644 --- a/include/ac_tunahiki_control.h +++ b/include/ac_tunahiki_control.h @@ -8,6 +8,49 @@ extern "C" { #endif +#define aTNC_FLAG_NPC_DELETE0 (1 << 0) +#define aTNC_FLAG_NPC_DELETE1 (1 << 1) +#define aTNC_FLAG_NPC_DELETE2 (1 << 2) +#define aTNC_FLAG_NPC_DELETE3 (1 << 3) +#define aTNC_FLAG_NPC_DELETE4 (1 << 4) +#define aTNC_FLAG_NPC_TALK0 (1 << 5) +#define aTNC_FLAG_NPC_TALK1 (1 << 6) +#define aTNC_FLAG_NPC_TALK2 (1 << 7) +#define aTNC_FLAG_NPC_TALK3 (1 << 8) +#define aTNC_FLAG_NPC_TALK4 (1 << 9) +#define aTNC_FLAG_NPC_TALK_ALL (aTNC_FLAG_NPC_TALK0 | aTNC_FLAG_NPC_TALK1 | aTNC_FLAG_NPC_TALK2 | aTNC_FLAG_NPC_TALK3 | aTNC_FLAG_NPC_TALK4) + +#define aTNC_FLAG_SHAKE (1 << 15) + +enum { + aTNC_NPC_STATE0, + aTNC_NPC_STATE1, + aTNC_NPC_STATE2, + + aTNC_NPC_STATE_NUM +}; + +typedef struct tunahiki_event_s { + f32 rope; + f32 rope_base; + f32 speed; + f32 next_speed; + s16 npc_state; + u16 flag; + s16 _14; + u16 counter; +} aEv_tunahiki_c; + +typedef struct tunahiki_control_actor_s TUNAHIKI_CONTROL_ACTOR; + +typedef void (*aTNC_PROC)(TUNAHIKI_CONTROL_ACTOR* actor, GAME_PLAY* play); + +struct tunahiki_control_actor_s { + ACTOR actor_class; + aTNC_PROC act_proc; + int action; +}; + extern ACTOR_PROFILE Tunahiki_Control_Profile; #ifdef __cplusplus @@ -15,4 +58,3 @@ extern ACTOR_PROFILE Tunahiki_Control_Profile; #endif #endif - diff --git a/include/m_soncho.h b/include/m_soncho.h index 7128f916..0509e3f6 100644 --- a/include/m_soncho.h +++ b/include/m_soncho.h @@ -130,7 +130,7 @@ extern void mSC_get_event_name_str(u8* buf, int buf_len, int soncho_event); extern void mSC_event_name_set(u8 soncho_event); extern void mSC_set_free_str_number(int free_str_no, u32 num); extern int mSC_Radio_Set_Talk_Proc(TAISOU_NPC0_ACTOR* taisou_actor); -extern mSC_Radio_Talk_Proc(TAISOU_NPC0_ACTOR* taisou_actor, GAME_PLAY* play); +extern void mSC_Radio_Talk_Proc(TAISOU_NPC0_ACTOR* taisou_actor, GAME_PLAY* play); extern int mSC_LightHouse_get_period(lbRTC_time_c* time); extern int mSC_LightHouse_day(const lbRTC_time_c* time); extern int mSC_LightHouse_Event_Check(int player_no); diff --git a/src/actor/ac_tunahiki_control.c b/src/actor/ac_tunahiki_control.c new file mode 100644 index 00000000..faec87b5 --- /dev/null +++ b/src/actor/ac_tunahiki_control.c @@ -0,0 +1,106 @@ +#include "ac_tunahiki_control.h" + +#include "m_actor.h" +#include "m_event.h" +#include "m_name_table.h" +#include "m_play.h" + +enum { + aTNC_ACT_WAIT, + + aTNC_ACT_NUM +}; + +static void aTNC_actor_ct(ACTOR* actorx, GAME* game); +static void aTNC_actor_dt(ACTOR* actorx, GAME* game); +static void aTNC_actor_move(ACTOR* actorx, GAME* game); + + +// clang-format off +ACTOR_PROFILE Tunahiki_Control_Profile = { + mAc_PROFILE_TUNAHIKI_CONTROL, + ACTOR_PART_CONTROL, + ACTOR_STATE_NO_MOVE_WHILE_CULLED, + EMPTY_NO, + ACTOR_OBJ_BANK_KEEP, + sizeof(TUNAHIKI_CONTROL_ACTOR), + aTNC_actor_ct, + aTNC_actor_dt, + aTNC_actor_move, + mActor_NONE_PROC1, + NULL, +}; +// clang-format on + +static void aTNC_setupAction(TUNAHIKI_CONTROL_ACTOR* actor, int action); + +static void aTNC_actor_ct(ACTOR* actorx, GAME* game) { + TUNAHIKI_CONTROL_ACTOR* actor = (TUNAHIKI_CONTROL_ACTOR*)actorx; + aEv_tunahiki_c* tunahiki = (aEv_tunahiki_c*)mEv_get_save_area(mEv_EVENT_SPORTS_FAIR_TUG_OF_WAR, 9); + + aTNC_setupAction(actor, aTNC_ACT_WAIT); + if (tunahiki == NULL) { + tunahiki = (aEv_tunahiki_c*)mEv_reserve_save_area(mEv_EVENT_SPORTS_FAIR_TUG_OF_WAR, 9); + if (tunahiki != NULL) { + tunahiki->rope = 0.0f; + tunahiki->rope_base = 0.0f; + tunahiki->flag = 0; + tunahiki->npc_state = aTNC_NPC_STATE0; + tunahiki->_14 = 0; + } + } +} + +static void aTNC_actor_dt(ACTOR* actorx, GAME* game) { + mEv_actor_dying_message(mEv_EVENT_SPORTS_FAIR_TUG_OF_WAR, actorx); +} + +static void aTNC_actor_move(ACTOR* actorx, GAME* game) { + TUNAHIKI_CONTROL_ACTOR* actor = (TUNAHIKI_CONTROL_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + + actor->act_proc(actor, play); +} + +static void aTNC_wait(TUNAHIKI_CONTROL_ACTOR* actor, GAME_PLAY* play) { + aEv_tunahiki_c* tunahiki = (aEv_tunahiki_c*)mEv_get_save_area(mEv_EVENT_SPORTS_FAIR_TUG_OF_WAR, 9); + f32 shake = 0.0f; + + if (tunahiki->flag & aTNC_FLAG_SHAKE) { + if (play->game_frame & 1) { + shake = 0.3f; + } else { + shake = -0.3f; + } + + if ((tunahiki->flag & aTNC_FLAG_NPC_TALK_ALL) == 0) { + tunahiki->rope_base += tunahiki->speed * 0.025f; + if (tunahiki->rope_base < -10.0f) { + tunahiki->rope_base = -10.0f; + tunahiki->speed = 0.0f; + } else if (tunahiki->rope_base > 10.0f) { + tunahiki->rope_base = 10.0f; + tunahiki->speed = 0.0f; + } + } + } + + { + f32 rope = tunahiki->rope_base + shake; + aEv_tunahiki_c* _tunahiki = (aEv_tunahiki_c*)mEv_get_save_area(mEv_EVENT_SPORTS_FAIR_TUG_OF_WAR, 9); + + _tunahiki->rope = rope; + } + + tunahiki->counter++; + if (tunahiki->counter >= 65) { + tunahiki->counter = 2; + } +} + +static void aTNC_setupAction(TUNAHIKI_CONTROL_ACTOR* actor, int action) { + static aTNC_PROC process[] = { aTNC_wait }; + + actor->action = action; + actor->act_proc = process[action]; +} diff --git a/src/game/m_soncho.c b/src/game/m_soncho.c index 9ce5e58d..61727bc1 100644 --- a/src/game/m_soncho.c +++ b/src/game/m_soncho.c @@ -825,7 +825,7 @@ static void mSCR_talk_next(TAISOU_NPC0_ACTOR* taisou_actor, GAME_PLAY* play) { typedef void (*mSCR_TALK_PROC)(TAISOU_NPC0_ACTOR*, GAME_PLAY*); -extern mSC_Radio_Talk_Proc(TAISOU_NPC0_ACTOR* taisou_actor, GAME_PLAY* play) { +extern void mSC_Radio_Talk_Proc(TAISOU_NPC0_ACTOR* taisou_actor, GAME_PLAY* play) { static mSCR_TALK_PROC proc[mSCR_TALK_NUM] = { &mSCR_talk_pickup_all, &mSCR_talk_inspection, &mSCR_talk_next,