mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-30 08:26:27 -04:00
Implement & link ac_gyoei
This commit is contained in:
+1
-1
@@ -975,7 +975,7 @@ config.libs = [
|
||||
Object(NonMatching, "actor/ac_gyo_kaseki.c"),
|
||||
Object(Matching, "actor/ac_gyo_release.c"),
|
||||
Object(NonMatching, "actor/ac_gyo_test.c"),
|
||||
Object(NonMatching, "actor/ac_gyoei.c"),
|
||||
Object(Matching, "actor/ac_gyoei.c"),
|
||||
Object(Matching, "actor/ac_handOverItem.c"),
|
||||
Object(Matching, "actor/ac_haniwa.c"),
|
||||
Object(Matching, "actor/ac_hatumode_control.c"),
|
||||
|
||||
+7
-2
@@ -3,12 +3,14 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "ac_tools.h"
|
||||
#include "ac_gyoei_h.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define aGYO_MAX_GYOEI 2
|
||||
#define aGYO_EXIST_MAX 4
|
||||
|
||||
enum {
|
||||
aGYO_GYO_TYPE_TEST,
|
||||
@@ -150,10 +152,13 @@ typedef struct gyoei_actor_s GYOEI_ACTOR;
|
||||
struct gyoei_actor_s {
|
||||
/* 0x000 */ ACTOR actor_class;
|
||||
/* 0x174 */ aGYO_CTRL_ACTOR ctrl[aGYO_MAX_GYOEI];
|
||||
/* 0x614 */ u8 exist[4];
|
||||
/* 0x618 */ int segment_type[4];
|
||||
/* 0x614 */ u8 exist[aGYO_EXIST_MAX];
|
||||
/* 0x618 */ int segment_type[aGYO_EXIST_MAX];
|
||||
};
|
||||
|
||||
extern void aGTT_actor_init(ACTOR* actorx, GAME* game); // ac_gyo_test.c
|
||||
extern void aGKK_actor_init(ACTOR* actorx, GAME* game); // ac_gyo_kaseki
|
||||
|
||||
extern ACTOR_PROFILE Gyoei_Profile;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
#include "ac_gyoei.h"
|
||||
|
||||
#include "m_common_data.h"
|
||||
#include "m_actor_shadow.h"
|
||||
#include "libultra/libultra.h"
|
||||
#include "m_malloc.h"
|
||||
#include "sys_matrix.h"
|
||||
#include "m_skin_matrix.h"
|
||||
#include "m_rcp.h"
|
||||
#include "m_player_lib.h"
|
||||
|
||||
static void aGYO_actor_ct(ACTOR* actorx, GAME* game);
|
||||
static void aGYO_actor_dt(ACTOR* actorx, GAME* game);
|
||||
static void aGYO_actor_move(ACTOR* actorx, GAME* game);
|
||||
static void aGYO_actor_draw(ACTOR* actorx, GAME* game);
|
||||
|
||||
// clang-format off
|
||||
ACTOR_PROFILE Gyoei_Profile = {
|
||||
mAc_PROFILE_GYOEI,
|
||||
ACTOR_PART_CONTROL,
|
||||
ACTOR_STATE_NO_DRAW_WHILE_CULLED | ACTOR_STATE_NO_MOVE_WHILE_CULLED,
|
||||
EMPTY_NO,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(GYOEI_ACTOR),
|
||||
&aGYO_actor_ct,
|
||||
&aGYO_actor_dt,
|
||||
&aGYO_actor_move,
|
||||
&aGYO_actor_draw,
|
||||
NULL,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static int aGYO_init_dma_and_clip_area(void);
|
||||
static void aGYO_free_clip_area(void);
|
||||
|
||||
static ACTOR* aGYO_ctrlActor = NULL;
|
||||
|
||||
typedef struct gyoei_overlay_s {
|
||||
u8 buf[0x3C00];
|
||||
} aGYO_overlay_c ATTRIBUTE_ALIGN(8);
|
||||
|
||||
static aGYO_overlay_c aGYO_overlay[aGYO_MAX_GYOEI];
|
||||
|
||||
static void aGYO_actor_ct(ACTOR* actorx, GAME* game) {
|
||||
GYOEI_ACTOR* gyoei = (GYOEI_ACTOR*)actorx;
|
||||
int i;
|
||||
aGYO_CTRL_ACTOR* ctrl = gyoei->ctrl;
|
||||
|
||||
for (i = 0; i < aGYO_MAX_GYOEI; i++) {
|
||||
ctrl->exist = FALSE;
|
||||
ctrl->overlay_p = aGYO_overlay[i].buf;
|
||||
ctrl++;
|
||||
}
|
||||
|
||||
for (i = 0; i < aGYO_EXIST_MAX; i++) {
|
||||
gyoei->exist[i] = FALSE;
|
||||
gyoei->segment_type[i] = -1;
|
||||
}
|
||||
|
||||
aGYO_ctrlActor = (ACTOR*)gyoei;
|
||||
aGYO_init_dma_and_clip_area();
|
||||
}
|
||||
|
||||
static void aGYO_actor_dt(ACTOR* actorx, GAME* game) {
|
||||
GYOEI_ACTOR* gyoei = (GYOEI_ACTOR*)actorx;
|
||||
int i;
|
||||
aGYO_CTRL_ACTOR* ctrl = gyoei->ctrl;
|
||||
|
||||
for (i = 0; i < aGYO_MAX_GYOEI; i++) {
|
||||
if (ctrl->overlay_p != NULL) {
|
||||
ctrl->overlay_p = NULL;
|
||||
}
|
||||
|
||||
ctrl++;
|
||||
}
|
||||
|
||||
aGYO_free_clip_area();
|
||||
}
|
||||
|
||||
#include "../src/actor/ac_gyoei_model.c_inc"
|
||||
|
||||
static mActor_proc aGYO_program_dlftbl[] = {
|
||||
&aGTT_actor_init,
|
||||
&aGKK_actor_init,
|
||||
};
|
||||
|
||||
#include "../src/actor/ac_gyoei_clip.c_inc"
|
||||
#include "../src/actor/ac_gyoei_move.c_inc"
|
||||
#include "../src/actor/ac_gyoei_data.c_inc"
|
||||
#include "../src/actor/ac_gyoei_draw.c_inc"
|
||||
@@ -0,0 +1,273 @@
|
||||
static int aGYO_searchCastFishNum(void) {
|
||||
GYOEI_ACTOR* gyoei = (GYOEI_ACTOR*)aGYO_ctrlActor;
|
||||
aGYO_CTRL_ACTOR* ctrl = gyoei->ctrl;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < aGYO_MAX_GYOEI; i++) {
|
||||
if ((ctrl[i].gyo_flags & 4) != 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void aGYO_change_data_area(Object_Exchange_c* exc) {
|
||||
int idx = aGYO_searchCastFishNum();
|
||||
GYOEI_ACTOR* gyoei = (GYOEI_ACTOR*)aGYO_ctrlActor;
|
||||
// @BUG - idx can be -1... why isn't this bounds checked?
|
||||
aGYO_CTRL_ACTOR* ctrl = &gyoei->ctrl[idx];
|
||||
|
||||
ctrl->draw_type = aGYO_DRAW_TYPE_FISH;
|
||||
}
|
||||
|
||||
static void aGYO_destruct(ACTOR* actorx, GAME* game) {
|
||||
aGYO_CTRL_ACTOR* ctrl = (aGYO_CTRL_ACTOR*)actorx;
|
||||
|
||||
ctrl->exist = FALSE;
|
||||
ctrl->gyo_flags = 0;
|
||||
ClObjPipe_dt(game, &ctrl->col_pipe);
|
||||
}
|
||||
|
||||
static int aGYO_searchRegistSpace(void) {
|
||||
GYOEI_ACTOR* gyoei = (GYOEI_ACTOR*)aGYO_ctrlActor;
|
||||
aGYO_CTRL_ACTOR* ctrl = gyoei->ctrl;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < aGYO_MAX_GYOEI; i++) {
|
||||
if (!ctrl[i].exist) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void aGYO_setupActor(aGYO_Init_c* init_data, int idx) {
|
||||
// clang-format off
|
||||
static ACTOR_PROFILE Dummy_Profile = {
|
||||
mAc_PROFILE_GYOEI,
|
||||
ACTOR_PART_BG,
|
||||
ACTOR_STATE_NO_DRAW_WHILE_CULLED | ACTOR_STATE_NO_MOVE_WHILE_CULLED,
|
||||
EMPTY_NO,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(ACTOR),
|
||||
mActor_NONE_PROC1,
|
||||
mActor_NONE_PROC1,
|
||||
mActor_NONE_PROC1,
|
||||
mActor_NONE_PROC1,
|
||||
NULL,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
GYOEI_ACTOR* gyoei = (GYOEI_ACTOR*)aGYO_ctrlActor;
|
||||
aGYO_CTRL_ACTOR* ctrl = &gyoei->ctrl[idx];
|
||||
GAME_PLAY* play = (GAME_PLAY*)init_data->game;
|
||||
Object_Exchange_c* exc = &play->object_exchange;
|
||||
|
||||
bzero(ctrl, sizeof(aGYO_CTRL_ACTOR));
|
||||
ctrl->tools_class.actor_class.shape_info.ofs_y = 200.0f;
|
||||
ctrl->exist = TRUE;
|
||||
ctrl->draw_type = aGYO_DRAW_TYPE_GYOEI;
|
||||
ctrl->gyo_type = init_data->fish_type;
|
||||
ctrl->act_proc = (aGYO_ACT_PROC)&none_proc1;
|
||||
ctrl->range = 40.0f;
|
||||
ctrl->col_flags |= 1;
|
||||
|
||||
Actor_init_actor_class((ACTOR*)ctrl, &Dummy_Profile, NULL, play, -1, init_data->position.x, init_data->position.y,
|
||||
init_data->position.z, 0, 0, 0, play->block_table.block_x, play->block_table.block_z, -1,
|
||||
EMPTY_NO, 0);
|
||||
Shape_Info_init((ACTOR*)ctrl, 0.0f, &mAc_ActorShadowCircle, 5.0f, 5.0f);
|
||||
ctrl->tools_class.actor_class.shape_info.shadow_alpha_change_rate = 0.6f;
|
||||
ctrl->tools_class.actor_class.world = ctrl->tools_class.actor_class.home;
|
||||
ctrl->tools_class.actor_class.shape_info.rotation = ctrl->tools_class.actor_class.world.angle;
|
||||
Actor_world_to_eye((ACTOR*)ctrl, 0.0f);
|
||||
xyz_t_move(&ctrl->tools_class.actor_class.last_world_position, &ctrl->tools_class.actor_class.world.position);
|
||||
ctrl->tools_class.actor_class.cull_width = 350.0f;
|
||||
ctrl->tools_class.actor_class.cull_height = 700.0f;
|
||||
ctrl->tools_class.actor_class.cull_distance = 1000.0f;
|
||||
ctrl->tools_class.actor_class.cull_radius = 350.0f;
|
||||
|
||||
if ((mFI_BkNum2BlockKind(ctrl->tools_class.actor_class.block_x, ctrl->tools_class.actor_class.block_z) &
|
||||
mRF_BLOCKKIND_OFFING) == mRF_BLOCKKIND_OFFING) {
|
||||
ctrl->col_flags &= ~1;
|
||||
}
|
||||
|
||||
if (ctrl->gyo_type == aGYO_TYPE_WHALE) {
|
||||
ctrl->alpha = 50;
|
||||
ctrl->tools_class.actor_class.cull_width = 450.0f;
|
||||
ctrl->tools_class.actor_class.cull_radius = 450.0f;
|
||||
} else {
|
||||
ctrl->alpha = 120;
|
||||
}
|
||||
|
||||
{
|
||||
mActor_proc* init_proc;
|
||||
|
||||
switch (ctrl->gyo_type) {
|
||||
case aGYO_TYPE_SALMON2:
|
||||
ctrl->gyo_type = aGYO_TYPE_SALMON;
|
||||
// fallthrough
|
||||
case aGYO_TYPE_COELACANTH:
|
||||
case aGYO_TYPE_JELLYFISH:
|
||||
case aGYO_TYPE_SEA_BASS:
|
||||
case aGYO_TYPE_RED_SNAPPER:
|
||||
case aGYO_TYPE_BARRED_KNIFEJAW:
|
||||
case aGYO_TYPE_WHALE:
|
||||
init_proc = &aGYO_program_dlftbl[aGYO_GYO_TYPE_KASEKI];
|
||||
break;
|
||||
default:
|
||||
init_proc = &aGYO_program_dlftbl[aGYO_GYO_TYPE_TEST];
|
||||
break;
|
||||
}
|
||||
|
||||
ctrl->tools_class.actor_class.mv_proc = *init_proc;
|
||||
}
|
||||
|
||||
ctrl->tools_class.actor_class.drawn = TRUE;
|
||||
}
|
||||
|
||||
static int aGYO_make_gyoei(aGYO_Init_c* init_data) {
|
||||
int idx = aGYO_searchRegistSpace();
|
||||
int ret = FALSE;
|
||||
|
||||
if (idx >= 0) {
|
||||
aGYO_setupActor(init_data, idx);
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static f32 aGYO_escape_distance(s16 type) {
|
||||
if (type == 0) {
|
||||
return 150.0f;
|
||||
} else {
|
||||
return 30.0f;
|
||||
}
|
||||
}
|
||||
|
||||
static void aGYO_ballcheck(xyz_t* pos_p, f32 r, s16 type) {
|
||||
GYOEI_ACTOR* gyoei = (GYOEI_ACTOR*)aGYO_ctrlActor;
|
||||
aGYO_CTRL_ACTOR* ctrl = gyoei->ctrl;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < aGYO_MAX_GYOEI; i++) {
|
||||
if (ctrl->exist == TRUE) {
|
||||
f32 dist;
|
||||
f32 escape_dist;
|
||||
|
||||
ctrl->escape_flag = FALSE;
|
||||
dist = search_position_distance(&ctrl->tools_class.actor_class.world.position, pos_p);
|
||||
escape_dist = aGYO_escape_distance(type);
|
||||
|
||||
if (dist < escape_dist) {
|
||||
ctrl->escape_flag = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
ctrl++;
|
||||
}
|
||||
}
|
||||
|
||||
static void aGYO_hitcheck(xyz_t* pos_p, s16 size_type) {
|
||||
GYOEI_ACTOR* gyoei = (GYOEI_ACTOR*)aGYO_ctrlActor;
|
||||
aGYO_CTRL_ACTOR* ctrl = gyoei->ctrl;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < aGYO_MAX_GYOEI; i++) {
|
||||
if (ctrl->exist == TRUE && ctrl->escape_flag != TRUE) {
|
||||
f32 dist;
|
||||
f32 escape_dist;
|
||||
|
||||
dist = search_position_distance(&ctrl->tools_class.actor_class.world.position, pos_p);
|
||||
|
||||
switch (size_type) {
|
||||
case aGYO_SIZE_XXS:
|
||||
escape_dist = 70.0f;
|
||||
break;
|
||||
case aGYO_SIZE_XS:
|
||||
case aGYO_SIZE_S:
|
||||
case aGYO_SIZE_M:
|
||||
escape_dist = 85.0f;
|
||||
break;
|
||||
default:
|
||||
escape_dist = 100.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dist < escape_dist) {
|
||||
ctrl->escape_flag = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
ctrl++;
|
||||
}
|
||||
}
|
||||
|
||||
static int aGYO_chk_live_gyoei(int bx, int bz, GAME* game) {
|
||||
GYOEI_ACTOR* gyoei = (GYOEI_ACTOR*)aGYO_ctrlActor;
|
||||
aGYO_CTRL_ACTOR* ctrl = gyoei->ctrl;
|
||||
int i;
|
||||
int ret = FALSE;
|
||||
|
||||
for (i = 0; i < aGYO_MAX_GYOEI; i++) {
|
||||
if (ctrl->exist == TRUE && ctrl->tools_class.actor_class.block_x == bx &&
|
||||
ctrl->tools_class.actor_class.block_z == bz) {
|
||||
ret = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
ctrl++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ACTOR* aGYO_search_near_gyoei(f32 pos_x, f32 pos_z) {
|
||||
GYOEI_ACTOR* gyoei = (GYOEI_ACTOR*)aGYO_ctrlActor;
|
||||
aGYO_CTRL_ACTOR* ctrl = gyoei->ctrl;
|
||||
int i;
|
||||
aGYO_CTRL_ACTOR* ret = NULL;
|
||||
f32 min_dist = 819200.0f;
|
||||
|
||||
for (i = 0; i < aGYO_MAX_GYOEI; i++) {
|
||||
if (ctrl->exist == TRUE) {
|
||||
f32 dx = ((ACTOR*)ctrl)->world.position.x - pos_x;
|
||||
f32 dz = ((ACTOR*)ctrl)->world.position.z - pos_z;
|
||||
f32 dist = SQ(dx) + SQ(dz);
|
||||
|
||||
if (dist < min_dist) {
|
||||
ret = ctrl;
|
||||
min_dist = dist;
|
||||
}
|
||||
}
|
||||
|
||||
ctrl++;
|
||||
}
|
||||
|
||||
return (ACTOR*)ret;
|
||||
}
|
||||
|
||||
static int aGYO_init_dma_and_clip_area(void) {
|
||||
int ret = FALSE;
|
||||
|
||||
CLIP(gyo_clip) = (aGYO_Clip_c*)zelda_malloc(sizeof(aGYO_Clip_c));
|
||||
if (CLIP(gyo_clip) != NULL) {
|
||||
CLIP(gyo_clip)->make_gyoei_proc = &aGYO_make_gyoei;
|
||||
CLIP(gyo_clip)->dt_gyoei_proc = &aGYO_destruct;
|
||||
CLIP(gyo_clip)->ballcheck_gyoei_proc = &aGYO_ballcheck;
|
||||
CLIP(gyo_clip)->hitcheck_gyoei_proc = &aGYO_hitcheck;
|
||||
CLIP(gyo_clip)->chk_live_gyoei_proc = &aGYO_chk_live_gyoei;
|
||||
CLIP(gyo_clip)->search_near_gyoei_proc = &aGYO_search_near_gyoei;
|
||||
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void aGYO_free_clip_area(void) {
|
||||
zelda_free(CLIP(gyo_clip));
|
||||
CLIP(gyo_clip) = NULL;
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
enum {
|
||||
aGYO_ANIME_PAT_TYPE_NONE,
|
||||
aGYO_ANIME_PAT_TYPE_FAST,
|
||||
aGYO_ANIME_PAT_TYPE_SLOW,
|
||||
|
||||
aGYO_ANIME_PAT_TYPE_NUM
|
||||
};
|
||||
|
||||
static int aGYO_anime_ptn[] = {
|
||||
aGYO_ANIME_PAT_TYPE_FAST, aGYO_ANIME_PAT_TYPE_SLOW, aGYO_ANIME_PAT_TYPE_SLOW, aGYO_ANIME_PAT_TYPE_SLOW,
|
||||
aGYO_ANIME_PAT_TYPE_SLOW, aGYO_ANIME_PAT_TYPE_FAST, aGYO_ANIME_PAT_TYPE_SLOW, aGYO_ANIME_PAT_TYPE_SLOW,
|
||||
aGYO_ANIME_PAT_TYPE_FAST, aGYO_ANIME_PAT_TYPE_SLOW, aGYO_ANIME_PAT_TYPE_SLOW, aGYO_ANIME_PAT_TYPE_SLOW,
|
||||
aGYO_ANIME_PAT_TYPE_SLOW, aGYO_ANIME_PAT_TYPE_FAST, aGYO_ANIME_PAT_TYPE_FAST, aGYO_ANIME_PAT_TYPE_SLOW,
|
||||
aGYO_ANIME_PAT_TYPE_FAST, aGYO_ANIME_PAT_TYPE_FAST, aGYO_ANIME_PAT_TYPE_FAST, aGYO_ANIME_PAT_TYPE_SLOW,
|
||||
aGYO_ANIME_PAT_TYPE_SLOW, aGYO_ANIME_PAT_TYPE_SLOW, aGYO_ANIME_PAT_TYPE_SLOW, aGYO_ANIME_PAT_TYPE_FAST,
|
||||
aGYO_ANIME_PAT_TYPE_FAST, aGYO_ANIME_PAT_TYPE_SLOW, aGYO_ANIME_PAT_TYPE_SLOW, aGYO_ANIME_PAT_TYPE_FAST,
|
||||
aGYO_ANIME_PAT_TYPE_FAST, aGYO_ANIME_PAT_TYPE_FAST, aGYO_ANIME_PAT_TYPE_FAST, aGYO_ANIME_PAT_TYPE_SLOW,
|
||||
aGYO_ANIME_PAT_TYPE_FAST, aGYO_ANIME_PAT_TYPE_FAST, aGYO_ANIME_PAT_TYPE_FAST, aGYO_ANIME_PAT_TYPE_SLOW,
|
||||
aGYO_ANIME_PAT_TYPE_SLOW, aGYO_ANIME_PAT_TYPE_SLOW, aGYO_ANIME_PAT_TYPE_SLOW, aGYO_ANIME_PAT_TYPE_SLOW,
|
||||
aGYO_ANIME_PAT_TYPE_NONE, aGYO_ANIME_PAT_TYPE_NONE, aGYO_ANIME_PAT_TYPE_NONE, aGYO_ANIME_PAT_TYPE_NONE,
|
||||
aGYO_ANIME_PAT_TYPE_NONE,
|
||||
};
|
||||
|
||||
static int aGYO_anime_frame(aGYO_CTRL_ACTOR* ctrl) {
|
||||
static int aGYO_frame_ptn1[] = { 1, 1, 0, 0, 2, 2, 0, 0 };
|
||||
static int aGYO_frame_ptn2[] = { 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0 };
|
||||
|
||||
int idx = ctrl->anim_frame;
|
||||
int ret;
|
||||
|
||||
idx++;
|
||||
switch (aGYO_anime_ptn[ctrl->gyo_type]) {
|
||||
case aGYO_ANIME_PAT_TYPE_FAST:
|
||||
if (idx >= ARRAY_COUNT(aGYO_frame_ptn1)) {
|
||||
idx = 0;
|
||||
if ((ctrl->gyo_flags & 0x200) != 0) {
|
||||
ctrl->swork2--;
|
||||
}
|
||||
}
|
||||
|
||||
ret = aGYO_frame_ptn1[idx];
|
||||
break;
|
||||
case aGYO_ANIME_PAT_TYPE_SLOW:
|
||||
if (idx >= ARRAY_COUNT(aGYO_frame_ptn2)) {
|
||||
idx = 0;
|
||||
if ((ctrl->gyo_flags & 0x200) != 0) {
|
||||
ctrl->swork2--;
|
||||
}
|
||||
}
|
||||
|
||||
ret = aGYO_frame_ptn2[idx];
|
||||
break;
|
||||
default:
|
||||
idx = 0;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
ctrl->anim_frame = idx;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void aGYO_actor_draw_fish(GRAPH* graph, aGYO_CTRL_ACTOR* ctrl, GAME* game) {
|
||||
static f32 aGYO_hosei_y[] = {
|
||||
0.0f, 0.0f, 2.2f, 2.2f, 2.2f, 0.0f, 1.5f, 2.2f, 0.0f, 2.2f, 2.2f, 2.2f, 1.5f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f, 2.2f, 1.5f, 2.2f, 1.5f, 0.0f, 0.0f, 2.2f, 2.2f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 2.2f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
||||
};
|
||||
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
int frame;
|
||||
|
||||
Matrix_translate(((ACTOR*)ctrl)->world.position.x, ((ACTOR*)ctrl)->world.position.y - aGYO_hosei_y[ctrl->gyo_type],
|
||||
((ACTOR*)ctrl)->world.position.z, 0);
|
||||
Matrix_mult(&play->billboard_matrix, 1);
|
||||
|
||||
if (ctrl->gyo_type < (aGYO_TYPE_WHALE + 1) && (ctrl->gyo_flags & 0x200) != 0) {
|
||||
int cnt;
|
||||
|
||||
if (ctrl->pattern_subcounter == 0) {
|
||||
cnt = 0;
|
||||
} else {
|
||||
cnt = --ctrl->pattern_subcounter;
|
||||
}
|
||||
|
||||
if (cnt != 0) {
|
||||
if (aGYO_anime_ptn[ctrl->gyo_type] == aGYO_ANIME_PAT_TYPE_FAST) {
|
||||
ctrl->move_counter += 0xE38;
|
||||
} else {
|
||||
ctrl->move_counter += 0xAAA;
|
||||
}
|
||||
} else {
|
||||
if (ctrl->pattern_counter == 0) {
|
||||
cnt = 0;
|
||||
} else {
|
||||
cnt = --ctrl->pattern_counter;
|
||||
}
|
||||
|
||||
if (cnt == 0) {
|
||||
ctrl->pattern_counter = (s16)RANDOM(15);
|
||||
|
||||
if (aGYO_anime_ptn[ctrl->gyo_type] == aGYO_ANIME_PAT_TYPE_FAST) {
|
||||
ctrl->pattern_subcounter = 9;
|
||||
} else {
|
||||
ctrl->pattern_subcounter = 12;
|
||||
}
|
||||
|
||||
if (RANDOM_F(2.0f) < 1.0f) {
|
||||
ctrl->move_counter = DEG2SHORT_ANGLE2(0.0f);
|
||||
} else {
|
||||
ctrl->move_counter = DEG2SHORT_ANGLE2(180.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctrl->move_angle = DEG2SHORT_ANGLE2(13 * sin_s(ctrl->move_counter));
|
||||
Matrix_RotateY(ctrl->move_angle, 1);
|
||||
}
|
||||
|
||||
Matrix_scale(((ACTOR*)ctrl)->scale.x, ((ACTOR*)ctrl)->scale.y, ((ACTOR*)ctrl)->scale.z, 1);
|
||||
|
||||
if ((ctrl->gyo_flags & 0x200) != 0 && ctrl->swork2 <= 0) {
|
||||
int cnt;
|
||||
|
||||
if (ctrl->swork3 == 0) {
|
||||
cnt = 0;
|
||||
} else {
|
||||
cnt = --ctrl->swork3;
|
||||
}
|
||||
|
||||
if (cnt == 0) {
|
||||
ctrl->swork2 = RANDOM(3) + 1;
|
||||
ctrl->swork3 = RANDOM2(10) + 15;
|
||||
}
|
||||
|
||||
frame = 0;
|
||||
} else {
|
||||
frame = aGYO_anime_frame(ctrl);
|
||||
}
|
||||
|
||||
OPEN_POLY_OPA_DISP(graph);
|
||||
|
||||
gSPMatrix(POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_LOAD | G_MTX_NOPUSH);
|
||||
gSPDisplayList(POLY_OPA_DISP++, ((Gfx**)aGYO_displayList[ctrl->gyo_type])[(int)(frame * 0.5f)]);
|
||||
|
||||
CLOSE_POLY_OPA_DISP(graph);
|
||||
|
||||
{
|
||||
static xyz_t offset0 = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
mAc_UnagiActorShadow((ACTOR*)ctrl, game, offset0);
|
||||
}
|
||||
}
|
||||
|
||||
extern Gfx act_gyoei02_00_modelT[];
|
||||
|
||||
static void aGYO_actor_draw_gyoei(GRAPH* graph, aGYO_CTRL_ACTOR* ctrl, GAME* game) {
|
||||
s16 angleX;
|
||||
s16 angleY;
|
||||
int idx0;
|
||||
int idx1;
|
||||
u32 t;
|
||||
|
||||
angleX = ((ACTOR*)ctrl)->shape_info.rotation.x;
|
||||
angleY = ((ACTOR*)ctrl)->shape_info.rotation.y + DEG2SHORT_ANGLE2(180.0f);
|
||||
t = (u32)ctrl->fwork0;
|
||||
idx0 = aGYO_2tile_texture_idx[t][0];
|
||||
idx1 = aGYO_2tile_texture_idx[t][1];
|
||||
|
||||
if ((ctrl->gyo_flags & 0x100) != 0) {
|
||||
int alpha = (ctrl->work0 - 10) * 6;
|
||||
|
||||
if (alpha <= 0) {
|
||||
alpha = 0;
|
||||
}
|
||||
|
||||
ctrl->alpha = alpha;
|
||||
}
|
||||
|
||||
Matrix_translate(((ACTOR*)ctrl)->world.position.x, ((ACTOR*)ctrl)->world.position.y,
|
||||
((ACTOR*)ctrl)->world.position.z, 0);
|
||||
Matrix_RotateX(angleX, 1);
|
||||
Matrix_RotateY(angleY, 1);
|
||||
Matrix_scale(((ACTOR*)ctrl)->scale.x * 0.4f, ((ACTOR*)ctrl)->scale.y, ((ACTOR*)ctrl)->scale.z, 1);
|
||||
|
||||
OPEN_DISP(graph);
|
||||
|
||||
gSPMatrix(NEXT_POLY_XLU_DISP, _Matrix_to_Mtx_new(graph), G_MTX_LOAD | G_MTX_NOPUSH);
|
||||
gSPSegment(NEXT_POLY_XLU_DISP, ANIME_1_TXT_SEG, aGYO_texture_table[idx0]);
|
||||
gSPSegment(NEXT_POLY_XLU_DISP, ANIME_2_TXT_SEG, aGYO_texture_table[idx1]);
|
||||
gDPSetPrimColor(NEXT_POLY_XLU_DISP, 0, aGYO_prim_f[t], 0, 0, 0, ctrl->alpha);
|
||||
gSPDisplayList(NEXT_POLY_XLU_DISP, act_gyoei02_00_modelT);
|
||||
|
||||
CLOSE_DISP(graph);
|
||||
}
|
||||
|
||||
static void aGYO_actor_draw(ACTOR* actorx, GAME* game) {
|
||||
GYOEI_ACTOR* gyoei = (GYOEI_ACTOR*)actorx;
|
||||
aGYO_CTRL_ACTOR* ctrl = gyoei->ctrl;
|
||||
GRAPH* graph = game->graph;
|
||||
int i;
|
||||
|
||||
Matrix_push();
|
||||
_texture_z_light_fog_prim(graph);
|
||||
_texture_z_light_fog_prim_xlu(graph);
|
||||
|
||||
for (i = 0; i < aGYO_MAX_GYOEI; i++) {
|
||||
if (ctrl->exist == TRUE && ((ACTOR*)ctrl)->drawn &&
|
||||
(((ACTOR*)ctrl)->state_bitfield & (ACTOR_STATE_NO_CULL | ACTOR_STATE_NO_DRAW_WHILE_CULLED)) ==
|
||||
(ACTOR_STATE_NO_CULL | ACTOR_STATE_NO_DRAW_WHILE_CULLED)) {
|
||||
if (ctrl->draw_type == aGYO_DRAW_TYPE_FISH) {
|
||||
aGYO_actor_draw_fish(graph, ctrl, game);
|
||||
} else {
|
||||
aGYO_actor_draw_gyoei(graph, ctrl, game);
|
||||
}
|
||||
}
|
||||
|
||||
ctrl++;
|
||||
}
|
||||
|
||||
Matrix_pull();
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
static void aGYO_position_move(aGYO_CTRL_ACTOR* ctrl) {
|
||||
static f32 dec_step[] = {
|
||||
1.0f, // aGYO_SIZE_XXS
|
||||
1.0f, // aGYO_SIZE_XS
|
||||
1.0f, // aGYO_SIZE_S
|
||||
1.0f, // aGYO_SIZE_M
|
||||
1.0f, // aGYO_SIZE_L
|
||||
1.0f, // aGYO_SIZE_XL
|
||||
1.0f, // aGYO_SIZE_XXL
|
||||
0.0f, // aGYO_SIZE_WHALE
|
||||
};
|
||||
|
||||
xyz_t_move(&((ACTOR*)ctrl)->last_world_position, &((ACTOR*)ctrl)->world.position);
|
||||
|
||||
if (ctrl->fwork0 <= 0.0f) {
|
||||
ctrl->fwork0 += 19.0f;
|
||||
} else {
|
||||
ctrl->fwork0 -= dec_step[ctrl->size_type] * 0.5f;
|
||||
}
|
||||
|
||||
chase_f(&((ACTOR*)ctrl)->speed, ctrl->speed, ctrl->speed_step * 0.5f);
|
||||
Actor_position_moveF((ACTOR*)ctrl);
|
||||
}
|
||||
|
||||
static void aGYO_BGcheck(aGYO_CTRL_ACTOR* ctrl) {
|
||||
if ((ctrl->col_flags & 1) != 0) {
|
||||
mCoBG_BgCheckControll(NULL, (ACTOR*)ctrl, ctrl->range, 0.0f, FALSE, FALSE, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void aGYO_cull_check(ACTOR* actorx, GAME_PLAY* play) {
|
||||
Skin_Matrix_PrjMulVector(&play->projection_matrix, &actorx->world.position, &actorx->camera_position, &actorx->camera_w);
|
||||
if (!Actor_draw_actor_no_culling_check(actorx)) {
|
||||
f32 dist;
|
||||
ACTOR* playerx = GET_PLAYER_ACTOR_ACTOR(play);
|
||||
|
||||
actorx->state_bitfield &= ~ACTOR_STATE_NO_CULL;
|
||||
dist = search_position_distance(&actorx->world.position, &playerx->world.position);
|
||||
if (dist > 600.0f && (actorx->block_x != play->block_table.block_x || actorx->block_z != play->block_table.block_z)) {
|
||||
aGYO_destruct(actorx, (GAME*)play);
|
||||
}
|
||||
} else {
|
||||
actorx->state_bitfield |= ACTOR_STATE_NO_CULL;
|
||||
}
|
||||
}
|
||||
|
||||
static u8 bite_check(void) {
|
||||
GYOEI_ACTOR* gyoei = (GYOEI_ACTOR*)aGYO_ctrlActor;
|
||||
aGYO_CTRL_ACTOR* ctrl = gyoei->ctrl;
|
||||
s16 i;
|
||||
u8 ret = FALSE;
|
||||
|
||||
for (i = 0; i < aGYO_MAX_GYOEI; i++) {
|
||||
if ((ctrl->gyo_flags & 2) != 0) {
|
||||
ret = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
ctrl++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void aGYO_actor_move(ACTOR* actorx, GAME* game) {
|
||||
GYOEI_ACTOR* gyoei = (GYOEI_ACTOR*)actorx;
|
||||
aGYO_CTRL_ACTOR* ctrl = gyoei->ctrl;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < aGYO_MAX_GYOEI; i++) {
|
||||
if (ctrl->exist == TRUE) {
|
||||
((ACTOR*)ctrl)->state_bitfield &= ~ACTOR_STATE_24;
|
||||
|
||||
if ((((ACTOR*)ctrl)->state_bitfield & (ACTOR_STATE_NO_CULL | ACTOR_STATE_NO_MOVE_WHILE_CULLED)) != 0) {
|
||||
aGYO_position_move(ctrl);
|
||||
aGYO_BGcheck(ctrl);
|
||||
|
||||
if (bite_check()) {
|
||||
ctrl->gyo_flags |= 1;
|
||||
} else {
|
||||
ctrl->gyo_flags &= ~1;
|
||||
}
|
||||
|
||||
if ((ctrl->gyo_flags & 8) != 0) {
|
||||
ctrl->gyo_flags &= ~8;
|
||||
ctrl->gyo_flags |= 4;
|
||||
aGYO_change_data_area(&play->object_exchange);
|
||||
}
|
||||
|
||||
(*((ACTOR*)ctrl)->mv_proc)((ACTOR*)ctrl, game);
|
||||
Actor_world_to_eye((ACTOR*)ctrl, 0.0f);
|
||||
}
|
||||
|
||||
aGYO_cull_check((ACTOR*)ctrl, play);
|
||||
if ((ctrl->gyo_flags & 0x20) != 0) {
|
||||
ctrl->gyo_flags &= ~0x20;
|
||||
aGYO_destruct((ACTOR*)ctrl, game);
|
||||
}
|
||||
}
|
||||
|
||||
ctrl++;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user