Shipwright/soh/src/overlays/actors/ovl_Bg_Spot08_Bakudankabe/z_bg_spot08_bakudankabe.c

205 lines
6.5 KiB
C

/*
* File: z_bg_spot08_bakudankabe
* Overlay: ovl_Bg_Spot08_Bakudankabe
* Description: Destructible Wall (Zora's Fountain)
*/
#include "z_bg_spot08_bakudankabe.h"
#include "objects/object_spot08_obj/object_spot08_obj.h"
#include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h"
#include "objects/gameplay_field_keep/gameplay_field_keep.h"
#define FLAGS ACTOR_FLAG_22
void BgSpot08Bakudankabe_Init(Actor* thisx, GlobalContext* globalCtx);
void BgSpot08Bakudankabe_Destroy(Actor* thisx, GlobalContext* globalCtx);
void BgSpot08Bakudankabe_Update(Actor* thisx, GlobalContext* globalCtx);
void BgSpot08Bakudankabe_Draw(Actor* thisx, GlobalContext* globalCtx);
void func_808B02D0(BgSpot08Bakudankabe* this, GlobalContext* globalCtx);
void func_808B0324(BgSpot08Bakudankabe* this, GlobalContext* globalCtx);
const ActorInit Bg_Spot08_Bakudankabe_InitVars = {
ACTOR_BG_SPOT08_BAKUDANKABE,
ACTORCAT_BG,
FLAGS,
OBJECT_SPOT08_OBJ,
sizeof(BgSpot08Bakudankabe),
(ActorFunc)BgSpot08Bakudankabe_Init,
(ActorFunc)BgSpot08Bakudankabe_Destroy,
(ActorFunc)BgSpot08Bakudankabe_Update,
(ActorFunc)BgSpot08Bakudankabe_Draw,
NULL,
};
static ColliderJntSphElementInit sJntSphElementsInit[] = {
{
{
ELEMTYPE_UNK0,
{ 0x00000000, 0x00, 0x00 },
{ 0x00000008, 0x00, 0x00 },
TOUCH_NONE,
BUMP_ON,
OCELEM_NONE,
},
{ 0, { { 0, 50, 50 }, 70 }, 100 },
},
{
{
ELEMTYPE_UNK0,
{ 0x00000000, 0x00, 0x00 },
{ 0x00000008, 0x00, 0x00 },
TOUCH_NONE,
BUMP_ON,
OCELEM_NONE,
},
{ 0, { { -100, 50, 50 }, 70 }, 100 },
},
{
{
ELEMTYPE_UNK0,
{ 0x00000000, 0x00, 0x00 },
{ 0x00000008, 0x00, 0x00 },
TOUCH_NONE,
BUMP_ON,
OCELEM_NONE,
},
{ 0, { { 100, 50, 50 }, 70 }, 100 },
},
};
static ColliderJntSphInit sJntSphInit = {
{
COLTYPE_NONE,
AT_NONE,
AC_ON | AC_TYPE_PLAYER,
OC1_NONE,
OC2_TYPE_2,
COLSHAPE_JNTSPH,
},
3,
sJntSphElementsInit,
};
static Vec3f D_808B08AC[] = {
{ 0.0f, 116.65f, 50.0f },
{ 115.0f, 95.0f, 10.0f },
{ -115.0f, 95.0f, 10.0f },
};
static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F(scale, 1, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 3200, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 800, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 1000, ICHAIN_STOP),
};
void func_808B02D0(BgSpot08Bakudankabe* this, GlobalContext* globalCtx) {
s32 pad;
Collider_InitJntSph(globalCtx, &this->collider);
Collider_SetJntSph(globalCtx, &this->collider, &this->dyna.actor, &sJntSphInit, this->colliderItems);
}
void func_808B0324(BgSpot08Bakudankabe* this, GlobalContext* globalCtx) {
s32 pad[2];
s32 i;
Vec3f burstDepthY;
Vec3f burstDepthX;
f32 sinY;
f32 cosY;
sinY = Math_SinS(this->dyna.actor.shape.rot.y);
cosY = Math_CosS(this->dyna.actor.shape.rot.y);
burstDepthX.z = 0.0f;
burstDepthX.x = 0.0f;
for (i = 0; i < 24; i++) {
s16 gravityInfluence;
s16 scale;
f32 temp1;
f32 temp2;
s32 rotationSpeed;
temp1 = (Rand_ZeroOne() - 0.5f) * 440.0f;
temp2 = (Rand_ZeroOne() - 0.5f) * 20.0f;
burstDepthY.x = this->dyna.actor.world.pos.x + temp2 * sinY + (temp1 * cosY);
burstDepthY.y = (this->dyna.actor.world.pos.y + 20.0f) + (i * (65.0f / 12.0f));
burstDepthY.z = this->dyna.actor.world.pos.z + temp2 * cosY - (temp1 * sinY);
burstDepthX.y = (Rand_ZeroOne() - 0.2f) * 12.0f;
scale = Rand_ZeroOne() * 75.0f + 10.0f;
if (scale < 25) {
gravityInfluence = -300;
} else if (scale < 50) {
gravityInfluence = -360;
} else {
gravityInfluence = -420;
}
if (Rand_ZeroOne() < 0.4f) {
rotationSpeed = 65;
} else {
rotationSpeed = 33;
}
EffectSsKakera_Spawn(globalCtx, &burstDepthY, &burstDepthX, &burstDepthY, gravityInfluence, rotationSpeed, 0x1E,
4, 0, scale, 1, 3, 80, KAKERA_COLOR_NONE, OBJECT_GAMEPLAY_FIELD_KEEP, gFieldKakeraDL);
}
for (i = 0; i < ARRAY_COUNT(D_808B08AC); i++) {
burstDepthY.x = this->dyna.actor.world.pos.x + D_808B08AC[i].z * sinY + D_808B08AC[i].x * cosY;
burstDepthY.y = this->dyna.actor.world.pos.y + D_808B08AC[i].y;
burstDepthY.z = this->dyna.actor.world.pos.z + D_808B08AC[i].z * cosY - (D_808B08AC[i].x * sinY);
func_80033480(globalCtx, &burstDepthY, 120.0f, 4, 0x78, 0xA0, 1);
}
}
void BgSpot08Bakudankabe_Init(Actor* thisx, GlobalContext* globalCtx) {
BgSpot08Bakudankabe* this = (BgSpot08Bakudankabe*)thisx;
s32 pad;
CollisionHeader* colHeader = NULL;
DynaPolyActor_Init(&this->dyna, DPM_UNK);
if (Flags_GetSwitch(globalCtx, (this->dyna.actor.params & 0x3F))) {
Actor_Kill(&this->dyna.actor);
return;
}
func_808B02D0(this, globalCtx);
CollisionHeader_GetVirtual(&gZorasFountainBombableWallCol, &colHeader);
this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader);
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
}
void BgSpot08Bakudankabe_Destroy(Actor* thisx, GlobalContext* globalCtx) {
BgSpot08Bakudankabe* this = (BgSpot08Bakudankabe*)thisx;
DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
Collider_DestroyJntSph(globalCtx, &this->collider);
}
void BgSpot08Bakudankabe_Update(Actor* thisx, GlobalContext* globalCtx) {
BgSpot08Bakudankabe* this = (BgSpot08Bakudankabe*)thisx;
if (this->collider.base.acFlags & AC_HIT) {
func_808B0324(this, globalCtx);
Flags_SetSwitch(globalCtx, (this->dyna.actor.params & 0x3F));
SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->dyna.actor.world.pos, 40, NA_SE_EV_WALL_BROKEN);
func_80078884(NA_SE_SY_CORRECT_CHIME);
Actor_Kill(&this->dyna.actor);
} else if (this->dyna.actor.xzDistToPlayer < 800.0f) {
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
}
}
void BgSpot08Bakudankabe_Draw(Actor* thisx, GlobalContext* globalCtx) {
BgSpot08Bakudankabe* this = (BgSpot08Bakudankabe*)thisx;
Collider_UpdateSpheres(0, &this->collider);
Collider_UpdateSpheres(1, &this->collider);
Collider_UpdateSpheres(2, &this->collider);
Gfx_DrawDListOpa(globalCtx, gZorasFountainBombableWallDL);
}