Fix issues with faster heavy block lift (#4335)

This commit is contained in:
Garrett Cox 2024-09-19 11:15:31 -05:00 committed by GitHub
parent da6e4cac91
commit ee02e503fc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 89 additions and 32 deletions

View File

@ -0,0 +1,58 @@
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/OTRGlobals.h"
#include "spdlog/spdlog.h"
extern "C" {
#include "z64save.h"
#include "macros.h"
#include "variables.h"
#include "functions.h"
extern PlayState* gPlayState;
extern SaveContext gSaveContext;
}
/**
* This primarily handles speeding up the heavy block lifts (OGC and in the Fire Trial) but also handles skipping
* the one point cutscene since the two options are so similar in what they do.
*/
void FasterHeavyBlockLift_Register() {
REGISTER_VB_SHOULD(VB_PLAY_ONEPOINT_ACTOR_CS, {
Actor* actor = static_cast<Actor*>(opt);
if (
actor->id == ACTOR_BG_HEAVY_BLOCK &&
(CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0) || CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO))
) {
*should = false;
}
});
REGISTER_VB_SHOULD(VB_FREEZE_LINK_FOR_BLOCK_THROW, {
if (CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0) || CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO)) {
*should = false;
}
});
REGISTER_VB_SHOULD(VB_PLAY_THROW_ANIMATION, {
Player *player = GET_PLAYER(gPlayState);
Actor* interactRangeActor = player->interactRangeActor;
s32 interactActorId = interactRangeActor->id;
LinkAnimationHeader* anim = static_cast<LinkAnimationHeader*>(opt);
// Same actor is used for small and large silver rocks, use actor params to identify large ones
bool isLargeSilverRock = interactActorId == ACTOR_EN_ISHI && interactRangeActor->params & 1 == 1;
if (CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0) && (isLargeSilverRock || interactActorId == ACTOR_BG_HEAVY_BLOCK)) {
*should = false;
LinkAnimation_PlayOnceSetSpeed(gPlayState, &player->skelAnime, anim, 5.0f);
}
});
REGISTER_VB_SHOULD(VB_MOVE_THROWN_ACTOR, {
if (CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0)) {
Actor* heldActor = static_cast<Actor*>(opt);
heldActor->shape.rot.x -= 3510;
}
});
}

View File

@ -11,4 +11,5 @@ void TimeSavers_Register() {
SkipIntro_Register();
// SkipMiscInteractions
MoveMidoInKokiriForest_Register();
FasterHeavyBlockLift_Register();
}

View File

@ -13,5 +13,6 @@ void TimeSavers_Register();
void SkipIntro_Register();
// SkipMiscInteractions
void MoveMidoInKokiriForest_Register();
void FasterHeavyBlockLift_Register();
#endif // TIME_SAVERS_H

View File

@ -244,6 +244,8 @@ typedef enum {
```
*/
VB_DRAW_AMMO_COUNT,
VB_FREEZE_LINK_FOR_BLOCK_THROW,
VB_MOVE_THROWN_ACTOR,
/*** Play Cutscenes ***/
@ -286,6 +288,7 @@ typedef enum {
VB_PLAY_RAINBOW_BRIDGE_CS,
// Opt: *EnBox
VB_PLAY_SLOW_CHEST_CS,
VB_PLAY_THROW_ANIMATION,
/*** Give Items ***/

View File

@ -223,6 +223,10 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void*
if (actor->id == ACTOR_BG_MORI_HINERI) {
break;
}
// This is handled in the FasterHeavyBlockLift enhancement
if (actor->id == ACTOR_BG_HEAVY_BLOCK) {
break;
}
RateLimitedSuccessChime();
*should = false;

View File

@ -7,6 +7,7 @@
#include "z_bg_heavy_block.h"
#include "objects/object_heavy_object/object_heavy_object.h"
#include "vt.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS 0
@ -320,7 +321,6 @@ void BgHeavyBlock_Wait(BgHeavyBlock* this, PlayState* play) {
if (Actor_HasParent(&this->dyna.actor, play)) {
this->timer = 0;
if (!CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0)) {
switch (this->dyna.actor.params & 0xFF) {
case HEAVYBLOCK_BREAKABLE:
OnePointCutscene_Init(play, 4020, 270, &this->dyna.actor, MAIN_CAM);
@ -332,7 +332,6 @@ void BgHeavyBlock_Wait(BgHeavyBlock* this, PlayState* play) {
OnePointCutscene_Init(play, 4022, 210, &this->dyna.actor, MAIN_CAM);
break;
}
}
quakeIndex = Quake_Add(GET_ACTIVE_CAM(play), 3);
Quake_SetSpeed(quakeIndex, 25000);
@ -369,7 +368,7 @@ void BgHeavyBlock_LiftedUp(BgHeavyBlock* this, PlayState* play) {
this->timer++;
if (!CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0)) {
if (GameInteractor_Should(VB_FREEZE_LINK_FOR_BLOCK_THROW, true, this)) {
Player_SetCsActionWithHaltedActors(play, &player->actor, 8);
}
@ -408,13 +407,10 @@ void BgHeavyBlock_Fly(BgHeavyBlock* this, PlayState* play) {
Quake_SetQuakeValues(quakeIndex, 14, 2, 100, 0);
Quake_SetCountdown(quakeIndex, 30);
// We don't want this arbitrarily long quake with the enhancement enabled
if (!CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0)) {
quakeIndex = Quake_Add(GET_ACTIVE_CAM(play), 2);
Quake_SetSpeed(quakeIndex, 12000);
Quake_SetQuakeValues(quakeIndex, 5, 0, 0, 0);
Quake_SetCountdown(quakeIndex, 999);
}
SoundSource_PlaySfxAtFixedWorldPos(play, &this->dyna.actor.world.pos, 30,
NA_SE_EV_ELECTRIC_EXPLOSION);

View File

@ -5096,11 +5096,7 @@ void func_8083A0F4(PlayState* play, Player* this) {
anim = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_carryB, this->modelAnimType);
}
// Same actor is used for small and large silver rocks, use actor params to identify large ones
bool isLargeSilverRock = interactActorId == ACTOR_EN_ISHI && interactRangeActor->params & 1 == 1;
if (CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0) && (isLargeSilverRock || interactActorId == ACTOR_BG_HEAVY_BLOCK)) {
LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, anim, 5.0f);
} else {
if (GameInteractor_Should(VB_PLAY_THROW_ANIMATION, true, anim)) {
LinkAnimation_PlayOnce(play, &this->skelAnime, anim);
}
}
@ -9842,14 +9838,12 @@ void Player_Action_80846120(Player* this, PlayState* play) {
if (LinkAnimation_OnFrame(&this->skelAnime, 229.0f)) {
Actor* heldActor = this->heldActor;
if (CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0)) {
// This is the difference in rotation when the animation is sped up 5x
heldActor->shape.rot.x -= 3510;
}
if (GameInteractor_Should(VB_MOVE_THROWN_ACTOR, true, heldActor)) {
heldActor->speedXZ = Math_SinS(heldActor->shape.rot.x) * 40.0f;
heldActor->velocity.y = Math_CosS(heldActor->shape.rot.x) * 40.0f;
heldActor->gravity = -2.0f;
heldActor->minVelocityY = -30.0f;
}
Player_DetachHeldActor(play, this);
return;
}