mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-10-22 11:30:21 -04:00
113 lines
4.5 KiB
C++
113 lines
4.5 KiB
C++
#include <libultraship/bridge/consolevariablebridge.h>
|
|
|
|
#include "soh/Enhancements/enhancementTypes.h"
|
|
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
|
#include "soh/ShipInit.hpp"
|
|
#include "soh/OTRGlobals.h"
|
|
#include "soh/Enhancements/BunnyHood.h"
|
|
|
|
extern "C" {
|
|
#include "z64.h"
|
|
#include "macros.h"
|
|
#include "variables.h"
|
|
extern PlayState* gPlayState;
|
|
extern void func_8083DF68(Player* player, f32 arg1, s16 arg2);
|
|
extern void func_8083DDC8(Player* player, PlayState* play);
|
|
}
|
|
|
|
#define CVAR_SPEED_MODIFIER_VALUE_NAME CVAR_CHEAT("SpeedModifier.Value")
|
|
#define CVAR_SPEED_MODIFIER_JUMP_TOGGLE CVAR_CHEAT("SpeedModifier.DoesntChangeJump")
|
|
|
|
static f32 GetSpeedModifierFactor(bool inputAvailable) {
|
|
f32 value = CVarGetFloat(CVAR_SPEED_MODIFIER_VALUE_NAME, 1.0f);
|
|
if (value == 1.0f) {
|
|
return 1.0f;
|
|
}
|
|
|
|
if (CVarGetInteger(CVAR_CHEAT("SpeedModifier.SpeedToggle"), 0)) {
|
|
return gWalkSpeedToggle ? value : 1.0f;
|
|
}
|
|
|
|
if (inputAvailable) {
|
|
s32 mod1Mask = CVarGetInteger(CVAR_CHEAT("SpeedModifier.Btn"), BTN_CUSTOM_MODIFIER1);
|
|
Input* input = &gPlayState->state.input[0];
|
|
if (mod1Mask != 0 && CHECK_BTN_ALL(input->cur.button, mod1Mask)) {
|
|
return value;
|
|
}
|
|
}
|
|
|
|
return 1.0f;
|
|
}
|
|
|
|
static f32 GetSpeedModifierJumpFactor() {
|
|
if (CVarGetInteger(CVAR_CHEAT("SpeedModifier.DoesntChangeJump"), 0)) {
|
|
return 1.0f;
|
|
}
|
|
return GetSpeedModifierFactor(true);
|
|
}
|
|
|
|
static bool ShouldAmplifyJump(Player* player) {
|
|
return Ship_GetBunnyHoodJumpFactor(player) != 1.0f || GetSpeedModifierJumpFactor() != 1.0f;
|
|
}
|
|
|
|
static void RegisterSpeedModifiers() {
|
|
bool speedModifierActive = CVarGetFloat(CVAR_SPEED_MODIFIER_VALUE_NAME, 1.0f) != 1.0f;
|
|
bool bunnyHoodActive = Ship_GetBunnyHoodMode() != BUNNY_HOOD_VANILLA;
|
|
bool jumpsClamped =
|
|
Ship_GetBunnyHoodMode() == BUNNY_HOOD_FAST || (CVarGetFloat(CVAR_SPEED_MODIFIER_VALUE_NAME, 1.0f) != 1.0f &&
|
|
CVarGetInteger(CVAR_SPEED_MODIFIER_JUMP_TOGGLE, 0) == 1);
|
|
|
|
static f32 lastRunSpeed = 0.0f;
|
|
|
|
// Airborne (jump) velocity. z_player clamps linearVelocity to the vanilla run speed limit when this returns true;
|
|
// skip that clamp so the amplified running velocity carries into the jump.
|
|
COND_VB_SHOULD(VB_PLAYER_LIMIT_JUMP_SPEED, speedModifierActive || bunnyHoodActive, {
|
|
Player* player = va_arg(args, Player*);
|
|
if (ShouldAmplifyJump(player)) {
|
|
f32 maxSpeed =
|
|
(R_RUN_SPEED_LIMIT / 100.0f) * Ship_GetBunnyHoodJumpFactor(player) * GetSpeedModifierJumpFactor();
|
|
player->linearVelocity = CLAMP(player->linearVelocity, -maxSpeed, maxSpeed);
|
|
*should = false;
|
|
}
|
|
});
|
|
|
|
// dive-into-water animation never clamped by vanilla, so re-clamp to vanilla run speed limit here unless jump be
|
|
// amplified. This keeps dive vanilla-distance (e.g. Gerudo Valley canyon) for bunny hood "fast run" & "Don't affect
|
|
// jump distance" option.
|
|
COND_VB_SHOULD(VB_PLAYER_LIMIT_DIVE_XZ_SPEED, jumpsClamped, {
|
|
Player* player = va_arg(args, Player*);
|
|
if (player->linearVelocity <= lastRunSpeed) {
|
|
f32 maxSpeed =
|
|
(R_RUN_SPEED_LIMIT / 100.0f) * Ship_GetBunnyHoodJumpFactor(player) * GetSpeedModifierJumpFactor();
|
|
player->linearVelocity = CLAMP(player->linearVelocity, -maxSpeed, maxSpeed);
|
|
}
|
|
});
|
|
|
|
// Ground run speed target, multiplied in place.
|
|
COND_VB_SHOULD(VB_PLAYER_MODIFY_RUN_SPEED, speedModifierActive || bunnyHoodActive, {
|
|
Player* player = va_arg(args, Player*);
|
|
f32* speedTarget = va_arg(args, f32*);
|
|
s16* yawTarget = va_arg(args, s16*);
|
|
|
|
*speedTarget *= Ship_GetBunnyHoodRunFactor(player) * GetSpeedModifierFactor(true);
|
|
|
|
func_8083DF68(player, *speedTarget, *yawTarget);
|
|
func_8083DDC8(player, gPlayState);
|
|
|
|
lastRunSpeed = player->linearVelocity;
|
|
|
|
*should = false;
|
|
});
|
|
|
|
// Swim speed multiplied in place. Called per speed z_player scales; bunny hood does not apply underwater.
|
|
COND_VB_SHOULD(VB_PLAYER_MODIFY_SWIM_SPEED, speedModifierActive, {
|
|
[[maybe_unused]] Player* player = va_arg(args, Player*);
|
|
f32* value = va_arg(args, f32*);
|
|
bool inputAvailable = va_arg(args, int) != 0;
|
|
*value *= GetSpeedModifierFactor(inputAvailable);
|
|
});
|
|
}
|
|
|
|
static RegisterShipInitFunc initFunc(RegisterSpeedModifiers, { "IS_RANDO", CVAR_SPEED_MODIFIER_VALUE_NAME,
|
|
CVAR_BUNNY_HOOD_NAME, CVAR_SPEED_MODIFIER_JUMP_TOGGLE });
|