/* * File: z_bg_hidan_sima.c * Overlay: ovl_Bg_Hidan_Sima * Description: Stone platform (Fire Temple) */ #include "z_bg_hidan_sima.h" #include "objects/object_hidan_objects/object_hidan_objects.h" #define FLAGS 0 void BgHidanSima_Init(Actor* thisx, GlobalContext* globalCtx); void BgHidanSima_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgHidanSima_Update(Actor* thisx, GlobalContext* globalCtx); void BgHidanSima_Draw(Actor* thisx, GlobalContext* globalCtx); void func_8088E518(BgHidanSima* this, GlobalContext* globalCtx); void func_8088E5D0(BgHidanSima* this, GlobalContext* globalCtx); void func_8088E6D0(BgHidanSima* this, GlobalContext* globalCtx); void func_8088E760(BgHidanSima* this, GlobalContext* globalCtx); void func_8088E7A8(BgHidanSima* this, GlobalContext* globalCtx); void func_8088E90C(BgHidanSima* this); const ActorInit Bg_Hidan_Sima_InitVars = { ACTOR_BG_HIDAN_SIMA, ACTORCAT_BG, FLAGS, OBJECT_HIDAN_OBJECTS, sizeof(BgHidanSima), (ActorFunc)BgHidanSima_Init, (ActorFunc)BgHidanSima_Destroy, (ActorFunc)BgHidanSima_Update, (ActorFunc)BgHidanSima_Draw, NULL, }; static ColliderJntSphElementInit sJntSphElementsInit[2] = { { { ELEMTYPE_UNK0, { 0x20000000, 0x01, 0x04 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_NONE, OCELEM_NONE, }, { 1, { { 0, 40, 100 }, 22 }, 100 }, }, { { ELEMTYPE_UNK0, { 0x20000000, 0x01, 0x04 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_NONE, OCELEM_NONE, }, { 1, { { 0, 40, 145 }, 30 }, 100 }, }, }; static ColliderJntSphInit sJntSphInit = { { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_NONE, OC1_NONE, OC2_TYPE_2, COLSHAPE_JNTSPH, }, ARRAY_COUNT(sJntSphElementsInit), sJntSphElementsInit, }; static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; static void* sFireballsTexs[] = { gFireTempleFireball0Tex, gFireTempleFireball1Tex, gFireTempleFireball2Tex, gFireTempleFireball3Tex, gFireTempleFireball4Tex, gFireTempleFireball5Tex, gFireTempleFireball6Tex, gFireTempleFireball7Tex, }; void BgHidanSima_Init(Actor* thisx, GlobalContext* globalCtx) { BgHidanSima* this = (BgHidanSima*)thisx; s32 pad; CollisionHeader* colHeader = NULL; s32 i; Actor_ProcessInitChain(&this->dyna.actor, sInitChain); DynaPolyActor_Init(&this->dyna, DPM_PLAYER); if (this->dyna.actor.params == 0) { CollisionHeader_GetVirtual(&gFireTempleStonePlatform1Col, &colHeader); } else { CollisionHeader_GetVirtual(&gFireTempleStonePlatform2Col, &colHeader); } this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader); Collider_InitJntSph(globalCtx, &this->collider); Collider_SetJntSph(globalCtx, &this->collider, &this->dyna.actor, &sJntSphInit, this->elements); for (i = 0; i < ARRAY_COUNT(sJntSphElementsInit); i++) { this->collider.elements[i].dim.worldSphere.radius = this->collider.elements[i].dim.modelSphere.radius; } if (this->dyna.actor.params == 0) { this->actionFunc = func_8088E518; } else { this->actionFunc = func_8088E760; } } void BgHidanSima_Destroy(Actor* thisx, GlobalContext* globalCtx) { BgHidanSima* this = (BgHidanSima*)thisx; DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); Collider_DestroyJntSph(globalCtx, &this->collider); } void func_8088E518(BgHidanSima* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y, 3.4f); if (func_8004356C(&this->dyna) && !(player->stateFlags1 & 0x6000)) { this->timer = 20; this->dyna.actor.world.rot.y = Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx)) + 0x4000; if (this->dyna.actor.home.pos.y <= this->dyna.actor.world.pos.y) { this->actionFunc = func_8088E5D0; } else { this->actionFunc = func_8088E6D0; } } } void func_8088E5D0(BgHidanSima* this, GlobalContext* globalCtx) { if (this->timer != 0) { this->timer--; } if (this->timer != 0) { this->dyna.actor.world.pos.x = Math_SinS(this->dyna.actor.world.rot.y + (this->timer * 0x4000)) * 5.0f + this->dyna.actor.home.pos.x; this->dyna.actor.world.pos.z = Math_CosS(this->dyna.actor.world.rot.y + (this->timer * 0x4000)) * 5.0f + this->dyna.actor.home.pos.z; } else { this->actionFunc = func_8088E6D0; this->dyna.actor.world.pos.x = this->dyna.actor.home.pos.x; this->dyna.actor.world.pos.z = this->dyna.actor.home.pos.z; } if (!(this->timer % 4)) { func_800AA000(this->dyna.actor.xyzDistToPlayerSq, 180, 10, 100); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCK_SHAKE); } } void func_8088E6D0(BgHidanSima* this, GlobalContext* globalCtx) { if (func_8004356C(&this->dyna)) { this->timer = 20; } else if (this->timer != 0) { this->timer--; } Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y - 100.0f, 1.7f); if (this->timer == 0) { this->actionFunc = func_8088E518; } } void func_8088E760(BgHidanSima* this, GlobalContext* globalCtx) { if (this->timer != 0) { this->timer--; } if (this->timer == 0) { this->dyna.actor.world.rot.y += 0x8000; this->timer = 60; this->actionFunc = func_8088E7A8; } } void func_8088E7A8(BgHidanSima* this, GlobalContext* globalCtx) { f32 temp; if (this->timer != 0) { this->timer--; } if (this->dyna.actor.world.rot.y != this->dyna.actor.home.rot.y) { temp = (sinf(((60 - this->timer) * 0.01667 - 0.5) * M_PI) + 1) * 200; } else { temp = (sinf((this->timer * 0.01667 - 0.5) * M_PI) + 1) * -200; } this->dyna.actor.world.pos.x = Math_SinS(this->dyna.actor.world.rot.y) * temp + this->dyna.actor.home.pos.x; this->dyna.actor.world.pos.z = Math_CosS(this->dyna.actor.world.rot.y) * temp + this->dyna.actor.home.pos.z; if (this->timer == 0) { this->timer = 20; this->actionFunc = func_8088E760; } func_8002F974(&this->dyna.actor, NA_SE_EV_FIRE_PILLAR - SFX_FLAG); } void func_8088E90C(BgHidanSima* this) { ColliderJntSphElement* elem; s32 i; f32 cos = Math_CosS(this->dyna.actor.world.rot.y + 0x8000); f32 sin = Math_SinS(this->dyna.actor.world.rot.y + 0x8000); for (i = 0; i < 2; i++) { elem = &this->collider.elements[i]; elem->dim.worldSphere.center.x = this->dyna.actor.world.pos.x + sin * elem->dim.modelSphere.center.z; elem->dim.worldSphere.center.y = (s16)this->dyna.actor.world.pos.y + elem->dim.modelSphere.center.y; elem->dim.worldSphere.center.z = this->dyna.actor.world.pos.z + cos * elem->dim.modelSphere.center.z; } } void BgHidanSima_Update(Actor* thisx, GlobalContext* globalCtx) { BgHidanSima* this = (BgHidanSima*)thisx; s32 pad; this->actionFunc(this, globalCtx); if (this->dyna.actor.params != 0) { s32 temp = (this->dyna.actor.world.rot.y == this->dyna.actor.shape.rot.y) ? this->timer : (this->timer + 80); if (this->actionFunc == func_8088E7A8) { temp += 20; } this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y - ((1.0f - cosf(temp * (M_PI / 20))) * 5.0f); if (this->actionFunc == func_8088E7A8) { func_8088E90C(this); CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); } } } Gfx* func_8088EB54(GlobalContext* globalCtx, BgHidanSima* this, Gfx* gfx) { MtxF mtxF; s32 phi_s5; s32 s3; s32 v0; f32 cos; f32 sin; s32 pad[2]; Matrix_MtxFCopy(&mtxF, &gMtxFClear); cos = Math_CosS(this->dyna.actor.world.rot.y + 0x8000); sin = Math_SinS(this->dyna.actor.world.rot.y + 0x8000); phi_s5 = (60 - this->timer) >> 1; phi_s5 = CLAMP_MAX(phi_s5, 3); v0 = 3 - (this->timer >> 1); v0 = CLAMP_MIN(v0, 0); mtxF.xw = this->dyna.actor.world.pos.x + ((79 - ((this->timer % 6) * 4)) + v0 * 25) * sin; mtxF.zw = this->dyna.actor.world.pos.z + ((79 - ((this->timer % 6) * 4)) + v0 * 25) * cos; mtxF.yw = this->dyna.actor.world.pos.y + 40.0f; mtxF.zz = v0 * 0.4f + 1.0f; mtxF.yy = v0 * 0.4f + 1.0f; mtxF.xx = v0 * 0.4f + 1.0f; for (s3 = v0; s3 < phi_s5; s3++) { mtxF.xw += 25.0f * sin; mtxF.zw += 25.0f * cos; mtxF.xx += 0.4f; mtxF.yy += 0.4f; mtxF.zz += 0.4f; gSPSegment(gfx++, 0x09, SEGMENTED_TO_VIRTUAL(sFireballsTexs[(this->timer + s3) % 7])); gSPMatrix(gfx++, Matrix_MtxFToMtx(MATRIX_CHECKFLOATS(&mtxF), Graph_Alloc(globalCtx->state.gfxCtx, sizeof(Mtx))), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(gfx++, gFireTempleFireballDL); } mtxF.xw = this->dyna.actor.world.pos.x + (phi_s5 * 25 + 80) * sin; mtxF.zw = this->dyna.actor.world.pos.z + (phi_s5 * 25 + 80) * cos; gSPSegment(gfx++, 0x09, SEGMENTED_TO_VIRTUAL(sFireballsTexs[(this->timer + s3) % 7])); gSPMatrix(gfx++, Matrix_MtxFToMtx(MATRIX_CHECKFLOATS(&mtxF), Graph_Alloc(globalCtx->state.gfxCtx, sizeof(Mtx))), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(gfx++, gFireTempleFireballDL); return gfx; } void BgHidanSima_Draw(Actor* thisx, GlobalContext* globalCtx) { BgHidanSima* this = (BgHidanSima*)thisx; 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++, gFireTempleStonePlatform1DL); } else { gSPDisplayList(POLY_OPA_DISP++, gFireTempleStonePlatform2DL); if (this->actionFunc == func_8088E7A8) { POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0x14); gDPSetPrimColor(POLY_XLU_DISP++, 0, 1, 255, 255, 0, 150); gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 255); POLY_XLU_DISP = func_8088EB54(globalCtx, this, POLY_XLU_DISP); } } CLOSE_DISPS(globalCtx->state.gfxCtx); }