From b440100ee0e2b5730d0e829a92c202f6ed2134a3 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Sun, 28 Apr 2024 20:44:07 -0400 Subject: [PATCH] Implement & link ac_insect --- config/rel_slices.yml | 5 + include/ac_insect.h | 2 +- include/ac_insect_h.h | 164 +++++++++-- include/m_collision_bg.h | 5 + include/m_lib.h | 3 +- include/m_lights.h | 2 +- include/m_player_lib.h | 1 + src/ac_insect.c | 81 ++++++ src/ac_insect_clip.c_inc | 327 ++++++++++++++++++++++ src/ac_insect_data.c_inc | 581 +++++++++++++++++++++++++++++++++++++++ src/ac_insect_draw.c_inc | 173 ++++++++++++ src/ac_insect_move.c_inc | 396 ++++++++++++++++++++++++++ 12 files changed, 1709 insertions(+), 31 deletions(-) create mode 100644 src/ac_insect.c create mode 100644 src/ac_insect_clip.c_inc create mode 100644 src/ac_insect_data.c_inc create mode 100644 src/ac_insect_draw.c_inc create mode 100644 src/ac_insect_move.c_inc diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 9d0709b4..9bcc7cc1 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -765,6 +765,11 @@ ac_ev_majin.c: .text: [0x80592A40, 0x80593158] .rodata: [0x80649D98, 0x80649DA0] .data: [0x806C2B50, 0x806C2BD0] +ac_insect.c: + .text: [0x80594344, 0x80595C74] + .rodata: [0x80649E00, 0x80649E70] + .data: [0x806C2C80, 0x806C3200] + .bss: [0x8131B2C8, 0x81320738] ac_boat.c: .text: [0x805A6CF4, 0x805A856C] .rodata: [0x8064A5B0, 0x8064A630] diff --git a/include/ac_insect.h b/include/ac_insect.h index 19ce5300..fb726696 100644 --- a/include/ac_insect.h +++ b/include/ac_insect.h @@ -3,6 +3,7 @@ #include "types.h" #include "m_actor.h" +#include "ac_insect_h.h" #ifdef __cplusplus extern "C" { @@ -15,4 +16,3 @@ extern ACTOR_PROFILE Insect_Profile; #endif #endif - diff --git a/include/ac_insect_h.h b/include/ac_insect_h.h index 402888aa..eceff8c2 100644 --- a/include/ac_insect_h.h +++ b/include/ac_insect_h.h @@ -4,54 +4,162 @@ #include "types.h" #include "m_actor.h" #include "m_lib.h" +#include "ac_tools.h" #ifdef __cplusplus extern "C" { #endif +#define aINS_ACTOR_NUM 9 +#define aINS_MAX_STRESS_DIST (3 * mFI_UNIT_BASE_SIZE_F) +#define aINS_PATIENCE_STEP 0.5f + +enum { + aINS_MAKE_NEW, + aINS_MAKE_EXIST, + + aINS_MAKE_NUM +}; + +enum { + aINS_PROGRAM_CHOU, + aINS_PROGRAM_BATTA, + aINS_PROGRAM_TONBO, + aINS_PROGRAM_TENTOU, + aINS_PROGRAM_HOTARU, + aINS_PROGRAM_SEMI, + aINS_PROGRAM_KABUTO, + aINS_PROGRAM_GOKI, + aINS_PROGRAM_HITODAMA, + aINS_PROGRAM_AMENBO, + aINS_PROGRAM_KA, + aINS_PROGRAM_DANGO, + aINS_PROGRAM_KERA, + aINS_PROGRAM_MINO, + + aINS_PROGRAM_NUM +}; + /* sizeof(aINS_Init_c) == 0x18 */ typedef struct insect_init_s { - /* 0x00 */ int insect_type; - /* 0x04 */ xyz_t position; - /* 0x10 */ int extra_data; - /* 0x14 */ GAME* game; + /* 0x00 */ int insect_type; + /* 0x04 */ xyz_t position; + /* 0x10 */ int extra_data; + /* 0x14 */ GAME* game; } aINS_Init_c; -/* sizeof(aINS_INSECT_DUMMY_ACTOR) == 0x288 */ -typedef struct insect_dummy_actor_s { - ACTOR actor; - /* TODO: finish */ -} aINS_INSECT_DUMMY_ACTOR; +typedef void (*aINS_MOVE_PROC)(ACTOR*); +typedef void (*aINS_ACTION_PROC)(ACTOR*, GAME*); -typedef aINS_INSECT_DUMMY_ACTOR* (*aINS_make_insect_proc)(aINS_Init_c*, int); +/* sizeof(aINS_INSECT_ACTOR) == 0x288 */ +typedef struct insect_actor_s { + TOOLS_ACTOR tools_actor; /* why tools actor? */ + int exist_flag; + int type; + aINS_MOVE_PROC move_proc; + int action; + aINS_ACTION_PROC action_proc; + f32 _1E0; + f32 _1E4; + f32 speed_step; + f32 target_speed; + f32 patience; + ClObjPipe_c col_pipe; + f32 bg_range; + f32 bg_height; + int bg_type; + mActor_name_t item; + struct { + u8 destruct : 1; + u8 bit_1 : 1; + u8 bit_2 : 1; + u8 bit_3 : 1; + u8 bit_4 : 1; + u8 bit_5 : 1; + u8 bit_6 : 1; + u8 bit_7 : 1; + } insect_flags; + int life_time; + int alpha_time; + int timer; + int continue_timer; + int flag; + + /* Dynamic for each insect actor type */ + int s32_work0; + int s32_work1; + int s32_work2; + int s32_work3; + + f32 f32_work0; + f32 f32_work1; + f32 f32_work2; + f32 f32_work3; + + int _254; + int _258; + int alpha0; + int alpha1; + int alpha2; + s16 ut_x; + s16 ut_z; + + Lights point_light; + Light_list* light_list; + int light_flag; + s16 light_counter; + s16 light_step; +} aINS_INSECT_ACTOR; + +/* sizeof(aINS_CTRL_ACTOR) == 0x183C */ +typedef struct insect_ctrl_actor_s { + ACTOR actor_class; + aINS_INSECT_ACTOR insect_actor[aINS_ACTOR_NUM]; +} aINS_CTRL_ACTOR; + +/* sizeof(aINS_overlay_entry_c) == 0x1C08 */ +typedef struct insect_overlay_s { + u8 data[0x1C00]; + int _1C00; + int _1C04; +} ATTRIBUTE_ALIGN(8) aINS_overlay_entry_c; + +typedef struct { + aINS_overlay_entry_c entries[3]; +} aINS_overlay_c; + +typedef ACTOR* (*aINS_make_insect_proc)(aINS_Init_c*, int); typedef void (*aINS_make_ant_proc)(aINS_Init_c*, s8, s8); typedef void (*aINS_dt_proc)(ACTOR*, GAME*); -typedef aINS_INSECT_DUMMY_ACTOR* (*aINS_make_actor_proc)(GAME*, int, xyz_t*); +typedef ACTOR* (*aINS_make_actor_proc)(GAME*, int, xyz_t*); typedef void (*aINS_set_pl_act_tim_proc)(int, int, int); typedef int (*aINS_chk_live_insect_proc)(int, int, GAME*); typedef void (*aINS_position_move_proc)(ACTOR*); -typedef ACTOR* (*aINS_search_near_insect_proc)(GAME*, f32, f32); +typedef ACTOR* (*aINS_search_near_insect_proc)(f32, f32, GAME*); /* sizeof(aINS_Clip_c) == 0x50 */ typedef struct ac_insect_clip_s { - /* 0x00 */ aINS_make_insect_proc make_insect_proc; - /* 0x04 */ aINS_make_ant_proc make_ant_proc; // unused clip proc in AC - /* 0x08 */ void* unused_08; - /* 0x0C */ aINS_dt_proc dt_proc; - /* 0x10 */ aINS_make_actor_proc make_actor_proc; - /* 0x14 */ aINS_set_pl_act_tim_proc set_pl_act_tim_proc; - /* 0x18 */ aINS_chk_live_insect_proc chk_live_insect_proc; - /* 0x1C */ aINS_search_near_insect_proc search_near_insect_proc; - /* 0x20 */ int pl_action; - /* 0x24 */ int pl_action_ut_x; - /* 0x28 */ int pl_action_ut_z; - /* 0x2C */ aINS_position_move_proc position_move_proc; - /* 0x30 */ int ant_spawn_pending; - /* 0x34 */ aINS_Init_c ant_spawn_info; - /* 0x4C */ u8 ant_ut_x; - /* 0x4D */ u8 ant_ut_z; + /* 0x00 */ aINS_make_insect_proc make_insect_proc; + /* 0x04 */ aINS_make_ant_proc make_ant_proc; // unused clip proc in AC + /* 0x08 */ void* unused_08; + /* 0x0C */ aINS_dt_proc dt_proc; + /* 0x10 */ aINS_make_actor_proc make_actor_proc; + /* 0x14 */ aINS_set_pl_act_tim_proc set_pl_act_tim_proc; + /* 0x18 */ aINS_chk_live_insect_proc chk_live_insect_proc; + /* 0x1C */ aINS_search_near_insect_proc search_near_insect_proc; + /* 0x20 */ int pl_action; + /* 0x24 */ int pl_action_ut_x; + /* 0x28 */ int pl_action_ut_z; + /* 0x2C */ aINS_position_move_proc position_move_proc; + /* 0x30 */ int ant_spawn_pending; + /* 0x34 */ aINS_Init_c ant_spawn_info; + /* 0x4C */ s8 ant_bx; + /* 0x4D */ s8 ant_bz; } aINS_Clip_c; +/* must include m_common_data.h to use this macro */ +#define aINS_CLIP (Common_Get(clip).insect_clip) + #ifdef __cplusplus } #endif diff --git a/include/m_collision_bg.h b/include/m_collision_bg.h index 360dbe54..3c4b3e6d 100644 --- a/include/m_collision_bg.h +++ b/include/m_collision_bg.h @@ -286,6 +286,11 @@ extern int mCoBG_RangeCheckLinePoint(f32* start_xz, f32* end_xz, f32* point_xz); extern int mCoBG_GetDistPointAndLine2D_Norm(f32* dist, f32* start_xz, f32* end_xz, f32* norm, f32* point_xz); extern f32 mCoBG_Get2VectorAngleF(f32* v0, f32* v1, u8 type); extern int mCoBG_CheckUtFlat(const xyz_t* pos); +extern void mCoBG_BgCheckControll_RemoveDirectedUnitColumn(xyz_t* reverse_pos, ACTOR* actor, f32 check_range, + f32 offset_y, s16 wall_attr_check, s16 no_reverse, + s16 check_type, int ut_x, int ut_z); +extern xyz_t mCoBG_UniqueWallCheck(ACTOR* actorx, f32 range, f32 y_ofs); +extern xyz_t mCoBG_ScopeWallCheck(ACTOR* actorx, const xyz_t* pos, f32 x, f32 z, f32 range, f32 y_ofs); extern void mCoBG_InitMoveBgData(); extern void mCoBG_InitBlockBgCheckMode(); diff --git a/include/m_lib.h b/include/m_lib.h index 5180ca21..6c28288e 100644 --- a/include/m_lib.h +++ b/include/m_lib.h @@ -15,7 +15,8 @@ extern "C" { #define SHT_MINV (1.0f / SHT_MAX) #define ABS(x) (((x) >= 0) ? (x) : -(x)) #define SQ(x) ((x) * (x)) -#define CLAMP_MAX(x, min) ((min) < (x) ? (min) : (x)) +#define CLAMP_MIN(x, min) ((x) < (min) ? (min) : (x)) +#define CLAMP_MAX(x, max) ((max) < (x) ? (max) : (x)) #define CLAMP(x, min, max) ((x) < (min) ? (min) : ((x > (max) ? (max) : (x)))) /* Float modulo operator */ diff --git a/include/m_lights.h b/include/m_lights.h index 5279ba47..81ff7356 100644 --- a/include/m_lights.h +++ b/include/m_lights.h @@ -34,7 +34,7 @@ typedef union { typedef struct lights_s { u8 type; LightParams lights; -} Lights; +} Lights; // size = 0xE typedef struct light_list { /* 0x0 */ Lights* info; diff --git a/include/m_player_lib.h b/include/m_player_lib.h index a85da2a0..d6eeafe8 100644 --- a/include/m_player_lib.h +++ b/include/m_player_lib.h @@ -71,6 +71,7 @@ extern int mPlib_check_player_actor_main_index_Furniture_Move(GAME* game); extern int mPlib_request_main_sitdown_type1(GAME* game, int direct, const xyz_t* pos, int ftr_no); extern int mPlib_request_main_lie_bed_type1(GAME* game, int direct, const xyz_t* pos, int head_direct, int ftr_no); extern void mPlib_change_player_cloth(GAME* game, int idx); +extern u32 mPlib_Get_item_net_catch_label(void); extern mPlayer_change_data_from_submenu_c* mPlib_Get_change_data_from_submenu_p(); diff --git a/src/ac_insect.c b/src/ac_insect.c new file mode 100644 index 00000000..4a374b69 --- /dev/null +++ b/src/ac_insect.c @@ -0,0 +1,81 @@ +#include "ac_insect.h" + +#include "m_name_table.h" +#include "m_common_data.h" +#include "ac_set_ovl_insect.h" +#include "m_player_lib.h" +#include "m_actor_shadow.h" +#include "libultra/libultra.h" +#include "m_skin_matrix.h" +#include "sys_matrix.h" +#include "m_rcp.h" + +static aINS_CTRL_ACTOR* aINS_ctrlActor = NULL; +static aINS_overlay_c aINS_overlay; +static aINS_Clip_c aINS_clip; + +/* order .bss */ +#ifdef MUST_MATCH +BSS_ORDER_GROUP_START +BSS_ORDER_ITEM(aINS_ctrlActor); +BSS_ORDER_ITEM(aINS_overlay); +BSS_ORDER_ITEM(aINS_clip); +BSS_ORDER_GROUP_END +#endif + +static void aINS_actor_ct(ACTOR* actorx, GAME* game); +static void aINS_actor_dt(ACTOR* actorx, GAME* game); +static void aINS_actor_move(ACTOR* actorx, GAME* game); +static void aINS_actor_draw(ACTOR* actorx, GAME* game); + +// clang-format off +ACTOR_PROFILE Insect_Profile = { + mAc_PROFILE_INSECT, + ACTOR_PART_CONTROL, + ACTOR_STATE_NO_DRAW_WHILE_CULLED | ACTOR_STATE_NO_MOVE_WHILE_CULLED, + EMPTY_NO, + ACTOR_OBJ_BANK_KEEP, + sizeof(aINS_CTRL_ACTOR), + &aINS_actor_ct, + &aINS_actor_dt, + &aINS_actor_move, + &aINS_actor_draw, + NULL +}; +// clang-format on + +static void aINS_position_move(ACTOR* actorx); + +#include "../src/ac_insect_data.c_inc" +#include "../src/ac_insect_clip.c_inc" +#include "../src/ac_insect_move.c_inc" +#include "../src/ac_insect_draw.c_inc" + +static void aINS_actor_ct(ACTOR* actorx, GAME* game) { + aINS_CTRL_ACTOR* ctrl_actor = (aINS_CTRL_ACTOR*)actorx; + aINS_INSECT_ACTOR* insect_actor; + aINS_overlay_entry_c* overlay_p; + int i; + + aINS_ctrlActor = ctrl_actor; + aINS_init_dma_and_clip_area(ctrl_actor); + insect_actor = ctrl_actor->insect_actor; + overlay_p = aINS_overlay.entries; + + for (i = 0; i < aINS_ACTOR_NUM; i++) { + insect_actor->exist_flag = FALSE; + insect_actor->_254 = 0; + insect_actor->_258 = 0; + insect_actor++; + } + + for (i = 0; i < 3; i++) { + overlay_p->_1C00 = aINS_PROGRAM_NUM; + overlay_p->_1C04 = 0; + overlay_p++; + } +} + +static void aINS_actor_dt(ACTOR* actorx, GAME* game) { + aINS_free_clip_area(); +} diff --git a/src/ac_insect_clip.c_inc b/src/ac_insect_clip.c_inc new file mode 100644 index 00000000..ac416727 --- /dev/null +++ b/src/ac_insect_clip.c_inc @@ -0,0 +1,327 @@ +static ACTOR* aINS_make_actor(GAME* game, int type, xyz_t* pos) { + aINS_Init_c init_data; + + xyz_t_move(&init_data.position, pos); + init_data.insect_type = type; + init_data.extra_data = 1; + init_data.game = game; + + return aINS_CLIP->make_insect_proc(&init_data, 1); +} + +static int aINS_get_free_idx_set_block_table(mEv_gst_hitodama_block_c* block_table) { + int res = -1; + + if (block_table != NULL) { + int i; + + for (i = 0; i < mEv_GHOST_HITODAMA_NUM; i++) { + if (block_table->block_x[i] == 0xFF && block_table->block_z[i] == 0xFF) { + res = i; + break; + } + } + } + + return res; +} + +static void aINS_regist_set_block_table(ACTOR* actorx) { + mEv_gst_common_c* gst_common = (mEv_gst_common_c*)mEv_get_common_area(mEv_EVENT_GHOST, 55); + int free_idx = aINS_get_free_idx_set_block_table(&gst_common->hitodama_block_data); + + if (free_idx != -1) { + int bx; + int bz; + int i; + + /* Select random unused acre */ + while (TRUE) { + bx = (int)(1.0f + RANDOM_F(FG_BLOCK_X_NUM)); + bz = (int)(1.0f + RANDOM_F(FG_BLOCK_Z_NUM)); + + if (actorx->block_x != (u8)bx || actorx->block_z != (u8)bz) { + for (i = 0; i < mEv_GHOST_HITODAMA_NUM; i++) { + if (gst_common->hitodama_block_data.block_x[i] == (u8)bx && + gst_common->hitodama_block_data.block_z[i] == (u8)bz) { + break; + } + } + + /* If i is 5 then none of the spirits are in the same acre */ + if (i == 5) { + break; + } + } + } + + gst_common->hitodama_block_data.block_x[free_idx] = bx; + gst_common->hitodama_block_data.block_z[free_idx] = bz; + } +} + +static void aINS_destruct(ACTOR* actorx, GAME* game) { + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + + switch (insect->type) { + case aSOI_INSECT_TYPE_SPIRIT: + /* If we didn't catch the spirit, update it's location */ + if ((ACTOR*)mPlib_Get_item_net_catch_label() != actorx) { + aINS_regist_set_block_table(actorx); + } + /* fallthrough spirit -> firefly */ + case aSOI_INSECT_TYPE_FIREFLY: + if (insect->light_flag) { + Global_light_list_delete(&play->global_light, insect->light_list); + insect->light_flag = FALSE; + } + break; + } + + insect->exist_flag = FALSE; + ClObjPipe_dt(game, &insect->col_pipe); +} + +static int aINS_chk_live_ant(int bx, int bz, GAME* game) { + GAME_PLAY* play = (GAME_PLAY*)game; + Actor_list* bg_list = &play->actor_info.list[ACTOR_PART_BG]; + int res = FALSE; + ACTOR* actor = bg_list->actor; + int i; + + for (i = 0; i != bg_list->num_actors; i++) { + if (actor != NULL && actor->id == mAc_PROFILE_ANT && actor->block_x == bx && actor->block_z == bz) { + res = TRUE; + break; + } + + actor = actor->next_actor; + } + + return res; +} + +static int aINS_chk_live_insect(int bx, int bz, GAME* game) { + aINS_INSECT_ACTOR* insect = aINS_ctrlActor->insect_actor; + int res = FALSE; + + if (aINS_chk_live_ant(bx, bz, game) == TRUE) { + res = TRUE; + } else { + int i; + + for (i = 0; i < aINS_ACTOR_NUM - 1; i++) { + if (insect->exist_flag == TRUE && insect->tools_actor.actor_class.block_x == bx && + insect->tools_actor.actor_class.block_z == bz) { + res = TRUE; + break; + } + + insect++; + } + } + + return res; +} + +static ACTOR* aINS_search_near_ant(f32 pos_x, f32 pos_z, f32* dist, GAME* game) { + GAME_PLAY* play = (GAME_PLAY*)game; + Actor_list* bg_list = &play->actor_info.list[ACTOR_PART_BG]; + ACTOR* res = NULL; + ACTOR* actor = bg_list->actor; + int max = bg_list->num_actors; + int i; + + /* Find the closest ant actor (if any) */ + for (i = 0; i != max; i++) { + if (actor != NULL && actor->id == mAc_PROFILE_ANT) { + f32 dX = actor->world.position.x - pos_x; + f32 dZ = actor->world.position.z - pos_z; + f32 d = SQ(dX) + SQ(dZ); + + if (d < *dist) { + res = actor; + *dist = d; + } + } + + actor = actor->next_actor; + } + + return res; +} + +static ACTOR* aINS_search_near_insect(f32 pos_x, f32 pos_z, GAME* game) { + aINS_INSECT_ACTOR* insect = aINS_ctrlActor->insect_actor; + f32 dist = 819200.0f; + ACTOR* res = aINS_search_near_ant(pos_x, pos_z, &dist, game); + int i; + + for (i = 0; i < aINS_ACTOR_NUM - 1; i++) { + if (insect->exist_flag == TRUE) { + f32 dX = insect->tools_actor.actor_class.world.position.x - pos_x; + f32 dZ = insect->tools_actor.actor_class.world.position.z - pos_z; + f32 d = SQ(dX) + SQ(dZ); + + if (d < dist) { + res = (ACTOR*)insect; + dist = d; + } + } + + insect++; + } + + return res; +} + +static int aINS_searchRegistSpace(int make_type) { + aINS_INSECT_ACTOR* insect = aINS_ctrlActor->insect_actor; + + if (make_type == aINS_MAKE_NEW) { + int i; + + for (i = 0; i < aINS_ACTOR_NUM - 1; i++) { + if (insect->exist_flag == FALSE) { + return i; + } + + insect++; + } + } else { /* aINS_MAKE_EXIST -- spawn physical actor? */ + if (insect[aINS_ACTOR_NUM - 1].exist_flag == FALSE) { + return aINS_ACTOR_NUM - 1; + } + } + + return -1; +} + +static void aINS_setupActor(ACTOR* actorx, aINS_Init_c* init) { + // clang-format off + static ACTOR_PROFILE Dummy_Profile = { + mAc_PROFILE_INSECT, + ACTOR_PART_BG, + ACTOR_STATE_NO_DRAW_WHILE_CULLED | ACTOR_STATE_NO_MOVE_WHILE_CULLED, + EMPTY_NO, + ACTOR_OBJ_BANK_KEEP, + sizeof(ACTOR), + mActor_NONE_PROC1, + mActor_NONE_PROC1, + mActor_NONE_PROC1, + mActor_NONE_PROC1, + NULL + }; + // clang-format on + + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)init->game; + f32 shadow_size; + + insect->exist_flag = TRUE; + insect->type = init->insect_type; + insect->action_proc = (aINS_ACTION_PROC)&none_proc1; + insect->life_time = 216000; + insect->alpha0 = 255; + insect->insect_flags.bit_4 = TRUE; + insect->bg_range = 12.0f; + insect->ut_x = -1; + insect->ut_z = -1; + + Actor_init_actor_class(actorx, &Dummy_Profile, NULL, play, -1, init->position.x, init->position.y, init->position.z, + 0, 0, 0, play->block_table.block_x, play->block_table.block_z, -1, EMPTY_NO, + init->extra_data); + actorx->world = actorx->home; + actorx->shape_info.rotation = actorx->world.angle; + Actor_world_to_eye(actorx, 0.0f); + xyz_t_move(&actorx->last_world_position, &actorx->world.position); + actorx->scale.x = 0.01f; + actorx->scale.y = 0.01f; + actorx->scale.z = 0.01f; + actorx->cull_width = 350.0f; + actorx->cull_height = 700.0f; + actorx->cull_distance = 1000.0f; + actorx->cull_radius = 350.0f; + + switch (insect->type) { + case aSOI_INSECT_TYPE_TIGER_BUTTERFLY: + case aSOI_INSECT_TYPE_PURPLE_BUTTERFLY: + case aSOI_INSECT_TYPE_ROBUST_CICADA: + case aSOI_INSECT_TYPE_WALKER_CICADA: + case aSOI_INSECT_TYPE_EVENING_CICADA: + case aSOI_INSECT_TYPE_BROWN_CICADA: + case aSOI_INSECT_TYPE_BEE: + case aSOI_INSECT_TYPE_COMMON_DRAGONFLY: + case aSOI_INSECT_TYPE_RED_DRAGONFLY: + case aSOI_INSECT_TYPE_DARNER_DRAGONFLY: + case aSOI_INSECT_TYPE_BANDED_DRAGONFLY: + shadow_size = 8.0f; + break; + + case aSOI_INSECT_TYPE_BAGWORM: + case aSOI_INSECT_TYPE_PILL_BUG: + case aSOI_INSECT_TYPE_SPIDER: + case aSOI_INSECT_TYPE_MOSQUITO: + shadow_size = 4.0f; + break; + + case aSOI_INSECT_TYPE_ANT: + shadow_size = 2.0f; + break; + + default: + shadow_size = 6.0f; + break; + } + + Shape_Info_init(actorx, 0.0f, &mAc_ActorShadowCircle, shadow_size, shadow_size); + actorx->shape_info.shadow_alpha_change_rate = 0.4f; + actorx->mv_proc = aINS_program_dlftbl[aINS_program_type[insect->type]]; + insect->move_proc = &aINS_position_move; + actorx->drawn = TRUE; +} + +static ACTOR* aINS_make_insect(aINS_Init_c* init, int make_type) { + int free_idx = aINS_searchRegistSpace(make_type); + + if (free_idx >= 0) { + aINS_INSECT_ACTOR* insect = &aINS_ctrlActor->insect_actor[free_idx]; + + bzero(insect, sizeof(aINS_INSECT_ACTOR)); + aINS_setupActor((ACTOR*)insect, init); + return (ACTOR*)insect; + } + + return NULL; +} + +static void aINS_make_ant(aINS_Init_c* init, s8 bx, s8 bz) { + aINS_CLIP->ant_spawn_pending = TRUE; + bcopy(init, &aINS_CLIP->ant_spawn_info, sizeof(aINS_Init_c)); + aINS_CLIP->ant_bx = bx; + aINS_CLIP->ant_bz = bz; +} + +static void aINS_set_pl_act_tim(int action, int ut_x, int ut_z) { + aINS_CLIP->pl_action = action; + aINS_CLIP->pl_action_ut_x = ut_x; + aINS_CLIP->pl_action_ut_z = ut_z; +} + +static void aINS_init_dma_and_clip_area(aINS_CTRL_ACTOR* ctrl_actor) { + aINS_CLIP = &aINS_clip; + bzero(&aINS_clip, sizeof(aINS_Clip_c)); + aINS_CLIP->make_insect_proc = &aINS_make_insect; + aINS_CLIP->make_ant_proc = &aINS_make_ant; + aINS_CLIP->dt_proc = &aINS_destruct; + aINS_CLIP->make_actor_proc = &aINS_make_actor; + aINS_CLIP->set_pl_act_tim_proc = &aINS_set_pl_act_tim; + aINS_CLIP->chk_live_insect_proc = &aINS_chk_live_insect; + aINS_CLIP->position_move_proc = &aINS_position_move; + aINS_CLIP->search_near_insect_proc = &aINS_search_near_insect; +} + +static void aINS_free_clip_area(void) { + aINS_CLIP = NULL; +} diff --git a/src/ac_insect_data.c_inc b/src/ac_insect_data.c_inc new file mode 100644 index 00000000..b25e3d75 --- /dev/null +++ b/src/ac_insect_data.c_inc @@ -0,0 +1,581 @@ +extern Gfx act_m_abura1_1T_model[]; +extern Gfx act_m_abura1_2T_model[]; +extern Gfx act_m_abura1_1T_model[]; +extern Gfx act_m_abura2_2T_model[]; +extern Gfx act_m_akiakane1_1T_model[]; +extern Gfx act_m_akiakane1_2T_model[]; +extern Gfx act_m_akiakane1_1T_model[]; +extern Gfx act_m_akiakane2_2T_model[]; +extern Gfx act_m_danna1T_model[]; +extern Gfx act_m_danna1T_model[]; +extern Gfx act_m_danna2T_model[]; +extern Gfx act_m_danna2T_model[]; +extern Gfx act_m_genji2_a_model[]; +extern Gfx act_m_genji2_b_model[]; +extern Gfx act_m_genji2_c_model[]; +extern Gfx act_m_genji2_d_model[]; +extern Gfx act_m_ginyanma1_1T_model[]; +extern Gfx act_m_ginyanma1_2T_model[]; +extern Gfx act_m_ginyanma1_1T_model[]; +extern Gfx act_m_ginyanma2_2T_model[]; +extern Gfx act_m_higurashi1_1T_model[]; +extern Gfx act_m_higurashi1_2T_model[]; +extern Gfx act_m_higurashi1_1T_model[]; +extern Gfx act_m_higurashi2_2T_model[]; +extern Gfx act_m_hirata1T_model[]; +extern Gfx act_m_hirata1T_model[]; +extern Gfx act_m_hirata2T_model[]; +extern Gfx act_m_hirata2T_model[]; +extern Gfx act_m_kabuto1T_model[]; +extern Gfx act_m_kabuto1T_model[]; +extern Gfx act_m_kabuto2T_model[]; +extern Gfx act_m_kabuto2T_model[]; +extern Gfx act_m_kamakiri1T_model[]; +extern Gfx act_m_kamakiri1T_model[]; +extern Gfx act_m_kamakiri1T_model[]; +extern Gfx act_m_kamakiri2_2T_model[]; +extern Gfx act_m_kanabun1T_model[]; +extern Gfx act_m_kanabun1T_model[]; +extern Gfx act_m_kanabun2T_model[]; +extern Gfx act_m_kanabun2T_model[]; +extern Gfx act_m_kiageha1T_model[]; +extern Gfx act_m_kiageha1T_model[]; +extern Gfx act_m_kiageha2T_model[]; +extern Gfx act_m_kiageha2T_model[]; +extern Gfx act_m_kirigirisu1T_model[]; +extern Gfx act_m_kirigirisu1T_model[]; +extern Gfx act_m_kirigirisu1T_model[]; +extern Gfx act_m_kirigirisu2_2T_model[]; +extern Gfx act_m_koorogi1T_model[]; +extern Gfx act_m_koorogi1T_model[]; +extern Gfx act_m_koorogi1T_model[]; +extern Gfx act_m_koorogi1T_model[]; +extern Gfx act_m_hachi1_1T_model[]; +extern Gfx act_m_hachi1_2T_model[]; +extern Gfx act_m_hachi1_1T_model[]; +extern Gfx act_m_hachi2_2T_model[]; +extern Gfx act_m_matumushi1T_model[]; +extern Gfx act_m_matumushi1T_model[]; +extern Gfx act_m_matumushi1T_model[]; +extern Gfx act_m_matumushi1T_model[]; +extern Gfx act_m_minmin1_1T_model[]; +extern Gfx act_m_minmin1_2T_model[]; +extern Gfx act_m_minmin1_1T_model[]; +extern Gfx act_m_minmin2_2T_model[]; +extern Gfx act_m_monki1T_model[]; +extern Gfx act_m_monki1T_model[]; +extern Gfx act_m_monki2T_model[]; +extern Gfx act_m_monki2T_model[]; +extern Gfx act_m_monshiro1T_model[]; +extern Gfx act_m_monshiro1T_model[]; +extern Gfx act_m_monshiro2T_model[]; +extern Gfx act_m_monshiro2T_model[]; +extern Gfx act_m_nanahoshi1T_model[]; +extern Gfx act_m_nanahoshi1T_model[]; +extern Gfx act_m_nanahoshi2T_model[]; +extern Gfx act_m_nanahoshi2T_model[]; +extern Gfx act_m_ohmurasaki1T_model[]; +extern Gfx act_m_ohmurasaki1T_model[]; +extern Gfx act_m_ohmurasaki2T_model[]; +extern Gfx act_m_ohmurasaki2T_model[]; +extern Gfx act_m_oniyanma1_1T_model[]; +extern Gfx act_m_oniyanma1_2T_model[]; +extern Gfx act_m_oniyanma1_1T_model[]; +extern Gfx act_m_oniyanma2_2T_model[]; +extern Gfx act_m_shiokara1_1T_model[]; +extern Gfx act_m_shiokara1_2T_model[]; +extern Gfx act_m_shiokara1_1T_model[]; +extern Gfx act_m_shiokara2_2T_model[]; +extern Gfx act_m_suzumushi1T_model[]; +extern Gfx act_m_suzumushi1T_model[]; +extern Gfx act_m_suzumushi1T_model[]; +extern Gfx act_m_suzumushi2_2T_model[]; +extern Gfx act_m_syouryou1T_model[]; +extern Gfx act_m_syouryou1T_model[]; +extern Gfx act_m_syouryou1T_model[]; +extern Gfx act_m_syouryou2_2T_model[]; +extern Gfx act_m_tamamushi1T_model[]; +extern Gfx act_m_tamamushi1T_model[]; +extern Gfx act_m_tamamushi2T_model[]; +extern Gfx act_m_tamamushi2T_model[]; +extern Gfx act_m_gomadara1T_model[]; +extern Gfx act_m_gomadara1T_model[]; +extern Gfx act_m_gomadara2T_model[]; +extern Gfx act_m_gomadara2T_model[]; +extern Gfx act_m_tentou1T_model[]; +extern Gfx act_m_tentou1T_model[]; +extern Gfx act_m_tentou2T_model[]; +extern Gfx act_m_tentou2T_model[]; +extern Gfx act_m_tonosama1T_model[]; +extern Gfx act_m_tonosama1T_model[]; +extern Gfx act_m_tonosama1T_model[]; +extern Gfx act_m_tonosama2_2T_model[]; +extern Gfx act_m_tukutuku1_1T_model[]; +extern Gfx act_m_tukutuku1_2T_model[]; +extern Gfx act_m_tukutuku1_1T_model[]; +extern Gfx act_m_tukutuku2_2T_model[]; +extern Gfx act_m_nokogiri1T_model[]; +extern Gfx act_m_nokogiri1T_model[]; +extern Gfx act_m_nokogiri2T_model[]; +extern Gfx act_m_nokogiri2T_model[]; +extern Gfx act_m_miyama1T_model[]; +extern Gfx act_m_miyama1T_model[]; +extern Gfx act_m_miyama2T_model[]; +extern Gfx act_m_miyama2T_model[]; +extern Gfx act_m_okuwa1T_model[]; +extern Gfx act_m_okuwa1T_model[]; +extern Gfx act_m_okuwa2T_model[]; +extern Gfx act_m_okuwa2T_model[]; +extern Gfx act_m_amenbo1T_model[]; +extern Gfx act_m_amenbo1T_model[]; +extern Gfx act_m_amenbo1T_model[]; +extern Gfx act_m_amenbo2T_model[]; +extern Gfx act_m_ariT_model[]; +extern Gfx act_m_ariT_model[]; +extern Gfx act_m_ariT_model[]; +extern Gfx act_m_ariT_model[]; +extern Gfx act_m_dango2T_model[]; +extern Gfx act_m_dango2T_model[]; +extern Gfx act_m_dango1T_model[]; +extern Gfx act_m_dango1T_model[]; +extern Gfx act_m_ka1T_model[]; +extern Gfx act_m_ka2_2T_model[]; +extern Gfx act_m_ka1T_model[]; +extern Gfx act_m_ka2_1T_model[]; +extern Gfx act_m_keraT_model[]; +extern Gfx act_m_keraT_model[]; +extern Gfx act_m_kumo1_2T_model[]; +extern Gfx act_m_kumo1_2T_model[]; +extern Gfx act_m_kumo1_1T_model[]; +extern Gfx act_m_kumo2T_model[]; +extern Gfx act_m_maimaiT_model[]; +extern Gfx act_m_maimaiT_model[]; +extern Gfx act_m_maimaiT_model[]; +extern Gfx act_m_maimaiT_model[]; +extern Gfx act_m_mino1_1T_model[]; +extern Gfx act_m_mino1_1T_model[]; +extern Gfx act_m_mino1_1T_model[]; +extern Gfx act_m_mino2T_model[]; +extern Gfx act_m_mino1_2T_model[]; +extern Gfx act_m_mino1_2T_model[]; +extern Gfx act_m_hitodama_a_model[]; +extern Gfx act_m_hitodama_a_model[]; +extern Gfx act_m_hitodama_b_model[]; +extern Gfx act_m_hitodama_b_model[]; + +// clang-format off + +static Gfx* aINS_abura_dl[] = { + act_m_abura1_1T_model, + act_m_abura1_2T_model, + act_m_abura1_1T_model, + act_m_abura2_2T_model, +}; + +static Gfx* aINS_akiakane_dl[] = { + act_m_akiakane1_1T_model, + act_m_akiakane1_2T_model, + act_m_akiakane1_1T_model, + act_m_akiakane2_2T_model, +}; + +static Gfx* aINS_danna_dl[] = { + act_m_danna1T_model, + act_m_danna1T_model, + act_m_danna2T_model, + act_m_danna2T_model, +}; + +static Gfx* aINS_genji_dl[] = { + act_m_genji2_a_model, + act_m_genji2_b_model, + act_m_genji2_c_model, + act_m_genji2_d_model, +}; + +static Gfx* aINS_ginyanma_dl[] = { + act_m_ginyanma1_1T_model, + act_m_ginyanma1_2T_model, + act_m_ginyanma1_1T_model, + act_m_ginyanma2_2T_model, +}; + +static Gfx* aINS_higurashi_dl[] = { + act_m_higurashi1_1T_model, + act_m_higurashi1_2T_model, + act_m_higurashi1_1T_model, + act_m_higurashi2_2T_model, +}; + +static Gfx* aINS_hirata_dl[] = { + act_m_hirata1T_model, + act_m_hirata1T_model, + act_m_hirata2T_model, + act_m_hirata2T_model, +}; + +static Gfx* aINS_kabuto_dl[] = { + act_m_kabuto1T_model, + act_m_kabuto1T_model, + act_m_kabuto2T_model, + act_m_kabuto2T_model, +}; + +static Gfx* aINS_kamakiri_dl[] = { + act_m_kamakiri1T_model, + act_m_kamakiri1T_model, + act_m_kamakiri1T_model, + act_m_kamakiri2_2T_model, +}; + +static Gfx* aINS_kanabun_dl[] = { + act_m_kanabun1T_model, + act_m_kanabun1T_model, + act_m_kanabun2T_model, + act_m_kanabun2T_model, +}; + +static Gfx* aINS_kiageha_dl[] = { + act_m_kiageha1T_model, + act_m_kiageha1T_model, + act_m_kiageha2T_model, + act_m_kiageha2T_model, +}; + +static Gfx* aINS_kirigirisu_dl[] = { + act_m_kirigirisu1T_model, + act_m_kirigirisu1T_model, + act_m_kirigirisu1T_model, + act_m_kirigirisu2_2T_model, +}; + +static Gfx* aINS_koorogi_dl[] = { + act_m_koorogi1T_model, + act_m_koorogi1T_model, + act_m_koorogi1T_model, + act_m_koorogi1T_model, +}; + +static Gfx* aINS_kuma_dl[] = { + act_m_hachi1_1T_model, + act_m_hachi1_2T_model, + act_m_hachi1_1T_model, + act_m_hachi2_2T_model, +}; + +static Gfx* aINS_matumushi_dl[] = { + act_m_matumushi1T_model, + act_m_matumushi1T_model, + act_m_matumushi1T_model, + act_m_matumushi1T_model, +}; + +static Gfx* aINS_minmin_dl[] = { + act_m_minmin1_1T_model, + act_m_minmin1_2T_model, + act_m_minmin1_1T_model, + act_m_minmin2_2T_model, +}; + +static Gfx* aINS_monki_dl[] = { + act_m_monki1T_model, + act_m_monki1T_model, + act_m_monki2T_model, + act_m_monki2T_model, +}; + +static Gfx* aINS_monshiro_dl[] = { + act_m_monshiro1T_model, + act_m_monshiro1T_model, + act_m_monshiro2T_model, + act_m_monshiro2T_model, +}; + +static Gfx* aINS_nanahoshi_dl[] = { + act_m_nanahoshi1T_model, + act_m_nanahoshi1T_model, + act_m_nanahoshi2T_model, + act_m_nanahoshi2T_model, +}; + +static Gfx* aINS_ohmurasaki_dl[] = { + act_m_ohmurasaki1T_model, + act_m_ohmurasaki1T_model, + act_m_ohmurasaki2T_model, + act_m_ohmurasaki2T_model, +}; + +static Gfx* aINS_oniyanma_dl[] = { + act_m_oniyanma1_1T_model, + act_m_oniyanma1_2T_model, + act_m_oniyanma1_1T_model, + act_m_oniyanma2_2T_model, +}; + +static Gfx* aINS_shiokara_dl[] = { + act_m_shiokara1_1T_model, + act_m_shiokara1_2T_model, + act_m_shiokara1_1T_model, + act_m_shiokara2_2T_model, +}; + +static Gfx* aINS_suzumushi_dl[] = { + act_m_suzumushi1T_model, + act_m_suzumushi1T_model, + act_m_suzumushi1T_model, + act_m_suzumushi2_2T_model, +}; + +static Gfx* aINS_syouryou_dl[] = { + act_m_syouryou1T_model, + act_m_syouryou1T_model, + act_m_syouryou1T_model, + act_m_syouryou2_2T_model, +}; + +static Gfx* aINS_tamamushi_dl[] = { + act_m_tamamushi1T_model, + act_m_tamamushi1T_model, + act_m_tamamushi2T_model, + act_m_tamamushi2T_model, +}; + +static Gfx* aINS_gomadara_dl[] = { + act_m_gomadara1T_model, + act_m_gomadara1T_model, + act_m_gomadara2T_model, + act_m_gomadara2T_model, +}; + +static Gfx* aINS_tentou_dl[] = { + act_m_tentou1T_model, + act_m_tentou1T_model, + act_m_tentou2T_model, + act_m_tentou2T_model, +}; + +static Gfx* aINS_tonosama_dl[] = { + act_m_tonosama1T_model, + act_m_tonosama1T_model, + act_m_tonosama1T_model, + act_m_tonosama2_2T_model, +}; + +static Gfx* aINS_tukutuku_dl[] = { + act_m_tukutuku1_1T_model, + act_m_tukutuku1_2T_model, + act_m_tukutuku1_1T_model, + act_m_tukutuku2_2T_model, +}; + +static Gfx* aINS_nokogiri_dl[] = { + act_m_nokogiri1T_model, + act_m_nokogiri1T_model, + act_m_nokogiri2T_model, + act_m_nokogiri2T_model, +}; + +static Gfx* aINS_miyama_dl[] = { + act_m_miyama1T_model, + act_m_miyama1T_model, + act_m_miyama2T_model, + act_m_miyama2T_model, +}; + +static Gfx* aINS_okuwa_dl[] = { + act_m_okuwa1T_model, + act_m_okuwa1T_model, + act_m_okuwa2T_model, + act_m_okuwa2T_model, +}; + +static Gfx* aINS_amenbo_dl[] = { + act_m_amenbo1T_model, + act_m_amenbo1T_model, + act_m_amenbo1T_model, + act_m_amenbo2T_model, +}; + +static Gfx* aINS_ari_dl[] = { + act_m_ariT_model, + act_m_ariT_model, + act_m_ariT_model, + act_m_ariT_model, +}; + +static Gfx* aINS_dango_dl[] = { + act_m_dango2T_model, + act_m_dango2T_model, + act_m_dango1T_model, + act_m_dango1T_model, +}; + +static Gfx* aINS_ka_dl[] = { + act_m_ka1T_model, + act_m_ka2_2T_model, + act_m_ka1T_model, + act_m_ka2_1T_model, +}; + +static Gfx* aINS_kera_dl[] = { + act_m_keraT_model, + act_m_keraT_model, +}; + +static Gfx* aINS_kumo_dl[] = { + act_m_kumo1_2T_model, + act_m_kumo1_2T_model, + act_m_kumo1_1T_model, + act_m_kumo2T_model, +}; + +static Gfx* aINS_maimai_dl[] = { + act_m_maimaiT_model, + act_m_maimaiT_model, + act_m_maimaiT_model, + act_m_maimaiT_model, +}; + +static Gfx* aINS_mino_dl[] = { + act_m_mino1_1T_model, + act_m_mino1_1T_model, + act_m_mino1_1T_model, + act_m_mino2T_model, + act_m_mino1_2T_model, + act_m_mino1_2T_model, +}; + +static Gfx* aINS_hitodama_dl[] = { + act_m_hitodama_a_model, + act_m_hitodama_a_model, + act_m_hitodama_b_model, + act_m_hitodama_b_model, +}; + +// clang-format on + +// clang-format off +static Gfx** aINS_displayList[] = { + aINS_monshiro_dl, + aINS_monki_dl, + aINS_kiageha_dl, + aINS_ohmurasaki_dl, + aINS_minmin_dl, + aINS_tukutuku_dl, + aINS_higurashi_dl, + aINS_abura_dl, + aINS_kuma_dl, + aINS_shiokara_dl, + aINS_akiakane_dl, + aINS_ginyanma_dl, + aINS_oniyanma_dl, + aINS_syouryou_dl, + aINS_tonosama_dl, + aINS_koorogi_dl, + aINS_kirigirisu_dl, + aINS_suzumushi_dl, + aINS_matumushi_dl, + aINS_kanabun_dl, + aINS_kabuto_dl, + aINS_hirata_dl, + aINS_tamamushi_dl, + aINS_gomadara_dl, + aINS_tentou_dl, + aINS_nanahoshi_dl, + aINS_kamakiri_dl, + aINS_genji_dl, + aINS_danna_dl, + aINS_nokogiri_dl, + aINS_miyama_dl, + aINS_okuwa_dl, + aINS_maimai_dl, + aINS_kera_dl, + aINS_amenbo_dl, + aINS_mino_dl, + aINS_dango_dl, + aINS_kumo_dl, + aINS_ari_dl, + aINS_ka_dl, + aINS_hitodama_dl, +}; +// clang-format on + +extern void aICH_actor_init(ACTOR* actorx, GAME* game); +extern void aIBT_actor_init(ACTOR* actorx, GAME* game); +extern void aITB_actor_init(ACTOR* actorx, GAME* game); +extern void aITT_actor_init(ACTOR* actorx, GAME* game); +extern void aIHT_actor_init(ACTOR* actorx, GAME* game); +extern void aISM_actor_init(ACTOR* actorx, GAME* game); +extern void aIKB_actor_init(ACTOR* actorx, GAME* game); +extern void aIGK_actor_init(ACTOR* actorx, GAME* game); +extern void aIHD_actor_init(ACTOR* actorx, GAME* game); +extern void aIAB_actor_init(ACTOR* actorx, GAME* game); +extern void aIKA_actor_init(ACTOR* actorx, GAME* game); +extern void aIDG_actor_init(ACTOR* actorx, GAME* game); +extern void aIKR_actor_init(ACTOR* actorx, GAME* game); +extern void aIMN_actor_init(ACTOR* actorx, GAME* game); + +// clang-format off +static mActor_proc aINS_program_dlftbl[] = { + &aICH_actor_init, + &aIBT_actor_init, + &aITB_actor_init, + &aITT_actor_init, + &aIHT_actor_init, + &aISM_actor_init, + &aIKB_actor_init, + &aIGK_actor_init, + &aIHD_actor_init, + &aIAB_actor_init, + &aIKA_actor_init, + &aIDG_actor_init, + &aIKR_actor_init, + &aIMN_actor_init, +}; +// clang-format on + +// clang-format off +static int aINS_program_type[] = { + aINS_PROGRAM_CHOU, + aINS_PROGRAM_CHOU, + aINS_PROGRAM_CHOU, + aINS_PROGRAM_CHOU, + aINS_PROGRAM_SEMI, + aINS_PROGRAM_SEMI, + aINS_PROGRAM_SEMI, + aINS_PROGRAM_SEMI, + aINS_PROGRAM_SEMI, + aINS_PROGRAM_TONBO, + aINS_PROGRAM_TONBO, + aINS_PROGRAM_TONBO, + aINS_PROGRAM_TONBO, + aINS_PROGRAM_BATTA, + aINS_PROGRAM_BATTA, + aINS_PROGRAM_BATTA, + aINS_PROGRAM_BATTA, + aINS_PROGRAM_BATTA, + aINS_PROGRAM_BATTA, + aINS_PROGRAM_KABUTO, + aINS_PROGRAM_KABUTO, + aINS_PROGRAM_KABUTO, + aINS_PROGRAM_KABUTO, + aINS_PROGRAM_KABUTO, + aINS_PROGRAM_TENTOU, + aINS_PROGRAM_TENTOU, + aINS_PROGRAM_TENTOU, + aINS_PROGRAM_HOTARU, + aINS_PROGRAM_GOKI, + aINS_PROGRAM_KABUTO, + aINS_PROGRAM_KABUTO, + aINS_PROGRAM_KABUTO, + aINS_PROGRAM_TENTOU, + aINS_PROGRAM_KERA, + aINS_PROGRAM_AMENBO, + aINS_PROGRAM_MINO, + aINS_PROGRAM_DANGO, + aINS_PROGRAM_MINO, + aINS_PROGRAM_DANGO, + aINS_PROGRAM_KA, + aINS_PROGRAM_HITODAMA, +}; +// clang-format on diff --git a/src/ac_insect_draw.c_inc b/src/ac_insect_draw.c_inc new file mode 100644 index 00000000..93d15903 --- /dev/null +++ b/src/ac_insect_draw.c_inc @@ -0,0 +1,173 @@ +static void aINS_actor_draw_sub(GRAPH* graph, aINS_INSECT_ACTOR* insect, GAME* game, int draw_type, int alpha) { + GAME_PLAY* play = (GAME_PLAY*)game; + s16 angleX = insect->tools_actor.actor_class.shape_info.rotation.x; + s16 angleY = insect->tools_actor.actor_class.shape_info.rotation.y; + Gfx* gfx; + + if (insect->tools_actor.init_matrix == TRUE) { + Matrix_put(&insect->tools_actor.matrix_work); + Matrix_Position_Zero(&insect->tools_actor.actor_class.world.position); + angleX = 0; + angleY = angleX; + + switch (insect->type) { + case aSOI_INSECT_TYPE_LONG_LOCUST: + case aSOI_INSECT_TYPE_MIGRATORY_LOCUST: + case aSOI_INSECT_TYPE_GRASSHOPPER: + angleY = DEG2SHORT_ANGLE2(-90.0f); + break; + case aSOI_INSECT_TYPE_SPIDER: + angleX = DEG2SHORT_ANGLE2(90.0f); + break; + case aSOI_INSECT_TYPE_FIREFLY: + case aSOI_INSECT_TYPE_SPIRIT: + break; + default: + angleX = DEG2SHORT_ANGLE2(90.0f); + angleY = DEG2SHORT_ANGLE2(-180.0f); + break; + } + + Matrix_translate(insect->tools_actor.actor_class.world.position.x, + insect->tools_actor.actor_class.world.position.y + 2.0f, + insect->tools_actor.actor_class.world.position.z, 0); + Matrix_RotateX(angleX, 1); + Matrix_RotateY(angleY, 1); + } else { + Matrix_translate(insect->tools_actor.actor_class.world.position.x, + insect->tools_actor.actor_class.world.position.y + 2.0f, + insect->tools_actor.actor_class.world.position.z, 0); + + switch (insect->type) { + case aSOI_INSECT_TYPE_MOLE_CRICKET: + Matrix_RotateY(angleY, 1); + Matrix_RotateX(angleX, 1); + Matrix_RotateZ(insect->tools_actor.actor_class.shape_info.rotation.z, 1); + break; + case aSOI_INSECT_TYPE_SPIDER: + switch (draw_type) { + case 2: + Matrix_RotateX(angleX, 1); + Matrix_RotateZ(insect->tools_actor.actor_class.shape_info.rotation.z, 1); + break; + default: + Matrix_RotateX(angleX, 1); + Matrix_RotateY(angleY, 1); + Matrix_RotateZ(insect->tools_actor.actor_class.shape_info.rotation.z, 1); + break; + } + break; + default: + Matrix_RotateX(angleX, 1); + Matrix_RotateY(angleY, 1); + Matrix_RotateZ(insect->tools_actor.actor_class.shape_info.rotation.z, 1); + break; + } + } + + Matrix_scale(insect->tools_actor.actor_class.scale.x, insect->tools_actor.actor_class.scale.y, + insect->tools_actor.actor_class.scale.z, 1); + + OPEN_DISP(graph); + gfx = NOW_POLY_XLU_DISP; + + gDPPipeSync(gfx++); + gSPMatrix(gfx++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + /* initialize settings for env and billboard mtx */ + switch (insect->type) { + case aSOI_INSECT_TYPE_FIREFLY: + gSPMatrix(gfx++, play->billboard_mtx_p, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW); + gDPSetEnvColor(gfx++, 0, 255, 155, alpha); + break; + case aSOI_INSECT_TYPE_SPIRIT: + gSPMatrix(gfx++, play->billboard_mtx_p, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW); + gDPSetEnvColor(gfx++, 255, 255, 255, alpha); + break; + default: + gDPSetEnvColor(gfx++, 255, 255, 255, alpha); + break; + } + + /* draw insect model */ + gSPDisplayList(gfx++, aINS_displayList[insect->type][draw_type]); + + SET_POLY_XLU_DISP(gfx); + CLOSE_DISP(graph); +} + +static void aINS_actor_draw(ACTOR* actorx, GAME* game) { + GRAPH* graph = game->graph; + aINS_CTRL_ACTOR* ctrl_actor = (aINS_CTRL_ACTOR*)actorx; + aINS_INSECT_ACTOR* insect = ctrl_actor->insect_actor; + int alpha; + int i; + int draw_type; + + Matrix_push(); + _texture_z_light_fog_prim_xlu(graph); + + for (i = 0; i < aINS_ACTOR_NUM; i++) { + + draw_type = ((int)insect->_1E0) << 1; + if (insect->exist_flag == TRUE && insect->tools_actor.actor_class.drawn && + (insect->tools_actor.actor_class.state_bitfield & + (ACTOR_STATE_NO_CULL | ACTOR_STATE_NO_DRAW_WHILE_CULLED)) == + (ACTOR_STATE_NO_CULL | ACTOR_STATE_NO_DRAW_WHILE_CULLED)) { + if (insect->tools_actor.init_matrix == TRUE && insect->type != aSOI_INSECT_TYPE_SPIRIT) { + draw_type = 0; + } + + switch (insect->type) { + case aSOI_INSECT_TYPE_FIREFLY: + draw_type = (int)insect->_1E0; + alpha = insect->alpha0 - insect->alpha2; + + if (alpha < 0) { + alpha = 0; + } + break; + default: { + u32 label; + + alpha = insect->alpha0; + label = mPlib_Get_item_net_catch_label(); + if (label != (u32)insect && Camera2_CheckCullingMode() && + Camera2_CheckEnterCullingArea(insect->tools_actor.actor_class.world.position.x, + insect->tools_actor.actor_class.world.position.z, 60.0f)) { + alpha = 0; + } + break; + } + } + + aINS_actor_draw_sub(graph, insect, game, draw_type, alpha); + + switch (insect->type) { + case aSOI_INSECT_TYPE_FIREFLY: { + draw_type = insect->_1E4; + alpha = insect->alpha1 - insect->alpha2; + + if (alpha < 0) { + alpha = 0; + } + + aINS_actor_draw_sub(graph, insect, game, draw_type, alpha); + break; + } + case aSOI_INSECT_TYPE_SPIRIT: + break; + default: + aINS_actor_draw_sub(graph, insect, game, draw_type + 1, alpha); + break; + } + + mAc_NormalActorShadow((ACTOR*)insect, (GAME_PLAY*)game, 1.0f); + insect->tools_actor.init_matrix = FALSE; + } + + insect++; + } + + Matrix_pull(); +} diff --git a/src/ac_insect_move.c_inc b/src/ac_insect_move.c_inc new file mode 100644 index 00000000..c26120c3 --- /dev/null +++ b/src/ac_insect_move.c_inc @@ -0,0 +1,396 @@ +static void aINS_position_move(ACTOR* actorx) { + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx; + s16 angleY = actorx->world.angle.y; + + xyz_t_move(&actorx->last_world_position, &actorx->world.position); + chase_f(&actorx->speed, insect->target_speed, insect->speed_step * 0.5f); + actorx->position_speed.x = actorx->speed * sin_s(angleY); + actorx->position_speed.z = actorx->speed * cos_s(angleY); + + switch (insect->type) { + case aSOI_INSECT_TYPE_COMMON_BUTTERFLY: + case aSOI_INSECT_TYPE_YELLOW_BUTTERFLY: + case aSOI_INSECT_TYPE_TIGER_BUTTERFLY: + case aSOI_INSECT_TYPE_PURPLE_BUTTERFLY: + case aSOI_INSECT_TYPE_FIREFLY: + case aSOI_INSECT_TYPE_MOSQUITO: + case aSOI_INSECT_TYPE_SPIRIT: + break; + + default: + chase_f(&actorx->position_speed.y, actorx->max_velocity_y, actorx->gravity * 0.5f); + break; + } + + Actor_position_move(actorx); +} + +static void aINS_set_player_info(ACTOR* actorx, PLAYER_ACTOR* player) { + if (player != NULL) { + f32 distXZ; + f32 distY; + + distXZ = search_position_distanceXZ(&actorx->world.position, &player->actor_class.world.position); + actorx->player_distance_xz = distXZ; + + distY = player->actor_class.world.position.y - actorx->world.position.y; + actorx->player_distance_y = distY; + + actorx->player_distance = SQ(distXZ) + SQ(distY); + actorx->player_angle_y = search_position_angleY(&actorx->world.position, &player->actor_class.world.position); + } else { + actorx->player_distance_xz = 0.0f; + actorx->player_distance_y = 0.0f; + actorx->player_distance = 0.0f; + actorx->player_angle_y = 0; + } +} + +static void aINS_BGcheck(ACTOR* actorx) { + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx; + + switch (insect->bg_type) { + case 1: + mCoBG_BgCheckControll(NULL, actorx, insect->bg_range, insect->bg_height, TRUE, FALSE, 1); + break; + case 2: + mCoBG_BgCheckControll(NULL, actorx, insect->bg_range, insect->bg_height, FALSE, FALSE, 1); + break; + case 3: + mCoBG_BgCheckControll_RemoveDirectedUnitColumn(NULL, actorx, insect->bg_range, insect->bg_height, TRUE, + FALSE, 1, insect->ut_x, insect->ut_z); + break; + case 4: + mCoBG_BgCheckControll_RemoveDirectedUnitColumn(NULL, actorx, insect->bg_range, insect->bg_height, FALSE, + FALSE, 1, insect->ut_x, insect->ut_z); + break; + } + + if (insect->insect_flags.bit_2 == FALSE && insect->insect_flags.bit_4 == TRUE) { + mCoBG_UniqueWallCheck(actorx, insect->bg_range, 0.0f); + } +} + +// clang-format off +static f32 catch_ME_data[] = { + 0.0, + 0.0, + 0.0, + 0.0, + 10.0, + 10.0, + 10.0, + 0.0, + 10.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 20.0, + -20.0, + -20.0, + -20.0, + -20.0, + -20.0, + -20.0, + -20.0, + 0.0, + 0.0, + -20.0, + -20.0, + -20.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0f, +}; +// clang-format on + +static void aINS_get_stress_sub(f32* stress, Actor_list* actor_list, xyz_t* pos, aINS_INSECT_ACTOR* insect) { + static f32 calc_table[] = { 0.3f, 1.0f, 2.0f, 5.0f, 10.0f }; + f32 min_dist = aINS_MAX_STRESS_DIST; + ACTOR* actor; + + min_dist += catch_ME_data[insect->type]; + /* Calculate the greatest stress caused by any nearby actors */ + for (actor = actor_list->actor; actor != NULL; actor = actor->next_actor) { + f32 dist = search_position_distance(pos, &actor->world.position); + + if (dist < min_dist) { + f32 tmp0; + int idx; + f32 dX; + f32 dZ; + f32 calc_stress; + + tmp0 = dist - mFI_UNIT_BASE_SIZE_F; + if (tmp0 < 0.0f) { + tmp0 = 0.0f; + } + + idx = (int)((min_dist - mFI_UNIT_BASE_SIZE_F) - tmp0) / 20; + if (idx > ARRAY_COUNT(calc_table) - 1) { + idx = ARRAY_COUNT(calc_table) - 1; + } + + dX = actor->world.position.x - actor->last_world_position.x; + dZ = actor->world.position.z - actor->last_world_position.z; + calc_stress = sqrtf(SQ(dX) + SQ(dZ)) * calc_table[idx]; + + /* Stress is modified by the amount of movement over a single frame */ + if (calc_stress > *stress) { + *stress = calc_stress; + } + } + } +} + +static f32 aINS_get_stress(ACTOR* actorx, GAME* game) { + Actor_info* actor_info = &((GAME_PLAY*)game)->actor_info; + int i; + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx; + f32 stress = 0.0f; + + /* Calculate max stress on the insect from specific types of actors */ + for (i = 0; i < ACTOR_PART_NUM; i++) { + switch (i) { + case ACTOR_PART_UNUSED: + case ACTOR_PART_PLAYER: + case ACTOR_PART_NPC: + case ACTOR_PART_BG: + aINS_get_stress_sub(&stress, &actor_info->list[i], &actorx->world.position, insect); + break; + } + } + + return stress; /* return the max stress */ +} + +static void aINS_calc_patience(ACTOR* actorx, GAME* game) { + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx; + f32 stress = aINS_get_stress(actorx, game); + + if (F32_IS_ZERO(stress)) { + insect->patience -= aINS_PATIENCE_STEP; + if (insect->patience < 0.0f) { + insect->patience = 0.0f; + } + } else { + insect->patience += stress * aINS_PATIENCE_STEP; + if (insect->patience > 100.0f) { + insect->patience = 100.0f; + } + } +} + +static void aINS_calc_life_time(aINS_INSECT_ACTOR* insect) { + insect->life_time--; + + if (insect->life_time <= 0) { + insect->insect_flags.bit_3 = TRUE; + insect->life_time = 0; + } +} + +static void aINS_calc_alpha_time(aINS_INSECT_ACTOR* insect) { + if (insect->life_time != 0) { + return; + } + + if (insect->alpha_time <= 0) { + return; + } + + insect->alpha_time--; + if (insect->alpha_time >= 24) { + return; + } + + switch (insect->type) { + case aSOI_INSECT_TYPE_FIREFLY: { + int alpha = insect->alpha2; + + alpha += 11; + if (alpha >= 255) { + alpha = 255; + insect->alpha0 = 0; + insect->alpha1 = 0; + insect->insect_flags.destruct = TRUE; + } + + insect->alpha2 = alpha; + break; + } + + default: { + int alpha = insect->alpha0; + + alpha -= 11; + if (alpha <= 0) { + alpha = 0; + insect->insect_flags.destruct = TRUE; + } + + insect->alpha0 = alpha; + } + } +} + +static void aINS_cull_check(ACTOR* actorx, GAME* game) { + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + + Skin_Matrix_PrjMulVector(&play->projection_matrix, &actorx->world.position, &actorx->camera_position, + &actorx->camera_w); + + if (insect->insect_flags.destruct && (ACTOR*)mPlib_Get_item_net_catch_label() != actorx) { + aINS_destruct(actorx, game); + } + + if (Actor_draw_actor_no_culling_check(actorx) == FALSE) { + if (actorx->actor_specific == 1) { + if ((ACTOR*)mPlib_Get_item_net_catch_label() != actorx) { + aINS_destruct(actorx, game); + } + } else { + if ((ACTOR*)mPlib_Get_item_net_catch_label() != actorx) { + /* Allow actor to be culled since it's not been caught */ + actorx->state_bitfield &= ~ACTOR_STATE_NO_CULL; + } + + /* Despawn if player is more than 15 units away and in another acre and has not caught it */ + if (actorx->player_distance_xz > 600.0f && + (actorx->block_x != play->block_table.block_x || actorx->block_z != play->block_table.block_z) && + (ACTOR*)mPlib_Get_item_net_catch_label() != actorx) { + aINS_destruct(actorx, game); + } + } + } else { + /* Don't cull if the actor is still visible on the camera */ + actorx->state_bitfield |= ACTOR_STATE_NO_CULL; + } +} + +static f32 aINS_get_catch_range_sub(ACTOR* actorx) { + f32 range = 24.0f; + s16 dAngleY = ABS((s16)(actorx->world.angle.y - actorx->player_angle_y)); + + /* Player must be facing within 90 degrees of the insect */ + if (dAngleY > DEG2SHORT_ANGLE2(90.0f)) { + range = 0.0f; + } + + return range; +} + +static f32 aINS_get_catch_range(ACTOR* actorx) { + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx; + f32 range = 8.0f; + + switch (insect->type) { + case aSOI_INSECT_TYPE_COMMON_BUTTERFLY: + case aSOI_INSECT_TYPE_YELLOW_BUTTERFLY: + range = 24.0f; + break; + case aSOI_INSECT_TYPE_ROBUST_CICADA: + case aSOI_INSECT_TYPE_WALKER_CICADA: + case aSOI_INSECT_TYPE_EVENING_CICADA: + case aSOI_INSECT_TYPE_BROWN_CICADA: + case aSOI_INSECT_TYPE_BEE: + case aSOI_INSECT_TYPE_DRONE_BEETLE: + case aSOI_INSECT_TYPE_DYNASTID_BEETLE: + case aSOI_INSECT_TYPE_FLAT_STAG_BEETLE: + case aSOI_INSECT_TYPE_JEWEL_BEETLE: + case aSOI_INSECT_TYPE_LONGHORN_BEETLE: + case aSOI_INSECT_TYPE_SAW_STAG_BEETLE: + case aSOI_INSECT_TYPE_MOUNTAIN_BEETLE: + case aSOI_INSECT_TYPE_GIANT_BEETLE: + range = aINS_get_catch_range_sub(actorx); + break; + + case aSOI_INSECT_TYPE_COCKROACH: + if (insect->flag == 4) { + range = aINS_get_catch_range_sub(actorx); + } + break; + } + + return range; +} + +static void aINS_set_catch_range(ACTOR* actorx) { + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx; + + if (insect->insect_flags.bit_1 == FALSE) { + f32 catch_range = aINS_get_catch_range(actorx); + + if (!F32_IS_ZERO(catch_range)) { + GET_PLAYER_ACTOR_NOW()->Set_Item_net_catch_request_table_proc( + (ACTOR*)GET_PLAYER_ACTOR_NOW(), gamePT, (u32)actorx, 0, &actorx->world.position, catch_range); + } + } +} + +static void aINS_check_birth_ant(GAME* game) { + GAME_PLAY* play = (GAME_PLAY*)game; + + if (aINS_CLIP->ant_spawn_pending == TRUE) { + aINS_Init_c* init = &aINS_CLIP->ant_spawn_info; + ACTOR* actorx = Actor_info_make_actor(&play->actor_info, game, mAc_PROFILE_ANT, init->position.x, + init->position.y, init->position.z, 0, 0, 0, aINS_CLIP->ant_bx, + aINS_CLIP->ant_bz, -1, EMPTY_NO, -1, -1, -1); + + if (actorx != NULL) { + aINS_CLIP->ant_spawn_pending = FALSE; + } + } +} + +static void aINS_actor_move(ACTOR* actorx, GAME* game) { + aINS_CTRL_ACTOR* ctrl_actor = (aINS_CTRL_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play); + aINS_INSECT_ACTOR* insect = ctrl_actor->insect_actor; + int i; + + for (i = 0; i < aINS_ACTOR_NUM; i++) { + ACTOR* actorx = (ACTOR*)insect; + + if (insect->exist_flag == TRUE) { + actorx->state_bitfield &= ~ACTOR_STATE_24; + + if ((actorx->state_bitfield & (ACTOR_STATE_NO_MOVE_WHILE_CULLED | ACTOR_STATE_NO_CULL))) { + if (insect->tools_actor.init_matrix == FALSE) { + (*insect->move_proc)(actorx); + } + + aINS_set_player_info(actorx, player); + aINS_BGcheck(actorx); + aINS_calc_patience(actorx, game); + aINS_calc_life_time(insect); + aINS_calc_alpha_time(insect); + (*actorx->mv_proc)(actorx, game); + Actor_world_to_eye(actorx, 0.0f); + aINS_set_catch_range(actorx); + } + + aINS_cull_check(actorx, game); + } + + insect++; + } + + aINS_check_birth_ant(game); + aINS_set_pl_act_tim(0, -1, -1); +}