Implement & link ac_police_box (#313)

This commit is contained in:
Hexalotl
2024-03-25 03:23:46 -07:00
committed by GitHub
parent 80c63841ea
commit 1cbe0b55d0
6 changed files with 323 additions and 1 deletions
+4
View File
@@ -798,6 +798,10 @@ ac_needlework_shop.c:
.text: [0x805B65C4, 0x805B7338]
.rodata: [0x8064AAA0, 0x8064AAE8]
.data: [0x806C6138, 0x806C62D0]
ac_police_box.c:
.text: [0x805B7338, 0x805B7B0C]
.rodata: [0x8064AAE8, 0x8064AB18]
.data: [0x806C62D0, 0x806C63C0]
ac_post_office.c:
.text: [0x805B7B0C, 0x805B887C]
.rodata: [0x8064AB18, 0x8064AB58]
+1 -1
View File
@@ -2,7 +2,7 @@
#define AC_POLICE_BOX_H
#include "types.h"
#include "m_actor.h"
#include "ac_structure.h"
#ifdef __cplusplus
extern "C" {
+1
View File
@@ -2714,6 +2714,7 @@ extern int mNT_check_unknown(mActor_name_t item_no);
#define DUMMY_HANIWA3 (DUMMY_HANIWA2 + 1)
#define DUMMY_POST_OFFICE 0xF0FF
#define DUMMY_NEEDLEWORK_SHOP 0xF0FF
#define DUMMY_POLICE_STATION 0xF101
#define DUMMY_RESERVE 0xF102
#define DUMMY_SHRINE 0xF103
#define DUMMY_BROKER_SHOP 0xF104
+91
View File
@@ -0,0 +1,91 @@
#include "ac_police_box.h"
#include "m_name_table.h"
#include "bg_item_h.h"
#include "m_common_data.h"
#include "m_house.h"
#include "m_player_lib.h"
#include "m_demo.h"
#include "ac_intro_demo.h"
#include "m_bgm.h"
#include "sys_matrix.h"
#include "m_rcp.h"
#include "libforest/gbi_extensions.h"
static void aPBOX_actor_ct(ACTOR* actor, GAME* game);
static void aPBOX_actor_init(ACTOR* actor, GAME* game);
static void aPBOX_actor_draw(ACTOR* actor, GAME* game);
// clang-format off
ACTOR_PROFILE Police_Box_Profile = {
mAc_PROFILE_POLICE_BOX,
ACTOR_PART_ITEM,
ACTOR_STATE_TA_SET,
POLICE_STATION,
ACTOR_OBJ_BANK_KEEP,
sizeof(STRUCTURE_ACTOR),
&aPBOX_actor_ct,
mActor_NONE_PROC1,
&aPBOX_actor_init,
&aPBOX_actor_draw,
NULL
};
// clang-format on
// clang-format off
static u8 aPBOX_shadow_vtx_fix_flg_table0[] = {
TRUE, FALSE, TRUE, FALSE,
TRUE, FALSE, TRUE, FALSE,
TRUE, FALSE, FALSE, TRUE,
TRUE, FALSE, FALSE, TRUE,
TRUE, FALSE, FALSE, TRUE
};
// clang-format on
extern Vtx obj_s_kouban_shadow_v[];
extern Gfx obj_s_kouban_shadow_model[];
// clang-format off
static bIT_ShadowData_c aPBOX_shadow_data = {
20,
aPBOX_shadow_vtx_fix_flg_table0,
60.0f,
obj_s_kouban_shadow_v,
obj_s_kouban_shadow_model
};
// clang-format on
// clang-format off
static Door_data_c aPBOX_police_box_enter_data = {
SCENE_POLICE_BOX,
mSc_DIRECT_NORTH,
FALSE,
0,
{ 200, 0, 380 },
EMPTY_NO,
1,
{ 0, 0, 0 },
};
// clang-format on
static void aPBOX_set_bgOffset(STRUCTURE_ACTOR* shop, int idx);
static int aPBOX_ctrl_light(STRUCTURE_ACTOR* shop);
static void aPBOX_actor_ct(ACTOR* actor, GAME* game) {
STRUCTURE_ACTOR* box;
box = (STRUCTURE_ACTOR*)actor;
box->season = Common_Get(time.season);
aPBOX_set_bgOffset(box, 0);
if (aPBOX_ctrl_light(box) != FALSE) {
box->action = DEG2SHORT_ANGLE(90.0f) - 1; // 0x3FFF
} else {
box->action = DEG2SHORT_ANGLE(0.0f);
}
}
#include "../src/ac_police_box_move.c_inc"
#include "../src/ac_police_box_draw.c_inc"
+87
View File
@@ -0,0 +1,87 @@
extern Gfx obj_s_kouban_model[];
extern Gfx obj_w_kouban_model[];
extern Gfx obj_s_kouban_window_model[];
extern Gfx obj_w_kouban_window_model[];
static void aPBOX_actor_draw(ACTOR* actor, GAME* game) {
static Gfx* displayList[] = { obj_s_kouban_model, obj_w_kouban_model };
static Gfx* mdl[] = { obj_s_kouban_window_model, obj_w_kouban_window_model };
STRUCTURE_ACTOR* box;
GRAPH* graph;
f32 angle;
int winter;
int r1;
int g1;
int b1;
int l2;
int r2;
int g2;
int b2;
u16* pal;
Gfx* poly_opa;
Gfx* poly_xlu;
box = (STRUCTURE_ACTOR*)actor;
graph = game->graph;
pal = Common_Get(clip).structure_clip->get_pal_segment_proc(aSTR_PAL_POLICE_BOX);
winter = box->season == mTM_SEASON_WINTER;
if (box->action == DEG2SHORT_ANGLE(90.0f) - 1) { // 0x3FFF
r1 = 255;
g1 = 255;
b1 = 150;
l2 = 120;
r2 = 255;
g2 = 255;
b2 = 150;
} else if (box->action == DEG2SHORT_ANGLE(0.0f)) {
r1 = 0;
g1 = 0;
b1 = 0;
l2 = 0;
r2 = 0;
g2 = 0;
b2 = 0;
} else {
r2 = 255;
g2 = 255;
b2 = 150;
angle = (1.0f / (DEG2SHORT_ANGLE(90.0f) - 1)) * box->action;
r1 = angle * 255.0f;
g1 = angle * 255.0f;
b1 = angle * 150.0f;
l2 = angle * 120.0f;
}
OPEN_DISP(graph);
{
_texture_z_light_fog_prim_npc(graph);
poly_opa = NOW_POLY_OPA_DISP;
gSPMatrix(poly_opa++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPSegment(poly_opa++, G_MWO_SEGMENT_8, pal);
gDPPipeSync(poly_opa++);
gDPSetEnvColor(poly_opa++, r1, g1, b1, 0);
gSPDisplayList(poly_opa++, displayList[winter]);
SET_POLY_OPA_DISP(poly_opa);
}
{
_texture_z_light_fog_prim_xlu(graph);
poly_xlu = NOW_POLY_XLU_DISP;
gDPSetPrimColor(poly_xlu++, 0, l2, r2, g2, b2, 0);
gSPMatrix(poly_xlu++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(poly_xlu++, mdl[winter]);
SET_POLY_XLU_DISP(poly_xlu);
}
CLOSE_DISP(graph);
_texture_z_light_fog_prim_shadow(graph);
(*Common_Get(clip).bg_item_clip->draw_shadow_proc)(game, &aPBOX_shadow_data, FALSE);
}
+139
View File
@@ -0,0 +1,139 @@
static void aPBOX_set_bgOffset(STRUCTURE_ACTOR* box, int idx) {
// clang-format off
static mCoBG_OffsetTable_c height_table_ct[] = {
{ mCoBG_ATTRIBUTE_NONE, 10, 10, 0, 10, 10, 1 },
{ mCoBG_ATTRIBUTE_NONE, 10, 10, 10, 10, 10, 0 },
{ mCoBG_ATTRIBUTE_NONE, 10, 10, 10, 0, 10, 1 },
{ mCoBG_ATTRIBUTE_NONE, 10, 10, 10, 10, 10, 0 },
{ mCoBG_ATTRIBUTE_NONE, 10, 10, 10, 10, 10, 0 },
{ mCoBG_ATTRIBUTE_NONE, 10, 10, 10, 10, 10, 0 },
{ mCoBG_ATTRIBUTE_NONE, 10, 0, 10, 10, 10, 1 },
{ mCoBG_ATTRIBUTE_NONE, 10, 10, 10, 10, 10, 0 },
{ mCoBG_ATTRIBUTE_NONE, 10, 10, 10, 10, 0, 1 }
};
// clang-format on
static mCoBG_OffsetTable_c* height_table[] = { height_table_ct, height_table_ct };
static f32 addX[] = { -40.0f, 0.0f, 40.0f };
static f32 addZ[] = { 40.0f, 0.0f, -40.0f };
mCoBG_OffsetTable_c* offset;
int i;
xyz_t pos;
offset = height_table[idx];
for (i = 0; i < 3; i++) {
pos.z = box->actor_class.home.position.z + addZ[i];
pos.x = box->actor_class.home.position.x + addX[0];
mCoBG_SetPluss5PointOffset_file(pos, offset[0], __FILE__, 142);
pos.x = box->actor_class.home.position.x + addX[1];
mCoBG_SetPluss5PointOffset_file(pos, offset[1], __FILE__, 146);
pos.x = box->actor_class.home.position.x + addX[2];
mCoBG_SetPluss5PointOffset_file(pos, offset[2], __FILE__, 150);
offset += 3;
}
}
static void aPBOX_rewrite_out_data(STRUCTURE_ACTOR* shop, GAME_PLAY* play) {
Door_data_c* door_data;
xyz_t pos;
door_data = Common_GetPointer(structure_exit_door_data);
if (play->fb_wipe_mode == 0) {
door_data->next_scene_id = Save_Get(scene_no);
door_data->exit_orientation = mSc_DIRECT_SOUTH_EAST;
door_data->exit_type = 0;
door_data->extra_data = 3;
pos.x = shop->actor_class.home.position.x + 60.0f;
pos.z = shop->actor_class.home.position.z + 60.0f;
pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(pos, 0.0f);
door_data->exit_position.x = pos.x;
door_data->exit_position.y = pos.y;
door_data->exit_position.z = pos.z;
door_data->door_actor_name = POLICE_STATION;
door_data->wipe_type = 1;
mBGMPsComp_make_ps_wipe(0x2168);
}
}
static int aPBOX_check_player(ACTOR* actor, GAME_PLAY* play) {
u16 y;
f32 xOffs;
f32 zOffs;
f32 t;
int res;
PLAYER_ACTOR* player;
player = GET_PLAYER_ACTOR(play);
res = 1;
if (player == NULL) {
return 0;
}
y = player->actor_class.shape_info.rotation.y;
xOffs = actor->world.position.x + 24.0f;
zOffs = actor->world.position.z + 40.0f;
xOffs = SQ(player->actor_class.world.position.x - xOffs);
zOffs = SQ(player->actor_class.world.position.z - zOffs);
t = (xOffs) + (zOffs);
if ((y > 0x8000) && (y < 0xC000) && (t < 1100.0f)) {
res = 2;
}
return res;
}
static int aPBOX_ctrl_light(STRUCTURE_ACTOR* shop) {
int now_sec = Common_Get(time.now_sec);
return !(now_sec < (64800) && now_sec >= (18000));
}
static void aPBOX_actor_move(ACTOR* actor, GAME* game) {
STRUCTURE_ACTOR* box;
GAME_PLAY* play;
s16 target;
xyz_t pos;
box = (STRUCTURE_ACTOR*)actor;
play = (GAME_PLAY*)game;
target = (s16)box->action;
if (aPBOX_ctrl_light(box)) {
chase_s(&target, DEG2SHORT_ANGLE(90.0f) - 1, 320); // 0x3FFF
} else {
chase_s(&target, DEG2SHORT_ANGLE(0.0f), 320);
}
box->action = target;
if (box == (*GET_PLAYER_ACTOR_NOW()->get_door_label_proc)(gamePT)) {
aPBOX_rewrite_out_data(box, play);
goto_other_scene(play, &aPBOX_police_box_enter_data, FALSE);
} else {
if (aPBOX_check_player(actor, play) == 2) {
pos.x = actor->world.position.x + 50.0f;
pos.y = GET_PLAYER_ACTOR(play)->actor_class.world.position.y;
pos.z = actor->world.position.z + 50.0f;
mPlib_request_main_door_type1(game, &pos, -DEG2SHORT_ANGLE(135.0f), TRUE, actor); //-0x6000
}
}
}
static void aPBOX_actor_init(ACTOR* actor, GAME* game) {
mFI_SetFG_common(DUMMY_POLICE_STATION, actor->home.position, FALSE);
aPBOX_actor_move(actor, game);
actor->mv_proc = &aPBOX_actor_move;
}