summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEthan Roseman <ethteck@gmail.com>2020-05-04 12:11:37 -0400
committerGitHub <noreply@github.com>2020-05-04 12:11:37 -0400
commit713de9b9422aacc46a4adfaae7510e376cbcd236 (patch)
tree5cf847953979f5b5300035a23e97eefd242b8be9 /src
parentca20f56c09ebdf7a3cd874de311b374be9c720ad (diff)
Decompiled ovl_En_Cow (#113)
* Beginning the Cow * Decompiled ovl_En_Cow * Giving the cow milk
Diffstat (limited to 'src')
-rw-r--r--src/overlays/actors/ovl_En_Cow/z_en_cow.c362
-rw-r--r--src/overlays/actors/ovl_En_Cow/z_en_cow.h10
2 files changed, 349 insertions, 23 deletions
diff --git a/src/overlays/actors/ovl_En_Cow/z_en_cow.c b/src/overlays/actors/ovl_En_Cow/z_en_cow.c
index cff3d6f4c..92af2de83 100644
--- a/src/overlays/actors/ovl_En_Cow/z_en_cow.c
+++ b/src/overlays/actors/ovl_En_Cow/z_en_cow.c
@@ -13,7 +13,17 @@ void EnCow_Destroy(EnCow* this, GlobalContext* globalCtx);
void EnCow_Update(EnCow* this, GlobalContext* globalCtx);
void EnCow_Draw(EnCow* this, GlobalContext* globalCtx);
-/*
+void func_809DF494(EnCow* this, GlobalContext* globalCtx);
+void func_809DF6BC(EnCow* this, GlobalContext* globalCtx);
+void func_809DF778(EnCow* this, GlobalContext* globalCtx);
+void func_809DF7D8(EnCow* this, GlobalContext* globalCtx);
+void func_809DF870(EnCow* this, GlobalContext* globalCtx);
+void func_809DF8FC(EnCow* this, GlobalContext* globalCtx);
+void func_809DF96C(EnCow* this, GlobalContext* globalCtx);
+void func_809DFA84(EnCow* this, GlobalContext* globalCtx);
+void func_809DFE98(EnCow* this, GlobalContext* globalCtx);
+void func_809E0070(EnCow* this, GlobalContext* globalCtx);
+
const ActorInit En_Cow_InitVars = {
ACTOR_EN_COW,
ACTORTYPE_NPC,
@@ -25,43 +35,351 @@ const ActorInit En_Cow_InitVars = {
(ActorFunc)EnCow_Update,
(ActorFunc)EnCow_Draw,
};
-*/
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Cow/func_809DEE00.s")
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Cow/func_809DEE9C.s")
+static ColliderCylinderInit cylinderInit = {
+ { COLTYPE_UNK10, 0x00, 0x11, 0x39, 0x10, COLSHAPE_CYLINDER },
+ { 0x00, { 0x00000000, 0x00, 0x00 }, { 0xFFCFFFFF, 0x00, 0x00 }, 0x00, 0x01, 0x01 },
+ { 30, 40, 0, { 0, 0, 0 } },
+};
+
+Vec3f D_809E010C = {
+ 0.0f,
+ -1300.0f,
+ 1100.0f,
+};
+
+extern AnimationHeader D_060001CC;
+extern SkeletonHeader D_06004010;
+extern AnimationHeader D_06004264;
+extern AnimationHeader D_06004348;
+extern SkeletonHeader D_06004C30;
+extern AnimationHeader D_06004E98;
+
+void func_809DEE00(Vec3f* vec, s16 rotY) {
+ f32 xCalc;
+ f32 rotCalcTemp;
+
+ rotCalcTemp = Math_Coss(rotY);
+ xCalc = (Math_Sins(rotY) * vec->z) + (rotCalcTemp * vec->x);
+ rotCalcTemp = Math_Sins(rotY);
+ vec->z = (Math_Coss(rotY) * vec->z) + (-rotCalcTemp * vec->x);
+ vec->x = xCalc;
+}
+
+void func_809DEE9C(EnCow* this) {
+ Vec3f vec;
+
+ vec.y = 0.0f;
+ vec.x = 0.0f;
+ vec.z = 30.0f;
+ func_809DEE00(&vec, this->actor.shape.rot.y);
+ this->colliders[0].dim.pos.x = this->actor.posRot.pos.x + vec.x;
+ this->colliders[0].dim.pos.y = this->actor.posRot.pos.y;
+ this->colliders[0].dim.pos.z = this->actor.posRot.pos.z + vec.z;
+
+ vec.x = 0.0f;
+ vec.y = 0.0f;
+ vec.z = -20.0f;
+ func_809DEE00(&vec, this->actor.shape.rot.y);
+ this->colliders[1].dim.pos.x = this->actor.posRot.pos.x + vec.x;
+ this->colliders[1].dim.pos.y = this->actor.posRot.pos.y;
+ this->colliders[1].dim.pos.z = this->actor.posRot.pos.z + vec.z;
+}
+
+void func_809DEF94(EnCow* this) {
+ Vec3f vec;
+
+ // clang-format off
+ vec.x = 0.0f; vec.y = 57.0f; vec.z = -36.0f;
+ // clang-format on
+
+ func_809DEE00(&vec, this->actor.shape.rot.y);
+ this->actor.posRot.pos.x += vec.x;
+ this->actor.posRot.pos.y += vec.y;
+ this->actor.posRot.pos.z += vec.z;
+}
+
+void EnCow_Init(EnCow* this, GlobalContext* globalCtx) {
+ s32 pad[2];
+
+ ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawFunc_Circle, 72.0f);
+ switch (this->actor.params) {
+ case 0:
+ SkelAnime_InitSV(globalCtx, &this->skelAnime, &D_06004010, NULL, this->limbDrawTable,
+ this->transitionDrawTable, 6);
+ SkelAnime_ChangeAnimDefaultRepeat(&this->skelAnime, &D_060001CC);
+ Collider_InitCylinder(globalCtx, &this->colliders[0]);
+ Collider_SetCylinder(globalCtx, &this->colliders[0], &this->actor, &cylinderInit);
+ Collider_InitCylinder(globalCtx, &this->colliders[1]);
+ Collider_SetCylinder(globalCtx, &this->colliders[1], &this->actor, &cylinderInit);
+ func_809DEE9C(this);
+ this->actionFunc = (ActorFunc)func_809DF96C;
+ if (globalCtx->sceneNum == SCENE_LINK_HOME) {
+ if (gSaveContext.linkAge != 0) {
+ Actor_Kill(&this->actor);
+ return;
+ }
+ if (!(gSaveContext.eventChkInf[1] & 0x4000)) {
+ Actor_Kill(&this->actor);
+ return;
+ }
+ }
+ Actor_SpawnAttached(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_COW, this->actor.posRot.pos.x,
+ this->actor.posRot.pos.y, this->actor.posRot.pos.z, 0, this->actor.shape.rot.y, 0, 1);
+ this->unk_278 = Math_Rand_ZeroFloat(1000.0f) + 40.0f;
+ this->unk_27A = 0;
+ this->actor.unk_1F = 6;
+ DREG(53) = 0;
+ break;
+ case 1:
+ SkelAnime_InitSV(globalCtx, &this->skelAnime, &D_06004C30, NULL, this->limbDrawTable,
+ this->transitionDrawTable, 6);
+ SkelAnime_ChangeAnimDefaultRepeat(&this->skelAnime, &D_06004348);
+ this->actor.update = (ActorFunc)func_809DFE98;
+ this->actor.draw = (ActorFunc)func_809E0070;
+ this->actionFunc = (ActorFunc)func_809DFA84;
+ func_809DEF94(this);
+ this->actor.flags &= ~0x1;
+ this->unk_278 = ((u32)(Math_Rand_ZeroFloat(1000.0f)) & 0xFFFF) + 40.0f;
+ break;
+ }
+ this->actor.colChkInfo.mass = 0xFF;
+ Actor_SetScale(&this->actor, 0.01f);
+ this->unk_276 = 0;
+}
+
+void EnCow_Destroy(EnCow* this, GlobalContext* globalCtx) {
+ if (this->actor.params == 0) {
+ Collider_DestroyCylinder(globalCtx, &this->colliders[0]);
+ Collider_DestroyCylinder(globalCtx, &this->colliders[1]);
+ }
+}
+
+void func_809DF494(EnCow* this, GlobalContext* globalCtx) {
+ if (this->unk_278 > 0) {
+ this->unk_278 -= 1;
+ } else {
+ this->unk_278 = Math_Rand_ZeroFloat(500.0f) + 40.0f;
+ SkelAnime_ChangeAnim(&this->skelAnime, &D_060001CC, 1.0f, this->skelAnime.animCurrentFrame,
+ SkelAnime_GetFrameCount(&D_060001CC.genericHeader), 2, 1.0f);
+ }
+
+ if ((this->actor.xzDistanceFromLink < 150.0f) && (!(this->unk_276 & 2))) {
+ this->unk_276 |= 2;
+ if (this->skelAnime.animCurrentSeg == &D_060001CC) {
+ this->unk_278 = 0;
+ }
+ }
+
+ this->unk_27A += 1;
+ if (this->unk_27A >= 0x31) {
+ this->unk_27A = 0;
+ }
+
+ // (1.0f / 100.0f) instead of 0.01f below is necessary so 0.01f doesn't get reused mistakenly
+ if (this->unk_27A < 0x20) {
+ this->actor.scale.x = ((Math_Sins(this->unk_27A << 0xA) * (1.0f / 100.0f)) + 1.0f) * 0.01f;
+ } else {
+ this->actor.scale.x = 0.01f;
+ }
+
+ if (this->unk_27A >= 0x11) {
+ this->actor.scale.y = ((Math_Sins((this->unk_27A << 0xA) - 0x4000) * (1.0f / 100.0f)) + 1.0f) * 0.01f;
+ } else {
+ this->actor.scale.y = 0.01f;
+ }
+}
+
+void func_809DF6BC(EnCow* this, GlobalContext* globalCtx) {
+ if ((func_8010BDBC(&globalCtx->msgCtx) == 5) && (func_80106BC8(globalCtx) != 0)) {
+ this->actor.flags &= ~0x10000;
+ func_80106CCC(globalCtx);
+ this->actionFunc = (ActorFunc)func_809DF96C;
+ }
+}
+
+void func_809DF730(EnCow* this, GlobalContext* globalCtx) {
+ if (func_8002F334(&this->actor, globalCtx)) {
+ this->actor.flags &= ~0x10000;
+ this->actionFunc = (ActorFunc)func_809DF96C;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Cow/func_809DEF94.s")
+void func_809DF778(EnCow* this, GlobalContext* globalCtx) {
+ if (func_8002F410(&this->actor, globalCtx)) {
+ this->actor.attachedA = NULL;
+ this->actionFunc = (ActorFunc)func_809DF730;
+ } else {
+ func_8002F434(&this->actor, globalCtx, GI_MILK, 10000.0f, 100.0f);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Cow/EnCow_Init.s")
+void func_809DF7D8(EnCow* this, GlobalContext* globalCtx) {
+ if ((func_8010BDBC(&globalCtx->msgCtx) == 5) && (func_80106BC8(globalCtx) != 0)) {
+ this->actor.flags &= ~0x10000;
+ func_80106CCC(globalCtx);
+ this->actionFunc = (ActorFunc)func_809DF778;
+ func_8002F434(&this->actor, globalCtx, GI_MILK, 10000.0f, 100.0f);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Cow/EnCow_Destroy.s")
+void func_809DF870(EnCow* this, GlobalContext* globalCtx) {
+ if ((func_8010BDBC(&globalCtx->msgCtx) == 5) && (func_80106BC8(globalCtx) != 0)) {
+ if (Inventory_HasEmptyBottle()) {
+ func_8010B720(globalCtx, 0x2007);
+ this->actionFunc = (ActorFunc)func_809DF7D8;
+ } else {
+ func_8010B720(globalCtx, 0x2013);
+ this->actionFunc = (ActorFunc)func_809DF6BC;
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Cow/func_809DF494.s")
+void func_809DF8FC(EnCow* this, GlobalContext* globalCtx) {
+ if (func_8002F194(&this->actor, globalCtx)) {
+ this->actionFunc = (ActorFunc)func_809DF870;
+ } else {
+ this->actor.flags |= 0x10000;
+ func_8002F2CC(&this->actor, globalCtx, 170.0f);
+ this->actor.textId = 0x2006;
+ }
+ func_809DF494(this, globalCtx);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Cow/func_809DF6BC.s")
+void func_809DF96C(EnCow* this, GlobalContext* globalCtx) {
+ if ((globalCtx->msgCtx.unk_E3EE == 0) || (globalCtx->msgCtx.unk_E3EE == 4)) {
+ if (DREG(53) != 0) {
+ if (this->unk_276 & 4) {
+ this->unk_276 &= ~0x4;
+ DREG(53) = 0;
+ } else {
+ if ((this->actor.xzDistanceFromLink < 150.0f) &&
+ (ABS((s16)(this->actor.rotTowardsLinkY - this->actor.shape.rot.y)) < 0x61A8)) {
+ DREG(53) = 0;
+ this->actionFunc = (ActorFunc)func_809DF8FC;
+ this->actor.flags |= 0x10000;
+ func_8002F2CC(&this->actor, globalCtx, 170.0f);
+ this->actor.textId = 0x2006;
+ } else {
+ this->unk_276 |= 4;
+ }
+ }
+ } else {
+ this->unk_276 &= ~0x4;
+ }
+ }
+ func_809DF494(this, globalCtx);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Cow/func_809DF730.s")
+void func_809DFA84(EnCow* this, GlobalContext* globalCtx) {
+ if (this->unk_278 > 0) {
+ this->unk_278--;
+ } else {
+ this->unk_278 = Math_Rand_ZeroFloat(200.0f) + 40.0f;
+ SkelAnime_ChangeAnim(&this->skelAnime, &D_06004348, 1.0f, this->skelAnime.animCurrentFrame,
+ SkelAnime_GetFrameCount(&D_06004348.genericHeader), 2, 1.0f);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Cow/func_809DF778.s")
+ if ((this->actor.xzDistanceFromLink < 150.0f) &&
+ (ABS((s16)(this->actor.rotTowardsLinkY - this->actor.shape.rot.y)) >= 0x61A9) && (!(this->unk_276 & 2))) {
+ this->unk_276 |= 2;
+ if (this->skelAnime.animCurrentSeg == &D_06004348) {
+ this->unk_278 = 0;
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Cow/func_809DF7D8.s")
+void EnCow_Update(EnCow* this, GlobalContext* globalCtx) {
+ s32 pad;
+ CollisionCheckContext* colChckCtx = &globalCtx->colChkCtx;
+ s16 targetX;
+ s16 targetY;
+ Player* player = PLAYER;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Cow/func_809DF870.s")
+ CollisionCheck_SetOC(globalCtx, colChckCtx, &this->colliders[0].base);
+ if (globalCtx) {} // necessary to match
+ CollisionCheck_SetOC(globalCtx, colChckCtx, &this->colliders[1].base);
+ Actor_MoveForward(&this->actor);
+ func_8002E4B4(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4);
+ if (SkelAnime_FrameUpdateMatrix(&this->skelAnime) != 0) {
+ if (this->skelAnime.animCurrentSeg == &D_060001CC) {
+ Audio_PlayActorSound2(&this->actor, NA_SE_EV_COW_CRY);
+ SkelAnime_ChangeAnim(&this->skelAnime, &D_06004264, 1.0f, 0.0f,
+ SkelAnime_GetFrameCount(&D_06004264.genericHeader), 2, 1.0f);
+ } else {
+ SkelAnime_ChangeAnim(&this->skelAnime, &D_060001CC, 1.0f, 0.0f,
+ SkelAnime_GetFrameCount(&D_060001CC.genericHeader), 0, 1.0f);
+ }
+ }
+ this->actionFunc(this, globalCtx);
+ if ((this->actor.xzDistanceFromLink < 150.0f) &&
+ (ABS(Math_Vec3f_Yaw(&this->actor.posRot.pos, &player->actor.posRot.pos)) < 0xC000)) {
+ targetX = Math_Vec3f_Pitch(&this->actor.posRot2.pos, &player->actor.posRot2.pos);
+ targetY = Math_Vec3f_Yaw(&this->actor.posRot2.pos, &player->actor.posRot2.pos) - this->actor.shape.rot.y;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Cow/func_809DF8FC.s")
+ if (targetX > 0x1000) {
+ targetX = 0x1000;
+ } else if (targetX < -0x1000) {
+ targetX = -0x1000;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Cow/func_809DF96C.s")
+ if (targetY > 0x2500) {
+ targetY = 0x2500;
+ } else if (targetY < -0x2500) {
+ targetY = -0x2500;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Cow/func_809DFA84.s")
+ } else {
+ targetY = 0;
+ targetX = 0;
+ }
+ Math_SmoothScaleMaxMinS(&this->someRot.x, targetX, 0xA, 0xC8, 0xA);
+ Math_SmoothScaleMaxMinS(&this->someRot.y, targetY, 0xA, 0xC8, 0xA);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Cow/EnCow_Update.s")
+void func_809DFE98(EnCow* this, GlobalContext* globalCtx) {
+ SkelAnime* skelAnime = &this->skelAnime;
+ AnimationHeader* temp_a0 = &D_06004348;
+ if (this->skelAnime.animCurrentSeg) {} // necessary to match
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Cow/func_809DFE98.s")
+ if (SkelAnime_FrameUpdateMatrix(skelAnime) != 0) {
+ if (this->skelAnime.animCurrentSeg == temp_a0) {
+ SkelAnime_ChangeAnim(skelAnime, &D_06004E98, 1.0f, 0.0f,
+ (f32)SkelAnime_GetFrameCount(&D_06004E98.genericHeader), 2, 1.0f);
+ } else {
+ SkelAnime_ChangeAnim(skelAnime, temp_a0, 1.0f, 0.0f, (f32)SkelAnime_GetFrameCount(&temp_a0->genericHeader),
+ 0, 1.0f);
+ }
+ }
+ this->actionFunc(this, globalCtx);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Cow/func_809DFF84.s")
+s32 EnCow_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* this) {
+ EnCow* thisx = (EnCow*)this;
+ if (limbIndex == 2) {
+ rot->y += thisx->someRot.y;
+ rot->x += thisx->someRot.x;
+ }
+ if (limbIndex == 5) {
+ *dList = NULL;
+ }
+ return 0;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Cow/func_809DFFD4.s")
+void EnCow_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* this) {
+ if (limbIndex == 2) {
+ Matrix_MultVec3f(&D_809E010C, &this->posRot2.pos);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Cow/EnCow_Draw.s")
+void EnCow_Draw(EnCow* this, GlobalContext* globalCtx) {
+ func_800943C8(globalCtx->state.gfxCtx);
+ SkelAnime_DrawSV(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, this->skelAnime.dListCount,
+ EnCow_OverrideLimbDraw, EnCow_PostLimbDraw, &this->actor);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Cow/func_809E0070.s")
+void func_809E0070(EnCow* this, GlobalContext* globalCtx) {
+ func_800943C8(globalCtx->state.gfxCtx);
+ SkelAnime_DrawSV(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, this->skelAnime.dListCount, NULL,
+ NULL, &this->actor);
+}
diff --git a/src/overlays/actors/ovl_En_Cow/z_en_cow.h b/src/overlays/actors/ovl_En_Cow/z_en_cow.h
index 7b44f7771..73c9ff175 100644
--- a/src/overlays/actors/ovl_En_Cow/z_en_cow.h
+++ b/src/overlays/actors/ovl_En_Cow/z_en_cow.h
@@ -6,7 +6,15 @@
typedef struct {
/* 0x0000 */ Actor actor;
- /* 0x014C */ char unk_14C[0x134];
+ /* 0x014C */ ColliderCylinder colliders[2];
+ /* 0x01E4 */ SkelAnime skelAnime;
+ /* 0x0228 */ Vec3s limbDrawTable[6];
+ /* 0x024C */ Vec3s transitionDrawTable[6];
+ /* 0x0270 */ Vec3s someRot;
+ /* 0x0276 */ u16 unk_276;
+ /* 0x0278 */ u16 unk_278;
+ /* 0x027A */ u16 unk_27A;
+ /* 0x027C */ ActorFunc actionFunc;
} EnCow; // size = 0x0280
extern const ActorInit En_Cow_InitVars;