summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaide <34639600+Kelebek1@users.noreply.github.com>2022-02-28 02:52:39 +0000
committerGitHub <noreply@github.com>2022-02-28 02:52:39 +0000
commite127ee650a88ad128a83e564e975eb63badc0873 (patch)
treef456ba42a655cd7d1dd2f3cbc313c296f7f4a961 /src
parent6f4b349020705886ee09b80095a71b6b27d6a6a5 (diff)
En_Pr2 (#587)
* En_Pr2 * Cringe * Merge * PR * Revert EnEncount1 * PR
Diffstat (limited to 'src')
-rw-r--r--src/overlays/actors/ovl_En_Encount1/z_en_encount1.h6
-rw-r--r--src/overlays/actors/ovl_En_Pr2/z_en_pr2.c704
-rw-r--r--src/overlays/actors/ovl_En_Pr2/z_en_pr2.h41
3 files changed, 717 insertions, 34 deletions
diff --git a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h
index 72638d9a6..3cf01bd8a 100644
--- a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h
+++ b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h
@@ -10,7 +10,11 @@ typedef void (*EnEncount1ActionFunc)(struct EnEncount1*, GlobalContext*);
typedef struct EnEncount1 {
/* 0x0000 */ Actor actor;
/* 0x0144 */ EnEncount1ActionFunc actionFunc;
- /* 0x0148 */ char unk_148[0x1C];
+ /* 0x0148 */ char unk_148[0x6];
+ /* 0x014E */ s16 unk_14E;
+ /* 0x0150 */ char unk_150[0xA];
+ /* 0x015A */ s16 unk_15A;
+ /* 0x015C */ char unk_15C[0x8];
} EnEncount1; // size = 0x164
extern const ActorInit En_Encount1_InitVars;
diff --git a/src/overlays/actors/ovl_En_Pr2/z_en_pr2.c b/src/overlays/actors/ovl_En_Pr2/z_en_pr2.c
index 045d7cc3e..6fa76d817 100644
--- a/src/overlays/actors/ovl_En_Pr2/z_en_pr2.c
+++ b/src/overlays/actors/ovl_En_Pr2/z_en_pr2.c
@@ -5,6 +5,8 @@
*/
#include "z_en_pr2.h"
+#include "objects/object_pr/object_pr.h"
+#include "overlays/actors/ovl_En_Encount1/z_en_encount1.h"
#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10)
@@ -15,9 +17,16 @@ void EnPr2_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnPr2_Update(Actor* thisx, GlobalContext* globalCtx);
void EnPr2_Draw(Actor* thisx, GlobalContext* globalCtx);
-#if 0
-// static DamageTable sDamageTable = {
-static DamageTable D_80A75BC0 = {
+void func_80A745C4(EnPr2* this);
+void func_80A745FC(EnPr2* this, GlobalContext* globalCtx);
+void func_80A74888(EnPr2* this);
+void func_80A748E8(EnPr2* this, GlobalContext* globalCtx);
+void func_80A74DEC(EnPr2* this, GlobalContext* globalCtx);
+void func_80A74E90(EnPr2* this, GlobalContext* globalCtx);
+void func_80A751B4(EnPr2* this);
+void func_80A75310(EnPr2* this, GlobalContext* globalCtx);
+
+static DamageTable sDamageTable = {
/* Deku Nut */ DMG_ENTRY(0, 0x0),
/* Deku Stick */ DMG_ENTRY(0, 0x0),
/* Horse trample */ DMG_ENTRY(0, 0x0),
@@ -52,10 +61,23 @@ static DamageTable D_80A75BC0 = {
/* Powder Keg */ DMG_ENTRY(1, 0xF),
};
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_80A75BE0 = {
- { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_1, OC2_TYPE_1, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x08, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
+static ColliderCylinderInit sCylinderInit = {
+ {
+ COLTYPE_NONE,
+ AT_ON | AT_TYPE_ENEMY,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_1,
+ OC2_TYPE_1,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x08, 0x04 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
{ 17, 32, -10, { 0, 0, 0 } },
};
@@ -71,48 +93,668 @@ const ActorInit En_Pr2_InitVars = {
(ActorFunc)EnPr2_Draw,
};
-#endif
+static AnimationHeader* sAnimations[] = {
+ &object_pr_Anim_004340,
+ &object_pr_Anim_004274,
+ &object_pr_Anim_003904,
+};
+
+u8 D_80A75C38[] = { 0, 0, 2, 0 };
+
+s16 D_80A75C3C[] = {
+ 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
+};
+
+void EnPr2_Init(Actor* thisx, GlobalContext* globalCtx) {
+ EnPr2* this = THIS;
+
+ this->actor.targetMode = 3;
+ this->actor.hintId = 0x5B;
+ this->unk_1EC = 255;
+ this->actor.colChkInfo.health = 1;
+ this->actor.colChkInfo.damageTable = &sDamageTable;
+
+ SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_pr_Skel_004188, &object_pr_Anim_004340, this->jointTable,
+ this->morphtable, 5);
+ this->unk_1E0 = ENPR2_GET_F(&this->actor);
+ this->actor.colChkInfo.mass = 10;
+ Math_Vec3f_Copy(&this->unk_228, &this->actor.home.pos);
+
+ if (this->unk_1E0 == 2) {
+ this->unk_208 = ENPR2_GET_FF0(&this->actor) * 20.0f;
+ }
+ this->unk_1F4 = 255;
+ this->actor.shape.yOffset = 500.0f;
+ this->actor.shape.shadowScale = 12.0f;
+
+ if (this->unk_1E0 < 10) {
+ ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 19.0f);
+ Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
+ this->unk_218 = -1;
+ this->unk_204 = 0.0f;
+
+ if (this->actor.parent != NULL) {
+ Actor* parent = this->actor.parent;
+
+ if (parent->update != NULL) {
+ if (parent->world.rot.y != 0) {
+ this->unk_218 = parent->world.rot.y - 1;
+ }
+ }
+ } else if (this->actor.world.rot.z != 0) {
+ this->unk_218 = this->actor.world.rot.z - 1;
+ this->actor.world.rot.z = 0;
+ }
+
+ if (this->unk_1E0 == 3) {
+ if (this->actor.parent != NULL) {
+ Actor* parent = this->actor.parent;
+
+ if (parent->update != NULL) {
+ this->unk_1C8 = ((EnEncount1*)parent)->unk_15A;
+ this->path = func_8013D648(globalCtx, this->unk_1C8, 0x3F);
+ this->unk_208 = parent->world.rot.z * 20.0f;
+ if (this->unk_208 < 20.0f) {
+ this->unk_208 = 20.0f;
+ }
+ }
+ func_80A745C4(this);
+ } else {
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
+ } else {
+ func_80A74888(this);
+ }
+ } else {
+ this->unk_204 = 0.02f;
+ func_80A751B4(this);
+ }
+
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 20.0f, 20.0f, 0x1D);
+
+ if (!(this->actor.bgCheckFlags & 0x60)) {
+ Actor_MarkForDeath(&this->actor);
+ }
+}
+
+void EnPr2_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ EnPr2* this = THIS;
+
+ if (this->unk_1E0 < 10) {
+ Collider_DestroyCylinder(globalCtx, &this->collider);
+ }
+
+ if (this->actor.parent != NULL) {
+ Actor* parent = this->actor.parent;
+
+ if ((parent->update != NULL) && (((EnEncount1*)parent)->unk_14E > 0)) {
+ ((EnEncount1*)parent)->unk_14E--;
+ }
+ }
+}
+
+s32 func_80A7429C(EnPr2* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+ s16 sp1A;
+ s16 sp18;
+
+ Actor_GetScreenPos(globalCtx, &this->actor, &sp1A, &sp18);
+
+ if ((fabsf(player->actor.world.pos.y - this->actor.world.pos.y) > 160.0f) ||
+ (this->actor.projectedPos.z < -40.0f) || (sp1A < 0) || (sp1A > 320) || (sp18 < 0) || (sp18 > 240)) {
+ return false;
+ }
+
+ if (!(player->stateFlags1 & 0x8000000)) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+void func_80A7436C(EnPr2* this, s16 arg1) {
+ s16 sp2E = arg1 - this->actor.world.rot.y;
+
+ if (sp2E > 10000) {
+ sp2E = 10000;
+ } else if (sp2E < -10000) {
+ sp2E = -10000;
+ }
+
+ Math_ApproachF(&this->actor.world.pos.y, this->unk_21C.y, 0.3f, 5.0f);
+
+ if (fabsf(this->actor.world.pos.y - this->unk_21C.y) > 10.0f) {
+ Math_SmoothStepToS(&this->actor.world.rot.x, Math_Vec3f_Pitch(&this->actor.world.pos, &this->unk_21C) * 0.3f,
+ 20, 5000, 500);
+ } else {
+ Math_SmoothStepToS(&this->actor.world.rot.x, 0, 20, 5000, 500);
+ }
+
+ if (fabsf(this->actor.world.rot.y - arg1) < 30.0f) {
+ Math_ApproachZeroF(&this->unk_1FC, 0.5f, 20.0f);
+ } else {
+ Math_ApproachF(&this->unk_1FC, sp2E, 0.5f, 3000.0f);
+ }
+
+ Math_SmoothStepToS(&this->actor.world.rot.y, arg1, 1, 2000, 300);
+}
+
+void func_80A74510(EnPr2* this, s32 arg0) {
+ f32 sp34 = 1.0f;
+
+ this->unk_210 = arg0;
+ this->unk_1F8 = Animation_GetLastFrame(sAnimations[arg0]);
+ if (this->unk_210 == 3) {
+ sp34 = 0.0f;
+ }
+ Animation_Change(&this->skelAnime, sAnimations[arg0], sp34, 0.0f, this->unk_1F8, D_80A75C38[arg0], 0.0f);
+}
+
+void func_80A745C4(EnPr2* this) {
+ func_80A74510(this, 0);
+ this->unk_1D4 = 0;
+ this->actionFunc = func_80A745FC;
+}
+
+void func_80A745FC(EnPr2* this, GlobalContext* globalCtx) {
+ f32 x;
+ f32 y;
+ f32 z;
+ f32 sqrtXYZ;
+
+ if (fabsf(this->actor.world.rot.y - this->unk_1EE) < 200.0f) {
+ SkelAnime_Update(&this->skelAnime);
+ }
+
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PIRANHA_EXIST - SFX_FLAG);
+ Math_ApproachF(&this->unk_204, 0.02f, 0.1f, 0.005f);
+
+ if (this->path->unk2 < this->unk_1D0) {
+ Math_ApproachF(&this->actor.speedXZ, 5.0f, 0.3f, 1.0f);
+ } else {
+ Math_ApproachF(&this->actor.speedXZ, 10.0f, 0.3f, 1.0f);
+ }
+
+ if ((this->path != NULL) && !func_8013D68C(this->path, this->unk_1D0, &this->unk_21C)) {
+ Actor_MarkForDeath(&this->actor);
+ }
+
+ Math_ApproachF(&this->actor.world.pos.y, this->unk_21C.y, 0.3f, 5.0f);
+
+ if (fabsf(this->actor.world.pos.y - this->unk_21C.y) > 10.0f) {
+ Math_SmoothStepToS(&this->actor.world.rot.x, Math_Vec3f_Pitch(&this->actor.world.pos, &this->unk_21C) * 0.3f,
+ 20, 5000, 500);
+ } else {
+ Math_SmoothStepToS(&this->actor.world.rot.x, 0, 20, 5000, 500);
+ }
+
+ x = this->actor.world.pos.x - this->unk_21C.x;
+ y = this->actor.world.pos.y - this->unk_21C.y;
+ z = this->actor.world.pos.z - this->unk_21C.z;
+ sqrtXYZ = sqrtf(SQ(x) + SQ(y) + SQ(z));
+
+ if (sqrtXYZ < (Rand_ZeroFloat(20.0f) + 15.0f)) {
+ this->unk_1D0++;
+ Math_Vec3f_Copy(&this->unk_228, &this->actor.world.pos);
+ if (this->unk_1D0 >= this->path->count) {
+ this->unk_1E0 = 2;
+ func_80A74888(this);
+ }
+ }
+
+ this->unk_1EE = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_21C);
+ func_80A7436C(this, this->unk_1EE);
+}
+
+void func_80A74888(EnPr2* this) {
+ func_80A74510(this, 0);
+ this->unk_1DA = 2;
+ this->unk_1D8 = 0;
+ Math_Vec3f_Copy(&this->unk_21C, &this->unk_228);
+ this->unk_1D4 = 1;
+ this->actionFunc = func_80A748E8;
+}
+
+void func_80A748E8(EnPr2* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+ f32 temp_f12;
+ f32 temp_f2;
+ f32 sqrtXZ;
+ s32 sp4C = false;
+ s32 sp48 = false;
+ Vec3f sp3C;
+
+ Math_ApproachF(&this->unk_204, 0.02f, 0.1f, 0.005f);
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PIRANHA_EXIST - SFX_FLAG);
+
+ if (fabsf(this->actor.world.rot.y - this->unk_1EE) < 200.0f) {
+ sp48 = true;
+ SkelAnime_Update(&this->skelAnime);
+ }
+
+ if (this->unk_1F4 != 255) {
+ this->actor.speedXZ = 0.0f;
+ Math_SmoothStepToS(&this->unk_1F4, 0, 1, 30, 100);
+ if (this->unk_1F4 < 2) {
+ Actor_MarkForDeath(&this->actor);
+ }
+ } else {
+ switch (this->unk_1E0) {
+ case 1:
+ if (this->unk_1DC == 0) {
+ sp4C = true;
+ func_80A74DEC(this, globalCtx);
+ } else if (!func_80A7429C(this, globalCtx) && (this->unk_1F4 == 255)) {
+ this->unk_1F4 = 254;
+ }
+ break;
+
+ case 2:
+ if (this->unk_1DE == 0) {
+ temp_f2 = player->actor.world.pos.x - this->unk_228.x;
+ temp_f12 = player->actor.world.pos.z - this->unk_228.z;
+ sqrtXZ = sqrtf(SQ(temp_f2) + SQ(temp_f12));
+
+ if (sp48 && (player->stateFlags1 & 0x8000000) && (sqrtXZ < this->unk_208)) {
+ sp4C = true;
+ func_80A74DEC(this, globalCtx);
+ }
+ } else {
+ temp_f2 = this->actor.world.pos.x - this->unk_228.x;
+ temp_f12 = this->actor.world.pos.z - this->unk_228.z;
+ sqrtXZ = sqrtf(SQ(temp_f2) + SQ(temp_f12));
+
+ if (sqrtXZ > 20.0f) {
+ this->unk_1DE = 5;
+ sp4C = true;
+ this->unk_1DC = 0;
+ Math_Vec3f_Copy(&this->unk_21C, &this->unk_228);
+ Math_ApproachF(&this->actor.speedXZ, 3.0f, 0.3f, 0.2f);
+ }
+ }
+ break;
+ }
+
+ if (!sp4C) {
+ this->unk_21C.y = this->actor.world.pos.y;
+ if (this->unk_1DA != 0) {
+ if ((Rand_ZeroOne() < 0.3f) && !this->unk_1D6) {
+ this->unk_1D6 = true;
+ }
+
+ Math_ApproachZeroF(&this->actor.speedXZ, 0.1f, 0.2f);
+
+ if (this->unk_1DA == 1) {
+ this->unk_1D8 = Rand_S16Offset(100, 100);
+ Math_Vec3f_Copy(&sp3C, &this->unk_228);
+ sp3C.x += randPlusMinusPoint5Scaled(300.0f);
+ sp3C.z += randPlusMinusPoint5Scaled(300.0f);
+ Math_Vec3f_Copy(&this->unk_21C, &sp3C);
+ }
+ } else {
+ Math_ApproachF(&this->actor.speedXZ, 2.0f, 0.3f, 0.2f);
+ Math_Vec3f_Copy(&sp3C, &this->actor.world.pos);
+ sp3C.x += Math_SinS(this->actor.world.rot.y) * 20.0f;
+ sp3C.z += Math_CosS(this->actor.world.rot.y) * 20.0f;
+ if (fabsf(this->actor.world.rot.y - this->unk_1EE) < 100.0f) {
+ if (BgCheck_SphVsFirstPoly(&globalCtx->colCtx, &sp3C, 20.0f) || (this->actor.bgCheckFlags & 8)) {
+ this->unk_1DC = 0;
+ this->unk_1F2++;
+ Math_Vec3f_Copy(&this->unk_21C, &this->unk_228);
+ if (this->unk_1F2 > 10) {
+ this->unk_1F0 += 0x2000;
+ }
+ } else {
+ Math_SmoothStepToS(&this->unk_1F0, 0, 1, 1000, 100);
+ this->unk_1F2 = 0;
+ }
+ }
+
+ if ((this->unk_1D8 == 0) || ((fabsf(this->unk_21C.x - this->actor.world.pos.x) < 10.0f) &&
+ (fabsf(this->unk_21C.z - this->actor.world.pos.z) < 10.0f))) {
+ this->unk_1DA = Rand_S16Offset(20, 30);
+ }
+ }
+ }
+
+ if (this->unk_1DA == 0) {
+ this->unk_1EE = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_21C) + this->unk_1F0;
+ func_80A7436C(this, this->unk_1EE);
+ }
+ }
+}
+
+void func_80A74DEC(EnPr2* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+
+ this->unk_1F0 = 0;
+ func_80A74510(this, 1);
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PIRANHA_ATTACK);
+ Math_Vec3f_Copy(&this->unk_21C, &player->actor.world.pos);
+
+ this->unk_1EE = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_21C);
+ this->unk_20C = Rand_ZeroFloat(30.0f);
+ this->unk_1DC = 0;
+ this->unk_1D8 = 70;
+ this->unk_1D4 = 2;
+ this->actionFunc = func_80A74E90;
+}
+
+void func_80A74E90(EnPr2* this, GlobalContext* globalCtx) {
+ Player* player = GET_PLAYER(globalCtx);
+ WaterBox* sp40;
+
+ Math_ApproachF(&this->unk_204, 0.02f, 0.1f, 0.005f);
+ if ((this->unk_1D8 == 0) || !(player->stateFlags1 & 0x8000000) || (this->unk_1E0 == 0)) {
+ func_80A74888(this);
+ return;
+ }
+
+ if (this->unk_1F4 != 255) {
+ this->actor.speedXZ = 0.0f;
+ Math_SmoothStepToS(&this->unk_1F4, 0, 1, 30, 100);
+ if (this->unk_1F4 < 2) {
+ Actor_MarkForDeath(&this->actor);
+ }
+ } else {
+ SkelAnime_Update(&this->skelAnime);
+
+ if ((this->unk_1DC == 0) && (fabsf(this->actor.world.rot.y - this->unk_1EE) < 200.0f)) {
+ Math_Vec3f_Copy(&this->unk_21C, &player->actor.world.pos);
+ }
+
+ if ((Rand_ZeroOne() < 0.3f) && !this->unk_1D6) {
+ this->unk_1D6 = true;
+ this->unk_20C = Rand_ZeroFloat(30.0f);
+ }
+
+ this->unk_21C.y = player->actor.world.pos.y + 30.0f + this->unk_20C;
+ Math_ApproachF(&this->actor.speedXZ, 5.0f, 0.3f, 1.0f);
+ this->unk_1F0 = 0;
+
+ if (this->unk_1E0 == 2) {
+ f32 temp_f2 = this->actor.world.pos.x - this->unk_228.x;
+ f32 temp_f12 = this->actor.world.pos.z - this->unk_228.z;
+ f32 sqrtXZ = sqrtf(SQ(temp_f2) + SQ(temp_f12));
+
+ if (this->unk_208 < sqrtXZ) {
+ this->unk_1DE = 20;
+ func_80A74888(this);
+ return;
+ }
+ } else {
+ Math_Vec3f_Copy(&this->unk_228, &this->actor.world.pos);
+ }
+
+ if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z,
+ &this->unk_200, &sp40)) {
+ if ((this->unk_200 - 40.0f) < this->unk_21C.y) {
+ this->unk_21C.y = this->unk_200 - 40.0f;
+ }
+ }
+
+ if ((this->unk_1E0 == 1) && !func_80A7429C(this, globalCtx)) {
+ if (this->unk_1F4 == 255) {
+ this->unk_1F4 = 254;
+ }
+ } else {
+ if (this->collider.base.atFlags & AT_HIT) {
+ this->unk_1DC = Rand_S16Offset(30, 30);
+ this->unk_1D8 = 100;
+ if (this->unk_1E0 != 2) {
+ func_80A74888(this);
+ }
+ }
+ this->unk_1EE = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_21C);
+ func_80A7436C(this, this->unk_1EE);
+ }
+ }
+}
+
+void func_80A751B4(EnPr2* this) {
+ this->unk_1EC = 0;
+ this->actor.flags |= ACTOR_FLAG_8000000;
+ this->actor.flags &= ~ACTOR_FLAG_1;
+ if (this->unk_1E0 < 10) {
+ func_80A74510(this, 2);
+ } else {
+ this->unk_1F8 = Animation_GetLastFrame(&object_pr_Anim_003904);
+ Animation_Change(&this->skelAnime, &object_pr_Anim_003904, 1.0f, this->unk_1F8, this->unk_1F8, 2, 0.0f);
+ this->unk_1D8 = Rand_S16Offset(20, 30);
+ this->unk_1E4 = 0x4000;
+ if (Rand_ZeroOne() < 0.5f) {
+ this->unk_1E4 = -0x4000;
+ }
+ this->unk_1E6 = this->actor.world.rot.y;
+ this->actor.shape.rot.x = this->actor.world.rot.x;
+ this->actor.shape.rot.y = this->actor.world.rot.y;
+ this->actor.shape.rot.z = this->actor.world.rot.z;
+ this->unk_1D8 = 30;
+ this->actor.speedXZ = Rand_ZeroFloat(0.5f);
+ this->actor.world.rot.y = randPlusMinusPoint5Scaled(0x8000);
+ }
+ Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 10);
+ this->unk_1D4 = 3;
+ this->actionFunc = func_80A75310;
+}
+
+void func_80A75310(EnPr2* this, GlobalContext* globalCtx) {
+ s32 temp;
+ f32 frame;
+ WaterBox* sp74;
+
+ SkelAnime_Update(&this->skelAnime);
+ if (this->unk_1E0 < 10) {
+ s32 i;
+
+ frame = this->skelAnime.curFrame;
+
+ if (this->unk_1F8 <= frame) {
+ for (i = 0; i < ARRAY_COUNT(this->unk_234); i++) {
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_PR2, this->unk_234[i].x, this->unk_234[i].y,
+ this->unk_234[i].z, this->actor.world.rot.x, this->actor.world.rot.y,
+ this->actor.world.rot.z, i + 10);
+ }
+
+ Actor_MarkForDeath(&this->actor);
+ return;
+ }
+ } else {
+ Vec3f sp64;
+
+ temp = false;
+ Math_SmoothStepToS(&this->actor.shape.rot.x, 0, 5, 10000, 1000);
+ Math_SmoothStepToS(&this->actor.shape.rot.z, this->unk_1E4, 5, 10000, 1000);
+ Math_SmoothStepToS(&this->actor.shape.rot.y, this->unk_1E6, 5, 10000, 1000);
+
+ if ((Rand_ZeroOne() < 0.3f) && !this->unk_1D6) {
+ this->unk_1D6 = true;
+ }
+
+ if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z,
+ &this->unk_200, &sp74)) {
+ frame = this->unk_200 - 15.0f;
+
+ if (frame <= this->actor.world.pos.y) {
+ temp = true;
+ } else {
+ Math_ApproachF(&this->actor.world.pos.y, frame, 0.3f, 1.0f);
+ }
+ }
+
+ if ((this->unk_1D8 == 0) || temp) {
+ s32 i;
+
+ Math_SmoothStepToS(&this->unk_1F4, 0, 1, 15, 50);
+
+ if (this->unk_1F4 < 2) {
+ for (i = 0; i < 10; i++) {
+ Math_Vec3f_Copy(&sp64, &this->actor.world.pos);
+
+ sp64.x += randPlusMinusPoint5Scaled(20.0f);
+ sp64.y += randPlusMinusPoint5Scaled(5.0f);
+ sp64.z += randPlusMinusPoint5Scaled(20.0f);
+ frame = Rand_ZeroFloat(0.03f) + 0.07f;
+
+ EffectSsBubble_Spawn(globalCtx, &sp64, 0.0f, 5.0f, 5.0f, frame);
+ }
+
+ Actor_MarkForDeath(&this->actor);
+ }
+ }
+ }
+}
+
+void func_80A755D8(EnPr2* this, GlobalContext* globalCtx) {
+ s32 temp_v0;
+
+ if (this->collider.base.acFlags & AC_HIT) {
+ Actor_ApplyDamage(&this->actor);
+ if ((this->actor.colChkInfo.health <= 0) && (this->unk_1D4 != 3)) {
+ Enemy_StartFinishingBlow(globalCtx, &this->actor);
+ this->actor.speedXZ = 0.0f;
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PIRANHA_DEAD);
+
+ if (this->unk_218 >= 0) {
+ Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.world.pos, D_80A75C3C[this->unk_218]);
+ }
+
+ this->actor.colChkInfo.health = 0;
+ func_80A751B4(this);
+ }
+ }
+
+ if (this->collider.base.atFlags & AT_BOUNCED) {
+ this->actor.speedXZ = -10.0f;
+ }
+}
+
+void EnPr2_Update(Actor* thisx, GlobalContext* globalCtx) {
+ EnPr2* this = THIS;
+ f32 rand;
+
+ if (thisx) {}
+
+ Actor_SetScale(&this->actor, this->unk_204);
+
+ this->actionFunc(this, globalCtx);
+
+ if (this->unk_1DA != 0) {
+ this->unk_1DA--;
+ }
+
+ if (this->unk_1D8 != 0) {
+ this->unk_1D8--;
+ }
-extern DamageTable D_80A75BC0;
-extern ColliderCylinderInit D_80A75BE0;
+ if (this->unk_1DC != 0) {
+ this->unk_1DC--;
+ }
-extern UNK_TYPE D_06003904;
-extern UNK_TYPE D_06004340;
+ if (this->unk_1DE != 0) {
+ this->unk_1DE--;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/EnPr2_Init.s")
+ Actor_SetFocus(&this->actor, 10.0f);
+ func_80A755D8(this, globalCtx);
+ Actor_MoveWithGravity(&this->actor);
+ Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0, 10.0f, 20.0f, 0x1F);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/EnPr2_Destroy.s")
+ if (this->unk_1D6) {
+ s32 i;
+ Vec3f sp58;
+ f32 rand;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A7429C.s")
+ Math_Vec3f_Copy(&sp58, &this->unk_270);
+ this->unk_1D6 = false;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A7436C.s")
+ sp58.x += randPlusMinusPoint5Scaled(20.0f);
+ sp58.y += randPlusMinusPoint5Scaled(5.0f);
+ sp58.z += randPlusMinusPoint5Scaled(20.0f);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A74510.s")
+ for (i = 0; i < 2; i++) {
+ rand = Rand_ZeroFloat(0.03f) + 0.07f;
+ EffectSsBubble_Spawn(globalCtx, &sp58, 0, 5.0f, 5.0f, rand);
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A745C4.s")
+ if ((this->unk_1F4 == 255) && (this->unk_1E0 < 10)) {
+ this->actor.shape.rot.x = this->actor.world.rot.x;
+ this->actor.shape.rot.y = this->actor.world.rot.y;
+ this->actor.shape.rot.z = this->actor.world.rot.z;
+ if (this->unk_1D4 != 3) {
+ Collider_UpdateCylinder(&this->actor, &this->collider);
+ CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A745FC.s")
+s32 func_80A758E8(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) {
+ EnPr2* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A74888.s")
+ if (this->unk_1E0 < 10) {
+ if (limbIndex == 2) {
+ rot->y += (s16)this->unk_1FC * -1;
+ }
+ } else if ((limbIndex + 10) != this->unk_1E0) {
+ *dList = NULL;
+ }
+ return false;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A748E8.s")
+void func_80A75950(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
+ EnPr2* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A74DEC.s")
+ if (this->unk_1E0 < 10) {
+ if (limbIndex == 2) {
+ Matrix_InsertTranslation(0.0f, 0.0f, 0.0f, MTXMODE_APPLY);
+ Matrix_GetStateTranslation(&this->unk_270);
+ }
+ Matrix_GetStateTranslation(&this->unk_234[limbIndex]);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A74E90.s")
+s32 func_80A759D8(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx,
+ Gfx** gfx) {
+ EnPr2* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A751B4.s")
+ if (this->unk_1E0 < 10) {
+ if (limbIndex == 2) {
+ rot->y += (s16)this->unk_1FC * -1;
+ }
+ } else if ((limbIndex + 10) != this->unk_1E0) {
+ *dList = NULL;
+ }
+ return false;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A75310.s")
+void EnPr2_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ EnPr2* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A755D8.s")
+ OPEN_DISPS(globalCtx->state.gfxCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/EnPr2_Update.s")
+ func_8012C28C(globalCtx->state.gfxCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A758E8.s")
+ if (this->unk_1F4 == 255) {
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->unk_1EC, this->unk_1EC, this->unk_1EC, 255);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, this->unk_1F4);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A75950.s")
+ Scene_SetRenderModeXlu(globalCtx, 0, 1);
+ SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable,
+ this->skelAnime.dListCount, func_80A758E8, func_80A75950, &this->actor);
+ } else {
+ gDPPipeSync(POLY_XLU_DISP++);
+ gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->unk_1F4);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A759D8.s")
+ Scene_SetRenderModeXlu(globalCtx, 1, 2);
+ POLY_XLU_DISP =
+ SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable,
+ this->skelAnime.dListCount, func_80A759D8, NULL, &this->actor, POLY_XLU_DISP);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/EnPr2_Draw.s")
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+}
diff --git a/src/overlays/actors/ovl_En_Pr2/z_en_pr2.h b/src/overlays/actors/ovl_En_Pr2/z_en_pr2.h
index 68fb09b82..4ae14db77 100644
--- a/src/overlays/actors/ovl_En_Pr2/z_en_pr2.h
+++ b/src/overlays/actors/ovl_En_Pr2/z_en_pr2.h
@@ -7,11 +7,48 @@ struct EnPr2;
typedef void (*EnPr2ActionFunc)(struct EnPr2*, GlobalContext*);
+#define ENPR2_GET_F(thisx) ((thisx)->params & 0xF)
+#define ENPR2_GET_FF0(thisx) (((thisx)->params >> 4) & 0xFF)
+
typedef struct EnPr2 {
/* 0x0000 */ Actor actor;
- /* 0x0144 */ char unk_144[0x80];
+ /* 0x0144 */ SkelAnime skelAnime;
+ /* 0x0188 */ Vec3s jointTable[5];
+ /* 0x01A6 */ Vec3s morphtable[5];
/* 0x01C4 */ EnPr2ActionFunc actionFunc;
- /* 0x01C8 */ char unk_1C8[0x100];
+ /* 0x01C8 */ s16 unk_1C8;
+ /* 0x01CC */ Path* path;
+ /* 0x01D0 */ s32 unk_1D0;
+ /* 0x01D4 */ s16 unk_1D4;
+ /* 0x01D6 */ s16 unk_1D6;
+ /* 0x01D8 */ s16 unk_1D8;
+ /* 0x01DA */ s16 unk_1DA;
+ /* 0x01DC */ s16 unk_1DC;
+ /* 0x01DE */ s16 unk_1DE;
+ /* 0x01E0 */ s16 unk_1E0;
+ /* 0x01E2 */ UNK_TYPE1 unk1E2[2];
+ /* 0x01E4 */ s16 unk_1E4;
+ /* 0x01E6 */ s16 unk_1E6;
+ /* 0x01E8 */ UNK_TYPE1 unk1E8[4];
+ /* 0x01EC */ s16 unk_1EC;
+ /* 0x01EE */ s16 unk_1EE;
+ /* 0x01F0 */ s16 unk_1F0;
+ /* 0x01F2 */ s16 unk_1F2;
+ /* 0x01F4 */ s16 unk_1F4;
+ /* 0x01F8 */ f32 unk_1F8;
+ /* 0x01FC */ f32 unk_1FC;
+ /* 0x0200 */ f32 unk_200;
+ /* 0x0204 */ f32 unk_204;
+ /* 0x0208 */ f32 unk_208;
+ /* 0x020C */ f32 unk_20C;
+ /* 0x0210 */ s32 unk_210;
+ /* 0x0214 */ UNK_TYPE1 unk214[4];
+ /* 0x0218 */ s32 unk_218;
+ /* 0x021C */ Vec3f unk_21C;
+ /* 0x0228 */ Vec3f unk_228;
+ /* 0x0234 */ Vec3f unk_234[5];
+ /* 0x0270 */ Vec3f unk_270;
+ /* 0x027C */ ColliderCylinder collider;
} EnPr2; // size = 0x2C8
extern const ActorInit En_Pr2_InitVars;