ovl_En_Wdhand (#1629)

* 2 non-matching

* Matching

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

* Cleanup + docs

* Suggested changes

* Format

* Update EnWdhand_GetInitVelocity

---------

Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>
This commit is contained in:
Tharo 2024-05-19 18:18:34 +01:00 committed by GitHub
parent fd3431fa48
commit 44057c087a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 776 additions and 71 deletions

View File

@ -1,14 +1,14 @@
<Root>
<File Name="object_wdhand" Segment="6">
<Animation Name="object_wdhand_Anim_0000F4" Offset="0xF4" />
<Animation Name="gDexihandCloseAnim" Offset="0xF4" />
<Animation Name="object_wdhand_Anim_000364" Offset="0x364" />
<Animation Name="object_wdhand_Anim_000534" Offset="0x534" />
<Animation Name="object_wdhand_Anim_000854" Offset="0x854" />
<Animation Name="gDexihandOpenAnim" Offset="0x534" />
<Animation Name="gDexihandIdleAnim" Offset="0x854" />
<Texture Name="object_wdhand_Tex_000870" OutName="tex_000870" Format="rgba16" Width="16" Height="32" Offset="0x870" />
<Texture Name="object_wdhand_Tex_000C70" OutName="tex_000C70" Format="rgba16" Width="16" Height="32" Offset="0xC70" />
<Texture Name="object_wdhand_Tex_001070" OutName="tex_001070" Format="rgba16" Width="16" Height="32" Offset="0x1070" />
<DList Name="object_wdhand_DL_0014C0" Offset="0x14C0" />
<DList Name="object_wdhand_DL_0015B0" Offset="0x15B0" />
<DList Name="gDexihandBaseDL" Offset="0x14C0" />
<DList Name="gDexihandArmSegmentDL" Offset="0x15B0" />
<DList Name="object_wdhand_DL_001908" Offset="0x1908" />
<DList Name="object_wdhand_DL_001998" Offset="0x1998" />
<DList Name="object_wdhand_DL_001A20" Offset="0x1A20" />
@ -16,13 +16,13 @@
<DList Name="object_wdhand_DL_001B80" Offset="0x1B80" />
<DList Name="object_wdhand_DL_001C40" Offset="0x1C40" />
<DList Name="object_wdhand_DL_001CF0" Offset="0x1CF0" />
<Limb Name="object_wdhand_Standardlimb_001DB0" Type="Standard" EnumName="OBJECT_WDHAND_LIMB_01" Offset="0x1DB0" />
<Limb Name="object_wdhand_Standardlimb_001DBC" Type="Standard" EnumName="OBJECT_WDHAND_LIMB_02" Offset="0x1DBC" />
<Limb Name="object_wdhand_Standardlimb_001DC8" Type="Standard" EnumName="OBJECT_WDHAND_LIMB_03" Offset="0x1DC8" />
<Limb Name="object_wdhand_Standardlimb_001DD4" Type="Standard" EnumName="OBJECT_WDHAND_LIMB_04" Offset="0x1DD4" />
<Limb Name="object_wdhand_Standardlimb_001DE0" Type="Standard" EnumName="OBJECT_WDHAND_LIMB_05" Offset="0x1DE0" />
<Limb Name="object_wdhand_Standardlimb_001DEC" Type="Standard" EnumName="OBJECT_WDHAND_LIMB_06" Offset="0x1DEC" />
<Limb Name="object_wdhand_Standardlimb_001DF8" Type="Standard" EnumName="OBJECT_WDHAND_LIMB_07" Offset="0x1DF8" />
<Skeleton Name="object_wdhand_Skel_001E20" Type="Flex" LimbType="Standard" LimbNone="OBJECT_WDHAND_LIMB_NONE" LimbMax="OBJECT_WDHAND_LIMB_MAX" EnumName="ObjectWdhandLimb" Offset="0x1E20" />
<Limb Name="object_wdhand_Standardlimb_001DB0" Type="Standard" EnumName="DEXIHAND_LIMB_01" Offset="0x1DB0" />
<Limb Name="object_wdhand_Standardlimb_001DBC" Type="Standard" EnumName="DEXIHAND_LIMB_02" Offset="0x1DBC" />
<Limb Name="object_wdhand_Standardlimb_001DC8" Type="Standard" EnumName="DEXIHAND_LIMB_03" Offset="0x1DC8" />
<Limb Name="object_wdhand_Standardlimb_001DD4" Type="Standard" EnumName="DEXIHAND_LIMB_04" Offset="0x1DD4" />
<Limb Name="object_wdhand_Standardlimb_001DE0" Type="Standard" EnumName="DEXIHAND_LIMB_05" Offset="0x1DE0" />
<Limb Name="object_wdhand_Standardlimb_001DEC" Type="Standard" EnumName="DEXIHAND_LIMB_06" Offset="0x1DEC" />
<Limb Name="object_wdhand_Standardlimb_001DF8" Type="Standard" EnumName="DEXIHAND_LIMB_07" Offset="0x1DF8" />
<Skeleton Name="gDexihandSkel" Type="Flex" LimbType="Standard" LimbNone="DEXIHAND_LIMB_NONE" LimbMax="DEXIHAND_LIMB_MAX" EnumName="DexihandLimb" Offset="0x1E20" />
</File>
</Root>

3
spec
View File

@ -3432,8 +3432,7 @@ beginseg
name "ovl_En_Wdhand"
compress
include "$(BUILD_DIR)/src/overlays/actors/ovl_En_Wdhand/z_en_wdhand.o"
include "$(BUILD_DIR)/data/ovl_En_Wdhand/ovl_En_Wdhand.data.o"
include "$(BUILD_DIR)/data/ovl_En_Wdhand/ovl_En_Wdhand.reloc.o"
include "$(BUILD_DIR)/src/overlays/actors/ovl_En_Wdhand/ovl_En_Wdhand_reloc.o"
endseg
beginseg

View File

@ -15,7 +15,23 @@ void EnWdhand_Destroy(Actor* thisx, PlayState* play);
void EnWdhand_Update(Actor* thisx, PlayState* play);
void EnWdhand_Draw(Actor* thisx, PlayState* play);
#if 0
void EnWdhand_ReturnToIdle(EnWdhand* this, PlayState* play);
void EnWdhand_Idle(EnWdhand* this, PlayState* play);
void EnWdhand_LungeForPlayer(EnWdhand* this, PlayState* play);
void EnWdhand_FailedToGrabPlayer(EnWdhand* this, PlayState* play);
void EnWdhand_GrabbedPlayer(EnWdhand* this, PlayState* play);
void EnWdhand_Die(EnWdhand* this, PlayState* play);
void EnWdhand_SetupReturnToIdle(EnWdhand* this);
void EnWdhand_SetupIdle(EnWdhand* this);
void EnWdhand_SetupLungeForPlayer(EnWdhand* this);
void EnWdhand_SetupFailedToGrabPlayer(EnWdhand* this);
void EnWdhand_SetupGrabbedPlayer(EnWdhand* this, PlayState* play);
void EnWdhand_SetupDie(EnWdhand* this);
void EnWdhand_GetInitVelocity(EnWdhand* this, Vec3f* dst);
void EnWdhand_Vec3fToVec3s(Vec3s* dst, Vec3f* src);
ActorInit En_Wdhand_InitVars = {
/**/ ACTOR_EN_WDHAND,
/**/ ACTORCAT_ENEMY,
@ -28,49 +44,102 @@ ActorInit En_Wdhand_InitVars = {
/**/ EnWdhand_Draw,
};
// static ColliderJntSphElementInit sJntSphElementsInit[7] = {
static ColliderJntSphElementInit D_80AF63E0[7] = {
static ColliderJntSphElementInit sJntSphElementsInit[EN_WDHAND_NUM_COLLIDER_ELEMENTS] = {
{
{ ELEMTYPE_UNK1, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_ON, OCELEM_ON, },
{
ELEMTYPE_UNK1,
{ 0xF7CFFFFF, 0x00, 0x00 },
{ 0xF7CFFFFF, 0x00, 0x00 },
TOUCH_ON | TOUCH_SFX_NONE,
BUMP_ON,
OCELEM_ON,
},
{ 50, { { 0, 575, 0 }, 10 }, 100 },
},
{
{ ELEMTYPE_UNK1, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_ON, OCELEM_ON, },
{
ELEMTYPE_UNK1,
{ 0xF7CFFFFF, 0x00, 0x00 },
{ 0xF7CFFFFF, 0x00, 0x00 },
TOUCH_ON | TOUCH_SFX_NONE,
BUMP_ON,
OCELEM_ON,
},
{ 50, { { 0, 1725, 0 }, 10 }, 100 },
},
{
{ ELEMTYPE_UNK1, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_ON, OCELEM_ON, },
{
ELEMTYPE_UNK1,
{ 0xF7CFFFFF, 0x00, 0x00 },
{ 0xF7CFFFFF, 0x00, 0x00 },
TOUCH_ON | TOUCH_SFX_NONE,
BUMP_ON,
OCELEM_ON,
},
{ 50, { { 0, 575, 0 }, 10 }, 100 },
},
{
{ ELEMTYPE_UNK1, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_ON, OCELEM_ON, },
{
ELEMTYPE_UNK1,
{ 0xF7CFFFFF, 0x00, 0x00 },
{ 0xF7CFFFFF, 0x00, 0x00 },
TOUCH_ON | TOUCH_SFX_NONE,
BUMP_ON,
OCELEM_ON,
},
{ 50, { { 0, 1725, 0 }, 10 }, 100 },
},
{
{ ELEMTYPE_UNK1, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_ON, OCELEM_ON, },
{
ELEMTYPE_UNK1,
{ 0xF7CFFFFF, 0x00, 0x00 },
{ 0xF7CFFFFF, 0x00, 0x00 },
TOUCH_ON | TOUCH_SFX_NONE,
BUMP_ON,
OCELEM_ON,
},
{ 50, { { 0, 575, 0 }, 10 }, 100 },
},
{
{ ELEMTYPE_UNK1, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_ON, OCELEM_ON, },
{
ELEMTYPE_UNK1,
{ 0xF7CFFFFF, 0x00, 0x00 },
{ 0xF7CFFFFF, 0x00, 0x00 },
TOUCH_ON | TOUCH_SFX_NONE,
BUMP_ON,
OCELEM_ON,
},
{ 50, { { 0, 1725, 0 }, 10 }, 100 },
},
{
{ ELEMTYPE_UNK1, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_ON, OCELEM_ON, },
{
ELEMTYPE_UNK1,
{ 0xF7CFFFFF, 0x00, 0x00 },
{ 0xF7CFFFFF, 0x00, 0x00 },
TOUCH_ON | TOUCH_SFX_NONE,
BUMP_ON,
OCELEM_ON,
},
{ 50, { { 0, 1000, 0 }, 15 }, 100 },
},
};
// static ColliderJntSphInit sJntSphInit = {
static ColliderJntSphInit D_80AF64DC = {
{ COLTYPE_HIT0, AT_NONE | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, },
ARRAY_COUNT(sJntSphElementsInit), D_80AF63E0, // sJntSphElementsInit,
static ColliderJntSphInit sJntSphInit = {
{
COLTYPE_HIT0,
AT_NONE | AT_TYPE_ENEMY,
AC_ON | AC_TYPE_PLAYER,
OC1_ON | OC1_TYPE_ALL,
OC2_TYPE_1,
COLSHAPE_JNTSPH,
},
ARRAY_COUNT(sJntSphElementsInit),
sJntSphElementsInit,
};
// sColChkInfoInit
static CollisionCheckInfoInit D_80AF64EC = { 1, 25, 25, MASS_HEAVY };
static CollisionCheckInfoInit sColChkInfoInit = { 1, 25, 25, MASS_HEAVY };
// static DamageTable sDamageTable = {
static DamageTable D_80AF64F4 = {
static DamageTable sDamageTable = {
/* Deku Nut */ DMG_ENTRY(0, 0x0),
/* Deku Stick */ DMG_ENTRY(0, 0x0),
/* Horse trample */ DMG_ENTRY(0, 0x0),
@ -105,63 +174,679 @@ static DamageTable D_80AF64F4 = {
/* Powder Keg */ DMG_ENTRY(1, 0x0),
};
#endif
void EnWdhand_Init(Actor* thisx, PlayState* play) {
EnWdhand* this = THIS;
s32 i;
Vec3f initVel;
extern ColliderJntSphElementInit D_80AF63E0[7];
extern ColliderJntSphInit D_80AF64DC;
extern CollisionCheckInfoInit D_80AF64EC;
extern DamageTable D_80AF64F4;
SkelAnime_InitFlex(play, &this->skelAnime, &gDexihandSkel, &gDexihandIdleAnim, this->jointTable, this->morphTable,
DEXIHAND_LIMB_MAX);
CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
extern UNK_TYPE D_060000F4;
extern UNK_TYPE D_06000364;
extern UNK_TYPE D_06000534;
extern UNK_TYPE D_06000854;
extern UNK_TYPE D_060014C0;
// Constructs an affine transformation that maps world origin to actor origin and rotation
// (model -> world but without scaling)
Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW);
Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY);
Matrix_RotateXS(this->actor.shape.rot.x, MTXMODE_APPLY);
Matrix_RotateZS(this->actor.shape.rot.z, MTXMODE_APPLY);
// Get a world position offset by 3 units
Matrix_MultVecY(3.0f, &this->endPoints[EN_WDHAND_HAND_POINT]);
// Save this matrix for later
Matrix_MtxFCopy(&this->relativeToWorldTransform, Matrix_GetCurrent());
// Write the rotation back to the actor
Matrix_MtxFToYXZRot(&this->relativeToWorldTransform, &this->actor.shape.rot, false);
// Transpose the matrix, since it's a rotation matrix this creates the inverse rotation matrix
Matrix_Transpose(&this->relativeToWorldTransform);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/EnWdhand_Init.s")
this->actor.world.rot.y = this->actor.shape.rot.y;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/EnWdhand_Destroy.s")
EnWdhand_GetInitVelocity(this, &initVel);
this->actor.speed = initVel.z;
this->actor.velocity.y = initVel.y;
this->actor.velocity.x = Math_SinS(this->actor.world.rot.y) * this->actor.speed;
this->actor.velocity.z = Math_CosS(this->actor.world.rot.y) * this->actor.speed;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF4608.s")
Collider_InitAndSetJntSph(play, &this->collider, &this->actor, &sJntSphInit, this->colliderElements);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF4670.s")
for (i = 0; i < ARRAY_COUNT(this->colliderElements); i++) {
ColliderJntSphElement* elem = &this->collider.elements[i];
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF46F0.s")
elem->dim.worldSphere.radius = elem->dim.modelSphere.radius;
EnWdhand_Vec3fToVec3s(&elem->dim.worldSphere.center, &this->actor.world.pos);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF488C.s")
for (i = 0; i < EN_WDHAND_NUM_SEGMENTS; i++) {
this->limbScaleFactors[i] = 1.0f;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF48D0.s")
this->limbIndexBeforeCut = -1;
this->limbIndexAfterCut = 0;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF4964.s")
this->actor.world.rot.x = 0;
this->actor.world.rot.z =
Math_Atan2S_XY(this->relativeToWorldTransform.mf[2][1], this->relativeToWorldTransform.mf[0][1]);
this->actor.hintId = TATL_HINT_ID_DEXIHAND;
EnWdhand_SetupIdle(this);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF4A88.s")
void EnWdhand_Destroy(Actor* thisx, PlayState* play) {
EnWdhand* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF4C18.s")
Collider_DestroyJntSph(play, &this->collider);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF4C64.s")
void EnWdhand_GetInitVelocity(EnWdhand* this, Vec3f* dst) {
s32 param;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF4ED0.s")
param = EN_WDHAND_GET_Y_INIT_VELOCITY(&this->actor);
if (param == EN_WDHAND_INIT_VELOCITY_MAX) {
param = 40;
}
dst->y = param * 0.2f;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF4F30.s")
param = EN_WDHAND_GET_Z_INIT_VELOCITY(&this->actor);
if (param == EN_WDHAND_INIT_VELOCITY_MAX) {
param = 40;
}
dst->z = param * 0.2f;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF4F6C.s")
dst->x = 0.0f;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF4FF8.s")
void EnWdhand_GetRelativeRotationsToPlayerRightFoot(EnWdhand* this, Player* player, s16* pitchOut, s16* yawOut) {
Vec3f diffToPlayerRightFoot;
Vec3f diffToPlayerRightFootRelative;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF5130.s")
// Get the difference in world positions
Math_Vec3f_Diff(&player->bodyPartsPos[PLAYER_BODYPART_RIGHT_FOOT], &this->actor.world.pos, &diffToPlayerRightFoot);
// Re-express the difference in actor-relative coordinates
Matrix_Put(&this->relativeToWorldTransform);
Matrix_MultVec3f(&diffToPlayerRightFoot, &diffToPlayerRightFootRelative);
// Return actor-relative yaw and pitch
*yawOut = Actor_WorldYawTowardPoint(&this->actor, &diffToPlayerRightFootRelative);
*pitchOut = Actor_WorldPitchTowardPoint(&this->actor, &diffToPlayerRightFootRelative) + 0x4000;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF520C.s")
void EnWdhand_SetTransform(EnWdhand* this, s32 limbIndex, s32 arg2, Vec3f* translation) {
MtxF* currentMatrix = Matrix_GetCurrent();
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF5650.s")
Matrix_RotateZYX(this->limbRotations[limbIndex].x, this->limbRotations[limbIndex].y, 0, MTXMODE_APPLY);
if (arg2) {
Matrix_RotateYS(-this->limbRotations[limbIndex].y, MTXMODE_APPLY);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF56A0.s")
if (limbIndex == DEXIHAND_LIMB_03) {
if (this->globalLimbScaleFactor > 1.0f) {
f32 scale = CLAMP_MAX(this->globalLimbScaleFactor, 1.5f);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF5820.s")
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
}
} else if ((this->limbScaleFactors[limbIndex] < 1.0f) || (this->globalLimbScaleFactor > 1.0f)) {
if (this->limbScaleFactors[limbIndex] < 0.1f) {
Matrix_Scale(0.0f, this->globalLimbScaleFactor * this->limbScaleFactors[limbIndex], 0.0f, MTXMODE_APPLY);
} else {
Matrix_Scale(1.0f, this->globalLimbScaleFactor * this->limbScaleFactors[limbIndex], 1.0f, MTXMODE_APPLY);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF5E3C.s")
currentMatrix->mf[3][0] = translation->x;
currentMatrix->mf[3][1] = translation->y;
currentMatrix->mf[3][2] = translation->z;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/EnWdhand_Update.s")
void EnWdhand_Vec3fToVec3s(Vec3s* dst, Vec3f* src) {
dst->x = src->x;
dst->y = src->y;
dst->z = src->z;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/func_80AF5FE4.s")
s16 EnWdhand_GetLimbXRotation(EnWdhand* this, s32 limbIndex) {
return this->limbRotations[limbIndex].z * Math_SinF((this->timer - limbIndex * 20) * (M_PI / 40));
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wdhand/EnWdhand_Draw.s")
void EnWdhand_SetupIdle(EnWdhand* this) {
s32 i;
Animation_MorphToLoop(&this->skelAnime, &gDexihandIdleAnim, -5.0f);
if (this->actionFunc != EnWdhand_ReturnToIdle) {
this->timer = 80;
this->limbRotations[0].y = Rand_Next() >> 16;
for (i = 1; i < ARRAY_COUNT(this->limbRotations); i++) {
this->limbRotations[i].y = this->limbRotations[i - 1].y + (s32)Rand_ZeroFloat(0x2000) + 0x8000;
}
for (i = 0; i < ARRAY_COUNT(this->limbRotations); i++) {
this->limbRotations[i].z = Rand_S16Offset(0x1800, 0x1000);
}
}
for (i = 0; i < ARRAY_COUNT(this->limbRotations); i++) {
this->limbRotations[i].x = EnWdhand_GetLimbXRotation(this, i);
}
this->actionFunc = EnWdhand_Idle;
this->globalLimbScaleFactor = 1.0f;
}
void EnWdhand_Idle(EnWdhand* this, PlayState* play) {
Player* player = GET_PLAYER(play);
s32 i;
s16 pitchToPlayerRightFoot;
s16 yawToPlayerRightFoot;
SkelAnime_Update(&this->skelAnime);
this->timer--;
for (i = 0; i < ARRAY_COUNT(this->limbRotations); i++) {
this->limbRotations[i].x = EnWdhand_GetLimbXRotation(this, i);
if (this->timer == 20 * i) {
if (i != 0) {
this->limbRotations[i].y = this->limbRotations[i - 1].y + (s32)Rand_CenteredFloat(16384.0f);
this->limbRotations[i].y -= 0x8000;
} else {
this->limbRotations[0].y += (s16)(s32)Rand_CenteredFloat(16384.0f);
}
this->limbRotations[i].z = Rand_S16Offset(0x1800, 0x1000);
}
}
if (this->timer == 0) {
this->timer = 80;
}
if (!(player->stateFlags2 & PLAYER_STATE2_80) && (this->actor.xyzDistToPlayerSq < SQ(120.75f))) {
EnWdhand_GetRelativeRotationsToPlayerRightFoot(this, player, &pitchToPlayerRightFoot, &yawToPlayerRightFoot);
if (ABS_ALT(pitchToPlayerRightFoot) <= 0x4000) {
EnWdhand_SetupLungeForPlayer(this);
}
}
}
void EnWdhand_SetupLungeForPlayer(EnWdhand* this) {
Animation_MorphToPlayOnce(&this->skelAnime, &gDexihandOpenAnim, -5.0f);
this->timer = 5;
this->actionFunc = EnWdhand_LungeForPlayer;
}
void EnWdhand_LungeForPlayer(EnWdhand* this, PlayState* play) {
Player* player = GET_PLAYER(play);
s32 allStepsDone = true;
s32 i;
s16 pitchToPlayerRightFoot;
s16 yawToPlayerRightFoot;
SkelAnime_Update(&this->skelAnime);
// Only activate the collider and grab check after a short delay
if (this->timer > 0) {
this->timer--;
if (this->timer == 0) {
this->collider.base.atFlags |= AT_ON;
}
return;
}
Math_StepToF(&this->globalLimbScaleFactor, 1.5f, 0.05f);
EnWdhand_GetRelativeRotationsToPlayerRightFoot(this, player, &pitchToPlayerRightFoot, &yawToPlayerRightFoot);
for (i = 0; i < ARRAY_COUNT(this->limbRotations); i++) {
s16 yawDiff = yawToPlayerRightFoot - this->limbRotations[i].y;
if (ABS_ALT(yawDiff) < 0x4000) {
allStepsDone &=
Math_ScaledStepToS(&this->limbRotations[i].x, pitchToPlayerRightFoot, (i * 0.1f + 1.0f) * 1920.0f);
allStepsDone &= Math_ScaledStepToS(&this->limbRotations[i].y, yawToPlayerRightFoot, 0x800);
} else {
allStepsDone &=
Math_ScaledStepToS(&this->limbRotations[i].x, -pitchToPlayerRightFoot, (i * 0.1f + 1.0f) * 1920.0f);
allStepsDone &= Math_ScaledStepToS(&this->limbRotations[i].y, yawToPlayerRightFoot + 0x8000, 0x800);
}
}
if ((this->collider.base.atFlags & AT_HIT) && play->grabPlayer(play, player)) {
// Touched the player, grab
EnWdhand_SetupGrabbedPlayer(this, play);
} else if (allStepsDone) {
// Failed to grab player in time
EnWdhand_SetupFailedToGrabPlayer(this);
}
if (this->collider.base.atFlags & AT_HIT) {
this->collider.base.atFlags &= ~AT_HIT;
}
}
void EnWdhand_SetupFailedToGrabPlayer(EnWdhand* this) {
Animation_PlayOnce(&this->skelAnime, &gDexihandCloseAnim);
this->collider.base.atFlags &= ~AT_ON;
this->collider.base.atFlags &= ~AT_HIT;
this->actionFunc = EnWdhand_FailedToGrabPlayer;
this->globalLimbScaleFactor = 1.5f;
}
void EnWdhand_FailedToGrabPlayer(EnWdhand* this, PlayState* play) {
if (SkelAnime_Update(&this->skelAnime)) {
EnWdhand_SetupReturnToIdle(this);
}
}
void EnWdhand_SetupReturnToIdle(EnWdhand* this) {
s32 i;
Animation_MorphToLoop(&this->skelAnime, &gDexihandIdleAnim, -10.0f);
for (i = 0; i < ARRAY_COUNT(this->limbRotations); i++) {
this->limbRotations[i].z = Rand_S16Offset(0x1800, 0x1000);
}
this->timer = 80;
this->actionFunc = EnWdhand_ReturnToIdle;
}
void EnWdhand_ReturnToIdle(EnWdhand* this, PlayState* play) {
s32 i;
s32 allStepsDone;
SkelAnime_Update(&this->skelAnime);
this->timer--;
allStepsDone = Math_ScaledStepToS(&this->limbRotations[0].x, EnWdhand_GetLimbXRotation(this, 0), 0x200);
for (i = 1; i < ARRAY_COUNT(this->limbRotations); i++) {
allStepsDone &= Math_ScaledStepToS(&this->limbRotations[i].x, EnWdhand_GetLimbXRotation(this, i), 0x300);
if (this->timer == 20 * i) {
this->limbRotations[i].z = Rand_S16Offset(0x1800, 0x1000);
}
}
if (this->timer == 0) {
this->timer = 80;
this->limbRotations[0].z = Rand_S16Offset(0x1800, 0x1000);
}
Math_StepToF(&this->globalLimbScaleFactor, 1.0f, 0.05f);
if (allStepsDone) {
EnWdhand_SetupIdle(this);
}
}
void EnWdhand_SetupGrabbedPlayer(EnWdhand* this, PlayState* play) {
Player* player = GET_PLAYER(play);
s32 i;
this->collider.base.atFlags &= ~AT_ON;
this->collider.base.atFlags &= ~AT_HIT;
this->collider.base.ocFlags1 &= ~OC1_ON;
Animation_PlayOnce(&this->skelAnime, &gDexihandCloseAnim);
for (i = 0; i < ARRAY_COUNT(this->limbRotations); i++) {
this->limbRotations[i].z = Rand_S16Offset(0x2000, 0x1000);
}
this->timer = 80;
player->actor.parent = &this->actor;
// Return to original state as set in init, that is relative -> world
Matrix_Transpose(&this->relativeToWorldTransform);
this->globalLimbScaleFactor = 1.5f;
Actor_PlaySfx(&this->actor, NA_SE_EN_HANDW_GET);
this->actionFunc = EnWdhand_GrabbedPlayer;
}
void EnWdhand_GrabbedPlayer(EnWdhand* this, PlayState* play) {
Player* player = GET_PLAYER(play);
s32 i;
s32 t;
SkelAnime_Update(&this->skelAnime);
this->timer--;
player->av2.actionVar2 = 0;
t = this->timer;
for (i = 0; i < ARRAY_COUNT(this->limbRotations); i++) {
if (this->timer < 76) {
this->limbRotations[i].x = this->limbRotations[i].z * Math_SinF(t * (M_PI / 8));
} else {
Math_ScaledStepToS(&this->limbRotations[i].x, this->limbRotations[i].z * Math_SinF(t * (M_PI / 8)), 0x400);
}
if (t % 16 == 0) {
if (t == 16) {
this->limbRotations[i].y = 0;
} else if (i != 0) {
this->limbRotations[i].y = this->limbRotations[i - 1].y + (s32)Rand_CenteredFloat(12288.0f);
} else {
this->limbRotations[0].y += (s16)(s32)Rand_CenteredFloat(12288.0f);
}
this->limbRotations[i].z = Rand_S16Offset(0x2000, 0x1000);
}
t += 2;
}
if (this->timer < 4) {
Math_StepToF(&this->globalLimbScaleFactor, 1.5f, 1.0f / 8);
} else if (this->timer < 16) {
Math_StepToF(&this->globalLimbScaleFactor, 2.0f, 1.0f / 24);
}
if (this->timer == 0) {
this->collider.base.ocFlags1 |= OC1_ON;
EnWdhand_SetupReturnToIdle(this);
} else if (this->timer >= 4) {
Vec3f limbPos;
// Create a model -> world matrix
Matrix_Put(&this->relativeToWorldTransform);
Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY);
Matrix_MultVecY(300.0f, &limbPos);
for (i = 0; i < EN_WDHAND_NUM_SEGMENTS; i++) {
Matrix_Push();
// Further rotate and translate
EnWdhand_SetTransform(this, i, false, &limbPos);
Matrix_MultVecY(2300.0f, &limbPos);
Matrix_Pop();
}
// Set transform for the hand
EnWdhand_SetTransform(this, EN_WDHAND_NUM_SEGMENTS, true, &limbPos);
// Copy the hand rotation to player shape rotation
Matrix_MtxFToYXZRot(Matrix_GetCurrent(), &player->actor.shape.rot, false);
if (this->globalLimbScaleFactor > 1.0f) {
f32 zRotFactor = CLAMP_MAX(this->globalLimbScaleFactor, 1.5f);
Matrix_RotateZS((zRotFactor - 1.0f) * -32768.0f, MTXMODE_APPLY);
}
Matrix_MultVecY(1000.0f, &player->actor.world.pos);
if ((this->timer == 4) && (player->actor.parent == &this->actor)) {
// Throws the player, releasing them
player->av2.actionVar2 = 100;
player->actor.parent = NULL;
// Transpose again
Matrix_Transpose(&this->relativeToWorldTransform);
player->actor.shape.rot.x = 0;
player->actor.shape.rot.z = 0;
player->actor.world.pos.x += 2.0f * this->actor.velocity.x;
player->actor.world.pos.y += 2.0f * this->actor.velocity.y;
player->actor.world.pos.z += 2.0f * this->actor.velocity.z;
func_800B8D50(play, &this->actor, this->actor.speed, this->actor.world.rot.y, this->actor.velocity.y, 0);
Actor_PlaySfx(&this->actor, NA_SE_EN_HANDW_RELEASE);
} else if (this->timer == 2) {
Animation_PlayOnce(&this->skelAnime, &object_wdhand_Anim_000364);
}
}
}
s32 EnWdhand_ShrinkLimb(EnWdhand* this, s32 limbIndex) {
this->limbScaleFactors[limbIndex] -= 0.1f;
if (this->limbScaleFactors[limbIndex] <= 0.05f) {
this->limbScaleFactors[limbIndex] = 0.05f;
return true;
}
return false;
}
void EnWdhand_SetupDie(EnWdhand* this) {
s32 i;
this->actor.flags &= ~ACTOR_FLAG_TARGETABLE;
this->actor.flags |= ACTOR_FLAG_10;
// Finds the particular collider that was hit
for (i = 0; i < ARRAY_COUNT(this->colliderElements); i++) {
if (this->collider.elements[i].info.bumperFlags & BUMP_HIT) {
break;
}
}
// Record the limb indices immediately to either side of the cut point
this->limbIndexAfterCut = ((i + 1) / 2) % 4;
this->limbIndexBeforeCut = this->limbIndexAfterCut - 1;
// Create model -> world transform
Matrix_Put(&this->relativeToWorldTransform);
Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY);
Matrix_MultVecY(300.0f, &this->endPoints[EN_WDHAND_HAND_POINT]);
for (i = 0; i < this->limbIndexAfterCut; i++) {
Matrix_Push();
EnWdhand_SetTransform(this, i, false, &this->endPoints[EN_WDHAND_HAND_POINT]);
Matrix_MultVecY(2300.0f, &this->endPoints[EN_WDHAND_HAND_POINT]);
Matrix_Pop();
}
this->actor.velocity.y = 2.45f;
this->actor.velocity.x = 2.0f * Math_SinS(this->actor.world.rot.z);
this->actor.velocity.z = 2.0f * Math_CosS(this->actor.world.rot.z);
this->timer = 5;
this->actionFunc = EnWdhand_Die;
}
void EnWdhand_Die(EnWdhand* this, PlayState* play) {
static Vec3f sEffectVelocity = { 0.0f, 0.0f, 0.0f };
static Vec3f sEffectAccel = { 0.0f, 0.05f, 0.0f };
Vec3s* handCollider = &this->collider.elements[6].dim.worldSphere.center;
Vec3f spA0;
Vec3f sp94;
s16 effectScale;
s32 pointIndex;
s32 i;
s32 t;
Vec3f* endPoint = &this->endPoints[EN_WDHAND_HAND_POINT];
s32 limbIndex;
Vec3f effPos;
spA0.x = (endPoint->x - handCollider->x) * 0.5f;
spA0.y = (endPoint->y - handCollider->y) * 0.5f;
spA0.z = (endPoint->z - handCollider->z) * 0.5f;
Matrix_RotateXS(0x100, MTXMODE_NEW);
Matrix_MultVec3f(&spA0, &sp94);
endPoint->x = spA0.x + sp94.x + handCollider->x;
endPoint->y = spA0.y + sp94.y + handCollider->y;
endPoint->z = spA0.z + sp94.z + handCollider->z;
if (this->actor.velocity.y > -2.0f) {
this->actor.velocity.y += -0.15f;
}
Math_Vec3f_Sum(endPoint, &this->actor.velocity, endPoint);
this->actor.world.rot.x += 0x100;
if (this->limbIndexBeforeCut >= 0 && EnWdhand_ShrinkLimb(this, this->limbIndexBeforeCut)) {
this->limbIndexBeforeCut--;
}
limbIndex = this->limbIndexAfterCut;
if (this->limbIndexAfterCut < EN_WDHAND_NUM_SEGMENTS) {
if (EnWdhand_ShrinkLimb(this, this->limbIndexAfterCut)) {
this->limbIndexAfterCut++;
}
Matrix_RotateZYX(this->actor.world.rot.x, this->actor.world.rot.z, 0, MTXMODE_NEW);
Matrix_RotateYS(-this->actor.world.rot.z, MTXMODE_APPLY);
Matrix_Mult(&this->relativeToWorldTransform, MTXMODE_APPLY);
EnWdhand_SetTransform(this, limbIndex, false, endPoint);
Matrix_MultVecY(2.3f / this->limbScaleFactors[limbIndex], endPoint);
}
this->timer--;
limbIndex = this->limbIndexBeforeCut + 1;
t = this->timer;
for (i = 0; i < limbIndex; i++) {
if (this->timer > 0) {
Math_ScaledStepToS(&this->limbRotations[i].x, this->limbRotations[i].z * Math_SinF(t * (2 * M_PI / 7)),
0x200);
} else if (Rand_ZeroOne() < 0.65f) {
this->limbRotations[i].x = this->limbRotations[i].z * Math_SinF(t * (2 * M_PI / 7));
}
if (t % 7 == 0) {
if (i != 0) {
this->limbRotations[i].y = this->limbRotations[i - 1].y + (s32)Rand_CenteredFloat(12288.0f);
} else {
this->limbRotations[0].y += (s16)(s32)Rand_CenteredFloat(12288.0f);
}
this->limbRotations[i].z = Rand_S16Offset(i * 0x100 + 0xC00, 0x800);
}
t += 2;
}
if ((this->limbIndexBeforeCut < 0) && (this->limbIndexAfterCut >= EN_WDHAND_NUM_SEGMENTS)) {
if (Math_StepToF(&this->actor.scale.x, 0.0f, 0.001f)) {
for (pointIndex = 0; pointIndex < ARRAY_COUNT(this->endPoints); pointIndex++) {
for (i = 0; i < 5; i++) {
endPoint = &this->endPoints[pointIndex];
sEffectVelocity.y = Rand_ZeroOne() + 1.0f;
effectScale = Rand_S16Offset(0x28, 0x28);
effPos.x = endPoint->x + Rand_CenteredFloat(12.0f);
effPos.y = endPoint->y + Rand_CenteredFloat(12.0f);
effPos.z = endPoint->z + Rand_CenteredFloat(12.0f);
EffectSsDtBubble_SpawnColorProfile(play, &effPos, &sEffectVelocity, &sEffectAccel, effectScale, 25,
2, true);
}
}
Actor_Kill(&this->actor);
} else {
this->actor.scale.z = this->actor.scale.y = this->actor.scale.x;
}
}
for (i = 0; i < ARRAY_COUNT(this->endPoints); i++) {
sEffectVelocity.y = Rand_ZeroOne() + 1.0f;
EffectSsDtBubble_SpawnColorProfile(play, &this->endPoints[i], &sEffectVelocity, &sEffectAccel,
Rand_S16Offset(40, 40), 25, 2, true);
}
}
void EnWdhand_UpdateDamage(EnWdhand* this, PlayState* play) {
if (this->collider.base.acFlags & AC_HIT) {
Player* player = GET_PLAYER(play);
this->collider.base.acFlags &= ~AT_ON;
this->collider.base.acFlags &= ~AC_HIT;
this->collider.base.atFlags &= ~AT_ON;
this->collider.base.ocFlags1 &= ~AT_ON;
Actor_SetDropFlagJntSph(&this->actor, &this->collider);
Enemy_StartFinishingBlow(play, &this->actor);
if ((player->stateFlags2 & PLAYER_STATE2_80) && (&this->actor == player->actor.parent)) {
// Drop the player
player->av2.actionVar2 = 100;
player->actor.parent = NULL;
player->actor.shape.rot.x = 0;
player->actor.shape.rot.z = 0;
func_800B8D50(play, &this->actor, this->actor.speed, this->actor.world.rot.y, this->actor.velocity.y, 0);
} else {
// Only transpose if player is not grabbed, since it is already in the correct state if so.
Matrix_Transpose(&this->relativeToWorldTransform);
}
EnWdhand_SetupDie(this);
}
}
void EnWdhand_Update(Actor* thisx, PlayState* play) {
EnWdhand* this = THIS;
EnWdhand_UpdateDamage(this, play);
this->actionFunc(this, play);
if (this->collider.base.atFlags & AT_ON) {
CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider.base);
}
if (this->collider.base.acFlags & AC_ON) {
CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base);
}
if (this->collider.base.ocFlags1 & OC1_ON) {
CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base);
}
}
void EnWdhand_UpdateColliderLocationsForLimb(EnWdhand* this, s32 limbIndex, Vec3f* limbPos) {
EnWdhand_SetTransform(this, limbIndex, true, limbPos);
Matrix_MultVecY(575.0f, limbPos);
EnWdhand_Vec3fToVec3s(&this->collider.elements[2 * limbIndex + 0].dim.worldSphere.center, limbPos);
Matrix_MultVecY(1725.0f, limbPos);
EnWdhand_Vec3fToVec3s(&this->collider.elements[2 * limbIndex + 1].dim.worldSphere.center, limbPos);
Matrix_MultVecY(2300.0f, limbPos);
}
void EnWdhand_Draw(Actor* thisx, PlayState* play) {
EnWdhand* this = THIS;
Vec3f limbPos;
Gfx* gfx;
s32 limbIndex;
s32 i;
OPEN_DISPS(play->state.gfxCtx);
gfx = POLY_OPA_DISP;
gSPDisplayList(&gfx[0], gSetupDLs[25]);
gSPMatrix(&gfx[1], Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(&gfx[2], gDexihandBaseDL);
Matrix_MultVecY(300.0f, &limbPos);
gfx = &gfx[3];
limbIndex = this->limbIndexBeforeCut + 1;
for (i = 0; i < limbIndex; i++) {
Matrix_Push();
EnWdhand_UpdateColliderLocationsForLimb(this, i, &limbPos);
gSPMatrix(gfx++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(gfx++, gDexihandArmSegmentDL);
Matrix_Pop();
}
Math_Vec3f_Copy(&this->endPoints[EN_WDHAND_CUT_POINT], &limbPos);
Math_Vec3f_Copy(&limbPos, &this->endPoints[EN_WDHAND_HAND_POINT]);
if (this->actor.world.rot.x != 0) {
Matrix_RotateZYX(this->actor.world.rot.x, this->actor.world.rot.z, 0, MTXMODE_NEW);
Matrix_RotateYS(-this->actor.world.rot.z, MTXMODE_APPLY);
Matrix_Mult(&this->relativeToWorldTransform, MTXMODE_APPLY);
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
}
for (i = this->limbIndexAfterCut; i < EN_WDHAND_NUM_SEGMENTS; i++) {
Matrix_Push();
EnWdhand_UpdateColliderLocationsForLimb(this, i, &limbPos);
gSPMatrix(gfx++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(gfx++, gDexihandArmSegmentDL);
Matrix_Pop();
}
EnWdhand_SetTransform(this, EN_WDHAND_NUM_SEGMENTS, true, &limbPos);
if (this->globalLimbScaleFactor > 1.0f) {
s32 pad;
f32 scale = CLAMP_MAX(this->globalLimbScaleFactor, 1.5f);
Matrix_RotateZS((scale - 1.0f) * -32768.0f, MTXMODE_APPLY);
}
if (this->actor.scale.x < 0.01f) {
Matrix_Translate(0.0f, (10.0f / this->actor.scale.x) - 1000.0f, 0.0f, MTXMODE_APPLY);
}
Math_Vec3f_Copy(&this->actor.focus.pos, &limbPos);
Matrix_MultVecY(1000.0f, &limbPos);
EnWdhand_Vec3fToVec3s(&this->collider.elements[6].dim.worldSphere.center, &limbPos);
POLY_OPA_DISP = gfx;
SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, NULL,
NULL, &this->actor);
CLOSE_DISPS(play->state.gfxCtx);
}

View File

@ -2,16 +2,38 @@
#define Z_EN_WDHAND_H
#include "global.h"
#include "objects/object_wdhand/object_wdhand.h"
struct EnWdhand;
typedef void (*EnWdhandActionFunc)(struct EnWdhand*, PlayState*);
#define EN_WDHAND_NUM_SEGMENTS 3
#define EN_WDHAND_NUM_COLLIDER_ELEMENTS (2 * EN_WDHAND_NUM_SEGMENTS + 1)
#define EN_WDHAND_CUT_POINT 0
#define EN_WDHAND_HAND_POINT 1
#define EN_WDHAND_INIT_VELOCITY_MAX 0x7F
#define EN_WDHAND_GET_Y_INIT_VELOCITY(thisx) (((thisx)->params >> 0) & 0x7F)
#define EN_WDHAND_GET_Z_INIT_VELOCITY(thisx) (((thisx)->params >> 7) & 0x7F)
typedef struct EnWdhand {
/* 0x000 */ Actor actor;
/* 0x144 */ char unk_144[0xA4];
/* 0x144 */ SkelAnime skelAnime;
/* 0x188 */ Vec3s jointTable[DEXIHAND_LIMB_MAX];
/* 0x1B8 */ Vec3s morphTable[DEXIHAND_LIMB_MAX];
/* 0x1E8 */ EnWdhandActionFunc actionFunc;
/* 0x1EC */ char unk_1EC[0x268];
/* 0x1EC */ s16 limbIndexBeforeCut;
/* 0x1EE */ s16 limbIndexAfterCut;
/* 0x1F0 */ s16 timer;
/* 0x1F2 */ Vec3s limbRotations[EN_WDHAND_NUM_SEGMENTS + 1];
/* 0x20C */ f32 globalLimbScaleFactor;
/* 0x20C */ f32 limbScaleFactors[EN_WDHAND_NUM_SEGMENTS];
/* 0x21C */ MtxF relativeToWorldTransform;
/* 0x25C */ Vec3f endPoints[2];
/* 0x274 */ ColliderJntSph collider;
/* 0x294 */ ColliderJntSphElement colliderElements[EN_WDHAND_NUM_COLLIDER_ELEMENTS];
} EnWdhand; // size = 0x454
#endif // Z_EN_WDHAND_H

View File

@ -13198,8 +13198,7 @@
0x80AF64DC:("D_80AF64DC","UNK_TYPE1","",0x1),
0x80AF64EC:("D_80AF64EC","UNK_TYPE1","",0x1),
0x80AF64F4:("D_80AF64F4","UNK_TYPE1","",0x1),
0x80AF6514:("D_80AF6514","UNK_TYPE1","",0x1),
0x80AF6518:("D_80AF6518","f32","",0x4),
0x80AF6514:("D_80AF6514","Vec3f","",0xC),
0x80AF6520:("D_80AF6520","UNK_TYPE1","",0x1),
0x80AF6530:("D_80AF6530","f32","",0x4),
0x80AF6534:("D_80AF6534","f32","",0x4),