mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-22 22:24:16 -04:00
Implement & link ac_ins_kabuto
This commit is contained in:
@@ -782,6 +782,10 @@ ac_ins_ka.c:
|
||||
.text: [0x8059C174, 0x8059C9EC]
|
||||
.rodata: [0x8064A1A8, 0x8064A1F0]
|
||||
.data: [0x806C3550, 0x806C3580]
|
||||
ac_ins_kabuto.c:
|
||||
.text: [0x8059C9EC, 0x8059D1F4]
|
||||
.rodata: [0x8064A1F0, 0x8064A228]
|
||||
.data: [0x806C3580, 0x806C35E0]
|
||||
ac_boat.c:
|
||||
.text: [0x805A6CF4, 0x805A856C]
|
||||
.rodata: [0x8064A5B0, 0x8064A630]
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef AC_INS_KABUTO_H
|
||||
#define AC_INS_KABUTO_H
|
||||
|
||||
#include "types.h"
|
||||
#include "ac_insect_h.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void aIKB_actor_init(ACTOR* actorx, GAME* game);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -74,6 +74,10 @@ extern void mPlib_change_player_cloth(GAME* game, int idx);
|
||||
extern u32 mPlib_Get_item_net_catch_label(void);
|
||||
extern int mPlib_Check_stung_mosquito(ACTOR* actorx);
|
||||
extern int mPlib_request_main_stung_mosquito_type1(ACTOR* actorx);
|
||||
extern int mPlib_Check_StopNet(xyz_t* net_pos);
|
||||
extern int mPlib_Check_DigScoop(xyz_t* scoop_pos);
|
||||
extern int mPlib_Check_tree_shaken(const xyz_t* pos);
|
||||
extern int mPlib_Check_VibUnit_OneFrame(const xyz_t* pos);
|
||||
|
||||
extern mPlayer_change_data_from_submenu_c* mPlib_Get_change_data_from_submenu_p();
|
||||
|
||||
@@ -86,6 +90,7 @@ extern void mPlib_request_main_give_type1(GAME* game, mActor_name_t item, int mo
|
||||
|
||||
#define GET_PLAYER_ACTOR(play) get_player_actor_withoutCheck(play)
|
||||
#define GET_PLAYER_ACTOR_NOW() get_player_actor_withoutCheck((GAME_PLAY*)gamePT)
|
||||
#define GET_PLAYER_ACTOR_GAME(game) get_player_actor_withoutCheck((GAME_PLAY*)(game))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -0,0 +1,295 @@
|
||||
#include "ac_ins_kabuto.h"
|
||||
|
||||
#include "ac_set_ovl_insect.h"
|
||||
#include "m_field_info.h"
|
||||
#include "m_name_table.h"
|
||||
#include "m_common_data.h"
|
||||
#include "m_player_lib.h"
|
||||
|
||||
#define aIKB_BALL_SCARE_DIST (60.0f)
|
||||
#define aIKB_NET_SCARE_DIST (70.0f)
|
||||
#define aIKB_SCOOP_SCARE_DIST (30.0f)
|
||||
#define aIKB_VIB_SCARE_DIST (150.0f)
|
||||
#define aIKB_MAX_PATIENCE (90.0f) /* Patience threshold for scaring away */
|
||||
|
||||
#define aIKB_RANDOM_ANGLE() ((s16)((fqrand() - 0.5f) * (f32)DEG2SHORT_ANGLE2(120.0f)))
|
||||
|
||||
static void aIKB_actor_move(ACTOR* actorx, GAME* game);
|
||||
static void aIKB_setupAction(aINS_INSECT_ACTOR* insect, int action, GAME* game);
|
||||
|
||||
enum {
|
||||
aIKB_ACTION_AVOID,
|
||||
aIKB_ACTION_LET_ESCAPE,
|
||||
aIKB_ACTION_WAIT,
|
||||
|
||||
aIKB_ACTION_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aIKB_INIT_TREE,
|
||||
aIKB_INIT_CEDAR,
|
||||
|
||||
aIKB_INIT_NUM
|
||||
};
|
||||
|
||||
#define aIKB_CHASE_ANGLE_TIMER0(insect) ((insect)->s32_work0)
|
||||
#define aIKB_CHASE_ANGLE_TIMER1(insect) ((insect)->s32_work1)
|
||||
#define aIKB_CHASE_ANGLE_TIMER2(insect) ((insect)->s32_work2)
|
||||
#define aIKB_ROT_Y(insect) ((insect)->s32_work3)
|
||||
|
||||
extern void aIKB_actor_init(ACTOR* actorx, GAME* game) {
|
||||
aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx;
|
||||
int act;
|
||||
|
||||
if (actorx->actor_specific == 0) {
|
||||
static f32 init_posY[aIKB_INIT_NUM] = { 35.0f, 30.0f };
|
||||
static f32 init_posZ[aIKB_INIT_NUM] = { -2.0f, 8.0f };
|
||||
mActor_name_t* fg_p = mFI_GetUnitFG(actorx->world.position);
|
||||
int init_type;
|
||||
|
||||
if (fg_p != NULL && *fg_p == CEDAR_TREE) {
|
||||
init_type = aIKB_INIT_CEDAR;
|
||||
} else {
|
||||
init_type = aIKB_INIT_TREE;
|
||||
}
|
||||
|
||||
actorx->world.position.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(actorx->world.position, -init_posY[init_type]);
|
||||
actorx->world.position.z += init_posZ[init_type];
|
||||
actorx->shape_info.draw_shadow = FALSE;
|
||||
actorx->shape_info.rotation.x = DEG2SHORT_ANGLE2(90.0f);
|
||||
aIKB_ROT_Y(insect) = actorx->shape_info.rotation.y;
|
||||
act = aIKB_ACTION_WAIT;
|
||||
} else {
|
||||
act = aIKB_ACTION_LET_ESCAPE;
|
||||
}
|
||||
|
||||
switch (insect->type) {
|
||||
case aSOI_INSECT_TYPE_DRONE_BEETLE:
|
||||
insect->item = ITM_INSECT19;
|
||||
break;
|
||||
case aSOI_INSECT_TYPE_DYNASTID_BEETLE:
|
||||
insect->item = ITM_INSECT20;
|
||||
break;
|
||||
case aSOI_INSECT_TYPE_FLAT_STAG_BEETLE:
|
||||
insect->item = ITM_INSECT21;
|
||||
break;
|
||||
case aSOI_INSECT_TYPE_JEWEL_BEETLE:
|
||||
insect->item = ITM_INSECT22;
|
||||
break;
|
||||
case aSOI_INSECT_TYPE_LONGHORN_BEETLE:
|
||||
insect->item = ITM_INSECT23;
|
||||
break;
|
||||
case aSOI_INSECT_TYPE_SAW_STAG_BEETLE:
|
||||
insect->item = ITM_INSECT29;
|
||||
break;
|
||||
case aSOI_INSECT_TYPE_MOUNTAIN_BEETLE:
|
||||
insect->item = ITM_INSECT30;
|
||||
break;
|
||||
case aSOI_INSECT_TYPE_GIANT_BEETLE:
|
||||
insect->item = ITM_INSECT31;
|
||||
break;
|
||||
}
|
||||
|
||||
actorx->mv_proc = &aIKB_actor_move;
|
||||
aIKB_setupAction(insect, act, game);
|
||||
}
|
||||
|
||||
static void aIKB_anime_proc(aINS_INSECT_ACTOR* insect) {
|
||||
insect->_1E0 += 0.5f;
|
||||
if (insect->_1E0 >= 2.0f) {
|
||||
insect->_1E0 -= 2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
static int aIKB_check_ball(ACTOR* actorx) {
|
||||
f32 dX = Common_Get(ball_pos).x - actorx->world.position.x;
|
||||
f32 dZ = Common_Get(ball_pos).z - actorx->world.position.z;
|
||||
int res = FALSE;
|
||||
|
||||
if ((SQ(dX) + SQ(dZ)) < SQ(aIKB_BALL_SCARE_DIST)) {
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int aIKB_check_player_net(ACTOR* actorx) {
|
||||
xyz_t net_pos;
|
||||
int res = FALSE;
|
||||
|
||||
if (mPlib_Check_StopNet(&net_pos) == TRUE) {
|
||||
u32 label = mPlib_Get_item_net_catch_label();
|
||||
|
||||
if (label != (u32)actorx) {
|
||||
f32 dX = net_pos.x - actorx->world.position.x;
|
||||
f32 dZ = net_pos.z - actorx->world.position.z;
|
||||
|
||||
if ((SQ(dX) + SQ(dZ)) < SQ(aIKB_NET_SCARE_DIST)) {
|
||||
res = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int aIKB_check_player_scoop(ACTOR* actorx) {
|
||||
xyz_t scoop_pos;
|
||||
int res = FALSE;
|
||||
|
||||
if (mPlib_Check_DigScoop(&scoop_pos) == TRUE) {
|
||||
f32 dX = scoop_pos.x - actorx->world.position.x;
|
||||
f32 dZ = scoop_pos.z - actorx->world.position.z;
|
||||
|
||||
if ((SQ(dX) + SQ(dZ)) < SQ(aIKB_SCOOP_SCARE_DIST)) {
|
||||
res = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int aIKB_check_patience(aINS_INSECT_ACTOR* insect) {
|
||||
int res = FALSE;
|
||||
ACTOR* actorx = (ACTOR*)insect;
|
||||
|
||||
/* Check that no action which would scare the insect away has occurred */
|
||||
if (mPlib_Check_tree_shaken(&actorx->world.position) == TRUE) {
|
||||
insect->patience = 100.0f;
|
||||
} else if (mPlib_Check_VibUnit_OneFrame(&actorx->world.position) == TRUE &&
|
||||
actorx->player_distance_xz < aIKB_VIB_SCARE_DIST) {
|
||||
insect->patience = 100.0f;
|
||||
} else if (aIKB_check_ball(actorx) == TRUE) {
|
||||
insect->patience = 100.0f;
|
||||
} else if (aIKB_check_player_net(actorx) == TRUE) {
|
||||
insect->patience = 100.0f;
|
||||
} else if (aIKB_check_player_scoop(actorx) == TRUE) {
|
||||
insect->patience = 100.0f;
|
||||
}
|
||||
|
||||
if (insect->patience > aIKB_MAX_PATIENCE) {
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void aIKB_avoid(ACTOR* actorx, GAME* game) {
|
||||
aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx;
|
||||
f32 grav;
|
||||
|
||||
aIKB_anime_proc(insect);
|
||||
grav = actorx->gravity;
|
||||
grav *= 1.1f;
|
||||
|
||||
if (grav > 12.0f) {
|
||||
grav = 12.0f;
|
||||
}
|
||||
|
||||
actorx->gravity = grav;
|
||||
|
||||
sAdo_OngenPos((u32)actorx, NA_SE_25, &actorx->world.position);
|
||||
|
||||
if (insect->bg_type != 2) {
|
||||
int h_ut_x;
|
||||
int h_ut_z;
|
||||
int now_ut_x;
|
||||
int now_ut_z;
|
||||
|
||||
mFI_Wpos2UtNum(&h_ut_x, &h_ut_z, actorx->home.position);
|
||||
mFI_Wpos2UtNum(&now_ut_x, &now_ut_z, actorx->world.position);
|
||||
|
||||
if (h_ut_x != now_ut_x || h_ut_z != now_ut_z) {
|
||||
insect->bg_type = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aIKB_wait(ACTOR* actorx, GAME* game) {
|
||||
static s16 angle_table[] = { DEG2SHORT_ANGLE2(175.78125f), DEG2SHORT_ANGLE2(-175.78125f) };
|
||||
aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx;
|
||||
PLAYER_ACTOR* player = GET_PLAYER_ACTOR_GAME(game);
|
||||
|
||||
actorx->player_angle_y = search_position_angleY(&actorx->world.position, &player->actor_class.world.position);
|
||||
if (aIKB_check_patience(insect) == TRUE) {
|
||||
/* Insect was scared away */
|
||||
aIKB_setupAction(insect, aIKB_ACTION_AVOID, game);
|
||||
} else if (aIKB_CHASE_ANGLE_TIMER0(insect) == 0) {
|
||||
chase_angle(&actorx->shape_info.rotation.y, angle_table[(aIKB_CHASE_ANGLE_TIMER1(insect) & 1)], 128);
|
||||
|
||||
if (aIKB_CHASE_ANGLE_TIMER2(insect) == 0) {
|
||||
if (aIKB_CHASE_ANGLE_TIMER1(insect) == 0) {
|
||||
aIKB_CHASE_ANGLE_TIMER0(insect) = (int)((10.0f + RANDOM_F(10.0f)) * 2.0f);
|
||||
aIKB_CHASE_ANGLE_TIMER1(insect) = 3 + RANDOM(2);
|
||||
} else {
|
||||
aIKB_CHASE_ANGLE_TIMER1(insect)--;
|
||||
}
|
||||
|
||||
aIKB_CHASE_ANGLE_TIMER2(insect) = 30;
|
||||
} else {
|
||||
aIKB_CHASE_ANGLE_TIMER2(insect)--;
|
||||
}
|
||||
} else {
|
||||
aIKB_CHASE_ANGLE_TIMER0(insect)--;
|
||||
}
|
||||
}
|
||||
|
||||
static void aIKB_avoid_init(aINS_INSECT_ACTOR* insect, GAME* game) {
|
||||
PLAYER_ACTOR* player;
|
||||
|
||||
insect->life_time = 0;
|
||||
insect->alpha_time = 80;
|
||||
insect->tools_actor.actor_class.gravity = 0.06f;
|
||||
insect->tools_actor.actor_class.max_velocity_y = 12.0f;
|
||||
insect->tools_actor.actor_class.speed = 4.0f;
|
||||
insect->tools_actor.actor_class.shape_info.rotation.x = 0;
|
||||
|
||||
player = GET_PLAYER_ACTOR_GAME(game);
|
||||
if (player != NULL) {
|
||||
s16 angle = player->actor_class.shape_info.rotation.y + aIKB_RANDOM_ANGLE();
|
||||
|
||||
insect->tools_actor.actor_class.world.angle.y = angle;
|
||||
insect->tools_actor.actor_class.shape_info.rotation.y = angle;
|
||||
}
|
||||
|
||||
insect->insect_flags.bit_1 = TRUE;
|
||||
insect->insect_flags.bit_2 = TRUE;
|
||||
insect->tools_actor.actor_class.shape_info.draw_shadow = TRUE;
|
||||
}
|
||||
|
||||
static void aIKB_wait_init(aINS_INSECT_ACTOR* insect, GAME* game) {
|
||||
insect->tools_actor.actor_class.shape_info.rotation.y = DEG2SHORT_ANGLE2(-180.0f);
|
||||
}
|
||||
|
||||
typedef void (*aIKB_INIT_PROC)(aINS_INSECT_ACTOR*, GAME*);
|
||||
|
||||
static void aIKB_setupAction(aINS_INSECT_ACTOR* insect, int action, GAME* game) {
|
||||
static aIKB_INIT_PROC init_proc[] = {
|
||||
&aIKB_avoid_init,
|
||||
&aIKB_avoid_init,
|
||||
&aIKB_wait_init,
|
||||
};
|
||||
|
||||
static aINS_ACTION_PROC act_proc[] = {
|
||||
&aIKB_avoid,
|
||||
&aIKB_avoid,
|
||||
&aIKB_wait,
|
||||
};
|
||||
|
||||
insect->action = action;
|
||||
insect->action_proc = act_proc[action];
|
||||
(*init_proc[action])(insect, game);
|
||||
}
|
||||
|
||||
static void aIKB_actor_move(ACTOR* actorx, GAME* game) {
|
||||
aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx;
|
||||
u32 label = mPlib_Get_item_net_catch_label();
|
||||
|
||||
if (label == (u32)actorx) {
|
||||
aIKB_setupAction(insect, aIKB_ACTION_LET_ESCAPE, game);
|
||||
} else if (insect->insect_flags.bit_3 == TRUE && insect->insect_flags.bit_2 == FALSE) {
|
||||
aIKB_setupAction(insect, aIKB_ACTION_LET_ESCAPE, game);
|
||||
} else {
|
||||
(*insect->action_proc)(actorx, game);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user