Implement & link ac_ev_miko

This commit is contained in:
Cuyler36
2025-03-23 01:18:37 -04:00
parent 6b4d5ed8a6
commit 7c7a183e82
4 changed files with 321 additions and 2 deletions
+1 -1
View File
@@ -1173,7 +1173,7 @@ config.libs = [
Object(Matching, "actor/npc/event/ac_ev_gypsy.c"),
Object(Matching, "actor/npc/event/ac_ev_kabuPeddler.c"),
Object(Matching, "actor/npc/event/ac_ev_majin.c"),
Object(NonMatching, "actor/npc/event/ac_ev_miko.c"),
Object(Matching, "actor/npc/event/ac_ev_miko.c"),
Object(NonMatching, "actor/npc/event/ac_ev_pumpkin.c"),
Object(Matching, "actor/npc/event/ac_ev_santa.c"),
Object(Matching, "actor/npc/event/ac_ev_soncho.c"),
+13 -1
View File
@@ -3,11 +3,24 @@
#include "types.h"
#include "m_actor.h"
#include "ac_npc.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ev_miko_actor_s EV_MIKO_ACTOR;
typedef void (*aEMK_TALK_PROC)(EV_MIKO_ACTOR* miko, GAME_PLAY* play);
struct ev_miko_actor_s {
NPC_ACTOR npc_class;
int talk_action;
aEMK_TALK_PROC talk_proc;
int omikuji;
u8 in_front;
};
extern ACTOR_PROFILE Ev_Miko_Profile;
#ifdef __cplusplus
@@ -15,4 +28,3 @@ extern ACTOR_PROFILE Ev_Miko_Profile;
#endif
#endif
+105
View File
@@ -0,0 +1,105 @@
#include "ac_ev_miko.h"
#include "m_common_data.h"
#include "m_player_lib.h"
#include "m_string.h"
#include "m_handbill.h"
#include "m_msg.h"
#include "libultra/libultra.h"
enum {
aEMK_TALK_END_WAIT,
aEMK_TALK_SELECT,
aEMK_TALK_OMIKUJI,
aEMK_TALK_GIVE,
aEMK_TALK_NUM
};
enum {
aEMK_OMIKUJI_NORMAL,
aEMK_OMIKUJI_BAD,
aEMK_OMIKUJI_MONEY,
aEMK_OMIKUJI_GOODS,
aEMK_OMIKUJI_NUM
};
static void aEMK_actor_ct(ACTOR* actorx, GAME* game);
static void aEMK_actor_dt(ACTOR* actorx, GAME* game);
static void aEMK_actor_move(ACTOR* actorx, GAME* game);
static void aEMK_actor_draw(ACTOR* actorx, GAME* game);
static void aEMK_actor_init(ACTOR* actorx, GAME* game);
static void aEMK_actor_save(ACTOR* actorx, GAME* game);
ACTOR_PROFILE Ev_Miko_Profile = {
// clang-format off
mAc_PROFILE_EV_MIKO,
ACTOR_PART_NPC,
ACTOR_STATE_NO_MOVE_WHILE_CULLED,
SP_NPC_EV_MIKO,
ACTOR_OBJ_BANK_KEEP,
sizeof(EV_MIKO_ACTOR),
aEMK_actor_ct,
aEMK_actor_dt,
aEMK_actor_init,
mActor_NONE_PROC1,
aEMK_actor_save,
// clang-format on
};
static void aEMK_talk_request(ACTOR* actorx, GAME* game);
static int aEMK_talk_init(ACTOR* actorx, GAME* game);
static int aEMK_talk_end_chk(ACTOR* actorx, GAME* game);
static void aEMK_setupAction(EV_MIKO_ACTOR* miko, GAME_PLAY* play, int action);
static void aEMK_actor_ct(ACTOR* actorx, GAME* game) {
static aNPC_ct_data_c ct_data = {
// clang-format off
aEMK_actor_move,
aEMK_actor_draw,
aNPC_CT_SCHED_TYPE_STAND,
aEMK_talk_request,
aEMK_talk_init,
aEMK_talk_end_chk,
0
// clang-format on
};
if (NPC_CLIP->birth_check_proc(actorx, game) == TRUE) {
EV_MIKO_ACTOR* miko = (EV_MIKO_ACTOR*)actorx;
NPC_CLIP->ct_proc(actorx, game, &ct_data);
miko->npc_class.condition_info.hide_flg = FALSE;
miko->npc_class.palActorIgnoreTimer = -1;
actorx->status_data.weight = MASSTYPE_IMMOVABLE;
miko->npc_class.collision.check_kind = aNPC_BG_CHECK_TYPE_NONE;
actorx->world.position.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(actorx->world.position, 0.0f);
actorx->position_speed.y = 0.0f;
actorx->gravity = 0.0f;
actorx->max_velocity_y = 0.0f;
actorx->talk_distance = 78.0f;
NPC_CLIP->set_dst_pos_proc((NPC_ACTOR*)miko, actorx->world.position.x + 10.0f, actorx->world.position.z + 10.0f);
}
}
static void aEMK_actor_save(ACTOR* actorx, GAME* game) {
NPC_CLIP->save_proc(actorx, game);
}
static void aEMK_actor_dt(ACTOR* actorx, GAME* game) {
NPC_CLIP->dt_proc(actorx, game);
mEv_actor_dying_message(mEv_EVENT_NEW_YEARS_DAY, actorx);
}
static void aEMK_actor_init(ACTOR* actorx, GAME* game) {
NPC_CLIP->init_proc(actorx, game);
}
static void aEMK_actor_draw(ACTOR* actorx, GAME* game) {
NPC_CLIP->draw_proc(actorx, game);
}
#include "../src/actor/npc/event/ac_ev_miko_move.c_inc"
+202
View File
@@ -0,0 +1,202 @@
static int aEMK_set_request_act(EV_MIKO_ACTOR* miko, u8 prio, u8 idx, u8 type, u16 obj, s16 move_x, s16 move_z) {
int ret = FALSE;
if (prio >= miko->npc_class.request.act_priority) {
u16 arg_data[aNPC_REQUEST_ARG_NUM];
bzero(arg_data, sizeof(arg_data));
arg_data[0] = obj;
arg_data[2] = move_x;
arg_data[3] = move_z;
miko->npc_class.request.act_priority = prio;
miko->npc_class.request.act_idx = idx;
miko->npc_class.request.act_type = type;
mem_copy((u8*)miko->npc_class.request.act_args, (u8*)arg_data, sizeof(arg_data));
ret = TRUE;
}
return ret;
}
static int aEMK_mail_free_space(void) {
if (Now_Private != NULL && mMl_chk_mail_free_space(Now_Private->mail, mPr_INVENTORY_MAIL_COUNT) != -1) {
return TRUE;
}
return FALSE;
}
static void aEMK_get_omikuji(Mail_c* mail, int idx) {
static u8 pf_string[mMsg_FREE_STRING_LEN];
int header_back_start;
int load_idx;
static int table[] = { 0x2B1, 0x2A1, 0x2DA, 0x2CA };
static int kekka_table[] = { 2, 3, 1, 0 };
int i;
for (i = 0; i < 4; i++) {
load_idx = table[i] + RANDOM(16);
mString_Load_StringFromRom(pf_string, sizeof(pf_string), load_idx);
mHandbill_Set_free_str(i, pf_string, sizeof(pf_string));
}
mString_Load_StringFromRom(pf_string, sizeof(pf_string), 0x2C1 + kekka_table[idx]);
mHandbill_Set_free_str(mHandbill_FREE_STR4, pf_string, sizeof(pf_string));
load_idx = 0x072 + RANDOM(3);
mHandbill_Load_HandbillFromRom(mail->content.header, &header_back_start, mail->content.footer, mail->content.body, load_idx);
mail->content.font = mMl_FONT_RECV;
mail->content.header_back_start = header_back_start;
mail->content.mail_type = mMl_TYPE_OMIKUJI;
mMl_set_to_plname(mail, &Now_Private->player_ID);
}
static void aEMK_talk_select(EV_MIKO_ACTOR* miko, GAME_PLAY* play) {
if (mMsg_CHECK_MAINNORMALCONTINUE()) {
switch (mChoice_GET_CHOSENUM()) {
case mChoice_CHOICE0:
if (!aEMK_mail_free_space()) {
mMsg_SET_CONTINUE_MSG_NUM(0x190F);
aEMK_setupAction(miko, play, aEMK_TALK_END_WAIT);
} else if (mSP_money_check(50)) {
aEMK_setupAction(miko, play, aEMK_TALK_OMIKUJI);
} else {
mMsg_SET_CONTINUE_MSG_NUM(0x190E);
aEMK_setupAction(miko, play, aEMK_TALK_END_WAIT);
}
break;
case mChoice_CHOICE1:
aEMK_setupAction(miko, play, aEMK_TALK_END_WAIT);
break;
}
}
}
static void aEMK_talk_omikuji(EV_MIKO_ACTOR* miko, GAME_PLAY* play) {
int order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
static u8 destiny[] = { mPr_DESTINY_NORMAL, mPr_DESTINY_BAD_LUCK, mPr_DESTINY_MONEY_LUCK, mPr_DESTINY_GOODS_LUCK };
if (mMsg_CHECK_MAINNORMALCONTINUE() && order == 1) {
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
mMsg_SET_CONTINUE_MSG_NUM(0x1911 + miko->omikuji);
aEMK_setupAction(miko, play, aEMK_TALK_GIVE);
Now_Private->destiny.type = destiny[miko->omikuji];
mSP_get_sell_price(50);
}
}
static void aEMK_talk_give(EV_MIKO_ACTOR* miko, GAME_PLAY* play) {
int order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
Mail_c mail;
int idx;
if (order == 1) {
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 1, 2);
aNPC_DEMO_GIVE_ITEM(ITM_FORTUNE_SLIP, aHOI_REQUEST_PUTAWAY, FALSE);
aEMK_setupAction(miko, play, aEMK_TALK_END_WAIT);
mMl_clear_mail(&mail);
aEMK_get_omikuji(&mail, miko->omikuji);
if (Now_Private != NULL) {
idx = mMl_chk_mail_free_space(Now_Private->mail, mPr_INVENTORY_MAIL_COUNT);
if (idx != -1) {
mail.content.paper_type = (u8)ITM_PAPER25;
mMl_copy_mail(&Now_Private->mail[idx], &mail);
}
}
}
}
static void aEMK_talk_omikuji_init(EV_MIKO_ACTOR* miko, GAME_PLAY* play) {
miko->omikuji = RANDOM(aEMK_OMIKUJI_NUM);
}
typedef void (*aEMK_INIT_PROC)(EV_MIKO_ACTOR* miko, GAME_PLAY* play);
static void aEMK_init_proc(EV_MIKO_ACTOR* miko, GAME_PLAY* play, int action) {
static aEMK_INIT_PROC init_proc[] = {
// clang-format off
(aEMK_INIT_PROC)none_proc1,
(aEMK_INIT_PROC)none_proc1,
aEMK_talk_omikuji_init,
(aEMK_INIT_PROC)none_proc1,
// clang-format on
};
(*init_proc[action])(miko, play);
}
static void aEMK_setupAction(EV_MIKO_ACTOR* miko, GAME_PLAY* play, int action) {
static aEMK_TALK_PROC process[] = {
// clang-format off
(aEMK_TALK_PROC)none_proc1,
aEMK_talk_select,
aEMK_talk_omikuji,
aEMK_talk_give,
// clang-format on
};
miko->talk_action = action;
miko->talk_proc = process[action];
aEMK_init_proc(miko, play, action);
}
static void aEMK_set_talk_info(ACTOR* actorx) {
int msg_no;
EV_MIKO_ACTOR* miko = (EV_MIKO_ACTOR*)actorx;
if (miko->in_front == TRUE) {
msg_no = 0x190C;
} else {
msg_no = 0x1916;
}
mDemo_Set_msg_num(msg_no);
}
static void aEMK_talk_request(ACTOR* actorx, GAME* game) {
EV_MIKO_ACTOR* miko = (EV_MIKO_ACTOR*)actorx;
if (miko->npc_class.action.idx == aNPC_ACT_WAIT) {
mDemo_Request(mDemo_TYPE_TALK, actorx, aEMK_set_talk_info);
}
}
static int aEMK_talk_init(ACTOR* actorx, GAME* game) {
EV_MIKO_ACTOR* miko = (EV_MIKO_ACTOR*)actorx;
GAME_PLAY* play = (GAME_PLAY*)game;
aEMK_setupAction(miko, play, aEMK_TALK_SELECT);
mDemo_Set_ListenAble();
return TRUE;
}
static int aEMK_talk_end_chk(ACTOR* actorx, GAME* game) {
EV_MIKO_ACTOR* miko = (EV_MIKO_ACTOR*)actorx;
GAME_PLAY* play = (GAME_PLAY*)game;
int ret = FALSE;
(*miko->talk_proc)(miko, play);
if (!mDemo_Check(mDemo_TYPE_TALK, actorx)) {
ret = TRUE;
NPC_CLIP->set_dst_pos_proc((NPC_ACTOR*)miko, actorx->world.position.x + 10.0f, actorx->world.position.z + 10.0f);
aEMK_set_request_act(miko, 4, aNPC_ACT_TURN, aNPC_ACT_TYPE_TO_POINT, aNPC_ACT_OBJ_DEFAULT, actorx->world.position.x + 10.0f, actorx->world.position.z + 10.0f);
}
return ret;
}
static void aEMK_actor_move(ACTOR* actorx, GAME* game) {
EV_MIKO_ACTOR* miko = (EV_MIKO_ACTOR*)actorx;
if (ABS((s16)(actorx->player_angle_y - actorx->shape_info.rotation.y)) < DEG2SHORT_ANGLE2(33.75f)) {
miko->in_front = TRUE;
} else {
miko->in_front = FALSE;
}
NPC_CLIP->move_proc(actorx, game);
}