mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-31 00:45:27 -04:00
Merge pull request #337 from Cuyler36:master
Implement & link ac_ins_goki
This commit is contained in:
@@ -774,6 +774,10 @@ ac_ins_amenbo.c:
|
||||
.text: [0x80595C74, 0x80596388]
|
||||
.rodata: [0x80649E70, 0x80649EC8]
|
||||
.data: [0x806C3200, 0x806C3230]
|
||||
ac_ins_goki.c:
|
||||
.text: [0x80599A2C, 0x8059A8E8]
|
||||
.rodata: [0x8064A028, 0x8064A090]
|
||||
.data: [0x806C33C8, 0x806C3460]
|
||||
ac_ins_hitodama.c:
|
||||
.text: [0x8059A8E8, 0x8059B354]
|
||||
.rodata: [0x8064A090, 0x8064A108]
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef AC_INS_GOKI_H
|
||||
#define AC_INS_GOKI_H
|
||||
|
||||
#include "types.h"
|
||||
#include "ac_insect_h.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void aIGK_actor_init(ACTOR* actorx, GAME* game);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+93
-88
@@ -13,92 +13,97 @@ extern "C" {
|
||||
#define aSOI_INSECT_TYPE_INVALID -1
|
||||
|
||||
enum insect_type {
|
||||
aSOI_INSECT_TYPE_COMMON_BUTTERFLY,
|
||||
aSOI_INSECT_TYPE_YELLOW_BUTTERFLY,
|
||||
aSOI_INSECT_TYPE_TIGER_BUTTERFLY,
|
||||
aSOI_INSECT_TYPE_PURPLE_BUTTERFLY,
|
||||
aSOI_INSECT_TYPE_ROBUST_CICADA,
|
||||
aSOI_INSECT_TYPE_WALKER_CICADA,
|
||||
aSOI_INSECT_TYPE_EVENING_CICADA,
|
||||
aSOI_INSECT_TYPE_BROWN_CICADA,
|
||||
aSOI_INSECT_TYPE_BEE,
|
||||
aSOI_INSECT_TYPE_COMMON_DRAGONFLY,
|
||||
aSOI_INSECT_TYPE_RED_DRAGONFLY,
|
||||
aSOI_INSECT_TYPE_DARNER_DRAGONFLY,
|
||||
aSOI_INSECT_TYPE_BANDED_DRAGONFLY,
|
||||
aSOI_INSECT_TYPE_LONG_LOCUST,
|
||||
aSOI_INSECT_TYPE_MIGRATORY_LOCUST,
|
||||
aSOI_INSECT_TYPE_CRICKET,
|
||||
aSOI_INSECT_TYPE_GRASSHOPPER,
|
||||
aSOI_INSECT_TYPE_BELL_CRICKET,
|
||||
aSOI_INSECT_TYPE_PINE_CRICKET,
|
||||
aSOI_INSECT_TYPE_DRONE_BEETLE,
|
||||
aSOI_INSECT_TYPE_DYNASTID_BEETLE,
|
||||
aSOI_INSECT_TYPE_FLAT_STAG_BEETLE,
|
||||
aSOI_INSECT_TYPE_JEWEL_BEETLE,
|
||||
aSOI_INSECT_TYPE_LONGHORN_BEETLE,
|
||||
aSOI_INSECT_TYPE_LADYBUG,
|
||||
aSOI_INSECT_TYPE_SPOTTED_LADYBUG,
|
||||
aSOI_INSECT_TYPE_MANTIS,
|
||||
aSOI_INSECT_TYPE_FIREFLY,
|
||||
aSOI_INSECT_TYPE_COCKROACH,
|
||||
aSOI_INSECT_TYPE_SAW_STAG_BEETLE,
|
||||
aSOI_INSECT_TYPE_MOUNTAIN_BEETLE,
|
||||
aSOI_INSECT_TYPE_GIANT_BEETLE,
|
||||
aSOI_INSECT_TYPE_SNAIL,
|
||||
aSOI_INSECT_TYPE_MOLE_CRICKET,
|
||||
aSOI_INSECT_TYPE_POND_SKATER,
|
||||
aSOI_INSECT_TYPE_BAGWORM,
|
||||
aSOI_INSECT_TYPE_PILL_BUG,
|
||||
aSOI_INSECT_TYPE_SPIDER,
|
||||
aSOI_INSECT_TYPE_ANT,
|
||||
aSOI_INSECT_TYPE_MOSQUITO,
|
||||
aSOI_INSECT_TYPE_NUM,
|
||||
aSOI_INSECT_TYPE_COMMON_BUTTERFLY,
|
||||
aSOI_INSECT_TYPE_YELLOW_BUTTERFLY,
|
||||
aSOI_INSECT_TYPE_TIGER_BUTTERFLY,
|
||||
aSOI_INSECT_TYPE_PURPLE_BUTTERFLY,
|
||||
aSOI_INSECT_TYPE_ROBUST_CICADA,
|
||||
aSOI_INSECT_TYPE_WALKER_CICADA,
|
||||
aSOI_INSECT_TYPE_EVENING_CICADA,
|
||||
aSOI_INSECT_TYPE_BROWN_CICADA,
|
||||
aSOI_INSECT_TYPE_BEE,
|
||||
aSOI_INSECT_TYPE_COMMON_DRAGONFLY,
|
||||
aSOI_INSECT_TYPE_RED_DRAGONFLY,
|
||||
aSOI_INSECT_TYPE_DARNER_DRAGONFLY,
|
||||
aSOI_INSECT_TYPE_BANDED_DRAGONFLY,
|
||||
aSOI_INSECT_TYPE_LONG_LOCUST,
|
||||
aSOI_INSECT_TYPE_MIGRATORY_LOCUST,
|
||||
aSOI_INSECT_TYPE_CRICKET,
|
||||
aSOI_INSECT_TYPE_GRASSHOPPER,
|
||||
aSOI_INSECT_TYPE_BELL_CRICKET,
|
||||
aSOI_INSECT_TYPE_PINE_CRICKET,
|
||||
aSOI_INSECT_TYPE_DRONE_BEETLE,
|
||||
aSOI_INSECT_TYPE_DYNASTID_BEETLE,
|
||||
aSOI_INSECT_TYPE_FLAT_STAG_BEETLE,
|
||||
aSOI_INSECT_TYPE_JEWEL_BEETLE,
|
||||
aSOI_INSECT_TYPE_LONGHORN_BEETLE,
|
||||
aSOI_INSECT_TYPE_LADYBUG,
|
||||
aSOI_INSECT_TYPE_SPOTTED_LADYBUG,
|
||||
aSOI_INSECT_TYPE_MANTIS,
|
||||
aSOI_INSECT_TYPE_FIREFLY,
|
||||
aSOI_INSECT_TYPE_COCKROACH,
|
||||
aSOI_INSECT_TYPE_SAW_STAG_BEETLE,
|
||||
aSOI_INSECT_TYPE_MOUNTAIN_BEETLE,
|
||||
aSOI_INSECT_TYPE_GIANT_BEETLE,
|
||||
aSOI_INSECT_TYPE_SNAIL,
|
||||
aSOI_INSECT_TYPE_MOLE_CRICKET,
|
||||
aSOI_INSECT_TYPE_POND_SKATER,
|
||||
aSOI_INSECT_TYPE_BAGWORM,
|
||||
aSOI_INSECT_TYPE_PILL_BUG,
|
||||
aSOI_INSECT_TYPE_SPIDER,
|
||||
aSOI_INSECT_TYPE_ANT,
|
||||
aSOI_INSECT_TYPE_MOSQUITO,
|
||||
aSOI_INSECT_TYPE_NUM,
|
||||
|
||||
aSOI_INSECT_TYPE_SPIRIT = aSOI_INSECT_TYPE_NUM,
|
||||
aSOI_INSECT_TYPE_NONE,
|
||||
aSOI_INSECT_TYPE_EXTENDED_NUM
|
||||
aSOI_INSECT_TYPE_SPIRIT = aSOI_INSECT_TYPE_NUM,
|
||||
aSOI_INSECT_TYPE_NONE,
|
||||
aSOI_INSECT_TYPE_EXTENDED_NUM
|
||||
};
|
||||
|
||||
#define aSOI_SPAWN_AREA_INVALID -1
|
||||
|
||||
enum insect_spawn_area {
|
||||
aSOI_SPAWN_AREA_ON_TREE,
|
||||
aSOI_SPAWN_AREA_ON_FLOWER,
|
||||
aSOI_SPAWN_AREA_RAINING_ON_FLOWER,
|
||||
aSOI_SPAWN_AREA_FLYING,
|
||||
aSOI_SPAWN_AREA_ON_GROUND,
|
||||
aSOI_SPAWN_AREA_IN_BUSH,
|
||||
aSOI_SPAWN_AREA_FLYING_NEAR_WATER,
|
||||
aSOI_SPAWN_AREA_ON_WATER,
|
||||
aSOI_SPAWN_AREA_ON_CANDY,
|
||||
aSOI_SPAWN_AREA_ON_TRASH,
|
||||
aSOI_SPAWN_AREA_UNDER_ROCK,
|
||||
aSOI_SPAWN_AREA_UNDERGROUND,
|
||||
aSOI_SPAWN_AREA_FLYING_NEAR_FLOWERS_OR_AROUND, /* this prefers flowers, but will default to "FLYING" if no flowers are in the acre */
|
||||
aSOI_SPAWN_AREA_NOTHING,
|
||||
aSOI_SPAWN_AREA_ON_TREE,
|
||||
aSOI_SPAWN_AREA_ON_FLOWER,
|
||||
aSOI_SPAWN_AREA_RAINING_ON_FLOWER,
|
||||
aSOI_SPAWN_AREA_FLYING,
|
||||
aSOI_SPAWN_AREA_ON_GROUND,
|
||||
aSOI_SPAWN_AREA_IN_BUSH,
|
||||
aSOI_SPAWN_AREA_FLYING_NEAR_WATER,
|
||||
aSOI_SPAWN_AREA_ON_WATER,
|
||||
aSOI_SPAWN_AREA_ON_CANDY,
|
||||
aSOI_SPAWN_AREA_ON_TRASH,
|
||||
aSOI_SPAWN_AREA_UNDER_ROCK,
|
||||
aSOI_SPAWN_AREA_UNDERGROUND,
|
||||
aSOI_SPAWN_AREA_FLYING_NEAR_FLOWERS_OR_AROUND, /* this prefers flowers, but will default to "FLYING" if no flowers
|
||||
are in the acre */
|
||||
aSOI_SPAWN_AREA_NOTHING,
|
||||
|
||||
aSOI_SPAWN_AREA_NUM
|
||||
aSOI_SPAWN_AREA_NUM
|
||||
};
|
||||
|
||||
enum insect_spawn_type {
|
||||
aSOI_SPAWN_TYPE_NONE, /* none/unused? */
|
||||
aSOI_SPAWN_TYPE_TOWN, /* pull from town spawns */
|
||||
aSOI_SPAWN_TYPE_ISLAND, /* pull from island spawns */
|
||||
aSOI_SPAWN_TYPE_SPIRIT, /* pull from town spawns but force spirit if Wisp is active */
|
||||
aSOI_SPAWN_TYPE_NONE, /* none/unused? */
|
||||
aSOI_SPAWN_TYPE_TOWN, /* pull from town spawns */
|
||||
aSOI_SPAWN_TYPE_ISLAND, /* pull from island spawns */
|
||||
aSOI_SPAWN_TYPE_SPIRIT, /* pull from town spawns but force spirit if Wisp is active */
|
||||
|
||||
aSOI_SPAWN_TYPE_NUM
|
||||
aSOI_SPAWN_TYPE_NUM
|
||||
};
|
||||
|
||||
enum insect_spawn_category {
|
||||
aSOI_SPAWN_CATEGORY_FG_ITEM_RANGE,
|
||||
aSOI_SPAWN_CATEGORY_UT_ATTRIBUTE,
|
||||
aSOI_SPAWN_CATEGORY_TREE,
|
||||
aSOI_SPAWN_CATEGORY_UT_ATTRIBUTE_AND_FG_ITEM_RANGE,
|
||||
aSOI_SPAWN_CATEGORY_FG_ITEM_RANGE,
|
||||
aSOI_SPAWN_CATEGORY_UT_ATTRIBUTE,
|
||||
aSOI_SPAWN_CATEGORY_TREE,
|
||||
aSOI_SPAWN_CATEGORY_UT_ATTRIBUTE_AND_FG_ITEM_RANGE,
|
||||
|
||||
aSOI_SPAWN_CATEGORY_NUM
|
||||
aSOI_SPAWN_CATEGORY_NUM
|
||||
};
|
||||
|
||||
#define aSOI_SPAWN_NORMAL 0
|
||||
#define aSOI_SPAWN_TREE 4
|
||||
#define aSOI_SPAWN_ITEM 6
|
||||
|
||||
/**
|
||||
* Insect term periods:
|
||||
* TERM0: 11PM-4AM (5 hours)
|
||||
@@ -109,28 +114,28 @@ enum insect_spawn_category {
|
||||
* TERM5: 7PM-11PM (4 hours)
|
||||
**/
|
||||
|
||||
#define aSOI_TERM0_START_HR 11+12 // 11:00PM
|
||||
#define aSOI_TERM0_END_HR 3 // 03:59AM
|
||||
#define aSOI_TERM1_START_HR 4 // 04:00AM
|
||||
#define aSOI_TERM1_END_HR 7 // 07:59AM
|
||||
#define aSOI_TERM2_START_HR 8 // 08:00AM
|
||||
#define aSOI_TERM2_END_HR 3+12 // 03:59PM
|
||||
#define aSOI_TERM3_START_HR 4+12 // 04:00PM
|
||||
#define aSOI_TERM3_END_HR 4+12 // 04:59PM
|
||||
#define aSOI_TERM4_START_HR 5+12 // 05:00PM
|
||||
#define aSOI_TERM4_END_HR 6+12 // 06:59PM
|
||||
#define aSOI_TERM5_START_HR 7+12 // 07:00PM
|
||||
#define aSOI_TERM5_END_HR 10+12 // 10:59PM
|
||||
#define aSOI_TERM0_START_HR 11 + 12 // 11:00PM
|
||||
#define aSOI_TERM0_END_HR 3 // 03:59AM
|
||||
#define aSOI_TERM1_START_HR 4 // 04:00AM
|
||||
#define aSOI_TERM1_END_HR 7 // 07:59AM
|
||||
#define aSOI_TERM2_START_HR 8 // 08:00AM
|
||||
#define aSOI_TERM2_END_HR 3 + 12 // 03:59PM
|
||||
#define aSOI_TERM3_START_HR 4 + 12 // 04:00PM
|
||||
#define aSOI_TERM3_END_HR 4 + 12 // 04:59PM
|
||||
#define aSOI_TERM4_START_HR 5 + 12 // 05:00PM
|
||||
#define aSOI_TERM4_END_HR 6 + 12 // 06:59PM
|
||||
#define aSOI_TERM5_START_HR 7 + 12 // 07:00PM
|
||||
#define aSOI_TERM5_END_HR 10 + 12 // 10:59PM
|
||||
|
||||
enum insect_term {
|
||||
aSOI_TERM0,
|
||||
aSOI_TERM1,
|
||||
aSOI_TERM2,
|
||||
aSOI_TERM3,
|
||||
aSOI_TERM4,
|
||||
aSOI_TERM5,
|
||||
aSOI_TERM0,
|
||||
aSOI_TERM1,
|
||||
aSOI_TERM2,
|
||||
aSOI_TERM3,
|
||||
aSOI_TERM4,
|
||||
aSOI_TERM5,
|
||||
|
||||
aSOI_TERM_NUM
|
||||
aSOI_TERM_NUM
|
||||
};
|
||||
|
||||
extern int aSOI_insect_set(SET_MANAGER* set_manager, GAME_PLAY* play);
|
||||
|
||||
@@ -36,6 +36,7 @@ typedef enum audio_sound_effects {
|
||||
NA_SE_LIGHT_OFF,
|
||||
|
||||
NA_SE_25 = 0x25,
|
||||
NA_SE_26 = 0x26,
|
||||
|
||||
NA_SE_DRAWER_SHUT = 0x3A,
|
||||
|
||||
@@ -70,6 +71,8 @@ typedef enum audio_sound_effects {
|
||||
NA_SE_STONECOIN_ROLL = 0x7D,
|
||||
NA_SE_STONECOIN_DRAG = 0x7E,
|
||||
|
||||
NA_SE_A8 = 0xA8,
|
||||
|
||||
NA_SE_CF = 0xCF,
|
||||
|
||||
NA_SE_ROD_STROKE = 0x109,
|
||||
|
||||
@@ -0,0 +1,474 @@
|
||||
#include "ac_ins_goki.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 {
|
||||
aIGK_INIT_TREE,
|
||||
aIGK_INIT_CEDAR,
|
||||
|
||||
aIGK_INIT_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
aIGK_ACTION_AVOID,
|
||||
aIGK_ACTION_LET_ESCAPE,
|
||||
aIGK_ACTION_WAIT_ON_FLOWER,
|
||||
aIGK_ACTION_MOVE_ON_FLOWER,
|
||||
aIGK_ACTION_WAIT_ON_TREE,
|
||||
aIGK_ACTION_MOVE_ON_TREE,
|
||||
aIGK_ACTION_WAIT_ON_ITEM,
|
||||
aIGK_ACTION_MOVE_ON_ITEM,
|
||||
|
||||
aIGK_ACTION_NUM
|
||||
};
|
||||
|
||||
#define aIGK_PLACE_TREE 4
|
||||
#define aIGK_PLACE_FLOWER 5
|
||||
#define aIGK_PLACE_ITEM 6
|
||||
|
||||
#define aIGK_BALL_SCARE_DIST (60.0f)
|
||||
#define aIGK_NET_SCARE_DIST (70.0f)
|
||||
#define aIGK_SCOOP_SCARE_DIST (30.0f)
|
||||
#define aIGK_VIB_SCARE_DIST (150.0f)
|
||||
#define aIGK_MAX_PATIENCE (90.0f) /* Patience threshold for scaring away */
|
||||
|
||||
#define aIGK_RANDOM_ANGLE() ((int)((fqrand() - 0.5f) * 2 * (f32)DEG2SHORT_ANGLE2(90.0f)))
|
||||
#define aIGK_RANDOM_ANGLE2() ((s16)((fqrand() - 0.5f) * (f32)DEG2SHORT_ANGLE2(120.0f)))
|
||||
|
||||
#define aIGK_TARGET_ANGLE(insect) ((insect)->s32_work0)
|
||||
#define aIGK_CHANGE_WAIT_TIMER(insect) ((insect)->s32_work1)
|
||||
#define aIGK_MOVE_TIMER(insect) ((insect)->s32_work2)
|
||||
#define aIGK_GET_ITEM_P(insect) ((insect)->s32_work3)
|
||||
#define aIGK_SET_ITEM_P(insect, item_p) ((insect)->s32_work3 = (int)item_p)
|
||||
|
||||
static void aIGK_actor_move(ACTOR* actorx, GAME* game);
|
||||
static void aIGK_setupAction(aINS_INSECT_ACTOR* insect, int action, GAME* game);
|
||||
|
||||
extern void aIGK_actor_init(ACTOR* actorx, GAME* game) {
|
||||
aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx;
|
||||
int act;
|
||||
|
||||
insect->item = ITM_INSECT28;
|
||||
actorx->mv_proc = &aIGK_actor_move;
|
||||
insect->bg_range = 6.0f;
|
||||
|
||||
switch (actorx->actor_specific) {
|
||||
case aSOI_SPAWN_NORMAL: {
|
||||
/* Spawn on flower */
|
||||
insect->bg_type = 2;
|
||||
actorx->world.position.y = 6.0f + mCoBG_GetBgY_OnlyCenter_FromWpos(actorx->world.position, -19.0f);
|
||||
xyz_t_move(&actorx->home.position, &actorx->world.position);
|
||||
actorx->shape_info.draw_shadow = FALSE;
|
||||
insect->flag = aIGK_PLACE_FLOWER;
|
||||
actorx->actor_specific = 0;
|
||||
act = aIGK_ACTION_WAIT_ON_FLOWER;
|
||||
break;
|
||||
}
|
||||
case aSOI_SPAWN_TREE: {
|
||||
/* Spawn insect on tree */
|
||||
static f32 init_posY[aIGK_INIT_NUM] = { 35.0f, 30.0f };
|
||||
static f32 init_posZ[aIGK_INIT_NUM] = { -2.0f, 8.0f };
|
||||
mActor_name_t* fg_p = mFI_GetUnitFG(actorx->world.position);
|
||||
int type;
|
||||
|
||||
if (fg_p != NULL && *fg_p == CEDAR_TREE) {
|
||||
type = aIGK_INIT_CEDAR;
|
||||
} else {
|
||||
type = aIGK_INIT_TREE;
|
||||
}
|
||||
|
||||
actorx->world.position.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(actorx->world.position, -init_posY[type]);
|
||||
actorx->world.position.z += init_posZ[type];
|
||||
xyz_t_move(&actorx->home.position, &actorx->world.position);
|
||||
actorx->shape_info.draw_shadow = FALSE;
|
||||
insect->flag = aIGK_PLACE_TREE;
|
||||
actorx->actor_specific = 0;
|
||||
actorx->shape_info.rotation.y = DEG2SHORT_ANGLE2(-180.0f);
|
||||
actorx->shape_info.rotation.x = DEG2SHORT_ANGLE2(90.0f);
|
||||
act = aIGK_ACTION_WAIT_ON_TREE;
|
||||
break;
|
||||
}
|
||||
case aSOI_SPAWN_ITEM: {
|
||||
/* Spawn insect on ground item */
|
||||
actorx->world.position.y = 5.0f + mCoBG_GetBgY_OnlyCenter_FromWpos2(actorx->world.position, -2.0f);
|
||||
xyz_t_move(&actorx->home.position, &actorx->world.position);
|
||||
actorx->shape_info.draw_shadow = FALSE;
|
||||
insect->flag = aIGK_PLACE_ITEM;
|
||||
actorx->actor_specific = 0;
|
||||
|
||||
aIGK_SET_ITEM_P(insect, mFI_GetUnitFG(actorx->world.position));
|
||||
if (aIGK_GET_ITEM_P(insect) == 0) {
|
||||
Actor_delete(actorx);
|
||||
return;
|
||||
}
|
||||
|
||||
actorx->shape_info.rotation.y = DEG2SHORT_ANGLE2(-180.0f);
|
||||
actorx->shape_info.rotation.x = DEG2SHORT_ANGLE2(45.0f);
|
||||
act = aIGK_ACTION_WAIT_ON_ITEM;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
act = aIGK_ACTION_LET_ESCAPE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
aIGK_setupAction(insect, act, game);
|
||||
}
|
||||
|
||||
static void aIGK_anime_proc(aINS_INSECT_ACTOR* insect) {
|
||||
insect->_1E0 += 0.5f;
|
||||
if (insect->_1E0 >= 2.0f) {
|
||||
insect->_1E0 -= 2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
static int aIGK_check_tree_shaken(aINS_INSECT_ACTOR* insect) {
|
||||
int res = FALSE;
|
||||
|
||||
if (insect->flag == aIGK_PLACE_TREE) {
|
||||
if (mPlib_Check_tree_shaken(&insect->tools_actor.actor_class.world.position) == TRUE) {
|
||||
res = TRUE;
|
||||
} else if (mPlib_Check_VibUnit_OneFrame(&insect->tools_actor.actor_class.world.position) == TRUE &&
|
||||
insect->tools_actor.actor_class.player_distance_xz < aIGK_VIB_SCARE_DIST) {
|
||||
res = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int aIGK_check_ball(aINS_INSECT_ACTOR* insect) {
|
||||
f32 dX = Common_Get(ball_pos).x - insect->tools_actor.actor_class.world.position.x;
|
||||
f32 dZ = Common_Get(ball_pos).z - insect->tools_actor.actor_class.world.position.z;
|
||||
int res = FALSE;
|
||||
|
||||
if ((SQ(dX) + SQ(dZ)) < SQ(aIGK_BALL_SCARE_DIST)) {
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int aIGK_check_player_net(aINS_INSECT_ACTOR* insect) {
|
||||
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)insect) {
|
||||
f32 dX = net_pos.x - insect->tools_actor.actor_class.world.position.x;
|
||||
f32 dZ = net_pos.z - insect->tools_actor.actor_class.world.position.z;
|
||||
|
||||
if ((SQ(dX) + SQ(dZ)) < SQ(aIGK_NET_SCARE_DIST)) {
|
||||
res = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int aIGK_check_player_scoop(aINS_INSECT_ACTOR* insect) {
|
||||
xyz_t scoop_pos;
|
||||
int res = FALSE;
|
||||
|
||||
if (mPlib_Check_DigScoop(&scoop_pos) == TRUE) {
|
||||
f32 dX = scoop_pos.x - insect->tools_actor.actor_class.world.position.x;
|
||||
f32 dZ = scoop_pos.z - insect->tools_actor.actor_class.world.position.z;
|
||||
|
||||
if ((SQ(dX) + SQ(dZ)) < SQ(aIGK_SCOOP_SCARE_DIST)) {
|
||||
res = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int aIGK_check_patience(aINS_INSECT_ACTOR* insect) {
|
||||
int res = FALSE;
|
||||
|
||||
/* Check that no action which would scare the insect away has occurred */
|
||||
if (aIGK_check_tree_shaken(insect) == TRUE) {
|
||||
insect->patience = 100.0f;
|
||||
} else if (aIGK_check_ball(insect) == TRUE) {
|
||||
insect->patience = 100.0f;
|
||||
} else if (aIGK_check_player_net(insect) == TRUE) {
|
||||
insect->patience = 100.0f;
|
||||
} else if (aIGK_check_player_scoop(insect) == TRUE) {
|
||||
insect->patience = 100.0f;
|
||||
} else if (insect->flag == aIGK_PLACE_ITEM && *(mActor_name_t*)aIGK_GET_ITEM_P(insect) != ITM_KABU_SPOILED) {
|
||||
insect->patience = 100.0f;
|
||||
}
|
||||
|
||||
if (insect->patience >= aIGK_MAX_PATIENCE) {
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void aIGK_avoid(ACTOR* actorx, GAME* game) {
|
||||
aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx;
|
||||
f32 grav;
|
||||
|
||||
grav = actorx->gravity;
|
||||
grav *= 1.1f;
|
||||
if (grav > 12.0f) {
|
||||
grav = 12.0f;
|
||||
}
|
||||
|
||||
actorx->gravity = grav;
|
||||
sAdo_OngenPos((u32)actorx, NA_SE_26, &actorx->world.position);
|
||||
aIGK_anime_proc(insect);
|
||||
|
||||
if (insect->bg_type == 0) {
|
||||
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 = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aIGK_wait_on_flower(ACTOR* actorx, GAME* game) {
|
||||
aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx;
|
||||
|
||||
if (aIGK_check_patience(insect) == TRUE) {
|
||||
aIGK_setupAction(insect, aIGK_ACTION_AVOID, game);
|
||||
} else {
|
||||
insect->timer--;
|
||||
|
||||
if (insect->timer <= 0) {
|
||||
aIGK_setupAction(insect, aIGK_ACTION_MOVE_ON_FLOWER, game);
|
||||
} else {
|
||||
chase_angle(&actorx->world.angle.y, aIGK_TARGET_ANGLE(insect), DEG2SHORT_ANGLE2(8.4375f));
|
||||
actorx->shape_info.rotation.y = actorx->world.angle.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aIGK_move_on_flower(ACTOR* actorx, GAME* game) {
|
||||
aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx;
|
||||
|
||||
if (aIGK_check_patience(insect) == TRUE) {
|
||||
aIGK_setupAction(insect, aIGK_ACTION_AVOID, game);
|
||||
} else {
|
||||
aIGK_MOVE_TIMER(insect)--;
|
||||
|
||||
if (aIGK_MOVE_TIMER(insect) <= 0) {
|
||||
sAdo_OngenPos((u32)actorx, NA_SE_A8, &actorx->world.position);
|
||||
insect->timer = (int)(2 * (90.0f + RANDOM_F(90.0f)));
|
||||
aIGK_setupAction(insect, aIGK_ACTION_WAIT_ON_FLOWER, game);
|
||||
} else {
|
||||
int flag = 0;
|
||||
f32 dX = actorx->world.position.x - actorx->home.position.x;
|
||||
f32 dZ = actorx->world.position.z - actorx->home.position.z;
|
||||
|
||||
if (ABS(dX) >= 15.0f) {
|
||||
if (dX < 0.0f) {
|
||||
actorx->world.position.x = actorx->home.position.x - 14.0f;
|
||||
flag = 1;
|
||||
} else {
|
||||
actorx->world.position.x = actorx->home.position.x + 14.0f;
|
||||
flag = 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (ABS(dZ) >= 15.0f) {
|
||||
if (dZ < 0.0f) {
|
||||
actorx->world.position.z = actorx->home.position.z - 14.0f;
|
||||
flag |= 4;
|
||||
} else {
|
||||
actorx->world.position.z = actorx->home.position.z + 14.0f;
|
||||
flag |= 8;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag != 0) {
|
||||
// clang-format off
|
||||
static int ref_angl[16] = {
|
||||
DEG2SHORT_ANGLE2(0.0f), DEG2SHORT_ANGLE2(90.0f), DEG2SHORT_ANGLE2(-90.0f), DEG2SHORT_ANGLE2(0.0f),
|
||||
DEG2SHORT_ANGLE2(0.0f), DEG2SHORT_ANGLE2(45.0f), DEG2SHORT_ANGLE2(-45.0f), DEG2SHORT_ANGLE2(0.0f),
|
||||
DEG2SHORT_ANGLE2(180.0f), DEG2SHORT_ANGLE2(135.0f), DEG2SHORT_ANGLE2(-135.0f), DEG2SHORT_ANGLE2(180.0f),
|
||||
DEG2SHORT_ANGLE2(90.0f), DEG2SHORT_ANGLE2(90.0f), DEG2SHORT_ANGLE2(-90.0f), DEG2SHORT_ANGLE2(0.0f),
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
aIGK_TARGET_ANGLE(insect) = ref_angl[flag];
|
||||
insect->timer = 10;
|
||||
aIGK_setupAction(insect, aIGK_ACTION_WAIT_ON_FLOWER, game);
|
||||
} else {
|
||||
int done = chase_angle(&actorx->world.angle.y, aIGK_TARGET_ANGLE(insect), DEG2SHORT_ANGLE2(8.4375f));
|
||||
|
||||
if (done == TRUE) {
|
||||
aIGK_TARGET_ANGLE(insect) = actorx->world.angle.y + aIGK_RANDOM_ANGLE();
|
||||
}
|
||||
|
||||
actorx->shape_info.rotation.y = actorx->world.angle.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aIGK_wait_on_tree(ACTOR* actorx, GAME* game) {
|
||||
aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx;
|
||||
|
||||
if (aIGK_check_patience(insect) == TRUE) {
|
||||
aIGK_setupAction(insect, aIGK_ACTION_AVOID, game);
|
||||
} else {
|
||||
insect->timer--;
|
||||
if (insect->timer <= 0) {
|
||||
aIGK_setupAction(insect, insect->action + 1, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aIGK_move_on_tree(ACTOR* actorx, GAME* game) {
|
||||
aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx;
|
||||
|
||||
if (aIGK_check_patience(insect) == TRUE) {
|
||||
aIGK_setupAction(insect, aIGK_ACTION_AVOID, game);
|
||||
} else {
|
||||
chase_angle(&actorx->shape_info.rotation.y, aIGK_TARGET_ANGLE(insect), 128);
|
||||
aIGK_MOVE_TIMER(insect)--;
|
||||
|
||||
if (aIGK_MOVE_TIMER(insect) <= 0) {
|
||||
aIGK_CHANGE_WAIT_TIMER(insect)--;
|
||||
if (aIGK_CHANGE_WAIT_TIMER(insect) <= 0) {
|
||||
aIGK_setupAction(insect, insect->action - 1, game);
|
||||
} else {
|
||||
aIGK_TARGET_ANGLE(insect) = -aIGK_TARGET_ANGLE(insect);
|
||||
aIGK_MOVE_TIMER(insect) = 30;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aIGK_avoid_init(aINS_INSECT_ACTOR* insect, GAME* game) {
|
||||
static f32 base_angl[2] = { DEG2SHORT_ANGLE2(-22.5f), DEG2SHORT_ANGLE2(22.5f) };
|
||||
f32 rnd;
|
||||
s16 angl;
|
||||
|
||||
insect->tools_actor.actor_class.shape_info.draw_shadow = TRUE;
|
||||
insect->tools_actor.actor_class.speed = 4.0f;
|
||||
insect->tools_actor.actor_class.max_velocity_y = 12.0f;
|
||||
insect->tools_actor.actor_class.gravity = 0.06f;
|
||||
insect->tools_actor.actor_class.shape_info.rotation.x = 0;
|
||||
insect->tools_actor.actor_class.position_speed.y = 0.0f;
|
||||
rnd = fqrand();
|
||||
insect->life_time = 0;
|
||||
insect->alpha_time = 80;
|
||||
angl = (int)(rnd * DEG2SHORT_ANGLE2(90.0f) - (f32)DEG2SHORT_ANGLE2(45.0f) + base_angl[rnd >= 0.5f]);
|
||||
|
||||
insect->tools_actor.actor_class.world.angle.y = angl;
|
||||
insect->tools_actor.actor_class.shape_info.rotation.y = angl;
|
||||
insect->insect_flags.bit_1 = TRUE;
|
||||
}
|
||||
|
||||
static void aIGK_let_escape_init(aINS_INSECT_ACTOR* insect, GAME* game) {
|
||||
PLAYER_ACTOR* player;
|
||||
|
||||
insect->tools_actor.actor_class.shape_info.draw_shadow = TRUE;
|
||||
insect->life_time = 0;
|
||||
insect->alpha_time = 80;
|
||||
insect->tools_actor.actor_class.speed = 4.0f;
|
||||
insect->tools_actor.actor_class.max_velocity_y = 12.0f;
|
||||
insect->tools_actor.actor_class.gravity = 0.06f;
|
||||
insect->tools_actor.actor_class.shape_info.rotation.x = 0;
|
||||
insect->tools_actor.actor_class.position_speed.y = 0.0f;
|
||||
|
||||
player = GET_PLAYER_ACTOR_GAME(game);
|
||||
if (player != NULL) {
|
||||
s16 angl = player->actor_class.shape_info.rotation.y + aIGK_RANDOM_ANGLE2();
|
||||
|
||||
insect->tools_actor.actor_class.world.angle.y = angl;
|
||||
insect->tools_actor.actor_class.shape_info.rotation.y = angl;
|
||||
}
|
||||
|
||||
insect->insect_flags.bit_1 = TRUE;
|
||||
insect->insect_flags.bit_2 = TRUE;
|
||||
}
|
||||
|
||||
static void aIGK_wait_on_flower_init(aINS_INSECT_ACTOR* insect, GAME* game) {
|
||||
insect->tools_actor.actor_class.speed = 0.0f;
|
||||
insect->speed_step = 0.0f;
|
||||
insect->target_speed = 0.0f;
|
||||
}
|
||||
|
||||
static void aIGK_move_on_flower_init(aINS_INSECT_ACTOR* insect, GAME* game) {
|
||||
if (aIGK_MOVE_TIMER(insect) == 0) {
|
||||
aIGK_MOVE_TIMER(insect) = (int)(2 * (90.0f + RANDOM_F(210.0f)));
|
||||
}
|
||||
|
||||
insect->target_speed = 0.4f;
|
||||
insect->speed_step = 0.1f;
|
||||
}
|
||||
|
||||
static void aIGK_wait_on_tree_init(aINS_INSECT_ACTOR* insect, GAME* game) {
|
||||
insect->timer = (int)(2 * (10.0f + RANDOM_F(10.0f)));
|
||||
}
|
||||
|
||||
static void aIGK_move_on_tree_init(aINS_INSECT_ACTOR* insect, GAME* game) {
|
||||
aIGK_TARGET_ANGLE(insect) = DEG2SHORT_ANGLE2(175.78125f);
|
||||
aIGK_CHANGE_WAIT_TIMER(insect) = 3 + RANDOM(2);
|
||||
aIGK_MOVE_TIMER(insect) = 30;
|
||||
}
|
||||
|
||||
typedef void (*aIGK_INIT_PROC)(aINS_INSECT_ACTOR* insect, GAME* game);
|
||||
|
||||
static void aIGK_setupAction(aINS_INSECT_ACTOR* insect, int action, GAME* game) {
|
||||
// clang-format off
|
||||
static aIGK_INIT_PROC init_proc[aIGK_ACTION_NUM] = {
|
||||
&aIGK_avoid_init,
|
||||
&aIGK_let_escape_init,
|
||||
&aIGK_wait_on_flower_init,
|
||||
&aIGK_move_on_flower_init,
|
||||
&aIGK_wait_on_tree_init,
|
||||
&aIGK_move_on_tree_init,
|
||||
&aIGK_wait_on_tree_init,
|
||||
&aIGK_move_on_tree_init,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
// clang-format off
|
||||
static aINS_ACTION_PROC act_proc[aIGK_ACTION_NUM] = {
|
||||
&aIGK_avoid,
|
||||
&aIGK_avoid,
|
||||
&aIGK_wait_on_flower,
|
||||
&aIGK_move_on_flower,
|
||||
&aIGK_wait_on_tree,
|
||||
&aIGK_move_on_tree,
|
||||
&aIGK_wait_on_tree,
|
||||
&aIGK_move_on_tree,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
insect->action = action;
|
||||
insect->action_proc = act_proc[action];
|
||||
(*init_proc[action])(insect, game);
|
||||
}
|
||||
|
||||
static void aIGK_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) {
|
||||
aIGK_setupAction(insect, aIGK_ACTION_LET_ESCAPE, game);
|
||||
} else if (insect->insect_flags.bit_3 == TRUE && insect->insect_flags.bit_2 == FALSE) {
|
||||
aIGK_setupAction(insect, aIGK_ACTION_LET_ESCAPE, game);
|
||||
} else {
|
||||
(*insect->action_proc)(actorx, game);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user