#include "z_boss_ganon2.h" #include "overlays/actors/ovl_Demo_Gj/z_demo_gj.h" #include "overlays/actors/ovl_En_Zl3/z_en_zl3.h" #include "objects/object_ganon/object_ganon.h" #include "objects/object_ganon2/object_ganon2.h" #include "objects/object_ganon_anime3/object_ganon_anime3.h" #include "objects/object_geff/object_geff.h" #include "soh/frame_interpolation.h" #include #define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_2 | ACTOR_FLAG_4 | ACTOR_FLAG_5) void BossGanon2_Init(Actor* thisx, GlobalContext* globalCtx); void BossGanon2_Destroy(Actor* thisx, GlobalContext* globalCtx); void BossGanon2_Update(Actor* thisx, GlobalContext* globalCtx); void BossGanon2_Draw(Actor* thisx, GlobalContext* globalCtx); void BossGanon2_Reset(void); void func_808FD5C4(BossGanon2* this, GlobalContext* globalCtx); void func_808FD5F4(BossGanon2* this, GlobalContext* globalCtx); void func_808FFDB0(BossGanon2* this, GlobalContext* globalCtx); void func_808FFEBC(BossGanon2* this, GlobalContext* globalCtx); void func_808FFFE0(BossGanon2* this, GlobalContext* globalCtx); void func_80900104(BossGanon2* this, GlobalContext* globalCtx); void func_8090026C(BossGanon2* this, GlobalContext* globalCtx); void func_809002CC(BossGanon2* this, GlobalContext* globalCtx); void func_80900344(BossGanon2* this, GlobalContext* globalCtx); void func_80900580(BossGanon2* this, GlobalContext* globalCtx); void func_80900650(BossGanon2* this, GlobalContext* globalCtx); void func_80900890(BossGanon2* this, GlobalContext* globalCtx); void func_8090120C(BossGanon2* this, GlobalContext* globalCtx); void func_80905DA8(BossGanon2* this, GlobalContext* globalCtx); void func_809060E8(GlobalContext* globalCtx); void BossGanon2_GenShadowTexture(void* shadowTexture, BossGanon2* this, GlobalContext* globalCtx); void BossGanon2_DrawShadowTexture(void* shadowTexture, BossGanon2* this, GlobalContext* globalCtx); const ActorInit Boss_Ganon2_InitVars = { ACTOR_BOSS_GANON2, ACTORCAT_BOSS, FLAGS, OBJECT_GANON2, sizeof(BossGanon2), (ActorFunc)BossGanon2_Init, (ActorFunc)BossGanon2_Destroy, (ActorFunc)BossGanon2_Update, (ActorFunc)BossGanon2_Draw, (ActorResetFunc)BossGanon2_Reset, }; #include "z_boss_ganon2_data.c" Vec3f D_8090EB20; EnZl3* sBossGanon2Zelda; Actor* D_8090EB30; BossGanon2Effect sBossGanon2Particles[100]; s32 sBossGanon2Seed1; s32 sBossGanon2Seed2; s32 sBossGanon2Seed3; Vec3f D_809105D8[4]; Vec3f D_80910608[4]; s8 D_80910638; void BossGanon2_InitRand(s32 seedInit0, s32 seedInit1, s32 seedInit2) { sBossGanon2Seed1 = seedInit0; sBossGanon2Seed2 = seedInit1; sBossGanon2Seed3 = seedInit2; } f32 BossGanon2_RandZeroOne(void) { // Wichmann-Hill algorithm f32 randFloat; sBossGanon2Seed1 = (sBossGanon2Seed1 * 171) % 30269; sBossGanon2Seed2 = (sBossGanon2Seed2 * 172) % 30307; sBossGanon2Seed3 = (sBossGanon2Seed3 * 170) % 30323; randFloat = (sBossGanon2Seed1 / 30269.0f) + (sBossGanon2Seed2 / 30307.0f) + (sBossGanon2Seed3 / 30323.0f); while (randFloat >= 1.0f) { randFloat -= 1.0f; } return fabsf(randFloat); } void func_808FD080(s32 idx, ColliderJntSph* collider, Vec3f* arg2) { collider->elements[idx].dim.worldSphere.center.x = arg2->x; collider->elements[idx].dim.worldSphere.center.y = arg2->y; collider->elements[idx].dim.worldSphere.center.z = arg2->z; collider->elements[idx].dim.worldSphere.radius = collider->elements[idx].dim.modelSphere.radius * collider->elements[idx].dim.scale; } void BossGanon2_SetObjectSegment(BossGanon2* this, GlobalContext* globalCtx, s32 objectId, u8 setRSPSegment) { s32 pad; s32 objectIdx = Object_GetIndex(&globalCtx->objectCtx, objectId); gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[objectIdx].segment); if (setRSPSegment) { OPEN_DISPS(globalCtx->state.gfxCtx); gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[objectIdx].segment); gSPSegment(POLY_XLU_DISP++, 0x06, globalCtx->objectCtx.status[objectIdx].segment); CLOSE_DISPS(globalCtx->state.gfxCtx); } } void func_808FD210(GlobalContext* globalCtx, Vec3f* arg1) { BossGanon2Effect* effect = globalCtx->specialEffects; effect->type = 1; effect->position = *arg1; effect->unk_2E = 0; effect->unk_01 = 0; effect->velocity.x = 25.0f; effect->velocity.y = 15.0f; effect->velocity.z = 0.0f; effect->accel.x = 0.0f; effect->accel.y = -1.0f; effect->accel.z = 0.0f; } void func_808FD27C(GlobalContext* globalCtx, Vec3f* position, Vec3f* velocity, f32 scale) { BossGanon2Effect* effect = globalCtx->specialEffects; s16 i; for (i = 0; i < ARRAY_COUNT(sBossGanon2Particles); i++, effect++) { if (effect->type == 0) { effect->type = 2; effect->position = *position; effect->velocity = *velocity; effect->accel.x = 0.0; effect->accel.y = -1.0f; effect->accel.z = 0.0; effect->unk_38.z = Rand_ZeroFloat(2 * M_PI); effect->unk_38.y = Rand_ZeroFloat(2 * M_PI); effect->unk_38.x = Rand_ZeroFloat(2 * M_PI); effect->scale = scale; break; } } } void BossGanon2_Init(Actor* thisx, GlobalContext* globalCtx) { BossGanon2* this = (BossGanon2*)thisx; s32 pad; s16 i; globalCtx->specialEffects = sBossGanon2Particles; for (i = 0; i < ARRAY_COUNT(sBossGanon2Particles); i++) { sBossGanon2Particles[i].type = 0; } this->actor.colChkInfo.mass = MASS_IMMOVABLE; this->actor.colChkInfo.health = 30; Collider_InitJntSph(globalCtx, &this->unk_424); Collider_SetJntSph(globalCtx, &this->unk_424, &this->actor, &sJntSphInit1, this->unk_464); Collider_InitJntSph(globalCtx, &this->unk_444); Collider_SetJntSph(globalCtx, &this->unk_444, &this->actor, &sJntSphInit2, this->unk_864); BossGanon2_SetObjectSegment(this, globalCtx, OBJECT_GANON, false); SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGanondorfSkel, NULL, NULL, NULL, 0); func_808FD5C4(this, globalCtx); this->actor.naviEnemyId = 0x3E; this->actor.gravity = 0.0f; } void BossGanon2_Destroy(Actor* thisx, GlobalContext* globalCtx) { BossGanon2* this = (BossGanon2*)thisx; SkelAnime_Free(&this->skelAnime, globalCtx); Collider_DestroyJntSph(globalCtx, &this->unk_424); Collider_DestroyJntSph(globalCtx, &this->unk_444); } void func_808FD4D4(BossGanon2* this, GlobalContext* globalCtx, s16 arg2, s16 arg3) { if ((arg2 == 0) || (arg2 == 1)) { Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->unk_1D0, 25.0f, arg3, 8.0f, 500, 10, true); } if ((arg2 == 0) || (arg2 == 2)) { Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->unk_1DC, 25.0f, arg3, 8.0f, 500, 10, true); } Audio_PlayActorSound2(&this->actor, NA_SE_EN_MGANON_WALK); func_80033E88(&this->actor, globalCtx, 2, 0xA); } void func_808FD5C4(BossGanon2* this, GlobalContext* globalCtx) { this->actionFunc = func_808FD5F4; this->actor.flags &= ~ACTOR_FLAG_0; this->actor.world.pos.y = -3000.0f; } void func_808FD5F4(BossGanon2* this, GlobalContext* globalCtx) { s16 pad; u8 sp8D; Player* player; s32 objectIdx; s32 zero = 0; s32 pad2; sp8D = false; player = GET_PLAYER(globalCtx); this->unk_398++; switch (this->unk_39C) { case 0: objectIdx = Object_GetIndex(&globalCtx->objectCtx, OBJECT_GANON_ANIME3); if (Object_IsLoaded(&globalCtx->objectCtx, objectIdx)) { func_80064520(globalCtx, &globalCtx->csCtx); func_8002DF54(globalCtx, &this->actor, 8); this->unk_39E = Gameplay_CreateSubCamera(globalCtx); Gameplay_ChangeCameraStatus(globalCtx, MAIN_CAM, CAM_STAT_WAIT); Gameplay_ChangeCameraStatus(globalCtx, this->unk_39E, CAM_STAT_ACTIVE); this->unk_39C = 1; sBossGanon2Zelda = (EnZl3*)Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_ZL3, 970.0f, 1086.0f, -200.0f, 0, 0, 0, 1); sBossGanon2Zelda->unk_3C8 = 0; sBossGanon2Zelda->actor.world.pos.x = 970.0f; sBossGanon2Zelda->actor.world.pos.y = 1086.0f; sBossGanon2Zelda->actor.world.pos.z = -214.0f; sBossGanon2Zelda->actor.shape.rot.y = -0x7000; this->unk_3BC.x = 0.0f; this->unk_3BC.y = 1.0f; this->unk_3BC.z = 0.0f; this->unk_398 = 0; this->unk_3A4.x = 0.0f; this->unk_3A4.y = 1400.0f; this->unk_3A4.z = 1600.0f; player->actor.world.pos.x = 970.0f; player->actor.world.pos.y = 1086.0f; player->actor.world.pos.z = -186.0f; player->actor.shape.rot.y = -0x5000; Animation_MorphToLoop(&this->skelAnime, &gGanondorfBurstOutAnim, 0.0f); globalCtx->envCtx.unk_D8 = 0.0f; // fake, tricks the compiler into allocating more stack if (zero) { this->unk_3A4.x *= 2.0; } } else { break; } case 1: if (this->unk_398 < 70) { globalCtx->envCtx.unk_D8 = 0.0f; } this->unk_339 = 3; Math_ApproachF(&this->unk_3A4.x, 1500.0f, 0.1f, this->unk_410.x * 1500.0f); Math_ApproachF(&this->unk_3A4.z, -160.0f, 0.1f, this->unk_410.x * 1760.0f); Math_ApproachF(&this->unk_410.x, 0.0075f, 1.0f, 0.0001f); this->unk_3B0.x = -200.0f; this->unk_3B0.y = 1086.0f; this->unk_3B0.z = -200.0f; if (this->unk_398 == 150) { Message_StartTextbox(globalCtx, 0x70D3, NULL); } if (this->unk_398 > 250 && Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_NONE) { this->unk_39C = 2; this->unk_398 = 0; this->unk_410.x = 0.0f; globalCtx->envCtx.unk_D8 = 1.0f; } else { break; } case 2: this->unk_339 = 4; player->actor.world.pos.x = 970.0f; player->actor.world.pos.y = 1086.0f; player->actor.world.pos.z = -166.0f; sBossGanon2Zelda->actor.world.pos.x = 974.0f; sBossGanon2Zelda->actor.world.pos.y = 1086.0f; sBossGanon2Zelda->actor.world.pos.z = -186.0f; player->actor.shape.rot.y = -0x5000; sBossGanon2Zelda->actor.shape.rot.y = -0x5000; if (this->unk_398 == 60) { Message_StartTextbox(globalCtx, 0x70D4, NULL); } if (this->unk_398 == 40) { sBossGanon2Zelda->unk_3C8 = 1; func_8002DF54(globalCtx, &this->actor, 0x4E); } if (this->unk_398 == 85) { sBossGanon2Zelda->unk_3C8 = 2; func_8002DF54(globalCtx, &this->actor, 0x4F); } this->unk_3A4.x = 930.0f; this->unk_3A4.y = 1129.0f; this->unk_3A4.z = -181.0f; this->unk_3B0.x = player->actor.world.pos.x; this->unk_3B0.z = (player->actor.world.pos.z - 15.0f) + 5.0f; if (this->unk_398 > 104) { Math_ApproachF(&this->unk_3B0.y, player->actor.world.pos.y + 47.0f + 7.0f + 15.0f, 0.1f, this->unk_410.x); Math_ApproachF(&this->unk_410.x, 2.0f, 1.0f, 0.1f); } else { this->unk_3B0.y = player->actor.world.pos.y + 47.0f + 7.0f; } if ((this->unk_398 > 170) && (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_NONE)) { this->unk_39C = 3; this->unk_398 = 0; this->unk_410.x = 0.0f; } break; case 3: Math_ApproachF(&this->unk_3B0.y, player->actor.world.pos.y + 47.0f + 7.0f, 0.1f, 2.0f); this->unk_339 = 4; if (this->unk_398 == 10) { func_80078914(&D_80906D6C, NA_SE_EV_STONE_BOUND); Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_STOP); } if (this->unk_398 == 20) { sBossGanon2Zelda->unk_3C8 = 3; func_8002DF54(globalCtx, &this->actor, 0x50); } if (this->unk_398 == 55) { this->unk_39C = 4; this->unk_398 = 0; this->unk_410.x = 0.0f; sBossGanon2Zelda->unk_3C8 = 4; func_8002DF54(globalCtx, &this->actor, 0x50); } break; case 4: this->unk_339 = 4; Math_ApproachF(&this->unk_3A4.x, -360.0f, 0.1f, this->unk_410.x * 1290.0f); Math_ApproachF(&this->unk_3A4.z, -20.0f, 0.1f, this->unk_410.x * 170.0f); Math_ApproachF(&this->unk_410.x, 0.04f, 1.0f, 0.0005f); if (this->unk_398 == 100) { Camera* camera = Gameplay_GetCamera(globalCtx, MAIN_CAM); camera->eye = this->unk_3A4; camera->eyeNext = this->unk_3A4; camera->at = this->unk_3B0; func_800C08AC(globalCtx, this->unk_39E, 0); this->unk_39E = 0; func_80064534(globalCtx, &globalCtx->csCtx); func_8002DF54(globalCtx, &this->actor, 7); this->unk_39C = 5; this->unk_398 = 0; } break; case 5: this->unk_339 = 4; if (this->actor.xzDistToPlayer < 500.0f) { Message_CloseTextbox(globalCtx); this->unk_39C = 10; this->unk_398 = 0; func_80064520(globalCtx, &globalCtx->csCtx); this->unk_39E = Gameplay_CreateSubCamera(globalCtx); Gameplay_ChangeCameraStatus(globalCtx, MAIN_CAM, CAM_STAT_WAIT); Gameplay_ChangeCameraStatus(globalCtx, this->unk_39E, CAM_STAT_ACTIVE); } else { break; } case 10: player->actor.world.pos.x = 490.0f; player->actor.world.pos.y = 1086.0f; player->actor.world.pos.z = -166.0f; sBossGanon2Zelda->actor.world.pos.x = 724.0f; sBossGanon2Zelda->actor.world.pos.y = 1086.0f; sBossGanon2Zelda->actor.world.pos.z = -186.0f; player->actor.shape.rot.y = -0x4000; sBossGanon2Zelda->actor.shape.rot.y = -0x5000; this->unk_3A4.x = 410.0f; this->unk_3A4.y = 1096.0f; this->unk_3A4.z = -110.0f; this->unk_3B0.x = player->actor.world.pos.x + 10.0f; this->unk_3B0.y = (player->actor.world.pos.y + 200.0f) - 160.0f; this->unk_3B0.z = player->actor.world.pos.z; if (this->unk_398 >= 20) { func_80078884(NA_SE_EN_GOMA_LAST - SFX_FLAG); Math_ApproachF(&this->unk_324, 255.0f, 1.0f, 10.0f); this->unk_339 = 5; if (this->unk_398 == 20) { this->unk_33C = 0.0f; globalCtx->envCtx.unk_D8 = 0.0f; } } else { this->unk_339 = 4; } if (this->unk_398 == 30) { sBossGanon2Zelda->unk_3C8 = 5; func_8002DF54(globalCtx, &this->actor, 0x51); } if (this->unk_398 == 50) { this->unk_398 = 0; this->unk_39C = 11; } break; case 11: this->unk_339 = 5; func_80078884(NA_SE_EN_GOMA_LAST - SFX_FLAG); player->actor.world.pos.x = 490.0f; player->actor.world.pos.y = 1086.0f; player->actor.world.pos.z = -166.0f; sBossGanon2Zelda->actor.world.pos.x = 724.0f; sBossGanon2Zelda->actor.world.pos.y = 1086.0f; sBossGanon2Zelda->actor.world.pos.z = -186.0f; player->actor.shape.rot.y = -0x4000; sBossGanon2Zelda->actor.shape.rot.y = -0x5000; this->unk_3A4.x = 450.0f; this->unk_3A4.y = 1121.0f; this->unk_3A4.z = -158.0f; this->unk_3B0.x = (player->actor.world.pos.x - 20.0f) + 2.0f; this->unk_3B0.y = ((player->actor.world.pos.y + 200.0f) - 151.0f) - 2.0f; this->unk_3B0.z = player->actor.world.pos.z + 2.0f; if (this->unk_398 == 10) { func_80078914(&D_80906D6C, NA_SE_EV_STONE_BOUND); } if (this->unk_398 == 20) { func_80078884(NA_SE_EV_STONE_BOUND); } if (this->unk_398 == 30) { func_8002DF54(globalCtx, &this->actor, 0x52); } if (this->unk_398 == 50) { this->unk_398 = 0; this->unk_39C = 12; Animation_MorphToPlayOnce(&this->skelAnime, &gGanondorfBurstOutAnim, 0.0f); this->unk_194 = Animation_GetLastFrame(&gGanondorfBurstOutAnim); this->actor.world.pos.x = this->actor.world.pos.z = -200.0f; this->actor.world.pos.y = 1009.0f; this->actor.shape.yOffset = 7000.0f; this->actor.world.rot.y = 0x5000; this->unk_3A4.x = -60.0f; this->unk_3A4.y = 1106.0f; this->unk_3A4.z = -200.0f; this->unk_3B0.x = this->unk_3B0.z = -200.0f; this->unk_3B0.y = this->actor.world.pos.y + 70.0f; globalCtx->envCtx.unk_D8 = 0.0f; globalCtx->envCtx.unk_BE = globalCtx->envCtx.unk_BD = 0; this->unk_339 = 0; } else { break; } case 12: case 13: SkelAnime_Update(&this->skelAnime); if (this->unk_398 == 30) { D_80906D78 = 1; this->unk_314 = 1; func_800A9F6C(0.0f, 0xC8, 0x14, 0x14); } if (this->unk_398 == 30) { func_80078884(NA_SE_EV_GRAVE_EXPLOSION); } if (this->unk_398 >= 30) { Math_ApproachF(&this->actor.world.pos.y, 1289.0f, 0.1f, 10.0f); this->unk_3B0.y = this->actor.world.pos.y + 70.0f; } if (Animation_OnFrame(&this->skelAnime, this->unk_194)) { Animation_MorphToLoop(&this->skelAnime, &gGanondorfFloatingHeavyBreathingAnim, 0.0f); this->unk_39C = 14; this->unk_398 = 0; this->actor.world.pos.x = -200.0f; this->actor.world.pos.y = this->actor.world.pos.y - 30.0f; this->actor.world.pos.z = -200.0f; Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_OPENING_GANON); } else { break; } case 14: SkelAnime_Update(&this->skelAnime); Math_ApproachF(&this->actor.world.pos.y, 1289.0f, 0.05f, 1.0f); player->actor.world.pos.x = 250.0f; player->actor.world.pos.y = 1086.0f; player->actor.world.pos.z = -266.0f; player->actor.shape.rot.y = -0x4000; sBossGanon2Zelda->actor.world.pos.x = 724.0f; sBossGanon2Zelda->actor.world.pos.y = 1086.0f; sBossGanon2Zelda->actor.world.pos.z = -186.0f; this->unk_3A4.x = this->actor.world.pos.x + -10.0f; this->unk_3A4.y = this->actor.world.pos.y + 80.0f; this->unk_3A4.z = this->actor.world.pos.z + 50.0f; this->unk_3B0.x = player->actor.world.pos.x; this->unk_3B0.y = player->actor.world.pos.y; this->unk_3B0.z = player->actor.world.pos.z - 200.0f; if (this->unk_398 == 20) { func_8002DF54(globalCtx, &this->actor, 0x1E); } if (this->unk_398 == 60) { this->unk_3A4.x = (this->actor.world.pos.x + 200.0f) - 154.0f; this->unk_3A4.y = this->actor.world.pos.y + 60.0f; this->unk_3A4.z = this->actor.world.pos.z - 15.0f; this->unk_39C = 15; this->unk_398 = 0; this->unk_3B0.y = this->actor.world.pos.y + 77.0f + 100.0f; this->unk_314 = 2; this->unk_3B0.z = this->actor.world.pos.z + 5.0f; this->unk_3B0.x = this->actor.world.pos.x; } if ((globalCtx->gameplayFrames % 32) == 0) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_BREATH); } break; case 15: if (((globalCtx->gameplayFrames % 32) == 0) && (this->unk_398 < 100)) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_BREATH); } SkelAnime_Update(&this->skelAnime); Math_ApproachF(&this->unk_3B0.y, this->actor.world.pos.y + 77.0f, 0.05f, 5.0f); if (this->unk_398 >= 50) { if (this->unk_398 == 50) { Animation_MorphToPlayOnce(&this->skelAnime, &gGanondorfShowTriforceStartAnim, 0.0f); this->unk_194 = Animation_GetLastFrame(&gGanondorfShowTriforceStartAnim); this->unk_314 = 3; } if (Animation_OnFrame(&this->skelAnime, this->unk_194)) { Animation_MorphToLoop(&this->skelAnime, &gGanondorfShowTriforceLoopAnim, 0.0f); this->unk_194 = 1000.0f; } } if (this->unk_398 > 70) { Math_ApproachF(&this->unk_1B4, 255.0f, 1.0f, 10.0f); } if (this->unk_398 == 140) { this->unk_39C = 16; this->unk_398 = 0; Animation_MorphToPlayOnce(&this->skelAnime, &gGanondorfTransformStartAnim, 0.0f); this->unk_194 = Animation_GetLastFrame(&gGanondorfTransformStartAnim); this->unk_339 = 55; globalCtx->envCtx.unk_D8 = 1.0f; Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_CASBREAK); } else { break; } case 16: if (this->unk_398 < 25) { this->unk_339 = 55; } else { this->unk_339 = 6; if (this->unk_194 > 100.0f) { Math_ApproachF(&this->unk_30C, 15.0f, 1.0f, 2.0f); } else { Math_ApproachF(&this->unk_30C, 7.0f, 1.0f, 0.2f); } } this->unk_1B4 = 0.0f; SkelAnime_Update(&this->skelAnime); if (Animation_OnFrame(&this->skelAnime, this->unk_194)) { Animation_MorphToPlayOnce(&this->skelAnime, &gGanondorfTransformEndAnim, 0.0f); this->unk_194 = 1000.0f; } Math_ApproachF(&this->unk_3A4.x, (this->actor.world.pos.x + 200.0f) - 90.0f, 0.1f, 6.3999996f); Math_ApproachF(&this->unk_3A4.y, ((this->actor.world.pos.y + 60.0f) - 60.0f) - 70.0f, 0.1f, 13.0f); Math_ApproachF(&this->unk_3B0.y, this->actor.world.pos.y + 40.0f, 0.1f, 3.6999998f); if (this->unk_398 == 30) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_BIGMASIC); Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_THROW_BIG); } if (this->unk_398 <= 50) { sp8D = true; } if (this->unk_398 >= 60) { Camera* camera = Gameplay_GetCamera(globalCtx, MAIN_CAM); camera->eye = this->unk_3A4; camera->eyeNext = this->unk_3A4; camera->at = this->unk_3B0; this->unk_39C = 17; this->unk_398 = 0; this->unk_337 = 2; BossGanon2_SetObjectSegment(this, globalCtx, OBJECT_GANON2, false); SkelAnime_Free(&this->skelAnime, globalCtx); SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGanonSkel, NULL, NULL, NULL, 0); BossGanon2_SetObjectSegment(this, globalCtx, OBJECT_GANON_ANIME3, false); func_8002DF54(globalCtx, &this->actor, 0x54); this->unk_314 = 3; // At this point, the actor has Ganon's skeleton but is still playing an animation for Ganondorf. This // causes issues when trying to access the limb posotions as Ganon has more limbs than Ganondorf. When // animating, data from past the end of the animation data is accessed. This is a hack solution so // that we are at least playing an animation meant for Ganon. There is no visible change since Ganon is // off-screen. There is actually 1 frame where he is visible, and in the vanilla game he is an // explosion of limbs since half of them are in random positions from the junk data accessed. Animation_PlayOnce(&this->skelAnime, &gGanonUncurlAndFlailAnim); } // fake, tricks the compiler into using stack the way we need it to if (zero) { Math_ApproachF(&this->unk_3B0.y, 0.0f, 0.0f, 0.0f); } break; case 17: this->unk_339 = 6; SkelAnime_Update(&this->skelAnime); this->unk_3A4.x = player->actor.world.pos.x - 40.0f; this->unk_3A4.y = player->actor.world.pos.y + 40.0f; this->unk_3A4.z = player->actor.world.pos.z + 20.0f; this->unk_3B0.x = player->actor.world.pos.x; this->unk_3B0.y = (player->actor.world.pos.y + 10.0f + 60.0f) - 30.0f; this->unk_3B0.z = player->actor.world.pos.z; if (this->unk_398 == 25) { this->unk_39C = 18; this->unk_398 = 0; Animation_MorphToPlayOnce(&this->skelAnime, &gGanonUncurlAndFlailAnim, 0.0f); this->skelAnime.playSpeed = 0.0f; this->unk_3A4.x = ((this->actor.world.pos.x + 500.0f) - 350.0f) - 50.0f; this->unk_3A4.y = this->actor.world.pos.y; this->unk_3A4.z = this->actor.world.pos.z; this->unk_3B0.x = this->actor.world.pos.x + 50.0f; this->unk_3B0.y = this->actor.world.pos.y + 60.0f; this->unk_3B0.z = this->actor.world.pos.z; this->actor.world.rot.y = 0x4000; } break; case 18: this->unk_339 = 6; if (this->unk_398 == 30) { Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_GANON_BOSS); } Math_ApproachF(&this->unk_30C, 7.0f, 1.0f, 0.1f); Math_ApproachF(&this->unk_3A4.x, (this->actor.world.pos.x + 500.0f) - 350.0f, 0.1f, 1.0f); Math_ApproachF(&this->unk_3B0.x, this->actor.world.pos.x, 0.1f, 1.0f); Math_ApproachF(&this->unk_228, 1.0f, 0.1f, 0.02f); if (this->unk_398 == 65) { this->unk_39C = 19; this->unk_398 = 0; } break; case 19: this->unk_394 += 0.5f; this->unk_339 = 6; this->actor.world.pos.y += this->actor.velocity.y; this->actor.velocity.y -= 1.0f; if (this->unk_398 == 10) { this->unk_39C = 20; this->unk_398 = 0; this->actor.world.pos.x += 250; this->actor.world.pos.y = 1886.0f; this->unk_394 = 0.0f; func_8002DF54(globalCtx, &this->actor, 0x53); this->unk_30C = 5.0f; this->unk_228 = 1.0f; } break; case 20: this->unk_339 = 6; SkelAnime_Update(&this->skelAnime); this->actor.world.pos.y += this->actor.velocity.y; this->actor.velocity.y -= 1.0f; player->actor.world.pos.x = 250.0f; player->actor.world.pos.y = 1086.0f; player->actor.world.pos.z = -266.0f; player->actor.shape.rot.y = -0x4000; this->unk_3A4.x = (player->actor.world.pos.x - 40.0f) - 200.0f; this->unk_3A4.y = (player->actor.world.pos.y + 40.0f) - 30.0f; this->unk_3A4.z = (player->actor.world.pos.z - 20.0f) + 100.0f; this->unk_3B0.x = player->actor.world.pos.x; this->unk_3B0.y = ((player->actor.world.pos.y + 10.0f + 60.0f) - 20.0f) + 30.0f; this->unk_3B0.z = player->actor.world.pos.z; this->unk_3BC.x = 0.8f; if (this->actor.world.pos.y <= 1099.0f) { this->actor.world.pos.y = 1099.0f; this->unk_39C = 21; this->unk_398 = 0; this->unk_420 = 10.0f; this->actor.velocity.y = 0.0f; Animation_MorphToPlayOnce(&this->skelAnime, &gGanonUncurlAndFlailAnim, 0.0f); func_808FD4D4(this, globalCtx, 0, 3); func_800A9F6C(0.0f, 0xC8, 0x14, 0x14); } break; case 21: this->unk_339 = 6; SkelAnime_Update(&this->skelAnime); this->unk_41C = Math_CosS(globalCtx->gameplayFrames * 0x8000) * this->unk_420; Math_ApproachZeroF(&this->unk_420, 1.0f, 0.75f); if (this->unk_398 == 30) { this->unk_39C = 22; this->unk_30C = 10.0f; } else { break; } case 22: if (this->unk_398 < 60) { this->unk_339 = 7; } this->unk_3BC.x = 0.0f; this->actor.world.pos.y = 1099.0f; SkelAnime_Update(&this->skelAnime); Math_ApproachZeroF(&this->unk_30C, 1.0f, 0.1f); if (this->unk_398 > 50) { Math_ApproachF(&this->unk_224, 1.0f, 1.0f, 0.025f); } if (this->unk_398 == 60) { this->unk_336 = 2; } if (this->unk_398 == 80) { BossGanon2_SetObjectSegment(this, globalCtx, OBJECT_GANON2, false); TitleCard_InitBossName(globalCtx, &globalCtx->actorCtx.titleCtx, SEGMENTED_TO_VIRTUAL(gGanonTitleCardTex), 160, 180, 128, 40, true); //It has translation but they are all the same. they all say "GANON" only } this->unk_3A4.x = ((this->actor.world.pos.x + 500.0f) - 350.0f) + 100.0f; this->unk_3A4.y = this->actor.world.pos.y; this->unk_3A4.z = this->actor.world.pos.z; this->unk_3B0.x = this->actor.world.pos.x; this->unk_3B0.z = this->actor.world.pos.z; this->unk_3B0.y = (this->unk_1B8.y + 60.0f) - 40.0f; if (this->unk_398 > 166 && this->unk_398 < 173) { this->unk_312 = 2; } if (this->unk_398 > 186 && this->unk_398 < 196) { this->unk_312 = 1; } if (this->unk_398 > 202 && this->unk_398 < 210) { this->unk_312 = 2; } if ((this->unk_398 == 166) || (this->unk_398 == 185) || (this->unk_398 == 200)) { func_80078884(NA_SE_EN_MGANON_SWORD); func_80078884(NA_SE_EN_MGANON_ROAR); } if (this->unk_398 == 215) { this->unk_39C = 23; this->unk_224 = 0.0f; func_8002DF54(globalCtx, &this->actor, 0x55); } break; case 23: SkelAnime_Update(&this->skelAnime); if (this->unk_398 > 222 && this->unk_398 < 232) { this->unk_312 = 2; } if (this->unk_398 == 222) { func_80078884(NA_SE_EN_MGANON_SWORD); func_80078884(NA_SE_EN_MGANON_ROAR); } this->unk_3A4.x = (player->actor.world.pos.x - 40.0f) + 6.0f; this->unk_3A4.y = player->actor.world.pos.y + 40.0f; this->unk_3A4.z = (player->actor.world.pos.z + 20.0f) - 7.0f; this->unk_3B0.x = player->actor.world.pos.x; this->unk_3B0.y = ((player->actor.world.pos.y + 10.0f + 60.0f) - 20.0f) - 2.0f; this->unk_3B0.z = player->actor.world.pos.z; if (this->unk_398 == 228) { func_80078884(NA_SE_IT_SHIELD_REFLECT_SW); func_8002DF54(globalCtx, &this->actor, 0x56); func_800A9F6C(0.0f, 0xFF, 0xA, 0x32); } if (this->unk_398 >= 229) { globalCtx->envCtx.fillScreen = true; globalCtx->envCtx.screenFillColor[0] = globalCtx->envCtx.screenFillColor[1] = globalCtx->envCtx.screenFillColor[2] = 255; globalCtx->envCtx.screenFillColor[3] = 100; if (this->unk_398 == 234) { Vec3f sp68; globalCtx->envCtx.fillScreen = false; this->unk_39C = 24; this->unk_398 = 0; sp68 = player->actor.world.pos; sp68.y += 60.0f; func_808FD210(globalCtx, &sp68); globalCtx->envCtx.unk_D8 = 0.0f; globalCtx->envCtx.unk_BE = 0; this->unk_339 = 0; } } break; case 24: SkelAnime_Update(&this->skelAnime); if (1) { BossGanon2Effect* effect = globalCtx->specialEffects; this->unk_3B0 = effect->position; this->unk_3A4.x = effect->position.x + 70.0f; this->unk_3A4.y = effect->position.y - 30.0f; this->unk_3A4.z = effect->position.z + 70.0f; } if ((this->unk_398 & 3) == 0) { func_80078884(NA_SE_IT_SWORD_SWING); } if (this->unk_398 == 25) { func_8002DF54(globalCtx, &this->actor, 0x57); this->unk_39C = 25; this->unk_398 = 0; } break; case 25: SkelAnime_Update(&this->skelAnime); this->unk_3A4.x = (player->actor.world.pos.x - 40.0f) + 80.0f; this->unk_3A4.y = player->actor.world.pos.y + 40.0f + 10.0f; this->unk_3A4.z = player->actor.world.pos.z + 20.0f + 10.0f; this->unk_3B0.x = player->actor.world.pos.x - 20.0f; this->unk_3B0.y = ((player->actor.world.pos.y + 10.0f + 60.0f) - 20.0f) - 3.0f; this->unk_3B0.z = (player->actor.world.pos.z - 40.0f) - 10.0f; if (this->unk_398 == 10) { BossGanon2Effect* effect = globalCtx->specialEffects; effect->unk_2E = 1; effect->position.x = sBossGanon2Zelda->actor.world.pos.x + 50.0f + 10.0f; effect->position.y = sBossGanon2Zelda->actor.world.pos.y + 350.0f; effect->position.z = sBossGanon2Zelda->actor.world.pos.z - 25.0f; effect->velocity.x = 0.0f; effect->velocity.z = 0.0f; effect->velocity.y = -30.0f; this->unk_39C = 26; this->unk_398 = 0; } else { break; } case 26: this->unk_3A4.x = sBossGanon2Zelda->actor.world.pos.x + 100.0f + 30.0f; this->unk_3A4.y = sBossGanon2Zelda->actor.world.pos.y + 10.0f; this->unk_3A4.z = sBossGanon2Zelda->actor.world.pos.z + 5.0f; this->unk_3B0.x = sBossGanon2Zelda->actor.world.pos.x; this->unk_3B0.y = sBossGanon2Zelda->actor.world.pos.y + 30.0f; this->unk_3B0.z = sBossGanon2Zelda->actor.world.pos.z - 20.0f; this->unk_3BC.z = -0.5f; if (this->unk_398 == 13) { sBossGanon2Zelda->unk_3C8 = 6; } if (this->unk_398 == 50) { this->unk_39C = 27; this->unk_398 = 0; } break; case 27: this->unk_3BC.z = 0.0f; if (this->unk_398 == 4) { func_8002DF54(globalCtx, &this->actor, 0x58); } this->unk_3A4.x = player->actor.world.pos.x - 20.0f; this->unk_3A4.y = player->actor.world.pos.y + 50.0f; this->unk_3A4.z = player->actor.world.pos.z; this->unk_3B0.x = player->actor.world.pos.x; this->unk_3B0.y = player->actor.world.pos.y + 50.0f; this->unk_3B0.z = player->actor.world.pos.z; if (this->unk_398 == 26) { D_8090EB30 = globalCtx->actorCtx.actorLists[ACTORCAT_ITEMACTION].head; while (D_8090EB30 != NULL) { if (D_8090EB30->id == ACTOR_EN_ELF) { this->unk_3A4.x = D_8090EB30->world.pos.x - 30.0f; this->unk_3A4.y = D_8090EB30->world.pos.y; this->unk_3A4.z = D_8090EB30->world.pos.z; this->unk_3B0.x = D_8090EB30->world.pos.x; this->unk_3B0.y = D_8090EB30->world.pos.y; this->unk_3B0.z = D_8090EB30->world.pos.z; break; } D_8090EB30 = D_8090EB30->next; } this->unk_39C = 28; this->unk_398 = 0; } break; case 28: if (this->unk_398 == 5) { Message_StartTextbox(globalCtx, 0x70D6, NULL); } if (D_8090EB30 != NULL) { this->unk_3A4.x = D_8090EB30->world.pos.x - 20.0f; this->unk_3A4.y = D_8090EB30->world.pos.y; this->unk_3A4.z = D_8090EB30->world.pos.z; Math_ApproachF(&this->unk_3B0.x, D_8090EB30->world.pos.x, 0.2f, 50.0f); Math_ApproachF(&this->unk_3B0.y, D_8090EB30->world.pos.y, 0.2f, 50.0f); Math_ApproachF(&this->unk_3B0.z, D_8090EB30->world.pos.z, 0.2f, 50.0f); if ((this->unk_398 > 40) && (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_NONE)) { this->unk_39C = 29; this->unk_398 = 0; Animation_MorphToPlayOnce(&this->skelAnime, &gGanonRoarAnim, 0.0f); this->unk_194 = Animation_GetLastFrame(&gGanonRoarAnim); this->actor.shape.yOffset = 0.0f; this->actor.world.pos.y = 1086.0f; this->actor.gravity = -1.0f; this->unk_335 = 1; this->unk_224 = 1.0f; } } break; case 29: SkelAnime_Update(&this->skelAnime); this->unk_3A4.x = (((this->actor.world.pos.x + 500.0f) - 350.0f) + 100.0f) - 60.0f; this->unk_3B0.x = this->actor.world.pos.x; this->unk_3B0.z = this->actor.world.pos.z; this->unk_3A4.y = this->actor.world.pos.y; this->unk_3A4.z = this->actor.world.pos.z + 10.0f; this->unk_3B0.y = (this->unk_1B8.y + 60.0f) - 40.0f; player->actor.shape.rot.y = -0x4000; player->actor.world.pos.x = 140.0f; player->actor.world.pos.z = -196.0f; if (this->unk_398 == 50) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_MGANON_ROAR); } if (Animation_OnFrame(&this->skelAnime, this->unk_194)) { Camera* camera = Gameplay_GetCamera(globalCtx, MAIN_CAM); camera->eye = this->unk_3A4; camera->eyeNext = this->unk_3A4; camera->at = this->unk_3B0; func_800C08AC(globalCtx, this->unk_39E, 0); this->unk_39E = 0; func_80064534(globalCtx, &globalCtx->csCtx); func_8002DF54(globalCtx, &this->actor, 7); this->unk_39C = 0; this->unk_337 = 1; func_808FFDB0(this, globalCtx); this->unk_1A2[1] = 50; this->actor.flags |= ACTOR_FLAG_0; sBossGanon2Zelda->unk_3C8 = 7; } break; } if ((this->unk_30C > 4.0f) && !sp8D) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_BODY_SPARK - SFX_FLAG); } if (this->unk_39E != 0) { // fake, tricks the compiler into putting some pointers on the stack if (zero) { osSyncPrintf(NULL, 0, 0); } this->unk_3B0.y += this->unk_41C; Gameplay_CameraSetAtEyeUp(globalCtx, this->unk_39E, &this->unk_3B0, &this->unk_3A4, &this->unk_3BC); } } void func_808FF898(BossGanon2* this, GlobalContext* globalCtx) { if ((this->unk_312 != 0) && (this->unk_39E == 0)) { Actor* actor = globalCtx->actorCtx.actorLists[ACTORCAT_PROP].head; while (actor != NULL) { if (actor->id == ACTOR_DEMO_GJ) { DemoGj* gj = (DemoGj*)actor; if (((actor->params & 0xFF) == 0x10) || ((actor->params & 0xFF) == 0x11) || ((actor->params & 0xFF) == 0x16)) { if (SQ(this->unk_218.x - gj->dyna.actor.world.pos.x) + SQ(this->unk_218.z - gj->dyna.actor.world.pos.z) < SQ(100.0f)) { s32 pad; Vec3f sp28; Matrix_RotateY(((this->actor.shape.rot.y / (f32)0x8000) * M_PI) + 0.5f, MTXMODE_NEW); sp28.x = 0.0f; sp28.y = 0.0f; sp28.z = 1.0f; Matrix_MultVec3f(&sp28, &gj->unk_26C); gj->killFlag = true; func_800A9F6C(0.0f, 0x96, 0x14, 0x32); this->unk_392 = 6; return; } } } actor = actor->next; } if (this->unk_392 == 4) { func_80078884(NA_SE_EV_GRAVE_EXPLOSION); } if (this->unk_392 == 3) { func_80078884(NA_SE_EN_MGANON_SWDIMP); } } } s32 func_808FFA24(BossGanon2* this, GlobalContext* globalCtx) { Actor* actor = globalCtx->actorCtx.actorLists[ACTORCAT_PROP].head; while (actor != NULL) { if (actor->id == ACTOR_DEMO_GJ) { DemoGj* gj = (DemoGj*)actor; if (((actor->params & 0xFF) == 0x10) || ((actor->params & 0xFF) == 0x11) || ((actor->params & 0xFF) == 0x16)) { if (SQ(this->actor.world.pos.x - gj->dyna.actor.world.pos.x) + SQ(this->actor.world.pos.z - gj->dyna.actor.world.pos.z) < SQ(200.0f)) { return true; } } } actor = actor->next; } return false; } void func_808FFAC8(BossGanon2* this, GlobalContext* globalCtx, u8 arg2) { s16 temp_v1; s16 phi_a1; if (this->unk_313 || (arg2 != 0)) { phi_a1 = this->actor.shape.rot.y - this->actor.yawTowardsPlayer; if (phi_a1 > 0x3000) { phi_a1 = 0x3000; } else if (phi_a1 < -0x3000) { phi_a1 = -0x3000; } } else if (this->unk_19C & 0x20) { phi_a1 = 0x3000; } else { phi_a1 = -0x3000; } Math_ApproachS(&this->unk_31A, phi_a1, 5, 0x7D0); temp_v1 = Math_Atan2S(this->actor.xzDistToPlayer, 150.0f) - 0xBB8; temp_v1 = CLAMP_MAX(temp_v1, 0x1B58); temp_v1 = CLAMP_MIN(temp_v1, -0x1B58); Math_ApproachS(&this->unk_31C, temp_v1, 5, 0x7D0); } void func_808FFBBC(BossGanon2* this, GlobalContext* globalCtx, u8 arg2) { if (arg2 != 0 || this->unk_313) { f32 phi_f0; f32 phi_f2; Math_ApproachS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 5, this->unk_320); if (this->unk_334 != 0) { phi_f0 = 5000.0f; phi_f2 = 200.0f; } else { phi_f0 = 3000.0f; phi_f2 = 30.0f; } Math_ApproachF(&this->unk_320, phi_f0, 1.0f, phi_f2); } else { this->unk_320 = 0.0f; } } void func_808FFC84(BossGanon2* this) { if (ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) < 0x2800) { this->unk_313 = true; this->actor.focus.pos = this->unk_1B8; } else { this->unk_313 = false; this->actor.focus.pos = this->unk_1C4; } } void func_808FFCFC(BossGanon2* this, GlobalContext* globalCtx) { if (this->actor.xzDistToPlayer < 150.0f && ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) < 0x2800) { this->unk_311 = false; func_80900580(this, globalCtx); Audio_StopSfxById(NA_SE_EN_MGANON_UNARI); } else if ((this->actor.bgCheckFlags & 8) && func_808FFA24(this, globalCtx)) { this->unk_311 = false; func_80900580(this, globalCtx); Audio_StopSfxById(NA_SE_EN_MGANON_UNARI); } } void func_808FFDB0(BossGanon2* this, GlobalContext* globalCtx) { s32 sp28; s32 objectIdx = Object_GetIndex(&globalCtx->objectCtx, OBJECT_GANON2); if (Object_IsLoaded(&globalCtx->objectCtx, objectIdx)) { gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[objectIdx].segment); Animation_MorphToLoop(&this->skelAnime, &gGanonGuardIdleAnim, -10.0f); this->actionFunc = func_808FFEBC; if (this->unk_334 != 0) { this->unk_1A2[0] = Rand_ZeroFloat(30.0f); } else { this->unk_1A2[0] = 40; } this->unk_336 = 1; this->actor.flags |= ACTOR_FLAG_0; this->unk_228 = 1.0f; this->unk_224 = 1.0f; } else { this->actionFunc = func_808FFDB0; } } void func_808FFEBC(BossGanon2* this, GlobalContext* globalCtx) { if (this->unk_390 == 0) { this->unk_390 = (s16)Rand_ZeroFloat(50.0f) + 30; Audio_PlayActorSound2(&this->actor, NA_SE_EN_MGANON_UNARI); } SkelAnime_Update(&this->skelAnime); Math_ApproachZeroF(&this->actor.speedXZ, 0.5f, 1.0f); if (this->unk_1A2[0] == 0) { func_809002CC(this, globalCtx); } else if (this->unk_1A2[1] == 0) { func_808FFCFC(this, globalCtx); } func_808FFAC8(this, globalCtx, 0); func_808FFBBC(this, globalCtx, 0); } void func_808FFF90(BossGanon2* this, GlobalContext* globalCtx) { Animation_MorphToLoop(&this->skelAnime, &gGanonGuardIdleAnim, -10.0f); this->actionFunc = func_808FFFE0; this->unk_1A2[0] = 40; } void func_808FFFE0(BossGanon2* this, GlobalContext* globalCtx) { s16 target; SkelAnime_Update(&this->skelAnime); Math_ApproachZeroF(&this->actor.speedXZ, 0.5f, 1.0f); if (this->unk_1A2[0] == 0) { func_809002CC(this, globalCtx); } if (this->unk_1A2[0] < 30 && this->unk_1A2[0] >= 10) { target = Math_SinS(this->unk_1A2[0] * 0x3000) * (f32)0x2000; } else { target = 0; } Math_ApproachS(&this->unk_31A, target, 2, 0x4000); } void func_809000A0(BossGanon2* this, GlobalContext* globalCtx) { Animation_MorphToLoop(&this->skelAnime, &gGanonStunStartAnim, -2.0f); this->unk_194 = Animation_GetLastFrame(&gGanonStunStartAnim); this->unk_1AC = 0; this->actionFunc = func_80900104; } void func_80900104(BossGanon2* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); Math_ApproachZeroF(&this->actor.speedXZ, 0.5f, 1.0f); switch (this->unk_1AC) { case 0: if (Animation_OnFrame(&this->skelAnime, this->unk_194)) { this->unk_1AC = 1; Animation_MorphToLoop(&this->skelAnime, &gGanonStunLoopAnim, 0.0f); this->unk_1A2[0] = 80; } break; case 1: if (this->unk_1A2[0] == 0) { this->unk_1AC = 2; Animation_MorphToLoop(&this->skelAnime, &gGanonStunEndAnim, -5.0f); this->unk_194 = Animation_GetLastFrame(&gGanonStunEndAnim); } break; case 2: if (Animation_OnFrame(&this->skelAnime, this->unk_194)) { func_809002CC(this, globalCtx); } break; } } void func_80900210(BossGanon2* this, GlobalContext* globalCtx) { Animation_MorphToPlayOnce(&this->skelAnime, &gGanonDamageAnim, -3.0f); this->unk_194 = Animation_GetLastFrame(&gGanonDamageAnim); this->actionFunc = func_8090026C; } void func_8090026C(BossGanon2* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); Math_ApproachZeroF(&this->actor.speedXZ, 0.5f, 2.0f); if (Animation_OnFrame(&this->skelAnime, this->unk_194)) { func_809002CC(this, globalCtx); } } void func_809002CC(BossGanon2* this, GlobalContext* globalCtx) { Animation_MorphToLoop(&this->skelAnime, &gGanonGuardWalkAnim, -10.0f); this->actionFunc = func_80900344; this->unk_338 = 0; this->unk_1A2[0] = 100; this->unk_390 = (s16)Rand_ZeroFloat(50.0f) + 50; } void func_80900344(BossGanon2* this, GlobalContext* globalCtx) { f32 phi_f0; if (this->unk_390 == 0) { this->unk_390 = (s16)Rand_ZeroFloat(50.0f) + 30; Audio_PlayActorSound2(&this->actor, NA_SE_EN_MGANON_UNARI); } Math_ApproachF(&this->unk_324, 255.0f, 1.0f, 10.0f); if (this->unk_338 != 0) { if (Animation_OnFrame(&this->skelAnime, 13.0f)) { func_808FD4D4(this, globalCtx, 1, 3); } else if (Animation_OnFrame(&this->skelAnime, 28.0f)) { func_808FD4D4(this, globalCtx, 2, 3); } if (this->actor.xzDistToPlayer < 200.0f) { this->unk_338 = 0; Animation_MorphToLoop(&this->skelAnime, &gGanonGuardWalkAnim, -10.0f); } else { this->skelAnime.playSpeed = ((this->actor.xzDistToPlayer - 300.0f) * 0.005f) + 1.0f; if (this->skelAnime.playSpeed > 2.0f) { this->skelAnime.playSpeed = 2.0f; } if (this->unk_334 != 0) { this->skelAnime.playSpeed *= 1.5f; } } phi_f0 = this->skelAnime.playSpeed * 3.0f; } else { phi_f0 = 2.0f; if (this->actor.xzDistToPlayer >= 200.0f) { this->unk_338 = 1; Animation_MorphToLoop(&this->skelAnime, &gGanonWalkAnim, -10.0f); } } SkelAnime_Update(&this->skelAnime); Math_ApproachF(&this->actor.speedXZ, phi_f0, 0.5f, 1.0f); if (this->unk_1A2[0] == 0) { func_808FFDB0(this, globalCtx); } else { func_808FFCFC(this, globalCtx); } func_808FFAC8(this, globalCtx, 1); func_808FFBBC(this, globalCtx, 1); } void func_80900580(BossGanon2* this, GlobalContext* globalCtx) { if (this->unk_311 == 0) { Animation_MorphToPlayOnce(&this->skelAnime, &gGanonLeftSwordSwingAnim, -5.0f); this->unk_194 = Animation_GetLastFrame(&gGanonLeftSwordSwingAnim); this->unk_198 = (this->unk_194 - 15.0f) - 5.0f; } else { Animation_MorphToPlayOnce(&this->skelAnime, &gGanonRightSwordSwingAnim, -5.0f); this->unk_194 = Animation_GetLastFrame(&gGanonRightSwordSwingAnim); this->unk_198 = (this->unk_194 - 15.0f) - 5.0f; } this->actionFunc = func_80900650; } void func_80900650(BossGanon2* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); if (Animation_OnFrame(&this->skelAnime, this->unk_198)) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_MGANON_SWORD); Audio_PlayActorSound2(&this->actor, NA_SE_EN_MGANON_ROAR); } if (this->unk_311 == 0) { if (((this->unk_198 - 4.0f) < this->skelAnime.curFrame) && (this->skelAnime.curFrame < (this->unk_198 + 6.0f))) { this->unk_312 = 1; } } else if ((((this->unk_198 - 4.0f) + 4.0f) < this->skelAnime.curFrame) && (this->skelAnime.curFrame < (this->unk_198 + 6.0f))) { this->unk_312 = 2; } Math_ApproachZeroF(&this->actor.speedXZ, 0.5f, 1.0f); if (Animation_OnFrame(&this->skelAnime, this->unk_194)) { this->unk_311 = 1 - this->unk_311; if ((this->unk_311 == 1) && (this->actor.xzDistToPlayer < 250.0f) && this->unk_313) { func_80900580(this, globalCtx); } else { func_808FFDB0(this, globalCtx); } } func_808FFAC8(this, globalCtx, 0); if ((this->unk_334 == 0) && (this->unk_311 == 0)) { this->unk_320 = 0.0f; } else { func_808FFBBC(this, globalCtx, 0); } } void func_80900818(BossGanon2* this, GlobalContext* globalCtx) { Animation_MorphToPlayOnce(&this->skelAnime, &gGanonDownedStartAnim, -5.0f); this->unk_194 = Animation_GetLastFrame(&gGanonDownedStartAnim); this->actionFunc = func_80900890; this->unk_1AC = 0; this->unk_39C = 0; Audio_PlayActorSound2(&this->actor, NA_SE_EN_MGANON_DEAD1); this->unk_336 = 0; } void func_80900890(BossGanon2* this, GlobalContext* globalCtx) { Vec3f sp5C; Vec3f sp50; Camera* sp4C; Player* player; Camera* temp_v0; Camera* temp_v0_2; s32 pad; f32 temp_f12; f32 temp_f2; sp4C = Gameplay_GetCamera(globalCtx, MAIN_CAM); player = GET_PLAYER(globalCtx); SkelAnime_Update(&this->skelAnime); this->unk_398++; this->unk_339 = 20; switch (this->unk_39C) { case 0: func_80064520(globalCtx, &globalCtx->csCtx); this->unk_39E = Gameplay_CreateSubCamera(globalCtx); Gameplay_ChangeCameraStatus(globalCtx, MAIN_CAM, CAM_STAT_WAIT); Gameplay_ChangeCameraStatus(globalCtx, this->unk_39E, CAM_STAT_ACTIVE); func_8002DF54(globalCtx, &this->actor, 8); this->unk_39C = 1; this->unk_3A4 = sp4C->eye; this->unk_3B0 = sp4C->at; this->unk_1A2[0] = 300; this->unk_1A2[1] = 100; globalCtx->envCtx.unk_D8 = 0.0f; case 1: if (this->unk_1A2[1] == 50) { func_80078884(NA_SE_EN_MGANON_WALK); } Matrix_RotateY(((this->actor.shape.rot.y / (f32)0x8000) * M_PI) + 0.3f, MTXMODE_NEW); sp5C.x = 0.0f; sp5C.y = 0.0f; sp5C.z = 250.0f; Matrix_MultVec3f(&sp5C, &sp50); Math_ApproachF(&this->unk_3A4.x, this->actor.world.pos.x + sp50.x, 0.2f, 100.0f); Math_ApproachF(&this->unk_3A4.y, 1136.0f, 0.2f, 100.0f); Math_ApproachF(&this->unk_3A4.z, this->actor.world.pos.z + sp50.z, 0.2f, 100.0f); Math_ApproachF(&this->unk_3B0.x, this->unk_1B8.x, 0.2f, 100.0f); Math_ApproachF(&this->unk_3B0.y, this->unk_1B8.y, 0.2f, 100.0f); Math_ApproachF(&this->unk_3B0.z, this->unk_1B8.z, 0.2f, 100.0f); if (this->unk_1A2[1] == 0) { this->unk_39C = 2; this->unk_1A2[1] = 90; } break; case 2: this->unk_1A2[0] = 300; this->unk_3A4.x = sBossGanon2Zelda->actor.world.pos.x - 100.0f; this->unk_3A4.y = sBossGanon2Zelda->actor.world.pos.y + 30.0f; this->unk_3A4.z = (sBossGanon2Zelda->actor.world.pos.z + 30.0f) - 60.0f; this->unk_3B0.x = sBossGanon2Zelda->actor.world.pos.x; this->unk_3B0.y = sBossGanon2Zelda->actor.world.pos.y + 30.0f; this->unk_3B0.z = sBossGanon2Zelda->actor.world.pos.z - 10.0f; Math_ApproachZeroF(&this->unk_324, 1.0f, 5.0f); Math_ApproachF(&globalCtx->envCtx.unk_D8, 1.0f, 1.0f, 1.0f / 51); if (this->unk_1A2[1] == 80) { Message_StartTextbox(globalCtx, 0x70D7, NULL); } if ((this->unk_1A2[1] < 30) && (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_NONE)) { temp_v0 = Gameplay_GetCamera(globalCtx, MAIN_CAM); temp_v0->eye = this->unk_3A4; temp_v0->eyeNext = this->unk_3A4; temp_v0->at = this->unk_3B0; func_800C08AC(globalCtx, this->unk_39E, 0); this->unk_39E = 0; func_80064534(globalCtx, &globalCtx->csCtx); func_8002DF54(globalCtx, &this->actor, 7); this->unk_39C = 3; } break; case 10: func_80064520(globalCtx, &globalCtx->csCtx); this->unk_39E = Gameplay_CreateSubCamera(globalCtx); Gameplay_ChangeCameraStatus(globalCtx, MAIN_CAM, CAM_STAT_WAIT); Gameplay_ChangeCameraStatus(globalCtx, this->unk_39E, CAM_STAT_ACTIVE); this->unk_39C = 11; this->unk_334 = 1; func_8002DF54(globalCtx, &this->actor, 0x60); this->unk_398 = 0; case 11: player->actor.world.pos.x = sBossGanon2Zelda->actor.world.pos.x + 50.0f + 10.0f; player->actor.world.pos.z = sBossGanon2Zelda->actor.world.pos.z - 25.0f; player->actor.shape.rot.y = -0x8000; this->unk_3A4.x = (player->actor.world.pos.x + 100.0f) - 80.0f; this->unk_3A4.y = (player->actor.world.pos.y + 60.0f) - 40.0f; this->unk_3A4.z = player->actor.world.pos.z - 110.0f; this->unk_3B0.x = player->actor.world.pos.x; this->unk_3B0.y = (player->actor.world.pos.y + 60.0f) - 25.0f; this->unk_3B0.z = player->actor.world.pos.z; if (this->unk_398 == 80) { temp_v0_2 = Gameplay_GetCamera(globalCtx, MAIN_CAM); temp_v0_2->eye = this->unk_3A4; temp_v0_2->eyeNext = this->unk_3A4; temp_v0_2->at = this->unk_3B0; this->unk_39C = 3; func_800C08AC(globalCtx, this->unk_39E, 0); this->unk_39E = 0; func_80064534(globalCtx, &globalCtx->csCtx); func_8002DF54(globalCtx, &this->actor, 7); } break; } if (this->unk_39E != 0) { Gameplay_CameraSetAtEye(globalCtx, this->unk_39E, &this->unk_3B0, &this->unk_3A4); } switch (this->unk_1AC) { case 0: if (Animation_OnFrame(&this->skelAnime, this->unk_194)) { Animation_MorphToLoop(&this->skelAnime, &gGanonDownedLoopAnim, 0.0f); this->unk_1AC = 1; } break; case 1: if ((globalCtx->gameplayFrames % 32) == 0) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_MGANON_BREATH); } if ((this->unk_1A2[0] == 0) || (this->unk_334 != 0)) { temp_f2 = -200.0f - player->actor.world.pos.x; temp_f12 = -200.0f - player->actor.world.pos.z; if (sqrtf(SQ(temp_f2) + SQ(temp_f12)) <= 784.0f) { Animation_MorphToPlayOnce(&this->skelAnime, &gGanonGetUpAnim, 0.0f); this->unk_194 = Animation_GetLastFrame(&gGanonGetUpAnim); this->unk_1AC = 2; this->unk_1A2[0] = 40; Audio_PlayActorSound2(&this->actor, NA_SE_EN_MGANON_ROAR); } } break; case 2: Math_ApproachF(&this->unk_324, 255.0f, 1.0f, 10.0f); Math_ApproachZeroF(&globalCtx->envCtx.unk_D8, 1.0f, 2.0f / 51.0f); if (Animation_OnFrame(&this->skelAnime, this->unk_194)) { func_808FFDB0(this, globalCtx); if (this->unk_334 == 0) { this->actor.colChkInfo.health = 25; } this->unk_336 = 1; } break; } Math_ApproachZeroF(&this->actor.speedXZ, 0.5f, 1.0f); } void func_80901020(BossGanon2* this, GlobalContext* globalCtx) { Animation_MorphToPlayOnce(&this->skelAnime, &gGanonDownedStartAnim, -5.0f); this->unk_194 = Animation_GetLastFrame(&gGanonDownedStartAnim); this->actionFunc = func_8090120C; this->unk_1AC = 0; this->unk_39C = 0; Audio_PlayActorSound2(&this->actor, NA_SE_EN_MGANON_DEAD1); this->unk_314 = 4; } void func_8090109C(BossGanon2* this, GlobalContext* globalCtx) { u8 i; static Color_RGBA8 sPrimColor = { 0, 120, 0, 255 }; static Color_RGBA8 sEnvColor = { 0, 120, 0, 255 }; if(CVar_GetS32("gRedGanonBlood", 0)) { sPrimColor.r = 120; sPrimColor.g = 0; sEnvColor.r = 120; sEnvColor.g = 0; } for (i = 0; i < 70; i++) { Vec3f velocity; Vec3f accel; Vec3f pos; velocity.x = Rand_CenteredFloat(50.0f); velocity.y = Rand_CenteredFloat(10.0f) + 5.0f; velocity.z = Rand_CenteredFloat(50.0f); accel.x = 0.0f; accel.y = -1.0f; accel.z = 0.0f; pos.x = this->unk_1B8.x; pos.y = this->unk_1B8.y; pos.z = this->unk_1B8.z; func_8002836C(globalCtx, &pos, &velocity, &accel, &sPrimColor, &sEnvColor, (s16)Rand_ZeroFloat(50.0f) + 50, 0, 17); } } void func_8090120C(BossGanon2* this, GlobalContext* globalCtx) { Player* player; f32 temp_f14; f32 temp_f12; Camera* temp_v0_2; s16 temp_a0_2; f32 phi_f0; s32 phi_a1; player = GET_PLAYER(globalCtx); this->unk_398++; SkelAnime_Update(&this->skelAnime); this->unk_3BC.x = 0.0f; this->unk_3BC.y = 1.0f; this->unk_3BC.z = 0.0f; switch (this->unk_39C) { case 0: func_80064520(globalCtx, &globalCtx->csCtx); this->unk_39E = Gameplay_CreateSubCamera(globalCtx); Gameplay_ChangeCameraStatus(globalCtx, MAIN_CAM, CAM_STAT_WAIT); Gameplay_ChangeCameraStatus(globalCtx, this->unk_39E, CAM_STAT_ACTIVE); func_8002DF54(globalCtx, &this->actor, 8); this->unk_39C = 1; this->unk_398 = 0; sBossGanon2Zelda->unk_3C8 = 9; this->unk_31C = 0; this->unk_1A2[2] = 0; this->unk_336 = 0; this->unk_324 = 0.0f; this->actor.speedXZ = 0.0f; this->unk_31A = this->unk_31C; globalCtx->envCtx.unk_D8 = 0.0f; case 1: if (this->unk_398 < 90) { this->unk_339 = 20; Math_ApproachF(&globalCtx->envCtx.unk_D8, 1.0f, 1.0f, 0.1f); } else if (this->unk_398 >= 90) { this->unk_339 = 21; Math_ApproachZeroF(&globalCtx->envCtx.unk_D8, 1.0f, 0.08f); } if (this->unk_398 == 50) { func_80078884(NA_SE_EN_MGANON_WALK); } if (this->unk_398 > 90) { Math_ApproachF(&this->unk_380, 0.25f, 1.0f, 0.0125f); this->unk_37C = 200.0f; func_80078884(NA_SE_EV_TIMETRIP_LIGHT - SFX_FLAG); } if (this->unk_398 >= 110) { if (this->unk_398 == 110) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_HIT_THUNDER); Audio_PlayActorSound2(&this->actor, NA_SE_EN_MGANON_DAMAGE); } Math_ApproachF(&this->unk_30C, 10.0f, 0.2f, 5.0f); this->skelAnime.playSpeed = 3.0f; } if (this->unk_398 == 120) { func_8002DF54(globalCtx, &this->actor, 0x63); } this->actor.world.rot.y = 0x4000; this->actor.world.pos.x = this->actor.world.pos.z = 0.0f; player->actor.shape.rot.y = -0x4000; player->actor.world.pos.x = 200.0f; player->actor.world.pos.z = 30.0f; sBossGanon2Zelda->actor.world.pos.x = 340.0f; sBossGanon2Zelda->actor.world.pos.z = -250.0f; sBossGanon2Zelda->actor.world.rot.y = sBossGanon2Zelda->actor.shape.rot.y = -0x2000; this->unk_3A4.x = 250; this->unk_3A4.y = 1150.0f; this->unk_3A4.z = 0.0f; this->unk_3B0.x = this->unk_1B8.x; this->unk_3B0.y = this->unk_1B8.y; this->unk_3B0.z = this->unk_1B8.z; if (this->unk_398 > 135) { this->unk_39C = 2; this->unk_398 = 0; } break; case 2: this->unk_339 = 22; Math_ApproachF(&globalCtx->envCtx.unk_D8, 1.0f, 1.0f, 0.1f); func_80078884(NA_SE_EV_TIMETRIP_LIGHT - SFX_FLAG); this->unk_3A4.x = 250; this->unk_3A4.y = 1150.0f; this->unk_3A4.z = 0.0f; Math_ApproachF(&this->unk_3B0.x, sBossGanon2Zelda->actor.world.pos.x, 0.2f, 20.0f); Math_ApproachF(&this->unk_3B0.y, sBossGanon2Zelda->actor.world.pos.y + 50.0f, 0.2f, 10.0f); Math_ApproachF(&this->unk_3B0.z, sBossGanon2Zelda->actor.world.pos.z, 0.2f, 20.0f); if (this->unk_398 == 50) { this->unk_39C = 3; this->unk_398 = 0; } break; case 3: this->unk_339 = 22; func_80078884(NA_SE_EV_TIMETRIP_LIGHT - SFX_FLAG); this->unk_3A4.x = 330.0f; this->unk_3A4.y = 1120.0f; this->unk_3A4.z = -150.0f; this->unk_3B0.x = sBossGanon2Zelda->actor.world.pos.x; this->unk_3B0.y = sBossGanon2Zelda->actor.world.pos.y + 40.0f; this->unk_3B0.z = sBossGanon2Zelda->actor.world.pos.z; if (this->unk_398 == 10) { Message_StartTextbox(globalCtx, 0x70D8, NULL); } if ((this->unk_398 > 80) && (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_NONE)) { this->unk_39C = 4; this->unk_398 = 0; } break; case 4: if (this->unk_398 > 10) { Math_ApproachZeroF(&this->unk_37C, 1.0f, 10.0f); if (this->unk_398 == 30) { sBossGanon2Zelda->unk_3C8 = 10; } this->unk_339 = 23; Math_ApproachZeroF(&globalCtx->envCtx.unk_D8, 1.0f, 0.05f); } else { this->unk_339 = 22; } if (this->unk_398 == 100) { this->unk_39C = 5; this->unk_398 = 40; this->skelAnime.playSpeed = 1.0f; func_8002DF54(globalCtx, &this->actor, 0x64); } break; case 5: this->unk_339 = 23; if ((this->unk_398 >= 60) && (this->unk_398 <= 90)) { if (this->unk_398 == 62) { func_80078884(NA_SE_EV_TRIFORCE_FLASH); } Math_ApproachF(&this->unk_38C, 200.0f, 1.0f, 8.0f); } else { Math_ApproachZeroF(&this->unk_38C, 1.0f, 8.0f); } if (this->unk_398 == 70) { func_8002DF54(globalCtx, &this->actor, 0x65); } if (this->unk_398 == 150) { func_8002DF54(globalCtx, &this->actor, 0x66); } this->unk_30C = 10.0f; player->actor.world.pos.x = 250.0f; player->actor.world.pos.z = 30.0f; this->unk_3A4.x = player->actor.world.pos.x - 50.0f; this->unk_3A4.y = player->actor.world.pos.y + 50.0f; this->unk_3A4.z = player->actor.world.pos.z + 40.0f; this->unk_3B0.x = player->actor.world.pos.x; this->unk_3B0.y = player->actor.world.pos.y + 40.0f; this->unk_3B0.z = player->actor.world.pos.z; if (this->unk_398 == 166) { temp_v0_2 = Gameplay_GetCamera(globalCtx, MAIN_CAM); temp_v0_2->eye = this->unk_3A4; temp_v0_2->eyeNext = this->unk_3A4; temp_v0_2->at = this->unk_3B0; func_800C08AC(globalCtx, this->unk_39E, 0); this->unk_39E = 0; func_80064534(globalCtx, &globalCtx->csCtx); func_8002DF54(globalCtx, &this->actor, 7); this->unk_39C = 6; } break; case 6: this->unk_339 = 23; temp_f14 = this->unk_1B8.x - player->actor.world.pos.x; temp_f12 = this->unk_1B8.z - player->actor.world.pos.z; temp_a0_2 = Math_Atan2S(temp_f12, temp_f14) - player->actor.shape.rot.y; if ((ABS(temp_a0_2) < 0x2000) && (sqrtf(SQ(temp_f14) + SQ(temp_f12)) < 70.0f) && (player->swordState != 0) && (player->heldItemActionParam == PLAYER_AP_SWORD_MASTER)) { func_80064520(globalCtx, &globalCtx->csCtx); this->unk_39E = Gameplay_CreateSubCamera(globalCtx); Gameplay_ChangeCameraStatus(globalCtx, MAIN_CAM, CAM_STAT_WAIT); Gameplay_ChangeCameraStatus(globalCtx, this->unk_39E, CAM_STAT_ACTIVE); this->unk_39C = 7; this->unk_398 = 0; Animation_MorphToPlayOnce(&this->skelAnime, &gGanonFinalBlowAnim, 0.0f); this->unk_194 = Animation_GetLastFrame(&gGanonFinalBlowAnim); globalCtx->startPlayerCutscene(globalCtx, &this->actor, 0x61); } else { break; } case 7: this->unk_339 = 23; Math_ApproachZeroF(&globalCtx->envCtx.unk_D8, 1.0f, 0.2f); player->actor.world.pos.x = 250.0f; player->actor.shape.rot.y = -0x4000; player->actor.world.pos.z = 30.0f; if ((this->unk_398 == 20) || (this->unk_398 == 30) || (this->unk_398 == 65) || (this->unk_398 == 40)) { func_80078884(NA_SE_VO_LI_SWORD_N); func_80078884(NA_SE_IT_SWORD_SWING_HARD); } if ((this->unk_398 == 22) || (this->unk_398 == 35) || (this->unk_398 == 72) || (this->unk_398 == 45)) { func_80078884(NA_SE_EN_MGANON_DAMAGE); func_80078884(NA_SE_IT_SHIELD_BOUND); globalCtx->envCtx.unk_D8 = 1.0f; } if ((this->unk_398 == 22) || (this->unk_398 == 35) || (this->unk_398 == 72) || (this->unk_398 == 45)) { func_8090109C(this, globalCtx); } if ((this->unk_398 >= 34) && (this->unk_398 < 40)) { this->unk_3A4.x = 269.0f; this->unk_3A4.y = 1112.0f; this->unk_3A4.z = -28.0f; this->unk_3B0.x = 234.0f; this->unk_3B0.y = 1117.0f; this->unk_3B0.z = -11.0f; } else { if (this->unk_398 < 30) { phi_a1 = 0; } else if (this->unk_398 < 43) { phi_a1 = 1; } else { this->unk_3BC.z = -0.8f; player->actor.world.pos.x = 200.0f; player->actor.world.pos.z = 10.0f; phi_a1 = 2; } this->unk_3A4.x = D_8090702C[phi_a1].x + (player->actor.world.pos.x - 50.0f); this->unk_3A4.y = D_8090702C[phi_a1].y + (player->actor.world.pos.y + 50.0f); this->unk_3A4.z = D_8090702C[phi_a1].z + (player->actor.world.pos.z + 40.0f); this->unk_3B0.x = D_80907050[phi_a1].x + player->actor.world.pos.x; this->unk_3B0.y = D_80907050[phi_a1].y + (player->actor.world.pos.y + 40.0f); this->unk_3B0.z = D_80907050[phi_a1].z + player->actor.world.pos.z; } if (this->unk_398 > 80) { Audio_QueueSeqCmd(0x1 << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0x100FF); this->unk_39C = 75; this->unk_398 = 0; this->unk_3A4.x = 112.0f; this->unk_3A4.y = 1146.0f; this->unk_3A4.z = 202.0f; this->unk_3B0.x = 110.0f; this->unk_3B0.y = 1144.0f; this->unk_3B0.z = 177.0f; player->actor.world.pos.x = 200.0f; this->unk_3BC.z = 0.0f; } break; case 75: this->unk_339 = 23; if (this->unk_398 == 55) { Animation_MorphToPlayOnce(&this->skelAnime, &gGanonDeadStartAnim, 0.0f); this->unk_194 = Animation_GetLastFrame(&gGanonDeadStartAnim); func_8002DF54(globalCtx, &this->actor, 0x62); this->unk_39C = 8; this->unk_398 = 1000; } break; case 8: if (this->unk_398 == 1025) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_MGANON_STAND); } if (this->unk_398 >= 1000) { if (this->unk_398 < 1040) { this->unk_339 = 23; Math_ApproachZeroF(&globalCtx->envCtx.unk_D8, 1.0f, 0.2f); } } if (this->unk_398 == 1040) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_MGANON_DEAD2); this->unk_336 = 2; this->unk_339 = 0; globalCtx->envCtx.unk_BE = 0; globalCtx->envCtx.unk_D8 = 0.0f; } if (Animation_OnFrame(&this->skelAnime, this->unk_194)) { Animation_MorphToPlayOnce(&this->skelAnime, &gGanonDeadLoopAnim, 0.0f); this->unk_398 = 0; this->unk_194 = 1000.0f; } this->unk_3A4.x = 250; this->unk_3A4.y = 1150.0f; this->unk_3A4.z = 0.0f; this->unk_3B0.x = this->unk_1B8.x; this->unk_3B0.y = this->unk_1B8.y; this->unk_3B0.z = this->unk_1B8.z; if ((this->unk_398 < 1000) && ((this->unk_398 % 16) == 0)) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_MGANON_SWORD); } if (this->unk_398 == 40) { this->unk_39C = 9; this->unk_398 = 0; sBossGanon2Zelda->unk_3C8 = 11; Message_StartTextbox(globalCtx, 0x70D9, NULL); this->unk_336 = 0; globalCtx->envCtx.unk_D8 = 0.0f; } break; case 9: this->unk_339 = 24; this->unk_3A4.x = 330.0f; this->unk_3A4.y = 1120.0f; this->unk_3A4.z = -150.0f; this->unk_3B0.x = sBossGanon2Zelda->actor.world.pos.x; this->unk_3B0.y = sBossGanon2Zelda->actor.world.pos.y + 40.0f; this->unk_3B0.z = sBossGanon2Zelda->actor.world.pos.z; if (this->unk_398 > 60) { this->unk_39C = 10; this->unk_398 = 0; this->unk_410.x = 0.0f; } break; case 10: this->unk_339 = 24; Math_ApproachF(&this->unk_3A4.x, 290.0f, 0.05f, this->unk_410.x); Math_ApproachF(&this->unk_3A4.y, 1130.0f, 0.05f, this->unk_410.x * 0.25f); Math_ApproachF(&this->unk_3A4.z, -260.0f, 0.05f, this->unk_410.x * 1.25f); if ((this->unk_398 >= 40) && (this->unk_398 <= 110)) { Math_ApproachF(&globalCtx->envCtx.unk_D8, 1.0f, 1.0f, 0.02f); Math_ApproachF(&this->unk_384, 10.0f, 0.1f, 0.2f); Audio_PlayActorSound2(&sBossGanon2Zelda->actor, NA_SE_EV_GOD_LIGHTBALL_2 - SFX_FLAG); } else { Math_ApproachZeroF(&this->unk_384, 1.0f, 0.2f); } if (this->unk_398 > 130) { Math_ApproachF(&this->unk_3B0.y, (sBossGanon2Zelda->actor.world.pos.y + 40.0f + 10.0f) - 20.0f, 0.1f, this->unk_410.x); } else { Math_ApproachF(&this->unk_3B0.y, sBossGanon2Zelda->actor.world.pos.y + 40.0f + 10.0f, 0.05f, this->unk_410.x * 0.25f); } Math_ApproachF(&this->unk_410.x, 1.0f, 1.0f, 0.01f); if (this->unk_398 == 10) { sBossGanon2Zelda->unk_3C8 = 12; } if (this->unk_398 == 110) { sBossGanon2Zelda->unk_3C8 = 13; } if (this->unk_398 == 140) { Audio_PlayActorSound2(&sBossGanon2Zelda->actor, NA_SE_EV_HUMAN_BOUND); } if (this->unk_398 < 160) { break; } case 20: globalCtx->nextEntranceIndex = 0x6B; gSaveContext.nextCutsceneIndex = 0xFFF2; globalCtx->sceneLoadFlag = 0x14; globalCtx->fadeTransition = 3; globalCtx->linkAgeOnLoad = 1; break; } if (this->unk_39E != 0) { Gameplay_CameraSetAtEyeUp(globalCtx, this->unk_39E, &this->unk_3B0, &this->unk_3A4, &this->unk_3BC); } switch (this->unk_1AC) { case 0: if (Animation_OnFrame(&this->skelAnime, this->unk_194)) { Animation_MorphToLoop(&this->skelAnime, &gGanonDownedLoopAnim, 0.0f); this->unk_1AC = 1; } break; case 1: if ((this->unk_39C < 7) && ((globalCtx->gameplayFrames % 32) == 0)) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_MGANON_BREATH); } break; } } void func_80902348(BossGanon2* this, GlobalContext* globalCtx) { Player* player; f32 temp_f2; f32 temp_f12; s16 i; s16 j; s16 phi_v0_2; if (this->unk_316 == 0) { for (i = 0; i < ARRAY_COUNT(this->unk_864); i++) { if (this->unk_444.elements[i].info.bumperFlags & 2) { this->unk_444.elements[i].info.bumperFlags &= ~2; } else if (this->unk_444.elements[i].info.toucherFlags & 2) { this->unk_444.elements[i].info.toucherFlags &= ~2; if (this->unk_312 == 1) { phi_v0_2 = 0x1800; } else { phi_v0_2 = 0; } func_8002F6D4(globalCtx, &this->actor, 15.0f, this->actor.yawTowardsPlayer + phi_v0_2, 2.0f, 0); sBossGanon2Zelda->unk_3C8 = 8; this->unk_316 = 10; break; } } } if (this->unk_324 > 0.0f) { player = GET_PLAYER(globalCtx); temp_f2 = -200.0f - player->actor.world.pos.x; temp_f12 = -200.0f - player->actor.world.pos.z; if (sqrtf(SQ(temp_f2) + SQ(temp_f12)) > 784.0f) { for (j = 0; j < ARRAY_COUNT(player->flameTimers); j++) { player->flameTimers[j] = Rand_S16Offset(0, 200); } player->isBurning = true; func_8002F6D4(globalCtx, &this->actor, 10.0f, Math_Atan2S(temp_f12, temp_f2), 0.0f, 0x10); sBossGanon2Zelda->unk_3C8 = 8; } } } void func_80902524(BossGanon2* this, GlobalContext* globalCtx) { s8 temp_v0_4; ColliderInfo* acHitInfo; s16 i; u8 phi_v1_2; osSyncPrintf("this->no_hit_time %d\n", this->unk_316); if (this->unk_316 != 0 || ((this->unk_334 == 0) && (this->actionFunc == func_80900890))) { for (i = 0; i < ARRAY_COUNT(this->unk_464); i++) { this->unk_424.elements[i].info.bumperFlags &= ~2; } } osSyncPrintf("this->look_on %d\n", this->unk_313); if (this->unk_313) { if (this->actionFunc != func_808FFFE0) { if (this->unk_424.elements[0].info.bumperFlags & 2) { this->unk_424.elements[0].info.bumperFlags &= ~2; acHitInfo = this->unk_424.elements[0].info.acHitInfo; if ((acHitInfo->toucher.dmgFlags & 0x2000) && (this->actionFunc != func_80900890)) { func_809000A0(this, globalCtx); Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_HIT_THUNDER); Audio_PlayActorSound2(&this->actor, NA_SE_EN_MGANON_DAMAGE); Audio_StopSfxById(NA_SE_EN_MGANON_UNARI); } else if ((this->actionFunc == func_80900890) && (acHitInfo->toucher.dmgFlags & 0x9000200)) { this->unk_316 = 60; this->unk_342 = 5; Audio_PlayActorSound2(&this->actor, NA_SE_EN_MGANON_DAMAGE); Audio_StopSfxById(NA_SE_EN_MGANON_UNARI); this->actor.colChkInfo.health -= 2; temp_v0_4 = this->actor.colChkInfo.health; if (temp_v0_4 < 0x15 && this->unk_334 == 0) { func_80900818(this, globalCtx); } else { if (temp_v0_4 <= 0) { func_80901020(this, globalCtx); } else { func_80900210(this, globalCtx); } } } else if (this->actionFunc != func_80900890) { func_808FFF90(this, globalCtx); Audio_PlayActorSound2(&this->actor, NA_SE_IT_HOOKSHOT_REFLECT); } } } } else { if (this->unk_424.elements[15].info.bumperFlags & 2) { this->unk_424.elements[15].info.bumperFlags &= ~2; acHitInfo = this->unk_424.elements[15].info.acHitInfo; this->unk_316 = 60; this->unk_344 = 0x32; this->unk_342 = 5; Audio_PlayActorSound2(&this->actor, NA_SE_EN_MGANON_DAMAGE); Audio_StopSfxById(NA_SE_EN_MGANON_UNARI); phi_v1_2 = 1; if (acHitInfo->toucher.dmgFlags & 0x9000200) { if (acHitInfo->toucher.dmgFlags & 0x8000000) { phi_v1_2 = 4; } else { phi_v1_2 = 2; } } this->actor.colChkInfo.health -= phi_v1_2; temp_v0_4 = this->actor.colChkInfo.health; if ((temp_v0_4 < 0x15) && (this->unk_334 == 0)) { func_80900818(this, globalCtx); } else if ((temp_v0_4 <= 0) && (phi_v1_2 >= 2)) { func_80901020(this, globalCtx); } else { if (temp_v0_4 <= 0) { this->actor.colChkInfo.health = 1; } func_80900210(this, globalCtx); } } } } void BossGanon2_Update(Actor* thisx, GlobalContext* globalCtx) { BossGanon2* this = (BossGanon2*)thisx; s32 pad; s16 i; f32 phi_f2; u16 i2; Vec3f sp58; Vec3f sp4C; f32 angle; f32 sp44; if ((this->unk_337 == 0) || (this->unk_337 == 2)) { BossGanon2_SetObjectSegment(this, globalCtx, OBJECT_GANON_ANIME3, false); } else { BossGanon2_SetObjectSegment(this, globalCtx, OBJECT_GANON2, false); Math_ApproachZeroF(&this->unk_30C, 1.0f, 0.5f); } func_808FFC84(this); this->unk_312 = 0; this->unk_19C++; Actor_SetScale(&this->actor, 0.01f); this->actionFunc(this, globalCtx); for (i = 0; i < ARRAY_COUNT(this->unk_1A2); i++) { if (this->unk_1A2[i] != 0) { this->unk_1A2[i]--; } } if (this->unk_316 != 0) { this->unk_316--; } if (this->unk_342 != 0) { this->unk_342--; } if (this->unk_390 != 0) { this->unk_390--; } if (this->unk_392 != 0) { this->unk_392--; } Actor_MoveForward(&this->actor); this->actor.shape.rot = this->actor.world.rot; if (this->unk_335 != 0) { Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 60.0f, 60.0f, 100.0f, 5); if (this->actor.bgCheckFlags & 1) { if (this->actor.velocity.y < -5.0f) { func_80033E88(&this->actor, globalCtx, 5, 20); func_80078884(NA_SE_IT_BOMB_EXPLOSION); } this->actor.velocity.y = 0.0f; } } if (((this->unk_19C & 0x1F) == 0) && (Rand_ZeroOne() < 0.3f)) { this->unk_318 = 4; } this->unk_310 = D_80907074[this->unk_318]; if (this->unk_318 != 0) { this->unk_318--; } this->unk_1B0 = (Math_SinS(this->unk_19C * 0x2AAA) * 64.0f) + 191.0f; if (this->unk_344 != 0) { this->unk_344--; Math_ApproachF(&this->unk_360.x, 5000.0f, 0.5f, 3000.0f); Math_ApproachF(&this->unk_370.x, 5500.0f, 0.5f, 3000.0f); Math_ApproachF(&this->unk_360.z, 8000.0f, 0.1f, 4000.0f); Math_ApproachF(&this->unk_370.z, 8000.0f, 0.1f, 4000.0f); Math_ApproachS(&this->unk_346, 0xFA0, 0xA, 0x7D0); } else { this->unk_360.y = 14000.0f; Math_ApproachF(&this->unk_360.x, 2000.0f, 0.1f, 100.0f); this->unk_370.y = 12000.0f; Math_ApproachF(&this->unk_370.x, 1500.0f, 0.1f, 100.0f); if ((this->actionFunc == func_808FFEBC) || (this->actionFunc == func_808FFFE0) || (this->actionFunc == func_80900104)) { Math_ApproachF(&this->unk_360.z, 1000.0f, 0.1f, 100.0f); Math_ApproachF(&this->unk_370.z, 1000.0f, 0.1f, 100.0f); Math_ApproachS(&this->unk_346, -0xFA0, 0xA, 0x64); } else { Math_ApproachF(&this->unk_360.z, 5000.0f, 0.1f, 200.0f); Math_ApproachF(&this->unk_370.z, 5000.0f, 0.1f, 200.0f); Math_ApproachS(&this->unk_346, 0, 0xA, 0x64); } } if (this->unk_39C != 75) { this->unk_35C += this->unk_360.x; this->unk_36C += this->unk_370.x; } if (this->unk_337 == 2) { this->unk_370.z = 0.0f; this->unk_360.z = 0.0f; } for (i = 0; i < ARRAY_COUNT(this->unk_348); i++) { if (i == 0) { phi_f2 = 0.2f; } else if (i == 1) { phi_f2 = 0.5f; } else { phi_f2 = 1.0f; } this->unk_348[i] = Math_SinS(((s16)this->unk_35C + (i * (s16)this->unk_360.y))) * phi_f2 * this->unk_360.z; this->unk_352[i] = Math_SinS(((s16)this->unk_36C + (i * (s16)this->unk_370.y))) * phi_f2 * this->unk_370.z; } func_808FF898(this, globalCtx); func_80902348(this, globalCtx); CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->unk_424.base); if (this->actionFunc != func_8090120C) { func_80902524(this, globalCtx); CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->unk_424.base); CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->unk_444.base); CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->unk_444.base); if (this->unk_39E == 0) { CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->unk_444.base); } } if ((this->unk_332 == 0) && (this->unk_336 != 0)) { if (this->unk_336 == 2) { this->unk_332 = (s16)Rand_ZeroFloat(30.0f) + 8; } else { this->unk_332 = (s16)Rand_ZeroFloat(60.0f) + 0xA; } this->unk_339 = 0; globalCtx->envCtx.unk_BE = 0; globalCtx->envCtx.unk_BD = (s8)Rand_ZeroFloat(1.9f) + 1; globalCtx->envCtx.unk_D8 = 1.0f; D_8090EB20.y = 0.0f; D_8090EB20.x = D_8090EB20.y; D_8090EB20.z = D_8090EB20.x; if (Rand_ZeroOne() < 0.5f) { D_8090EB20.z = Rand_ZeroFloat(1000.0f); } func_80078914(&D_8090EB20, NA_SE_EV_LIGHTNING); this->unk_328 = 0xFF; this->unk_330 = 5; this->unk_32C = 0.0f; this->unk_340 = (s16)Rand_ZeroFloat(10000.0f); } else if (this->unk_332 != 0) { this->unk_332--; } if ((globalCtx->envCtx.unk_D8 > 0.0f) && (this->unk_336 != 0)) { globalCtx->envCtx.customSkyboxFilter = 1; globalCtx->envCtx.skyboxFilterColor[0] = 255; globalCtx->envCtx.skyboxFilterColor[1] = 255; globalCtx->envCtx.skyboxFilterColor[2] = 255; globalCtx->envCtx.skyboxFilterColor[3] = (s16)(globalCtx->envCtx.unk_D8 * 200.0f); } else { globalCtx->envCtx.customSkyboxFilter = 0; } globalCtx->envCtx.unk_BF = 0; globalCtx->envCtx.unk_DC = 2; switch (this->unk_339) { case 0: Math_ApproachZeroF(&globalCtx->envCtx.unk_D8, 1.0f, 0.1f); break; case 3: globalCtx->envCtx.unk_BE = 3; globalCtx->envCtx.unk_BD = 4; Math_ApproachF(&globalCtx->envCtx.unk_D8, 1.0f, 1.0f, 0.0125f); break; case 4: globalCtx->envCtx.unk_BE = 5; globalCtx->envCtx.unk_BD = 6; Math_ApproachF(&globalCtx->envCtx.unk_D8, 1.0f, 1.0f, 0.0125f); break; case 5: globalCtx->envCtx.unk_BE = 6; globalCtx->envCtx.unk_BD = 7; Math_ApproachF(&this->unk_33C, 0.69f, 1.0f, 0.05f); globalCtx->envCtx.unk_D8 = (Math_SinS(globalCtx->gameplayFrames * 0x5000) * 0.15f) + (0.15f + this->unk_33C); break; case 55: globalCtx->envCtx.unk_BE = 2; globalCtx->envCtx.unk_BD = 0; Math_ApproachZeroF(&globalCtx->envCtx.unk_D8, 1.0f, 0.05f); break; case 6: globalCtx->envCtx.unk_BE = 2; globalCtx->envCtx.unk_BD = 8; Math_ApproachF(&this->unk_33C, 0.69f, 1.0f, 0.05f); globalCtx->envCtx.unk_D8 = (Math_SinS(globalCtx->gameplayFrames * 0x7000) * 0.15f) + (0.15f + this->unk_33C); break; case 7: globalCtx->envCtx.unk_BE = 0; globalCtx->envCtx.unk_BD = 8; Math_ApproachZeroF(&globalCtx->envCtx.unk_D8, 1.0f, 0.02f); break; case 20: globalCtx->envCtx.unk_BE = 0; globalCtx->envCtx.unk_BD = 9; break; case 21: globalCtx->envCtx.unk_BE = 0xA; globalCtx->envCtx.unk_BD = 9; break; case 22: globalCtx->envCtx.unk_BE = 0xA; globalCtx->envCtx.unk_BD = 0xB; break; case 23: globalCtx->envCtx.unk_BE = 9; globalCtx->envCtx.unk_BD = 0xB; break; case 24: globalCtx->envCtx.unk_BE = 0; globalCtx->envCtx.unk_BD = 0xC; break; case -1: break; } if (this->unk_339 >= 0) { this->unk_339 = 0; } if (D_80906D78 != 0) { D_80906D78 = 0; for (i2 = 0; i2 < ARRAY_COUNT(sBossGanon2Particles); i2++) { angle = Rand_ZeroFloat(2 * M_PI); sp44 = Rand_ZeroFloat(40.0f) + 10.0f; sp58 = this->actor.world.pos; sp58.y = 1200.0f; sp4C.x = cosf(angle) * sp44; sp4C.z = sinf(angle) * sp44; sp4C.y = Rand_ZeroFloat(15.0f) + 15.0f; sp58.x += sp4C.x * 10.0f * 0.1f; sp58.z += sp4C.z * 10.0f * 0.1f; func_808FD27C(globalCtx, &sp58, &sp4C, Rand_ZeroFloat(0.3f) + 0.2f); } } this->unk_388 += 0.15f; func_80905DA8(this, globalCtx); } void func_809034E4(Vec3f* arg0, Vec3f* arg1) { Vtx* vtx; Vec3f sp2D0; s16 temp_s1; s16 temp_a1; s16 sp2CA; s16 sp2C8; s16 i; u8 phi_s2; u8 temp_s4; u8 temp_s4_2; f32 temp_f12; Vec3f temp_f20; Vec3f temp_f2; Vec3f temp_f22; f32 sp294; f32 phi_f30; f32 temp_f28; f32 temp_f26; s32 pad[3]; Vec3f sp18C[20]; Vec3f sp9C[20]; for (i = 0; i < 20; i++) { sp18C[i] = *arg0; sp9C[i] = *arg1; } temp_s4 = 0; D_809105D8[3] = D_809105D8[2]; D_809105D8[2] = D_809105D8[1]; D_809105D8[1] = D_809105D8[0]; D_809105D8[0] = *arg0; sp2D0 = D_809105D8[0]; temp_f20.x = D_809105D8[1].x - sp2D0.x; temp_f20.y = D_809105D8[1].y - sp2D0.y; temp_f20.z = D_809105D8[1].z - sp2D0.z; sp2CA = Math_Atan2S(temp_f20.z, temp_f20.x); sp2C8 = Math_Atan2S(sqrtf(SQXZ(temp_f20)), temp_f20.y); temp_f2.x = D_809105D8[2].x - D_809105D8[1].x; temp_f2.y = D_809105D8[2].y - D_809105D8[1].y; temp_f2.z = D_809105D8[2].z - D_809105D8[1].z; temp_f22.x = D_809105D8[3].x - D_809105D8[2].x; temp_f22.y = D_809105D8[3].y - D_809105D8[2].y; temp_f22.z = D_809105D8[3].z - D_809105D8[2].z; temp_f12 = sqrtf(SQXYZ(temp_f20)) + sqrtf(SQXYZ(temp_f2)) + sqrtf(SQXYZ(temp_f22)); if (temp_f12 <= 1.0f) { temp_f12 = 1.0f; } temp_f28 = temp_f12 * 0.083f; phi_f30 = sqrtf(SQXYZ(temp_f20)) / 2.0f; sp294 = sqrtf(SQXYZ(temp_f2)) / 2.0f; phi_s2 = 1; while (true) { temp_f20.x = D_809105D8[phi_s2].x - sp2D0.x; temp_f20.y = D_809105D8[phi_s2].y - sp2D0.y; temp_f20.z = D_809105D8[phi_s2].z - sp2D0.z; temp_s1 = Math_Atan2S(temp_f20.z, temp_f20.x); temp_a1 = Math_Atan2S(sqrtf(SQXZ(temp_f20)), temp_f20.y); Math_ApproachS(&sp2C8, temp_a1, 1, 0x1000); Math_ApproachS(&sp2CA, temp_s1, 1, 0x1000); temp_f26 = temp_f28 * Math_CosS(sp2C8); sp18C[temp_s4] = sp2D0; sp2D0.x += temp_f26 * Math_SinS(sp2CA); sp2D0.y += temp_f28 * Math_SinS(sp2C8); sp2D0.z += temp_f26 * Math_CosS(sp2CA); temp_f20.x = D_809105D8[phi_s2].x - sp2D0.x; temp_f20.y = D_809105D8[phi_s2].y - sp2D0.y; temp_f20.z = D_809105D8[phi_s2].z - sp2D0.z; if (phi_s2 < 3) { if (sqrtf(SQXYZ(temp_f20)) <= phi_f30) { phi_f30 = sp294; phi_s2++; } } else { if (sqrtf(SQXYZ(temp_f20)) <= (temp_f28 + 1.0f)) { phi_s2++; } } temp_s4++; if ((temp_s4 >= 20) || (phi_s2 >= 4)) { break; } } temp_s4_2 = 0; D_80910608[3] = D_80910608[2]; D_80910608[2] = D_80910608[1]; D_80910608[1] = D_80910608[0]; D_80910608[0] = *arg1; sp2D0 = D_80910608[0]; temp_f20.x = D_80910608[1].x - sp2D0.x; temp_f20.y = D_80910608[1].y - sp2D0.y; temp_f20.z = D_80910608[1].z - sp2D0.z; sp2CA = Math_Atan2S(temp_f20.z, temp_f20.x); sp2C8 = Math_Atan2S(sqrtf(SQXZ(temp_f20)), temp_f20.y); temp_f2.x = D_80910608[2].x - D_80910608[1].x; temp_f2.y = D_80910608[2].y - D_80910608[1].y; temp_f2.z = D_80910608[2].z - D_80910608[1].z; temp_f22.x = D_80910608[3].x - D_80910608[2].x; temp_f22.y = D_80910608[3].y - D_80910608[2].y; temp_f22.z = D_80910608[3].z - D_80910608[2].z; temp_f12 = sqrtf(SQXYZ(temp_f20)) + sqrtf(SQXYZ(temp_f2)) + sqrtf(SQXYZ(temp_f22)); if (temp_f12 <= 1.0f) { temp_f12 = 1.0f; } temp_f28 = temp_f12 * 0.083f; phi_f30 = sqrtf(SQXYZ(temp_f20)) / 2.0f; sp294 = sqrtf(SQXYZ(temp_f2)) / 2.0f; phi_s2 = 1; while (true) { temp_f20.x = D_80910608[phi_s2].x - sp2D0.x; temp_f20.y = D_80910608[phi_s2].y - sp2D0.y; temp_f20.z = D_80910608[phi_s2].z - sp2D0.z; temp_s1 = Math_Atan2S(temp_f20.z, temp_f20.x); temp_a1 = Math_Atan2S(sqrtf(SQXZ(temp_f20)), temp_f20.y); Math_ApproachS(&sp2C8, temp_a1, 1, 0x1000); Math_ApproachS(&sp2CA, temp_s1, 1, 0x1000); temp_f26 = temp_f28 * Math_CosS(sp2C8); sp9C[temp_s4_2] = sp2D0; sp2D0.x += temp_f26 * Math_SinS(sp2CA); sp2D0.y += temp_f28 * Math_SinS(sp2C8); sp2D0.z += temp_f26 * Math_CosS(sp2CA); temp_f20.x = D_80910608[phi_s2].x - sp2D0.x; temp_f20.y = D_80910608[phi_s2].y - sp2D0.y; temp_f20.z = D_80910608[phi_s2].z - sp2D0.z; if (phi_s2 < 3) { if (sqrtf(SQXYZ(temp_f20)) <= phi_f30) { phi_f30 = sp294; phi_s2++; } } else { if (sqrtf(SQXYZ(temp_f20)) <= (temp_f28 + 1.0f)) { phi_s2++; } } temp_s4_2++; if ((temp_s4_2 >= 20) || (phi_s2 >= 4)) { break; } } vtx = ResourceMgr_LoadVtxByName(SEGMENTED_TO_VIRTUAL(ovl_Boss_Ganon2_Vtx_00BA20)); for (i = 0; i < 11; i++) { if ((temp_s4 - i) > 0) { vtx[D_80907084[i]].n.ob[0] = sp18C[temp_s4 - i - 1].x; vtx[D_80907084[i]].n.ob[1] = sp18C[temp_s4 - i - 1].y; vtx[D_80907084[i]].n.ob[2] = sp18C[temp_s4 - i - 1].z; } if ((temp_s4_2 - i) > 0) { vtx[D_80907090[i]].n.ob[0] = sp9C[temp_s4_2 - i - 1].x; vtx[D_80907090[i]].n.ob[1] = sp9C[temp_s4_2 - i - 1].y; vtx[D_80907090[i]].n.ob[2] = sp9C[temp_s4_2 - i - 1].z; } } } void func_80903F38(BossGanon2* this, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); if (this->unk_312 != 0) { func_809034E4(&this->unk_200, &this->unk_20C); D_80907080 = 0xFF; } if (D_80910638 >= 4) { gSPSegment( POLY_XLU_DISP++, 0x08, Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 32, 32, 1, globalCtx->gameplayFrames * 18, 0, 32, 32)); gDPPipeSync(POLY_XLU_DISP++); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, D_80907080); Matrix_Translate(0.0f, 0.0f, 0.0f, MTXMODE_NEW); gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, ovl_Boss_Ganon2_DL_00BB80); } CLOSE_DISPS(globalCtx->state.gfxCtx); } void func_80904108(BossGanon2* this, GlobalContext* globalCtx) { s32 pad; if (this->unk_324 > 0.0f) { OPEN_DISPS(globalCtx->state.gfxCtx); Matrix_Push(); gDPPipeSync(POLY_XLU_DISP++); gSPSegment(POLY_XLU_DISP++, 0x08, Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (s32)globalCtx->gameplayFrames, 0, 32, 64, 1, -globalCtx->gameplayFrames * 2, -globalCtx->gameplayFrames * 8, 32, 32)); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 200, 0, (s8)this->unk_324); gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 128); Matrix_Translate(-200.0f, 1086.0f, -200.0f, MTXMODE_NEW); Matrix_Scale(0.098000005f, 0.1f, 0.098000005f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(ovl_Boss_Ganon2_DL_00E1C0)); Matrix_Pop(); CLOSE_DISPS(globalCtx->state.gfxCtx); } } void func_80904340(BossGanon2* this, GlobalContext* globalCtx) { s16 i; f32 rand; f32 angle; f32 sin; f32 cos; OPEN_DISPS(globalCtx->state.gfxCtx); Matrix_Push(); if ((this->unk_330 != 0) || (this->unk_328 != 0)) { if (this->unk_330 != 0) { this->unk_330--; } else { this->unk_328 -= 70; if (this->unk_328 < 0) { this->unk_328 = 0; } } Math_ApproachF(&this->unk_32C, 0.13f, 1.0f, 0.065f); gDPPipeSync(POLY_XLU_DISP++); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, this->unk_328); BossGanon2_InitRand(this->unk_340 + 1, 0x71AC - this->unk_340, 0x263A); rand = BossGanon2_RandZeroOne(); for (i = 0; i < 5; i++) { FrameInterpolation_RecordOpenChild("Ganon 80904340", i); angle = (i * (2 * M_PI / 5)) + (rand * M_PI); sin = 5000.0f * sinf(angle); cos = 5000.0f * cosf(angle); Matrix_Translate(-200.0f + sin, 4786.0f, -200.0f + cos, MTXMODE_NEW); Matrix_Scale(this->unk_32C, this->unk_32C, this->unk_32C, MTXMODE_APPLY); Matrix_RotateY(angle, MTXMODE_APPLY); Matrix_RotateZ((BossGanon2_RandZeroOne() - 0.5f) * 100.0f * 0.01f, MTXMODE_APPLY); if (BossGanon2_RandZeroOne() < 0.5f) { Matrix_RotateY(M_PI, MTXMODE_APPLY); } gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(ovl_Boss_Ganon2_DL_00D798)); FrameInterpolation_RecordCloseChild(); } } Matrix_Pop(); CLOSE_DISPS(globalCtx->state.gfxCtx); } void func_8090464C(BossGanon2* this, GlobalContext* globalCtx) { s32 pad; if (this->unk_1B4 > 0.0f) { OPEN_DISPS(globalCtx->state.gfxCtx); Matrix_Push(); gDPPipeSync(POLY_XLU_DISP++); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 170, (s16)this->unk_1B4); gDPSetEnvColor(POLY_XLU_DISP++, 255, 200, 0, 128); Matrix_Translate(this->unk_1B8.x, this->unk_1B8.y, this->unk_1B8.z, MTXMODE_NEW); Matrix_ReplaceRotation(&globalCtx->billboardMtxF); Matrix_RotateZ(-0.2f, MTXMODE_APPLY); Matrix_Scale(0.6f, 0.6f, 1.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(ovl_Boss_Ganon2_DL_00CCD8)); Matrix_Pop(); CLOSE_DISPS(globalCtx->state.gfxCtx); } } s32 BossGanon2_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) { s32 pad; BossGanon2* this = (BossGanon2*)thisx; OPEN_DISPS(globalCtx->state.gfxCtx); if (limbIndex == 15) { rot->y += this->unk_31A; rot->z += this->unk_31C; } if (limbIndex >= 42) { rot->x += this->unk_2F4[limbIndex] + this->unk_346; rot->y += this->unk_2FE[limbIndex]; if (this->unk_342 & 1) { gDPSetEnvColor(POLY_OPA_DISP++, 255, 0, 0, 255); } else { gDPSetEnvColor(POLY_OPA_DISP++, (s16)this->unk_1B0, (s16)this->unk_1B0, (s16)(*this).unk_1B0, 255); } } if ((limbIndex == 7) || (limbIndex == 13) || (limbIndex == 33) || (limbIndex == 34)) { *dList = NULL; } CLOSE_DISPS(globalCtx->state.gfxCtx); return 0; } void BossGanon2_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) { s8 pad; s8 temp_v0; BossGanon2* this = (BossGanon2*)thisx; Vec3f sp4C; OPEN_DISPS(globalCtx->state.gfxCtx); D_80907120.z = 17000.0f; D_8090712C.z = 3000.0f; if (D_809070CC[limbIndex] >= 0) { Matrix_MultVec3f(&D_80906D60, &this->unk_234[D_809070CC[limbIndex]]); } if (limbIndex == 15) { Matrix_MultVec3f(&D_80906D60, &this->unk_1B8); } else if (limbIndex == 3) { Matrix_MultVec3f(&D_80907108, &this->unk_1F4); } else if (limbIndex == 9) { Matrix_MultVec3f(&D_80907114, &this->unk_1E8); } else if (limbIndex == 38) { Matrix_MultVec3f(&D_80906D60, &this->unk_1DC); } else if (limbIndex == 41) { Matrix_MultVec3f(&D_80906D60, &this->unk_1D0); } else if (limbIndex == 45) { Matrix_MultVec3f(&D_80907138, &this->unk_1C4); } temp_v0 = D_8090709C[limbIndex]; if (temp_v0 >= 0) { Matrix_MultVec3f(&D_80906D60, &sp4C); func_808FD080(temp_v0, &this->unk_424, &sp4C); } if ((limbIndex == 7) || (limbIndex == 13)) { Matrix_Push(); Matrix_Scale(this->unk_224, this->unk_224, this->unk_224, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, *dList); Matrix_Pop(); } else if ((limbIndex == 33) || (limbIndex == 34)) { Matrix_Push(); Matrix_Scale(this->unk_228, this->unk_228, this->unk_228, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, *dList); Matrix_Pop(); } if (*dList != NULL) { if ((limbIndex == 7) && (this->unk_312 == 1)) { Matrix_MultVec3f(&D_809070FC, &this->unk_218); func_808FD080(0, &this->unk_444, &this->unk_218); Matrix_MultVec3f(&D_80907120, &this->unk_200); Matrix_MultVec3f(&D_8090712C, &this->unk_20C); } else if ((limbIndex == 13) && (this->unk_312 == 2)) { Matrix_MultVec3f(&D_809070FC, &this->unk_218); func_808FD080(1, &this->unk_444, &this->unk_218); Matrix_MultVec3f(&D_80907120, &this->unk_200); Matrix_MultVec3f(&D_8090712C, &this->unk_20C); } } CLOSE_DISPS(globalCtx->state.gfxCtx); } void func_80904D88(BossGanon2* this, GlobalContext* globalCtx) { s32 pad; s16 i; OPEN_DISPS(globalCtx->state.gfxCtx); if (this->unk_30C > 0.0f) { func_80093D84(globalCtx->state.gfxCtx); if (this->unk_380 > 0.0f) { gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 170, 255); gDPSetEnvColor(POLY_XLU_DISP++, 255, 200, 0, 0); } else { gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 255); gDPSetEnvColor(POLY_XLU_DISP++, 100, 255, 255, 0); } gSPDisplayList(POLY_XLU_DISP++, ovl_Boss_Ganon2_DL_00B308); for (i = 0; i < 15; i++) { FrameInterpolation_RecordOpenChild("Ganon 80904D88", i); Matrix_Translate(this->unk_234[i].x, this->unk_234[i].y, this->unk_234[i].z, MTXMODE_NEW); Matrix_ReplaceRotation(&globalCtx->billboardMtxF); Matrix_Scale(this->unk_30C, this->unk_30C, this->unk_30C, MTXMODE_APPLY); Matrix_RotateZ(Rand_CenteredFloat(M_PI), MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, ovl_Boss_Ganon2_DL_00B378); FrameInterpolation_RecordCloseChild(); } } CLOSE_DISPS(globalCtx->state.gfxCtx); } void func_80904FC8(BossGanon2* this, GlobalContext* globalCtx) { s32 pad; OPEN_DISPS(globalCtx->state.gfxCtx); if (this->unk_384 > 0.0f) { func_80093D84(globalCtx->state.gfxCtx); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 200); gDPSetEnvColor(POLY_XLU_DISP++, 255, 200, 0, 0); gSPDisplayList(POLY_XLU_DISP++, ovl_Boss_Ganon2_DL_00B308); Matrix_Translate(sBossGanon2Zelda->actor.world.pos.x, sBossGanon2Zelda->actor.world.pos.y + 80.0f, sBossGanon2Zelda->actor.world.pos.z, MTXMODE_NEW); Matrix_ReplaceRotation(&globalCtx->billboardMtxF); Matrix_Scale(this->unk_384, this->unk_384, this->unk_384, MTXMODE_APPLY); Matrix_RotateZ(this->unk_388, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(ovl_Boss_Ganon2_DL_00B378)); Matrix_RotateZ(this->unk_388 * -2.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(ovl_Boss_Ganon2_DL_00B378)); } CLOSE_DISPS(globalCtx->state.gfxCtx); } void func_8090523C(BossGanon2* this, GlobalContext* globalCtx) { Player* player; f32 phi_f20; OPEN_DISPS(globalCtx->state.gfxCtx); if (this->unk_38C > 0.0f) { s8 i; player = GET_PLAYER(globalCtx); func_80093D84(globalCtx->state.gfxCtx); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (s16)this->unk_38C); gDPSetEnvColor(POLY_XLU_DISP++, 0, 255, 255, 0); gSPDisplayList(POLY_XLU_DISP++, ovl_Boss_Ganon2_DL_00B308); for (i = 0; i < 11; i++) { FrameInterpolation_RecordOpenChild("Ganon 8090523C", i); Matrix_Mult(&player->mf_9E0, MTXMODE_NEW); Matrix_Translate((i * 250.0f) + 900.0f, 350.0f, 0.0f, MTXMODE_APPLY); if (i < 7) { phi_f20 = 1.0f; } else { phi_f20 = 1.0f - ((i - 7) * 0.2333333f); // 7 / 30 } Matrix_ReplaceRotation(&globalCtx->billboardMtxF); Matrix_Scale(200.0f * phi_f20, 200.0f * phi_f20, 1.0f, MTXMODE_APPLY); Matrix_RotateZ(Rand_ZeroFloat(2.0f * M_PI), MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(ovl_Boss_Ganon2_DL_00B378)); FrameInterpolation_RecordCloseChild(); } } CLOSE_DISPS(globalCtx->state.gfxCtx); } void BossGanon2_PostLimbDraw2(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) { s8 temp_v1 = D_80907144[limbIndex]; BossGanon2* this = (BossGanon2*)thisx; if (temp_v1 >= 0) { Matrix_MultVec3f(&D_80906D60, &this->unk_234[temp_v1]); } if (limbIndex == 11) { OPEN_DISPS(globalCtx->state.gfxCtx); gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gGanondorfEyesDL)); CLOSE_DISPS(globalCtx->state.gfxCtx); } else if (limbIndex == 10) { Matrix_MultVec3f(&D_80907164, &this->unk_1B8); } } void func_80905674(BossGanon2* this, GlobalContext* globalCtx) { s32 pad; if (this->unk_380 > 0.0f) { OPEN_DISPS(globalCtx->state.gfxCtx); Matrix_Push(); gDPPipeSync(POLY_XLU_DISP++); gSPSegment(POLY_XLU_DISP++, 0x08, Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, this->unk_19C * -8, 0, 32, 64, 1, this->unk_19C * -4, this->unk_19C * -8, 32, 32)); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 170, (s16)this->unk_37C); gDPSetEnvColor(POLY_XLU_DISP++, 255, 200, 0, 128); Matrix_Translate(sBossGanon2Zelda->actor.world.pos.x + 100.0f, sBossGanon2Zelda->actor.world.pos.y + 35.0f + 7.0f, sBossGanon2Zelda->actor.world.pos.z - 100.0f, MTXMODE_NEW); Matrix_RotateY(-M_PI / 4.0f, MTXMODE_APPLY); Matrix_Scale(0.040000003f, 0.040000003f, this->unk_380, MTXMODE_APPLY); Matrix_RotateX(M_PI / 2.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(ovl_Boss_Ganon2_DL_00EC40)); Matrix_Pop(); CLOSE_DISPS(globalCtx->state.gfxCtx); } } void BossGanon2_Draw(Actor* thisx, GlobalContext* globalCtx) { void* shadowTexture = Graph_Alloc(globalCtx->state.gfxCtx, 4096); BossGanon2* this = (BossGanon2*)thisx; s16 i; OPEN_DISPS(globalCtx->state.gfxCtx); func_80093D18(globalCtx->state.gfxCtx); func_80093D84(globalCtx->state.gfxCtx); switch (this->unk_337) { case 0: BossGanon2_SetObjectSegment(this, globalCtx, OBJECT_GANON, true); gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(gGanondorfEmptyEyeTex)); gSPSegment(POLY_XLU_DISP++, 0x09, SEGMENTED_TO_VIRTUAL(gGanondorfEmptyEyeTex)); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, NULL, BossGanon2_PostLimbDraw2, this); break; case 1: case 2: BossGanon2_SetObjectSegment(this, globalCtx, OBJECT_GANON2, true); gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sEyeTextures[this->unk_310])); func_808FD080(0, &this->unk_444, &D_8090717C); func_808FD080(1, &this->unk_444, &D_8090717C); this->unk_218 = D_8090717C; if (this->unk_342 & 1) { POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 0xFF, 0, 0, 0xFF, 0x384, 0x44B); } Matrix_Translate(0.0f, -4000.0f, 4000.0f, MTXMODE_APPLY); Matrix_RotateX(this->unk_394, MTXMODE_APPLY); Matrix_Translate(0.0f, 4000.0f, -4000.0f, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, BossGanon2_OverrideLimbDraw, BossGanon2_PostLimbDraw, this); POLY_OPA_DISP = Gameplay_SetFog(globalCtx, POLY_OPA_DISP); BossGanon2_GenShadowTexture(shadowTexture, this, globalCtx); BossGanon2_DrawShadowTexture(shadowTexture, this, globalCtx); break; } BossGanon2_SetObjectSegment(this, globalCtx, OBJECT_GANON2, true); func_80904340(this, globalCtx); func_80904108(this, globalCtx); func_80904D88(this, globalCtx); func_8090464C(this, globalCtx); func_80905674(this, globalCtx); func_80904FC8(this, globalCtx); func_8090523C(this, globalCtx); if ((this->unk_312 != 0) || (D_80907080 != 0)) { func_80903F38(this, globalCtx); if (this->unk_312 == 0) { s32 pad; D_80907080 -= 40; if (D_80907080 <= 0) { D_80907080 = 0; } } D_80910638++; } else { for (i = 0; i < 3; i++) { D_809105D8[i] = this->unk_200; D_80910608[i] = this->unk_20C; } D_80910638 = 0; } CLOSE_DISPS(globalCtx->state.gfxCtx); func_809060E8(globalCtx); } void func_80905DA8(BossGanon2* this, GlobalContext* globalCtx) { s32 pad[5]; Player* player = GET_PLAYER(globalCtx); BossGanon2Effect* effect = globalCtx->specialEffects; Vec3f sp78; s16 i; for (i = 0; i < ARRAY_COUNT(sBossGanon2Particles); i++, effect++) { if (effect->type != 0) { effect->position.x += effect->velocity.x; effect->position.y += effect->velocity.y; effect->position.z += effect->velocity.z; effect->unk_01++; effect->velocity.x += effect->accel.x; effect->velocity.y += effect->accel.y; effect->velocity.z += effect->accel.z; if (effect->type == 1) { if (effect->unk_2E == 0) { effect->unk_38.z += 1.0f; effect->unk_38.y = (2.0f * M_PI) / 5.0f; } else { effect->unk_38.z = M_PI / 2.0f; effect->unk_38.y = 0.0f; if (effect->position.y <= 1098.0f) { effect->position.y = 1098.0f; if (effect->velocity.y < -10.0f) { sp78 = effect->position; sp78.y = 1086.0f; func_80078884(NA_SE_IT_SHIELD_REFLECT_SW); CollisionCheck_SpawnShieldParticlesMetal(globalCtx, &sp78); } effect->velocity.y = 0.0f; } if ((SQ(player->actor.world.pos.x - effect->position.x) + SQ(player->actor.world.pos.z - effect->position.z)) < SQ(25.0f)) { effect->type = 0; this->unk_39C = 10; } } } else if (effect->type == 2) { effect->unk_38.x += 0.1f; effect->unk_38.y += 0.4f; if ((sqrtf(SQ(-200.0f - effect->position.x) + SQ(-200.0f - effect->position.z)) < 1000.0f)) { if (effect->position.y < 1186.0f) { if (effect->unk_2E == 0) { effect->unk_2E++; effect->position.y = 1186.0f; effect->velocity.x *= 0.75f; effect->velocity.z *= 0.75f; effect->velocity.y *= -0.2f; } else { effect->type = 0; } } } else if ((effect->position.y < 0.0f)) { effect->type = 0; } } } } } void func_809060E8(GlobalContext* globalCtx) { s16 alpha; u8 usingObjectGEff = false; BossGanon2Effect* effect; s16 i; BossGanon2Effect* effects; effects = effect = globalCtx->specialEffects; OPEN_DISPS(globalCtx->state.gfxCtx); func_80093D18(globalCtx->state.gfxCtx); for (i = 0; i < 1; i++) { if (effect->type == 1) { FrameInterpolation_RecordOpenChild("Ganon 809060E8 0", i); Vec3f spA0; f32 temp_f0; f32 angle; func_80093D84(globalCtx->state.gfxCtx); spA0.x = globalCtx->envCtx.dirLight1.params.dir.x; spA0.y = globalCtx->envCtx.dirLight1.params.dir.y; spA0.z = globalCtx->envCtx.dirLight1.params.dir.z; func_8002EABC(&effect->position, &globalCtx->view.eye, &spA0, globalCtx->state.gfxCtx); Matrix_Translate(effect->position.x, effect->position.y, effect->position.z, MTXMODE_NEW); Matrix_Scale(0.03f, 0.03f, 0.03f, MTXMODE_APPLY); Matrix_RotateY(effect->unk_38.z, MTXMODE_APPLY); Matrix_RotateX(effect->unk_38.y, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPSegment(POLY_OPA_DISP++, 0x08, Gfx_TexScroll(globalCtx->state.gfxCtx, 0, 0 - (globalCtx->gameplayFrames & 0x7F), 32, 32)); gSPDisplayList(POLY_OPA_DISP++, ovl_Boss_Ganon2_DL_0103A8); if ((globalCtx->envCtx.unk_BD == 1) || (globalCtx->envCtx.unk_BD == 2)) { alpha = (s16)(globalCtx->envCtx.unk_D8 * 150.0f) + 50; angle = M_PI / 5.0f; } else { alpha = 100; angle = M_PI / 2.0f; } gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 0, 0, 0, alpha); temp_f0 = effect->position.y - 1098.0f; Matrix_Translate(effect->position.x + temp_f0, 1086.0f, (effect->position.z - 1.0f) + temp_f0, MTXMODE_NEW); Matrix_RotateY(angle, MTXMODE_APPLY); Matrix_Scale(1.0f, 0.0f, 1.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, ovl_Boss_Ganon2_DL_00F188); FrameInterpolation_RecordCloseChild(); } } effect = effects; for (i = 0; i < ARRAY_COUNT(sBossGanon2Particles); i++, effect++) { if (effect->type == 2) { FrameInterpolation_RecordOpenChild("Ganon 809060E8 1", i); if (!usingObjectGEff) { BossGanon2_SetObjectSegment(NULL, globalCtx, OBJECT_GEFF, true); usingObjectGEff++; } Matrix_Translate(effect->position.x, effect->position.y, effect->position.z, MTXMODE_NEW); Matrix_Scale(effect->scale, effect->scale, effect->scale, MTXMODE_APPLY); Matrix_RotateY(effect->unk_38.z, MTXMODE_APPLY); Matrix_RotateX(effect->unk_38.y, MTXMODE_APPLY); Matrix_RotateZ(effect->unk_38.x, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, gGanonRubbleDL); FrameInterpolation_RecordCloseChild(); } } CLOSE_DISPS(globalCtx->state.gfxCtx); } void func_80906538(BossGanon2* this, u8* shadowTexture, f32 arg2) { s16 temp_t0; s16 temp_v0; s16 temp_a3; s16 phi_v1; s16 phi_a1; s16 i; f32 lerpx; s16 j; f32 lerpy; f32 lerpz; Vec3f sp70; Vec3f sp64; for (i = 0; i < 15; i++) { if ((arg2 == 0.0f) || ((j = D_809071CC[i]) >= 0)) { if (arg2 > 0.0f) { lerpx = this->unk_234[i].x + (this->unk_234[j].x - this->unk_234[i].x) * arg2; lerpy = this->unk_234[i].y + (this->unk_234[j].y - this->unk_234[i].y) * arg2; lerpz = this->unk_234[i].z + (this->unk_234[j].z - this->unk_234[i].z) * arg2; sp70.x = lerpx - this->actor.world.pos.x; sp70.y = lerpy - this->actor.world.pos.y + 76.0f + 30.0f + 30.0f + 100.0f; sp70.z = lerpz - this->actor.world.pos.z; } else { sp70.x = this->unk_234[i].x - this->actor.world.pos.x; sp70.y = this->unk_234[i].y - this->actor.world.pos.y + 76.0f + 30.0f + 30.0f + 100.0f; sp70.z = this->unk_234[i].z - this->actor.world.pos.z; } Matrix_MultVec3f(&sp70, &sp64); sp64.x *= 0.2f; sp64.y *= 0.2f; temp_a3 = sp64.x + 32.0f; temp_t0 = (s16)sp64.y * 64; if (D_809071EC[i] == 2) { for (j = 0, phi_a1 = -0x180; j < 12; j++, phi_a1 += 0x40) { for (phi_v1 = -D_809071B4[j]; phi_v1 < D_809071B4[j]; phi_v1++) { temp_v0 = temp_a3 + phi_v1 + temp_t0 + phi_a1; if ((temp_v0 >= 0) && (temp_v0 < 0x1000)) { shadowTexture[temp_v0] = 0xFF; } } } } else if (D_809071EC[i] == 1) { for (j = 0, phi_a1 = -0x100; j < 8; j++, phi_a1 += 0x40) { for (phi_v1 = -D_809071A4[j]; phi_v1 < D_809071A4[j]; phi_v1++) { temp_v0 = temp_a3 + phi_v1 + temp_t0 + phi_a1; if ((temp_v0 >= 0) && (temp_v0 < 0x1000)) { shadowTexture[temp_v0] = 0xFF; } } } } else if (D_809071EC[i] == 0) { for (j = 0, phi_a1 = -0xC0; j < 7; j++, phi_a1 += 0x40) { for (phi_v1 = -D_80907194[j]; phi_v1 < D_80907194[j] - 1; phi_v1++) { temp_v0 = temp_a3 + phi_v1 + temp_t0 + phi_a1; if ((temp_v0 >= 0) && (temp_v0 < 0x1000)) { shadowTexture[temp_v0] = 0xFF; } } } } else { for (j = 0, phi_a1 = -0x80; j < 6; j++, phi_a1 += 0x40) { for (phi_v1 = -D_80907188[j]; phi_v1 < D_80907188[j] - 1; phi_v1++) { temp_v0 = temp_a3 + phi_v1 + temp_t0 + phi_a1; if ((temp_v0 >= 0) && (temp_v0 < 0x1000)) { shadowTexture[temp_v0] = 0xFF; } } } } } } } void BossGanon2_GenShadowTexture(void* shadowTexture, BossGanon2* this, GlobalContext* globalCtx) { s16 i; u32* p = shadowTexture; for (i = 0; i < 1024; i++, p++) { *p = 0; } Matrix_RotateX(1.0f, MTXMODE_NEW); for (i = 0; i < 6; i++) { func_80906538(this, shadowTexture, i / 5.0f); } } void BossGanon2_DrawShadowTexture(void* shadowTexture, BossGanon2* this, GlobalContext* globalCtx) { s32 pad; GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; s16 alpha; OPEN_DISPS(gfxCtx); func_80093D18(globalCtx->state.gfxCtx); if ((globalCtx->envCtx.unk_BD == 1) || (globalCtx->envCtx.unk_BD == 2)) { alpha = (s16)(globalCtx->envCtx.unk_D8 * 180.0f) + 30; } else { alpha = 120; } gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, alpha); gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0); Matrix_Translate(this->actor.world.pos.x, this->actor.floorHeight, this->actor.world.pos.z - 20.0f, MTXMODE_NEW); Matrix_Scale(1.65f, 1.0f, 1.65f, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, ovl_Boss_Ganon2_DL_00B3D0); gDPLoadTextureBlock(POLY_OPA_DISP++, shadowTexture, G_IM_FMT_I, G_IM_SIZ_8b, 64, 64, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD); gSPDisplayList(POLY_OPA_DISP++, ovl_Boss_Ganon2_DL_00B3F0); CLOSE_DISPS(gfxCtx); } void BossGanon2_Reset(void) { D_8090EB20.x = 0; D_8090EB20.y = 0; D_8090EB20.z = 0; D_80910638 = 0; sBossGanon2Zelda = NULL; D_8090EB30 = NULL; sBossGanon2Seed1 = 0; sBossGanon2Seed2 = 0; sBossGanon2Seed3 = 0; memset(D_809105D8, 0, sizeof(D_809105D8)); memset(D_80910608, 0, sizeof(D_80910608)); memset(sBossGanon2Particles, 0, sizeof(sBossGanon2Particles)); }