/* * File: z_en_fhg.c * Overlay: ovl_En_fHG * Description: Phantom Ganon's Horse */ #include "z_en_fhg.h" #include "objects/object_fhg/object_fhg.h" #include "overlays/actors/ovl_Door_Shutter/z_door_shutter.h" #include "overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.h" #include "overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.h" #define FLAGS ACTOR_FLAG_4 typedef struct { /* 0x00 */ Vec3f pos; /* 0x0C */ s16 yRot; } EnfHGPainting; // size = 0x10; typedef enum { /* 0 */ INTRO_WAIT, /* 1 */ INTRO_START, /* 2 */ INTRO_FENCE, /* 3 */ INTRO_BACK, /* 4 */ INTRO_REVEAL, /* 5 */ INTRO_CUT, /* 6 */ INTRO_LAUGH, /* 7 */ INTRO_TITLE, /* 8 */ INTRO_RETREAT, /* 9 */ INTRO_FINISH, /* 15 */ INTRO_READY = 15 } EnfHGIntroState; void EnfHG_Init(Actor* thisx, GlobalContext* globalCtx); void EnfHG_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnfHG_Update(Actor* thisx, GlobalContext* globalCtx); void EnfHG_Draw(Actor* thisx, GlobalContext* globalCtx); void EnfHG_SetupIntro(EnfHG* this, GlobalContext* globalCtx); void EnfHG_Intro(EnfHG* this, GlobalContext* globalCtx); void EnfHG_SetupApproach(EnfHG* this, GlobalContext* globalCtx, s16 paintingIndex); void EnfHG_Approach(EnfHG* this, GlobalContext* globalCtx); void EnfHG_Attack(EnfHG* this, GlobalContext* globalCtx); void EnfHG_Damage(EnfHG* this, GlobalContext* globalCtx); void EnfHG_Retreat(EnfHG* this, GlobalContext* globalCtx); void EnfHG_Done(EnfHG* this, GlobalContext* globalCtx); const ActorInit En_fHG_InitVars = { ACTOR_EN_FHG, ACTORCAT_BG, FLAGS, OBJECT_FHG, sizeof(EnfHG), (ActorFunc)EnfHG_Init, (ActorFunc)EnfHG_Destroy, (ActorFunc)EnfHG_Update, (ActorFunc)EnfHG_Draw, NULL, }; static EnfHGPainting sPaintings[] = { { { 0.0f, 60.0f, -315.0f }, 0x0000 }, { { -260.0f, 60.0f, -145.0f }, 0x2AAA }, { { -260.0f, 60.0f, 165.0f }, 0x5554 }, { { 0.0f, 60.0f, 315.0f }, 0x7FFE }, { { 260.0f, 60.0f, 155.0f }, 0xAAA8 }, { { 260.0f, 60.0f, -155.0f }, 0xD552 }, }; static InitChainEntry sInitChain[] = { ICHAIN_S8(naviEnemyId, 0x1A, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 1200, ICHAIN_STOP), }; void EnfHG_Init(Actor* thisx, GlobalContext* globalCtx2) { GlobalContext* globalCtx = globalCtx2; EnfHG* this = (EnfHG*)thisx; Actor_ProcessInitChain(&this->actor, sInitChain); Flags_SetSwitch(globalCtx, 0x14); Actor_SetScale(&this->actor, 0.011499999f); this->actor.gravity = -3.5f; ActorShape_Init(&this->actor.shape, -2600.0f, NULL, 20.0f); this->actor.speedXZ = 0.0f; this->actor.focus.pos = this->actor.world.pos; this->actor.focus.pos.y += 70.0f; Skin_Init(globalCtx, &this->skin, &gPhantomHorseSkel, &gPhantomHorseRunningAnim); if (this->actor.params >= GND_FAKE_BOSS) { EnfHG_SetupApproach(this, globalCtx, this->actor.params - GND_FAKE_BOSS); } else { EnfHG_SetupIntro(this, globalCtx); } } void EnfHG_Destroy(Actor* thisx, GlobalContext* globalCtx) { s32 pad; EnfHG* this = (EnfHG*)thisx; osSyncPrintf("F DT1\n"); Skin_Free(globalCtx, &this->skin); osSyncPrintf("F DT2\n"); } void EnfHG_SetupIntro(EnfHG* this, GlobalContext* globalCtx) { Animation_PlayLoop(&this->skin.skelAnime, &gPhantomHorseIdleAnim); this->actionFunc = EnfHG_Intro; this->actor.world.pos.x = GND_BOSSROOM_CENTER_X; this->actor.world.pos.y = GND_BOSSROOM_CENTER_Y - 267.0f; this->actor.world.pos.z = GND_BOSSROOM_CENTER_Z; } void EnfHG_Intro(EnfHG* this, GlobalContext* globalCtx) { static Vec3f audioVec = { 0.0f, 0.0f, 50.0f }; s32 pad64; Player* player = GET_PLAYER(globalCtx); BossGanondrof* bossGnd = (BossGanondrof*)this->actor.parent; s32 pad58; s32 pad54; if (this->cutsceneState != INTRO_FINISH) { SkelAnime_Update(&this->skin.skelAnime); } switch (this->cutsceneState) { case INTRO_WAIT: if ((fabsf(player->actor.world.pos.x - (GND_BOSSROOM_CENTER_X + 0.0f)) < 150.0f) && (fabsf(player->actor.world.pos.z - (GND_BOSSROOM_CENTER_Z + 0.0f)) < 150.0f)) { this->cutsceneState = INTRO_READY; } break; case INTRO_READY: if ((fabsf(player->actor.world.pos.x - (GND_BOSSROOM_CENTER_X + 0.0f)) < 100.0f) && (fabsf(player->actor.world.pos.z - (GND_BOSSROOM_CENTER_Z + 315.0f)) < 100.0f)) { this->cutsceneState = INTRO_START; if (gSaveContext.eventChkInf[7] & 4) { this->timers[0] = 57; } } break; case INTRO_START: if (gSaveContext.eventChkInf[7] & 4) { if (this->timers[0] == 55) { Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_DOOR_SHUTTER, GND_BOSSROOM_CENTER_X + 0.0f, GND_BOSSROOM_CENTER_Y - 97.0f, GND_BOSSROOM_CENTER_Z + 308.0f, 0, 0, 0, (SHUTTER_PG_BARS << 6)); } if (this->timers[0] == 51) { Audio_PlayActorSound2(this->actor.child, NA_SE_EV_SPEAR_FENCE); Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_BOSS); } if (this->timers[0] == 0) { EnfHG_SetupApproach(this, globalCtx, Rand_ZeroOne() * 5.99f); this->bossGndSignal = FHG_START_FIGHT; } break; } func_80064520(globalCtx, &globalCtx->csCtx); func_8002DF54(globalCtx, &this->actor, 8); this->cutsceneCamera = Gameplay_CreateSubCamera(globalCtx); Gameplay_ChangeCameraStatus(globalCtx, MAIN_CAM, CAM_STAT_WAIT); Gameplay_ChangeCameraStatus(globalCtx, this->cutsceneCamera, CAM_STAT_ACTIVE); this->cutsceneState = INTRO_FENCE; this->timers[0] = 60; this->actor.world.pos.y = GND_BOSSROOM_CENTER_Y - 7.0f; Audio_QueueSeqCmd(0x1 << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0x100FF); gSaveContext.eventChkInf[7] |= 4; Flags_SetSwitch(globalCtx, 0x23); case INTRO_FENCE: player->actor.world.pos.x = GND_BOSSROOM_CENTER_X + 0.0f; player->actor.world.pos.y = GND_BOSSROOM_CENTER_Y + 7.0f; player->actor.world.pos.z = GND_BOSSROOM_CENTER_Z + 155.0f; player->actor.world.rot.y = player->actor.shape.rot.y = 0; player->actor.speedXZ = 0.0f; this->cameraEye.x = GND_BOSSROOM_CENTER_X + 0.0f; this->cameraEye.y = GND_BOSSROOM_CENTER_Y + 37.0f; this->cameraEye.z = GND_BOSSROOM_CENTER_Z + 170.0f; this->cameraAt.x = GND_BOSSROOM_CENTER_X + 0.0f; this->cameraAt.y = GND_BOSSROOM_CENTER_Y + 47.0f; this->cameraAt.z = GND_BOSSROOM_CENTER_Z + 315.0f; if (this->timers[0] == 25) { Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_DOOR_SHUTTER, GND_BOSSROOM_CENTER_X + 0.0f, GND_BOSSROOM_CENTER_Y - 97.0f, GND_BOSSROOM_CENTER_Z + 308.0f, 0, 0, 0, (SHUTTER_PG_BARS << 6)); } if (this->timers[0] == 21) { Audio_PlayActorSound2(this->actor.child, NA_SE_EV_SPEAR_FENCE); } if (this->timers[0] == 0) { this->cutsceneState = INTRO_BACK; this->timers[0] = 80; } break; case INTRO_BACK: if (this->timers[0] == 25) { Audio_PlayActorSound2(&this->actor, NA_SE_EV_GANON_HORSE_GROAN); } if (this->timers[0] == 20) { func_8002DF54(globalCtx, &this->actor, 9); } if (this->timers[0] == 1) { Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_OPENING_GANON); } Math_ApproachF(&this->cameraEye.x, GND_BOSSROOM_CENTER_X + 40.0f, 0.05f, this->cameraSpeedMod * 20.0f); Math_ApproachF(&this->cameraEye.y, GND_BOSSROOM_CENTER_Y + 37.0f, 0.05f, this->cameraSpeedMod * 20.0f); Math_ApproachF(&this->cameraEye.z, GND_BOSSROOM_CENTER_Z + 80.0f, 0.05f, this->cameraSpeedMod * 20.0f); Math_ApproachF(&this->cameraAt.x, GND_BOSSROOM_CENTER_X - 100.0f, 0.05f, this->cameraSpeedMod * 20.0f); Math_ApproachF(&this->cameraAt.y, GND_BOSSROOM_CENTER_Y + 47.0f, 0.05f, this->cameraSpeedMod * 20.0f); Math_ApproachF(&this->cameraAt.z, GND_BOSSROOM_CENTER_Z + 335.0f, 0.05f, this->cameraSpeedMod * 20.0f); Math_ApproachF(&this->cameraSpeedMod, 1.0f, 1.0f, 0.01f); if (this->timers[0] == 0) { this->cutsceneState = INTRO_REVEAL; this->timers[0] = 50; this->cameraSpeedMod = 0.0f; } break; case INTRO_REVEAL: Math_ApproachF(&this->cameraEye.x, GND_BOSSROOM_CENTER_X + 70.0f, 0.1f, this->cameraSpeedMod * 20.0f); Math_ApproachF(&this->cameraEye.y, GND_BOSSROOM_CENTER_Y + 7.0f, 0.1f, this->cameraSpeedMod * 20.0f); Math_ApproachF(&this->cameraEye.z, GND_BOSSROOM_CENTER_Z + 200.0f, 0.1f, this->cameraSpeedMod * 20.0f); Math_ApproachF(&this->cameraAt.x, GND_BOSSROOM_CENTER_X - 150.0f, 0.1f, this->cameraSpeedMod * 20.0f); Math_ApproachF(&this->cameraAt.y, GND_BOSSROOM_CENTER_Y + 107.0f, 0.1f, this->cameraSpeedMod * 20.0f); Math_ApproachF(&this->cameraAt.z, GND_BOSSROOM_CENTER_Z - 65.0f, 0.1f, this->cameraSpeedMod * 40.0f); Math_ApproachF(&this->cameraSpeedMod, 1.0f, 1.0f, 0.05f); if (this->timers[0] == 5) { Audio_PlayActorSound2(&this->actor, NA_SE_EV_HORSE_SANDDUST); } if (this->timers[0] == 0) { this->cutsceneState = INTRO_CUT; this->timers[0] = 50; this->cameraSpeedMod = 0.0f; } break; case INTRO_CUT: this->cutsceneState = INTRO_LAUGH; this->cameraEye.x = GND_BOSSROOM_CENTER_X + 50.0f; this->cameraEye.y = GND_BOSSROOM_CENTER_Y + 17.0f; this->cameraEye.z = GND_BOSSROOM_CENTER_Z + 110.0f; this->cameraAt.x = GND_BOSSROOM_CENTER_X - 150.0f; this->cameraAt.y = GND_BOSSROOM_CENTER_Y + 207.0f; this->cameraAt.z = GND_BOSSROOM_CENTER_Z - 155.0f; this->cameraEyeVel.x = fabsf(this->cameraEye.x - (GND_BOSSROOM_CENTER_X + 20.0f)); this->cameraEyeVel.y = fabsf(this->cameraEye.y - (GND_BOSSROOM_CENTER_Y + 102.0f)); this->cameraEyeVel.z = fabsf(this->cameraEye.z - (GND_BOSSROOM_CENTER_Z + 25.0f)); this->cameraAtVel.x = fabsf(this->cameraAt.x - (GND_BOSSROOM_CENTER_X - 150.0f)); this->cameraAtVel.y = fabsf(this->cameraAt.y - (GND_BOSSROOM_CENTER_Y + 197.0f)); this->cameraAtVel.z = fabsf(this->cameraAt.z - (GND_BOSSROOM_CENTER_Z - 65.0f)); this->timers[0] = 250; case INTRO_LAUGH: Math_ApproachF(&this->cameraEye.x, GND_BOSSROOM_CENTER_X + 20.0f, 0.05f, this->cameraSpeedMod * this->cameraEyeVel.x); Math_ApproachF(&this->cameraEye.y, GND_BOSSROOM_CENTER_Y + 102.0f, 0.05f, this->cameraSpeedMod * this->cameraEyeVel.y); Math_ApproachF(&this->cameraEye.z, GND_BOSSROOM_CENTER_Z + 25.0f, 0.05f, this->cameraSpeedMod * this->cameraEyeVel.z); Math_ApproachF(&this->cameraAt.x, GND_BOSSROOM_CENTER_X - 150.0f, 0.05f, this->cameraSpeedMod * this->cameraAtVel.x); Math_ApproachF(&this->cameraAt.y, GND_BOSSROOM_CENTER_Y + 197.0f, 0.05f, this->cameraSpeedMod * this->cameraAtVel.y); Math_ApproachF(&this->cameraAt.z, GND_BOSSROOM_CENTER_Z - 65.0f, 0.05f, this->cameraSpeedMod * this->cameraAtVel.z); Math_ApproachF(&this->cameraSpeedMod, 0.01f, 1.0f, 0.001f); if ((this->timers[0] == 245) || (this->timers[0] == 3)) { Animation_MorphToPlayOnce(&this->skin.skelAnime, &gPhantomHorseRearingAnim, -8.0f); this->bossGndSignal = FHG_REAR; Audio_PlayActorSound2(&this->actor, NA_SE_EV_GANON_HORSE_NEIGH); if (this->timers[0] == 3) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_VOICE); } } if (this->timers[0] == 192) { Audio_PlayActorSound2(&this->actor, NA_SE_EV_HORSE_SANDDUST); } if (this->timers[0] == 212) { Audio_PlayActorSound2(&this->actor, NA_SE_EV_HORSE_LAND2); Animation_Change(&this->skin.skelAnime, &gPhantomHorseIdleAnim, 0.3f, 0.0f, 5.0f, ANIMMODE_LOOP_INTERP, -10.0f); } if (this->timers[0] == 90) { globalCtx->envCtx.unk_BF = 2; globalCtx->envCtx.unk_D6 = 0x14; } if (this->timers[0] == 100) { this->bossGndSignal = FHG_LIGHTNING; } if (this->timers[0] == 60) { this->bossGndSignal = FHG_RIDE; } if (this->timers[0] == 130) { Audio_QueueSeqCmd(0x1 << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0x5000FF); } if (this->timers[0] == 30) { bossGnd->work[GND_EYE_STATE] = GND_EYESTATE_BRIGHTEN; } if (this->timers[0] == 35) { func_80078914(&audioVec, NA_SE_EN_FANTOM_EYE); } if (this->timers[0] == 130) { bossGnd->work[GND_EYE_STATE] = GND_EYESTATE_FADE; func_80078914(&audioVec, NA_SE_EN_FANTOM_ST_LAUGH); } if (this->timers[0] == 20) { Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_BOSS); } if (this->timers[0] == 2) { this->cameraSpeedMod = 0.0f; this->cutsceneState = INTRO_TITLE; this->cameraEyeVel.x = fabsf(this->cameraEye.x - (GND_BOSSROOM_CENTER_X + 180.0f)); this->cameraEyeVel.y = fabsf(this->cameraEye.y - (GND_BOSSROOM_CENTER_Y + 7.0f)); this->cameraEyeVel.z = fabsf(this->cameraEye.z - (GND_BOSSROOM_CENTER_Z + 140.0f)); this->timers[0] = 100; this->timers[1] = 34; this->cameraAtVel.x = fabsf(this->cameraAt.x - this->actor.world.pos.x); this->cameraAtVel.y = fabsf(this->cameraAt.y - ((this->actor.world.pos.y + 70.0f) - 20.0f)); this->cameraAtVel.z = fabsf(this->cameraAt.z - this->actor.world.pos.z); } break; case INTRO_TITLE: if (this->timers[1] == 1) { Animation_Change(&this->skin.skelAnime, &gPhantomHorseIdleAnim, 0.5f, 0.0f, Animation_GetLastFrame(&gPhantomHorseIdleAnim), ANIMMODE_LOOP_INTERP, -3.0f); } Math_ApproachF(&this->cameraEye.x, GND_BOSSROOM_CENTER_X + 180.0f, 0.1f, this->cameraSpeedMod * this->cameraEyeVel.x); Math_ApproachF(&this->cameraEye.y, GND_BOSSROOM_CENTER_Y + 7.0f, 0.1f, this->cameraSpeedMod * this->cameraEyeVel.y); Math_ApproachF(&this->cameraEye.z, this->cameraPanZ + (GND_BOSSROOM_CENTER_Z + 140.0f), 0.1f, this->cameraSpeedMod * this->cameraEyeVel.z); Math_ApproachF(&this->cameraPanZ, -100.0f, 0.1f, 1.0f); Math_ApproachF(&this->cameraAt.x, this->actor.world.pos.x, 0.1f, this->cameraSpeedMod * 10.0f); Math_ApproachF(&this->cameraAt.y, (this->actor.world.pos.y + 70.0f) - 20.0f, 0.1f, this->cameraSpeedMod * 10.0f); Math_ApproachF(&this->cameraAt.z, this->actor.world.pos.z, 0.1f, this->cameraSpeedMod * 10.0f); Math_ApproachF(&this->actor.world.pos.y, 60.0f, 0.1f, 2.0f); this->actor.world.pos.y += 2.0f * Math_SinS(this->gallopTimer * 0x5DC); Math_ApproachF(&this->cameraSpeedMod, 1.0f, 1.0f, 0.05f); if (this->timers[0] == 75) { TitleCard_InitBossName(globalCtx, &globalCtx->actorCtx.titleCtx, SEGMENTED_TO_VIRTUAL(gPhantomGanonTitleCardTex), 160, 180, 128, 40, true); } if (this->timers[0] == 0) { this->cutsceneState = INTRO_RETREAT; this->timers[0] = 200; this->timers[1] = 23; this->cameraSpeedMod = 0.0f; Animation_Change(&this->skin.skelAnime, &gPhantomHorseLeapAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gPhantomHorseLeapAnim), ANIMMODE_ONCE_INTERP, -4.0f); this->bossGndSignal = FHG_SPUR; Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_VOICE); Audio_PlayActorSound2(&this->actor, NA_SE_EV_GANON_HORSE_NEIGH); } break; case INTRO_RETREAT: if (this->timers[1] == 1) { Animation_Change(&this->skin.skelAnime, &gPhantomHorseLandAnim, 0.5f, 0.0f, Animation_GetLastFrame(&gPhantomHorseLandAnim), ANIMMODE_ONCE_INTERP, -3.0f); this->bossGndSignal = FHG_FINISH; } if (this->timers[0] == 170) { func_8002DF54(globalCtx, &this->actor, 8); Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_MASIC2); } Math_ApproachF(&this->cameraEye.z, this->cameraPanZ + (GND_BOSSROOM_CENTER_Z + 100.0f), 0.1f, this->cameraSpeedMod * 1.5f); Math_ApproachF(&this->cameraPanZ, -100.0f, 0.1f, 1.0f); Math_ApproachF(&this->actor.world.pos.z, GND_BOSSROOM_CENTER_Z + 400.0f - 0.5f, 1.0f, this->cameraSpeedMod * 10.0f); Math_ApproachF(&this->cameraSpeedMod, 1.0f, 1.0f, 0.05f); if ((fabsf(this->actor.world.pos.z - (GND_BOSSROOM_CENTER_Z + 400.0f - 0.5f)) < 300.0f) && !this->spawnedWarp) { this->spawnedWarp = true; Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_FHG_FIRE, GND_BOSSROOM_CENTER_X + 0.0f, this->actor.world.pos.y + 50.0f, GND_BOSSROOM_CENTER_Z + 400.0f - 0.5f, 0, this->actor.shape.rot.y, 0, FHGFIRE_WARP_RETREAT); this->fhgFireKillWarp = true; } Math_ApproachF(&this->cameraAt.x, this->actor.world.pos.x, 0.2f, 50.0f); Math_ApproachF(&this->cameraAt.z, this->actor.world.pos.z, 0.2f, 50.0f); osSyncPrintf("TIME %d-------------------------------------------------\n", this->timers[0]); if (fabsf(this->actor.world.pos.z - (GND_BOSSROOM_CENTER_Z + 400.0f - 0.5f)) < 1.0f) { globalCtx->envCtx.unk_BF = 0; globalCtx->envCtx.unk_D6 = 0x14; this->cutsceneState = INTRO_FINISH; Animation_MorphToLoop(&this->skin.skelAnime, &gPhantomHorseRunningAnim, -3.0f); this->bossGndSignal = FHG_START_FIGHT; this->timers[1] = 75; this->timers[0] = 140; } break; case INTRO_FINISH: EnfHG_Retreat(this, globalCtx); Math_ApproachF(&this->cameraEye.z, this->cameraPanZ + (GND_BOSSROOM_CENTER_Z + 100.0f), 0.1f, this->cameraSpeedMod * 1.5f); Math_ApproachF(&this->cameraPanZ, -100.0f, 0.1f, 1.0f); Math_ApproachF(&this->cameraAt.y, (this->actor.world.pos.y + 70.0f) - 20.0f, 0.1f, this->cameraSpeedMod * 10.0f); if (this->timers[1] == 0) { Camera* camera = Gameplay_GetCamera(globalCtx, 0); camera->eye = this->cameraEye; camera->eyeNext = this->cameraEye; camera->at = this->cameraAt; func_800C08AC(globalCtx, this->cutsceneCamera, 0); this->cutsceneCamera = 0; func_80064534(globalCtx, &globalCtx->csCtx); func_8002DF54(globalCtx, &this->actor, 7); this->actionFunc = EnfHG_Retreat; } break; } if (this->cutsceneCamera != 0) { Gameplay_CameraSetAtEye(globalCtx, this->cutsceneCamera, &this->cameraAt, &this->cameraEye); } } void EnfHG_SetupApproach(EnfHG* this, GlobalContext* globalCtx, s16 paintingIndex) { s16 oppositeIndex[6] = { 3, 4, 5, 0, 1, 2 }; Animation_MorphToLoop(&this->skin.skelAnime, &gPhantomHorseRunningAnim, 0.0f); this->actionFunc = EnfHG_Approach; this->curPainting = paintingIndex; this->targetPainting = oppositeIndex[this->curPainting]; osSyncPrintf("KABE NO 1 = %d\n", this->curPainting); osSyncPrintf("KABE NO 2 = %d\n", this->targetPainting); this->actor.world.pos.x = (1.3f * sPaintings[this->curPainting].pos.x) + (GND_BOSSROOM_CENTER_X - 4.0f); this->actor.world.pos.y = sPaintings[this->curPainting].pos.y + (GND_BOSSROOM_CENTER_Y + 153.0f); this->actor.world.pos.z = (1.3f * sPaintings[this->curPainting].pos.z) - -(GND_BOSSROOM_CENTER_Z - 10.0f); this->actor.world.rot.y = sPaintings[this->curPainting].yRot; osSyncPrintf("XP1 = %f\n", this->actor.world.pos.x); osSyncPrintf("ZP1 = %f\n", this->actor.world.pos.z); this->inPaintingPos.x = (sPaintings[this->targetPainting].pos.x * 1.3f) + (GND_BOSSROOM_CENTER_X - 4.0f); this->inPaintingPos.y = sPaintings[this->targetPainting].pos.y + (GND_BOSSROOM_CENTER_Y + 33.0f); this->inPaintingPos.z = (sPaintings[this->targetPainting].pos.z * 1.3f) - -(GND_BOSSROOM_CENTER_Z - 10.0f); this->inPaintingVelX = (fabsf(this->inPaintingPos.x - this->actor.world.pos.x) * 2) * 0.01f; if (this->inPaintingVelX < 1.0f) { this->inPaintingVelX = 1.0f; } this->inPaintingVelZ = (fabsf(this->inPaintingPos.z - this->actor.world.pos.z) * 2) * 0.01f; if (this->inPaintingVelZ < 1.0f) { this->inPaintingVelZ = 1.0f; } this->timers[0] = 100; this->actor.scale.x = 0.002f; this->actor.scale.y = 0.002f; this->actor.scale.z = 0.001f; this->approachRate = 0.0f; this->warpColorFilterR = globalCtx->lightCtx.fogColor[0]; this->warpColorFilterG = globalCtx->lightCtx.fogColor[1]; this->warpColorFilterB = globalCtx->lightCtx.fogColor[2]; this->warpColorFilterUnk1 = 0.0f; this->warpColorFilterUnk2 = 0.0f; this->turnRot = 0; this->turnTarget = 0; this->spawnedWarp = false; } void EnfHG_Approach(EnfHG* this, GlobalContext* globalCtx) { osSyncPrintf("STANDBY !!\n"); osSyncPrintf("XP2 = %f\n", this->actor.world.pos.x); osSyncPrintf("ZP2 = %f\n", this->actor.world.pos.z); if (this->actor.params == GND_REAL_BOSS) { this->hoofSfxPos.x = this->actor.projectedPos.x / (this->actor.scale.x * 100.0f); this->hoofSfxPos.y = this->actor.projectedPos.y / (this->actor.scale.x * 100.0f); this->hoofSfxPos.z = this->actor.projectedPos.z / (this->actor.scale.x * 100.0f); if ((this->gallopTimer % 8) == 0) { func_80078914(&this->hoofSfxPos, NA_SE_EV_HORSE_RUN); } } SkelAnime_Update(&this->skin.skelAnime); Math_ApproachF(&this->actor.scale.x, 0.011499999f, 1.0f, this->approachRate); Math_ApproachF(&this->approachRate, 0.0002f, 1.0f, 0.0000015f); Math_ApproachF(&this->actor.world.pos.y, 60.0f, 0.1f, 1.0f); this->actor.scale.y = this->actor.scale.x; if (this->timers[0] == 0) { osSyncPrintf("arg_data ------------------------------------>%d\n", this->actor.params); if (this->actor.params != GND_REAL_BOSS) { this->timers[0] = 140; this->actionFunc = EnfHG_Retreat; Animation_MorphToLoop(&this->skin.skelAnime, &gPhantomHorseRunningAnim, 0.0f); this->turnTarget = -0x8000; } else { this->actionFunc = EnfHG_Attack; Audio_PlayActorSound2(&this->actor, NA_SE_EV_GANON_HORSE_NEIGH); this->timers[0] = 40; Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_FHG_FIRE, this->actor.world.pos.x, this->actor.world.pos.y + 50.0f, this->actor.world.pos.z, 0, this->actor.shape.rot.y + 0x8000, 0, FHGFIRE_WARP_EMERGE); this->fhgFireKillWarp = false; } } } void EnfHG_Attack(EnfHG* this, GlobalContext* globalCtx) { osSyncPrintf("KABE OUT !!\n"); this->bossGndInPainting = false; SkelAnime_Update(&this->skin.skelAnime); if (this->timers[0] != 0) { Math_ApproachF(&this->actor.scale.z, 0.011499999f, 1.0f, 0.0002f); if (this->timers[0] == 1) { this->bossGndSignal = FHG_RAISE_SPEAR; this->timers[1] = 50; Animation_MorphToPlayOnce(&this->skin.skelAnime, &gPhantomHorseLeapAnim, 0.0f); } Math_ApproachF(&this->warpColorFilterR, 255.0f, 1.0f, 10.0f); Math_ApproachF(&this->warpColorFilterG, 255.0f, 1.0f, 10.0f); Math_ApproachF(&this->warpColorFilterB, 255.0f, 1.0f, 10.0f); Math_ApproachF(&this->warpColorFilterUnk1, -60.0f, 1.0f, 5.0f); } else { Math_ApproachF(&this->warpColorFilterR, globalCtx->lightCtx.fogColor[0], 1.0f, 10.0f); Math_ApproachF(&this->warpColorFilterG, globalCtx->lightCtx.fogColor[0], 1.0f, 10.0f); Math_ApproachF(&this->warpColorFilterB, globalCtx->lightCtx.fogColor[0], 1.0f, 10.0f); Math_ApproachF(&this->warpColorFilterUnk1, 0.0f, 1.0f, 5.0f); if (this->timers[1] == 29) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_MASIC2); Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_VOICE); } if (this->hitTimer == 0) { if (this->timers[1] == 24) { Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_FHG_FIRE, this->actor.world.pos.x, (this->actor.world.pos.y + 100.0f) + 25.0f, this->actor.world.pos.z, 0, 0, 0, FHGFIRE_LIGHTNING_STRIKE); } if (this->timers[1] == 45) { Animation_MorphToLoop(&this->skin.skelAnime, &gPhantomHorseAirAnim, 0.0f); } if (this->timers[1] == 38) { this->bossGndSignal = FHG_LIGHTNING; } if (this->timers[1] == 16) { Animation_MorphToPlayOnce(&this->skin.skelAnime, &gPhantomHorseLandAnim, 0.0f); this->bossGndSignal = FHG_RESET; } } Math_ApproachF(&this->actor.scale.z, 0.011499999f, 1.0f, 0.002f); Math_ApproachF(&this->actor.world.pos.x, this->inPaintingPos.x, 1.0f, this->inPaintingVelX); Math_ApproachF(&this->actor.world.pos.y, 60.0f, 0.1f, 1.0f); Math_ApproachF(&this->actor.world.pos.z, this->inPaintingPos.z, 1.0f, this->inPaintingVelZ); } if (this->hitTimer == 20) { this->actionFunc = EnfHG_Damage; this->spawnedWarp = false; Animation_Change(&this->skin.skelAnime, &gPhantomHorseLandAnim, -1.0f, 0.0f, Animation_GetLastFrame(&gPhantomHorseLandAnim), ANIMMODE_ONCE, -5.0f); this->timers[0] = 10; this->bossGndSignal = FHG_RESET; this->damageSpeedMod = 1.0f; } else { f32 dx = this->actor.world.pos.x - this->inPaintingPos.x; f32 dz = this->actor.world.pos.z - this->inPaintingPos.z; f32 dxz = sqrtf(SQ(dx) + SQ(dz)); if (dxz < 350.0f) { this->bossGndInPainting = true; } if ((dxz < 300.0f) && !this->spawnedWarp) { this->spawnedWarp = true; Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_FHG_FIRE, this->inPaintingPos.x, this->actor.world.pos.y + 50.0f, this->inPaintingPos.z, 0, this->actor.shape.rot.y, 0, FHGFIRE_WARP_RETREAT); this->fhgFireKillWarp = true; } osSyncPrintf("SPD X %f\n", this->inPaintingVelX); osSyncPrintf("SPD Z %f\n", this->inPaintingVelZ); osSyncPrintf("X=%f\n", dx); osSyncPrintf("Z=%f\n", dz); if (dxz == 0.0f) { this->timers[0] = 140; this->actionFunc = EnfHG_Retreat; Animation_MorphToLoop(&this->skin.skelAnime, &gPhantomHorseRunningAnim, 0.0f); this->bossGndSignal = FHG_RIDE; } } } void EnfHG_Damage(EnfHG* this, GlobalContext* globalCtx) { f32 dx; f32 dz; f32 dxz2; osSyncPrintf("REVISE !!\n"); SkelAnime_Update(&this->skin.skelAnime); Math_ApproachF(&this->warpColorFilterR, globalCtx->lightCtx.fogColor[0], 1.0f, 10.0f); Math_ApproachF(&this->warpColorFilterG, globalCtx->lightCtx.fogColor[0], 1.0f, 10.0f); Math_ApproachF(&this->warpColorFilterB, globalCtx->lightCtx.fogColor[0], 1.0f, 10.0f); Math_ApproachF(&this->warpColorFilterUnk1, 0.0f, 1.0f, 5.0f); Math_ApproachF(&this->actor.scale.z, 0.011499999f, 1.0f, 0.002f); if (this->timers[0] != 0) { Math_ApproachZeroF(&this->damageSpeedMod, 1.0f, 0.1f); if (this->timers[0] == 1) { this->targetPainting = this->curPainting; this->inPaintingPos.x = (sPaintings[this->targetPainting].pos.x * 1.3f) + (GND_BOSSROOM_CENTER_X - 4.0f); this->inPaintingPos.y = sPaintings[this->targetPainting].pos.y; this->inPaintingPos.z = (sPaintings[this->targetPainting].pos.z * 1.3f) - -(GND_BOSSROOM_CENTER_Z - 10.0f); } } else { Math_ApproachF(&this->damageSpeedMod, 1.0f, 1.0f, 0.1f); } Math_ApproachF(&this->actor.world.pos.x, this->inPaintingPos.x, 1.0f, this->damageSpeedMod * this->inPaintingVelX); Math_ApproachF(&this->actor.world.pos.y, 60.0f, 0.1f, 1.0f); Math_ApproachF(&this->actor.world.pos.z, this->inPaintingPos.z, 1.0f, this->damageSpeedMod * this->inPaintingVelZ); dx = this->actor.world.pos.x - this->inPaintingPos.x; dz = this->actor.world.pos.z - this->inPaintingPos.z; dxz2 = sqrtf(SQ(dx) + SQ(dz)); if ((dxz2 < 300.0f) && (!this->spawnedWarp)) { this->spawnedWarp = true; Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_FHG_FIRE, this->inPaintingPos.x, this->actor.world.pos.y + 50.0f, this->inPaintingPos.z, 0, this->actor.shape.rot.y + 0x8000, 0, FHGFIRE_WARP_RETREAT); } if (dxz2 == 0.0f) { BossGanondrof* bossGnd = (BossGanondrof*)this->actor.parent; this->timers[0] = 140; this->actionFunc = EnfHG_Retreat; Animation_MorphToLoop(&this->skin.skelAnime, &gPhantomHorseRunningAnim, 0.0f); if (bossGnd->actor.colChkInfo.health > 24) { this->bossGndSignal = FHG_RIDE; } else { bossGnd->flyMode = GND_FLY_NEUTRAL; } this->turnTarget = -0x8000; } } void EnfHG_Retreat(EnfHG* this, GlobalContext* globalCtx) { osSyncPrintf("KABE IN !!\n"); if (this->turnTarget != 0) { Math_ApproachS(&this->turnRot, this->turnTarget, 5, 2000); } if (this->actor.params == GND_REAL_BOSS) { this->hoofSfxPos.x = this->actor.projectedPos.x / (this->actor.scale.x * 100.0f); this->hoofSfxPos.y = this->actor.projectedPos.y / (this->actor.scale.x * 100.0f); this->hoofSfxPos.z = this->actor.projectedPos.z / (this->actor.scale.x * 100.0f); if ((this->gallopTimer % 8) == 0) { func_80078914(&this->hoofSfxPos, NA_SE_EV_HORSE_RUN); } } SkelAnime_Update(&this->skin.skelAnime); Math_ApproachF(&this->actor.scale.z, 0.001f, 1.0f, 0.001f); Math_ApproachF(&this->actor.scale.x, 0.002f, 0.05f, 0.0001f); Math_ApproachF(&this->actor.world.pos.y, 200.0f, 0.05f, 1.0f); this->actor.scale.y = this->actor.scale.x; if ((this->timers[0] == 80) && (this->actor.params == GND_REAL_BOSS)) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_LAUGH); } if (this->timers[0] == 0) { BossGanondrof* bossGnd = (BossGanondrof*)this->actor.parent; s16 paintingIdxReal; s16 paintingIdxFake; if (this->actor.params != GND_REAL_BOSS) { this->killActor = true; bossGnd->killActor = true; } else if (bossGnd->flyMode != GND_FLY_PAINTING) { this->actionFunc = EnfHG_Done; this->actor.draw = NULL; } else { paintingIdxReal = Rand_ZeroOne() * 5.99f; EnfHG_SetupApproach(this, globalCtx, paintingIdxReal); do { paintingIdxFake = Rand_ZeroOne() * 5.99f; } while (paintingIdxFake == paintingIdxReal); osSyncPrintf("ac1 = %x `````````````````````````````````````````````````\n", Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_BOSS_GANONDROF, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, paintingIdxFake + GND_FAKE_BOSS)); } } } void EnfHG_Done(EnfHG* this, GlobalContext* globalCtx) { this->bossGndInPainting = false; } void EnfHG_Update(Actor* thisx, GlobalContext* globalCtx) { s32 pad; EnfHG* this = (EnfHG*)thisx; u8 i; if (this->killActor) { Actor_Kill(&this->actor); return; } this->gallopTimer++; this->bossGndInPainting = true; for (i = 0; i < 5; i++) { if (this->timers[i] != 0) { this->timers[i]--; } } this->actionFunc(this, globalCtx); if (this->hitTimer != 0) { this->hitTimer--; } this->actor.focus.pos = this->actor.world.pos; this->actor.focus.pos.y += 70.0f; this->actor.shape.rot.y = this->actor.world.rot.y; this->actor.shape.yOffset = Math_SinS(this->hitTimer * 0x9000) * 700.0f * (this->hitTimer / 20.0f); this->actor.shape.rot.z = (s16)(Math_SinS(this->hitTimer * 0x7000) * 1500.0f) * (this->hitTimer / 20.0f); } void EnfHG_PostDraw(Actor* thisx, GlobalContext* globalCtx, Skin* skin) { } void EnfHG_Draw(Actor* thisx, GlobalContext* globalCtx) { EnfHG* this = (EnfHG*)thisx; BossGanondrof* bossGnd = (BossGanondrof*)this->actor.parent; s32 pad; OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_fhg.c", 2439); func_80093D18(globalCtx->state.gfxCtx); POLY_OPA_DISP = ((bossGnd->work[GND_INVINC_TIMER] & 4) && (bossGnd->flyMode == GND_FLY_PAINTING)) ? Gfx_SetFog(POLY_OPA_DISP, 255, 50, 0, 0, 900, 1099) : Gfx_SetFog(POLY_OPA_DISP, (u32)this->warpColorFilterR, (u32)this->warpColorFilterG, (u32)this->warpColorFilterB, 0, (s32)this->warpColorFilterUnk1 + 995, (s32)this->warpColorFilterUnk2 + 1000); func_800A6330(&this->actor, globalCtx, &this->skin, EnfHG_PostDraw, SKIN_TRANSFORM_IS_FHG); POLY_OPA_DISP = Gameplay_SetFog(globalCtx, POLY_OPA_DISP); CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_fhg.c", 2480); }