mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-23 06:34:18 -04:00
Implement & link ac_ev_turkey
This commit is contained in:
+1
-1
@@ -1179,7 +1179,7 @@ config.libs = [
|
||||
Object(Matching, "actor/npc/event/ac_ev_soncho.c"),
|
||||
Object(Matching, "actor/npc/event/ac_ev_soncho2.c"),
|
||||
Object(Matching, "actor/npc/event/ac_ev_speech_soncho.c"),
|
||||
Object(NonMatching, "actor/npc/event/ac_ev_turkey.c"),
|
||||
Object(Matching, "actor/npc/event/ac_ev_turkey.c"),
|
||||
Object(NonMatching, "actor/npc/event/ac_ev_yomise.c"),
|
||||
],
|
||||
),
|
||||
|
||||
+35
-1
@@ -3,11 +3,46 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "m_actor.h"
|
||||
#include "ac_npc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
PersonalID_c pid;
|
||||
u16 given_present_bitfield;
|
||||
} aEv_turkey_save_c;
|
||||
|
||||
typedef struct {
|
||||
u8 _00;
|
||||
u8 _01;
|
||||
u8 _02;
|
||||
} aEv_turkey_common_c;
|
||||
|
||||
typedef struct ev_turkey_actor_s EV_TURKEY_ACTOR;
|
||||
|
||||
typedef void (*aETKY_ACT_PROC)(EV_TURKEY_ACTOR* turkey);
|
||||
typedef void (*aETKY_TALK_PROC)(EV_TURKEY_ACTOR* turkey, GAME_PLAY* play);
|
||||
typedef void (*aETKY_TALK_SETUP_STATUS_PROC)(EV_TURKEY_ACTOR* turkey, GAME_PLAY* play, int talk_act);
|
||||
|
||||
struct ev_turkey_actor_s {
|
||||
NPC_ACTOR npc_class;
|
||||
int talk_action;
|
||||
aETKY_TALK_PROC talk_proc;
|
||||
aETKY_TALK_SETUP_STATUS_PROC talk_setup_proc;
|
||||
int talk_msg_no;
|
||||
int next_talk_action;
|
||||
aEv_turkey_save_c* ev_save_p;
|
||||
aEv_turkey_common_c* ev_common_p;
|
||||
u8 present_idx;
|
||||
u8 _9B1;
|
||||
aETKY_ACT_PROC act_proc;
|
||||
int action;
|
||||
int _9BC;
|
||||
xyz_t _9C0;
|
||||
};
|
||||
|
||||
extern ACTOR_PROFILE Ev_Turkey_Profile;
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -15,4 +50,3 @@ extern ACTOR_PROFILE Ev_Turkey_Profile;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -26,6 +26,9 @@ extern "C" {
|
||||
#define aNPC_SPNPC_BIT_SET(field, bit) ((field) |= (1 << (bit)))
|
||||
#define aNPC_SPNPC_BIT_CLR(field, bit) ((field) &= ~(1 << (bit)))
|
||||
|
||||
// To use this enum, make sure that m_common_data.h is included!
|
||||
#define NPC_CLIP CLIP(npc_clip)
|
||||
|
||||
enum {
|
||||
aNPC_JOINT_BASE_ROOT,
|
||||
aNPC_JOINT_BASE,
|
||||
|
||||
+55
-2
@@ -2475,7 +2475,55 @@ extern int mNT_check_unknown(mActor_name_t item_no);
|
||||
|
||||
#define FTR_SPRING_MEDAL 0x32A8
|
||||
#define FTR_AUTUMN_MEDAL 0x32AC
|
||||
|
||||
#define FTR_TUMBLEWEED 0x32B0
|
||||
#define FTR_COW_SKULL 0x32B4
|
||||
#define FTR_OIL_DRUM 0x32B8
|
||||
#define FTR_SADDLE_FENCE 0x32BC
|
||||
#define FTR_WESTERN_FENCE 0x32C0
|
||||
#define FTR_WATERING_TROUGH 0x32C4
|
||||
#define FTR_LUIGI_TROPHY 0x32C8
|
||||
#define FTR_MARIO_TROPHY 0x32CC
|
||||
#define FTR_HARVEST_LAMP 0x32D0
|
||||
#define FTR_COVERED_WAGON 0x32D4
|
||||
#define FTR_STOREFRONT 0x32D8
|
||||
#define FTR_PICNIC_TABLE 0x32DC
|
||||
#define FTR_HARVEST_TABLE 0x32E0
|
||||
#define FTR_HARVEST_TV 0x32E4
|
||||
#define FTR_HARVEST_BED 0x32E8
|
||||
#define FTR_HARVEST_CHAIR 0x32EC
|
||||
#define FTR_HARVEST_CLOCK 0x32F0
|
||||
#define FTR_HARVEST_SOFA 0x32F4
|
||||
#define FTR_GREEN_PIPE 0x32F8
|
||||
#define FTR_BRICK_BLOCK 0x32FC
|
||||
#define FTR_HARVEST_BUREAU 0x3300
|
||||
#define FTR_FLAGPOLE 0x3304
|
||||
#define FTR_HARVEST_DRESSER 0x3308
|
||||
#define FTR_SUPER_MUSHROOM 0x330C
|
||||
#define FTR_HARVEST_MIRROR 0x3310
|
||||
#define FTR_COIN 0x3314
|
||||
#define FTR_Q_BLOCK 0x3318
|
||||
#define FTR_STARMAN 0x331C
|
||||
#define FTR_KOOPA_SHELL 0x3320
|
||||
#define FTR_CANNON 0x3324
|
||||
#define FTR_DESERT_CACTUS 0x3328
|
||||
#define FTR_FIRE_FLOWER 0x332C
|
||||
#define FTR_WAGON_WHEEL 0x3330
|
||||
#define FTR_WELL 0x3334
|
||||
#define FTR_BOXING_BARRICADE 0x3338
|
||||
#define FTR_NEUTRAL_CORNER 0x333C
|
||||
#define FTR_RED_CORNER 0x3340
|
||||
#define FTR_BLUE_CORNER 0x3344
|
||||
#define FTR_BOXING_MAT 0x3348
|
||||
#define FTR_RINGSIDE_TABLE 0x334C
|
||||
#define FTR_SPEED_BAG 0x3350
|
||||
#define FTR_SANDBAG 0x3354
|
||||
#define FTR_WEIGHT_BENCH 0x3358
|
||||
#define FTR_CAMPFIRE 0x335C
|
||||
#define FTR_BONFIRE 0x3360
|
||||
#define FTR_KAYAK 0x3364
|
||||
#define FTR_SPRINKLER 0x3368
|
||||
#define FTR_TENT_MODEL 0x336C
|
||||
#define FTR_BACKPACK 0x3370
|
||||
#define FTR_ANGLER_TROPHY 0x3374
|
||||
#define FTR_PANSY_MODEL1 0x3378
|
||||
#define FTR_PANSY_MODEL2 0x337C
|
||||
@@ -2486,7 +2534,12 @@ extern int mNT_check_unknown(mActor_name_t item_no);
|
||||
#define FTR_TULIP_MODEL1 0x3390
|
||||
#define FTR_TULIP_MODEL2 0x3394
|
||||
#define FTR_TULIP_MODEL3 0x3398
|
||||
|
||||
#define FTR_LANTERN 0x339C
|
||||
#define FTR_LAWN_MOWER 0x33A0
|
||||
#define FTR_COOLER 0x33A4
|
||||
#define FTR_MOUNTAIN_BIKE 0x33A8
|
||||
#define FTR_SLEEPING_BAG 0x33AC
|
||||
#define FTR_PROPANE_STOVE 0x33B0
|
||||
#define FTR_CORNUCOPIA 0x33B4
|
||||
#define FTR_JUDGES_BELL 0x33B8
|
||||
#define FTR_NOISEMAKER 0x33BC
|
||||
|
||||
@@ -0,0 +1,564 @@
|
||||
#include "ac_ev_turkey.h"
|
||||
|
||||
#include "m_common_data.h"
|
||||
#include "m_msg.h"
|
||||
#include "m_player_lib.h"
|
||||
#include "libultra/libultra.h"
|
||||
|
||||
#define aETKY_PRESENT_NUM 12
|
||||
#define aETKY_ALL_BITS ((1 << aETKY_PRESENT_NUM) - 1)
|
||||
|
||||
enum {
|
||||
aETKY_ACTION_WAIT,
|
||||
aETKY_ACTION_KYORO,
|
||||
|
||||
aETKY_ACTION_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aETKY_TALK_WAIT_END,
|
||||
aETKY_TALK_EXPLAIN_ENV0,
|
||||
aETKY_TALK_EXPLAIN_ENV1,
|
||||
aETKY_TALK_EXPLAIN_ENV2,
|
||||
aETKY_TALK_EXPLAIN_ENV3,
|
||||
aETKY_TALK_FIND_REAC,
|
||||
aETKY_TALK_GIVE_ME_FORK,
|
||||
aETKY_TALK_GIVE_YOU_PRESENT,
|
||||
|
||||
aETKY_TALK_NUM
|
||||
};
|
||||
|
||||
static void aETKY_actor_ct(ACTOR* actorx, GAME* game);
|
||||
static void aETKY_actor_dt(ACTOR* actorx, GAME* game);
|
||||
static void aETKY_actor_init(ACTOR* actorx, GAME* game);
|
||||
static void aETKY_actor_save(ACTOR* actorx, GAME* game);
|
||||
static void aETKY_actor_move(ACTOR* actorx, GAME* game);
|
||||
static void aETKY_actor_draw(ACTOR* actorx, GAME* game);
|
||||
|
||||
ACTOR_PROFILE Ev_Turkey_Profile = {
|
||||
// clang-format off
|
||||
mAc_PROFILE_EV_TURKEY,
|
||||
ACTOR_PART_NPC,
|
||||
ACTOR_STATE_NONE,
|
||||
SP_NPC_TURKEY,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(EV_TURKEY_ACTOR),
|
||||
aETKY_actor_ct,
|
||||
aETKY_actor_dt,
|
||||
aETKY_actor_init,
|
||||
mActor_NONE_PROC1,
|
||||
aETKY_actor_save,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static const mActor_name_t aETKY_present_table[] = {
|
||||
// clang-format off
|
||||
FTR_HARVEST_LAMP,
|
||||
FTR_HARVEST_TABLE,
|
||||
FTR_HARVEST_TV,
|
||||
FTR_HARVEST_BED,
|
||||
FTR_HARVEST_CHAIR,
|
||||
FTR_HARVEST_CLOCK,
|
||||
FTR_HARVEST_SOFA,
|
||||
FTR_HARVEST_BUREAU,
|
||||
FTR_HARVEST_DRESSER,
|
||||
FTR_HARVEST_MIRROR,
|
||||
ITM_CARPET66,
|
||||
ITM_WALL66,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int aETKY_DecidePresent(u16* given_bitfield) {
|
||||
int dont_have_count = 0;
|
||||
int check_count = 0;
|
||||
int selected;
|
||||
int i;
|
||||
|
||||
if ((*given_bitfield & aETKY_ALL_BITS) == aETKY_ALL_BITS) {
|
||||
*given_bitfield = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < aETKY_PRESENT_NUM; i++) {
|
||||
if (((*given_bitfield >> i) & 1) == 0) {
|
||||
dont_have_count++;
|
||||
}
|
||||
}
|
||||
|
||||
selected = RANDOM(dont_have_count);
|
||||
for (i = 0; i < aETKY_PRESENT_NUM; i++) {
|
||||
if (((*given_bitfield >> i) & 1) == 0) {
|
||||
if (check_count == selected) {
|
||||
return i;
|
||||
}
|
||||
|
||||
check_count++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void aETKY_ReportPresent(u16* given_bitfield, int idx) {
|
||||
if (given_bitfield != NULL) {
|
||||
*given_bitfield |= (u16)(1 << idx);
|
||||
}
|
||||
}
|
||||
|
||||
static void aETKY_ActionWait(EV_TURKEY_ACTOR* turkey) {
|
||||
if (turkey->npc_class.draw.main_animation_state == cKF_STATE_CONTINUE) {
|
||||
if (turkey->npc_class.draw.loop_flag == FALSE) {
|
||||
turkey->npc_class.action.step = aNPC_ACTION_END_STEP;
|
||||
} else {
|
||||
turkey->npc_class.draw.loop_flag--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aETKY_ActionKyoro(EV_TURKEY_ACTOR* turkey) {
|
||||
if (turkey->npc_class.draw.main_animation_state == cKF_STATE_CONTINUE) {
|
||||
if (turkey->npc_class.draw.loop_flag == FALSE) {
|
||||
turkey->npc_class.action.step = aNPC_ACTION_END_STEP;
|
||||
} else {
|
||||
turkey->npc_class.draw.loop_flag--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aETKY_setupAction(EV_TURKEY_ACTOR* turkey, int action) {
|
||||
static aETKY_ACT_PROC process[] = { aETKY_ActionWait, aETKY_ActionKyoro };
|
||||
static int animeSeqNo[] = { aNPC_ANIM_WAIT1, aNPC_ANIM_TKYKYORO1 };
|
||||
|
||||
turkey->npc_class.action.step = 0;
|
||||
turkey->action = action;
|
||||
turkey->act_proc = process[action];
|
||||
|
||||
if (action == aETKY_ACTION_WAIT) {
|
||||
turkey->npc_class.draw.loop_flag = RANDOM(2);
|
||||
} else {
|
||||
turkey->npc_class.draw.loop_flag = RANDOM(2);
|
||||
}
|
||||
|
||||
NPC_CLIP->animation_init_proc((ACTOR*)turkey, animeSeqNo[action], FALSE);
|
||||
}
|
||||
|
||||
static void aETKY_act_chg_data_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
nactorx->action.act_obj = aNPC_ACT_OBJ_PLAYER;
|
||||
}
|
||||
|
||||
static void aETKY_act_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
EV_TURKEY_ACTOR* turkey = (EV_TURKEY_ACTOR*)nactorx;
|
||||
|
||||
if (turkey->_9B1 == 1) {
|
||||
aETKY_setupAction(turkey, aETKY_ACTION_WAIT);
|
||||
} else {
|
||||
aETKY_setupAction(turkey, aETKY_ACTION_KYORO);
|
||||
}
|
||||
}
|
||||
|
||||
static void aETKY_act_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
EV_TURKEY_ACTOR* turkey = (EV_TURKEY_ACTOR*)nactorx;
|
||||
|
||||
(*turkey->act_proc)(turkey);
|
||||
}
|
||||
|
||||
static void aETKY_act_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
static aNPC_SUB_PROC act_proc[] = {
|
||||
// clang-format off
|
||||
aETKY_act_init_proc,
|
||||
aETKY_act_chg_data_proc,
|
||||
aETKY_act_main_proc,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
(*act_proc[proc_type])(nactorx, play);
|
||||
}
|
||||
|
||||
static void aETKY_set_request_act(NPC_ACTOR* nactorx) {
|
||||
nactorx->request.act_priority = 4;
|
||||
nactorx->request.act_idx = aNPC_ACT_SPECIAL;
|
||||
nactorx->request.act_type = aNPC_ACT_TYPE_SEARCH;
|
||||
}
|
||||
|
||||
static void aETKY_think_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
nactorx->think.interrupt_flags = 0;
|
||||
nactorx->action.act_proc = aETKY_act_proc;
|
||||
aETKY_set_request_act(nactorx);
|
||||
}
|
||||
|
||||
static void aETKY_think_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
EV_TURKEY_ACTOR* turkey = (EV_TURKEY_ACTOR*)nactorx;
|
||||
|
||||
if (nactorx->action.step == aNPC_ACTION_END_STEP) {
|
||||
switch (nactorx->action.idx) {
|
||||
case aNPC_ACT_SPECIAL:
|
||||
if (turkey->_9BC != -1) {
|
||||
aETKY_setupAction(turkey, turkey->_9BC);
|
||||
turkey->_9BC = -1;
|
||||
} else if (turkey->_9B1 == 1) {
|
||||
aETKY_setupAction(turkey, aETKY_ACTION_WAIT);
|
||||
} else {
|
||||
aETKY_setupAction(turkey, (turkey->action + 1) & 1);
|
||||
}
|
||||
|
||||
nactorx->condition_info.demo_flg = aNPC_COND_DEMO_SKIP_HEAD_LOOKAT;
|
||||
nactorx->collision.check_kind = aNPC_BG_CHECK_TYPE_ONLY_GROUND;
|
||||
|
||||
if (turkey->_9C0.x != nactorx->actor_class.world.position.x) {
|
||||
add_calc(&turkey->_9C0.x, nactorx->actor_class.world.position.x, 1.0f - sqrtf(0.7f), 0.25f, 0.05f);
|
||||
} else if (turkey->_9C0.y != nactorx->actor_class.world.position.y) {
|
||||
add_calc(&turkey->_9C0.y, nactorx->actor_class.world.position.y, 1.0f - sqrtf(0.7f), 0.25f, 0.05f);
|
||||
} else if (turkey->_9C0.z != nactorx->actor_class.world.position.z) {
|
||||
add_calc(&turkey->_9C0.z, nactorx->actor_class.world.position.z, 1.0f - sqrtf(0.7f), 0.25f, 0.05f);
|
||||
}
|
||||
|
||||
break;
|
||||
case aNPC_ACT_TALK:
|
||||
nactorx->condition_info.demo_flg = aNPC_COND_DEMO_SKIP_HEAD_LOOKAT;
|
||||
nactorx->movement.mv_angl = 0;
|
||||
aETKY_set_request_act(nactorx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aETKY_think_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
static aNPC_SUB_PROC think_proc[] = { aETKY_think_init_proc, aETKY_think_main_proc };
|
||||
|
||||
(*think_proc[proc_type & 1])(nactorx, play);
|
||||
}
|
||||
|
||||
static void aETKY_schedule_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
EV_TURKEY_ACTOR* turkey = (EV_TURKEY_ACTOR*)nactorx;
|
||||
|
||||
nactorx->think.think_proc = aETKY_think_proc;
|
||||
nactorx->condition_info.hide_request = FALSE;
|
||||
nactorx->palActorIgnoreTimer = -1;
|
||||
nactorx->talk_info.default_animation = aNPC_ANIM_WAIT1;
|
||||
turkey->_9BC = -1;
|
||||
NPC_CLIP->think_proc(nactorx, play, aNPC_THINK_SPECIAL, aNPC_THINK_TYPE_INIT);
|
||||
}
|
||||
|
||||
static void aETKY_schedule_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
|
||||
if (NPC_CLIP->think_proc(nactorx, play, -1, aNPC_THINK_TYPE_CHK_INTERRUPT) == FALSE) {
|
||||
NPC_CLIP->think_proc(nactorx, play, -1, aNPC_THINK_TYPE_MAIN);
|
||||
}
|
||||
}
|
||||
|
||||
static void aETKY_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int proc_type) {
|
||||
static aNPC_SUB_PROC sche_proc[] = { aETKY_schedule_init_proc, aETKY_schedule_main_proc };
|
||||
|
||||
(*sche_proc[proc_type & 1])(nactorx, play);
|
||||
}
|
||||
|
||||
static void aETKY_SetupSaveData(ACTOR* actorx) {
|
||||
EV_TURKEY_ACTOR* turkey = (EV_TURKEY_ACTOR*)actorx;
|
||||
aEv_turkey_save_c* save_p = (aEv_turkey_save_c*)mEv_get_save_area(mEv_EVENT_HARVEST_FESTIVAL_FRANKLIN, 0);
|
||||
|
||||
if (save_p == NULL) {
|
||||
save_p = (aEv_turkey_save_c*)mEv_reserve_save_area(mEv_EVENT_HARVEST_FESTIVAL_FRANKLIN, 0);
|
||||
bzero(save_p, sizeof(aEv_turkey_save_c));
|
||||
mPr_ClearPersonalID(&save_p->pid);
|
||||
turkey->ev_save_p = save_p;
|
||||
} else {
|
||||
turkey->ev_save_p = save_p;
|
||||
}
|
||||
}
|
||||
|
||||
static void aETKY_SetupCommonData(ACTOR* actorx) {
|
||||
EV_TURKEY_ACTOR* turkey = (EV_TURKEY_ACTOR*)actorx;
|
||||
aEv_turkey_common_c* common_p = (aEv_turkey_common_c*)mEv_get_common_area(mEv_EVENT_HARVEST_FESTIVAL_FRANKLIN, 0);
|
||||
|
||||
if (common_p == NULL) {
|
||||
common_p = (aEv_turkey_common_c*)mEv_reserve_common_area(mEv_EVENT_HARVEST_FESTIVAL_FRANKLIN, 0);
|
||||
turkey->ev_common_p = common_p;
|
||||
common_p->_01 = 0;
|
||||
common_p->_02 = 0;
|
||||
common_p->_00 = 0;
|
||||
} else {
|
||||
turkey->ev_common_p = common_p;
|
||||
}
|
||||
}
|
||||
|
||||
static void aETKY_TalkRequest(ACTOR* actorx, GAME* game);
|
||||
static int aETKY_TalkInit(ACTOR* actorx, GAME* game);
|
||||
static int aETKY_TalkEndCheck(ACTOR* actorx, GAME* game);
|
||||
|
||||
static void aETKY_SetupTalkStat(EV_TURKEY_ACTOR* turkey, GAME_PLAY* play, int talk_action);
|
||||
|
||||
static void aETKY_actor_ct(ACTOR* actorx, GAME* game) {
|
||||
static aNPC_ct_data_c ct_data = {
|
||||
// clang-format off
|
||||
aETKY_actor_move,
|
||||
aETKY_actor_draw,
|
||||
aNPC_CT_SCHED_TYPE_SPECIAL,
|
||||
aETKY_TalkRequest,
|
||||
aETKY_TalkInit,
|
||||
aETKY_TalkEndCheck,
|
||||
0,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
EV_TURKEY_ACTOR* turkey = (EV_TURKEY_ACTOR*)actorx;
|
||||
|
||||
if (NPC_CLIP->birth_check_proc(actorx, game) == TRUE) {
|
||||
turkey->npc_class.schedule.schedule_proc = aETKY_schedule_proc;
|
||||
NPC_CLIP->ct_proc(actorx, game, &ct_data);
|
||||
turkey->talk_setup_proc = aETKY_SetupTalkStat;
|
||||
aETKY_SetupSaveData(actorx);
|
||||
aETKY_SetupCommonData(actorx);
|
||||
turkey->present_idx = aETKY_DecidePresent(&turkey->ev_save_p->given_present_bitfield);
|
||||
turkey->npc_class.actor_class.status_data.weight = MASSTYPE_HEAVY;
|
||||
}
|
||||
|
||||
turkey->_9C0 = turkey->npc_class.actor_class.world.position;
|
||||
}
|
||||
|
||||
static void aETKY_Give_Me_Fork_Init(EV_TURKEY_ACTOR* turkey, GAME_PLAY* play) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
static void aETKY_Give_You_Present_Init(EV_TURKEY_ACTOR* turkey, GAME_PLAY* play) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
typedef void (*aETKY_TALK_INIT_PROC)(EV_TURKEY_ACTOR* turkey, GAME_PLAY* play);
|
||||
|
||||
static void aETKY_init_proc(EV_TURKEY_ACTOR* turkey, GAME_PLAY* play, int talk_act) {
|
||||
static aETKY_TALK_INIT_PROC init_proc[] = {
|
||||
// clang-format off
|
||||
(aETKY_TALK_INIT_PROC)none_proc1,
|
||||
(aETKY_TALK_INIT_PROC)none_proc1,
|
||||
(aETKY_TALK_INIT_PROC)none_proc1,
|
||||
(aETKY_TALK_INIT_PROC)none_proc1,
|
||||
(aETKY_TALK_INIT_PROC)none_proc1,
|
||||
(aETKY_TALK_INIT_PROC)none_proc1,
|
||||
aETKY_Give_Me_Fork_Init,
|
||||
aETKY_Give_You_Present_Init,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
(*init_proc[talk_act])(turkey, play);
|
||||
}
|
||||
|
||||
static void aETKY_DeleteKnifeInPlayerBag(void) {
|
||||
int idx = mPr_GetPossessionItemIdxWithCond(Now_Private, ITM_KNIFE_AND_FORK, mPr_ITEM_COND_NORMAL);
|
||||
|
||||
if (idx != -1) {
|
||||
mPr_SetPossessionItem(Now_Private, idx, EMPTY_NO, mPr_ITEM_COND_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
static void aETKY_SetKnifeForkSequence(EV_TURKEY_ACTOR* turkey, GAME_PLAY* play) {
|
||||
int item_idx = mPr_GetPossessionItemIdxWithCond(Now_Private, ITM_KNIFE_AND_FORK, mPr_ITEM_COND_NORMAL);
|
||||
u8 present_idx;
|
||||
mActor_name_t present;
|
||||
u8 item_name[mIN_ITEM_NAME_LEN];
|
||||
|
||||
if (item_idx == -1) {
|
||||
mMsg_SET_CONTINUE_MSG_NUM(0x3C02 + RANDOM(3));
|
||||
aETKY_SetupTalkStat(turkey, play, aETKY_TALK_WAIT_END);
|
||||
} else {
|
||||
present_idx = turkey->present_idx;
|
||||
present = aETKY_present_table[present_idx];
|
||||
mIN_copy_name_str(item_name, present);
|
||||
mMsg_SET_CONTINUE_MSG_NUM(0x3C11 + present_idx);
|
||||
mMsg_SET_ITEM_STR_ART(mMsg_ITEM_STR0, item_name, mIN_ITEM_NAME_LEN, present);
|
||||
aETKY_SetupTalkStat(turkey, play, aETKY_TALK_GIVE_ME_FORK);
|
||||
}
|
||||
}
|
||||
|
||||
static void aETKY_Explain_Env0123(EV_TURKEY_ACTOR* turkey, GAME_PLAY* play) {
|
||||
int talk_action = turkey->talk_action;
|
||||
int msg_no = mMsg_GET_MSG_NUM();
|
||||
|
||||
if (mMsg_CHECK_MAINNORMALCONTINUE() && msg_no == 0x3BFD + talk_action) {
|
||||
if (turkey->talk_action == aETKY_TALK_EXPLAIN_ENV3) {
|
||||
aETKY_SetKnifeForkSequence(turkey, play);
|
||||
} else {
|
||||
mMsg_SET_CONTINUE_MSG_NUM(0x3BFD + talk_action + 1);
|
||||
aETKY_SetupTalkStat(turkey, play, turkey->talk_action + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aETKY_Find_Reac(EV_TURKEY_ACTOR* turkey, GAME_PLAY* play) {
|
||||
if (mMsg_CHECK_MAINNORMALCONTINUE()) {
|
||||
aETKY_SetKnifeForkSequence(turkey, play);
|
||||
}
|
||||
}
|
||||
|
||||
static void aETKY_Give_Me_Fork(EV_TURKEY_ACTOR* turkey, GAME_PLAY* play) {
|
||||
int order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
|
||||
int msg_no = mMsg_GET_MSG_NUM(); // @unused
|
||||
|
||||
switch (order) {
|
||||
case 1:
|
||||
// Wait for give_type1 to succeed, and then move over to waiting for give to finish
|
||||
if (mPlib_request_main_give_type1((GAME*)play, ITM_KNIFE_AND_FORK, aHOI_REQUEST_PUTAWAY, FALSE, FALSE)) {
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 2);
|
||||
mMsg_SET_LOCKCONTINUE();
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 1, 3);
|
||||
aETKY_DeleteKnifeInPlayerBag();
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
// Wait for hand over item sequence to finish, then clear order
|
||||
if (CLIP(handOverItem_clip)->master_actor == NULL) {
|
||||
mMsg_UNSET_LOCKCONTINUE();
|
||||
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
|
||||
aETKY_SetupTalkStat(turkey, play, aETKY_TALK_GIVE_YOU_PRESENT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void aETKY_Give_You_Present(EV_TURKEY_ACTOR* turkey, GAME_PLAY* play) {
|
||||
int order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 1);
|
||||
|
||||
if (order == 2) {
|
||||
mActor_name_t present = aETKY_present_table[turkey->present_idx];
|
||||
|
||||
aNPC_DEMO_GIVE_ITEM(present, aHOI_REQUEST_PUTAWAY, FALSE);
|
||||
mPr_SetFreePossessionItem(Now_Private, present, mPr_ITEM_COND_NORMAL);
|
||||
aETKY_ReportPresent(&turkey->ev_save_p->given_present_bitfield, turkey->present_idx);
|
||||
aETKY_SetupTalkStat(turkey, play, aETKY_TALK_WAIT_END);
|
||||
}
|
||||
}
|
||||
|
||||
static void aETKY_SetupTalkStat(EV_TURKEY_ACTOR* turkey, GAME_PLAY* play, int talk_act) {
|
||||
static aETKY_TALK_PROC process[] = {
|
||||
// clang-format off
|
||||
(aETKY_TALK_PROC)none_proc1,
|
||||
aETKY_Explain_Env0123,
|
||||
aETKY_Explain_Env0123,
|
||||
aETKY_Explain_Env0123,
|
||||
aETKY_Explain_Env0123,
|
||||
aETKY_Find_Reac,
|
||||
aETKY_Give_Me_Fork,
|
||||
aETKY_Give_You_Present,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
turkey->talk_action = talk_act;
|
||||
turkey->talk_proc = process[talk_act];
|
||||
aETKY_init_proc(turkey, play, talk_act);
|
||||
}
|
||||
|
||||
static void aETKY_actor_save(ACTOR* actorx, GAME* game) {
|
||||
NPC_CLIP->save_proc(actorx, game);
|
||||
}
|
||||
|
||||
static void aETKY_actor_dt(ACTOR* actorx, GAME* game) {
|
||||
NPC_CLIP->dt_proc(actorx, game);
|
||||
mEv_actor_dying_message(mEv_EVENT_HARVEST_FESTIVAL_FRANKLIN, actorx);
|
||||
}
|
||||
|
||||
static void aETKY_actor_init(ACTOR* actorx, GAME* game) {
|
||||
NPC_CLIP->init_proc(actorx, game);
|
||||
}
|
||||
|
||||
static void aETKY_GetTalkStartStatus(int* msg_no, int* next_talk_act, ACTOR* actorx) {
|
||||
EV_TURKEY_ACTOR* turkey = (EV_TURKEY_ACTOR*)actorx;
|
||||
aEv_turkey_common_c* common_p = turkey->ev_common_p;
|
||||
|
||||
if (turkey->_9B1 == 1) {
|
||||
*msg_no = 0x3C1D + gamePT->frame_counter % 5;
|
||||
*next_talk_act = aETKY_TALK_WAIT_END;
|
||||
} else {
|
||||
*msg_no = 0x3BFE;
|
||||
*next_talk_act = aETKY_TALK_EXPLAIN_ENV0;
|
||||
|
||||
if (common_p != NULL && common_p->_00 != 0) {
|
||||
*msg_no = 0x3C05 + turkey->present_idx;
|
||||
*next_talk_act = aETKY_TALK_FIND_REAC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aETKY_SetTalkInfo(ACTOR* actorx) {
|
||||
EV_TURKEY_ACTOR* turkey = (EV_TURKEY_ACTOR*)actorx;
|
||||
int msg_no;
|
||||
int next_talk_act;
|
||||
|
||||
aETKY_GetTalkStartStatus(&msg_no, &next_talk_act, actorx);
|
||||
turkey->talk_msg_no = msg_no;
|
||||
turkey->next_talk_action = next_talk_act;
|
||||
mEv_set_status(mEv_EVENT_HARVEST_FESTIVAL_FRANKLIN, mEv_STATUS_TALK);
|
||||
mDemo_Set_msg_num(msg_no);
|
||||
turkey->ev_common_p->_00++;
|
||||
turkey->_9B1 = 1;
|
||||
}
|
||||
|
||||
static void aETKY_TalkRequest(ACTOR* actorx, GAME* game) {
|
||||
EV_TURKEY_ACTOR* turkey = (EV_TURKEY_ACTOR*)actorx;
|
||||
|
||||
if (turkey->_9B1 == 0) {
|
||||
ACTOR* playerx = GET_PLAYER_ACTOR_GAME_ACTOR(game);
|
||||
xyz_t delta;
|
||||
|
||||
delta.x = playerx->world.position.x - actorx->world.position.x;
|
||||
delta.y = ABS(playerx->world.position.y - actorx->world.position.y);
|
||||
delta.z = playerx->world.position.z - actorx->world.position.z;
|
||||
|
||||
if (delta.y <= 10.0f) {
|
||||
if (SQ(delta.x) + SQ(delta.z) <= SQ(55.0f)) {
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, actorx) == TRUE) {
|
||||
if (mDemo_Check_ListenAble() == FALSE) {
|
||||
mDemo_Set_ListenAble();
|
||||
turkey->_9B1 = 1;
|
||||
}
|
||||
} else {
|
||||
mDemo_Request(mDemo_TYPE_SPEAK, actorx, aETKY_SetTalkInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mDemo_Request(mDemo_TYPE_TALK, actorx, aETKY_SetTalkInfo);
|
||||
}
|
||||
}
|
||||
|
||||
static int aETKY_TalkInit(ACTOR* actorx, GAME* game) {
|
||||
EV_TURKEY_ACTOR* turkey = (EV_TURKEY_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
|
||||
(*turkey->talk_setup_proc)(turkey, play, turkey->next_talk_action);
|
||||
mDemo_Set_ListenAble();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int aETKY_TalkEndCheck(ACTOR* actorx, GAME* game) {
|
||||
EV_TURKEY_ACTOR* turkey = (EV_TURKEY_ACTOR*)actorx;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
|
||||
(*turkey->talk_proc)(turkey, play);
|
||||
|
||||
if (!mDemo_Check(mDemo_TYPE_TALK, actorx) && !mDemo_Check(mDemo_TYPE_SPEAK, actorx)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (mDemo_Check(mDemo_TYPE_SPEAK, actorx) == TRUE) {
|
||||
ACTOR* playerx = GET_PLAYER_ACTOR_GAME_ACTOR(game);
|
||||
s16 actor_look_angle = actorx->shape_info.rotation.y + DEG2SHORT_ANGLE2(180.0f);
|
||||
s_xyz pl_angle = playerx->shape_info.rotation;
|
||||
|
||||
if (actor_look_angle != pl_angle.y) {
|
||||
add_calc_short_angle2(&pl_angle.y, actor_look_angle, 0.2f, DEG2SHORT_ANGLE(22.5f), 0);
|
||||
GET_PLAYER_ACTOR_NOW()->Set_force_position_angle_proc(gamePT, NULL, &pl_angle, mPlayer_FORCE_POSITION_ANGLE_ROTY);
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void aETKY_actor_move(ACTOR* actorx, GAME* game) {
|
||||
EV_TURKEY_ACTOR* turkey = (EV_TURKEY_ACTOR*)actorx;
|
||||
ACTOR* playerx = GET_PLAYER_ACTOR_GAME_ACTOR(game); // @unused
|
||||
|
||||
turkey->npc_class.palActorIgnoreTimer = -1;
|
||||
NPC_CLIP->move_proc(actorx, game);
|
||||
turkey->npc_class.palActorIgnoreTimer = -1;
|
||||
}
|
||||
|
||||
static void aETKY_actor_draw(ACTOR* actorx, GAME* game) {
|
||||
NPC_CLIP->draw_proc(actorx, game);
|
||||
}
|
||||
Reference in New Issue
Block a user