/* * File: z_bg_hidan_sekizou.c * Overlay: ovl_Bg_Hidan_Sekizou * Description: Stationary flame thrower statue */ #include "z_bg_hidan_sekizou.h" #include "objects/object_hidan_objects/object_hidan_objects.h" #define FLAGS 0 void BgHidanSekizou_Init(Actor* thisx, GlobalContext* globalCtx); void BgHidanSekizou_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgHidanSekizou_Update(Actor* thisx, GlobalContext* globalCtx); void BgHidanSekizou_Draw(Actor* thisx, GlobalContext* globalCtx); void func_8088D434(BgHidanSekizou* this, GlobalContext* globalCtx); void func_8088D720(BgHidanSekizou* this, GlobalContext* globalCtx); const ActorInit Bg_Hidan_Sekizou_InitVars = { ACTOR_BG_HIDAN_SEKIZOU, ACTORCAT_BG, FLAGS, OBJECT_HIDAN_OBJECTS, sizeof(BgHidanSekizou), (ActorFunc)BgHidanSekizou_Init, (ActorFunc)BgHidanSekizou_Destroy, (ActorFunc)BgHidanSekizou_Update, (ActorFunc)BgHidanSekizou_Draw, NULL, }; static ColliderJntSphElementInit sJntSphElementsInit[6] = { { { ELEMTYPE_UNK0, { 0x20000000, 0x01, 0x04 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_NONE, OCELEM_ON, }, { 1, { { 0, 30, 40 }, 23 }, 100 }, }, { { ELEMTYPE_UNK0, { 0x20000000, 0x01, 0x04 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_NONE, OCELEM_ON, }, { 1, { { 0, 32, 87 }, 30 }, 100 }, }, { { ELEMTYPE_UNK0, { 0x20000000, 0x01, 0x04 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_NONE, OCELEM_ON, }, { 1, { { 0, 35, 150 }, 40 }, 100 }, }, { { ELEMTYPE_UNK0, { 0x20000000, 0x01, 0x04 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_NONE, OCELEM_ON, }, { 1, { { 0, 30, 40 }, 23 }, 100 }, }, { { ELEMTYPE_UNK0, { 0x20000000, 0x01, 0x04 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_NONE, OCELEM_ON, }, { 1, { { 0, 32, 87 }, 30 }, 100 }, }, { { ELEMTYPE_UNK0, { 0x20000000, 0x01, 0x04 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_NONE, OCELEM_ON, }, { 1, { { 0, 35, 150 }, 40 }, 100 }, }, }; static ColliderJntSphInit sJntSphInit = { { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_NONE, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_2, COLSHAPE_JNTSPH, }, 6, sJntSphElementsInit, }; static CollisionCheckInfoInit sColChkInfoInit = { 1, 40, 240, MASS_IMMOVABLE }; static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 400, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 1500, ICHAIN_STOP), }; static void* sFireballsTexs[] = { gFireTempleFireball0Tex, gFireTempleFireball1Tex, gFireTempleFireball2Tex, gFireTempleFireball3Tex, gFireTempleFireball4Tex, gFireTempleFireball5Tex, gFireTempleFireball6Tex, gFireTempleFireball7Tex, }; void func_8088CEC0(BgHidanSekizou* this, s32 arg1, s16 arg2) { s32 i; s32 start = arg1 * 3; s32 end = start + 3; f32 sp30 = Math_SinS(arg2); f32 sp2C = Math_CosS(arg2); for (i = start; i < end; i++) { ColliderJntSphElement* element = &this->collider.elements[i]; element->dim.worldSphere.center.x = this->dyna.actor.home.pos.x + (sp2C * element->dim.modelSphere.center.x) + (sp30 * element->dim.modelSphere.center.z); element->dim.worldSphere.center.y = (s16)this->dyna.actor.home.pos.y + element->dim.modelSphere.center.y; element->dim.worldSphere.center.z = this->dyna.actor.home.pos.z - (sp30 * element->dim.modelSphere.center.x) + (sp2C * element->dim.modelSphere.center.z); element->info.toucherFlags |= TOUCH_ON; element->info.ocElemFlags |= OCELEM_ON; } } void BgHidanSekizou_Init(Actor* thisx, GlobalContext* globalCtx) { s32 pad; BgHidanSekizou* this = (BgHidanSekizou*)thisx; s32 i; CollisionHeader* colHeader = NULL; Actor_ProcessInitChain(&this->dyna.actor, sInitChain); DynaPolyActor_Init(&this->dyna, DPM_UNK); Collider_InitJntSph(globalCtx, &this->collider); Collider_SetJntSph(globalCtx, &this->collider, &this->dyna.actor, &sJntSphInit, this->elements); for (i = 0; i < ARRAY_COUNT(this->elements); i++) { this->collider.elements[i].dim.worldSphere.radius = this->collider.elements[i].dim.modelSphere.radius; } if (this->dyna.actor.params == 0) { this->unk_168[0] = 36; for (i = 0; i < 2; i++) { func_8088CEC0(this, i, this->dyna.actor.shape.rot.y + ((i == 0) ? 0x2000 : -0x2000)); } CollisionHeader_GetVirtual(&gFireTempleStationaryFlamethrowerShortCol, &colHeader); this->updateFunc = func_8088D720; } else { this->unk_168[0] = this->unk_168[1] = this->unk_168[2] = this->unk_168[3] = 0; CollisionHeader_GetVirtual(&gFireTempleStationaryFlamethrowerTallCol, &colHeader); this->updateFunc = func_8088D434; } this->unk_170 = 0; this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader); CollisionCheck_SetInfo(&this->dyna.actor.colChkInfo, NULL, &sColChkInfoInit); } void BgHidanSekizou_Destroy(Actor* thisx, GlobalContext* globalCtx2) { GlobalContext* globalCtx = globalCtx2; BgHidanSekizou* this = (BgHidanSekizou*)thisx; DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); Collider_DestroyJntSph(globalCtx, &this->collider); } void func_8088D434(BgHidanSekizou* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); s32 i; s32 isAligned[2]; s32 isClose; s32 phi_s4; isClose = this->dyna.actor.xzDistToPlayer < 300.0f; isAligned[0] = fabsf(this->dyna.actor.world.pos.x - player->actor.world.pos.x) < 80.0f; isAligned[1] = fabsf(this->dyna.actor.world.pos.z - player->actor.world.pos.z) < 80.0f; phi_s4 = 0; for (i = 0; i < 4; i++) { s16 diff; s16* temp = &this->unk_168[i]; DECR(*temp); diff = this->dyna.actor.yawTowardsPlayer - i * 0x4000; if (isAligned[i % 2] && isClose) { if (ABS(diff) <= 0x4000) { if (*temp < 4) { *temp = 35 - *temp; } func_8088CEC0(this, (phi_s4 > 1) ? 1 : phi_s4, this->dyna.actor.shape.rot.y + i * 0x4000); phi_s4++; } } } for (i = 3 * phi_s4; i < ARRAY_COUNT(this->elements); i++) { this->collider.elements[i].info.toucherFlags &= ~TOUCH_ON; this->collider.elements[i].info.ocElemFlags &= ~OCELEM_ON; } } void func_8088D720(BgHidanSekizou* this, GlobalContext* globalCtx) { this->unk_168[0]--; if (this->unk_168[0] <= -36) { this->unk_168[0] = 36; } } void func_8088D750(BgHidanSekizou* this, GlobalContext* globalCtx) { s16 phi_a3; if (this->dyna.actor.xzDistToPlayer > 200.0f) { phi_a3 = this->dyna.actor.yawTowardsPlayer; } else if (this->dyna.actor.params == 0) { phi_a3 = this->dyna.actor.yawTowardsPlayer - this->dyna.actor.shape.rot.y; if (phi_a3 > 0x2000) { phi_a3 = this->dyna.actor.shape.rot.y + 0x6000; } else if (phi_a3 < -0x2000) { phi_a3 = this->dyna.actor.shape.rot.y - 0x6000; } else if (phi_a3 > 0) { phi_a3 = this->dyna.actor.shape.rot.y - 0x2000; } else { phi_a3 = this->dyna.actor.shape.rot.y + 0x2000; } } else { phi_a3 = this->dyna.actor.yawTowardsPlayer; if (phi_a3 > 0x6000) { phi_a3 = 0x4000; } else if (phi_a3 > 0x4000) { phi_a3 = -0x8000; } else if (phi_a3 > 0x2000) { phi_a3 = 0; } else if (phi_a3 > 0) { phi_a3 = 0x4000; } else if (phi_a3 < -0x6000) { phi_a3 = -0x4000; } else if (phi_a3 < -0x4000) { phi_a3 = -0x8000; } else if (phi_a3 < -0x2000) { phi_a3 = 0; } else { phi_a3 = -0x4000; } } func_8002F71C(globalCtx, &this->dyna.actor, 5.0f, phi_a3, 1.0f); } void BgHidanSekizou_Update(Actor* thisx, GlobalContext* globalCtx2) { GlobalContext* globalCtx = globalCtx2; BgHidanSekizou* this = (BgHidanSekizou*)thisx; if (this->unk_170 != 0) { this->unk_170--; } if (this->unk_170 == 0) { this->unk_170 = 4; } if (this->collider.base.atFlags & AT_HIT) { this->collider.base.atFlags &= ~AT_HIT; func_8088D750(this, globalCtx); } this->updateFunc(this, globalCtx); if (this->dyna.actor.params == 0) { if (this->unk_168[0] > 0) { CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); func_8002F974(&this->dyna.actor, NA_SE_EV_FIRE_PILLAR - SFX_FLAG); } } else { if ((this->unk_168[0] > 0) || (this->unk_168[1] > 0) || (this->unk_168[2] > 0) || (this->unk_168[3] > 0)) { CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); func_8002F974(&this->dyna.actor, NA_SE_EV_FIRE_PILLAR - SFX_FLAG); } } } Gfx* func_8088D9F4(GlobalContext* globalCtx, BgHidanSekizou* this, s16 arg2, MtxF* arg3, f32 arg4, f32 arg5, s16 arg6, Gfx* arg7) { f32 temp_f0; f32 temp_f2; f32 phi_f12; arg6 = (((arg6 + arg2) % 8) * 7) * (1 / 7.0f); arg2++; gSPSegment(arg7++, 9, SEGMENTED_TO_VIRTUAL(sFireballsTexs[arg6])); if (arg2 != 4) { phi_f12 = arg2 + ((4 - this->unk_170) / 4.0f); } else { phi_f12 = arg2; } gDPSetPrimColor(arg7++, 0, 1, 255, 255, 0, 150); gDPSetEnvColor(arg7++, 255, 0, 0, 255); arg3->xx = arg3->yy = arg3->zz = (0.7f * phi_f12) + 0.5f; temp_f2 = (arg3->xx * 10.0f * phi_f12) + 20.0f; arg3->xw = (temp_f2 * arg4) + this->dyna.actor.world.pos.x; arg3->yw = this->dyna.actor.world.pos.y + 30.0f + (.7f * phi_f12); arg3->zw = (temp_f2 * arg5) + this->dyna.actor.world.pos.z; gSPMatrix(arg7++, Matrix_MtxFToMtx(MATRIX_CHECKFLOATS(arg3), Graph_Alloc(globalCtx->state.gfxCtx, sizeof(Mtx))), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(arg7++, gFireTempleFireballDL); return arg7; } Gfx* func_8088DC50(GlobalContext* globalCtx, BgHidanSekizou* this, s16 arg2, s16 arg3, Gfx* arg4) { s32 pad; s16 temp_v1; s32 phi_s1; s32 phi_s2; f32 temp_f20; f32 temp_f22; MtxF sp68; s32 i; if (arg3 < 4) { phi_s1 = 4 - arg3; phi_s2 = 4; } else { phi_s1 = 0; phi_s2 = 36 - arg3; phi_s2 = CLAMP_MAX(phi_s2, 4); } temp_f20 = Math_SinS(arg2); temp_f22 = Math_CosS(arg2); Matrix_MtxFCopy(&sp68, &gMtxFClear); temp_v1 = Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx)) - arg2; if (ABS(temp_v1) < 0x4000) { for (i = phi_s2 - 1; i >= phi_s1; i--) { arg4 = func_8088D9F4(globalCtx, this, i, &sp68, temp_f20, temp_f22, arg3, arg4); } } else { for (i = phi_s1; i < phi_s2; i++) { arg4 = func_8088D9F4(globalCtx, this, i, &sp68, temp_f20, temp_f22, arg3, arg4); } } return arg4; } void func_8088DE08(s16 arg0, s16 arg1, s32 arg2[]) { s16 diff = arg0 - arg1; if (ABS(diff) <= 0x2000) { arg2[0] = 0; arg2[1] = 1; arg2[2] = 3; arg2[3] = 2; } else if (ABS(diff) >= 0x6000) { arg2[0] = 2; arg2[1] = 3; arg2[2] = 1; arg2[3] = 0; } else if (diff > 0x2000) { arg2[0] = 1; arg2[1] = 0; arg2[2] = 2; arg2[3] = 3; } else { arg2[0] = 3; arg2[1] = 2; arg2[2] = 0; arg2[3] = 1; } } void BgHidanSekizou_Draw(Actor* thisx, GlobalContext* globalCtx2) { GlobalContext* globalCtx = globalCtx2; BgHidanSekizou* this = (BgHidanSekizou*)thisx; s32 i; s32 sp6C[4]; OPEN_DISPS(globalCtx->state.gfxCtx); func_80093D18(globalCtx->state.gfxCtx); gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); if (this->dyna.actor.params == 0) { gSPDisplayList(POLY_OPA_DISP++, gFireTempleStationaryFlamethrowerShortDL); } else { gSPDisplayList(POLY_OPA_DISP++, gFireTempleStationaryFlamethrowerTallDL); } POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0x14); if (this->dyna.actor.params == 0) { if (this->unk_168[0] > 0) { if ((s16)(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx)) - this->dyna.actor.shape.rot.y) >= 0) { POLY_XLU_DISP = func_8088DC50(globalCtx, this, this->dyna.actor.shape.rot.y + 0x2000, this->unk_168[0], POLY_XLU_DISP); POLY_XLU_DISP = func_8088DC50(globalCtx, this, this->dyna.actor.shape.rot.y - 0x2000, this->unk_168[0], POLY_XLU_DISP); } else { POLY_XLU_DISP = func_8088DC50(globalCtx, this, this->dyna.actor.shape.rot.y - 0x2000, this->unk_168[0], POLY_XLU_DISP); POLY_XLU_DISP = func_8088DC50(globalCtx, this, this->dyna.actor.shape.rot.y + 0x2000, this->unk_168[0], POLY_XLU_DISP); } } } else { func_8088DE08(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx)), this->dyna.actor.shape.rot.y, sp6C); for (i = 0; i < 4; i++) { s32 index = sp6C[i]; if (this->unk_168[index] > 0) { POLY_XLU_DISP = func_8088DC50(globalCtx, this, this->dyna.actor.shape.rot.y + index * 0x4000, this->unk_168[index], POLY_XLU_DISP); } } } CLOSE_DISPS(globalCtx->state.gfxCtx); }