diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 4ec4c2b3..60b66f5e 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -778,6 +778,10 @@ ac_ins_batta.c: .text: [0x80596388, 0x80597708] .rodata: [0x80649EC8, 0x80649F60] .data: [0x806C3230, 0x806C32B8] +ac_ins_dango.c: + .text: [0x80597708, 0x805983F8] + .rodata: [0x80649F60, 0x80649FA8] + .data: [0x806C32B8, 0x806C3308] ac_ins_goki.c: .text: [0x80599A2C, 0x8059A8E8] .rodata: [0x8064A028, 0x8064A090] diff --git a/include/ac_ins_dango.h b/include/ac_ins_dango.h new file mode 100644 index 00000000..2dd4c270 --- /dev/null +++ b/include/ac_ins_dango.h @@ -0,0 +1,17 @@ +#ifndef AC_INS_DANGO_H +#define AC_INS_DANGO_H + +#include "types.h" +#include "ac_insect_h.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void aIDG_actor_init(ACTOR* actor, GAME* game); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/ac_ins_batta.c b/src/ac_ins_batta.c index 1194c768..12310672 100644 --- a/src/ac_ins_batta.c +++ b/src/ac_ins_batta.c @@ -12,7 +12,7 @@ enum { aIBT_ACTION_CHANGE_DIRECTION, aIBT_ACTION_WAIT, aIBT_ACTION_JUMP, - aIBT_ACTION_IN_WATER, + aIBT_ACTION_DROWN, aIBT_ACTION_NUM }; @@ -297,7 +297,7 @@ static void aIBT_avoid(ACTOR* actor, GAME* game) { aIBT_anime_proc(insect); if (insect->tools_actor.actor_class.bg_collision_check.result.is_in_water) { - aIBT_setupAction(insect, aIBT_ACTION_IN_WATER, &play->game); + aIBT_setupAction(insect, aIBT_ACTION_DROWN, &play->game); } else if ((aIBT_check_player_net(insect) == FALSE) && (insect->tools_actor.actor_class.bg_collision_check.result.on_ground)) { if (insect->timer > 0) { @@ -333,7 +333,7 @@ static void aIBT_let_escape(ACTOR* actor, GAME* game) { aIBT_anime_proc(insect); if (insect->tools_actor.actor_class.bg_collision_check.result.is_in_water) { - aIBT_setupAction(insect, aIBT_ACTION_IN_WATER, game); + aIBT_setupAction(insect, aIBT_ACTION_DROWN, game); } else { if (insect->tools_actor.actor_class.bg_collision_check.result.on_ground) { if (insect->timer > 0) { @@ -407,7 +407,7 @@ static void aIBT_wait(ACTOR* actor, GAME* game) { if (actor->bg_collision_check.result.is_in_water) { - aIBT_setupAction(insect, aIBT_ACTION_IN_WATER, game); + aIBT_setupAction(insect, aIBT_ACTION_DROWN, game); } else if (aIBT_check_patience(insect,game) == TRUE) { aIBT_setupAction(insect, aIBT_ACTION_AVOID, game); diff --git a/src/ac_ins_dango.c b/src/ac_ins_dango.c new file mode 100644 index 00000000..a42ea9d1 --- /dev/null +++ b/src/ac_ins_dango.c @@ -0,0 +1,404 @@ +#include "ac_ins_dango.h" + +#include "m_field_info.h" +#include "m_name_table.h" +#include "m_common_data.h" +#include "m_player_lib.h" +#include "ac_set_ovl_insect.h" + +enum { + aIDG_ACTION_AVOID, + aIDG_ACTION_LET_ESCAPE, + aIDG_ACTION_STOP, + aIDG_ACTION_HIDE, + aIDG_ACTION_APPEAR, + aIDG_ACTION_DIVE, + aIDG_ACTION_DROWN, + aIDG_ACTION_RETIRE, + + aIDG_ACTION_NUM +}; + +void aIDG_actor_move(ACTOR*, GAME*); +static void aIDG_setupAction(aINS_INSECT_ACTOR* insect, int action, GAME* game); + +void aIDG_actor_init(ACTOR* actor, GAME* game) { + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actor; + int bx, bz; + int action; + + if (insect->tools_actor.actor_class.actor_specific == 0) { + mFI_BkNum2WposXZ(&insect->f32_work2, &insect->f32_work3, insect->tools_actor.actor_class.block_x, + insect->tools_actor.actor_class.block_z); + insect->f32_work2 += 320.0f; + insect->f32_work3 += 320.0f; + mFI_Wpos2UtNum(&bx, &bz, insect->tools_actor.actor_class.world.position); + action = aIDG_ACTION_HIDE; + insect->ut_x = bx; + insect->ut_z = bz; + } else { + action = aIDG_ACTION_LET_ESCAPE; + insect->tools_actor.actor_class.drawn = TRUE; + } + insect->insect_flags.bit_4 = FALSE; + insect->bg_range = 2.0f; + + switch (insect->type) { + case aSOI_INSECT_TYPE_SPIDER: + break; + case aSOI_INSECT_TYPE_PILL_BUG: + insect->item = ITM_INSECT36; + break; + case aSOI_INSECT_TYPE_ANT: + insect->item = ITM_INSECT38; + break; + } + insect->tools_actor.actor_class.mv_proc = aIDG_actor_move; + aIDG_setupAction(insect, action, game); +} + +int aIDG_check_strike_stone(aINS_INSECT_ACTOR* insect) { + int ret; + int bx, bz; + + ret = FALSE; + if ((aINS_CLIP->pl_action == 1) || (aINS_CLIP->pl_action == 2)) { + mFI_Wpos2UtNum(&bx, &bz, insect->tools_actor.actor_class.world.position); + if ((aINS_CLIP->pl_action_ut_x == bx) && (aINS_CLIP->pl_action_ut_z == bz)) { + ret = TRUE; + } + } + return ret; +} + +int aIDG_check_ball(aINS_INSECT_ACTOR* insect) { + f32 xDiff; + f32 zDiff; + int ret; + + ret = FALSE; + + xDiff = Common_Get(ball_pos).x - insect->tools_actor.actor_class.world.position.x; + zDiff = Common_Get(ball_pos).z - insect->tools_actor.actor_class.world.position.z; + + if (((xDiff * xDiff) + (zDiff * zDiff)) < 3600.0f) { + ret = TRUE; + } + + return ret; +} + +int aIDG_check_player_net(aINS_INSECT_ACTOR* insect) { + f32 xDiff; + f32 zDiff; + int ret; + xyz_t pos; + + ret = FALSE; + if (mPlib_Check_StopNet(&pos) == TRUE) { + xDiff = pos.x - insect->tools_actor.actor_class.world.position.x; + zDiff = pos.z - insect->tools_actor.actor_class.world.position.z; + + if (((xDiff * xDiff) + (zDiff * zDiff)) < 3600.0f) { + ret = TRUE; + } + } + + return ret; +} + +int aIDG_check_player_scoop(aINS_INSECT_ACTOR* insect) { + f32 xDiff; + f32 zDiff; + int ret; + xyz_t pos; + + ret = FALSE; + if (mPlib_Check_DigScoop(&pos) == TRUE) { + xDiff = pos.x - insect->tools_actor.actor_class.world.position.x; + zDiff = pos.z - insect->tools_actor.actor_class.world.position.z; + + if (((xDiff * xDiff) + (zDiff * zDiff)) < 3600.0f) { + ret = TRUE; + } + } + + return ret; +} + +int aIDG_check_player_axe(aINS_INSECT_ACTOR* insect) { + f32 xDiff; + f32 zDiff; + int ret; + xyz_t pos; + + ret = FALSE; + if (mPlib_Check_HitAxe(&pos) == TRUE) { + xDiff = pos.x - insect->tools_actor.actor_class.world.position.x; + zDiff = pos.z - insect->tools_actor.actor_class.world.position.z; + + if (((xDiff * xDiff) + (zDiff * zDiff)) < 3600.0f) { + ret = TRUE; + } + } + + return ret; +} + +int aIDG_check_patience(aINS_INSECT_ACTOR* insect) { + int ret; + + ret = FALSE; + if ((insect->ut_x == -1) && (insect->ut_z == -1)) { + if (aIDG_check_ball(insect) == TRUE) { + insect->patience = 100.0f; + } else if (aIDG_check_player_net(insect) == TRUE) { + insect->patience = 100.0f; + } else if (aIDG_check_player_scoop(insect) == TRUE) { + insect->patience = 100.0f; + } else if (aIDG_check_player_axe(insect) == TRUE) { + insect->patience = 100.0f; + } + if (insect->patience > 90.0f) { + ret = TRUE; + } + } + return ret; +} + +int aIDG_chk_active_range(aINS_INSECT_ACTOR* insect) { + f32 z, x; + int ret; + + ret = TRUE; + x = insect->f32_work2 - insect->tools_actor.actor_class.world.position.x; + z = insect->f32_work3 - insect->tools_actor.actor_class.world.position.z; + if (((x * x) + (z * z)) >= 160000.0f) { + ret = FALSE; + } + return ret; +} + +int aIDG_chk_water_attr(aINS_INSECT_ACTOR* insect, GAME* game) { + int ret = FALSE; + + if (insect->tools_actor.actor_class.bg_collision_check.result.on_ground) { + xyz_t pos = insect->tools_actor.actor_class.world.position; + f32 speed = insect->bg_range + insect->tools_actor.actor_class.speed; + s16 yAngle = insect->tools_actor.actor_class.world.angle.y; + + pos.x += speed * sin_s(yAngle); + pos.z += speed * cos_s(yAngle); + + if (mCoBG_CheckWaterAttribute(mCoBG_Wpos2BgAttribute_Original(pos))) { + aIDG_setupAction(insect, aIDG_ACTION_DIVE, game); + ret = TRUE; + } + } + + return ret; +} + +void aIDG_calc_direction_angl(aINS_INSECT_ACTOR* insect) { + if (insect->tools_actor.actor_class.bg_collision_check.result.hit_wall & mCoBG_HIT_WALL_FRONT) { + int wallCount = insect->tools_actor.actor_class.bg_collision_check.result.hit_wall_count & 7; + if (wallCount != 0) { + int i; + + for (i = 0; i < wallCount; i++) { + mCoBG_WallInfo_c* info = &insect->tools_actor.actor_class.bg_collision_check.wall_info[i]; + if (info->type == 0) { + insect->tools_actor.actor_class.world.angle.y = + insect->tools_actor.actor_class.bg_collision_check.wall_info[i].angleY + 0x4000; + break; + } + } + } + } + chase_angle(&insect->tools_actor.actor_class.shape_info.rotation.y, insect->tools_actor.actor_class.world.angle.y, + 0x800); +} + +void aIDG_avoid(ACTOR* actor, GAME* game) { + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actor; + int bx, bz; + if (aIDG_chk_water_attr(insect, game) == FALSE) { + if (aIDG_chk_active_range(insect) == FALSE) { + aIDG_setupAction(insect, aIDG_ACTION_RETIRE, game); + } else { + aIDG_calc_direction_angl(insect); + if (insect->bg_type == 4) { + mFI_Wpos2UtNum(&bx, &bz, insect->tools_actor.actor_class.world.position); + if ((insect->ut_x != bx) || ((s16)insect->ut_z != bz)) { + insect->ut_x = -1; + insect->ut_z = -1; + insect->bg_type = 2; + } + } else if (aIDG_check_patience(insect) == TRUE) { + aIDG_setupAction(insect, aIDG_ACTION_LET_ESCAPE, game); + } + } + }1 +} + +void aIDG_let_escape(ACTOR* actor, GAME* game) { + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actor; + if (aIDG_chk_water_attr(insect, game) == FALSE) { + aIDG_calc_direction_angl(insect); + } +} + +void aIDG_stop(ACTOR* actor, GAME* game) { + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actor; + if ((aIDG_chk_water_attr(insect, game) == FALSE) && (insect->patience < 50.0f)) { + aIDG_setupAction(insect, aIDG_ACTION_AVOID, game); + } +} + +void aIDG_hide(ACTOR* actor, GAME* game) { + GAME_PLAY* play = (GAME_PLAY*) game; + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actor; + + if (aIDG_check_strike_stone(insect) == TRUE) { + aIDG_setupAction(insect, aIDG_ACTION_HIDE, &play->game); + } +} + +void aIDG_appear(ACTOR* actor, GAME* game) { + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actor; + if (insect->tools_actor.actor_class.bg_collision_check.result.on_ground) { + aIDG_setupAction(insect, aIDG_ACTION_STOP , game); + } +} + +void aIDG_dive(ACTOR* actor, GAME* game) { + GAME_PLAY* play = (GAME_PLAY*) game; + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actor; + + if (actor->world.position.y <= + mCoBG_GetWaterHeight_File(actor->world.position, "ac_ins_dango.c", 608)) { + aIDG_setupAction(insect, aIDG_ACTION_DROWN, &play->game); + } +} + +void aIDG_avoid_init(aINS_INSECT_ACTOR* insect, GAME* game) { + GAME_PLAY* play = (GAME_PLAY*)game; + PLAYER_ACTOR* player; + s16 angle; + + insect->tools_actor.actor_class.speed = 1.5f; + insect->target_speed = 1.5f; + insect->speed_step = 0.3f; + insect->_1E0 = 1.0f; + + player = get_player_actor_withoutCheck(play); + if (player != NULL) { + angle = player->actor_class.shape_info.rotation.y + (s16)(21845.0f * (fqrand() - 0.5f)); + insect->tools_actor.actor_class.world.angle.y = angle; + insect->tools_actor.actor_class.shape_info.rotation.y = angle; + } +} + +void aIDG_let_escape_init(aINS_INSECT_ACTOR* insect, GAME* game) { + insect->life_time = 0; + insect->alpha_time = 80; + insect->tools_actor.actor_class.shape_info.rotation.x = 0; + insect->bg_type = 2; + insect->tools_actor.actor_class.gravity = 2.0f; + insect->tools_actor.actor_class.max_velocity_y = -20.0f; + aIDG_avoid_init(insect, game); + insect->insect_flags.bit_1 = TRUE; + insect->insect_flags.bit_2 = TRUE; +} + +void aIDG_stop_init(aINS_INSECT_ACTOR* insect, GAME* game) { + insect->target_speed = 0.0f; + insect->speed_step = 0.05f; + insect->_1E0 = 0.0f; +} + +void aIDG_hide_init(aINS_INSECT_ACTOR* insect, GAME* game) { + insect->bg_type = 4; + insect->tools_actor.actor_class.gravity = 2.0f; + insect->tools_actor.actor_class.max_velocity_y = -20.0f; + insect->tools_actor.actor_class.drawn = FALSE; +} + +void aIDG_appear_init(aINS_INSECT_ACTOR* insect, GAME* game) { + aIDG_avoid_init(insect, game); + insect->tools_actor.actor_class.drawn = TRUE; + insect->_1E0 = 0.0f; + insect->tools_actor.actor_class.position_speed.y = 12.0f; +} + +void aIDG_dive_init(aINS_INSECT_ACTOR* insect, GAME* game) { + insect->tools_actor.actor_class.speed = 1.5f; + insect->speed_step = 0.3f; + insect->target_speed = 1.5f; + insect->tools_actor.actor_class.position_speed.y = 8.0f; + insect->_1E0 = 0.0f; + insect->insect_flags.bit_1 = TRUE; +} + +void aIDG_drown_init(aINS_INSECT_ACTOR* insect, GAME* game) { + xyz_t pos = insect->tools_actor.actor_class.world.position; + f32 height = mCoBG_GetWaterHeight_File(pos, "ac_ins_dango.c", 763); + + pos.y = height; + + eEC_CLIP->effect_make_proc(0x46, pos, 1, insect->tools_actor.actor_class.world.angle.y, game, 0, 4, 0); + sAdo_OngenTrgStart(0x438, &insect->tools_actor.actor_class.world.position); + + insect->insect_flags.bit_1 = TRUE; + insect->insect_flags.destruct = TRUE; + insect->tools_actor.actor_class.shape_info.draw_shadow = FALSE; +} + +void aIDG_retire_init(aINS_INSECT_ACTOR* insect, GAME* game) { + insect->life_time = 0; + insect->alpha_time = 0x50; + insect->tools_actor.actor_class.shape_info.rotation.x = 0; + insect->bg_type = 2; + insect->insect_flags.bit_1 = TRUE; + insect->insect_flags.bit_2 = TRUE; +} + +typedef void (*aIBT_INIT_PROC)(aINS_INSECT_ACTOR*, GAME*); + +static void aIDG_setupAction(aINS_INSECT_ACTOR* insect, int action, GAME* game) { + static aIBT_INIT_PROC init_proc[] = { + &aIDG_avoid_init, aIDG_let_escape_init, aIDG_stop_init, aIDG_hide_init, + aIDG_appear_init, aIDG_dive_init, aIDG_drown_init, aIDG_retire_init, + }; + + static aINS_ACTION_PROC act_proc[] = { + aIDG_avoid, + aIDG_let_escape, + aIDG_stop, + aIDG_hide, + aIDG_appear, + aIDG_dive, + (aINS_ACTION_PROC)none_proc1, + aIDG_let_escape, + }; + + insect->action = action; + insect->action_proc = act_proc[action]; + (*init_proc[action])(insect, game); +} + + +void aIBT_actor_move(ACTOR* actor, GAME* game) { + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actor; + GAME_PLAY* play = (GAME_PLAY*)game; + + u32 label = mPlib_Get_item_net_catch_label(); + + if (label == (u32)actor) { + insect->alpha0 = 255; + aIDG_setupAction(insect, aIDG_ACTION_LET_ESCAPE, game); + } else { + insect->action_proc(actor,game); + } +} +