mirror of
https://github.com/zeldaret/mm.git
synced 2024-11-23 04:49:45 +00:00
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:
parent
fd3431fa48
commit
44057c087a
@ -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
3
spec
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user