Adds Quick Boss Death checkbox and implements Phantom Ganon's quick death (#119)

* Adds Quick Boss Death checkbox and implements Phantom Ganon's quick death.

* Clarifies relocation comment.
This commit is contained in:
Christopher Leggett
2024-04-30 23:31:08 -04:00
committed by GitHub
parent 7e7445ebcc
commit baaa00569d
5 changed files with 80 additions and 56 deletions
@@ -12,19 +12,10 @@
#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
#include "soh/Enhancements/boss-rush/BossRush.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED)
typedef enum {
/* 0 */ NOT_DEAD,
/* 1 */ DEATH_START,
/* 2 */ DEATH_THROES,
/* 3 */ DEATH_WARP,
/* 4 */ DEATH_SCREAM,
/* 5 */ DEATH_DISINTEGRATE,
/* 6 */ DEATH_FINISH
} BossGanondrofDeathState;
typedef enum {
/* 0 */ THROW_NORMAL,
/* 1 */ THROW_SLOW
@@ -42,12 +33,6 @@ typedef enum {
/* 3 */ CHARGE_FINISH
} BossGanondrofChargeAction;
typedef enum {
/* 0 */ DEATH_SPASM,
/* 1 */ DEATH_LIMP,
/* 2 */ DEATH_HUNCHED
} BossGanondrofDeathAction;
void BossGanondrof_Init(Actor* thisx, PlayState* play);
void BossGanondrof_Destroy(Actor* thisx, PlayState* play);
void BossGanondrof_Update(Actor* thisx, PlayState* play);
@@ -959,26 +944,13 @@ void BossGanondrof_Death(BossGanondrof* this, PlayState* play) {
case DEATH_THROES:
switch (this->work[GND_ACTION_STATE]) {
case DEATH_SPASM:
if (Animation_OnFrame(&this->skelAnime, this->fwork[GND_END_FRAME]) && !IS_RANDO && !IS_BOSS_RUSH) {
this->fwork[GND_END_FRAME] = Animation_GetLastFrame(&gPhantomGanonAirDamageAnim);
Animation_Change(&this->skelAnime, &gPhantomGanonAirDamageAnim, 0.5f, 0.0f,
this->fwork[GND_END_FRAME], ANIMMODE_ONCE_INTERP, 0.0f);
this->work[GND_ACTION_STATE] = DEATH_LIMP;
} else if (IS_RANDO || IS_BOSS_RUSH) {
// Skip to death scream animation and move ganondrof to middle
this->deathState = DEATH_SCREAM;
this->timers[0] = 50;
Animation_MorphToLoop(&this->skelAnime, &gPhantomGanonScreamAnim, -10.0f);
this->actor.world.pos.x = GND_BOSSROOM_CENTER_X;
this->actor.world.pos.y = GND_BOSSROOM_CENTER_Y + 83.0f;
this->actor.world.pos.z = GND_BOSSROOM_CENTER_Z;
this->actor.shape.rot.y = 0;
this->work[GND_BODY_DECAY_INDEX] = 0;
Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_LAST);
// Move Player out of the center of the room
player->actor.world.pos.x = GND_BOSSROOM_CENTER_X - 200.0f;
player->actor.world.pos.z = GND_BOSSROOM_CENTER_Z;
if (GameInteractor_Should(GI_VB_PHANTOM_GANON_DEATH_SCENE, true, this)) {
if (Animation_OnFrame(&this->skelAnime, this->fwork[GND_END_FRAME])) {
this->fwork[GND_END_FRAME] = Animation_GetLastFrame(&gPhantomGanonAirDamageAnim);
Animation_Change(&this->skelAnime, &gPhantomGanonAirDamageAnim, 0.5f, 0.0f,
this->fwork[GND_END_FRAME], ANIMMODE_ONCE_INTERP, 0.0f);
this->work[GND_ACTION_STATE] = DEATH_LIMP;
}
}
break;
case DEATH_LIMP:
@@ -991,26 +963,25 @@ void BossGanondrof_Death(BossGanondrof* this, PlayState* play) {
bodyDecayLevel = 1;
break;
}
if (IS_RANDO || IS_BOSS_RUSH) {
break;
}
Math_ApproachS(&this->actor.shape.rot.y, this->work[GND_VARIANCE_TIMER] * -100, 5, 0xBB8);
Math_ApproachF(&this->cameraNextEye.z, this->targetPos.z + 60.0f, 0.02f, 0.5f);
Math_ApproachF(&this->actor.world.pos.y, GND_BOSSROOM_CENTER_Y + 133.0f, 0.05f, 100.0f);
this->actor.world.pos.y += Math_SinS(this->work[GND_VARIANCE_TIMER] * 1500);
this->cameraNextAt.x = this->targetPos.x;
this->cameraNextAt.y = this->targetPos.y - 10.0f;
this->cameraNextAt.z = this->targetPos.z;
if (this->timers[0] == 0) {
this->deathState = DEATH_WARP;
this->timers[0] = 350;
this->timers[1] = 50;
this->fwork[GND_CAMERA_ZOOM] = 300.0f;
this->cameraNextEye.y = GND_BOSSROOM_CENTER_Y + 233.0f;
player->actor.world.pos.x = GND_BOSSROOM_CENTER_X - 200.0f;
player->actor.world.pos.z = GND_BOSSROOM_CENTER_Z;
holdCamera = true;
bodyDecayLevel = 1;
if (GameInteractor_Should(GI_VB_PHANTOM_GANON_DEATH_SCENE, true, NULL)) {
Math_ApproachS(&this->actor.shape.rot.y, this->work[GND_VARIANCE_TIMER] * -100, 5, 0xBB8);
Math_ApproachF(&this->cameraNextEye.z, this->targetPos.z + 60.0f, 0.02f, 0.5f);
Math_ApproachF(&this->actor.world.pos.y, GND_BOSSROOM_CENTER_Y + 133.0f, 0.05f, 100.0f);
this->actor.world.pos.y += Math_SinS(this->work[GND_VARIANCE_TIMER] * 1500);
this->cameraNextAt.x = this->targetPos.x;
this->cameraNextAt.y = this->targetPos.y - 10.0f;
this->cameraNextAt.z = this->targetPos.z;
if (this->timers[0] == 0) {
this->deathState = DEATH_WARP;
this->timers[0] = 350;
this->timers[1] = 50;
this->fwork[GND_CAMERA_ZOOM] = 300.0f;
this->cameraNextEye.y = GND_BOSSROOM_CENTER_Y + 233.0f;
player->actor.world.pos.x = GND_BOSSROOM_CENTER_X - 200.0f;
player->actor.world.pos.z = GND_BOSSROOM_CENTER_Z;
holdCamera = true;
bodyDecayLevel = 1;
}
}
break;
case DEATH_WARP:
@@ -61,6 +61,23 @@ typedef enum {
/* 13 */ GND_FLOAT_COUNT = 13
} BossGanondrofF32Var;
// SOH [Enhancements] Relocated from z_boss_ganondrof.c to use in time saver.
typedef enum {
/* 0 */ NOT_DEAD,
/* 1 */ DEATH_START,
/* 2 */ DEATH_THROES,
/* 3 */ DEATH_WARP,
/* 4 */ DEATH_SCREAM,
/* 5 */ DEATH_DISINTEGRATE,
/* 6 */ DEATH_FINISH
} BossGanondrofDeathState;
typedef enum {
/* 0 */ DEATH_SPASM,
/* 1 */ DEATH_LIMP,
/* 2 */ DEATH_HUNCHED
} BossGanondrofDeathAction;
typedef struct BossGanondrof {
/* 0x0000 */ Actor actor;
/* 0x014C */ SkelAnime skelAnime;