Skip to content

Commit

Permalink
Merge branch 'develop' into waterfall-always-open
Browse files Browse the repository at this point in the history
  • Loading branch information
JordanLongstaff authored Nov 8, 2024
2 parents 5eedae0 + 4eeb019 commit 76cc904
Show file tree
Hide file tree
Showing 30 changed files with 1,136 additions and 649 deletions.
12 changes: 12 additions & 0 deletions soh/include/attributes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef ATTRIBUTES_H
#define ATTRIBUTES_H

#if !defined(__GNUC__) && !defined(__attribute__)
#define __attribute__(x)
#endif

#define UNUSED __attribute__((unused))
#define FALLTHROUGH __attribute__((fallthrough))
#define NORETURN __attribute__((noreturn))

#endif
8 changes: 4 additions & 4 deletions soh/include/functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -1536,9 +1536,9 @@ void KaleidoScopeCall_Init(PlayState* play);
void KaleidoScopeCall_Destroy(PlayState* play);
void KaleidoScopeCall_Update(PlayState* play);
void KaleidoScopeCall_Draw(PlayState* play);
void func_800BC490(PlayState* play, s16 point);
s32 func_800BC56C(PlayState* play, s16 arg1);
void func_800BC590(PlayState* play);
void Play_SetViewpoint(PlayState* play, s16 viewpoint);
s32 Play_CheckViewpoint(PlayState* play, s16 viewpoint);
void Play_SetShopBrowsingViewpoint(PlayState* play);
void Gameplay_SetupTransition(PlayState* play, s32 arg1);
Gfx* Play_SetFog(PlayState* play, Gfx* gfx);
void Play_Destroy(GameState* thisx);
Expand All @@ -1552,7 +1552,7 @@ u8 CheckLACSRewardCount();
s32 Play_InCsMode(PlayState* play);
f32 func_800BFCB8(PlayState* play, MtxF* mf, Vec3f* vec);
void* Play_LoadFile(PlayState* play, RomFile* file);
void Play_SpawnScene(PlayState* play, s32 sceneNum, s32 spawn);
void Play_SpawnScene(PlayState* play, s32 sceneId, s32 spawn);
void func_800C016C(PlayState* play, Vec3f* src, Vec3f* dest);
s16 Play_CreateSubCamera(PlayState* play);
s16 Play_GetActiveCamId(PlayState* play);
Expand Down
2 changes: 1 addition & 1 deletion soh/include/variables.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ extern "C"
extern KaleidoMgrOverlay gKaleidoMgrOverlayTable[KALEIDO_OVL_MAX];
extern KaleidoMgrOverlay* gKaleidoMgrCurOvl;
extern u8 gBossMarkState;
extern void* D_8012D1F0;
extern void* gDebugCutsceneScript;
extern s32 gScreenWidth;
extern s32 gScreenHeight;
extern Mtx gMtxClear;
Expand Down
1 change: 1 addition & 0 deletions soh/include/z64.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <libultraship/libultra.h>
#include "unk.h" // this used to get pulled in via ultra64.h
#include "attributes.h"
#include "z64save.h"
#include "z64light.h"
#include "z64bgcheck.h"
Expand Down
2 changes: 1 addition & 1 deletion soh/include/z64save.h
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ typedef enum {
/* 4 */ SCENE_LAYER_CUTSCENE_FIRST
} SceneLayer;

#define IS_CUTSCENE_LAYER (gSaveContext.sceneLayer >= SCENE_LAYER_CUTSCENE_FIRST)
#define IS_CUTSCENE_LAYER (gSaveContext.sceneSetupIndex >= SCENE_LAYER_CUTSCENE_FIRST)

typedef enum {
/* 0 */ LINK_AGE_ADULT,
Expand Down
51 changes: 35 additions & 16 deletions soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,43 @@
#include "soh/OTRGlobals.h"

extern "C" {
#include "macros.h"
#include "src/overlays/actors/ovl_En_Ko/z_en_ko.h"
#include "z64save.h"
#include "functions.h"
#include "variables.h"
#include "macros.h"
#include "src/overlays/actors/ovl_En_Ko/z_en_ko.h"
#include "z64save.h"
#include "functions.h"
#include "variables.h"
}

#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetSelectedOptionIndex()

static bool sEnteredBlueWarp = false;

/**
* This will override the transitions into the blue warp cutscenes, set any appropriate flags, and
* set the entrance index to where you would normally end up after the blue warp cutscene. This
* should also account for the difference between your first and following visits to the blue warp.
*/
void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_list originalArgs) {
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
uint8_t isBlueWarpCutscene = 0;
bool overrideBlueWarpDestinations =
IS_RANDO && (RAND_GET_OPTION(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF ||
RAND_GET_OPTION(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF);

// Force blue warp skip on when ER needs to place Link somewhere else.
// This is preferred over having story cutscenes play in the overworld and then reloading Link somewhere else after.
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO) || overrideBlueWarpDestinations) {
bool isBlueWarpCutscene = false;
// Deku Tree Blue warp
if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_0 && gSaveContext.cutsceneIndex == 0xFFF1) {
gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP;
isBlueWarpCutscene = 1;
isBlueWarpCutscene = true;
// Dodongo's Cavern Blue warp
} else if (gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT && gSaveContext.cutsceneIndex == 0xFFF1) {
gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP;
isBlueWarpCutscene = 1;
isBlueWarpCutscene = true;
// Jabu Jabu's Blue warp
} else if (gSaveContext.entranceIndex == ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP && gSaveContext.cutsceneIndex == 0xFFF0) {
gSaveContext.entranceIndex = ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP;
isBlueWarpCutscene = 1;
isBlueWarpCutscene = true;
// Forest Temple Blue warp
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_FOREST) {
// Normally set in the blue warp cutscene
Expand All @@ -43,30 +51,30 @@ void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_l
gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_12;
}

isBlueWarpCutscene = 1;
isBlueWarpCutscene = true;
// Fire Temple Blue warp
} else if (gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_FRONT_GATE && gSaveContext.cutsceneIndex == 0xFFF3) {
// Normally set in the blue warp cutscene
Flags_SetEventChkInf(EVENTCHKINF_DEATH_MOUNTAIN_ERUPTED);

gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP;
isBlueWarpCutscene = 1;
isBlueWarpCutscene = true;
// Water Temple Blue warp
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_WATER) {
// Normally set in the blue warp cutscene
gSaveContext.dayTime = gSaveContext.skyboxTime = 0x4800;
Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER);

gSaveContext.entranceIndex = ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP;
isBlueWarpCutscene = 1;
isBlueWarpCutscene = true;
// Spirit Temple Blue warp
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_SPIRIT) {
gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP;
isBlueWarpCutscene = 1;
isBlueWarpCutscene = true;
// Shadow Temple Blue warp
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_SHADOW) {
gSaveContext.entranceIndex = ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP;
isBlueWarpCutscene = 1;
isBlueWarpCutscene = true;
}

if (isBlueWarpCutscene) {
Expand All @@ -80,10 +88,20 @@ void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_l
}

// This is outside the above condition because we want to handle both first and following visits to the blue warp
if (IS_RANDO && (RAND_GET_OPTION(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF || RAND_GET_OPTION(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF)) {
if (sEnteredBlueWarp && overrideBlueWarpDestinations) {
Entrance_OverrideBlueWarp();
}
}

sEnteredBlueWarp = false;
}

/**
* Using this hook to simply observe that Link has entered a bluewarp
* This way we know to allow entrance rando overrides to be processed on the next tranisition hook
*/
void SkipBlueWarp_ShouldPlayBlueWarpCS(GIVanillaBehavior _, bool* should, va_list originalArgs) {
sEnteredBlueWarp = true;
}

/**
Expand Down Expand Up @@ -143,6 +161,7 @@ void SkipBlueWarp_ShouldDekuJrConsiderForestTempleFinished(GIVanillaBehavior _,
void SkipBlueWarp_Register() {
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnActorUpdate>(ACTOR_EN_KO, SkipBlueWarp_OnActorUpdate);
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_PLAY_TRANSITION_CS, SkipBlueWarp_ShouldPlayTransitionCS);
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_PLAY_BLUE_WARP_CS, SkipBlueWarp_ShouldPlayBlueWarpCS);
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_DEKU_JR_CONSIDER_FOREST_TEMPLE_FINISHED, SkipBlueWarp_ShouldDekuJrConsiderForestTempleFinished);
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_GIVE_ITEM_FROM_BLUE_WARP, SkipBlueWarp_ShouldGiveItem);
}
13 changes: 8 additions & 5 deletions soh/soh/Enhancements/debugger/colViewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <libultraship/bridge.h>
#include <libultraship/libultraship.h>
#include "soh/OTRGlobals.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"

extern "C" {
#include <z64.h>
Expand Down Expand Up @@ -276,11 +277,6 @@ void CreateSphereData() {
sphereGfx.push_back(gsSPEndDisplayList());
}

void ColViewerWindow::InitElement() {
CreateCylinderData();
CreateSphereData();
}

// Initializes the display list for a ColRenderSetting
void InitGfx(std::vector<Gfx>& gfx, ColRenderSetting setting) {
uint32_t rm;
Expand Down Expand Up @@ -689,3 +685,10 @@ extern "C" void DrawColViewer() {

CLOSE_DISPS(gPlayState->state.gfxCtx);
}

void ColViewerWindow::InitElement() {
CreateCylinderData();
CreateSphereData();

GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayDrawEnd>(DrawColViewer);
}
1 change: 1 addition & 0 deletions soh/soh/Enhancements/game-interactor/GameInteractor.h
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ typedef enum {
VB_SHOULD_GIVE_VANILLA_FISHING_PRIZE,
VB_GIVE_RANDO_FISHING_PRIZE,
VB_PLAY_THROW_ANIMATION,
VB_INFLICT_VOID_DAMAGE,

/*** Give Items ***/

Expand Down
100 changes: 41 additions & 59 deletions soh/soh/Enhancements/mods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,6 @@ static const ALIGN_ASSET(2) char tokinoma_room_0DL_007A70[] = dtokinoma_room_0DL
#define dtokinoma_room_0DL_007FD0 "__OTR__scenes/shared/tokinoma_scene/tokinoma_room_0DL_007FD0"
static const ALIGN_ASSET(2) char tokinoma_room_0DL_007FD0[] = dtokinoma_room_0DL_007FD0;

// TODO: When there's more uses of something like this, create a new GI::RawAction?
void ReloadSceneTogglingLinkAge() {
gPlayState->nextEntranceIndex = gSaveContext.entranceIndex;
gPlayState->transitionTrigger = TRANS_TRIGGER_START;
gPlayState->transitionType = TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_WHITE, TCS_FAST); // Fade Out
gSaveContext.nextTransitionType = TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_WHITE, TCS_FAST);
gPlayState->linkAgeOnLoad ^= 1; // toggle linkAgeOnLoad
}

void RegisterInfiniteMoney() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() {
if (!GameInteractor::IsSaveLoaded(true)) return;
Expand Down Expand Up @@ -219,51 +210,51 @@ void RegisterFreezeTime() {
}

/// Switches Link's age and respawns him at the last entrance he entered.
void RegisterSwitchAge() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() {
static bool warped = false;
void SwitchAge() {
if (gPlayState == NULL) return;

if (!GameInteractor::IsSaveLoaded(true)) {
CVarClear(CVAR_GENERAL("SwitchAge"));
warped = false;
return;
}
Player* player = GET_PLAYER(gPlayState);

static Vec3f playerPos;
static int16_t playerYaw;
static RoomContext* roomCtx;
static s32 roomNum;

if (CVarGetInteger(CVAR_GENERAL("SwitchAge"), 0) && !warped) {
playerPos = GET_PLAYER(gPlayState)->actor.world.pos;
playerYaw = GET_PLAYER(gPlayState)->actor.shape.rot.y;
roomCtx = &gPlayState->roomCtx;
roomNum = roomCtx->curRoom.num;
ReloadSceneTogglingLinkAge();
warped = true;
}
// Hyrule Castle: Very likely to fall through floor, so we force a specific entrance
if (gPlayState->sceneNum == SCENE_HYRULE_CASTLE || gPlayState->sceneNum == SCENE_OUTSIDE_GANONS_CASTLE) {
gPlayState->nextEntranceIndex = ENTR_CASTLE_GROUNDS_SOUTH_EXIT;
} else {
gSaveContext.respawnFlag = 1;
gPlayState->nextEntranceIndex = gSaveContext.entranceIndex;

if (warped && gPlayState->transitionTrigger != TRANS_TRIGGER_START &&
gSaveContext.nextTransitionType == TRANS_NEXT_TYPE_DEFAULT) {
GET_PLAYER(gPlayState)->actor.shape.rot.y = playerYaw;
GET_PLAYER(gPlayState)->actor.world.pos = playerPos;
if (roomNum != roomCtx->curRoom.num) {
func_8009728C(gPlayState, roomCtx, roomNum); //load original room
//func_800973FC(gPlayState, &gPlayState->roomCtx); // commit to room load?
func_80097534(gPlayState, roomCtx); // load map for new room (unloading the previous room)
}
warped = false;
CVarClear(CVAR_GENERAL("SwitchAge"));
// Preserve the player's position and orientation
gSaveContext.respawn[RESPAWN_MODE_DOWN].entranceIndex = gPlayState->nextEntranceIndex;
gSaveContext.respawn[RESPAWN_MODE_DOWN].roomIndex = gPlayState->roomCtx.curRoom.num;
gSaveContext.respawn[RESPAWN_MODE_DOWN].pos = player->actor.world.pos;
gSaveContext.respawn[RESPAWN_MODE_DOWN].yaw = player->actor.shape.rot.y;

if (gPlayState->roomCtx.curRoom.behaviorType2 < 4) {
gSaveContext.respawn[RESPAWN_MODE_DOWN].playerParams = 0x0DFF;
} else {
// Scenes with static backgrounds use a special camera we need to preserve
Camera* camera = GET_ACTIVE_CAM(gPlayState);
s16 camId = camera->camDataIdx;
gSaveContext.respawn[RESPAWN_MODE_DOWN].playerParams = 0x0D00 | camId;
}
}

gPlayState->transitionTrigger = TRANS_TRIGGER_START;
gPlayState->transitionType = TRANS_TYPE_INSTANT;
gSaveContext.nextTransitionType = TRANS_TYPE_FADE_BLACK_FAST;
gPlayState->linkAgeOnLoad ^= 1;

static HOOK_ID hookId = 0;
hookId = REGISTER_VB_SHOULD(VB_INFLICT_VOID_DAMAGE, {
*should = false;
GameInteractor::Instance->UnregisterGameHookForID<GameInteractor::OnVanillaBehavior>(hookId);
});
}

/// Switches Link's age and respawns him at the last entrance he entered.
void RegisterOcarinaTimeTravel() {

GameInteractor::Instance->RegisterGameHook<GameInteractor::OnOcarinaSongAction>([]() {
if (!GameInteractor::IsSaveLoaded(true)) {
CVarClear(CVAR_ENHANCEMENT("TimeTravel"));
if (!GameInteractor::IsSaveLoaded(true) || !CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0)) {
return;
}

Expand All @@ -273,22 +264,14 @@ void RegisterOcarinaTimeTravel() {
Actor* nearbyOcarinaSpot = Actor_FindNearby(gPlayState, player, ACTOR_EN_OKARINA_TAG, ACTORCAT_PROP, 120.0f);
Actor* nearbyDoorOfTime = Actor_FindNearby(gPlayState, player, ACTOR_DOOR_TOKI, ACTORCAT_BG, 500.0f);
Actor* nearbyFrogs = Actor_FindNearby(gPlayState, player, ACTOR_EN_FR, ACTORCAT_NPC, 300.0f);
uint8_t hasMasterSword = CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER);
uint8_t hasOcarinaOfTime = (INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME);
// If TimeTravel + Player have the Ocarina of Time + Have Master Sword + is in proper range
bool justPlayedSoT = gPlayState->msgCtx.lastPlayedSong == OCARINA_SONG_TIME;
bool notNearAnySource = !nearbyTimeBlockEmpty && !nearbyTimeBlock && !nearbyOcarinaSpot && !nearbyDoorOfTime && !nearbyFrogs;
bool hasOcarinaOfTime = (INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME);
bool doesntNeedOcarinaOfTime = CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 2;
bool hasMasterSword = CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER);
// TODO: Once Swordless Adult is fixed: Remove the Master Sword check
if (((CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 1 && hasOcarinaOfTime) || CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 2) && hasMasterSword &&
gPlayState->msgCtx.lastPlayedSong == OCARINA_SONG_TIME && !nearbyTimeBlockEmpty && !nearbyTimeBlock &&
!nearbyOcarinaSpot && !nearbyFrogs) {

if (IS_RANDO) {
CVarSetInteger(CVAR_GENERAL("SwitchTimeline"), 1);
} else if (!IS_RANDO && !nearbyDoorOfTime) {
// This check is made for when Link is learning the Song Of Time in a vanilla save file that load a
// Temple of Time scene where the only object present is the Door of Time
CVarSetInteger(CVAR_GENERAL("SwitchTimeline"), 1);
}
ReloadSceneTogglingLinkAge();
if (justPlayedSoT && notNearAnySource && (hasOcarinaOfTime || doesntNeedOcarinaOfTime) && hasMasterSword) {
SwitchAge();
}
});
}
Expand Down Expand Up @@ -1429,7 +1412,6 @@ void InitMods() {
RegisterEzQPA();
RegisterUnrestrictedItems();
RegisterFreezeTime();
RegisterSwitchAge();
RegisterOcarinaTimeTravel();
RegisterAutoSave();
RegisterDaytimeGoldSkultullas();
Expand Down
1 change: 1 addition & 0 deletions soh/soh/Enhancements/mods.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ void UpdateHyperEnemiesState();
void UpdateHyperBossesState();
void InitMods();
void UpdatePatchHand();
void SwitchAge();

#ifdef __cplusplus
}
Expand Down
2 changes: 1 addition & 1 deletion soh/soh/Enhancements/nametag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ extern "C" void NameTag_RegisterForActorWithOptions(Actor* actor, const char* te
processedText.erase(std::remove_if(processedText.begin(), processedText.end(), [](const char& c) {
// 172 is max supported texture for the in-game font system,
// and filter anything less than a space but not the newline or nul characters
return c > (s8)172 || (c < ' ' && c != '\n' && c != '\0');
return (unsigned char)c > 172 || (c < ' ' && c != '\n' && c != '\0');
}), processedText.end());

int16_t numChar = processedText.length();
Expand Down
2 changes: 0 additions & 2 deletions soh/soh/Enhancements/presets.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,8 +354,6 @@ const std::vector<const char*> cheatCvars = {
CVAR_DEVELOPER_TOOLS("SaveFileID"),
CVAR_CHEAT("EnableBetaQuest"),
CVAR_DEVELOPER_TOOLS("BetterDebugWarpScreen"),
CVAR_GENERAL("SwitchAge"),
CVAR_GENERAL("SwitchTimeline"),
CVAR_CHEAT("NoRedeadFreeze"),
CVAR_CHEAT("NoKeeseGuayTarget"),
CVAR_CHEAT("BombTimerMultiplier"),
Expand Down
Loading

0 comments on commit 76cc904

Please sign in to comment.