From 2aa1228f3ac34a4e3d14d3c36845918db7e5e957 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Mon, 29 Apr 2024 09:55:41 -0400 Subject: [PATCH] Implement & link ac_ins_amenbo --- config/rel_slices.yml | 4 + include/ac_ins_amenbo.h | 18 ++++ include/audio_defs.h | 2 + src/ac_ins_amenbo.c | 216 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 240 insertions(+) create mode 100644 include/ac_ins_amenbo.h create mode 100644 src/ac_ins_amenbo.c diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 9bcc7cc1..e09a4a26 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -770,6 +770,10 @@ ac_insect.c: .rodata: [0x80649E00, 0x80649E70] .data: [0x806C2C80, 0x806C3200] .bss: [0x8131B2C8, 0x81320738] +ac_ins_amenbo.c: + .text: [0x80595C74, 0x80596388] + .rodata: [0x80649E70, 0x80649EC8] + .data: [0x806C3200, 0x806C3230] ac_boat.c: .text: [0x805A6CF4, 0x805A856C] .rodata: [0x8064A5B0, 0x8064A630] diff --git a/include/ac_ins_amenbo.h b/include/ac_ins_amenbo.h new file mode 100644 index 00000000..4fada5d7 --- /dev/null +++ b/include/ac_ins_amenbo.h @@ -0,0 +1,18 @@ +#ifndef AC_INS_AMENBO_H +#define AC_INS_AMENBO_H + +#include "types.h" +#include "ac_insect_h.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void aIAB_actor_init(ACTOR* actorx, GAME* game); +extern void aIAB_actor_move(ACTOR* actorx, GAME* game); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/audio_defs.h b/include/audio_defs.h index e8fddb79..500dffd2 100644 --- a/include/audio_defs.h +++ b/include/audio_defs.h @@ -35,6 +35,8 @@ typedef enum audio_sound_effects { NA_SE_LIGHT_ON, NA_SE_LIGHT_OFF, + NA_SE_25 = 0x25, + NA_SE_DRAWER_SHUT = 0x3A, NA_SE_ITEM_GET = 0x40, diff --git a/src/ac_ins_amenbo.c b/src/ac_ins_amenbo.c new file mode 100644 index 00000000..30c56caa --- /dev/null +++ b/src/ac_ins_amenbo.c @@ -0,0 +1,216 @@ +#include "ac_ins_amenbo.h" + +#include "m_field_info.h" +#include "m_name_table.h" +#include "m_common_data.h" +#include "m_player_lib.h" + +enum { + aIAB_ACTION_WAIT, + aIAB_ACTION_LET_ESCAPE, + aIAB_ACTION_MOVE, + aIAB_ACTION_REST, + + aIAB_ACTION_NUM +}; + +#define aIAB_SCALE(insect) ((insect)->f32_work0) +#define aIAB_SCALE_RATE(insect) ((insect)->f32_work1) +#define aIAB_HIT_WALL(insect) ((insect)->s32_work3) + +#define aIAB_RANDOM_ANGLE() ((s16)((fqrand() - 0.5f) * (f32)DEG2SHORT_ANGLE2(120.0f))) + +static void aIAB_actor_move(ACTOR* actorx, GAME* game); +static void aIAB_setupAction(aINS_INSECT_ACTOR* insect, int action, GAME* game); + +extern void aIAB_actor_init(ACTOR* actorx, GAME* game) { + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx; + int act; + + if (actorx->actor_specific == 0) { + actorx->world.position.y = mCoBG_GetBgY_OnlyCenter_FromWpos(actorx->world.position, -14.0f); + xyz_t_move(&actorx->home.position, &actorx->world.position); + insect->bg_type = 2; + act = aIAB_ACTION_MOVE; + } else { + act = aIAB_ACTION_LET_ESCAPE; + } + + insect->bg_range = mFI_UNIT_BASE_SIZE_F; + insect->bg_height = -14.0f; + insect->item = ITM_INSECT34; + actorx->mv_proc = aIAB_actor_move; + aIAB_setupAction(insect, act, game); +} + +static void aIAB_anime_proc(aINS_INSECT_ACTOR* insect) { + insect->_1E0 += 0.5f; + if (insect->_1E0 >= 2.0f) { + insect->_1E0 -= 2.0f; + } +} + +static void aIAB_BGcheck(aINS_INSECT_ACTOR* insect) { + if ((insect->tools_actor.actor_class.bg_collision_check.result.hit_wall & mCoBG_HIT_WALL_FRONT) != 0 && + aIAB_HIT_WALL(insect) == FALSE) { + aIAB_HIT_WALL(insect) = TRUE; + } +} + +static void aIAB_make_hamon(ACTOR* actorx, GAME* game) { + xyz_t ef_pos; + xyz_t water_flow; + s16 dir; + + xyz_t_move(&ef_pos, &actorx->world.position); + ef_pos.y = mCoBG_GetWaterHeight_File(actorx->world.position, __FILE__, 210); + mCoBG_GetWaterFlow(&water_flow, actorx->bg_collision_check.result.unit_attribute); + dir = atans_table(water_flow.z, water_flow.x); + eEC_CLIP->effect_make_proc(eEC_EFFECT_TURI_HAMON, ef_pos, 1, dir, game, EMPTY_NO, 1, 0); +} + +static void aIAB_let_escape(ACTOR* actorx, GAME* game) { + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx; + f32 grav; + + aIAB_anime_proc(insect); + grav = actorx->gravity; + grav += grav * 0.1f * 0.5f; + if (grav > 12.0f) { + grav = 12.0f; + } + + actorx->gravity = grav; + sAdo_OngenPos((u32)actorx, NA_SE_25, &actorx->world.position); +} + +static void aIAB_move(ACTOR* actorx, GAME* game) { + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx; + f32 scale = aIAB_SCALE(insect); + + chase_f(&aIAB_SCALE_RATE(insect), -0.0021f, 0.00035f); + scale += aIAB_SCALE_RATE(insect); + if (scale < 0.0f) { + scale = 0.0f; + } + + aIAB_SCALE(insect) = scale; + actorx->scale.x = 0.01f + scale; + actorx->scale.y = 0.01f - scale; + aIAB_BGcheck(insect); + + /* Change to rest action if not moving or if hit a wall */ + if (F32_IS_ZERO(actorx->speed) || aIAB_HIT_WALL(insect) == TRUE) { + aIAB_setupAction(insect, aIAB_ACTION_REST, game); + } +} + +static void aIAB_rest(ACTOR* actorx, GAME* game) { + aINS_INSECT_ACTOR* insect = (aINS_INSECT_ACTOR*)actorx; + + aIAB_BGcheck(insect); + insect->timer--; + + /* When timer is 0, move again */ + if (insect->timer <= 0) { + aIAB_setupAction(insect, aIAB_ACTION_MOVE, game); + } +} + +static void aIAB_let_escape_init(aINS_INSECT_ACTOR* insect, GAME* game) { + GAME_PLAY* play = (GAME_PLAY*)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(play); + if (player != NULL) { + s16 angleY = player->actor_class.shape_info.rotation.y + aIAB_RANDOM_ANGLE(); + + insect->tools_actor.actor_class.world.angle.y = angleY; + insect->tools_actor.actor_class.shape_info.rotation.y = angleY; + } + + insect->insect_flags.bit_1 = TRUE; + insect->insect_flags.bit_2 = TRUE; +} + +static void aIAB_move_init(aINS_INSECT_ACTOR* insect, GAME* game) { + ACTOR* actorx = (ACTOR*)insect; + s16 angleY = insect->tools_actor.actor_class.world.angle.y; + s16 newAngle; + + /* Turn around if hit a wall */ + if (aIAB_HIT_WALL(insect) == TRUE) { + angleY += DEG2SHORT_ANGLE2(180.0f); + } + + /* Add random angle between -60, 60 */ + newAngle = angleY + aIAB_RANDOM_ANGLE(); + + insect->tools_actor.actor_class.world.angle.y = newAngle; + insect->tools_actor.actor_class.shape_info.rotation.y = newAngle; + insect->tools_actor.actor_class.gravity = 0.3f; + insect->tools_actor.actor_class.max_velocity_y = -2.0f; + insect->target_speed = 0.0f; + insect->speed_step = 0.05f - RANDOM_F(0.03f); + insect->tools_actor.actor_class.speed = 2.3f; + aIAB_SCALE(insect) = 0.0f; + aIAB_SCALE_RATE(insect) = 0.0021f; + aIAB_HIT_WALL(insect) = FALSE; + aIAB_make_hamon(actorx, game); +} + +static void aIAB_rest_init(aINS_INSECT_ACTOR* insect, GAME* game) { + insect->tools_actor.actor_class.speed = 0.0f; + insect->speed_step = 0.0f; + + if (aIAB_HIT_WALL(insect) == TRUE) { + insect->timer = 0; + } else { + insect->timer = 2.0f * RANDOM_F(30.0f); + } + + insect->tools_actor.actor_class.scale.y = 0.01f; +} + +typedef void (*aIAB_INIT_PROC)(aINS_INSECT_ACTOR*, GAME*); + +static void aIAB_setupAction(aINS_INSECT_ACTOR* insect, int action, GAME* game) { + static aIAB_INIT_PROC init_proc[] = { + (aIAB_INIT_PROC)&none_proc1, + &aIAB_let_escape_init, + &aIAB_move_init, + &aIAB_rest_init, + }; + + static aINS_ACTION_PROC act_proc[] = { + (aINS_ACTION_PROC)&none_proc1, + &aIAB_let_escape, + &aIAB_move, + &aIAB_rest, + }; + + insect->action = action; + insect->action_proc = act_proc[action]; + (*init_proc[action])(insect, game); +} + +extern void aIAB_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) { + insect->alpha0 = 255; + aIAB_setupAction(insect, aIAB_ACTION_LET_ESCAPE, game); + } else if (insect->insect_flags.bit_3 == TRUE && insect->insect_flags.bit_2 == FALSE) { + aIAB_setupAction(insect, aIAB_ACTION_LET_ESCAPE, game); + } else { + (*insect->action_proc)(actorx, game); + } +}