From af1a4b01ef376f2c0a66ec4a7660395716ee7f60 Mon Sep 17 00:00:00 2001 From: Maide <34639600+Kelebek1@users.noreply.github.com> Date: Thu, 26 May 2022 02:40:34 +0100 Subject: [PATCH] En_Scopecrow (#808) * En_Scopecrow * PR --- spec | 3 +- .../actors/ovl_En_Scopecrow/z_en_scopecrow.c | 324 ++++++++++++++++-- .../actors/ovl_En_Scopecrow/z_en_scopecrow.h | 21 +- undefined_syms.txt | 5 - 4 files changed, 318 insertions(+), 35 deletions(-) diff --git a/spec b/spec index 1a733af09a..137ff62490 100644 --- a/spec +++ b/spec @@ -4546,8 +4546,7 @@ beginseg name "ovl_En_Scopecrow" compress include "build/src/overlays/actors/ovl_En_Scopecrow/z_en_scopecrow.o" - include "build/data/ovl_En_Scopecrow/ovl_En_Scopecrow.data.o" - include "build/data/ovl_En_Scopecrow/ovl_En_Scopecrow.reloc.o" + include "build/src/overlays/actors/ovl_En_Scopecrow/ovl_En_Scopecrow_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Scopecrow/z_en_scopecrow.c b/src/overlays/actors/ovl_En_Scopecrow/z_en_scopecrow.c index bf0b6a839a..5743f4a48e 100644 --- a/src/overlays/actors/ovl_En_Scopecrow/z_en_scopecrow.c +++ b/src/overlays/actors/ovl_En_Scopecrow/z_en_scopecrow.c @@ -18,7 +18,6 @@ void EnScopecrow_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80BCD590(EnScopecrow* this, GlobalContext* globalCtx); void func_80BCD640(EnScopecrow* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Scopecrow_InitVars = { ACTOR_EN_SCOPECROW, ACTORCAT_NPC, @@ -31,47 +30,324 @@ const ActorInit En_Scopecrow_InitVars = { (ActorFunc)EnScopecrow_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_80BCDB70[1] = { +static ColliderJntSphElementInit sJntSphElementsInit[] = { { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 1, { { 0, 60, 0 }, 50 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80BCDB94 = { - { COLTYPE_HIT3, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 1, D_80BCDB70, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_HIT3, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(sJntSphElementsInit), + sJntSphElementsInit, }; -#endif +void func_80BCD000(EnScopecrow* this, GlobalContext* globalCtx) { + this->collider.elements->dim.worldSphere.center.x = this->actor.world.pos.x; + this->collider.elements->dim.worldSphere.center.y = + sJntSphInit.elements[0].dim.modelSphere.center.y + this->actor.world.pos.y; + this->collider.elements->dim.worldSphere.center.z = this->actor.world.pos.z; -extern ColliderJntSphElementInit D_80BCDB70[1]; -extern ColliderJntSphInit D_80BCDB94; + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} -extern UNK_TYPE D_060010C0; +s32 func_80BCD09C(s16 arg0) { + switch (arg0) { + case 0: + if (gSaveContext.save.weekEventReg[53] & 4) { + return true; + } + return false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/func_80BCD000.s") + case 1: + if (gSaveContext.save.weekEventReg[53] & 0x80) { + return true; + } + return false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/func_80BCD09C.s") + case 2: + if (gSaveContext.save.weekEventReg[54] & 1) { + return true; + } + return false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/func_80BCD1AC.s") + case 3: + if (gSaveContext.save.weekEventReg[54] & 2) { + return true; + } + return false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/func_80BCD2BC.s") + case 4: + if (gSaveContext.save.weekEventReg[54] & 4) { + return true; + } + return false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/func_80BCD334.s") + case 5: + if (gSaveContext.save.weekEventReg[54] & 8) { + return true; + } + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/func_80BCD4D0.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/func_80BCD590.s") +s32 func_80BCD1AC(s16 arg0) { + switch (arg0) { + case 0: + if (!(gSaveContext.save.weekEventReg[53] & 4)) { + gSaveContext.save.weekEventReg[53] |= 4; + return true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/func_80BCD640.s") + case 1: + if (!(gSaveContext.save.weekEventReg[53] & 0x80)) { + gSaveContext.save.weekEventReg[53] |= 0x80; + return true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/EnScopecrow_Init.s") + case 2: + if (!(gSaveContext.save.weekEventReg[54] & 1)) { + gSaveContext.save.weekEventReg[54] |= 1; + return true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/EnScopecrow_Destroy.s") + case 3: + if (!(gSaveContext.save.weekEventReg[54] & 2)) { + gSaveContext.save.weekEventReg[54] |= 2; + return true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/EnScopecrow_Update.s") + case 4: + if (!(gSaveContext.save.weekEventReg[54] & 4)) { + gSaveContext.save.weekEventReg[54] |= 4; + return true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/EnScopecrow_Draw.s") + case 5: + if (!(gSaveContext.save.weekEventReg[54] & 8)) { + gSaveContext.save.weekEventReg[54] |= 8; + return true; + } + break; + } + + return false; +} + +void func_80BCD2BC(EnScopecrow* this, GlobalContext* globalCtx) { + Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ACTOR_EN_SC_RUPPE, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, this->actor.shape.rot.x, + this->actor.shape.rot.y, this->actor.shape.rot.z, this->actor.params, + this->actor.cutscene, this->actor.unk20, NULL); +} + +s32 func_80BCD334(EnScopecrow* this, Path* path, s32 pointIndex) { + Vec3s* points = Lib_SegmentedToVirtual(path->points); + s32 sp58 = path->count; + s32 index = pointIndex; + s32 ret = false; + f32 phi_fa0; + f32 phi_fa1; + Vec3f sp3C; + Vec3f sp30; + + Math_Vec3s_ToVec3f(&sp30, &points[index]); + + if (index == 0) { + phi_fa0 = points[1].x - points[0].x; + phi_fa1 = points[1].z - points[0].z; + } else if ((sp58 - 1) == index) { + phi_fa0 = points[sp58 - 1].x - points[sp58 - 2].x; + phi_fa1 = points[sp58 - 1].z - points[sp58 - 2].z; + } else { + phi_fa0 = points[index + 1].x - points[index - 1].x; + phi_fa1 = points[index + 1].z - points[index - 1].z; + } + + func_8017B7F8(&sp30, RADF_TO_BINANG(func_80086B30(phi_fa0, phi_fa1)), &sp3C.z, &sp3C.y, &sp3C.x); + + if (((this->actor.world.pos.x * sp3C.z) + (sp3C.y * this->actor.world.pos.z) + sp3C.x) > 0.0f) { + ret = true; + } + return ret; +} + +f32 func_80BCD4D0(Path* path, s32 count, Vec3f* arg2, Vec3s* arg3) { + Vec3s* temp; + Vec3f sp20; + Vec3s* points; + + if (path != NULL) { + temp = Lib_SegmentedToVirtual(path->points); + points = temp + count; + + sp20.x = points->x; + sp20.y = points->y; + sp20.z = points->z; + } + + arg3->y = Math_Vec3f_Yaw(arg2, &sp20); + arg3->x = Math_Vec3f_Pitch(arg2, &sp20); + return sp20.y - arg2->y; +} + +void func_80BCD590(EnScopecrow* this, GlobalContext* globalCtx) { + Vec3f sp1C; + + func_80169474(globalCtx, &this->actor.world.pos, &sp1C); + + if ((sp1C.x >= 130.0f) && (sp1C.x < 190.0f) && (sp1C.y >= 90.0f) && (sp1C.y < 150.0f)) { + this->actor.draw = EnScopecrow_Draw; + this->actionFunc = func_80BCD640; + } +} + +void func_80BCD640(EnScopecrow* this, GlobalContext* globalCtx) { + Vec3s sp30; + + if (this->path != NULL) { + func_80BCD4D0(this->path, this->unk_1FC, &this->actor.world.pos, &sp30); + if (this->actor.bgCheckFlags & 8) { + sp30.y = this->actor.wallYaw; + } + + Math_SmoothStepToS(&this->actor.world.rot.y, sp30.y, 4, 0x3E8, 1); + this->actor.shape.rot.y = this->actor.world.rot.y; + Math_SmoothStepToS(&this->actor.world.rot.x, -sp30.x, 4, 0x3E8, 1); + + if (func_80BCD334(this, this->path, this->unk_1FC)) { + if ((this->unk_1FC == this->unk_262) && func_80BCD1AC(this->unk_260)) { + func_80BCD2BC(this, globalCtx); + } + + if (this->unk_1FC >= (this->path->count - 1)) { + Actor_MarkForDeath(&this->actor); + } else { + this->unk_1FC++; + } + } + } + + Math_ApproachF(&this->actor.speedXZ, 6.0f, 0.2f, 1.0f); + Actor_MoveWithoutGravity(&this->actor); + this->unk_264 += 0x1000; + this->actor.shape.yOffset = Math_SinS(this->unk_264) * 500.0f; +} + +void EnScopecrow_Init(Actor* thisx, GlobalContext* globalCtx) { + EnScopecrow* this = THIS; + Vec3s* temp; + CollisionPoly* sp4C; + Vec3s* points; + Vec3f sp3C; + + this->unk_260 = ENSCOPECROW_GET_1F(&this->actor); + if ((this->unk_260 < 0) || (this->unk_260 >= 6)) { + this->unk_260 = 0; + } + + if (func_80BCD09C(this->unk_260)) { + this->path = SubS_GetPathByIndex(globalCtx, ENSCOPECROW_GET_PATH(&this->actor), 0x3F); + this->unk_262 = ENSCOPECROW_GET_3E0(&this->actor); + + if (this->path != NULL) { + if ((this->unk_262 <= 0) || ((this->path->count - 1) < this->unk_262)) { + this->unk_262 = this->path->count - 1; + } + + temp = Lib_SegmentedToVirtual(this->path->points); + points = temp + this->unk_262; + + sp3C.x = points->x; + sp3C.y = points->y; + sp3C.z = points->z; + + this->actor.world.pos = sp3C; + this->actor.world.pos.y = BgCheck_EntityRaycastFloor1(&globalCtx->colCtx, &sp4C, &sp3C); + if (this->actor.world.pos.y == BGCHECK_Y_MIN) { + Actor_MarkForDeath(&this->actor); + } + + func_80BCD2BC(this, globalCtx); + Actor_MarkForDeath(&this->actor); + return; + } + + Actor_MarkForDeath(&this->actor); + return; + } + + if (globalCtx->actorCtx.unk5 & 2) { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGuaySkel, &gGuayFlyAnim, this->jointTable, this->morphTable, + OBJECT_CROW_LIMB_MAX); + ActorShape_Init(&this->actor.shape, 2000.0f, ActorShadow_DrawCircle, 20.0f); + + Collider_InitJntSph(globalCtx, &this->collider); + Collider_InitAndSetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements); + this->collider.elements->dim.worldSphere.radius = sJntSphInit.elements[0].dim.modelSphere.radius; + + Actor_SetScale(&this->actor, 0.03f); + this->path = SubS_GetPathByIndex(globalCtx, ENSCOPECROW_GET_PATH(&this->actor), 0x3F); + this->unk_262 = ENSCOPECROW_GET_3E0(&this->actor); + + if (this->path != NULL) { + if ((this->unk_262 <= 0) || ((this->path->count - 1) < this->unk_262)) { + this->unk_262 = this->path->count - 1; + } + this->actor.draw = NULL; + this->actor.gravity = 0.0f; + this->actionFunc = func_80BCD590; + return; + } + + Actor_MarkForDeath(&this->actor); + return; + } + + Actor_MarkForDeath(&this->actor); +} + +void EnScopecrow_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnScopecrow* this = THIS; + + Collider_DestroyJntSph(globalCtx, &this->collider); +} + +void EnScopecrow_Update(Actor* thisx, GlobalContext* globalCtx) { + EnScopecrow* this = THIS; + + this->actionFunc(this, globalCtx); + + SkelAnime_Update(&this->skelAnime); + func_80BCD000(this, globalCtx); +} + +void EnScopecrow_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnScopecrow* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + NULL, NULL, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Scopecrow/z_en_scopecrow.h b/src/overlays/actors/ovl_En_Scopecrow/z_en_scopecrow.h index 2b5b38eae0..72469bd755 100644 --- a/src/overlays/actors/ovl_En_Scopecrow/z_en_scopecrow.h +++ b/src/overlays/actors/ovl_En_Scopecrow/z_en_scopecrow.h @@ -2,16 +2,29 @@ #define Z_EN_SCOPECROW_H #include "global.h" +#include "objects/object_crow/object_crow.h" struct EnScopecrow; typedef void (*EnScopecrowActionFunc)(struct EnScopecrow*, GlobalContext*); +#define ENSCOPECROW_GET_1F(thisx) ((thisx)->params & 0x1F) +#define ENSCOPECROW_GET_3E0(thisx) (((thisx)->params & 0x3E0) >> 5) +#define ENSCOPECROW_GET_PATH(thisx) (((thisx)->params & 0xFC00) >> 0xA) + typedef struct EnScopecrow { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; - /* 0x0188 */ EnScopecrowActionFunc actionFunc; - /* 0x018C */ char unk_18C[0xDC]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ EnScopecrowActionFunc actionFunc; + /* 0x18C */ Vec3s jointTable[OBJECT_CROW_LIMB_MAX]; + /* 0x1C2 */ Vec3s morphTable[OBJECT_CROW_LIMB_MAX]; + /* 0x1F8 */ Path* path; + /* 0x1FC */ s32 unk_1FC; + /* 0x200 */ ColliderJntSph collider; + /* 0x220 */ ColliderJntSphElement colliderElements[1]; + /* 0x260 */ s16 unk_260; + /* 0x262 */ s16 unk_262; + /* 0x264 */ s16 unk_264; } EnScopecrow; // size = 0x268 extern const ActorInit En_Scopecrow_InitVars; diff --git a/undefined_syms.txt b/undefined_syms.txt index 91ead11f3b..f24e3b6274 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -1444,11 +1444,6 @@ D_06003A20 = 0x06003A20; D_0600D768 = 0x0600D768; D_0600D8D8 = 0x0600D8D8; -// ovl_En_Scopecrow - -D_060000F0 = 0x060000F0; -D_060010C0 = 0x060010C0; - // ovl_En_Slime D_060004C0 = 0x060004C0;