mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-11-26 03:12:18 -05:00
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:
parent
7e7445ebcc
commit
baaa00569d
@ -376,6 +376,10 @@ typedef enum {
|
|||||||
/*** Fixes ***/
|
/*** Fixes ***/
|
||||||
// Vanilla condition: false
|
// Vanilla condition: false
|
||||||
GI_VB_FIX_SAW_SOFTLOCK,
|
GI_VB_FIX_SAW_SOFTLOCK,
|
||||||
|
|
||||||
|
/*** Quick Boss Deaths ***/
|
||||||
|
// Vanilla condition: true
|
||||||
|
GI_VB_PHANTOM_GANON_DEATH_SCENE,
|
||||||
} GIVanillaBehavior;
|
} GIVanillaBehavior;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -24,6 +24,8 @@ extern "C" {
|
|||||||
#include "src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h"
|
#include "src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h"
|
||||||
#include "src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.h"
|
#include "src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.h"
|
||||||
#include "src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h"
|
#include "src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h"
|
||||||
|
#include <overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.h>
|
||||||
|
#include <objects/object_gnd/object_gnd.h>
|
||||||
extern SaveContext gSaveContext;
|
extern SaveContext gSaveContext;
|
||||||
extern PlayState* gPlayState;
|
extern PlayState* gPlayState;
|
||||||
extern int32_t D_8011D3AC;
|
extern int32_t D_8011D3AC;
|
||||||
@ -719,6 +721,31 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void*
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case GI_VB_PHANTOM_GANON_DEATH_SCENE: {
|
||||||
|
if (CVarGetInteger("gTimeSavers.SkipCutscene.QuickBossDeaths", IS_RANDO || IS_BOSS_RUSH)) {
|
||||||
|
*should = false;
|
||||||
|
BossGanondrof* pg = static_cast<BossGanondrof*>(opt);
|
||||||
|
Player* player = GET_PLAYER(gPlayState);
|
||||||
|
if (pg != nullptr && pg->work[GND_ACTION_STATE] == DEATH_SPASM) {
|
||||||
|
// Skip to death scream animation and move ganondrof to middle
|
||||||
|
pg->deathState = DEATH_SCREAM;
|
||||||
|
pg->timers[0] = 50;
|
||||||
|
AnimationHeader* screamAnim = (AnimationHeader*)gPhantomGanonScreamAnim;
|
||||||
|
Animation_MorphToLoop(&pg->skelAnime, screamAnim, -10.0f);
|
||||||
|
pg->actor.world.pos.x = GND_BOSSROOM_CENTER_X;
|
||||||
|
pg->actor.world.pos.y = GND_BOSSROOM_CENTER_Y + 83.0f;
|
||||||
|
pg->actor.world.pos.z = GND_BOSSROOM_CENTER_Z;
|
||||||
|
pg->actor.shape.rot.y = 0;
|
||||||
|
pg->work[GND_BODY_DECAY_INDEX] = 0;
|
||||||
|
Audio_PlayActorSound2(&pg->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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,6 +581,7 @@ void DrawEnhancementsMenu() {
|
|||||||
CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO) &&
|
CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO) &&
|
||||||
CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) &&
|
CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) &&
|
||||||
CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO) &&
|
CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO) &&
|
||||||
|
CVarGetInteger("gTimeSavers.SkipCutscene.QuickBossDeaths", IS_RANDO) &&
|
||||||
CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", IS_RANDO) &&
|
CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", IS_RANDO) &&
|
||||||
CVarGetInteger("gTimeSavers.NoForcedDialog", IS_RANDO) &&
|
CVarGetInteger("gTimeSavers.NoForcedDialog", IS_RANDO) &&
|
||||||
CVarGetInteger("gTimeSavers.SkipOwlInteractions", IS_RANDO) &&
|
CVarGetInteger("gTimeSavers.SkipOwlInteractions", IS_RANDO) &&
|
||||||
@ -592,6 +593,7 @@ void DrawEnhancementsMenu() {
|
|||||||
CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO) ||
|
CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO) ||
|
||||||
CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) ||
|
CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) ||
|
||||||
CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO) ||
|
CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO) ||
|
||||||
|
CVarGetInteger("gTimeSavers.SkipCutscene.QuickBossDeaths", IS_RANDO) ||
|
||||||
CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", IS_RANDO) ||
|
CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", IS_RANDO) ||
|
||||||
CVarGetInteger("gTimeSavers.NoForcedDialog", IS_RANDO) ||
|
CVarGetInteger("gTimeSavers.NoForcedDialog", IS_RANDO) ||
|
||||||
CVarGetInteger("gTimeSavers.SkipOwlInteractions", IS_RANDO) ||
|
CVarGetInteger("gTimeSavers.SkipOwlInteractions", IS_RANDO) ||
|
||||||
@ -608,6 +610,7 @@ void DrawEnhancementsMenu() {
|
|||||||
CVarSetInteger("gTimeSavers.SkipCutscene.Story", 1);
|
CVarSetInteger("gTimeSavers.SkipCutscene.Story", 1);
|
||||||
CVarSetInteger("gTimeSavers.SkipCutscene.LearnSong", 1);
|
CVarSetInteger("gTimeSavers.SkipCutscene.LearnSong", 1);
|
||||||
CVarSetInteger("gTimeSavers.SkipCutscene.BossIntro", 1);
|
CVarSetInteger("gTimeSavers.SkipCutscene.BossIntro", 1);
|
||||||
|
CVarSetInteger("gTimeSavers.SkipCutscene.QuickBossDeaths", 1);
|
||||||
CVarSetInteger("gTimeSavers.SkipCutscene.OnePoint", 1);
|
CVarSetInteger("gTimeSavers.SkipCutscene.OnePoint", 1);
|
||||||
CVarSetInteger("gTimeSavers.NoForcedDialog", 1);
|
CVarSetInteger("gTimeSavers.NoForcedDialog", 1);
|
||||||
CVarSetInteger("gTimeSavers.SkipOwlInteractions", 1);
|
CVarSetInteger("gTimeSavers.SkipOwlInteractions", 1);
|
||||||
@ -619,6 +622,7 @@ void DrawEnhancementsMenu() {
|
|||||||
CVarSetInteger("gTimeSavers.SkipCutscene.Story", 0);
|
CVarSetInteger("gTimeSavers.SkipCutscene.Story", 0);
|
||||||
CVarSetInteger("gTimeSavers.SkipCutscene.LearnSong", 0);
|
CVarSetInteger("gTimeSavers.SkipCutscene.LearnSong", 0);
|
||||||
CVarSetInteger("gTimeSavers.SkipCutscene.BossIntro", 0);
|
CVarSetInteger("gTimeSavers.SkipCutscene.BossIntro", 0);
|
||||||
|
CVarSetInteger("gTimeSavers.SkipCutscene.QuickBossDeaths", 0);
|
||||||
CVarSetInteger("gTimeSavers.SkipCutscene.OnePoint", 0);
|
CVarSetInteger("gTimeSavers.SkipCutscene.OnePoint", 0);
|
||||||
CVarSetInteger("gTimeSavers.NoForcedDialog", 0);
|
CVarSetInteger("gTimeSavers.NoForcedDialog", 0);
|
||||||
CVarSetInteger("gTimeSavers.SkipOwlInteractions", 0);
|
CVarSetInteger("gTimeSavers.SkipOwlInteractions", 0);
|
||||||
@ -633,6 +637,7 @@ void DrawEnhancementsMenu() {
|
|||||||
UIWidgets::PaddedEnhancementCheckbox("Skip Story Cutscenes", "gTimeSavers.SkipCutscene.Story", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
|
UIWidgets::PaddedEnhancementCheckbox("Skip Story Cutscenes", "gTimeSavers.SkipCutscene.Story", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
|
||||||
UIWidgets::PaddedEnhancementCheckbox("Skip Song Cutscenes", "gTimeSavers.SkipCutscene.LearnSong", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
|
UIWidgets::PaddedEnhancementCheckbox("Skip Song Cutscenes", "gTimeSavers.SkipCutscene.LearnSong", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
|
||||||
UIWidgets::PaddedEnhancementCheckbox("Skip Boss Introductions", "gTimeSavers.SkipCutscene.BossIntro", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
|
UIWidgets::PaddedEnhancementCheckbox("Skip Boss Introductions", "gTimeSavers.SkipCutscene.BossIntro", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
|
||||||
|
UIWidgets::PaddedEnhancementCheckbox("Quick Boss Deaths", "gTimeSavers.SkipCutscene.QuickBossDeaths", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
|
||||||
UIWidgets::PaddedEnhancementCheckbox("Skip One Point Cutscenes (Chests, Door Unlocks, etc)", "gTimeSavers.SkipCutscene.OnePoint", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
|
UIWidgets::PaddedEnhancementCheckbox("Skip One Point Cutscenes (Chests, Door Unlocks, etc)", "gTimeSavers.SkipCutscene.OnePoint", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
|
||||||
UIWidgets::PaddedEnhancementCheckbox("No Forced Dialog", "gTimeSavers.NoForcedDialog", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
|
UIWidgets::PaddedEnhancementCheckbox("No Forced Dialog", "gTimeSavers.NoForcedDialog", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
|
||||||
UIWidgets::Tooltip("Prevent forced conversations with Navi or other NPCs");
|
UIWidgets::Tooltip("Prevent forced conversations with Navi or other NPCs");
|
||||||
|
@ -12,19 +12,10 @@
|
|||||||
#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h"
|
#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h"
|
||||||
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
|
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
|
||||||
#include "soh/Enhancements/boss-rush/BossRush.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)
|
#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 {
|
typedef enum {
|
||||||
/* 0 */ THROW_NORMAL,
|
/* 0 */ THROW_NORMAL,
|
||||||
/* 1 */ THROW_SLOW
|
/* 1 */ THROW_SLOW
|
||||||
@ -42,12 +33,6 @@ typedef enum {
|
|||||||
/* 3 */ CHARGE_FINISH
|
/* 3 */ CHARGE_FINISH
|
||||||
} BossGanondrofChargeAction;
|
} BossGanondrofChargeAction;
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
/* 0 */ DEATH_SPASM,
|
|
||||||
/* 1 */ DEATH_LIMP,
|
|
||||||
/* 2 */ DEATH_HUNCHED
|
|
||||||
} BossGanondrofDeathAction;
|
|
||||||
|
|
||||||
void BossGanondrof_Init(Actor* thisx, PlayState* play);
|
void BossGanondrof_Init(Actor* thisx, PlayState* play);
|
||||||
void BossGanondrof_Destroy(Actor* thisx, PlayState* play);
|
void BossGanondrof_Destroy(Actor* thisx, PlayState* play);
|
||||||
void BossGanondrof_Update(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:
|
case DEATH_THROES:
|
||||||
switch (this->work[GND_ACTION_STATE]) {
|
switch (this->work[GND_ACTION_STATE]) {
|
||||||
case DEATH_SPASM:
|
case DEATH_SPASM:
|
||||||
if (Animation_OnFrame(&this->skelAnime, this->fwork[GND_END_FRAME]) && !IS_RANDO && !IS_BOSS_RUSH) {
|
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);
|
this->fwork[GND_END_FRAME] = Animation_GetLastFrame(&gPhantomGanonAirDamageAnim);
|
||||||
Animation_Change(&this->skelAnime, &gPhantomGanonAirDamageAnim, 0.5f, 0.0f,
|
Animation_Change(&this->skelAnime, &gPhantomGanonAirDamageAnim, 0.5f, 0.0f,
|
||||||
this->fwork[GND_END_FRAME], ANIMMODE_ONCE_INTERP, 0.0f);
|
this->fwork[GND_END_FRAME], ANIMMODE_ONCE_INTERP, 0.0f);
|
||||||
this->work[GND_ACTION_STATE] = DEATH_LIMP;
|
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;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DEATH_LIMP:
|
case DEATH_LIMP:
|
||||||
@ -991,9 +963,7 @@ void BossGanondrof_Death(BossGanondrof* this, PlayState* play) {
|
|||||||
bodyDecayLevel = 1;
|
bodyDecayLevel = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (IS_RANDO || IS_BOSS_RUSH) {
|
if (GameInteractor_Should(GI_VB_PHANTOM_GANON_DEATH_SCENE, true, NULL)) {
|
||||||
break;
|
|
||||||
}
|
|
||||||
Math_ApproachS(&this->actor.shape.rot.y, this->work[GND_VARIANCE_TIMER] * -100, 5, 0xBB8);
|
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->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);
|
Math_ApproachF(&this->actor.world.pos.y, GND_BOSSROOM_CENTER_Y + 133.0f, 0.05f, 100.0f);
|
||||||
@ -1012,6 +982,7 @@ void BossGanondrof_Death(BossGanondrof* this, PlayState* play) {
|
|||||||
holdCamera = true;
|
holdCamera = true;
|
||||||
bodyDecayLevel = 1;
|
bodyDecayLevel = 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case DEATH_WARP:
|
case DEATH_WARP:
|
||||||
if (this->timers[1] == 1) {
|
if (this->timers[1] == 1) {
|
||||||
|
@ -61,6 +61,23 @@ typedef enum {
|
|||||||
/* 13 */ GND_FLOAT_COUNT = 13
|
/* 13 */ GND_FLOAT_COUNT = 13
|
||||||
} BossGanondrofF32Var;
|
} 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 {
|
typedef struct BossGanondrof {
|
||||||
/* 0x0000 */ Actor actor;
|
/* 0x0000 */ Actor actor;
|
||||||
/* 0x014C */ SkelAnime skelAnime;
|
/* 0x014C */ SkelAnime skelAnime;
|
||||||
|
Loading…
Reference in New Issue
Block a user