mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-07-28 15:07:07 -04:00
405 lines
12 KiB
C
405 lines
12 KiB
C
#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
|
|
};
|
|
|
|
static void aIDG_actor_move(ACTOR*, GAME*);
|
|
static void aIDG_setupAction(aINS_INSECT_ACTOR* insect, int action, GAME* game);
|
|
|
|
extern 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);
|
|
}
|
|
|
|
static 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;
|
|
}
|
|
|
|
static 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;
|
|
}
|
|
|
|
static 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)) < 4900.0f) {
|
|
ret = TRUE;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static 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)) < 4900.0f) {
|
|
ret = TRUE;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static 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)) < 4900.0f) {
|
|
ret = TRUE;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static 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;
|
|
}
|
|
|
|
static 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;
|
|
}
|
|
|
|
static 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;
|
|
}
|
|
|
|
static 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);
|
|
}
|
|
|
|
static 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_STOP, game);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static 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);
|
|
}
|
|
}
|
|
|
|
static 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);
|
|
}
|
|
}
|
|
|
|
static 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_APPEAR, &play->game);
|
|
}
|
|
}
|
|
|
|
static 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);
|
|
}
|
|
}
|
|
|
|
static 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);
|
|
}
|
|
}
|
|
|
|
static 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;
|
|
}
|
|
}
|
|
|
|
static 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;
|
|
}
|
|
|
|
static void aIDG_stop_init(aINS_INSECT_ACTOR* insect, GAME* game) {
|
|
insect->target_speed = 0.0f;
|
|
insect->speed_step = 0.05f;
|
|
insect->_1E0 = 0.0f;
|
|
}
|
|
|
|
static 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;
|
|
}
|
|
|
|
static 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;
|
|
}
|
|
|
|
static 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;
|
|
}
|
|
|
|
static 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;
|
|
}
|
|
|
|
static 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);
|
|
}
|
|
|
|
|
|
static void aIDG_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);
|
|
}
|
|
}
|
|
|