Implement & link ac_house

This commit is contained in:
Cuyler36
2024-12-01 04:51:31 -05:00
parent b5f0796fc1
commit 8dac07e97c
7 changed files with 1267 additions and 2 deletions
+252
View File
@@ -0,0 +1,252 @@
#include "ac_house.h"
#include "m_common_data.h"
#include "m_player_lib.h"
#include "m_bgm.h"
#include "sys_matrix.h"
#include "m_rcp.h"
#include "m_debug.h"
enum {
aHUS_ACTION_WAIT,
aHUS_ACTION_OPEN_DOOR_WAIT,
aHUS_ACTION_OPEN_DOOR,
aHUS_ACTION_NEXT_SCENE_WAIT,
aHUS_ACTION_NUM
};
enum {
aHUS_MSG_NONE,
aHUS_MSG_AWAY,
aHUS_MSG_SLEEP,
aHUS_MSG_NUM
};
enum {
aHUS_REQUEST_NPC_CLOSE_DOOR,
aHUS_REQUEST_NPC_OPEN_DOOR,
aHUS_REQUEST_PLAYER_ENTER,
aHUS_REQUEST_PLAYER_LEAVE,
aHUS_REQUEST_NUM
};
#define aHUS_GET_LOOKS(h) ((h)->arg0)
#define aHUS_GET_ANIMAL_P(h) ((Animal_c*)(h)->arg1)
#define aHUS_GET_ANIMAL_IDX(h) ((h)->arg2)
#define aHUS_GET_LIGHT_PERCENT(h) ((h)->arg1_f)
#define aHUS_SET_LOOKS(h, v) ((h)->arg0 = (v))
#define aHUS_SET_ANIMAL_P(h, v) ((h)->arg1 = (int)(v))
#define aHUS_SET_ANIMAL_IDX(h, v) ((h)->arg2 = (v))
#define aHUS_SET_LIGHT_PERCENT(h, v) ((h)->arg1_f = (v))
static void aHUS_actor_ct(ACTOR* actorx, GAME* game);
static void aHUS_actor_dt(ACTOR* actorx, GAME* game);
static void aHUS_actor_init(ACTOR* actorx, GAME* game);
static void aHUS_actor_move(ACTOR* actorx, GAME* game);
static void aHUS_actor_draw(ACTOR* actorx, GAME* game);
// clang-format off
ACTOR_PROFILE House_Profile = {
mAc_PROFILE_HOUSE,
ACTOR_PART_ITEM,
ACTOR_STATE_NONE,
NPC_HOUSE_START,
ACTOR_OBJ_BANK_KEEP,
sizeof(HOUSE_ACTOR),
&aHUS_actor_ct,
&aHUS_actor_dt,
&aHUS_actor_init,
&aHUS_actor_draw,
NULL,
};
// clang-format on
static void aHUS_setup_animation(HOUSE_ACTOR* house, f32 speed);
static void aHUS_setup_action(HOUSE_ACTOR* house, int action);
static void change_FGUnit(ACTOR* actorx, int keep_flag);
static void aHUS_set_bgOffset(ACTOR* actorx, int idx);
static f32 aHUS_ctrl_light(HOUSE_ACTOR* house);
extern Vtx obj_house1_shadow_v[];
extern Gfx obj_house1_shadow_model[];
extern Vtx obj_s_house2_shadow_v[];
extern Gfx obj_s_house2_shadow_model[];
extern Vtx obj_s_house3_shadow_v[];
extern Gfx obj_s_house3_shadow_model[];
extern Vtx obj_s_house4_shadow_v[];
extern Gfx obj_s_house4_shadow_model[];
extern Vtx obj_s_house5_shadow_v[];
extern Gfx obj_s_house5_shadow_model[];
// clang-format off
static u8 aHUS_shadow_vtx_fix_flg_table0[] = {
TRUE, FALSE, FALSE, TRUE,
FALSE, TRUE, TRUE, FALSE,
FALSE, TRUE, TRUE, FALSE,
TRUE, FALSE, FALSE, TRUE,
FALSE, TRUE, FALSE, TRUE,
};
// clang-format on
// clang-format off
static u8 aHUS_shadow_vtx_fix_flg_table1[] = {
TRUE, FALSE, FALSE, TRUE,
FALSE, TRUE, FALSE, TRUE,
TRUE, FALSE, FALSE, TRUE,
TRUE, FALSE, FALSE, TRUE,
TRUE, FALSE, FALSE, TRUE,
FALSE, TRUE, TRUE, FALSE,
TRUE, FALSE, FALSE, TRUE,
};
// clang-format on
// clang-format off
static u8 aHUS_shadow_vtx_fix_flg_table2[] = {
TRUE, FALSE, FALSE, TRUE,
FALSE, TRUE, FALSE, TRUE,
TRUE, FALSE, FALSE, TRUE,
TRUE, FALSE, FALSE, TRUE,
TRUE, FALSE, FALSE, TRUE,
FALSE, TRUE, TRUE, FALSE,
};
// clang-format on
static bIT_ShadowData_c aHUS_shadow_data0 = {
ARRAY_COUNT(aHUS_shadow_vtx_fix_flg_table0),
aHUS_shadow_vtx_fix_flg_table0,
60.0f,
obj_house1_shadow_v,
obj_house1_shadow_model,
};
static bIT_ShadowData_c aHUS_shadow_data1 = {
ARRAY_COUNT(aHUS_shadow_vtx_fix_flg_table1),
aHUS_shadow_vtx_fix_flg_table1,
60.0f,
obj_s_house2_shadow_v,
obj_s_house2_shadow_model,
};
static bIT_ShadowData_c aHUS_shadow_data2 = {
ARRAY_COUNT(aHUS_shadow_vtx_fix_flg_table2),
aHUS_shadow_vtx_fix_flg_table2,
60.0f,
obj_s_house3_shadow_v,
obj_s_house3_shadow_model,
};
static bIT_ShadowData_c aHUS_shadow_data3 = {
ARRAY_COUNT(aHUS_shadow_vtx_fix_flg_table1),
aHUS_shadow_vtx_fix_flg_table1,
60.0f,
obj_s_house4_shadow_v,
obj_s_house4_shadow_model,
};
static bIT_ShadowData_c aHUS_shadow_data4 = {
ARRAY_COUNT(aHUS_shadow_vtx_fix_flg_table1),
aHUS_shadow_vtx_fix_flg_table1,
60.0f,
obj_s_house5_shadow_v,
obj_s_house5_shadow_model,
};
extern cKF_Skeleton_R_c cKF_bs_r_obj_s_house1;
extern cKF_Skeleton_R_c cKF_bs_r_obj_s_house2;
extern cKF_Skeleton_R_c cKF_bs_r_obj_s_house3;
extern cKF_Skeleton_R_c cKF_bs_r_obj_s_house4;
extern cKF_Skeleton_R_c cKF_bs_r_obj_s_house5;
extern cKF_Skeleton_R_c cKF_bs_r_obj_w_house1;
extern cKF_Skeleton_R_c cKF_bs_r_obj_w_house2;
extern cKF_Skeleton_R_c cKF_bs_r_obj_w_house3;
extern cKF_Skeleton_R_c cKF_bs_r_obj_w_house4;
extern cKF_Skeleton_R_c cKF_bs_r_obj_w_house5;
// clang-format off
static cKF_Skeleton_R_c* aHUS_house_model_normal[] = {
&cKF_bs_r_obj_s_house1,
&cKF_bs_r_obj_s_house2,
&cKF_bs_r_obj_s_house3,
&cKF_bs_r_obj_s_house4,
&cKF_bs_r_obj_s_house5,
};
// clang-format on
// clang-format off
static cKF_Skeleton_R_c* aHUS_house_model_winter[] = {
&cKF_bs_r_obj_w_house1,
&cKF_bs_r_obj_w_house2,
&cKF_bs_r_obj_w_house3,
&cKF_bs_r_obj_w_house4,
&cKF_bs_r_obj_w_house5,
};
// clang-format on
static cKF_Skeleton_R_c** aHUS_house_model[] = { aHUS_house_model_normal, aHUS_house_model_winter };
// clang-format off
static bIT_ShadowData_c* aHUS_shadow_data[] = {
&aHUS_shadow_data0,
&aHUS_shadow_data1,
&aHUS_shadow_data2,
&aHUS_shadow_data3,
&aHUS_shadow_data4,
};
// clang-format on
static void aHUS_actor_ct(ACTOR* actorx, GAME* game) {
HOUSE_ACTOR* house = (HOUSE_ACTOR*)actorx;
int season;
s16 shape;
s16 pal;
int idx = mNpc_SearchAnimalinfo(Save_Get(animals), NPC_START + (actorx->npc_id - NPC_HOUSE_START), ANIMAL_NUM_MAX);
if (idx >= 0) {
aHUS_SET_LOOKS(house, mNpc_GetLooks(Common_Get(npclist[idx]).name));
aHUS_SET_ANIMAL_P(house, Save_GetPointer(animals[idx]));
aHUS_SET_ANIMAL_IDX(house, idx);
house->season = Common_Get(time.season);
season = house->season == mTM_SEASON_WINTER;
shape = Common_Get(npclist[idx]).house_data.type;
pal = Common_Get(npclist[idx]).house_data.palette;
house->structure_type = aSTR_TYPE_HOUSE1 + shape;
house->structure_pal = aSTR_PAL_HOUSE1_A + (s16)(pal + (shape * 5));
} else {
aHUS_SET_LOOKS(house, mNpc_LOOKS_GIRL);
aHUS_SET_ANIMAL_P(house, Save_GetPointer(animals[0]));
aHUS_SET_ANIMAL_IDX(house, 0);
house->season = Common_Get(time.season);
shape = 0;
pal = 0;
season = house->season == mTM_SEASON_WINTER;
house->structure_type = aSTR_TYPE_HOUSE1;
house->structure_pal = aSTR_PAL_HOUSE1_A;
}
cKF_SkeletonInfo_R_ct(&house->keyframe, aHUS_house_model[season][shape], NULL, house->work_area, house->morph_area);
aHUS_set_bgOffset(actorx, 1);
change_FGUnit(actorx, TRUE);
aHUS_setup_action(house, aHUS_ACTION_WAIT);
aHUS_setup_animation(house, 0.0f);
cKF_SkeletonInfo_R_play(&house->keyframe);
aHUS_SET_LIGHT_PERCENT(house, aHUS_ctrl_light(house));
}
static void aHUS_actor_dt(ACTOR* actorx, GAME* game) {
HOUSE_ACTOR* house = (HOUSE_ACTOR*)actorx;
change_FGUnit(actorx, FALSE);
cKF_SkeletonInfo_R_dt(&house->keyframe);
}
#include "../src/actor/ac_house_move.c_inc"
#include "../src/actor/ac_house_draw.c_inc"
+281
View File
@@ -0,0 +1,281 @@
extern Gfx obj_s_shop2_window_model[];
extern Gfx obj_w_shop2_window_model[];
static int aHUS_actor_draw_before(GAME* game, cKF_SkeletonInfo_R_c* keyframe, int joint_idx, Gfx** joint_shape,
u8* joint_flags, void* arg, s_xyz* joint_rot, xyz_t* joint_pos) {
HOUSE_ACTOR* house;
GRAPH* graph;
int b;
int rg;
house = (HOUSE_ACTOR*)arg;
graph = game->graph;
if (joint_idx == 1 || joint_idx == 3) {
OPEN_POLY_OPA_DISP(graph);
b = 0.5f + (150 * aHUS_GET_LIGHT_PERCENT(house));
rg = 0.5f + (255 * aHUS_GET_LIGHT_PERCENT(house));
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, rg, rg, b, 255);
CLOSE_POLY_OPA_DISP(graph);
}
if (joint_idx == 7) {
*joint_shape = NULL;
}
return TRUE;
}
extern Gfx obj_s_house1_windowL_model[];
extern Gfx obj_s_house1_windowR_model[];
extern Gfx obj_s_house2_window_model[];
extern Gfx obj_s_house3_windowL_model[];
extern Gfx obj_s_house3_windowR_model[];
extern Gfx obj_s_house4_windowL_model[];
extern Gfx obj_s_house4_windowR_model[];
extern Gfx obj_s_house5_windowL_model[];
extern Gfx obj_s_house5_windowR_model[];
extern Gfx obj_w_house1_windowL_model[];
extern Gfx obj_w_house1_windowR_model[];
extern Gfx obj_w_house2_window_model[];
extern Gfx obj_w_house3_windowL_model[];
extern Gfx obj_w_house3_windowR_model[];
extern Gfx obj_w_house4_windowL_model[];
extern Gfx obj_w_house4_windowR_model[];
extern Gfx obj_w_house5_windowL_model[];
extern Gfx obj_w_house5_windowR_model[];
static int aHUS_actor_draw_after(GAME* game, cKF_SkeletonInfo_R_c* keyframe, int joint_idx, Gfx** joint_shape,
u8* joint_flags, void* arg, s_xyz* joint_rot, xyz_t* joint_pos) {
static Gfx* window_model_table[][2][2] = {
{
{ obj_s_house1_windowL_model, obj_s_house1_windowR_model },
{ obj_w_house1_windowL_model, obj_w_house1_windowR_model },
},
{
{ obj_s_house2_window_model, NULL },
{ obj_w_house2_window_model, NULL },
},
{
{ obj_s_house3_windowL_model, obj_s_house3_windowR_model },
{ obj_w_house3_windowL_model, obj_w_house3_windowR_model },
},
{
{ obj_s_house4_windowL_model, obj_s_house4_windowR_model },
{ obj_w_house4_windowL_model, obj_w_house4_windowR_model },
},
{
{ obj_s_house5_windowL_model, obj_s_house5_windowR_model },
{ obj_w_house5_windowL_model, obj_w_house5_windowR_model },
},
};
static xyz_t window_light_offset_table[] = { { -100.0f, 0.0f, 0.0f }, { 100.0f, 0.0f, 0.0f } };
GRAPH* graph;
HOUSE_ACTOR* house;
u16* pal_p;
int season;
int type;
int l;
int r;
int g;
int b;
Mtx* mtx;
xyz_t posR;
xyz_t posL;
int mod_l;
house = (HOUSE_ACTOR*)arg;
graph = game->graph;
if (joint_idx == 7) {
mtx = _Matrix_to_Mtx_new(graph);
if (mtx != NULL) {
if (aHUS_GET_LIGHT_PERCENT(house) > 0.0f) {
l = aHUS_GET_LIGHT_PERCENT(house) * 120.0f + 0.5f;
r = 255;
g = 255;
b = 150;
} else {
l = 0;
r = 0;
g = 0;
b = 0;
}
pal_p = CLIP(structure_clip)->get_pal_segment_proc(house->structure_pal);
type = house->structure_type;
season = house->season == mTM_SEASON_WINTER;
_texture_z_light_fog_prim_shadow(graph);
OPEN_SHADOW_DISP(graph);
gSPSegment(SHADOW_DISP++, ANIME_1_TXT_SEG, pal_p);
gDPSetPrimColor(SHADOW_DISP++, 0, l, r, g, b, 0);
gSPMatrix(SHADOW_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
// @cleanup - why check this so late? we already deferenced house multiple times
if (house != NULL) {
posL.x = house->actor_class.world.position.x + window_light_offset_table[0].x;
posL.y = house->actor_class.world.position.y + window_light_offset_table[0].y;
posL.z = house->actor_class.world.position.z + window_light_offset_table[0].z;
mCoBG_GetBgY_AngleS_FromWpos(NULL, posL, 0.0f); // @cleanup - leftover call? completely unused, waste of cycles
posR.x = house->actor_class.world.position.x + window_light_offset_table[1].x;
posR.y = house->actor_class.world.position.y + window_light_offset_table[1].y;
posR.z = house->actor_class.world.position.z + window_light_offset_table[1].z;
mCoBG_GetBgY_AngleS_FromWpos(NULL, posR, 0.0f); // @cleanup - leftover call? completely unused, waste of cycles
mod_l = REGADDR(mREG, 10) + l;
gDPSetPrimColor(SHADOW_DISP++, 0, mod_l, r, g, b, 0);
gSPLoadGeometryMode(SHADOW_DISP++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_SHADING_SMOOTH | 0x40 | 0x10);
if (REGADDR(mREG, 13) == 5) {
gSPLoadGeometryMode(SHADOW_DISP++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_SHADING_SMOOTH);
} else if (REGADDR(mREG, 13) == 1) {
gSPLoadGeometryMode(SHADOW_DISP++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_SHADING_SMOOTH | 0x10);
} else if (REGADDR(mREG, 13) == 2) {
gSPLoadGeometryMode(SHADOW_DISP++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_SHADING_SMOOTH);
} else if (REGADDR(mREG, 13) == 3) {
gSPLoadGeometryMode(SHADOW_DISP++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_SHADING_SMOOTH | 0x40 | 0x10);
} else if (REGADDR(mREG, 13) == 4) {
gSPLoadGeometryMode(SHADOW_DISP++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_SHADING_SMOOTH | 0x40);
}
if (REGADDR(mREG, 13) >= 0) {
if (window_model_table[type][season][1] != NULL) {
gSPDisplayList(SHADOW_DISP++, window_model_table[type][season][1]);
}
gSPDisplayList(SHADOW_DISP++, window_model_table[type][season][0]);
}
mod_l = REGADDR(mREG, 11) + l;
gDPSetPrimColor(SHADOW_DISP++, 0, mod_l, r, g, b, 0);
gSPLoadGeometryMode(SHADOW_DISP++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_SHADING_SMOOTH | 0x40);
if (REGADDR(mREG, 15) == 5) {
gSPLoadGeometryMode(SHADOW_DISP++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_SHADING_SMOOTH);
} else if (REGADDR(mREG, 15) == 1) {
gSPLoadGeometryMode(SHADOW_DISP++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_SHADING_SMOOTH | 0x10);
} else if (REGADDR(mREG, 15) == 2) {
gSPLoadGeometryMode(SHADOW_DISP++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_SHADING_SMOOTH);
} else if (REGADDR(mREG, 15) == 3) {
gSPLoadGeometryMode(SHADOW_DISP++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_SHADING_SMOOTH | 0x40 | 0x10);
} else if (REGADDR(mREG, 15) == 4) {
gSPLoadGeometryMode(SHADOW_DISP++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_SHADING_SMOOTH | 0x40);
}
if (REGADDR(mREG, 15) >= 0) {
if (window_model_table[type][season][1] != NULL) {
gSPDisplayList(SHADOW_DISP++, window_model_table[type][season][1]);
}
gSPDisplayList(SHADOW_DISP++, window_model_table[type][season][0]);
}
gSPClearGeometryMode(SHADOW_DISP++, 0x40 | 0x10);
}
CLOSE_SHADOW_DISP(graph);
}
}
return TRUE;
}
static void aHUS_actor_draw_ta_set(ACTOR* actorx, GAME* game) {
// clang-format off
static u8 edge_alpha[][2] = {
{ 64, 64 },
{ 91, 91 },
{ 63, 3 },
{ 92, 92 },
{ 48, 48 },
};
// clang-format on
// clang-format off
static int adjust_mode[][2] = {
{ G_TA_DOLPHIN, G_TA_DOLPHIN },
{ G_TA_N64, G_TA_N64 },
{ G_TA_DOLPHIN, G_TA_N64 },
{ G_TA_DOLPHIN, G_TA_DOLPHIN },
{ G_TA_DOLPHIN, G_TA_DOLPHIN },
};
// clang-format on
GRAPH* graph = game->graph;
HOUSE_ACTOR* house = (HOUSE_ACTOR*)actorx;
int type = house->structure_type;
int season = house->season == mTM_SEASON_WINTER;
u8 a = GETREG(MYKREG, 1) + edge_alpha[type][season];
int adjust = adjust_mode[type][season];
OPEN_DISP(graph);
gDPSetTextureAdjustMode(NEXT_POLY_OPA_DISP, adjust);
gDPSetTextureAdjustMode(NEXT_SHADOW_DISP, adjust);
gDPSetTexEdgeAlpha(NEXT_POLY_OPA_DISP, a);
gDPSetTexEdgeAlpha(NEXT_SHADOW_DISP, a);
CLOSE_DISP(graph);
}
static void aHUS_actor_draw_ta_clr(ACTOR* actorx, GAME* game) {
GRAPH* graph = game->graph;
OPEN_DISP(graph);
gDPSetTextureAdjustMode(NEXT_POLY_OPA_DISP, G_TA_N64);
gDPSetTextureAdjustMode(NEXT_SHADOW_DISP, G_TA_N64);
gDPSetTexEdgeAlpha(NEXT_POLY_OPA_DISP, 144);
gDPSetTexEdgeAlpha(NEXT_SHADOW_DISP, 144);
CLOSE_DISP(graph);
}
static void aHUS_actor_draw(ACTOR* actorx, GAME* game) {
GRAPH* graph;
cKF_SkeletonInfo_R_c* keyframe;
Mtx* mtx;
u16* pal;
HOUSE_ACTOR* house;
graph = game->graph;
house = (HOUSE_ACTOR*)actorx;
keyframe = &house->keyframe;
mtx = GRAPH_ALLOC_TYPE(graph, Mtx, (u32)keyframe->skeleton->num_shown_joints);
if (mtx == NULL) {
return;
}
aHUS_actor_draw_ta_set(actorx, game);
pal = Common_Get(clip).structure_clip->get_pal_segment_proc(house->structure_pal);
_texture_z_light_fog_prim_npc(graph);
OPEN_POLY_OPA_DISP(graph);
gSPSegment(POLY_OPA_DISP++, ANIME_1_TXT_SEG, pal);
CLOSE_POLY_OPA_DISP(graph);
cKF_Si3_draw_R_SV(game, keyframe, mtx, &aHUS_actor_draw_before, &aHUS_actor_draw_after, actorx);
CLIP(bg_item_clip)->draw_shadow_proc(game, aHUS_shadow_data[house->structure_type], TRUE);
aHUS_actor_draw_ta_clr(actorx, game);
}
+485
View File
@@ -0,0 +1,485 @@
static void aHUS_set_door_SE_sub(ACTOR* actorx, u16 se_no) {
sAdo_OngenTrgStart(se_no, &actorx->world.position);
}
static void change_FGUnit(ACTOR* actorx, int keep_flag) {
mActor_name_t* fg_p;
mActor_name_t item;
xyz_t pos;
xyz_t_move(&pos, &actorx->world.position);
pos.z += 2 * mFI_UT_WORLDSIZE_Z_F;
if (keep_flag == FALSE) {
mFI_SetFG_common(EMPTY_NO, pos, TRUE);
} else {
fg_p = mFI_GetUnitFG(pos);
if (fg_p != NULL) {
if (!mSN_ClearSnowman(fg_p)) {
item = *fg_p;
if ((ITEM_IS_BURIED_PITFALL_HOLE(item) || item == SHINE_SPOT) == TRUE) {
item = bg_item_fg_sub_dig2take_conv(item);
mPB_keep_item(item);
mFI_SetFG_common(RSV_NO, pos, TRUE);
mFI_Wpos2DepositOFF(pos);
} else {
mFI_Wpos2DepositOFF(pos);
mPB_keep_item(*fg_p);
mFI_SetFG_common(RSV_NO, pos, TRUE);
}
} else {
mFI_SetFG_common(RSV_NO, pos, TRUE);
}
}
}
}
static void aHUS_set_doorSE(HOUSE_ACTOR* house) {
static f32 chk_pat_in[] = { 10.0f, 14.0f, 35.0f, 50.0f };
static f32 chk_pat_out[] = { 2.0f, 8.0f, 33.0f, 40.0f };
static u16 se_no[] = { NA_SE_6, NA_SE_7, NA_SE_8, NA_SE_9 };
f32* chk_pat_p;
int i;
switch (house->request_type) {
case aHUS_REQUEST_NPC_OPEN_DOOR:
case aHUS_REQUEST_PLAYER_LEAVE:
chk_pat_p = chk_pat_in;
break;
// case aHUS_REQUEST_NPC_CLOSE_DOOR:
case aHUS_REQUEST_PLAYER_ENTER:
default:
chk_pat_p = chk_pat_out;
break;
}
for (i = 0; i < 4; i++) {
if (cKF_FrameControl_passCheck_now(&house->keyframe.frame_control, *chk_pat_p)) {
aHUS_set_door_SE_sub((ACTOR*)house, se_no[i]);
break;
}
chk_pat_p++;
}
}
// clang-format off
static Door_data_c aHUS_npc_house_door_data = {
SCENE_NPC_HOUSE,
mSc_DIRECT_NORTH,
0,
0,
{ 160, 0, 300 },
EMPTY_NO,
1,
{ 0, 0, 0 },
};
// clang-format on
static int aHUS_odekake_check(HOUSE_ACTOR* house, GAME_PLAY* play) {
Animal_c* animal_p;
int ret;
int idx;
ACTOR* npc_actor_p;
int status;
int goal;
mActor_name_t name;
animal_p = aHUS_GET_ANIMAL_P(house);
idx = aHUS_GET_ANIMAL_IDX(house);
ret = FALSE;
house->arg0_f = 0.0f;
name = Common_Get(npclist[idx]).name;
npc_actor_p = Actor_info_fgName_search(&play->actor_info, Common_Get(npclist[idx]).name, ACTOR_PART_NPC);
if (mEvNM_CheckJointEvent(name)) {
house->arg0_f = 1.0f;
ret = TRUE;
} else if (mNpc_CheckNpcExistBlock(idx, play->block_table.block_x, play->block_table.block_z) && npc_actor_p != NULL) {
if (animal_p->is_home == TRUE) {
if (house->arg3 == 2) {
house->arg0_f = 2.0f;
ret = TRUE;
}
} else if (mNpcW_GetWalkInfoStatusGoalAnimalIdx(&status, &goal, idx) && status == mNpcW_INFO_STATUS_WALKING && goal == mNpcW_GOAL_MY_HOME && !animal_p->is_home) {
house->arg0_f = 1.0f;
ret = TRUE;
}
} else {
if (animal_p->is_home == TRUE) {
if (house->arg3 == 2) {
house->arg0_f = 2.0f;
ret = TRUE;
}
} else {
house->arg0_f = 1.0f;
ret = TRUE;
}
}
return ret;
}
extern cKF_Animation_R_c cKF_ba_r_obj_s_house1;
extern cKF_Animation_R_c cKF_ba_r_obj_w_house1;
extern cKF_Animation_R_c cKF_ba_r_obj_s_house2;
extern cKF_Animation_R_c cKF_ba_r_obj_w_house2;
extern cKF_Animation_R_c cKF_ba_r_obj_s_house3;
extern cKF_Animation_R_c cKF_ba_r_obj_w_house3;
extern cKF_Animation_R_c cKF_ba_r_obj_s_house4;
extern cKF_Animation_R_c cKF_ba_r_obj_w_house4;
extern cKF_Animation_R_c cKF_ba_r_obj_s_house5;
extern cKF_Animation_R_c cKF_ba_r_obj_w_house5;
extern cKF_Animation_R_c cKF_ba_r_obj_s_house1_out;
extern cKF_Animation_R_c cKF_ba_r_obj_w_house1_out;
extern cKF_Animation_R_c cKF_ba_r_obj_s_house2_out;
extern cKF_Animation_R_c cKF_ba_r_obj_w_house2_out;
extern cKF_Animation_R_c cKF_ba_r_obj_s_house3_out;
extern cKF_Animation_R_c cKF_ba_r_obj_w_house3_out;
extern cKF_Animation_R_c cKF_ba_r_obj_s_house4_out;
extern cKF_Animation_R_c cKF_ba_r_obj_w_house4_out;
extern cKF_Animation_R_c cKF_ba_r_obj_s_house5_out;
extern cKF_Animation_R_c cKF_ba_r_obj_w_house5_out;
static void aHUS_setup_animation(HOUSE_ACTOR* house, f32 speed) {
static cKF_Animation_R_c* animation[][5][2] = {
{
{ &cKF_ba_r_obj_s_house1, &cKF_ba_r_obj_w_house1 },
{ &cKF_ba_r_obj_s_house2, &cKF_ba_r_obj_w_house2 },
{ &cKF_ba_r_obj_s_house3, &cKF_ba_r_obj_w_house3 },
{ &cKF_ba_r_obj_s_house4, &cKF_ba_r_obj_w_house4 },
{ &cKF_ba_r_obj_s_house5, &cKF_ba_r_obj_w_house5 },
},
{
{ &cKF_ba_r_obj_s_house1_out, &cKF_ba_r_obj_w_house1_out },
{ &cKF_ba_r_obj_s_house2_out, &cKF_ba_r_obj_w_house2_out },
{ &cKF_ba_r_obj_s_house3_out, &cKF_ba_r_obj_w_house3_out },
{ &cKF_ba_r_obj_s_house4_out, &cKF_ba_r_obj_w_house4_out },
{ &cKF_ba_r_obj_s_house5_out, &cKF_ba_r_obj_w_house5_out },
},
};
static f32 start_idx[] = { 1.0f, 25.0f, 1.0f, 1.0f };
static f32 end_idx[] = { 51.0f, 51.0f, 51.0f, 51.0f };
int type;
cKF_Animation_R_c* anim_p;
int season;
f32 start;
f32 end;
season = house->season == mTM_SEASON_WINTER;
switch (house->request_type) {
case aHUS_REQUEST_PLAYER_ENTER:
type = 2;
break;
case aHUS_REQUEST_NUM:
type = 1;
break; // what would trigger this??
default:
type = 0;
break;
}
anim_p = animation[type != 0][house->structure_type - aSTR_TYPE_HOUSE1][season];
start = start_idx[type];
end = end_idx[type];
cKF_SkeletonInfo_R_init(&house->keyframe, house->keyframe.skeleton, anim_p, start, end, start, speed, 0.0f, cKF_FRAMECONTROL_STOP, NULL);
}
static void aHUS_rewrite_out_data(HOUSE_ACTOR* house, GAME_PLAY* play) {
Door_data_c* out_data_p = Common_GetPointer(structure_exit_door_data);
mActor_name_t name;
xyz_t pos;
if (play->fb_wipe_mode == 0) {
name = NPC_START + (house->actor_class.npc_id - NPC_HOUSE_START);
if (mNpc_SearchAnimalinfo(Save_Get(animals), name, ANIMAL_NUM_MAX) == -1) {
name = RSV_NO;
}
Common_Set(house_owner_name, name);
out_data_p->next_scene_id = Save_Get(scene_no);
out_data_p->exit_orientation = mSc_DIRECT_SOUTH;
out_data_p->exit_type = 0;
out_data_p->extra_data = 2;
pos.x = house->actor_class.home.position.x;
pos.z = house->actor_class.home.position.z + 60.0f;
pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(pos, 0.0f);
out_data_p->exit_position.x = (s16)pos.x;
out_data_p->exit_position.y = (s16)pos.y;
out_data_p->exit_position.z = (s16)pos.z;
out_data_p->door_actor_name = house->actor_class.npc_id;
out_data_p->wipe_type = 1;
}
}
static void aHUS_set_talk_info_check_player(ACTOR* actorx) {
HOUSE_ACTOR* house = (HOUSE_ACTOR*)actorx;
rgba_t window_color;
int msg_no;
if (house->arg0_f == 2.0f) {
msg_no = 0x1363 + aHUS_GET_LOOKS(house); // Sleeping
} else {
msg_no = 0x2AFE; // I'm not in right now.
}
mDemo_Set_msg_num(msg_no);
mDemo_Set_talk_display_name(FALSE);
mDemo_Set_camera(CAMERA2_PROCESS_NORMAL);
mPlib_Set_able_hand_all_item_in_demo(mPlayer_ABLE_ITEM_CAN_USE_UMBRELLA);
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 int aHUS_check_player(HOUSE_ACTOR* house, GAME_PLAY* play) {
int ret = 0;
PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play);
mNPS_schedule_c* sched_p;
Animal_c* animal_p;
mActor_name_t name;
if (player == NULL) {
return 0;
}
name = house->actor_class.npc_id;
name = name - NPC_HOUSE_START + DUMMY_NPC_HOUSE_000;
if ((mActor_name_t)player->item_in_front == name && chkTrigger(BUTTON_A)) {
if ((mEv_CheckFirstJob() == TRUE || mEv_check_status(mEv_EVENT_HALLOWEEN, mEv_STATUS_ACTIVE)) == TRUE) {
house->arg3 = 0;
} else {
animal_p = aHUS_GET_ANIMAL_P(house);
sched_p = mNPS_get_schedule_area(&animal_p->id);
house->arg3 = sched_p->current_type;
}
if (aHUS_odekake_check(house, play)) {
mDemo_Request(mDemo_TYPE_SPEAK, (ACTOR*)house, &aHUS_set_talk_info_check_player);
} else {
ret = 2;
}
}
return ret;
}
static void aHUS_open_door_demo_ct(ACTOR* actorx) {
mDemo_Set_house_info(mFI_UNIT_BASE_SIZE_F, mDemo_DIRECT_S);
mDemo_Set_camera(CAMERA2_PROCESS_DOOR);
}
static int aHUS_check_open(HOUSE_ACTOR* house, GAME_PLAY* play) {
int ret = 0;
int request;
if (mDemo_Check(mDemo_TYPE_DOOR, (ACTOR*)house)) {
return 2;
} else {
request = house->request_type;
if (request == 0) {
if (aHUS_check_player(house, play) == 2) {
mDemo_Request(mDemo_TYPE_DOOR, (ACTOR*)house, &aHUS_open_door_demo_ct);
}
ret = 0;
} else if (request == 1 || request == 2) {
ret = 1;
} else if (request == 3) {
ret = 2;
} else if (request == 4) {
ret = 3;
}
}
return ret;
}
static void aHUS_set_bgOffset(ACTOR* actorx, int idx) {
// clang-format off
static mCoBG_OffsetTable_c height_table_ct[] = {
{ mCoBG_ATTRIBUTE_NONE, 7, 7, 7, 7, 7, 0 },
{ mCoBG_ATTRIBUTE_NONE, 0, 0, 0, 0, 0, 0 },
{ mCoBG_ATTRIBUTE_NONE, 7, 7, 7, 7, 7, 0 },
{ mCoBG_ATTRIBUTE_NONE, 7, 7, 7, 7, 7, 0 },
{ mCoBG_ATTRIBUTE_NONE, 7, 7, 7, 7, 7, 0 },
{ mCoBG_ATTRIBUTE_NONE, 7, 7, 7, 7, 7, 0 },
{ mCoBG_ATTRIBUTE_NONE, 7, 7, 7, 7, 7, 0 },
{ mCoBG_ATTRIBUTE_NONE, 7, 7, 7, 7, 7, 0 },
{ mCoBG_ATTRIBUTE_NONE, 7, 7, 7, 7, 7, 0 },
};
// clang-format on
static mCoBG_OffsetTable_c* height_table[] = { height_table_ct, height_table_ct };
static f32 addX[] = { -mFI_UT_WORLDSIZE_X_F, 0.0f, mFI_UT_WORLDSIZE_X_F };
static f32 addZ[] = { mFI_UT_WORLDSIZE_Z_F, 0.0f, -mFI_UT_WORLDSIZE_Z_F };
mCoBG_OffsetTable_c* ofs_p = height_table[idx];
xyz_t pos;
int i;
for (i = 0; i < 3; i++) {
pos.z = actorx->home.position.z + addZ[i];
pos.x = actorx->home.position.x + addX[0];
mCoBG_SetPluss5PointOffset_file(pos, ofs_p[0], __FILE__, 620);
pos.x = actorx->home.position.x + addX[1];
mCoBG_SetPluss5PointOffset_file(pos, ofs_p[1], __FILE__, 624);
pos.x = actorx->home.position.x + addX[2];
mCoBG_SetPluss5PointOffset_file(pos, ofs_p[2], __FILE__, 628);
ofs_p += 3;
}
}
static f32 aHUS_ctrl_light(HOUSE_ACTOR* house) {
Animal_c* animal_p = aHUS_GET_ANIMAL_P(house);
mNPS_schedule_c* sched_p = mNPS_get_schedule_area(&animal_p->id);
int now_sec = Common_Get(time.now_sec);
mActor_name_t name;
if (sched_p == NULL) {
return 0.0f;
}
name = Common_Get(npclist[aHUS_GET_ANIMAL_IDX(house)]).name;
if (mEvNM_CheckJointEvent(name) && !mEv_CheckArbeit()) {
return 0.0f;
}
if (sched_p->current_type == mNPS_SCHED_IN_HOUSE && animal_p->is_home == TRUE &&
(now_sec >= (18 * mTM_SECONDS_IN_HOUR) || now_sec <= (5 * mTM_SECONDS_IN_HOUR))) {
if (house->request_type == 2) {
return 0.0f;
} else {
return 1.0f;
}
} else {
return 0.0f;
}
}
static void aHUS_wait(HOUSE_ACTOR* house, GAME_PLAY* play) {
int next_act = -1;
switch (aHUS_check_open(house, play)) {
case 1:
next_act = aHUS_ACTION_OPEN_DOOR;
break;
case 3:
if (mPlib_check_player_outdoor_start((GAME*)play)) {
next_act = aHUS_ACTION_OPEN_DOOR;
}
break;
case 2:
next_act = aHUS_ACTION_OPEN_DOOR_WAIT;
break;
}
if (next_act != -1) {
aHUS_setup_action(house, next_act);
} else {
return;
}
switch (house->request_type) {
case 1:
case 2:
case 4:
aHUS_setup_animation(house, 0.5f);
break;
case 3:
break;
}
}
static void aHUS_open_door_wait(HOUSE_ACTOR* house, GAME_PLAY* play) {
ACTOR* actorx = (ACTOR*)house;
if (actorx == GET_PLAYER_ACTOR_NOW()->get_door_label_proc(gamePT)) {
mBGMPsComp_make_ps_wipe(0x249);
house->request_type = 3;
aHUS_setup_animation(house, 0.5f);
aHUS_setup_action(house, aHUS_ACTION_OPEN_DOOR);
}
}
static void aHUS_open_door(HOUSE_ACTOR* house, GAME_PLAY* play) {
int next_act;
if (cKF_SkeletonInfo_R_play(&house->keyframe) == cKF_STATE_STOPPED) {
switch (house->request_type) {
case 3:
aHUS_rewrite_out_data(house, play);
goto_other_scene(play, &aHUS_npc_house_door_data, FALSE);
play->fb_fade_type = 9;
next_act = aHUS_ACTION_NEXT_SCENE_WAIT;
mDemo_End((ACTOR*)house);
break;
case 1:
case 2:
house->actor_class.state_bitfield = House_Profile.initial_flags_state;
next_act = aHUS_ACTION_WAIT;
break;
default:
next_act = aHUS_ACTION_WAIT;
break;
}
house->request_type = 0;
aHUS_setup_action(house, next_act);
}
}
static void aHUS_setup_action(HOUSE_ACTOR* house, int action) {
// clang-format off
static void* process[] = {
&aHUS_wait,
&aHUS_open_door_wait,
&aHUS_open_door,
&none_proc1,
};
// clang-format on
house->action_proc = process[action];
}
static void aHUS_actor_move(ACTOR* actorx, GAME* game) {
GAME_PLAY* play = (GAME_PLAY*)game;
HOUSE_ACTOR* house = (HOUSE_ACTOR*)actorx;
aHUS_set_doorSE(house);
(*house->action_proc)((STRUCTURE_ACTOR*)house, play);
chase_f(&aHUS_GET_LIGHT_PERCENT(house), aHUS_ctrl_light(house), 0.019532442f);
}
static void aHUS_actor_init(ACTOR* actorx, GAME* game) {
mActor_name_t name;
name =actorx->npc_id;
name = name - NPC_HOUSE_START + DUMMY_NPC_HOUSE_000;
mFI_SetFG_common(name, actorx->home.position, FALSE);
aHUS_actor_move(actorx, game);
actorx->mv_proc = &aHUS_actor_move;
}