diff --git a/linker_scripts/code_script.txt b/linker_scripts/code_script.txt index 523720cc58..3907f86562 100644 --- a/linker_scripts/code_script.txt +++ b/linker_scripts/code_script.txt @@ -7063,9 +7063,9 @@ SECTIONS ovl_Bg_Kin2_Fence : AT(RomLocation) { build/src/overlays/actors/ovl_Bg_Kin2_Fence/z_bg_kin2_fence.o(.text) - build/asm/overlays/ovl_Bg_Kin2_Fence_data.o(.data) + build/src/overlays/actors/ovl_Bg_Kin2_Fence/z_bg_kin2_fence.o(.data) build/src/overlays/actors/ovl_Bg_Kin2_Fence/z_bg_kin2_fence.o(.rodata) - build/asm/overlays/ovl_Bg_Kin2_Fence_rodata.o(.rodata) + build/src/overlays/actors/ovl_Bg_Kin2_Fence/z_bg_kin2_fence_overlay.o(.ovl) } SegmentEnd = .; SegmentSize = SegmentEnd - SegmentStart; diff --git a/linker_scripts/object_script.txt b/linker_scripts/object_script.txt index 734e0ad0f5..60774d00df 100644 --- a/linker_scripts/object_script.txt +++ b/linker_scripts/object_script.txt @@ -142,6 +142,10 @@ D_060005F8 = 0x060005F8; D_06013328 = 0x06013328; D_0600CC94 = 0x0600CC94; +/* z_bg_kin2_fence */ +D_06000828 = 0x06000828; +D_06000908 = 0x06000908; + /* bg_ikana_shutter */ D_06000F28 = 0x06000F28; D_06000CE8 = 0x06000CE8; diff --git a/src/overlays/actors/ovl_Bg_Kin2_Fence/z_bg_kin2_fence.c b/src/overlays/actors/ovl_Bg_Kin2_Fence/z_bg_kin2_fence.c index cde65ef707..c9db2f0095 100644 --- a/src/overlays/actors/ovl_Bg_Kin2_Fence/z_bg_kin2_fence.c +++ b/src/overlays/actors/ovl_Bg_Kin2_Fence/z_bg_kin2_fence.c @@ -9,7 +9,17 @@ void BgKin2Fence_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgKin2Fence_Update(Actor* thisx, GlobalContext* globalCtx); void BgKin2Fence_Draw(Actor* thisx, GlobalContext* globalCtx); -/* +void BgKin2Fence_SetupHandleMaskCode(BgKin2Fence* this); +void BgKin2Fence_HandleMaskCode(BgKin2Fence* this, GlobalContext* globalCtx); +void BgKin2Fence_SetupPlayOpenCutscene(BgKin2Fence* this); +void BgKin2Fence_PlayOpenCutscene(BgKin2Fence* this, GlobalContext* globalCtx); +void BgKin2Fence_SetupWaitBeforeOpen(BgKin2Fence* this); +void BgKin2Fence_WaitBeforeOpen(BgKin2Fence* this, GlobalContext* globalCtx); +void BgKin2Fence_SetupRaiseFence(BgKin2Fence* this); +void BgKin2Fence_RaiseFence(BgKin2Fence* this, GlobalContext* globalCtx); +void BgKin2Fence_SetupDoNothing(BgKin2Fence* this); +void BgKin2Fence_DoNothing(BgKin2Fence* this, GlobalContext* globalCtx); + const ActorInit Bg_Kin2_Fence_InitVars = { ACTOR_BG_KIN2_FENCE, ACTORCAT_BG, @@ -21,36 +31,202 @@ const ActorInit Bg_Kin2_Fence_InitVars = { (ActorFunc)BgKin2Fence_Update, (ActorFunc)BgKin2Fence_Draw }; -*/ -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Kin2_Fence_0x80B6E820/func_80B6E820.asm") +static ColliderJntSphElementInit sJntSphElementsInit[4] = { + { + { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00003820, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { 0, { { -2040, 1400, 350 }, 28 }, 100 }, + }, + { + { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00003820, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { 0, { { -1140, 1400, 350 }, 28 }, 100 }, + }, + { + { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00003820, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { 0, { { 1140, 1400, 350 }, 28 }, 100 }, + }, + { + { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00003820, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { 0, { { 2040, 1400, 350 }, 28 }, 100 }, + }, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Kin2_Fence_0x80B6E820/func_80B6E890.asm") +static ColliderJntSphInit sJntSphInit = { + { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_2, COLSHAPE_JNTSPH, }, + 4, sJntSphElementsInit, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Kin2_Fence_0x80B6E820/BgKin2Fence_Init.asm") +Vec3f eyeSparkleSpawnPositions[][2] = { { { -215.0f, 139.0f, 50.0f }, { -193.0f, 139.0f, 50.0f } }, -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Kin2_Fence_0x80B6E820/BgKin2Fence_Destroy.asm") + { { -125.0f, 139.0f, 50.0f }, { -103.0f, 139.0f, 50.0f } }, -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Kin2_Fence_0x80B6E820/func_80B6EADC.asm") + { { 103.0f, 139.0f, 50.0f }, { 125.0f, 139.0f, 50.0f } }, -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Kin2_Fence_0x80B6E820/func_80B6EAF4.asm") + { { 193.0f, 139.0f, 50.0f }, { 215.0f, 139.0f, 50.0f } } }; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Kin2_Fence_0x80B6E820/func_80B6EBF4.asm") +Color_RGBA8 primColor = { 0xFF, 0xFF, 0xFF, 0x00 }; +Color_RGBA8 envColor = { 0x00, 128, 128, 0x00 }; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Kin2_Fence_0x80B6E820/func_80B6EC08.asm") +static InitChainEntry sInitChain[] = { + ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_CONTINUE), + ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Kin2_Fence_0x80B6E820/func_80B6EC70.asm") +extern Gfx D_06000828[]; +extern CollisionHeader* D_06000908; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Kin2_Fence_0x80B6E820/func_80B6EC8C.asm") +s32 BgKin2Fence_CheckHitMask(BgKin2Fence* this) { + ColliderJntSphElement* elements = this->collider.elements; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Kin2_Fence_0x80B6E820/func_80B6ECC4.asm") + if (elements[0].info.bumperFlags & 2) { + return 0; + } + if (elements[1].info.bumperFlags & 2) { + return 1; + } + if (elements[2].info.bumperFlags & 2) { + return 2; + } + if (elements[3].info.bumperFlags & 2) { + return 3; + } + return -1; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Kin2_Fence_0x80B6E820/func_80B6ECD8.asm") +void BgKin2Fence_SpawnEyeSparkles(BgKin2Fence* this, GlobalContext* globalCtx, s32 mask) { + s32 i; + Vec3f sp58; + s32 pad[2]; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Kin2_Fence_0x80B6E820/func_80B6ED30.asm") + SysMatrix_SetStateRotationAndTranslation(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Kin2_Fence_0x80B6E820/func_80B6ED58.asm") + for (i = 0; i < 2; i++) { + SysMatrix_MultiplyVector3fByState(&eyeSparkleSpawnPositions[mask][i], &sp58); + EffectSsKiraKira_SpawnDispersed(globalCtx, &sp58, &D_801D15B0, &D_801D15B0, &primColor, &envColor, 6000, -10); + } +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Kin2_Fence_0x80B6E820/BgKin2Fence_Update.asm") +void BgKin2Fence_Init(Actor* thisx, GlobalContext* globalCtx) { + BgKin2Fence* this = THIS; + s32 i = 0; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Bg_Kin2_Fence_0x80B6E820/BgKin2Fence_Draw.asm") + Actor_ProcessInitChain(&this->dyna.actor, &sInitChain); + BcCheck3_BgActorInit(&this->dyna, 0); + BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06000908); + Collider_InitJntSph(globalCtx, &this->collider); + Collider_SetJntSph(globalCtx, &this->collider, &this->dyna.actor, &sJntSphInit, &this->colliderElements); + SysMatrix_SetStateRotationAndTranslation(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape); + Matrix_Scale(this->dyna.actor.scale.x, this->dyna.actor.scale.y, this->dyna.actor.scale.z, 1); + + for (i = 0; i < 4; i++) { + Collider_UpdateSpheres(i, &this->collider); + } + + if (Actor_GetSwitchFlag(globalCtx, this->dyna.actor.params & 0x7F)) { + BgKin2Fence_SetupDoNothing(this); + return; + } + BgKin2Fence_SetupHandleMaskCode(this); +} + +void BgKin2Fence_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgKin2Fence* this = THIS; + + BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + Collider_DestroyJntSph(globalCtx, &this->collider); +} + +void BgKin2Fence_SetupHandleMaskCode(BgKin2Fence* this) { + this->masksHit = 0; + this->actionFunc = BgKin2Fence_HandleMaskCode; +} + +void BgKin2Fence_HandleMaskCode(BgKin2Fence* this, GlobalContext* globalCtx) { + s32 hitMask; + s32 nextMask; + + if (this->collider.base.acFlags & 2) { + hitMask = BgKin2Fence_CheckHitMask(this); + if (hitMask >= 0) { + nextMask = (s8)gSaveContext.perm.spiderHouseMaskOrder[this->masksHit]; + if (hitMask == nextMask) { + play_sound(0x4807); + this->masksHit += 1; + BgKin2Fence_SpawnEyeSparkles(this, globalCtx, nextMask); + } else { + play_sound(0x4806); + this->masksHit = 0; + } + } + this->collider.base.acFlags &= 0xFFFD; + this->cooldownTimer = 5; + if (this->masksHit > 5) { + BgKin2Fence_SetupPlayOpenCutscene(this); + return; + } + } else { + if (this->cooldownTimer > 0) { + this->cooldownTimer -= 1; + return; + } + CollisionCheck_SetAC(globalCtx, &globalCtx->colCheckCtx, &this->collider); + } +} + +void BgKin2Fence_SetupPlayOpenCutscene(BgKin2Fence* this) { + this->actionFunc = BgKin2Fence_PlayOpenCutscene; +} + +void BgKin2Fence_PlayOpenCutscene(BgKin2Fence* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + Actor_SetSwitchFlag(globalCtx, this->dyna.actor.params & 0x7F); + BgKin2Fence_SetupWaitBeforeOpen(this); + return; + } + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); +} + +void BgKin2Fence_SetupWaitBeforeOpen(BgKin2Fence* this) { + this->waitBeforeOpenTimer = 14; + this->actionFunc = BgKin2Fence_WaitBeforeOpen; +} + +void BgKin2Fence_WaitBeforeOpen(BgKin2Fence* this, GlobalContext* globalCtx) { + if (this->waitBeforeOpenTimer > 0) { + this->waitBeforeOpenTimer -= 1; + } else { + BgKin2Fence_SetupRaiseFence(this); + } +} + +void BgKin2Fence_SetupRaiseFence(BgKin2Fence* this) { + this->actionFunc = BgKin2Fence_RaiseFence; +} + +void BgKin2Fence_RaiseFence(BgKin2Fence* this, GlobalContext* globalCtx) { + if (Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y + 58.0f, 5.0f)) { + BgKin2Fence_SetupDoNothing(this); + } +} +void BgKin2Fence_SetupDoNothing(BgKin2Fence* this) { + this->actionFunc = BgKin2Fence_DoNothing; + this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + 58.0f; +} + +void BgKin2Fence_DoNothing(BgKin2Fence* this, GlobalContext* globalCtx) { +} + +void BgKin2Fence_Update(Actor* thisx, GlobalContext* globalCtx) { + BgKin2Fence* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void BgKin2Fence_Draw(Actor* thisx, GlobalContext* globalCtx) { + func_800BDFC0(globalCtx, D_06000828); +} diff --git a/src/overlays/actors/ovl_Bg_Kin2_Fence/z_bg_kin2_fence.h b/src/overlays/actors/ovl_Bg_Kin2_Fence/z_bg_kin2_fence.h index e8656e68d8..0f51636dea 100644 --- a/src/overlays/actors/ovl_Bg_Kin2_Fence/z_bg_kin2_fence.h +++ b/src/overlays/actors/ovl_Bg_Kin2_Fence/z_bg_kin2_fence.h @@ -5,9 +5,16 @@ struct BgKin2Fence; +typedef void (*BgKin2FenceActionFunc)(struct BgKin2Fence*, GlobalContext*); + typedef struct BgKin2Fence { - /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x140]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ ColliderJntSph collider; + /* 0x17C */ ColliderJntSphElement colliderElements[4]; + /* 0x27C */ BgKin2FenceActionFunc actionFunc; + /* 0x280 */ s8 masksHit; + /* 0x281 */ s8 cooldownTimer; + /* 0x282 */ s8 waitBeforeOpenTimer; } BgKin2Fence; // size = 0x284 extern const ActorInit Bg_Kin2_Fence_InitVars; diff --git a/tables/functions.txt b/tables/functions.txt index fce3f4732d..96223e0248 100644 --- a/tables/functions.txt +++ b/tables/functions.txt @@ -14319,20 +14319,20 @@ 0x80B6E614:("func_80B6E614",), 0x80B6E664:("BgKin2Bombwall_Update",), 0x80B6E688:("BgKin2Bombwall_Draw",), - 0x80B6E820:("func_80B6E820",), - 0x80B6E890:("func_80B6E890",), + 0x80B6E820:("BgKin2Fence_CheckHitMask",), + 0x80B6E890:("BgKin2Fence_SpawnEyeSparkles",), 0x80B6E980:("BgKin2Fence_Init",), 0x80B6EA94:("BgKin2Fence_Destroy",), - 0x80B6EADC:("func_80B6EADC",), - 0x80B6EAF4:("func_80B6EAF4",), - 0x80B6EBF4:("func_80B6EBF4",), - 0x80B6EC08:("func_80B6EC08",), - 0x80B6EC70:("func_80B6EC70",), - 0x80B6EC8C:("func_80B6EC8C",), - 0x80B6ECC4:("func_80B6ECC4",), - 0x80B6ECD8:("func_80B6ECD8",), - 0x80B6ED30:("func_80B6ED30",), - 0x80B6ED58:("func_80B6ED58",), + 0x80B6EADC:("BgKin2Fence_SetupHandleMaskCode",), + 0x80B6EAF4:("BgKin2Fence_HandleMaskCode",), + 0x80B6EBF4:("BgKin2Fence_SetupPlayOpenCutscene",), + 0x80B6EC08:("BgKin2Fence_PlayOpenCutscene",), + 0x80B6EC70:("BgKin2Fence_SetupWaitBeforeOpen",), + 0x80B6EC8C:("BgKin2Fence_WaitBeforeOpen",), + 0x80B6ECC4:("BgKin2Fence_SetupRaiseFence",), + 0x80B6ECD8:("BgKin2Fence_RaiseFence",), + 0x80B6ED30:("BgKin2Fence_SetupDoNothing",), + 0x80B6ED58:("BgKin2Fence_DoNothing",), 0x80B6ED68:("BgKin2Fence_Update",), 0x80B6ED8C:("BgKin2Fence_Draw",), 0x80B6EFA0:("func_80B6EFA0",),