EnGe3 (Aveil) OK and documented, object_geldb documented (#1072)

* OK

* Import data

* Name functions and variables

* CSACTION enum

* Finish code documentation, do most of object

* Document object

* Finish docs

* Apply suggestions from code review

Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>

* More review

* Format

* Review

* Format

* fix merge

* weekEventReg

* PR

* review

* format

---------

Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>
Co-authored-by: angie <angheloalf95@gmail.com>
This commit is contained in:
EllipticEllipsis
2023-09-24 03:11:36 +01:00
committed by GitHub
parent b88aa2c0fc
commit 17e7f470e2
6 changed files with 522 additions and 121 deletions
+382 -26
View File
@@ -1,7 +1,7 @@
/*
* File: z_en_ge3.c
* Overlay: ovl_En_Ge3
* Description: Aviel
* Description: Aviel, leader of the Gerudo Pirates
*/
#include "z_en_ge3.h"
@@ -15,7 +15,26 @@ void EnGe3_Destroy(Actor* thisx, PlayState* play);
void EnGe3_Update(Actor* thisx, PlayState* play);
void EnGe3_Draw(Actor* thisx, PlayState* play);
#if 0
void EnGe3_ChangeAnim(EnGe3* this, s16 animIndex, u8 mode, f32 morphFrames);
void EnGe3_SetupPath(EnGe3* this, PlayState* play);
void EnGe3_Idle(EnGe3* this, PlayState* play);
void EnGe3_AveilsChamberIdle(EnGe3* this, PlayState* play);
s32 EnGe3_ValidatePictograph(PlayState* play, Actor* thisx);
typedef enum GerudoAveilAnimation {
/* -1 */ GERUDO_AVEIL_ANIM_NONE = -1,
/* 0 */ GERUDO_AVEIL_ANIM_STAND,
/* 1 */ GERUDO_AVEIL_ANIM_WALK,
/* 2 */ GERUDO_AVEIL_ANIM_HAND_ON_HIP_WAIT,
/* 3 */ GERUDO_AVEIL_ANIM_TURN_HEAD,
/* 4 */ GERUDO_AVEIL_ANIM_WAIT,
/* 5 */ GERUDO_AVEIL_ANIM_DEMAND,
/* 6 */ GERUDO_AVEIL_ANIM_DISMISS,
/* 7 */ GERUDO_AVEIL_ANIM_BEG,
/* 8 */ GERUDO_AVEIL_ANIM_RUN_AWAY,
/* 9 */ GERUDO_AVEIL_ANIM_MAX
} GerudoAveilAnimation;
ActorInit En_Ge3_InitVars = {
ACTOR_EN_GE3,
ACTORCAT_NPC,
@@ -28,49 +47,386 @@ ActorInit En_Ge3_InitVars = {
(ActorFunc)EnGe3_Draw,
};
// static ColliderCylinderInit sCylinderInit = {
static ColliderCylinderInit D_809A0DA0 = {
{ COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, },
{ ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x01000222, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
static ColliderCylinderInit sCylinderInit = {
{
COLTYPE_NONE,
AT_NONE,
AC_ON | AC_TYPE_PLAYER,
OC1_ON | OC1_TYPE_ALL,
OC2_TYPE_1,
COLSHAPE_CYLINDER,
},
{
ELEMTYPE_UNK0,
{ 0x00000000, 0x00, 0x00 },
{ 0x01000222, 0x00, 0x00 },
TOUCH_NONE | TOUCH_SFX_NORMAL,
BUMP_ON,
OCELEM_ON,
},
{ 20, 50, 0, { 0, 0, 0 } },
};
#endif
void EnGe3_Init(Actor* thisx, PlayState* play) {
s32 pad;
EnGe3* this = THIS;
extern ColliderCylinderInit D_809A0DA0;
ActorShape_Init(&this->picto.actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f);
SkelAnime_InitFlex(play, &this->skelAnime, &gGerudoRedSkel, NULL, this->jointTable, this->morphTable,
GERUDO_RED_LIMB_MAX);
Animation_PlayLoop(&this->skelAnime, &gGerudoRedHandOnHipWaitAnim);
Collider_InitAndSetCylinder(play, &this->collider, &this->picto.actor, &sCylinderInit);
this->picto.actor.colChkInfo.mass = MASS_IMMOVABLE;
Actor_SetScale(&this->picto.actor, 0.01f);
extern UNK_TYPE D_0600A808;
this->animIndex = GERUDO_AVEIL_ANIM_NONE;
this->cueId = GERUDO_AVEIL_CUEID_NONE;
this->picto.validationFunc = EnGe3_ValidatePictograph;
EnGe3_SetupPath(this, play);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge3/EnGe3_Init.s")
if (GERUDO_AVEIL_GET_TYPE(&this->picto.actor) == GERUDO_AVEIL_TYPE_AVEILS_CHAMBER) {
EnGe3_ChangeAnim(this, GERUDO_AVEIL_ANIM_HAND_ON_HIP_WAIT, ANIMMODE_LOOP, 0.0f);
this->actionFunc = EnGe3_AveilsChamberIdle;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge3/EnGe3_Destroy.s")
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_83_02)) {
Actor_Kill(&this->picto.actor);
return;
}
} else {
EnGe3_ChangeAnim(this, GERUDO_AVEIL_ANIM_WALK, ANIMMODE_LOOP, 0.0f);
this->actionFunc = EnGe3_Idle;
this->picto.actor.speed = 1.5f;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge3/func_809A0070.s")
this->stateFlags = 0;
this->picto.actor.targetMode = 6;
this->picto.actor.terminalVelocity = -4.0f;
this->picto.actor.gravity = -1.0f;
CLEAR_WEEKEVENTREG(WEEKEVENTREG_80_08);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge3/func_809A00F8.s")
void EnGe3_Destroy(Actor* thisx, PlayState* play) {
EnGe3* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge3/func_809A020C.s")
Collider_DestroyCylinder(play, &this->collider);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge3/func_809A024C.s")
void EnGe3_ChangeAnim(EnGe3* this, s16 animIndex, u8 mode, f32 morphFrames) {
static AnimationHeader* sAnimations[GERUDO_AVEIL_ANIM_MAX] = {
&gGerudoRedStandAnim, // GERUDO_AVEIL_ANIM_STAND
&gGerudoRedWalkAnim, // GERUDO_AVEIL_ANIM_WALK
&gGerudoRedHandOnHipWaitAnim, // GERUDO_AVEIL_ANIM_HAND_ON_HIP_WAIT
&gGerudoRedTurnHeadAnim, // GERUDO_AVEIL_ANIM_TURN_HEAD
&gGerudoRedWaitAnim, // GERUDO_AVEIL_ANIM_WAIT
&gGerudoRedDemandAnim, // GERUDO_AVEIL_ANIM_DEMAND
&gGerudoRedDismissAnim, // GERUDO_AVEIL_ANIM_DISMISS
&gGerudoRedBegAnim, // GERUDO_AVEIL_ANIM_BEG
&gGerudoRedRunAwayAnim, // GERUDO_AVEIL_ANIM_RUN_AWAY
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge3/func_809A0350.s")
Animation_Change(&this->skelAnime, sAnimations[animIndex], 1.0f, 0.0f,
Animation_GetLastFrame(sAnimations[animIndex]), mode, morphFrames);
this->animIndex = animIndex;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge3/func_809A03AC.s")
void EnGe3_LookAtPlayer(EnGe3* this, PlayState* play) {
s16 yawDiff = this->picto.actor.yawTowardsPlayer - this->picto.actor.shape.rot.y;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge3/func_809A03FC.s")
if ((ABS_ALT(yawDiff) <= 0x2300) && (this->picto.actor.xzDistToPlayer < 100.0f)) {
Actor_TrackPlayer(play, &this->picto.actor, &this->headRot, &this->torsoRot, this->picto.actor.focus.pos);
} else {
Math_SmoothStepToS(&this->headRot.x, 0, 6, 0x1838, 0x64);
Math_SmoothStepToS(&this->headRot.y, 0, 6, 0x1838, 0x64);
Math_SmoothStepToS(&this->torsoRot.x, 0, 6, 0x1838, 0x64);
Math_SmoothStepToS(&this->torsoRot.y, 0, 6, 0x1838, 0x64);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge3/func_809A04D0.s")
void EnGe3_SetupPath(EnGe3* this, PlayState* play) {
this->curPointIndex = 0;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge3/func_809A0820.s")
if (GERUDO_AVEIL_GET_PATH(&this->picto.actor) != GERUDO_AVEIL_PATH_INDEX_NONE) {
this->path = &play->setupPathList[GERUDO_AVEIL_GET_PATH(&this->picto.actor)];
} else {
this->path = NULL;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge3/func_809A08A4.s")
/**
* @return true if no path or reached end of path
*/
s32 EnGe3_FollowPath(EnGe3* this) {
Path* path = this->path;
Vec3s* curPoint;
f32 diffX;
f32 diffZ;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge3/EnGe3_Update.s")
if (path == NULL) {
return true;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge3/func_809A096C.s")
curPoint = Lib_SegmentedToVirtual(path->points);
curPoint += this->curPointIndex;
diffX = curPoint->x - this->picto.actor.world.pos.x;
diffZ = curPoint->z - this->picto.actor.world.pos.z;
this->picto.actor.world.rot.y = Math_Atan2S(diffX, diffZ);
Math_SmoothStepToS(&this->picto.actor.shape.rot.y, this->picto.actor.world.rot.y, 2, 0x7D0, 0xC8);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge3/func_809A0A14.s")
if ((SQ(diffX) + SQ(diffZ)) < SQ(10.0f)) {
this->curPointIndex++;
if (this->curPointIndex >= path->count) {
return true;
}
}
return false;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge3/func_809A0C60.s")
void EnGe3_Scream(EnGe3* this) {
if ((s32)Rand_ZeroFloat(2.0f) == 0) {
Actor_PlaySfx(&this->picto.actor, NA_SE_VO_FPVO00);
} else {
Actor_PlaySfx(&this->picto.actor, NA_SE_VO_FPVO01);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge3/EnGe3_Draw.s")
void EnGe3_Idle(EnGe3* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
EnGe3_LookAtPlayer(this, play);
if (EnGe3_FollowPath(this)) {
EnGe3_SetupPath(this, play);
}
}
void EnGe3_ThrowPlayerOut(EnGe3* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
Math_SmoothStepToS(&this->picto.actor.shape.rot.y, this->picto.actor.yawTowardsPlayer, 2, 0x400, 0x100);
if (this->actionTimer > 0) {
this->actionTimer--;
} else if (play->nextEntrance != play->setupExitList[GERUDO_AVEIL_GET_EXIT(&this->picto.actor)]) {
play->nextEntrance = play->setupExitList[GERUDO_AVEIL_GET_EXIT(&this->picto.actor)];
play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_38;
CLEAR_WEEKEVENTREG(WEEKEVENTREG_80_08);
}
}
void EnGe3_AveilsChamberIdle(EnGe3* this, PlayState* play) {
if (SkelAnime_Update(&this->skelAnime) && (this->cueId == GERUDO_AVEIL_CUEID_INSTRUCT)) {
EnGe3_ChangeAnim(this, GERUDO_AVEIL_ANIM_WAIT, ANIMMODE_ONCE, 0.0f);
}
if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_108)) {
s16 cueId = play->csCtx.actorCues[Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_108)]->id;
if (this->cueId != GERUDO_AVEIL_CUEID_BEEHIVE_RUN_AWAY) {
Cutscene_ActorTranslateAndYaw(&this->picto.actor, play, Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_108));
}
if (this->cueId != cueId) {
this->cueId = cueId;
switch (this->cueId) {
// Both cutscenes
case GERUDO_AVEIL_CUEID_WAIT:
EnGe3_ChangeAnim(this, GERUDO_AVEIL_ANIM_HAND_ON_HIP_WAIT, ANIMMODE_LOOP, 0.0f);
break;
// Instructing expedition leader cutscene
case GERUDO_AVEIL_CUEID_PAUSE:
EnGe3_ChangeAnim(this, GERUDO_AVEIL_ANIM_TURN_HEAD, ANIMMODE_ONCE, 0.0f);
this->skelAnime.playSpeed = 0.0f;
break;
case GERUDO_AVEIL_CUEID_INSTRUCT:
EnGe3_ChangeAnim(this, GERUDO_AVEIL_ANIM_TURN_HEAD, ANIMMODE_ONCE, 0.0f);
break;
case GERUDO_AVEIL_CUEID_DEMAND:
EnGe3_ChangeAnim(this, GERUDO_AVEIL_ANIM_DEMAND, ANIMMODE_LOOP, 0.0f);
break;
case GERUDO_AVEIL_CUEID_DISMISS:
EnGe3_ChangeAnim(this, GERUDO_AVEIL_ANIM_DISMISS, ANIMMODE_ONCE, 0.0f);
break;
case GERUDO_AVEIL_CUEID_BEG:
EnGe3_ChangeAnim(this, GERUDO_AVEIL_ANIM_BEG, ANIMMODE_LOOP, 0.0f);
break;
// Fleeing from bees cutscene
case GERUDO_AVEIL_CUEID_BEEHIVE_RUN_AWAY:
EnGe3_ChangeAnim(this, GERUDO_AVEIL_ANIM_RUN_AWAY, ANIMMODE_LOOP, 0.0f);
this->picto.actor.speed = 5.0f;
this->screamTimer = (s32)(Rand_ZeroFloat(10.0f) + 20.0f);
break;
case GERUDO_AVEIL_CUEID_BEEHIVE_VANISH:
Actor_Kill(&this->picto.actor);
break;
default:
break;
}
SkelAnime_Update(&this->skelAnime);
}
} else if ((this->picto.actor.xzDistToPlayer < 700.0f) && (fabsf(this->picto.actor.playerHeightRel) < 100.0f) &&
!Play_InCsMode(play)) {
func_800B7298(play, &this->picto.actor, PLAYER_CSMODE_26);
Lib_PlaySfx(NA_SE_SY_FOUND);
if (Player_GetMask(play) == PLAYER_MASK_STONE) { // Not fooled by Stone Mask
Message_StartTextbox(play, 0x11AF, &this->picto.actor);
} else {
Message_StartTextbox(play, 0x11AE, &this->picto.actor);
}
this->actionFunc = EnGe3_ThrowPlayerOut;
this->actionTimer = 50;
SET_WEEKEVENTREG(WEEKEVENTREG_80_08);
}
if (this->cueId == GERUDO_AVEIL_CUEID_BEEHIVE_RUN_AWAY) {
this->picto.actor.speed = 5.0f;
EnGe3_FollowPath(this);
if (Animation_OnFrame(&this->skelAnime, 2.0f) || Animation_OnFrame(&this->skelAnime, 6.0f)) {
Actor_PlaySfx(&this->picto.actor, NA_SE_EV_PIRATE_WALK);
}
if (this->screamTimer > 0) {
this->screamTimer--;
} else {
this->screamTimer = (s32)(Rand_ZeroFloat(10.0f) + 20.0f);
EnGe3_Scream(this);
}
}
}
void EnGe3_UpdateColliderAndMove(Actor* thisx, PlayState* play) {
s32 pad;
EnGe3* this = THIS;
Collider_UpdateCylinder(&this->picto.actor, &this->collider);
CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base);
Actor_MoveWithGravity(&this->picto.actor);
Actor_UpdateBgCheckInfo(play, &this->picto.actor, 40.0f, 25.0f, 40.0f, UPDBGCHECKINFO_FLAG_4);
}
void EnGe3_Blink(EnGe3* this, PlayState* play) {
if (DECR(this->blinkTimer) == 0) {
this->blinkTimer = Rand_S16Offset(60, 60);
}
this->eyeIndex = this->blinkTimer;
if (this->eyeIndex >= 3) {
this->eyeIndex = 0;
}
}
void EnGe3_Update(Actor* thisx, PlayState* play) {
EnGe3* this = THIS;
EnGe3_UpdateColliderAndMove(&this->picto.actor, play);
this->actionFunc(this, play);
EnGe3_Blink(this, play);
}
s32 EnGe3_ValidatePictograph(PlayState* play, Actor* thisx) {
s32 ret = Snap_ValidatePictograph(play, thisx, PICTO_VALID_PIRATE_GOOD, &thisx->focus.pos, &thisx->shape.rot, 10.0f,
400.0f, -1);
ret |= Snap_ValidatePictograph(play, thisx, PICTO_VALID_PIRATE_TOO_FAR, &thisx->focus.pos, &thisx->shape.rot, 10.0f,
1200.0f, -1);
return ret;
}
s32 EnGe3_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) {
EnGe3* this = THIS;
switch (limbIndex) {
case GERUDO_RED_LIMB_VEIL:
case GERUDO_RED_LIMB_RIGHT_SWORD:
case GERUDO_RED_LIMB_LEFT_SWORD:
*dList = NULL;
return false;
case GERUDO_RED_LIMB_HEAD:
rot->x += this->headRot.y;
// fallthrough
default:
// This is required since EnGe3 shares a skeleton with EnKaizoku; it avoids stale colours being used in the
// displaylists.
OPEN_DISPS(play->state.gfxCtx);
switch (limbIndex) {
case GERUDO_RED_LIMB_NECK:
break;
case GERUDO_RED_LIMB_HEAD:
gDPPipeSync(POLY_OPA_DISP++);
gDPSetEnvColor(POLY_OPA_DISP++, 80, 60, 10, 255);
break;
case GERUDO_RED_LIMB_RIGHT_SWORD:
case GERUDO_RED_LIMB_LEFT_SWORD:
gDPPipeSync(POLY_OPA_DISP++);
gDPSetEnvColor(POLY_OPA_DISP++, 140, 170, 230, 255);
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255);
break;
default:
gDPPipeSync(POLY_OPA_DISP++);
gDPSetEnvColor(POLY_OPA_DISP++, 140, 0, 0, 255);
break;
}
CLOSE_DISPS(play->state.gfxCtx);
if (this->animIndex == GERUDO_AVEIL_ANIM_HAND_ON_HIP_WAIT) {
// Fidget
if ((limbIndex == GERUDO_RED_LIMB_RIGHT_FOREARM) || (limbIndex == GERUDO_RED_LIMB_LEFT_FOREARM) ||
(limbIndex == GERUDO_RED_LIMB_TORSO)) {
s32 temp = limbIndex * 50;
// required to match
rot->y = rot->y + (s32)(Math_SinS(play->state.frames * (temp + 0x814)) * 200.0f);
rot->z = rot->z + (s32)(Math_CosS(play->state.frames * (temp + 0x940)) * 200.0f);
}
}
break;
}
return false;
}
void EnGe3_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
EnGe3* this = THIS;
Vec3f sFocusOffset = { 600.0f, 700.0f, 0.0f };
if (limbIndex == GERUDO_RED_LIMB_HEAD) {
Matrix_MultVec3f(&sFocusOffset, &this->picto.actor.focus.pos);
}
}
void EnGe3_Draw(Actor* thisx, PlayState* play) {
static TexturePtr sEyeTextures[] = {
gGerudoRedEyeOpenTex,
gGerudoRedEyeHalfTex,
gGerudoRedEyeClosedTex,
};
s32 pad;
EnGe3* this = THIS;
OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL37_Opa(play->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sEyeTextures[this->eyeIndex]));
func_800B8050(&this->picto.actor, play, 0);
SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
EnGe3_OverrideLimbDraw, EnGe3_PostLimbDraw, &this->picto.actor);
CLOSE_DISPS(play->state.gfxCtx);
}
+42 -2
View File
@@ -2,14 +2,54 @@
#define Z_EN_GE3_H
#include "global.h"
#include "z64snap.h"
#include "objects/object_geldb/object_geldb.h"
struct EnGe3;
typedef void (*EnGe3ActionFunc)(struct EnGe3*, PlayState*);
#define GERUDO_AVEIL_GET_PATH(thisx) (((thisx)->params & 0xFC00) >> 10)
#define GERUDO_AVEIL_GET_EXIT(thisx) (((thisx)->params & 0x1F0) >> 4)
#define GERUDO_AVEIL_GET_TYPE(thisx) ((thisx)->params & 1)
#define GERUDO_AVEIL_PATH_INDEX_NONE 0x3F
typedef enum GerudoAveilType {
/* 0 */ GERUDO_AVEIL_TYPE_0, // Unused, just walks forwards
/* 1 */ GERUDO_AVEIL_TYPE_AVEILS_CHAMBER
} GerudoAveilType;
typedef enum GerudoAveilCueId {
/* -1 */ GERUDO_AVEIL_CUEID_NONE = -1,
/* 0 */ GERUDO_AVEIL_CUEID_0, // Unused
/* 1 */ GERUDO_AVEIL_CUEID_WAIT,
/* 2 */ GERUDO_AVEIL_CUEID_PAUSE,
/* 3 */ GERUDO_AVEIL_CUEID_INSTRUCT,
/* 4 */ GERUDO_AVEIL_CUEID_DEMAND,
/* 5 */ GERUDO_AVEIL_CUEID_DISMISS,
/* 6 */ GERUDO_AVEIL_CUEID_BEG,
/* 7 */ GERUDO_AVEIL_CUEID_BEEHIVE_RUN_AWAY,
/* 8 */ GERUDO_AVEIL_CUEID_BEEHIVE_VANISH
} GerudoAveilCueId;
typedef struct EnGe3 {
/* 0x000 */ Actor actor;
/* 0x144 */ char unk_144[0x1D8];
/* 0x000 */ PictoActor picto;
/* 0x148 */ ColliderCylinder collider;
/* 0x194 */ SkelAnime skelAnime;
/* 0x1D8 */ Vec3s jointTable[GERUDO_RED_LIMB_MAX];
/* 0x268 */ Vec3s morphTable[GERUDO_RED_LIMB_MAX];
/* 0x2F8 */ s16 eyeIndex;
/* 0x2FA */ s16 blinkTimer;
/* 0x2FC */ Path* path;
/* 0x300 */ s32 curPointIndex;
/* 0x304 */ Vec3s headRot;
/* 0x30A */ Vec3s torsoRot;
/* 0x310 */ s16 stateFlags; // Set and not used, named based on OoT use
/* 0x312 */ s16 animIndex;
/* 0x314 */ s16 cueId;
/* 0x316 */ s16 actionTimer;
/* 0x318 */ s16 screamTimer;
/* 0x31C */ EnGe3ActionFunc actionFunc;
} EnGe3; // size = 0x320