diff --git a/spec b/spec index 46a8fc6775..cb1adb6e40 100644 --- a/spec +++ b/spec @@ -3320,8 +3320,11 @@ beginseg name "ovl_Bg_Hakugin_Bombwall" compress include "build/src/overlays/actors/ovl_Bg_Hakugin_Bombwall/z_bg_hakugin_bombwall.o" - include "build/data/ovl_Bg_Hakugin_Bombwall/ovl_Bg_Hakugin_Bombwall.data.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_Bg_Hakugin_Bombwall/ovl_Bg_Hakugin_Bombwall_reloc.o" +#else include "build/data/ovl_Bg_Hakugin_Bombwall/ovl_Bg_Hakugin_Bombwall.reloc.o" +#endif endseg beginseg diff --git a/src/overlays/actors/ovl_Bg_Hakugin_Bombwall/z_bg_hakugin_bombwall.c b/src/overlays/actors/ovl_Bg_Hakugin_Bombwall/z_bg_hakugin_bombwall.c index 4061745f70..1f0030d28a 100644 --- a/src/overlays/actors/ovl_Bg_Hakugin_Bombwall/z_bg_hakugin_bombwall.c +++ b/src/overlays/actors/ovl_Bg_Hakugin_Bombwall/z_bg_hakugin_bombwall.c @@ -5,6 +5,7 @@ */ #include "z_bg_hakugin_bombwall.h" +#include "objects/object_hakugin_obj/object_hakugin_obj.h" #define FLAGS 0x00000000 @@ -15,7 +16,16 @@ void BgHakuginBombwall_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgHakuginBombwall_Update(Actor* thisx, GlobalContext* globalCtx); void BgHakuginBombwall_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80ABBFC0(BgHakuginBombwall* this, GlobalContext* globalCtx); +void func_80ABC2E0(BgHakuginBombwall* this, GlobalContext* globalCtx); +void func_80ABC58C(BgHakuginBombwall* this, GlobalContext* globalCtx); +void func_80ABC7FC(BgHakuginBombwall* this, GlobalContext* globalCtx); +s32 func_80ABCB5C(Actor* thisx, GlobalContext* globalCtx); +s32 func_80ABCC00(Actor* thisx, GlobalContext* globalCtx); +void func_80ABCCE4(BgHakuginBombwall* this, GlobalContext* globalCtx); +void func_80ABCD98(BgHakuginBombwall* this, GlobalContext* globalCtx); +void func_80ABCE60(BgHakuginBombwall* this, GlobalContext* globalCtx); + const ActorInit Bg_Hakugin_Bombwall_InitVars = { ACTOR_BG_HAKUGIN_BOMBWALL, ACTORCAT_BG, @@ -28,48 +38,404 @@ const ActorInit Bg_Hakugin_Bombwall_InitVars = { (ActorFunc)BgHakuginBombwall_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80ABCF80 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000008, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000008, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 80, 80, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80ABD040[] = { +Color_RGBA8 D_80ABCFAC = { 210, 210, 210, 255 }; +Color_RGBA8 D_80ABCFB0 = { 140, 140, 140, 255 }; + +Vec3f D_80ABCFB4 = { 0.0f, 0.33f, 0.0f }; + +typedef struct { + /* 0x00 */ CollisionHeader* unk_00; + /* 0x04 */ Gfx* unk_04; + /* 0x08 */ f32 unk_08; + /* 0x0C */ f32 unk_0C; + /* 0x10 */ f32 unk_10; + /* 0x14 */ s16 unk_14; + /* 0x16 */ s16 unk_16; + /* 0x18 */ s32 unk_18; + /* 0x1C */ f32 unk_1C; + /* 0x20 */ BgHakuginBombwallUnkFunc unk_20; + /* 0x24 */ BgHakuginBombwallUnkFunc2 unk_24; + /* 0x28 */ BgHakuginBombwallUnkFunc2 unk_28; + /* 0x2C */ s32 unk_2C; +} BgHakuginBombwallStruct; // size = 0x30 + +BgHakuginBombwallStruct D_80ABCFC0[] = { + { + &object_hakugin_obj_Colheader_009768, + object_hakugin_obj_DL_009658, + 70.0f, + 600.0f, + 400.0f, + 80, + 80, + 0x8, + 4225.0f, + func_80ABCB5C, + func_80ABBFC0, + func_80ABC58C, + 6, + }, + { + &object_hakugin_obj_Colheader_009AF0, + object_hakugin_obj_DL_0099A8, + 10.0f, + 600.0f, + 300.0f, + 50, + 20, + 0x408, + 4225.0f, + func_80ABCC00, + func_80ABC2E0, + func_80ABC7FC, + 18, + }, +}; + +s32 D_80ABD020[] = { -73, -40, -8, 24, 57 }; + +Vec3f D_80ABD034 = { 0.0f, 3.0f, 0.0f }; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; +#ifdef NON_MATCHING +// Breaks relocs +void func_80ABBFC0(BgHakuginBombwall* this, GlobalContext* globalCtx) { + s32 temp; + Vec3f spF0; + Vec3f spE4; + Vec3f spD8; + Vec3f spCC; + s32 pad; + s16 phi_s1; + s16 phi_s0; + s32 i; + s32 j; + + Matrix_RotateY(this->dyna.actor.shape.rot.y, MTXMODE_NEW); + + for (i = 0; i < 6; i++) { + temp = i + 1; + for (j = 0; j < ARRAY_COUNT(D_80ABD020); j++) { + spD8.x = D_80ABD020[j] + (s32)((u32)Rand_Next() >> 0x1C); + spD8.y = ((Rand_ZeroOne() - 0.5f) * 15.0f) + (temp * 26.666666f); + spD8.z = (Rand_ZeroOne() * 20.0f) - 10.0f; + + spCC.x = ((Rand_ZeroOne() - 0.5f) * 7.0f) + (spD8.x * 0.07777778f); + spCC.y = (Rand_ZeroOne() * 7.0f) - 2.0f; + spCC.z = spD8.z * 0.3f; + + Matrix_MultiplyVector3fByState(&spD8, &spF0); + Matrix_MultiplyVector3fByState(&spCC, &spE4); + + spF0.x += this->dyna.actor.world.pos.x; + spF0.y += this->dyna.actor.world.pos.y; + spF0.z += this->dyna.actor.world.pos.z; + + if ((Rand_Next() % 4) == 0) { + phi_s0 = 32; + } else { + phi_s0 = 64; + } + + if (Rand_Next() > 0) { + phi_s0 |= 1; + phi_s1 = 1; + func_800B0E48(globalCtx, &spF0, &gZeroVec3f, &D_80ABCFB4, &D_80ABCFAC, &D_80ABCFB0, + ((u32)Rand_Next() >> 0x1B) + 70, ((u32)Rand_Next() >> 0x1A) + 60); + } else { + phi_s1 = 0; + } + + EffectSsKakera_Spawn(globalCtx, &spF0, &spE4, &spF0, -550, phi_s0, 30, 0, 0, + (s32)(Rand_ZeroOne() * 22.0f) + 5, phi_s1, 0, 50, -1, OBJECT_HAKUGIN_OBJ, + object_hakugin_obj_DL_009830); + } + } +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/func_80ABBFC0.s") #endif -extern ColliderCylinderInit D_80ABCF80; -extern InitChainEntry D_80ABD040[]; +void func_80ABC2E0(BgHakuginBombwall* this, GlobalContext* globalCtx) { + s32 pad; + s32 i; + s16 phi_s2; + s16 phi_v0; + s16 phi_v1; + s16 phi_t0; + s16 temp_s1; + Vec3f spC8; + Vec3f spBC; + f32 temp_f20; + f32 temp_f22; + f32 temp_f24; -extern UNK_TYPE D_06009830; + for (i = 0, phi_s2 = 0; i < 25; i++, phi_s2 += 0x4E20) { + temp_f20 = (25 - i) * 2.4f; + temp_f22 = Math_SinS(phi_s2) * temp_f20; + temp_f24 = Math_CosS(phi_s2) * temp_f20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/func_80ABBFC0.s") + spC8.x = this->dyna.actor.world.pos.x + temp_f22; + spC8.y = this->dyna.actor.world.pos.y; + spC8.z = this->dyna.actor.world.pos.z + temp_f24; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/func_80ABC2E0.s") + spBC.x = ((Rand_ZeroOne() - 0.5f) * 10.0f) + (temp_f22 * 0.13333334f); + spBC.y = (Rand_ZeroOne() * 17.0f) + 7.0f; + spBC.z = ((Rand_ZeroOne() - 0.5f) * 10.0f) + (temp_f24 * 0.13333334f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/func_80ABC58C.s") + temp_s1 = (Rand_Next() & 3) + (i >> 2) + 4; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/func_80ABC7FC.s") + if ((Rand_Next() % 4) == 0) { + phi_v0 = 32; + } else { + phi_v0 = 64; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/BgHakuginBombwall_Init.s") + if (temp_s1 >= 8) { + phi_v0 |= 1; + phi_v1 = 1; + phi_t0 = -550; + } else { + phi_v1 = 0; + phi_t0 = -400; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/BgHakuginBombwall_Destroy.s") + EffectSsKakera_Spawn(globalCtx, &spC8, &spBC, &spC8, phi_t0, phi_v0, 30, 0, 0, temp_s1, phi_v1, 0, 50, -1, + OBJECT_HAKUGIN_OBJ, object_hakugin_obj_DL_009830); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/func_80ABCB5C.s") + if ((i & 1) == 0) { + func_800B0E48(globalCtx, &spC8, &D_80ABD034, &D_80ABCFB4, &D_80ABCFAC, &D_80ABCFB0, + ((u32)Rand_Next() >> 0x1B) + 60, ((u32)Rand_Next() >> 0x1A) + 50); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/func_80ABCC00.s") +void func_80ABC58C(BgHakuginBombwall* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f spD8; + Vec3f spCC; + Vec3f spC0; + Vec3f spB4; + Vec3f spA8; + Vec3f sp9C; + s32 i; + s16 phi_s1; + f32 temp_f20; + f32 temp_f22; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/func_80ABCCE4.s") + spA8.y = 0.0f; + spB4.y = 0.3f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/func_80ABCD98.s") + Matrix_RotateY(this->dyna.actor.shape.rot.y, MTXMODE_NEW); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/func_80ABCE60.s") + for (i = 0, phi_s1 = 0; i < 21; i++, phi_s1 += 0x618) { + temp_f20 = Math_SinS(phi_s1); + temp_f22 = Math_CosS(phi_s1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/BgHakuginBombwall_Update.s") + sp9C.x = (i - 10) * 9.0f; + sp9C.y = (Rand_ZeroOne() * 40.0f) + 15.0f; + sp9C.z = temp_f20 * 10.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/BgHakuginBombwall_Draw.s") + spA8.x = ((Rand_ZeroOne() - 0.5f) * 7.0f) + (temp_f22 * -12.0f); + spA8.z = ((Rand_ZeroOne() - 0.5f) * 7.0f) + (temp_f20 * 16.0f); + + spB4.x = spA8.x * -0.09f; + spB4.z = spA8.z * -0.09f; + + Matrix_MultiplyVector3fByState(&sp9C, &spC0); + Matrix_MultiplyVector3fByState(&spA8, &spCC); + Matrix_MultiplyVector3fByState(&spB4, &spD8); + + spC0.x += this->dyna.actor.world.pos.x; + spC0.y += this->dyna.actor.world.pos.y; + spC0.z += this->dyna.actor.world.pos.z; + + func_800B0E48(globalCtx, &spC0, &spCC, &spD8, &D_80ABCFAC, &D_80ABCFB0, ((u32)Rand_Next() >> 0x1A) + 60, + ((u32)Rand_Next() >> 0x1B) + 60); + } +} + +void func_80ABC7FC(BgHakuginBombwall* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f spB8; + Vec3f spAC; + Vec3f spA0; + f32 temp_f20; + f32 temp_f22; + f32 temp_f24; + s16 phi_s0; + s32 i; + + spAC.y = 0.0f; + spB8.y = 0.3f; + + for (i = 0, phi_s0 = 0; i < 20; i++, phi_s0 += 0xCCC) { + temp_f20 = Math_SinS(phi_s0); + temp_f22 = Math_CosS(phi_s0); + temp_f24 = Rand_ZeroOne() * 60.0f; + + spA0.x = (temp_f22 * temp_f24) + this->dyna.actor.world.pos.x; + spA0.y = (Rand_ZeroOne() * 20.0f) + this->dyna.actor.world.pos.y; + spA0.z = (temp_f20 * temp_f24) + this->dyna.actor.world.pos.z; + + spAC.x = ((Rand_ZeroOne() - 0.5f) * 7.0f) + (temp_f20 * 15.0f); + spAC.z = ((Rand_ZeroOne() - 0.5f) * 7.0f) + (temp_f22 * 15.0f); + + spB8.x = spAC.x * -0.095f; + spB8.z = spAC.z * -0.095f; + + func_800B0E48(globalCtx, &spA0, &spAC, &spB8, &D_80ABCFAC, &D_80ABCFB0, ((u32)Rand_Next() >> 0x1A) + 60, + ((u32)Rand_Next() >> 0x1B) + 60); + } +} + +void BgHakuginBombwall_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgHakuginBombwall* this = THIS; + BgHakuginBombwallStruct* ptr = &D_80ABCFC0[BGHAKUGIN_BOMBWALL_100(&this->dyna.actor)]; + + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + DynaPolyActor_Init(&this->dyna, 0); + Collider_InitCylinder(globalCtx, &this->collider); + + if (Flags_GetSwitch(globalCtx, BGHAKUGIN_BOMBWALL_SWITCHFLAG(&this->dyna.actor))) { + Actor_MarkForDeath(&this->dyna.actor); + return; + } + + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, ptr->unk_00); + + Collider_SetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit); + this->collider.dim.radius = ptr->unk_14; + this->collider.dim.height = ptr->unk_16; + this->collider.info.bumper.dmgFlags = ptr->unk_18; + Collider_UpdateCylinder(&this->dyna.actor, &this->collider); + + Actor_SetFocus(&this->dyna.actor, ptr->unk_08); + this->dyna.actor.uncullZoneScale = ptr->unk_0C; + this->dyna.actor.uncullZoneDownward = ptr->unk_10; + this->actionFunc = func_80ABCCE4; +} + +void BgHakuginBombwall_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgHakuginBombwall* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +s32 func_80ABCB5C(Actor* thisx, GlobalContext* globalCtx) { + BgHakuginBombwall* this = THIS; + s32 pad; + + if (this->collider.base.acFlags & AC_HIT) { + if (this->collider.base.ac != NULL) { + if (Math3D_Vec3fDistSq(&this->dyna.actor.world.pos, &this->collider.base.ac->world.pos) < + D_80ABCFC0[BGHAKUGIN_BOMBWALL_100(&this->dyna.actor)].unk_1C) { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->dyna.actor.world.pos, 60, NA_SE_EV_WALL_BROKEN); + return true; + } + } + } + return false; +} + +s32 func_80ABCC00(Actor* thisx, GlobalContext* globalCtx) { + BgHakuginBombwall* this = THIS; + s32 pad; + + if (this->collider.base.acFlags & AC_HIT) { + if (this->collider.info.acHitInfo->toucher.dmgFlags & 8) { + if (this->collider.base.ac != NULL) { + if (Math3D_Vec3fDistSq(&this->dyna.actor.world.pos, &this->collider.base.ac->world.pos) < + D_80ABCFC0[BGHAKUGIN_BOMBWALL_100(&this->dyna.actor)].unk_1C) { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->dyna.actor.world.pos, 50, + NA_SE_EV_WALL_BROKEN); + return true; + } + } + } else if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + label:; + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->dyna.actor.world.pos, 50, NA_SE_EV_WALL_BROKEN); + return true; + } + } + return false; +} + +void func_80ABCCE4(BgHakuginBombwall* this, GlobalContext* globalCtx) { + BgHakuginBombwallStruct* ptr = &D_80ABCFC0[BGHAKUGIN_BOMBWALL_100(&this->dyna.actor)]; + + if (ptr->unk_20(&this->dyna.actor, globalCtx)) { + this->dyna.actor.flags |= ACTOR_FLAG_10; + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + this->actionFunc = func_80ABCD98; + } else { + this->collider.base.acFlags &= ~AC_HIT; + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void func_80ABCD98(BgHakuginBombwall* this, GlobalContext* globalCtx) { + s32 pad; + + if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + BgHakuginBombwallStruct* ptr = &D_80ABCFC0[BGHAKUGIN_BOMBWALL_100(&this->dyna.actor)]; + + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + ptr->unk_24(this, globalCtx); + this->dyna.actor.draw = NULL; + this->unk_1AC = 20; + Flags_SetSwitch(globalCtx, BGHAKUGIN_BOMBWALL_SWITCHFLAG(&this->dyna.actor)); + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + this->actionFunc = func_80ABCE60; + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } +} + +void func_80ABCE60(BgHakuginBombwall* this, GlobalContext* globalCtx) { + BgHakuginBombwallStruct* ptr = &D_80ABCFC0[BGHAKUGIN_BOMBWALL_100(&this->dyna.actor)]; + + this->unk_1AC--; + if (this->unk_1AC <= 0) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + Actor_MarkForDeath(&this->dyna.actor); + } else if (this->unk_1AC == ptr->unk_2C) { + ptr->unk_28(this, globalCtx); + } +} + +void BgHakuginBombwall_Update(Actor* thisx, GlobalContext* globalCtx) { + BgHakuginBombwall* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void BgHakuginBombwall_Draw(Actor* thisx, GlobalContext* globalCtx) { + Gfx_DrawDListOpa(globalCtx, D_80ABCFC0[BGHAKUGIN_BOMBWALL_100(thisx)].unk_04); +} diff --git a/src/overlays/actors/ovl_Bg_Hakugin_Bombwall/z_bg_hakugin_bombwall.h b/src/overlays/actors/ovl_Bg_Hakugin_Bombwall/z_bg_hakugin_bombwall.h index 8522fd15cd..869741214f 100644 --- a/src/overlays/actors/ovl_Bg_Hakugin_Bombwall/z_bg_hakugin_bombwall.h +++ b/src/overlays/actors/ovl_Bg_Hakugin_Bombwall/z_bg_hakugin_bombwall.h @@ -6,12 +6,17 @@ struct BgHakuginBombwall; typedef void (*BgHakuginBombwallActionFunc)(struct BgHakuginBombwall*, GlobalContext*); +typedef s32 (*BgHakuginBombwallUnkFunc)(Actor*, GlobalContext*); +typedef void (*BgHakuginBombwallUnkFunc2)(struct BgHakuginBombwall*, GlobalContext*); + +#define BGHAKUGIN_BOMBWALL_SWITCHFLAG(thisx) ((thisx)->params & 0x7F) +#define BGHAKUGIN_BOMBWALL_100(thisx) (((thisx)->params >> 8) & 1) typedef struct BgHakuginBombwall { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x64]; - /* 0x01A8 */ BgHakuginBombwallActionFunc actionFunc; - /* 0x01AC */ char unk_1AC[0x4]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ ColliderCylinder collider; + /* 0x1A8 */ BgHakuginBombwallActionFunc actionFunc; + /* 0x1AC */ s32 unk_1AC; } BgHakuginBombwall; // size = 0x1B0 extern const ActorInit Bg_Hakugin_Bombwall_InitVars;