EnAni OK (Man in Tree in South Termina Field) (#566)

* EnAni:Start

* EnAni: done with matching

* EnAni: docs

* EnAni: forgot the display lists, they wouldnt load in z64utils, had to use limb->DL to name them

* EnAni: forgot the spec, so rusty

* Apply suggestions from code review

Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com>

* EnAni: more requested changes

* EnAni: format pass

* EnAni: remove typedef warning

* EnAni: typdef attempt

* Apply suggestions from code review

Co-authored-by: Anghelo Carvajal <angheloalf95@gmail.com>

* EnAni: changed ani state flags from enum to defines

* EnAni: formatter no

* EnAni: undefined behavior

* EnAni: chest rot discovered

* EnAni: fixes after merging

* EnAni: flags docs

* EnAni: flags at top using enum

* EnAni: jenkins bait

* EnAni: revert bgcheck flag

* EnAni: single doc

* EnOssan: format after fix to EnAni

* EnAni: requested changes, some documentation changes

* EnAni: forgot to re-extract

* EnAni: better object naming

* EnAni: changed STATE_SUFFERING to STATE_WRITHING to match object docs, removed extra whitespace from defines

* EnAni: removed object comment about z64util not rendering them

* EnAni: flipped actor flag to match OOT

* EnAni: formater pls

* EnAni: Animatation Enum values in Animation_change calls

Co-authored-by: Isghj8 <isghj8@gmail.com>
Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com>
Co-authored-by: Anghelo Carvajal <angheloalf95@gmail.com>
This commit is contained in:
Isghj 2022-02-19 10:59:43 -08:00 committed by GitHub
parent 26d1982f19
commit 926b575d13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 416 additions and 128 deletions

View File

@ -1,62 +1,67 @@
<Root>
<File Name="object_ani" Segment="6">
<Animation Name="object_ani_Anim_0007FC" Offset="0x7FC" />
<Animation Name="object_ani_Anim_000C14" Offset="0xC14" />
<Animation Name="object_ani_Anim_0011CC" Offset="0x11CC" />
<Animation Name="object_ani_Anim_001584" Offset="0x1584" />
<Animation Name="object_ani_Anim_001D48" Offset="0x1D48" />
<Animation Name="object_ani_Anim_0027A0" Offset="0x27A0" />
<Limb Name="object_ani_Standardlimb_0027B0" Type="Standard" Offset="0x27B0" />
<Limb Name="object_ani_Standardlimb_0027BC" Type="Standard" Offset="0x27BC" />
<Limb Name="object_ani_Standardlimb_0027C8" Type="Standard" Offset="0x27C8" />
<Limb Name="object_ani_Standardlimb_0027D4" Type="Standard" Offset="0x27D4" />
<Limb Name="object_ani_Standardlimb_0027E0" Type="Standard" Offset="0x27E0" />
<Limb Name="object_ani_Standardlimb_0027EC" Type="Standard" Offset="0x27EC" />
<Limb Name="object_ani_Standardlimb_0027F8" Type="Standard" Offset="0x27F8" />
<Limb Name="object_ani_Standardlimb_002804" Type="Standard" Offset="0x2804" />
<Limb Name="object_ani_Standardlimb_002810" Type="Standard" Offset="0x2810" />
<Limb Name="object_ani_Standardlimb_00281C" Type="Standard" Offset="0x281C" />
<Limb Name="object_ani_Standardlimb_002828" Type="Standard" Offset="0x2828" />
<Limb Name="object_ani_Standardlimb_002834" Type="Standard" Offset="0x2834" />
<Limb Name="object_ani_Standardlimb_002840" Type="Standard" Offset="0x2840" />
<Limb Name="object_ani_Standardlimb_00284C" Type="Standard" Offset="0x284C" />
<Limb Name="object_ani_Standardlimb_002858" Type="Standard" Offset="0x2858" />
<Skeleton Name="object_ani_Skel_0028A0" Type="Flex" LimbType="Standard" Offset="0x28A0" />
<DList Name="object_ani_DL_004860" Offset="0x4860" />
<DList Name="object_ani_DL_004A50" Offset="0x4A50" />
<DList Name="object_ani_DL_004B38" Offset="0x4B38" />
<DList Name="object_ani_DL_004C30" Offset="0x4C30" />
<DList Name="object_ani_DL_004E20" Offset="0x4E20" />
<DList Name="object_ani_DL_004F08" Offset="0x4F08" />
<DList Name="object_ani_DL_005000" Offset="0x5000" />
<DList Name="object_ani_DL_005270" Offset="0x5270" />
<DList Name="object_ani_DL_005420" Offset="0x5420" />
<DList Name="object_ani_DL_005668" Offset="0x5668" />
<DList Name="object_ani_DL_005778" Offset="0x5778" />
<DList Name="object_ani_DL_005928" Offset="0x5928" />
<DList Name="object_ani_DL_005C50" Offset="0x5C50" />
<DList Name="object_ani_DL_005D60" Offset="0x5D60" />
<Texture Name="object_ani_TLUT_005E58" OutName="tlut_005E58" Format="rgba16" Width="16" Height="16" Offset="0x5E58" />
<Texture Name="object_ani_Tex_006058" OutName="tex_006058" Format="ci8" Width="8" Height="8" Offset="0x6058" />
<Texture Name="object_ani_Tex_006098" OutName="tex_006098" Format="ci8" Width="8" Height="8" Offset="0x6098" />
<Texture Name="object_ani_Tex_0060D8" OutName="tex_0060D8" Format="i8" Width="8" Height="8" Offset="0x60D8" />
<Texture Name="object_ani_Tex_006118" OutName="tex_006118" Format="ci8" Width="16" Height="16" Offset="0x6118" />
<Texture Name="object_ani_Tex_006218" OutName="tex_006218" Format="ci8" Width="16" Height="16" Offset="0x6218" />
<Texture Name="object_ani_Tex_006318" OutName="tlut_006318" Format="rgba16" Width="192" Height="1" Offset="0x6318" />
<Texture Name="object_ani_Tex_006498" OutName="tex_006498" Format="ci8" TlutOffset="0x6318" Width="32" Height="32" Offset="0x6498" />
<Texture Name="object_ani_Tex_006898" OutName="tex_006898" Format="ci8" Width="16" Height="16" Offset="0x6898" />
<Texture Name="object_ani_Tex_006998" OutName="tex_006998" Format="ci8" Width="8" Height="8" Offset="0x6998" />
<Texture Name="object_ani_Tex_0069D8" OutName="tex_0069D8" Format="ci8" Width="8" Height="8" Offset="0x69D8" />
<Texture Name="object_ani_Tex_006A18" OutName="tex_006A18" Format="ci8" Width="16" Height="16" Offset="0x6A18" />
<Texture Name="object_ani_Tex_006B18" OutName="tex_006B18" Format="ci8" TlutOffset="0x6318" Width="32" Height="32" Offset="0x6B18" />
<Texture Name="object_ani_Tex_006F18" OutName="tex_006F18" Format="ci8" TlutOffset="0x6318" Width="32" Height="32" Offset="0x6F18" />
<DList Name="object_ani_DL_007B58" Offset="0x7B58" />
<Animation Name="object_ani_Anim_009220" Offset="0x9220" />
<Animation Name="object_ani_Anim_009734" Offset="0x9734" />
<Animation Name="object_ani_Anim_009D34" Offset="0x9D34" />
<Animation Name="object_ani_Anim_00A460" Offset="0xA460" />
<Animation Name="object_ani_Anim_00A978" Offset="0xA978" />
<Animation Name="object_ani_Anim_00B2B0" Offset="0xB2B0" />
<Animation Name="object_ani_Anim_00B8AC" Offset="0xB8AC" />
<Animation Name="gAniTreeHangLosingBalanceAnim" Offset="0x7FC" />
<Animation Name="gAniFallOverHoldingFootAnim" Offset="0xC14" />
<Animation Name="gAniHoldingFootWrithingInPainAnim" Offset="0x11CC" />
<Animation Name="gAniUnusedSidesteppingAnim" Offset="0x1584" />
<Animation Name="gAniTreeHangingAnim" Offset="0x1D48" />
<Animation Name="gAniTreeHangingReachAnim" Offset="0x27A0" />
<Limb Name="gAniPelvisLimb" Type="Standard" EnumName="ANI_LIMB_PELVIS" Offset="0x27B0" />
<Limb Name="gAniLeftThighLimb" Type="Standard" EnumName="ANI_LIMB_LEFT_THIGH" Offset="0x27BC" />
<Limb Name="gAniLeftCalfLimb" Type="Standard" EnumName="ANI_LIMB_LEFT_CALF" Offset="0x27C8" />
<Limb Name="gAniLeftFootLimb" Type="Standard" EnumName="ANI_LIMB_LEFT_FOOT" Offset="0x27D4" />
<Limb Name="gAniRightThighLimb" Type="Standard" EnumName="ANI_LIMB_RIGHT_THIGH" Offset="0x27E0" />
<Limb Name="gAniRightCalfLimb" Type="Standard" EnumName="ANI_LIMB_RIGHT_CALF" Offset="0x27EC" />
<Limb Name="gAniRightFootLimb" Type="Standard" EnumName="ANI_LIMB_RIGHT_FOOT" Offset="0x27F8" />
<Limb Name="gAniTorsoLimb" Type="Standard" EnumName="ANI_LIMB_TORSO" Offset="0x2804" />
<Limb Name="gAniLeftUpperArmLimb" Type="Standard" EnumName="ANI_LIMB_LEFT_UPPER_ARM" Offset="0x2810" />
<Limb Name="gAniLeftForArmLimb" Type="Standard" EnumName="ANI_LIMB_LEFT_FORARM" Offset="0x281C" />
<Limb Name="gAniLeftHandLimb" Type="Standard" EnumName="ANI_LIMB_LEFT_HAND" Offset="0x2828" />
<Limb Name="gAniRightUpperArmLimb" Type="Standard" EnumName="ANI_LIMB_RIGHT_UPPER_ARM" Offset="0x2834" />
<Limb Name="gAniRightForArmLimb" Type="Standard" EnumName="ANI_LIMB_RIGHT_FORARM" Offset="0x2840" />
<Limb Name="gAniRightHandLimb" Type="Standard" EnumName="ANI_LIMB_RIGHT_HAND" Offset="0x284C" />
<Limb Name="gAniHeadLimb" Type="Standard" EnumName="ANI_LIMB_HEAD" Offset="0x2858" />
<Skeleton Name="gAniSkeleton" Type="Flex" LimbType="Standard" LimbNone="ANI_LIMB_NONE" LimbMax="ANI_LIMB_MAX" EnumName="ObjectAniLimbs" Offset="0x28A0" />
<DList Name="gAniRightHandDL" Offset="0x4860" />
<DList Name="gAniRightForArmDL" Offset="0x4A50" />
<DList Name="gAniRightUpperArmDL" Offset="0x4B38" />
<DList Name="gAniLeftHandDL" Offset="0x4C30" />
<DList Name="gAniLeftForArmDL" Offset="0x4E20" />
<DList Name="gAniLeftUpperArmDL" Offset="0x4F08" />
<DList Name="gAniTorsoDL" Offset="0x5000" />
<DList Name="gAniRightFootDL" Offset="0x5270" />
<DList Name="gAniRightCalfDL" Offset="0x5420" />
<DList Name="gAniRightThighDL" Offset="0x5668" />
<DList Name="gAniLeftFootDL" Offset="0x5778" />
<DList Name="gAniLeftCalfDL" Offset="0x5928" />
<DList Name="gAniLeftThighDL" Offset="0x5C50" />
<DList Name="gAniPelvisDL" Offset="0x5D60" />
<Texture Name="gAniGeneralTlut" OutName="ani_general_tlut" Format="rgba16" Width="16" Height="16" Offset="0x5E58" />
<Texture Name="gAniUnkGradientTex" OutName="ani_unk_gradient1" Format="ci8" Width="8" Height="8" Offset="0x6058" />
<Texture Name="gAniFingersTex" OutName="ani_fingers" Format="ci8" Width="8" Height="8" Offset="0x6098" />
<Texture Name="gAniShirtEdgeTex" OutName="ani_shirt_edge" Format="i8" Width="8" Height="8" Offset="0x60D8" />
<Texture Name="gAniSandleBuckleTex" OutName="ani_sandle_buckle" Format="ci8" Width="16" Height="16" Offset="0x6118" />
<Texture Name="gAniPantsTex" OutName="ani_pants" Format="ci8" Width="16" Height="16" Offset="0x6218" />
<Texture Name="gAniEyeTlut" OutName="ani_eye_tlut" Format="rgba16" Width="16" Height="12" Offset="0x6318" />
<Texture Name="gAniOpenEyeTex" OutName="ani_open_eye" Format="ci8" Width="32" Height="32" Offset="0x6498" TlutOffset="0x6318" />
<Texture Name="gAniMouthTex" OutName="ani_mouth" Format="ci8" Width="16" Height="16" Offset="0x6898" />
<Texture Name="gAniUnkGradient2Tex" OutName="ani_unk_gradient2" Format="ci8" Width="8" Height="8" Offset="0x6998" />
<Texture Name="gAniEarTex" OutName="ani_ear" Format="ci8" Width="8" Height="8" Offset="0x69D8" />
<Texture Name="gAniHairTex" OutName="ani_hair" Format="ci8" Width="16" Height="16" Offset="0x6A18" />
<Texture Name="gAniClosingEyeTex" OutName="ani_closing_eye" Format="ci8" Width="32" Height="32" Offset="0x6B18" TlutOffset="0x6318"/>
<Texture Name="gAniClosedEyeTex" OutName="ani_closed_eye" Format="ci8" Width="32" Height="32" Offset="0x6F18" TlutOffset="0x6318"/>
<DList Name="gAniHeadDL" Offset="0x7B58" />
<!-- Only the first half of the animation is used by EnAni when knocked out of tree -->
<Animation Name="gAniLandingThenStandingUpAnim" Offset="0x9220" />
<!-- used by EnOssan -->
<Animation Name="gAniHoldUpHandAnim" Offset="0x9734" />
<Animation Name="gAniStandingNormalAnim" Offset="0x9D34" />
<Animation Name="gAniHandBehindHeadApologyAnim" Offset="0xA460" />
<!-- left over from OOT firetemple deathmountain cutscene, unused in MM -->
<Animation Name="gAniKnockBackAnim" Offset="0xA978" />
<Animation Name="gAniKnockBackGettingUpAnim" Offset="0xB2B0" />
<!-- left over from OOT sitting on roof, unused in MM -->
<Animation Name="gAniSittingBackAnim" Offset="0xB8AC" />
</File>
</Root>

3
spec
View File

@ -1729,8 +1729,7 @@ beginseg
name "ovl_En_Ani"
compress
include "build/src/overlays/actors/ovl_En_Ani/z_en_ani.o"
include "build/data/ovl_En_Ani/ovl_En_Ani.data.o"
include "build/data/ovl_En_Ani/ovl_En_Ani.reloc.o"
include "build/src/overlays/actors/ovl_En_Ani/ovl_En_Ani_reloc.o"
endseg
beginseg

View File

@ -1,21 +1,44 @@
/*
* File: z_en_ani.c
* Overlay: ovl_En_Ani
* Description: Part-time worker
* Description: Man in Tree in South Termina Field
* version in shop at night is EnOssan actor using object_ani
*/
#include "z_en_ani.h"
#define FLAGS 0x00000009
#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8)
#define THIS ((EnAni*)thisx)
// clang-format off
#define ANI_STATE_STANDING (0)
#define ANI_STATE_UNK (1 << 0)
#define ANI_STATE_WRITHING (1 << 1)
#define ANI_STATE_CLIMBING (1 << 2)
#define ANI_STATE_FALLING (1 << 3)
// clang-format on
void EnAni_Init(Actor* thisx, GlobalContext* globalCtx);
void EnAni_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnAni_Update(Actor* thisx, GlobalContext* globalCtx);
void EnAni_Draw(Actor* thisx, GlobalContext* globalCtx);
#if 0
void EnAni_DefaultBlink(EnAni* this);
void EnAni_WaitForEyeClose(EnAni* this);
void EnAni_WaitForEyeOpen(EnAni* this);
void EnAni_SetText(EnAni* this, GlobalContext* globalCtx, u16 textId);
void EnAni_HangInTree(EnAni* this, GlobalContext* globalCtx);
void EnAni_LoseBalance(EnAni* this, GlobalContext* globalCtx);
void EnAni_FallToGround(EnAni* this, GlobalContext* globalCtx);
void EnAni_LandOnFoot(EnAni* this, GlobalContext* globalCtx);
void EnAni_FallOverInPain(EnAni* this, GlobalContext* globalCtx);
void EnAni_IdleInPain(EnAni* this, GlobalContext* globalCtx);
void EnAni_Talk(EnAni* this, GlobalContext* globalCtx);
void EnAni_IdleStanding(EnAni* this, GlobalContext* globalCtx);
const ActorInit En_Ani_InitVars = {
ACTOR_EN_ANI,
ACTORCAT_NPC,
@ -28,62 +51,304 @@ const ActorInit En_Ani_InitVars = {
(ActorFunc)EnAni_Draw,
};
// static ColliderCylinderInit sCylinderInit = {
static ColliderCylinderInit D_80968670 = {
{ COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_ENEMY, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, },
{ ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
// two different colliders, but only one init for both
static ColliderCylinderInit sCylinderInit = {
{
COLTYPE_NONE,
AT_NONE,
AC_ON | AC_TYPE_ENEMY,
OC1_ON | OC1_TYPE_ALL,
OC2_TYPE_1,
COLSHAPE_CYLINDER,
},
{
ELEMTYPE_UNK0,
{ 0x00000000, 0x00, 0x00 },
{ 0xF7CFFFFF, 0x00, 0x00 },
TOUCH_NONE | TOUCH_SFX_NORMAL,
BUMP_ON,
OCELEM_ON,
},
{ 30, 40, 0, { 0, 0, 0 } },
};
// static InitChainEntry sInitChain[] = {
static InitChainEntry D_8096869C[] = {
static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F_DIV1000(scale, 10, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 850, ICHAIN_STOP),
};
#endif
void EnAni_DefaultBlink(EnAni* this) {
if (DECR(this->blinkTimer) == 0) {
this->blinkTimer = Rand_S16Offset(60, 60);
}
extern ColliderCylinderInit D_80968670;
extern InitChainEntry D_8096869C[];
this->eyeState = this->blinkTimer;
if (this->eyeState >= 3) {
this->eyeState = 0;
}
}
extern UNK_TYPE D_06000C14;
extern UNK_TYPE D_060011CC;
extern UNK_TYPE D_060027A0;
extern UNK_TYPE D_06009220;
extern UNK_TYPE D_06009D34;
void EnAni_WaitForEyeClose(EnAni* this) {
if (this->blinkTimer > 0) {
this->blinkTimer--;
} else if (this->eyeState < 2) {
this->eyeState++;
} else {
this->blinkFunc = EnAni_WaitForEyeOpen;
this->blinkTimer = Rand_S16Offset(20, 20);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_809679D0.s")
void EnAni_WaitForEyeOpen(EnAni* this) {
if (this->blinkTimer > 0) {
this->blinkTimer--;
} else if (this->eyeState > 0) {
this->eyeState--;
} else {
this->blinkFunc = EnAni_WaitForEyeClose;
this->blinkTimer = Rand_S16Offset(10, 10);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80967A48.s")
void EnAni_Init(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
EnAni* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80967AB4.s")
Actor_ProcessInitChain(&this->actor, sInitChain);
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 24.0f);
SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gAniSkeleton, &gAniStandingNormalAnim, this->jointTable,
this->morphTable, ANI_LIMB_MAX);
Animation_PlayOnce(&this->skelAnime, &gAniStandingNormalAnim);
Collider_InitAndSetCylinder(globalCtx, &this->collider1, &this->actor, &sCylinderInit);
Collider_InitAndSetCylinder(globalCtx, &this->collider2, &this->actor, &sCylinderInit);
Collider_UpdateCylinder(&this->actor, &this->collider2);
this->actor.colChkInfo.mass = MASS_IMMOVABLE;
this->stateFlags = ANI_STATE_STANDING;
this->unk2EE = 0;
this->treeReachTimer = 0;
this->blinkFunc = EnAni_DefaultBlink;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/EnAni_Init.s")
if (GET_ANI_TYPE(thisx) == ANI_TYPE_TREE_HANGING) {
Animation_Change(&this->skelAnime, &gAniTreeHangingAnim, 1.0f, 0.0f,
Animation_GetLastFrame(&gAniTreeHangingAnim), ANIMMODE_ONCE, 0.0f);
this->actionFunc = EnAni_HangInTree;
this->actor.velocity.y = 0.0f;
this->actor.terminalVelocity = 0.0f;
this->actor.gravity = 0.0f;
this->actor.flags |= ACTOR_FLAG_10;
this->stateFlags |= ANI_STATE_CLIMBING;
gSaveContext.eventInf[1] &= (u8)~0x10;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/EnAni_Destroy.s")
} else { // ANI_TYPE_STANDING
// ( unused code )
// for some reason standing he has a large collider
// possibly he was meant to be a blocking npc like bomber
this->collider2.dim.radius = 60;
this->actionFunc = EnAni_IdleStanding;
this->actor.velocity.y = -25.0f;
this->actor.terminalVelocity = -25.0f;
this->actor.gravity = -5.0f;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80967D20.s")
void EnAni_Destroy(Actor* thisx, GlobalContext* globalCtx) {
EnAni* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80967DA0.s")
Collider_DestroyCylinder(globalCtx, &this->collider1);
Collider_DestroyCylinder(globalCtx, &this->collider2);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80967DCC.s")
void EnAni_SetText(EnAni* this, GlobalContext* globalCtx, u16 textId) {
s16 diffAngle = this->actor.yawTowardsPlayer - this->actor.shape.rot.y;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80967E34.s")
this->actor.textId = textId;
if ((this->stateFlags & ANI_STATE_WRITHING) || ABS_ALT(diffAngle) <= 0x4300) {
if (this->actor.xzDistToPlayer < 100.0f) {
func_800B8614(&this->actor, globalCtx, 120.0f);
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80967E90.s")
void EnAni_IdleStanding(EnAni* this, GlobalContext* globalCtx) {
SkelAnime_Update(&this->skelAnime);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80967F20.s")
void EnAni_Talk(EnAni* this, GlobalContext* globalCtx) {
SkelAnime_Update(&this->skelAnime);
if (Message_GetState(&globalCtx->msgCtx) == 2 && globalCtx->msgCtx.unk11F04 == 0x6DE) {
this->actionFunc = EnAni_IdleInPain;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80967FA4.s")
void EnAni_IdleInPain(EnAni* this, GlobalContext* globalCtx) {
SkelAnime_Update(&this->skelAnime);
if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) {
this->actionFunc = EnAni_Talk;
} else {
// telling you not to take his rupees you knocked from the tree
EnAni_SetText(this, globalCtx, 0x6DE);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_809680B0.s")
void EnAni_FallOverInPain(EnAni* this, GlobalContext* globalCtx) {
if (SkelAnime_Update(&this->skelAnime)) {
this->blinkFunc = EnAni_WaitForEyeOpen;
this->actionFunc = EnAni_IdleInPain;
Animation_Change(&this->skelAnime, &gAniHoldingFootWrithingInPainAnim, 1.0f, 0.0f,
Animation_GetLastFrame(&gAniHoldingFootWrithingInPainAnim), ANIMMODE_LOOP, 0.0f);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80968164.s")
void EnAni_LandOnFoot(EnAni* this, GlobalContext* globalCtx) {
if (SkelAnime_Update(&this->skelAnime)) {
this->actionFunc = EnAni_FallOverInPain;
Animation_Change(&this->skelAnime, &gAniFallOverHoldingFootAnim, 1.0f, 0.0f,
Animation_GetLastFrame(&gAniFallOverHoldingFootAnim), ANIMMODE_ONCE, 0.0f);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/EnAni_Update.s")
void EnAni_FallToGround(EnAni* this, GlobalContext* globalCtx) {
s32 pad;
s16 quakeValue;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80968504.s")
if (this->actor.bgCheckFlags & 1) { // hit the ground
this->actor.flags &= ~ACTOR_FLAG_10;
this->actionFunc = EnAni_LandOnFoot;
this->actor.velocity.x = 0.0f;
this->actor.velocity.z = 0.0f;
// the animation gets cut short, (first 16 frames only) only the landing part is seen
Animation_Change(&this->skelAnime, &gAniLandingThenStandingUpAnim, 1.0f, 0.0f, 16.0f, ANIMMODE_ONCE, 0.0f);
this->stateFlags |= ANI_STATE_WRITHING;
quakeValue = Quake_Add(globalCtx->cameraPtrs[0], 3);
Quake_SetSpeed(quakeValue, 0x6978);
Quake_SetQuakeValues(quakeValue, 7, 0, 0, 0);
Quake_SetCountdown(quakeValue, 0x14);
Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_HAMMER_HIT);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_8096854C.s")
Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0x2, 0x7D0, 0x100);
this->actor.world.rot.y = this->actor.shape.rot.y;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/EnAni_Draw.s")
void EnAni_LoseBalance(EnAni* this, GlobalContext* globalCtx) {
s32 pad;
if (SkelAnime_Update(&this->skelAnime)) {
this->actor.terminalVelocity = -20.0f;
this->actor.gravity = -5.0f;
this->actor.velocity.y = 0.0f;
this->actor.velocity.z = -4.0f;
// frame count : 0.0f, only first frame, rest is handled in next action func
Animation_Change(&this->skelAnime, &gAniLandingThenStandingUpAnim, 0.0f, 0.0f, 0.0f, ANIMMODE_ONCE, 5.0f);
this->actionFunc = EnAni_FallToGround;
gSaveContext.eventInf[1] |= 0x10;
}
}
void EnAni_HangInTree(EnAni* this, GlobalContext* globalCtx) {
if (SkelAnime_Update(&this->skelAnime)) {
if (this->treeReachTimer > 0) {
this->treeReachTimer--;
if (this->treeReachTimer > 0) {
Animation_PlayOnce(&this->skelAnime, &gAniTreeHangingReachAnim);
} else {
Animation_PlayOnce(&this->skelAnime, &gAniTreeHangingAnim);
}
} else if (Rand_ZeroFloat(1.0f) < 0.4f) {
Animation_PlayOnce(&this->skelAnime, &gAniTreeHangingReachAnim);
this->treeReachTimer = 2;
} else {
Animation_PlayOnce(&this->skelAnime, &gAniTreeHangingAnim);
}
}
// his bonk detection is based on his tilt, neat
if (this->actor.home.rot.x != 0) {
this->stateFlags |= ANI_STATE_FALLING;
this->actionFunc = EnAni_LoseBalance;
Animation_Change(&this->skelAnime, &gAniTreeHangLosingBalanceAnim, 1.0f, 0.0f,
Animation_GetLastFrame(&gAniTreeHangLosingBalanceAnim), ANIMMODE_ONCE, -5.0f);
}
}
void EnAni_Update(Actor* thisx, GlobalContext* globalCtx) {
EnAni* this = THIS;
f32 minVelocity;
Collider_UpdateCylinder(&this->actor, &this->collider1);
Collider_UpdateCylinder(&this->actor, &this->collider2);
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base);
if (!(this->stateFlags & ANI_STATE_UNK)) {
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider2.base);
}
this->actor.velocity.y += this->actor.gravity;
minVelocity = this->actor.terminalVelocity;
if (this->actor.velocity.y < minVelocity) {
this->actor.velocity.y = minVelocity;
}
Actor_UpdatePos(&this->actor);
Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4);
this->actionFunc(this, globalCtx);
if (this->actor.xzDistToPlayer < 100.0f && !(this->stateFlags & ANI_STATE_CLIMBING)) {
func_800E9250(globalCtx, &this->actor, &this->headRot, &this->chestRot, this->actor.focus.pos);
this->chestRot.x = this->chestRot.y = this->chestRot.z = 0;
} else {
Math_SmoothStepToS(&this->headRot.x, 0, 0x6, 0x1838, 0x64);
Math_SmoothStepToS(&this->headRot.y, 0, 0x6, 0x1838, 0x64);
Math_SmoothStepToS(&this->chestRot.x, 0, 0x6, 0x1838, 0x64);
Math_SmoothStepToS(&this->chestRot.y, 0, 0x6, 0x1838, 0x64);
}
this->blinkFunc(this);
if (this->stateFlags & ANI_STATE_FALLING) {
if (this->actor.cutscene == -1) {
this->stateFlags &= ~ANI_STATE_FALLING;
} else if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) {
ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor);
this->actor.cutscene = ActorCutscene_GetAdditionalCutscene(this->actor.cutscene);
func_800E02AC(Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(this->actor.cutscene)),
&this->actor);
} else {
ActorCutscene_SetIntentToPlay(this->actor.cutscene);
}
}
}
s32 EnAni_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) {
EnAni* this = THIS;
if (limbIndex == ANI_LIMB_HEAD) {
rot->x += this->headRot.y;
rot->z += this->headRot.x;
}
return false;
}
void EnAni_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
static Vec3f D_809686A4 = { 800.0f, 500.0f, 0.0f };
if (limbIndex == ANI_LIMB_HEAD) {
Matrix_MultiplyVector3fByState(&D_809686A4, &thisx->focus.pos);
}
}
void EnAni_Draw(Actor* thisx, GlobalContext* globalCtx) {
static TexturePtr sEyeTextures[] = { gAniOpenEyeTex, gAniClosingEyeTex, gAniClosedEyeTex };
s32 pad;
EnAni* this = THIS;
OPEN_DISPS(globalCtx->state.gfxCtx);
Matrix_InsertTranslation(0.0f, 0.0f, -1000.0f, MTXMODE_APPLY);
func_8012C5B0(globalCtx->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sEyeTextures[this->eyeState]));
SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
EnAni_OverrideLimbDraw, EnAni_PostLimbDraw, &this->actor);
CLOSE_DISPS(globalCtx->state.gfxCtx);
}

View File

@ -2,18 +2,37 @@
#define Z_EN_ANI_H
#include "global.h"
#include "objects/object_ani/object_ani.h"
struct EnAni;
typedef void (*EnAniActionFunc)(struct EnAni*, GlobalContext*);
typedef void (*EnAniBlinkFunc)(struct EnAni*);
typedef struct EnAni {
/* 0x0000 */ Actor actor;
/* 0x0144 */ char unk_144[0x1B0];
/* 0x02F4 */ EnAniActionFunc actionFunc;
/* 0x02F8 */ char unk_2F8[0x8];
/* 0x000 */ Actor actor;
/* 0x144 */ ColliderCylinder collider1;
/* 0x190 */ ColliderCylinder collider2;
/* 0x1DC */ SkelAnime skelAnime;
/* 0x220 */ Vec3s jointTable[ANI_LIMB_MAX];
/* 0x280 */ Vec3s morphTable[ANI_LIMB_MAX];
/* 0x2E0 */ Vec3s headRot;
/* 0x2E6 */ Vec3s chestRot; // unused
/* 0x2EC */ u16 stateFlags;
/* 0x2EE */ s16 unk2EE; // assigned to zero in init, never used after
/* 0x2F0 */ s16 treeReachTimer;
/* 0x2F4 */ EnAniBlinkFunc blinkFunc;
/* 0x2F8 */ s16 eyeState;
/* 0x2FA */ s16 blinkTimer;
/* 0x2FC */ EnAniActionFunc actionFunc;
} EnAni; // size = 0x300
extern const ActorInit En_Ani_InitVars;
enum EnAniType {
/* else */ ANI_TYPE_STANDING, // unfinshed and unused
/* 1 */ ANI_TYPE_TREE_HANGING = 1,
};
#define GET_ANI_TYPE(thisx) (thisx->params & 0xFF)
#endif // Z_EN_ANI_H

View File

@ -82,18 +82,18 @@ static AnimationInfoS sAnimationsCuriosityShopMan[] = {
};
static AnimationInfoS sAnimationsPartTimeWorker[] = {
{ &object_ani_Anim_009D34, 1.0f, 0, -1, ANIMMODE_LOOP, -10 },
{ &object_ani_Anim_009D34, 1.0f, 0, -1, ANIMMODE_LOOP, -10 },
{ &object_ani_Anim_009D34, 1.0f, 0, -1, ANIMMODE_ONCE, 0 },
{ &object_ani_Anim_009D34, -1.0f, 0, -1, ANIMMODE_ONCE, 0 },
{ &object_ani_Anim_009D34, 1.0f, 0, -1, ANIMMODE_ONCE, 0 },
{ &object_ani_Anim_009D34, 1.0f, 0, -1, ANIMMODE_LOOP, 0 },
{ &object_ani_Anim_009D34, 1.0f, 0, -1, ANIMMODE_ONCE, 0 },
{ &object_ani_Anim_009D34, 1.0f, 0, -1, ANIMMODE_LOOP, 0 },
{ &object_ani_Anim_00A460, 1.0f, 0, -1, ANIMMODE_ONCE, -5 },
{ &object_ani_Anim_00A460, 1.0f, 0, -1, ANIMMODE_LOOP, -5 },
{ &object_ani_Anim_009D34, 1.0f, 0, -1, ANIMMODE_ONCE, 0 },
{ &object_ani_Anim_009D34, 1.0f, 0, -1, ANIMMODE_LOOP, 0 },
{ &gAniStandingNormalAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -10 },
{ &gAniStandingNormalAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -10 },
{ &gAniStandingNormalAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 },
{ &gAniStandingNormalAnim, -1.0f, 0, -1, ANIMMODE_ONCE, 0 },
{ &gAniStandingNormalAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 },
{ &gAniStandingNormalAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 },
{ &gAniStandingNormalAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 },
{ &gAniStandingNormalAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 },
{ &gAniHandBehindHeadApologyAnim, 1.0f, 0, -1, ANIMMODE_ONCE, -5 },
{ &gAniHandBehindHeadApologyAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -5 },
{ &gAniStandingNormalAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 },
{ &gAniStandingNormalAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 },
};
static s16 sObjectIds[] = { OBJECT_FSN, OBJECT_ANI };
@ -1331,7 +1331,7 @@ void EnOssan_InitCuriosityShopMan(EnOssan* this, GlobalContext* globalCtx) {
}
void EnOssan_InitPartTimeWorker(EnOssan* this, GlobalContext* globalCtx) {
SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ani_Skel_0028A0, &object_ani_Anim_009D34, this->jointTable,
SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gAniSkeleton, &gAniStandingNormalAnim, this->jointTable,
this->morphTable, 16);
this->actor.draw = EnOssan_DrawPartTimeWorker;
}
@ -1690,7 +1690,7 @@ void EnOssan_DrawCuriosityShopMan(Actor* thisx, GlobalContext* globalCtx) {
}
void EnOssan_DrawPartTimeWorker(Actor* thisx, GlobalContext* globalCtx) {
static TexturePtr sEyeTextures[] = { object_ani_Tex_006498, object_ani_Tex_006B18, object_ani_Tex_006F18 };
static TexturePtr sEyeTextures[] = { gAniOpenEyeTex, gAniClosingEyeTex, gAniClosedEyeTex };
EnOssan* this = THIS;
s32 pad;

View File

@ -7929,23 +7929,23 @@
0x80967608:("func_80967608",),
0x809676A4:("EnWeatherTag_Update",),
0x80967784:("EnWeatherTag_Draw",),
0x809679D0:("func_809679D0",),
0x80967A48:("func_80967A48",),
0x80967AB4:("func_80967AB4",),
0x809679D0:("EnAni_DefaultBlink",),
0x80967A48:("EnAni_WaitForEyeClose",),
0x80967AB4:("EnAni_WaitForEyeOpen",),
0x80967B1C:("EnAni_Init",),
0x80967CE0:("EnAni_Destroy",),
0x80967D20:("func_80967D20",),
0x80967DA0:("func_80967DA0",),
0x80967DCC:("func_80967DCC",),
0x80967E34:("func_80967E34",),
0x80967E90:("func_80967E90",),
0x80967F20:("func_80967F20",),
0x80967FA4:("func_80967FA4",),
0x809680B0:("func_809680B0",),
0x80968164:("func_80968164",),
0x80967D20:("EnAni_SetText",),
0x80967DA0:("EnAni_IdleStanding",),
0x80967DCC:("EnAni_Talk",),
0x80967E34:("EnAni_IdleInPain",),
0x80967E90:("EnAni_FallOverInPain",),
0x80967F20:("EnAni_LandOnFoot",),
0x80967FA4:("EnAni_FallToGround",),
0x809680B0:("EnAni_LoseBalance",),
0x80968164:("EnAni_HangInTree",),
0x809682A8:("EnAni_Update",),
0x80968504:("func_80968504",),
0x8096854C:("func_8096854C",),
0x80968504:("EnAni_OverrideLimbDraw",),
0x8096854C:("EnAni_PostLimbDraw",),
0x8096858C:("EnAni_Draw",),
0x809687B0:("EnJs_Init",),
0x809689D4:("EnJs_Destroy",),