diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 226d3e59..f0d9fef0 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -833,6 +833,10 @@ ac_s_car.c: .text: [0x805B9098, 0x805B9644] .rodata: [0x8064AB68, 0x8064AB88] .data: [0x806C6608, 0x806C66D0] +ac_shop.c: + .text: [0x805B9644, 0x805BA4D8] + .rodata: [0x8064AB88, 0x8064ABD0] + .data: [0x806C66D0, 0x806C6838] ac_shrine.c: .text: [0x805BA4D8, 0x805BB8D0] .rodata: [0x8064ABD0, 0x8064AC18] diff --git a/include/ac_shop.h b/include/ac_shop.h index 2e41029e..c414e8a3 100644 --- a/include/ac_shop.h +++ b/include/ac_shop.h @@ -2,7 +2,7 @@ #define AC_SHOP_H #include "types.h" -#include "m_actor.h" +#include "ac_structure.h" #ifdef __cplusplus extern "C" { diff --git a/include/m_name_table.h b/include/m_name_table.h index 65b5b1cd..8309f383 100644 --- a/include/m_name_table.h +++ b/include/m_name_table.h @@ -2708,6 +2708,7 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define DUMMY_HOUSE1 0xF0F4 #define DUMMY_HOUSE2 0xF0F5 #define DUMMY_HOUSE3 0xF0F6 +#define DUMMY_SHOP0 0xF0F7 #define DUMMY_HANIWA0 0xF0FB #define DUMMY_HANIWA1 (DUMMY_HANIWA0 + 1) #define DUMMY_HANIWA2 (DUMMY_HANIWA1 + 1) diff --git a/src/ac_shop.c b/src/ac_shop.c new file mode 100644 index 00000000..bf639e61 --- /dev/null +++ b/src/ac_shop.c @@ -0,0 +1,137 @@ +#include "ac_shop.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" + +// clang-format off +enum { + aSHOP_ACTION_CLOSE_WAIT, + aSHOP_ACTION_OPEN_WAIT, + aSHOP_ACTION_CLOSE_DOOR, + aSHOP_ACTION_OPEN_DOOR, + aSHOP_ACTION_PL_INTO_WAIT, + + aSHOP_ACTION_NUM +}; +// clang-format on + +static void aSHOP_actor_ct(ACTOR* actor, GAME* game); +static void aSHOP_actor_dt(ACTOR* actor, GAME* game); +static void aSHOP_actor_init(ACTOR* actor, GAME* game); +static void aSHOP_actor_draw(ACTOR* actor, GAME* game); + +// clang-format off +ACTOR_PROFILE Shop_Profile = { + mAc_PROFILE_SHOP, + ACTOR_PART_ITEM, + ACTOR_STATE_TA_SET, + SHOP0, + ACTOR_OBJ_BANK_KEEP, + sizeof(STRUCTURE_ACTOR), + &aSHOP_actor_ct, + &aSHOP_actor_dt, + &aSHOP_actor_init, + &aSHOP_actor_draw, + NULL +}; +// clang-format on + +// clang-format off +static u8 aSHOP_shadow_vtx_fix_flg_table[] = { + TRUE, FALSE, TRUE, FALSE, + TRUE, FALSE, FALSE, TRUE +}; +// clang-format on + +extern Vtx obj_shop1_shadow_v[]; +extern Gfx obj_shop1_shadowT_model[]; + +// clang-format off +static bIT_ShadowData_c aSHOP_shadow_data = { + 8, + aSHOP_shadow_vtx_fix_flg_table, + 60.0f, + obj_shop1_shadow_v, + obj_shop1_shadowT_model +}; +// clang-format on + +extern cKF_Skeleton_R_c cKF_bs_r_obj_s_shop1; +extern cKF_Skeleton_R_c cKF_bs_r_obj_w_shop1; + +static void aSHOP_set_bgOffset(STRUCTURE_ACTOR* shop, int offs); +static void aSHOP_setup_action(STRUCTURE_ACTOR* shop, int action); +static int aSHOP_ctrl_light(STRUCTURE_ACTOR* shop); + +static void aSHOP_actor_ct(ACTOR* actor, GAME* game) { + static cKF_Skeleton_R_c* skl[] = { &cKF_bs_r_obj_s_shop1, &cKF_bs_r_obj_w_shop1 }; + + STRUCTURE_ACTOR* shop; + GAME_PLAY* play; + PLAYER_ACTOR* player; + int winter; + int action; + int x; + int z; + + shop = (STRUCTURE_ACTOR*)actor; + play = (GAME_PLAY*)game; + player = GET_PLAYER_ACTOR(play); + + shop->season = Common_Get(time.season); + action = aSHOP_ACTION_OPEN_WAIT; + winter = shop->season == mTM_SEASON_WINTER; + + cKF_SkeletonInfo_R_ct(&shop->keyframe, skl[winter], NULL, shop->work_area, shop->morph_area); + + aSHOP_set_bgOffset(shop, 1); + + actor->world.position.x = actor->world.position.x + -20.0f; + actor->world.position.z = actor->world.position.z + 20.0f; + actor->talk_distance = 80.0f; + actor->cull_width = 550.0f; + actor->cull_radius = 550.0f; + + if (mSP_ShopOpen() != 2) { + action = aSHOP_ACTION_CLOSE_WAIT; + } + + x = (int)(shop->actor_class.world.position.x - 68.29f); + z = (int)(shop->actor_class.world.position.z + 68.29f); + if ((int)player->actor_class.world.position.x == x && (int)player->actor_class.world.position.z == z) { + action = aSHOP_ACTION_OPEN_WAIT; + } + + aSHOP_setup_action(shop, action); + + if (aSHOP_ctrl_light(shop)) { + shop->arg0 = DEG2SHORT_ANGLE(90.0f) - 1; + } else { + shop->arg0 = DEG2SHORT_ANGLE(0.0f); + } + + shop->keyframe_state = cKF_SkeletonInfo_R_play(&shop->keyframe); + shop->keyframe_saved_keyframe = 1; +} + +static void aSHOP_actor_dt(ACTOR* actor, GAME* game) { + STRUCTURE_ACTOR* shop; + shop = (STRUCTURE_ACTOR*)actor; + + cKF_SkeletonInfo_R_dt(&shop->keyframe); + actor->world.position.x = actor->world.position.x - -20.0f; + actor->world.position.z = actor->world.position.z - 20.0f; +} + +#include "../src/ac_shop_move.c_inc" + +#include "../src/ac_shop_draw.c_inc" diff --git a/src/ac_shop_draw.c_inc b/src/ac_shop_draw.c_inc new file mode 100644 index 00000000..69b2b763 --- /dev/null +++ b/src/ac_shop_draw.c_inc @@ -0,0 +1,145 @@ +extern Gfx obj_s_shop1_window_model[]; +extern Gfx obj_w_shop1_window_model[]; + +static int aSHOP_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) { + STRUCTURE_ACTOR* shop; + GRAPH* graph; + f32 inter; + int angle; + int r; + int g; + int b; + Gfx* gfx; + + shop = (STRUCTURE_ACTOR*)arg; + graph = game->graph; + + if (joint_idx == 5) { + angle = shop->arg0; + if (angle == DEG2SHORT_ANGLE(90.0f) - 1) { // 0x3FFF + r = 255; + g = 255; + b = 150; + } else if (angle == DEG2SHORT_ANGLE(0.0f)) { + r = 0; + g = 0; + b = 0; + } else { + inter = (1.0f / (DEG2SHORT_ANGLE(90.0f) - 1)) * angle; + r = (255.0f * inter); + g = (255.0f * inter); + b = (150.0f * inter); + } + + OPEN_DISP(graph); + gfx = NOW_POLY_OPA_DISP; + + gDPSetEnvColor(gfx++, r, g, b, 0); + + SET_POLY_OPA_DISP(gfx); + CLOSE_DISP(graph); + + } else if (joint_idx == 6) { + *joint_shape = NULL; + } + + return TRUE; +} + +static int aSHOP_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* mdl[] = { obj_s_shop1_window_model, obj_w_shop1_window_model }; + + STRUCTURE_ACTOR* office; + GRAPH* graph; + Mtx* mtx; + int angle; + int winter; + int l; + int r; + int g; + int b; + int a; + Gfx* gfx; + + office = (STRUCTURE_ACTOR*)arg; + graph = game->graph; + + if (joint_idx == 6) { + mtx = _Matrix_to_Mtx_new(graph); + if (mtx != NULL) { + angle = office->arg0; + if (angle == DEG2SHORT_ANGLE(90.0f) - 1) { // 0x3FFF + l = 120; + r = 255; + g = 255; + b = 150; + a = 255; + } else if (angle == DEG2SHORT_ANGLE(0.0f)) { + l = 0; + r = 0; + g = 0; + b = 0; + a = 255; + } else { + r = 255; + g = 255; + b = 150; + a = 255; + l = (1.0f / (DEG2SHORT_ANGLE(90.0f) - 1)) * angle * 120.0f; + } + + winter = office->season == mTM_SEASON_WINTER; + + _texture_z_light_fog_prim_shadow(graph); + + OPEN_DISP(graph); + gfx = NOW_SHADOW_DISP; + + gDPSetPrimColor(gfx++, 0, l, r, g, b, a); + gSPMatrix(gfx++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(gfx++, mdl[winter]); + + SET_SHADOW_DISP(gfx); + CLOSE_DISP(graph); + } + } + + return TRUE; +} + +static void aSHOP_actor_draw(ACTOR* actor, GAME* game) { + GRAPH* graph; + cKF_SkeletonInfo_R_c* keyframe; + Mtx* mtx; + Gfx* gfx; + u16* pal; + GAME_PLAY* play; + STRUCTURE_ACTOR* shop; + + graph = game->graph; + play = (GAME_PLAY*)game; + shop = (STRUCTURE_ACTOR*)actor; + keyframe = &shop->keyframe; + + mtx = GRAPH_ALLOC_TYPE(graph, Mtx, (u32)keyframe->skeleton->num_shown_joints); + if (mtx == NULL) { + return; + } + + pal = Common_Get(clip).structure_clip->get_pal_segment_proc(aSTR_PAL_SHOP1); + + _texture_z_light_fog_prim_npc(graph); + + OPEN_DISP(graph); + gfx = NOW_POLY_OPA_DISP; + + gSPSegment(gfx++, 8, pal); + + SET_POLY_OPA_DISP(gfx); + CLOSE_DISP(graph); + + cKF_Si3_draw_R_SV(game, keyframe, mtx, &aSHOP_actor_draw_before, &aSHOP_actor_draw_after, actor); + (*Common_Get(clip).bg_item_clip->draw_shadow_proc)(game, &aSHOP_shadow_data, FALSE); +} diff --git a/src/ac_shop_move.c_inc b/src/ac_shop_move.c_inc new file mode 100644 index 00000000..67a2669e --- /dev/null +++ b/src/ac_shop_move.c_inc @@ -0,0 +1,335 @@ +extern cKF_Animation_R_c cKF_ba_r_obj_s_shop1; +extern cKF_Animation_R_c cKF_ba_r_obj_w_shop1; + +// clang-format off +static Door_data_c aSHOP_shop_door_data = { + SCENE_SHOP0, + mSc_DIRECT_NORTH, + FALSE, + 0, + {160,0,300}, + EMPTY_NO, + 1, + {0,0,0}, +}; +// clang-format on + +static void aSHOP_set_bgOffset(STRUCTURE_ACTOR* shop, int offs) { + // clang-format off + static mCoBG_OffsetTable_c height_table_ct[] = { + { mCoBG_ATTRIBUTE_NONE, 0, 0, 0, 0, 0, 0 }, + { mCoBG_ATTRIBUTE_NONE, 12, 12, 0, 12, 12, 1 }, + { mCoBG_ATTRIBUTE_NONE, 12, 12, 12, 0, 12, 1 }, + { mCoBG_ATTRIBUTE_NONE, 0, 0, 0, 0, 0, 0 }, + { mCoBG_ATTRIBUTE_NONE, 12, 12, 0, 12, 12, 1 }, + { mCoBG_ATTRIBUTE_NONE, 12, 12, 12, 12, 12, 0 }, + { mCoBG_ATTRIBUTE_NONE, 12, 12, 12, 12, 12, 0 }, + { mCoBG_ATTRIBUTE_NONE, 12, 12, 12, 0, 12, 1 }, + { mCoBG_ATTRIBUTE_NONE, 12, 0, 12, 12, 12, 1 }, + { mCoBG_ATTRIBUTE_NONE, 12, 12, 12, 12, 12, 0 }, + { mCoBG_ATTRIBUTE_NONE, 12, 12, 12, 12, 12, 0 }, + { mCoBG_ATTRIBUTE_NONE, 12, 12, 12, 12, 0, 1 }, + { mCoBG_ATTRIBUTE_NONE, 0, 0, 0, 0, 0, 0 }, + { mCoBG_ATTRIBUTE_NONE, 12, 0, 12, 12, 12, 1 }, + { mCoBG_ATTRIBUTE_NONE, 12, 12, 12, 12, 0, 1 }, + { mCoBG_ATTRIBUTE_NONE, 0, 0, 0, 0, 0, 0 } + }; + // clang-format on + + static mCoBG_OffsetTable_c* height_table[] = { height_table_ct, height_table_ct }; + + static f32 addX[] = { -(mFI_UT_WORLDSIZE_X_F * 2.0f), -mFI_UT_WORLDSIZE_X_F, 0.0f, mFI_UT_WORLDSIZE_X_F }; + static f32 addZ[] = { (mFI_UT_WORLDSIZE_Z_F * 2.0f), mFI_UT_WORLDSIZE_Z_F, 0.0f, -mFI_UT_WORLDSIZE_Z_F }; + + mCoBG_OffsetTable_c* offset; + int i; + int j; + xyz_t pos; + + offset = height_table[offs]; + for (i = 0; i < 4; i++) { + pos.z = shop->actor_class.home.position.z + addZ[i]; + + for (j = 0; j < 4; j++) { + if (j + i * 4 != 0 && j + i * 4 != 3 && j + i * 4 != 12 && j + i * 4 != 15) { + pos.x = shop->actor_class.home.position.x + addX[j]; + mCoBG_SetPluss5PointOffset_file(pos, *offset, __FILE__, 221); + } + + offset++; + } + } +} + +static void aSHOP_rewrite_out_data(ACTOR* actor, 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) { + return; + } + + door_data->next_scene_id = Save_Get(scene_no); + door_data->exit_orientation = mSc_DIRECT_SOUTH_WEST; + door_data->exit_type = 0; + door_data->extra_data = 3; + + pos.x = actor->world.position.x - 68.29f; + pos.z = actor->world.position.z + 68.29f; + 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 = SHOP0; + + door_data->wipe_type = 1; + + mBGMPsComp_make_ps_wipe(0x2168); +} + +static int aSHOP_check_player2(GAME_PLAY* play) { + PLAYER_ACTOR* player; + u16 y; + int res; + + player = GET_PLAYER_ACTOR(play); + y = player->actor_class.world.angle.y; + + res = 0; + if ((y > DEG2SHORT_ANGLE2(90.0f)) && (y < DEG2SHORT_ANGLE2(180.0f)) && + (player->actor_class.speed > 0.0f)) { // 0x6000 && 0xA000 + res = 1; + } + + return res; +} + +static int aSHOP_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 = 0; + + if (player == NULL) { + return 0; + } + + y = player->actor_class.shape_info.rotation.y; + xOffs = SQ(player->actor_class.world.position.x - (actor->world.position.x - 38.0f)); + zOffs = SQ(player->actor_class.world.position.z - (actor->world.position.z + 42.0f)); + t = (xOffs) + (zOffs); + + if ((y > DEG2SHORT_ANGLE2(90.0f)) && (y < DEG2SHORT_ANGLE2(180.0f)) && (t < 550.0f)) { + res = 1; + } + + return res; +} + +static void aSHOP_set_talk_info_close_wait(ACTOR* actor) { + rgba_t window_color; + int msg_no; + int now_sec; + int status; + + now_sec = Common_Get(time.now_sec); + if (mSP_CheckFukubikiDay() != FALSE) { + if (now_sec >= (6 * mTM_SECONDS_IN_HOUR)) { + msg_no = mSP_ShopOpen() == mSP_SHOP_STATUS_PRE ? 0x7D6 : 0x7D7; + } else { + msg_no = 0x7CD; + } + } else { + switch (mSP_ShopOpen()) { + case mSP_SHOP_STATUS_PRE: // 0 + case mSP_SHOP_STATUS_END: // 1 + msg_no = 0x7CD; + break; + case mSP_SHOP_STATUS_PREEVENT: // 4 + msg_no = 0x7D1; + break; + case mSP_SHOP_STATUS_ENDEVENT: // 5 + msg_no = 0x7D9; + break; + case mSP_SHOP_STATUS_RENEW: // 3 + msg_no = 0x7D8; + break; + default: + msg_no = 0x7CD; + break; + } + } + + mDemo_Set_msg_num(msg_no); + + mDemo_Set_talk_display_name(FALSE); + mDemo_Set_camera(TRUE); + mPlib_Set_able_hand_all_item_in_demo(TRUE); + 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 aSHOP_ctrl_light(STRUCTURE_ACTOR* shop) { + int now_sec; + int res; + + now_sec = Common_Get(time.now_sec); + res = FALSE; + if (mEv_CheckArbeit() == TRUE) { + if ((mSP_ShopOpen() == mSP_SHOP_STATUS_OPEN || mSP_ShopOpen() == mSP_SHOP_STATUS_OPENEVENT)) { + if ((now_sec >= (18 * mTM_SECONDS_IN_HOUR) || now_sec < (5 * mTM_SECONDS_IN_HOUR))) { + res = TRUE; + } + } + } else if (now_sec >= (18 * mTM_SECONDS_IN_HOUR) || now_sec < (5 * mTM_SECONDS_IN_HOUR)) { + if (shop->action == aSHOP_ACTION_PL_INTO_WAIT) { + res = TRUE; + } else if (mSP_ShopOpen() == mSP_SHOP_STATUS_OPEN || mSP_ShopOpen() == mSP_SHOP_STATUS_OPENEVENT) { + res = TRUE; + } + } + + return res; +} + +static void aSHOP_close_wait(STRUCTURE_ACTOR* shop, GAME_PLAY* play) { + ACTOR* actor; + + actor = (ACTOR*)shop; + + if (mDemo_Check(mDemo_TYPE_TALK, actor) == TRUE) { + return; + } + + if ((mSP_ShopOpen() == mSP_SHOP_STATUS_OPEN) || (mSP_ShopOpen() == mSP_SHOP_STATUS_OPENEVENT)) { + aSHOP_setup_action(shop, aSHOP_ACTION_OPEN_DOOR); + return; + } + + if (aSHOP_check_player(actor, play) == mSP_SHOP_STATUS_PRE) { + return; + } + + mDemo_Request(mDemo_TYPE_TALK, actor, &aSHOP_set_talk_info_close_wait); +} + +static void aSHOP_open_wait(STRUCTURE_ACTOR* shop, GAME_PLAY* play) { + ACTOR* actor; + GAME* game; + xyz_t pos; + + actor = &shop->actor_class; + game = &play->game; + + if (mPlib_check_player_actor_main_index_OutDoorMove(play) != FALSE) { + return; + } + + if (mSP_ShopOpen() != mSP_SHOP_STATUS_OPEN && mSP_ShopOpen() != mSP_SHOP_STATUS_OPENEVENT) { + sAdo_OngenTrgStart(8, &actor->world.position); + aSHOP_setup_action(shop, aSHOP_ACTION_CLOSE_DOOR); + return; + } + + if (aSHOP_check_player(actor, play) == 1 && aSHOP_check_player2(play) == TRUE) { + 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; + mSP_SetTanukiShopStatus(); + + if (mPlib_request_main_door_type1(game, &pos, DEG2SHORT_ANGLE(135.0f), TRUE, actor) == 0) { // 0x6000 + return; + } + + aSHOP_setup_action(shop, aSHOP_ACTION_PL_INTO_WAIT); + } +} + +static void aSHOP_close_door(STRUCTURE_ACTOR* shop, GAME_PLAY* play) { + if (shop->keyframe_state != 1) { + return; + } + + sAdo_OngenTrgStart(9, &shop->actor_class.world.position); + aSHOP_setup_action(shop, aSHOP_ACTION_CLOSE_WAIT); +} + +static void aSHOP_open_door(STRUCTURE_ACTOR* shop, GAME_PLAY* play) { + if (shop->keyframe_state != 1) { + return; + } + + aSHOP_setup_action(shop, aSHOP_ACTION_OPEN_WAIT); +} + +static void aSHOP_pl_into_wait(STRUCTURE_ACTOR* shop, GAME_PLAY* play) { + if (shop != GET_PLAYER_ACTOR_NOW()->get_door_label_proc(gamePT)) { + return; + } + + aSHOP_rewrite_out_data(&shop->actor_class, play); + goto_other_scene(play, &aSHOP_shop_door_data, FALSE); +} + +static void aSHOP_setup_action(STRUCTURE_ACTOR* shop, int action) { + static cKF_Animation_R_c* ani[] = { &cKF_ba_r_obj_s_shop1, &cKF_ba_r_obj_w_shop1 }; + static f32 anime_spd[] = { 0.0f, 0.0f, 0.5f, 0.5f, 0.0f }; + static f32 set[] = { 1.0f, 16.0f, 16.0f, 1.0f, 16.0f }; + static f32 end[] = { 1.0f, 16.0f, 1.0f, 16.0f, 16.0f }; + + static aSTR_MOVE_PROC process[] = { &aSHOP_close_wait, &aSHOP_open_wait, &aSHOP_close_door, &aSHOP_open_door, + &aSHOP_pl_into_wait }; + + int winter; + + winter = shop->season == mTM_SEASON_WINTER; + + cKF_SkeletonInfo_R_init(&shop->keyframe, shop->keyframe.skeleton, ani[winter], 1.0f, end[action], set[action], + anime_spd[action], 0.0f, cKF_FRAMECONTROL_STOP, NULL); + + shop->action_proc = process[action]; + shop->action = action; +} + +static void aSHOP_actor_move(ACTOR* actor, GAME* game) { + STRUCTURE_ACTOR* shop; + GAME_PLAY* play; + s16 target; + xyz_t pos; + + shop = (STRUCTURE_ACTOR*)actor; + play = (GAME_PLAY*)game; + + shop->keyframe_state = cKF_SkeletonInfo_R_play(&shop->keyframe); + shop->keyframe_saved_keyframe = shop->keyframe.frame_control.current_frame; + + (*shop->action_proc)(shop, play); + + target = (s16)shop->arg0; + if (aSHOP_ctrl_light(shop)) { + chase_s(&target, DEG2SHORT_ANGLE(90.0f) - 1, 320); // 0x3FFF + } else { + chase_s(&target, DEG2SHORT_ANGLE(0.0f), 320); + } + + shop->arg0 = target; +} + +static void aSHOP_actor_init(ACTOR* actor, GAME* game) { + mFI_SetFG_common(DUMMY_SHOP0, actor->home.position, FALSE); + aSHOP_actor_move(actor, game); + actor->mv_proc = aSHOP_actor_move; +}