mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-23 06:34:18 -04:00
Implement & link ac_ev_miko
This commit is contained in:
+1
-1
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user