Merge branch 'develop' into SplitGF

This commit is contained in:
Pepper0ni 2025-05-15 20:05:27 +01:00
commit 9b82f62f44
47 changed files with 354 additions and 181 deletions

View file

@ -1044,6 +1044,7 @@ VecSph* OLib_Vec3fToVecSph(VecSph* dest, Vec3f* vec);
VecSph* OLib_Vec3fToVecSphGeo(VecSph* arg0, Vec3f* arg1);
VecSph* OLib_Vec3fDiffToVecSphGeo(VecSph* arg0, Vec3f* a, Vec3f* b);
Vec3f* OLib_Vec3fDiffRad(Vec3f* dest, Vec3f* a, Vec3f* b);
void OnePointCutscene_SetCsCamPoints(Camera* camera, s16 actionParameters, s16 initTimer, CutsceneCameraPoint* atPoints, CutsceneCameraPoint* eyePoints);
s16 OnePointCutscene_Init(PlayState* play, s16 csId, s16 timer, Actor* actor, s16 camIdx);
s16 OnePointCutscene_EndCutscene(PlayState* play, s16 camIdx);
s32 OnePointCutscene_Attention(PlayState* play, Actor* actor);
@ -1102,6 +1103,7 @@ void FrameAdvance_Init(FrameAdvanceContext* frameAdvCtx);
s32 FrameAdvance_Update(FrameAdvanceContext* frameAdvCtx, Input* input);
u8 PlayerGrounded(Player* player);
void Player_SetBootData(PlayState* play, Player* player);
void Player_StartAnimMovement(PlayState* play, Player* player, s32 flags);
s32 Player_InBlockingCsMode(PlayState* play, Player* player);
s32 Player_TryCsAction(PlayState* play, Actor* actor, s32 csAction);
s32 Player_InCsMode(PlayState* play);

View file

@ -61,8 +61,8 @@ std::vector<AltTrapType> getEnabledAddTraps() {
};
static void RollRandomTrap(uint32_t seed) {
uint32_t finalSeed =
seed + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() : gSaveContext.ship.stats.fileCreatedAt);
uint32_t finalSeed = seed + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed()
: static_cast<uint32_t>(gSaveContext.ship.stats.fileCreatedAt));
Random_Init(finalSeed);
roll = RandomElement(getEnabledAddTraps());
@ -126,12 +126,12 @@ static void OnPlayerUpdate() {
Play_TriggerRespawn(gPlayState);
break;
case ADD_AMMO_TRAP:
AMMO(ITEM_STICK) = AMMO(ITEM_STICK) * 0.5;
AMMO(ITEM_NUT) = AMMO(ITEM_NUT) * 0.5;
AMMO(ITEM_SLINGSHOT) = AMMO(ITEM_SLINGSHOT) * 0.5;
AMMO(ITEM_BOW) = AMMO(ITEM_BOW) * 0.5;
AMMO(ITEM_BOMB) = AMMO(ITEM_BOMB) * 0.5;
AMMO(ITEM_BOMBCHU) = AMMO(ITEM_BOMBCHU) * 0.5;
AMMO(ITEM_STICK) = static_cast<int8_t>(floor(AMMO(ITEM_STICK) * 0.5f));
AMMO(ITEM_NUT) = static_cast<int8_t>(floor(AMMO(ITEM_NUT) * 0.5f));
AMMO(ITEM_SLINGSHOT) = static_cast<int8_t>(floor(AMMO(ITEM_SLINGSHOT) * 0.5f));
AMMO(ITEM_BOW) = static_cast<int8_t>(floor(AMMO(ITEM_BOW) * 0.5f));
AMMO(ITEM_BOMB) = static_cast<int8_t>(floor(AMMO(ITEM_BOMB) * 0.5f));
AMMO(ITEM_BOMBCHU) = static_cast<int8_t>(floor(AMMO(ITEM_BOMBCHU) * 0.5f));
Audio_PlaySoundGeneral(NA_SE_VO_FR_SMILE_0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
break;

View file

@ -0,0 +1,110 @@
#include <libultraship/bridge.h>
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
#include "global.h"
extern "C" {
#include "functions.h"
#include "objects/gameplay_keep/gameplay_keep.h"
extern PlayState* gPlayState;
}
#define CVAR_CRAWL_SPEED_NAME CVAR_ENHANCEMENT("CrawlSpeed")
#define CVAR_CRAWL_SPEED_DEFAULT 1
#define CVAR_CRAWL_SPEED_VALUE CVarGetInteger(CVAR_CRAWL_SPEED_NAME, CVAR_CRAWL_SPEED_DEFAULT)
#define CVAR_GLITCH_AIDING_NAME CVAR_ENHANCEMENT("GlitchAidingCrawlspaces")
#define CVAR_GLITCH_AIDING_DEFAULT 0
#define CVAR_GLITCH_AIDING_VALUE CVarGetInteger(CVAR_GLITCH_AIDING_NAME, CVAR_GLITCH_AIDING_DEFAULT)
extern "C" void ExitCrawlspace(Player* player, PlayState* play) {
LinkAnimationHeader* animExit = (LinkAnimationHeader*)gPlayerAnim_link_child_tunnel_end;
LinkAnimationHeader* animEnter = (LinkAnimationHeader*)gPlayerAnim_link_child_tunnel_start;
if (player->linearVelocity > 0.0f) {
// Leaving a crawlspace forwards
player->actor.shape.rot.y = player->actor.wallYaw + 0x8000;
LinkAnimation_Change(play, &player->skelAnime, animExit, ((CVAR_CRAWL_SPEED_VALUE + 1.0f) / 2.0f), 0.0f,
Animation_GetLastFrame(animExit), ANIMMODE_ONCE, 0.0f);
Player_StartAnimMovement(play, player, 0x9D);
OnePointCutscene_Init(play, 9601, 999, NULL, MAIN_CAM);
} else {
// Leaving a crawlspace backwards
player->actor.shape.rot.y = player->actor.wallYaw;
LinkAnimation_Change(play, &player->skelAnime, animEnter, -1.0f * ((CVAR_CRAWL_SPEED_VALUE + 1.0f) / 2.0f),
Animation_GetLastFrame(animEnter), 0.0f, ANIMMODE_ONCE, 0.0f);
Player_StartAnimMovement(play, player, 0x9D);
OnePointCutscene_Init(play, 9602, 999, NULL, MAIN_CAM);
}
}
extern "C" void ExitCrawlspaceCS(PlayState* play, Camera* csCam, int16_t actionParameters, int16_t initTimer,
CutsceneCameraPoint* atPoints, CutsceneCameraPoint* eyePoints) {
s16 camCrawlTemp = CVAR_CRAWL_SPEED_VALUE;
s16 camCrawlTimer = initTimer / camCrawlTemp;
OnePointCutscene_SetCsCamPoints(csCam, actionParameters | 0x1000, camCrawlTimer, atPoints, eyePoints);
}
extern "C" void EnterCrawlspace(Player* player, PlayState* play) {
LinkAnimationHeader* anim = (LinkAnimationHeader*)gPlayerAnim_link_child_tunnel_start;
LinkAnimation_Change(play, &player->skelAnime, anim, ((CVAR_CRAWL_SPEED_VALUE + 1.0f) / 2.0f), 0.0f,
Animation_GetLastFrame(anim), ANIMMODE_ONCE, 0.0f);
}
extern "C" void IncreaseCrawlSpeed(Player* player, PlayState* play) {
Input* sControlInput = &play->state.input[0];
player->linearVelocity = sControlInput->rel.stick_y * 0.03f * CVAR_CRAWL_SPEED_VALUE;
}
void CrawlSpeed_Register() {
bool shouldRegister = CVAR_CRAWL_SPEED_VALUE > 1;
COND_VB_SHOULD(VB_CRAWL_SPEED_EXIT, shouldRegister, {
Player* player = GET_PLAYER(gPlayState);
bool excludeWellBackroom = (player->actor.world.pos.x > 950.0f) && (player->actor.world.pos.x < 1025.0f) &&
(player->actor.world.pos.z > -1510.0f) && (player->actor.world.pos.z < -1490.0f) &&
gPlayState->sceneNum == SCENE_BOTTOM_OF_THE_WELL;
bool excludeGlitchAiding = CVAR_GLITCH_AIDING_VALUE;
if (excludeGlitchAiding && excludeWellBackroom) {
*should = true;
} else {
ExitCrawlspace(player, gPlayState);
*should = false;
}
});
COND_VB_SHOULD(VB_CRAWL_SPEED_EXIT_CS, shouldRegister, {
Player* player = GET_PLAYER(gPlayState);
Camera* csCam = va_arg(args, Camera*);
s16 csId = va_arg(args, s16);
s16 actionParameters = va_arg(args, s16);
s16 initTimer = va_arg(args, s16);
CutsceneCameraPoint* atPoints = va_arg(args, CutsceneCameraPoint*);
CutsceneCameraPoint* eyePoints = va_arg(args, CutsceneCameraPoint*);
bool excludeWellBackroom = (player->actor.world.pos.x > 950.0f) && (player->actor.world.pos.x < 1025.0f) &&
(player->actor.world.pos.z > -1510.0f) && (player->actor.world.pos.z < -1490.0f) &&
gPlayState->sceneNum == SCENE_BOTTOM_OF_THE_WELL;
bool excludeGlitchAiding = CVAR_GLITCH_AIDING_VALUE;
if (excludeGlitchAiding && excludeWellBackroom) {
*should = true;
} else {
ExitCrawlspaceCS(gPlayState, csCam, actionParameters, initTimer, atPoints, eyePoints);
*should = false;
}
});
COND_VB_SHOULD(VB_CRAWL_SPEED_ENTER, shouldRegister, {
Player* player = GET_PLAYER(gPlayState);
EnterCrawlspace(player, gPlayState);
*should = false;
});
COND_VB_SHOULD(VB_CRAWL_SPEED_INCREASE, shouldRegister, {
Player* player = GET_PLAYER(gPlayState);
IncreaseCrawlSpeed(player, gPlayState);
*should = false;
});
}
static RegisterShipInitFunc initSpeed(CrawlSpeed_Register, { CVAR_CRAWL_SPEED_NAME });

View file

@ -0,0 +1,13 @@
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/ShipInit.hpp"
extern "C" {
#include "z64save.h"
}
void RegisterFasterBeanSkulltula() {
COND_VB_SHOULD(VB_SPAWN_BEAN_SKULLTULA, CVarGetInteger(CVAR_ENHANCEMENT("FasterBeanSkull"), 0),
{ *should = true; });
}
static RegisterShipInitFunc initFunc(RegisterFasterBeanSkulltula, { CVAR_ENHANCEMENT("FasterBeanSkull") });

View file

@ -0,0 +1,19 @@
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/ShipInit.hpp"
extern "C" {
#include "z64save.h"
}
void RegisterFasterEmptyBottle() {
COND_VB_SHOULD(VB_EMPTYING_BOTTLE, CVarGetInteger(CVAR_ENHANCEMENT("FasterBottleEmpty"), 0), {
Player* player = va_arg(args, Player*);
if (player->skelAnime.curFrame <= 60.0f) {
player->skelAnime.playSpeed = 3.0f;
} else {
player->skelAnime.playSpeed = 1.0f;
}
});
}
static RegisterShipInitFunc initFunc(RegisterFasterEmptyBottle, { CVAR_ENHANCEMENT("FasterBottleEmpty") });

View file

@ -111,7 +111,7 @@ const char* BossRush_GetSettingChoiceName(u8 optionIndex, u8 choiceIndex, u8 lan
}
u8 BossRush_GetSettingOptionsAmount(u8 optionIndex) {
return BossRushOptions[optionIndex].choices.size();
return static_cast<u8>(BossRushOptions[optionIndex].choices.size());
}
void BossRush_SpawnBlueWarps(PlayState* play) {
@ -311,7 +311,8 @@ void BossRush_HandleCompleteBoss(PlayState* play) {
play->sceneNum == SCENE_GANON_BOSS) {
gSaveContext.ship.stats.playTimer += 2;
gSaveContext.ship.stats.gameComplete = 1;
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_BOSSRUSH_FINISH] = GAMEPLAYSTAT_TOTAL_TIME;
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_BOSSRUSH_FINISH] =
static_cast<uint32_t>(GAMEPLAYSTAT_TOTAL_TIME);
}
}

View file

@ -345,7 +345,7 @@ void InputViewer::DrawElement() {
// Analog Stick
const int analogOutlineMode =
CVarGetInteger(CVAR_INPUT_VIEWER("AnalogStick.OutlineMode"), STICK_MODE_ALWAYS_SHOWN);
const float maxStickDistance = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogStick.Movement"), 12);
const int32_t maxStickDistance = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogStick.Movement"), 12);
if (analogOutlineMode == STICK_MODE_ALWAYS_SHOWN ||
(analogOutlineMode == STICK_MODE_HIDDEN_IN_DEADZONE && !analogStickIsInDeadzone)) {
ImGui::SetNextItemAllowOverlap();
@ -367,7 +367,7 @@ void InputViewer::DrawElement() {
}
// Right Stick
const float maxRightStickDistance = CVarGetInteger(CVAR_INPUT_VIEWER("RightStick.Movement"), 7);
const int32_t maxRightStickDistance = CVarGetInteger(CVAR_INPUT_VIEWER("RightStick.Movement"), 7);
const int rightOutlineMode =
CVarGetInteger(CVAR_INPUT_VIEWER("RightStick.OutlineMode"), STICK_MODE_ALWAYS_HIDDEN);
if (rightOutlineMode == STICK_MODE_ALWAYS_SHOWN ||
@ -401,7 +401,7 @@ void InputViewer::DrawElement() {
ImGui::PushFont(ImGui::GetFont());
// Calculate polar R coordinate from X and Y angles, squared to avoid sqrt
const float rSquared = pads[0].stick_x * pads[0].stick_x + pads[0].stick_y * pads[0].stick_y;
const int32_t rSquared = pads[0].stick_x * pads[0].stick_x + pads[0].stick_y * pads[0].stick_y;
// ESS range
const int range1Min = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Min"), 8);

View file

@ -50,8 +50,8 @@ void Mouse_HandleFirstPerson(Player* player) {
: 1;
s8 invertYAxisMulti = CVarGetInteger(CVAR_SETTING("Controls.InvertAimingYAxis"), 1) ? 1 : -1;
if (MOUSE_ENABLED) {
player->actor.focus.rot.y -= mouseCoordRel.x * 6.0f * xAxisMulti * invertXAxisMulti;
player->actor.focus.rot.x += mouseCoordRel.y * 6.0f * yAxisMulti * invertYAxisMulti;
player->actor.focus.rot.y -= static_cast<int16_t>(mouseCoordRel.x * 6.0f * xAxisMulti * invertXAxisMulti);
player->actor.focus.rot.x += static_cast<int16_t>(mouseCoordRel.y * 6.0f * yAxisMulti * invertYAxisMulti);
}
}
@ -59,7 +59,7 @@ void Mouse_RecenterCursor() {
u32 width = GetWindow()->GetWidth();
u32 height = GetWindow()->GetHeight();
if (MOUSE_ENABLED) {
GetWindow()->SetMousePos({ (s32)(width / 2), (s32)(height / 2) });
GetWindow()->SetMousePos({ static_cast<s32>(width / 2), static_cast<s32>(height / 2) });
}
}
@ -67,8 +67,8 @@ void Mouse_HandleShield(f32* sp50, f32* sp54) {
if (MOUSE_ENABLED) {
s32 width = GetWindow()->GetWidth();
s32 height = GetWindow()->GetHeight();
f32 xBound = 7200 / ((f32)width / 2);
f32 yBound = 6000 / ((f32)height / 2);
f32 xBound = 7200 / (width / 2.0f);
f32 yBound = 6000 / (height / 2.0f);
*sp50 +=
(mouseCoord.x - (width / 2)) * xBound * (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? 1 : -1);
*sp54 += (mouseCoord.y - (height / 2)) * yBound;
@ -78,8 +78,8 @@ void Mouse_HandleShield(f32* sp50, f32* sp54) {
}
static s8 iterMouse = 0;
static f32 mouseQuickspinX[5] = {};
static f32 mouseQuickspinY[5] = {};
static s32 mouseQuickspinX[5] = {};
static s32 mouseQuickspinY[5] = {};
static u8 quickspinCount = 0;
void Mouse_UpdateQuickspinCount() {
@ -102,9 +102,9 @@ bool Mouse_HandleQuickspin(bool* should, s8* iter2, s8* sp3C) {
for (i = 0; i < 4; i++, iter2++) {
// Calculating angles as per z_lib.c:func_80077D10()
f32 relY = mouseQuickspinY[i + 1] - mouseQuickspinY[i];
f32 relX = mouseQuickspinX[i + 1] - mouseQuickspinX[i];
s16 aTan = Math_Atan2S(relY, -relX);
s32 relY = mouseQuickspinY[i + 1] - mouseQuickspinY[i];
s32 relX = mouseQuickspinX[i + 1] - mouseQuickspinX[i];
s16 aTan = Math_Atan2S((f32)relY, (f32)-relX);
iterMouse = (u16)(aTan + 0x2000) >> 9; // See z_player.c:Player_ProcessControlStick()
if ((*iter2 = iterMouse) < 0) {
return *should = false;

View file

@ -112,7 +112,7 @@ void GameInteractor::RawAction::FreezePlayer() {
void GameInteractor::RawAction::BurnPlayer() {
Player* player = GET_PLAYER(gPlayState);
for (int i = 0; i < 18; i++) {
player->bodyFlameTimers[i] = Rand_S16Offset(0, 200);
player->bodyFlameTimers[i] = static_cast<uint8_t>(Rand_S16Offset(0, 200));
}
player->bodyIsBurning = true;
func_80837C0C(gPlayState, player, 0, 0, 0, 0, 0);
@ -559,7 +559,7 @@ void GameInteractor::RawAction::SetRandomWind(bool active) {
GameInteractor::State::RandomWindActive = 0;
GameInteractor::State::RandomWindSecondsSinceLastDirectionChange = 0;
player->pushedSpeed = 0.0f;
player->pushedYaw = 0.0f;
player->pushedYaw = 0;
}
}
@ -617,7 +617,7 @@ GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnEnemyWithOffset
}
// Generate point in random angle with a radius.
float angle = Random(0, 2 * M_PI);
float angle = static_cast<float>(RandomDouble() * 2 * M_PI);
float radius = 150;
float posXOffset = radius * cos(angle);
float posZOffset = radius * sin(angle);

View file

@ -294,6 +294,43 @@ typedef enum {
// - `*ObjKibako2`
VB_CRATE_SETUP_DRAW,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - None
VB_CRAWL_SPEED_ENTER,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - None
VB_CRAWL_SPEED_EXIT,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - `*Camera`
// - 'int16_t' (csId)
// - 'int16_t' (actionParameters)
// - 'int16_t' (initTimer)
// - 'CutsceneCameraPoint*' (atPoints)
// - 'CutsceneCameraPoint*' (eyePoints)
VB_CRAWL_SPEED_EXIT_CS,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - None
VB_CRAWL_SPEED_INCREASE,
// #### `result`
// ```c
// !Flags_GetItemGetInf(ITEMGETINF_1C)
@ -425,6 +462,14 @@ typedef enum {
// - `*int16_t` (item id)
VB_DRAW_AMMO_COUNT,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - Player*
VB_EMPTYING_BOTTLE,
// #### `result`
// ```c
// (Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)
@ -1790,6 +1835,14 @@ typedef enum {
// - `*ObjBean`
VB_SPAWN_BEAN_STALK_FAIRIES,
// #### `result`
// ```c
// this->timer >= 60
// ```
// #### `args`
// - `None`
VB_SPAWN_BEAN_SKULLTULA,
// #### `result`
// ```c
// true

View file

@ -14,8 +14,7 @@ void Random_Init(uint32_t seed) {
generator = boost::random::mt19937{ seed };
}
// Returns a random integer in range [min, max-1]
uint32_t Random(int min, int max) {
void Random_InitSeed() {
if (!init) {
// No seed given, get a random number from device to seed
#if !defined(__SWITCH__) && !defined(__WIIU__)
@ -25,11 +24,16 @@ uint32_t Random(int min, int max) {
#endif
Random_Init(seed);
}
}
// Returns a random unsigned integer in range [min, max-1]
uint32_t Random(uint32_t min, uint32_t max) {
Random_InitSeed();
boost::random::uniform_int_distribution<uint32_t> distribution(min, max - 1);
return distribution(generator);
}
// Returns a random floating point number in [0.0, 1.0]
// Returns a random floating point number in [0.0, 1.0)
double RandomDouble() {
boost::random::uniform_real_distribution<double> distribution(0.0, 1.0);
return distribution(generator);

View file

@ -8,7 +8,7 @@
#include <set>
void Random_Init(uint32_t seed);
uint32_t Random(int min, int max);
uint32_t Random(uint32_t min, uint32_t max);
double RandomDouble();
// Get a random element from a vector or array
@ -21,17 +21,17 @@ template <typename T> T RandomElement(std::vector<T>& vector, bool erase) {
return selected;
}
template <typename Container> auto& RandomElement(Container& container) {
return container[Random(0, std::size(container))];
return container[Random(0, static_cast<uint32_t>(std::size(container)))];
}
template <typename Container> const auto& RandomElement(const Container& container) {
return container[Random(0, std::size(container))];
return container[Random(0, static_cast<uint32_t>(std::size(container)))];
}
template <typename T> const T RandomElementFromSet(const std::set<T>& set) {
if (set.size() == 1) {
return *set.begin();
}
uint32_t rand = Random(0, set.size());
uint32_t rand = Random(0, static_cast<uint32_t>(set.size()));
auto it = set.begin();
for (uint32_t i = 0; i < rand; i++) {
it++;
@ -43,12 +43,12 @@ template <typename T> const T RandomElementFromSet(const std::set<T>& set) {
// Shuffle items within a vector or array
// RANDOTODO There's probably a more efficient way to do what this does.
template <typename T> void Shuffle(std::vector<T>& vector) {
for (std::size_t i = 0; i + 1 < vector.size(); i++) {
std::swap(vector[i], vector[Random(i, vector.size())]);
for (size_t i = 0; i + 1 < vector.size(); i++) {
std::swap(vector[i], vector[Random(static_cast<uint32_t>(i), static_cast<uint32_t>(vector.size()))]);
}
}
template <typename T, std::size_t size> void Shuffle(std::array<T, size>& arr) {
for (std::size_t i = 0; i + 1 < arr.size(); i++) {
std::swap(arr[i], arr[Random(i, arr.size())]);
template <typename T, size_t size> void Shuffle(std::array<T, size>& arr) {
for (size_t i = 0; i + 1 < arr.size(); i++) {
std::swap(arr[i], arr[Random(static_cast<uint32_t>(i), static_cast<uint32_t>(arr.size()))]);
}
}

View file

@ -1645,7 +1645,7 @@ void EntranceShuffler::ParseJson(nlohmann::json spoilerFileJson) {
try {
nlohmann::json entrancesJson = spoilerFileJson["entrances"];
size_t i = 0;
for (auto it = entrancesJson.begin(); it != entrancesJson.end(); ++it, i++) {
for (auto it = entrancesJson.begin(); it != entrancesJson.end() && i < entranceOverrides.size(); ++it, i++) {
nlohmann::json entranceJson = *it;
for (auto entranceIt = entranceJson.begin(); entranceIt != entranceJson.end(); ++entranceIt) {
if (entranceIt.key() == "type") {

View file

@ -90,7 +90,7 @@ class Entrance {
Entrance* reverse = nullptr;
Entrance* assumed = nullptr;
Entrance* replacement = nullptr;
int16_t index = 0xFFFF;
int16_t index = -1;
bool shuffled = false;
bool primary = false;
bool addedToPool = false;

View file

@ -136,8 +136,9 @@ Fishsanity::GetFishingPondLocations(FishsanityOptionsSource optionsSource) {
}
// NOTE: This only works because we can assume activeFish is already sorted; changes that break this assumption will
// also break this
FilterAndEraseFromPool(remainingFish,
[&](uint32_t loc) { return std::binary_search(activeFish.begin(), activeFish.end(), loc); });
FilterAndEraseFromPool(remainingFish, [&](RandomizerCheck loc) {
return std::binary_search(activeFish.begin(), activeFish.end(), loc);
});
return std::make_pair(activeFish, remainingFish);
}

View file

@ -328,7 +328,7 @@ void RandomizerOnPlayerUpdateForRCQueueHandler() {
(getItemEntry.getItemCategory == ITEM_CATEGORY_JUNK ||
getItemEntry.getItemCategory == ITEM_CATEGORY_SKULLTULA_TOKEN ||
getItemEntry.getItemCategory == ITEM_CATEGORY_LESSER))))) {
Item_DropCollectible(gPlayState, &spawnPos, ITEM00_SOH_GIVE_ITEM_ENTRY | 0x8000);
Item_DropCollectible(gPlayState, &spawnPos, static_cast<int16_t>(ITEM00_SOH_GIVE_ITEM_ENTRY | 0x8000));
}
}
@ -2157,7 +2157,7 @@ void RandomizerOnGameFrameUpdateHandler() {
}
if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_MAGIC_METER)) {
gSaveContext.magic = gSaveContext.magicCapacity;
gSaveContext.magic = static_cast<int8_t>(gSaveContext.magicCapacity);
}
if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BOMBCHUS)) {
@ -2203,7 +2203,8 @@ void RandomizerOnActorUpdateHandler(void* refActor) {
if (actor->id == ACTOR_OBJ_COMB) {
ObjComb* combActor = reinterpret_cast<ObjComb*>(actor);
combActor->actor.shape.rot.x =
Math_SinS(combActor->unk_1B2) * CLAMP_MIN(combActor->unk_1B0, 0) + combActor->actor.home.rot.x;
static_cast<int16_t>(Math_SinS(combActor->unk_1B2)) * CLAMP_MIN(combActor->unk_1B0, 0) +
combActor->actor.home.rot.x;
}
}
@ -2216,29 +2217,29 @@ typedef struct {
// special respawns used when voided out without swim to prevent infinite loops
std::map<s32, SpecialRespawnInfo> swimSpecialRespawnInfo = {
{ ENTR_ZORAS_RIVER_3, // hf to zr in water
{ { -1455.443, -20, 1384.826 }, 28761 } },
{ { -1455.443f, -20.0f, 1384.826f }, 28761 } },
{ ENTR_HYRULE_FIELD_14, // zr to hf in water
{ { 5730.209, -20, 3725.911 }, -20025 } },
{ { 5730.209f, -20.0f, 3725.911f }, -20025 } },
{ ENTR_LOST_WOODS_UNDERWATER_SHORTCUT, // zr to lw
{ { 1978.718, -36.908, -855 }, -16384 } },
{ { 1978.718f, -36.908f, -855.0f }, -16384 } },
{ ENTR_ZORAS_RIVER_UNDERWATER_SHORTCUT, // lw to zr
{ { 4082.366, 860.442, -1018.949 }, -32768 } },
{ { 4082.366f, 860.442f, -1018.949f }, -32768 } },
{ ENTR_LAKE_HYLIA_RIVER_EXIT, // gv to lh
{ { -3276.416, -1033, 2908.421 }, 11228 } },
{ { -3276.416f, -1033.0f, 2908.421f }, 11228 } },
{ ENTR_WATER_TEMPLE_ENTRANCE, // lh to water temple
{ { -182, 780, 759.5 }, -32768 } },
{ { -182.0f, 780.0f, 759.5f }, -32768 } },
{ ENTR_LAKE_HYLIA_OUTSIDE_TEMPLE, // water temple to lh
{ { -955.028, -1306.9, 6768.954 }, -32768 } },
{ { -955.028f, -1306.9f, 6768.954f }, -32768 } },
{ ENTR_ZORAS_DOMAIN_UNDERWATER_SHORTCUT, // lh to zd
{ { -109.86, 11.396, -9.933 }, -29131 } },
{ { -109.86f, 11.396f, -9.933f }, -29131 } },
{ ENTR_LAKE_HYLIA_UNDERWATER_SHORTCUT, // zd to lh
{ { -912, -1326.967, 3391 }, 0 } },
{ { -912.0f, -1326.967f, 3391.0f }, 0 } },
{ ENTR_GERUDO_VALLEY_1, // caught by gerudos as child
{ { -424, -2051, -74 }, 16384 } },
{ { -424.0f, -2051.0f, -74.0f }, 16384 } },
{ ENTR_HYRULE_FIELD_ON_BRIDGE_SPAWN, // mk to hf (can be a problem when it then turns night)
{ { 0, 0, 1100 }, 0 } },
{ { 0.0f, 0.0f, 1100.0f }, 0 } },
{ ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP, // jabu blue warp to zf
{ { -1580, 150, 1670 }, 8000 } },
{ { -1580.0f, 150.0f, 1670.0f }, 8000 } },
};
f32 triforcePieceScale;
@ -2298,8 +2299,8 @@ void RandomizerOnSceneSpawnActorsHandler() {
switch (gPlayState->sceneNum) {
case SCENE_TEMPLE_OF_TIME:
if (gPlayState->roomCtx.curRoom.num == 1) {
Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_XC, -104, -40, 2382, 0, 0x8000, 0,
SHEIK_TYPE_RANDO, false);
Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_XC, -104, -40, 2382, 0,
static_cast<int16_t>(0x8000), 0, SHEIK_TYPE_RANDO, false);
}
break;
case SCENE_INSIDE_GANONS_CASTLE:

View file

@ -312,7 +312,7 @@ void RegionTable_Init() {
logic = ctx->GetLogic(); // RANDOTODO do not hardcode, instead allow accepting a Logic class somehow
grottoEvents = {
EventAccess(&logic->GossipStoneFairy, [] { return logic->CallGossipFairy(); }),
EventAccess(&logic->ButterflyFairy, [] { return logic->ButterflyFairy || (logic->CanUse(RG_STICKS)); }),
EventAccess(&logic->ButterflyFairy, [] { return logic->CanUse(RG_STICKS); }),
EventAccess(&logic->BugShrub, [] { return logic->CanCutShrubs(); }),
EventAccess(&logic->LoneFish, [] { return true; }),
};

View file

@ -445,7 +445,7 @@ void RegionTable_Init_DekuTree() {
areaTable[RR_DEKU_TREE_BOSS_ROOM] = Region("Deku Tree Boss Room", "Deku Tree", {}, NO_DAY_NIGHT_CYCLE, {
// Events
EventAccess(&logic->DekuTreeClear, []{return logic->DekuTreeClear || logic->CanKillEnemy(RE_GOHMA);}),
EventAccess(&logic->DekuTreeClear, []{return logic->CanKillEnemy(RE_GOHMA);}),
}, {
// Locations
LOCATION(RC_QUEEN_GOHMA, logic->DekuTreeClear),

View file

@ -567,7 +567,7 @@ void RegionTable_Init_DodongosCavern() {
areaTable[RR_DODONGOS_CAVERN_BOSS_ROOM] = Region("Dodongos Cavern Boss Room", "Dodongos Cavern", {}, NO_DAY_NIGHT_CYCLE, {
// Events
EventAccess(&logic->DodongosCavernClear, []{return logic->DodongosCavernClear || (Here(RR_DODONGOS_CAVERN_BOSS_ROOM, []{return logic->HasExplosives() || (logic->CanUse(RG_MEGATON_HAMMER) && ctx->GetTrickOption(RT_DC_HAMMER_FLOOR));}) && logic->CanKillEnemy(RE_KING_DODONGO)); /*todo add chu kill to tricks*/}),
EventAccess(&logic->DodongosCavernClear, []{return Here(RR_DODONGOS_CAVERN_BOSS_ROOM, []{return logic->HasExplosives() || (logic->CanUse(RG_MEGATON_HAMMER) && ctx->GetTrickOption(RT_DC_HAMMER_FLOOR));}) && logic->CanKillEnemy(RE_KING_DODONGO); /*todo add chu kill to tricks*/}),
}, {
// Locations
LOCATION(RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST, true),

View file

@ -27,7 +27,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_NEAR_BOSS_ROOM] = Region("Fire Temple Near Boss Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->FairyPot, []{return logic->FairyPot || (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}),
EventAccess(&logic->FairyPot, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}),
}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_CHEST, true),
@ -67,7 +67,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_LOOP_HAMMER_SWITCH] = Region("Fire Temple Loop Hammer Switch", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->FireLoopSwitch, []{return logic->FireLoopSwitch || logic->CanUse(RG_MEGATON_HAMMER);}),
EventAccess(&logic->FireLoopSwitch, []{return logic->CanUse(RG_MEGATON_HAMMER);}),
}, {}, {
//Exits
Entrance(RR_FIRE_TEMPLE_LOOP_FLARE_DANCER, []{return true;}),
@ -745,7 +745,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_BOSS_ROOM] = Region("Fire Temple Boss Room", "Fire Temple", {}, NO_DAY_NIGHT_CYCLE, {
// Events
EventAccess(&logic->FireTempleClear, []{return logic->FireTempleClear || (logic->FireTimer() >= 64 && logic->CanKillEnemy(RE_VOLVAGIA));}),
EventAccess(&logic->FireTempleClear, []{return logic->FireTimer() >= 64 && logic->CanKillEnemy(RE_VOLVAGIA);}),
}, {
// Locations
LOCATION(RC_FIRE_TEMPLE_VOLVAGIA_HEART, logic->FireTempleClear),

View file

@ -34,7 +34,7 @@ void RegionTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_LOBBY] = Region("Forest Temple Lobby", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->ForestTempleMeg, []{return logic->ForestTempleMeg || (logic->ForestTempleJoelle && logic->ForestTempleBeth && logic->ForestTempleAmy && logic->CanUse(RG_FAIRY_BOW));}),
EventAccess(&logic->ForestTempleMeg, []{return logic->ForestTempleJoelle && logic->ForestTempleBeth && logic->ForestTempleAmy && logic->CanUse(RG_FAIRY_BOW);}),
}, {
//Locations
LOCATION(RC_FOREST_TEMPLE_GS_LOBBY, logic->HookshotOrBoomerang()),
@ -203,7 +203,7 @@ void RegionTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_RED_POE_ROOM] = Region("Forest Temple Red Poe Room", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->ForestTempleJoelle, []{return logic->ForestTempleJoelle || logic->CanUse(RG_FAIRY_BOW);}),
EventAccess(&logic->ForestTempleJoelle, []{return logic->CanUse(RG_FAIRY_BOW);}),
}, {
//Locations
LOCATION(RC_FOREST_TEMPLE_RED_POE_CHEST, logic->ForestTempleJoelle),
@ -228,7 +228,7 @@ void RegionTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_BLUE_POE_ROOM] = Region("Forest Temple Blue Poe Room", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->ForestTempleBeth, []{return logic->ForestTempleBeth || logic->CanUse(RG_FAIRY_BOW);}),
EventAccess(&logic->ForestTempleBeth, []{return logic->CanUse(RG_FAIRY_BOW);}),
}, {
//Locations
LOCATION(RC_FOREST_TEMPLE_BLUE_POE_CHEST, logic->ForestTempleBeth),
@ -274,7 +274,7 @@ void RegionTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_GREEN_POE_ROOM] = Region("Forest Temple Green Poe Room", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->ForestTempleAmy, []{return logic->ForestTempleAmy || logic->CanUse(RG_FAIRY_BOW);}),
EventAccess(&logic->ForestTempleAmy, []{return logic->CanUse(RG_FAIRY_BOW);}),
}, {
//Locations
LOCATION(RC_FOREST_TEMPLE_GREEN_POE_POT_1, logic->CanBreakPots()),
@ -608,7 +608,7 @@ void RegionTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_BOSS_ROOM] = Region("Forest Temple Boss Room", "Forest Temple", {}, NO_DAY_NIGHT_CYCLE, {
// Events
EventAccess(&logic->ForestTempleClear, []{return logic->ForestTempleClear || logic->CanKillEnemy(RE_PHANTOM_GANON);}),
EventAccess(&logic->ForestTempleClear, []{return logic->CanKillEnemy(RE_PHANTOM_GANON);}),
}, {
// Locations
LOCATION(RC_FOREST_TEMPLE_PHANTOM_GANON_HEART, logic->ForestTempleClear),

View file

@ -80,7 +80,7 @@ void RegionTable_Init_GanonsCastle() {
areaTable[RR_GANONS_CASTLE_WATER_TRIAL] = Region("Ganon's Castle Water Trial", "Ganon's Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->BlueFireAccess, []{return true;}),
EventAccess(&logic->FairyPot, []{return logic->FairyPot || (logic->BlueFire() && logic->CanKillEnemy(RE_FREEZARD));}),
EventAccess(&logic->FairyPot, []{return logic->BlueFire() && logic->CanKillEnemy(RE_FREEZARD);}),
EventAccess(&logic->WaterTrialClear, []{return logic->BlueFire() && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_LIGHT_ARROWS);}),
}, {
//Locations
@ -109,7 +109,7 @@ void RegionTable_Init_GanonsCastle() {
areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL] = Region("Ganon's Castle Spirit Trial", "Ganon's Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->NutPot, []{return logic->NutPot || (((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))));}),
EventAccess(&logic->NutPot, []{return ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)));}),
EventAccess(&logic->SpiritTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_MIRROR_SHIELD) || ctx->GetOption(RSK_SUNLIGHT_ARROWS)) && logic->CanUse(RG_BOMBCHU_5) && ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT));}),
}, {
//Locations

View file

@ -361,7 +361,7 @@ void RegionTable_Init_JabuJabusBelly() {
areaTable[RR_JABU_JABUS_BELLY_BOSS_ROOM] = Region("Jabu Jabus Belly Boss Room", "Jabu Jabus Belly", {}, NO_DAY_NIGHT_CYCLE, {
// Events //todo: add pot kill trick
EventAccess(&logic->JabuJabusBellyClear, []{return logic->JabuJabusBellyClear || logic->CanKillEnemy(RE_BARINADE);}),
EventAccess(&logic->JabuJabusBellyClear, []{return logic->CanKillEnemy(RE_BARINADE);}),
}, {
// Locations
LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_1, logic->CanBreakPots()),

View file

@ -408,7 +408,7 @@ void RegionTable_Init_ShadowTemple() {
areaTable[RR_SHADOW_TEMPLE_BOSS_ROOM] = Region("Shadow Temple Boss Room", "Shadow Temple", {}, NO_DAY_NIGHT_CYCLE, {
// Events
EventAccess(&logic->ShadowTempleClear, []{return logic->ShadowTempleClear || logic->CanKillEnemy(RE_BONGO_BONGO);}),
EventAccess(&logic->ShadowTempleClear, []{return logic->CanKillEnemy(RE_BONGO_BONGO);}),
}, {
// Locations
LOCATION(RC_SHADOW_TEMPLE_BONGO_BONGO_HEART, logic->ShadowTempleClear),

View file

@ -556,7 +556,7 @@ void RegionTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_BOSS_ROOM] = Region("Spirit Temple Boss Room", "Spirit Temple", {}, NO_DAY_NIGHT_CYCLE, {
// Events
EventAccess(&logic->SpiritTempleClear, []{return logic->SpiritTempleClear || logic->CanKillEnemy(RE_TWINROVA);}),
EventAccess(&logic->SpiritTempleClear, []{return logic->CanKillEnemy(RE_TWINROVA);}),
}, {
// Locations
LOCATION(RC_SPIRIT_TEMPLE_TWINROVA_HEART, logic->SpiritTempleClear),

View file

@ -40,7 +40,7 @@ void RegionTable_Init_WaterTemple() {
areaTable[RR_WATER_TEMPLE_EAST_LOWER] = Region("Water Temple East Lower", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->CanWaterTempleLowFromHigh, []{return logic->CanWaterTempleLowFromHigh || logic->CanUse(RG_ZELDAS_LULLABY);}),
EventAccess(&logic->CanWaterTempleLowFromHigh, []{return logic->CanUse(RG_ZELDAS_LULLABY);}),
}, {
//Locations
LOCATION(RC_WATER_TEMPLE_TORCH_POT_1, logic->CanBreakPots() && (logic->CanWaterTempleLowFromHigh || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)))),
@ -165,7 +165,7 @@ void RegionTable_Init_WaterTemple() {
areaTable[RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER] = Region("Water Temple Central Pillar Upper", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->CanWaterTempleMiddle, []{return logic->CanWaterTempleMiddle || logic->CanUse(RG_ZELDAS_LULLABY);}),
EventAccess(&logic->CanWaterTempleMiddle, []{return logic->CanUse(RG_ZELDAS_LULLABY);}),
}, {
//Locations
LOCATION(RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, logic->CanUse(RG_LONGSHOT) || (((ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE) || logic->SmallKeys(RR_WATER_TEMPLE, 5))) || (ctx->GetTrickOption(RT_WATER_IRONS_CENTRAL_GS) && logic->CanUse(RG_IRON_BOOTS) && ((logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FAIRY_BOW)) || (logic->CanUse(RG_DINS_FIRE))))) && logic->CanWaterTempleHigh && logic->HookshotOrBoomerang())),
@ -202,7 +202,7 @@ void RegionTable_Init_WaterTemple() {
areaTable[RR_WATER_TEMPLE_HIGH_WATER] = Region("Water Temple High Water", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->CanWaterTempleHigh, []{return logic->CanWaterTempleHigh || logic->CanUse(RG_ZELDAS_LULLABY);}),
EventAccess(&logic->CanWaterTempleHigh, []{return logic->CanUse(RG_ZELDAS_LULLABY);}),
}, {}, {
//Exits
Entrance(RR_WATER_TEMPLE_LOBBY, []{return true;}),
@ -848,7 +848,7 @@ void RegionTable_Init_WaterTemple() {
areaTable[RR_WATER_TEMPLE_BOSS_ROOM] = Region("Water Temple Boss Room", "Water Temple", {}, NO_DAY_NIGHT_CYCLE, {
// Events
EventAccess(&logic->WaterTempleClear, []{return logic->WaterTempleClear || logic->CanKillEnemy(RE_MORPHA);}),
EventAccess(&logic->WaterTempleClear, []{return logic->CanKillEnemy(RE_MORPHA);}),
}, {
// Locations
LOCATION(RC_WATER_TEMPLE_MORPHA_HEART, logic->WaterTempleClear),

View file

@ -17,7 +17,7 @@ void RegionTable_Init_CastleGrounds() {
areaTable[RR_HYRULE_CASTLE_GROUNDS] = Region("Hyrule Castle Grounds", "Castle Grounds", {RA_HYRULE_CASTLE}, DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairy();}),
EventAccess(&logic->ButterflyFairy, []{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}),
EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS);}),
EventAccess(&logic->BugRock, []{return true;}),
}, {
//Locations

View file

@ -14,7 +14,7 @@ void RegionTable_Init_DeathMountainCrater() {
areaTable[RR_DMC_UPPER_LOCAL] = Region("DMC Upper Local", "Death Mountain Crater", {RA_DEATH_MOUNTAIN_CRATER}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->GossipStoneFairy, []{return logic->GossipStoneFairy || (logic->HasExplosives() && logic->CallGossipFairyExceptSuns() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3));}),
EventAccess(&logic->GossipStoneFairy, []{return logic->HasExplosives() && logic->CallGossipFairyExceptSuns() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3);}),
}, {
//Locations
LOCATION(RC_DMC_WALL_FREESTANDING_POH, logic->FireTimer() >= 16 || logic->Hearts() >= 3),

View file

@ -33,7 +33,7 @@ void RegionTable_Init_DeathMountainTrail() {
areaTable[RR_DEATH_MOUNTAIN_SUMMIT] = Region("Death Mountain Summit", "Death Mountain", {RA_DEATH_MOUNTAIN_TRAIL}, DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairy();}),
EventAccess(&logic->BugRock, []{return logic->BugRock || logic->IsChild;}),
EventAccess(&logic->BugRock, []{return logic->IsChild;}),
}, {
//Locations
LOCATION(RC_DMT_TRADE_BROKEN_SWORD, logic->IsAdult && logic->CanUse(RG_BROKEN_SWORD)),

View file

@ -7,7 +7,7 @@ void RegionTable_Init_DesertColossus() {
// clang-format off
areaTable[RR_DESERT_COLOSSUS] = Region("Desert Colossus", "Desert Colossus", {RA_DESERT_COLOSSUS}, DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->FairyPond, []{return logic->FairyPond || logic->CanUse(RG_SONG_OF_STORMS);}),
EventAccess(&logic->FairyPond, []{return logic->CanUse(RG_SONG_OF_STORMS);}),
EventAccess(&logic->BugRock, []{return true;}),
}, {
//Locations

View file

@ -7,7 +7,7 @@ void RegionTable_Init_GerudoValley() {
// clang-format off
areaTable[RR_GERUDO_VALLEY] = Region("Gerudo Valley", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->BugRock, []{return logic->BugRock || logic->IsChild;}),
EventAccess(&logic->BugRock, []{return logic->IsChild;}),
}, {
//Locations
LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()),

View file

@ -8,12 +8,12 @@ void RegionTable_Init_GoronCity() {
areaTable[RR_GORON_CITY] = Region("Goron City", "Goron City", {RA_GORON_CITY}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}),
EventAccess(&logic->StickPot, []{return logic->StickPot || logic->IsChild;}),
EventAccess(&logic->BugRock, []{return logic->BugRock || (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS));}),
EventAccess(&logic->GoronCityChildFire, []{return logic->GoronCityChildFire || (logic->IsChild && logic->CanUse(RG_DINS_FIRE));}),
EventAccess(&logic->GCWoodsWarpOpen, []{return logic->GCWoodsWarpOpen || (logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_FAIRY_BOW) || logic->HasItem(RG_GORONS_BRACELET) || logic->GoronCityChildFire);}),
EventAccess(&logic->GCDaruniasDoorOpenChild, []{return logic->GCDaruniasDoorOpenChild || (logic->IsChild && logic->CanUse(RG_ZELDAS_LULLABY));}),
EventAccess(&logic->StopGCRollingGoronAsAdult, []{return logic->StopGCRollingGoronAsAdult || (logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_GC_LINK_GORON_DINS) && logic->CanUse(RG_DINS_FIRE))));}),
EventAccess(&logic->StickPot, []{return logic->IsChild;}),
EventAccess(&logic->BugRock, []{return logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS);}),
EventAccess(&logic->GoronCityChildFire, []{return logic->IsChild && logic->CanUse(RG_DINS_FIRE);}),
EventAccess(&logic->GCWoodsWarpOpen, []{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_FAIRY_BOW) || logic->HasItem(RG_GORONS_BRACELET) || logic->GoronCityChildFire;}),
EventAccess(&logic->GCDaruniasDoorOpenChild, []{return logic->IsChild && logic->CanUse(RG_ZELDAS_LULLABY);}),
EventAccess(&logic->StopGCRollingGoronAsAdult, []{return logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_GC_LINK_GORON_DINS) && logic->CanUse(RG_DINS_FIRE)));}),
}, {
//Locations
LOCATION(RC_GC_MAZE_LEFT_CHEST, logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_SILVER_GAUNTLETS) || (ctx->GetTrickOption(RT_GC_LEFTMOST) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS))),
@ -58,7 +58,7 @@ void RegionTable_Init_GoronCity() {
areaTable[RR_GC_WOODS_WARP] = Region("GC Woods Warp", "Goron City", {RA_GORON_CITY}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->GCWoodsWarpOpen, []{return logic->GCWoodsWarpOpen || (logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE));}),
EventAccess(&logic->GCWoodsWarpOpen, []{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE);}),
}, {}, {
//Exits
Entrance(RR_GORON_CITY, []{return logic->CanLeaveForest() && logic->GCWoodsWarpOpen;}),
@ -67,7 +67,7 @@ void RegionTable_Init_GoronCity() {
areaTable[RR_GC_DARUNIAS_CHAMBER] = Region("GC Darunias Chamber", "Goron City", {RA_GORON_CITY}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->GoronCityChildFire, []{return logic->GoronCityChildFire || (logic->IsChild && logic->CanUse(RG_STICKS));}),
EventAccess(&logic->GoronCityChildFire, []{return logic->IsChild && logic->CanUse(RG_STICKS);}),
}, {
//Locations
LOCATION(RC_GC_DARUNIAS_JOY, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)),

View file

@ -7,7 +7,7 @@ void RegionTable_Init_Graveyard() {
// clang-format off
areaTable[RR_THE_GRAVEYARD] = Region("The Graveyard", "The Graveyard", {RA_THE_GRAVEYARD}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->ButterflyFairy, []{return logic->ButterflyFairy || (logic->CanUse(RG_STICKS) && logic->AtDay);}),
EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS) && logic->AtDay;}),
EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}),
EventAccess(&logic->BugRock, []{return true;}),
}, {
@ -88,7 +88,7 @@ void RegionTable_Init_Graveyard() {
areaTable[RR_GRAVEYARD_DAMPES_GRAVE] = Region("Graveyard Dampes Grave", "Windmill and Dampes Grave", {}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->NutPot, []{return true;}),
EventAccess(&logic->DampesWindmillAccess, []{return logic->DampesWindmillAccess || (logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME));}),
EventAccess(&logic->DampesWindmillAccess, []{return logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME);}),
}, {
//Locations
LOCATION(RC_GRAVEYARD_HOOKSHOT_CHEST, true),

View file

@ -166,7 +166,7 @@ void RegionTable_Init_Kakariko() {
areaTable[RR_KAK_WINDMILL] = Region("Kak Windmill", "Windmill and Dampes Grave", {}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->DrainWell, []{return logic->DrainWell || (logic->IsChild && logic->CanUse(RG_SONG_OF_STORMS));}),
EventAccess(&logic->DrainWell, []{return logic->IsChild && logic->CanUse(RG_SONG_OF_STORMS);}),
}, {
//Locations
LOCATION(RC_KAK_WINDMILL_FREESTANDING_POH, logic->CanUse(RG_BOOMERANG) || logic->DampesWindmillAccess || (logic->IsAdult && ctx->GetTrickOption(RT_KAK_ADULT_WINDMILL_POH)) || (logic->IsChild && logic->CanJumpslashExceptHammer() && ctx->GetTrickOption(RT_KAK_CHILD_WINDMILL_POH))),

View file

@ -9,7 +9,7 @@ void RegionTable_Init_KokiriForest() {
//Events
EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}),
EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}),
EventAccess(&logic->ShowedMidoSwordAndShield, []{return logic->ShowedMidoSwordAndShield || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD));}),
EventAccess(&logic->ShowedMidoSwordAndShield, []{return logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD);}),
}, {
//Locations
LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild),
@ -93,7 +93,7 @@ void RegionTable_Init_KokiriForest() {
//Events
EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}),
EventAccess(&logic->ShowedMidoSwordAndShield, []{return logic->ShowedMidoSwordAndShield || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD));}),
EventAccess(&logic->ShowedMidoSwordAndShield, []{return logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD);}),
}, {
//Locations
LOCATION(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),

View file

@ -9,10 +9,10 @@ void RegionTable_Init_LakeHylia() {
//Events
EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairy();}),
EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}),
EventAccess(&logic->ButterflyFairy, []{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}),
EventAccess(&logic->BugShrub, []{return logic->BugShrub || (logic->IsChild && logic->CanCutShrubs());}),
EventAccess(&logic->ChildScarecrow, []{return logic->ChildScarecrow || (logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2);}),
EventAccess(&logic->AdultScarecrow, []{return logic->AdultScarecrow || (logic->IsAdult && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2);}),
EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS);}),
EventAccess(&logic->BugShrub, []{return logic->IsChild && logic->CanCutShrubs();}),
EventAccess(&logic->ChildScarecrow, []{return logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2;}),
EventAccess(&logic->AdultScarecrow, []{return logic->IsAdult && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2;}),
}, {
//Locations
LOCATION(RC_LH_UNDERWATER_ITEM, logic->IsChild && logic->HasItem(RG_SILVER_SCALE)),

View file

@ -7,8 +7,8 @@ void RegionTable_Init_LonLonRanch() {
// clang-format off
areaTable[RR_LON_LON_RANCH] = Region("Lon Lon Ranch", "Lon Lon Ranch", {RA_LON_LON_RANCH}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->FreedEpona, []{return logic->FreedEpona || ((logic->HasItem(RG_CHILD_WALLET) || ctx->GetOption(RSK_SKIP_EPONA_RACE)) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay);}),
EventAccess(&logic->LinksCow, []{return logic->LinksCow || (logic->HasItem(RG_CHILD_WALLET) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay);}),
EventAccess(&logic->FreedEpona, []{return (logic->HasItem(RG_CHILD_WALLET) || ctx->GetOption(RSK_SKIP_EPONA_RACE)) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay;}),
EventAccess(&logic->LinksCow, []{return logic->HasItem(RG_CHILD_WALLET) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay;}),
}, {
//Locations
LOCATION(RC_SONG_FROM_MALON, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER) && logic->HasItem(RG_FAIRY_OCARINA) && logic->AtDay),

View file

@ -64,7 +64,7 @@ void RegionTable_Init_LostWoods() {
areaTable[RR_LW_BEYOND_MIDO] = Region("LW Beyond Mido", "Lost Woods", {RA_THE_LOST_WOODS}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->ButterflyFairy, []{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}),
EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS);}),
}, {
//Locations
LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, logic->IsChild && logic->CanStunDeku()),

View file

@ -138,8 +138,8 @@ void RegionTable_Init_Market() {
areaTable[RR_MARKET_MASK_SHOP] = Region("Market Mask Shop", "Market Mask Shop", {}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->SkullMask, []{return logic->SkullMask || (logic->HasItem(RG_ZELDAS_LETTER) && (ctx->GetOption(RSK_COMPLETE_MASK_QUEST) || ChildCanAccess(RR_KAKARIKO_VILLAGE)));}), //RANDOTODO Complete mask quest does not need this location, so should be tied to link's pocket
EventAccess(&logic->MaskOfTruth, []{return logic->MaskOfTruth || (logic->SkullMask && (ctx->GetOption(RSK_COMPLETE_MASK_QUEST) || (ChildCanAccess(RR_THE_LOST_WOODS) && logic->CanUse(RG_SARIAS_SONG) && RegionTable(RR_THE_GRAVEYARD)->childDay && ChildCanAccess(RR_HYRULE_FIELD) && logic->StoneCount() == 3)));}),
EventAccess(&logic->SkullMask, []{return logic->HasItem(RG_ZELDAS_LETTER) && (ctx->GetOption(RSK_COMPLETE_MASK_QUEST) || ChildCanAccess(RR_KAKARIKO_VILLAGE));}), //RANDOTODO Complete mask quest does not need this location, so should be tied to link's pocket
EventAccess(&logic->MaskOfTruth, []{return logic->SkullMask && (ctx->GetOption(RSK_COMPLETE_MASK_QUEST) || (ChildCanAccess(RR_THE_LOST_WOODS) && logic->CanUse(RG_SARIAS_SONG) && RegionTable(RR_THE_GRAVEYARD)->childDay && ChildCanAccess(RR_HYRULE_FIELD) && logic->StoneCount() == 3));}),
}, {
//Locations
LOCATION(RC_MASK_SHOP_HINT, true),

View file

@ -9,10 +9,10 @@ void RegionTable_Init_ZorasDomain() {
//Events
EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}),
EventAccess(&logic->NutPot, []{return true;}),
EventAccess(&logic->StickPot, []{return logic->StickPot || logic->IsChild;}),
EventAccess(&logic->FishGroup, []{return logic->FishGroup || logic->IsChild;}),
EventAccess(&logic->KingZoraThawed, []{return logic->KingZoraThawed || (logic->IsAdult && logic->BlueFire());}),
EventAccess(&logic->DeliverLetter, []{return logic->DeliverLetter || (logic->CanUse(RG_RUTOS_LETTER) && logic->IsChild && ctx->GetOption(RSK_ZORAS_FOUNTAIN).IsNot(RO_ZF_OPEN));}),
EventAccess(&logic->StickPot, []{return logic->IsChild;}),
EventAccess(&logic->FishGroup, []{return logic->IsChild;}),
EventAccess(&logic->KingZoraThawed, []{return logic->IsAdult && logic->BlueFire();}),
EventAccess(&logic->DeliverLetter, []{return logic->CanUse(RG_RUTOS_LETTER) && logic->IsChild && ctx->GetOption(RSK_ZORAS_FOUNTAIN).IsNot(RO_ZF_OPEN);}),
}, {
//Locations
LOCATION(RC_ZD_DIVING_MINIGAME, logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_CHILD_WALLET) && logic->IsChild),

View file

@ -8,7 +8,7 @@ void RegionTable_Init_ZorasFountain() {
areaTable[RR_ZORAS_FOUNTAIN] = Region("Zoras Fountain", "Zoras Fountain", {RA_ZORAS_FOUNTAIN}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}),
EventAccess(&logic->ButterflyFairy, []{return logic->ButterflyFairy || (logic->CanUse(RG_STICKS) && logic->AtDay);}),
EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS) && logic->AtDay;}),
}, {
//Locations
LOCATION(RC_ZF_GS_TREE, logic->IsChild),

View file

@ -30,8 +30,8 @@ void RegionTable_Init_ZoraRiver() {
//Events
EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairy();}),
EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}),
EventAccess(&logic->ButterflyFairy, []{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}),
EventAccess(&logic->BugShrub, []{return logic->BugShrub || logic->CanCutShrubs();}),
EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS);}),
EventAccess(&logic->BugShrub, []{return logic->CanCutShrubs();}),
}, {
//Locations
LOCATION(RC_ZR_MAGIC_BEAN_SALESMAN, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild),

View file

@ -373,6 +373,9 @@ void SohMenu::AddMenuEnhancements() {
.CVar(CVAR_ENHANCEMENT("SkipSwimDeepEndAnim"))
.Options(CheckboxOptions().Tooltip("Skips Link's taking breath animation after coming up from water. "
"This setting does not interfere with getting items from underwater."));
AddWidget(path, "Empty Bottles Faster", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("FasterBottleEmpty"))
.Options(CheckboxOptions().Tooltip("Speeds up emptying animation when dumping out the contents of a bottle."));
AddWidget(path, "Vine/Ladder Climb Speed +%d", WIDGET_CVAR_SLIDER_INT)
.CVar(CVAR_ENHANCEMENT("ClimbSpeed"))
.Options(IntSliderOptions().Min(0).Max(12).DefaultValue(0).Format("+%d"));
@ -382,6 +385,11 @@ void SohMenu::AddMenuEnhancements() {
AddWidget(path, "Crawl Speed %dx", WIDGET_CVAR_SLIDER_INT)
.CVar(CVAR_ENHANCEMENT("CrawlSpeed"))
.Options(IntSliderOptions().Min(1).Max(4).DefaultValue(1).Format("%dx"));
AddWidget(path, "Exclude Glitch-Aiding Crawlspaces", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("GlitchAidingCrawlspaces"))
.PreFunc([](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 0) == 1; })
.Options(CheckboxOptions().Tooltip("Don't increase crawl speed when exiting glitch-useful crawlspaces."
"Currently it is only the BOTW crawlspace to locked door"));
AddWidget(path, "King Zora Speed: %.2fx", WIDGET_CVAR_SLIDER_FLOAT)
.CVar(CVAR_ENHANCEMENT("MweepSpeed"))
.Options(FloatSliderOptions().Min(0.1f).Max(5.0f).DefaultValue(1.0f).Format("%.2fx"));
@ -425,6 +433,10 @@ void SohMenu::AddMenuEnhancements() {
AddWidget(path, "Link as Default File Name", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("LinkDefaultName"))
.Options(CheckboxOptions().Tooltip("Allows you to have \"Link\" as a premade file name."));
AddWidget(path, "Spawn Bean Skulltula Faster", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("FasterBeanSkull"))
.Options(CheckboxOptions().Tooltip(
"Makes Gold Skulltulas come out of bean patches faster after bugs dig into center."));
AddWidget(path, "Biggoron Forge Time: %d days", WIDGET_CVAR_SLIDER_INT)
.CVar(CVAR_ENHANCEMENT("ForgeTime"))
.Options(IntSliderOptions().Min(0).Max(3).DefaultValue(3).Format("%d days").Tooltip(

View file

@ -606,9 +606,9 @@ bool Combobox(const char* label, T* value, const std::vector<const char*>& combo
PushStyleCombobox(options.color);
const char* longest;
int length = 0;
size_t length = 0;
for (auto& string : comboVector) {
int len = strlen(string);
size_t len = strlen(string);
if (len > length) {
longest = string;
length = len;
@ -690,9 +690,9 @@ bool Combobox(const char* label, T* value, const std::vector<std::string>& combo
PushStyleCombobox(options.color);
const char* longest;
int length = 0;
size_t length = 0;
for (auto& string : comboVector) {
int len = string.length();
size_t len = string.length();
if (len > length) {
longest = string.c_str();
length = len;

View file

@ -71,12 +71,6 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
f32 tempRand;
Unique9OnePointCs* csInfo = ONEPOINT_CS_INFO(csCam);
// #region SOH [Enhancement]
// the default is 90, lower values necessary to prevent camera swing as animation speeds up
s16 camCrawlTemp = CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1);
s16 camCrawlTimer = D_8012042C / camCrawlTemp;
// #endregion
switch (csId) {
case 1020:
if (timer < 20) {
@ -336,26 +330,19 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
case 9601:
Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3);
Play_CameraChangeSetting(play, MAIN_CAM, mainCam->prevSetting);
if (CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1) > 1) {
OnePointCutscene_SetCsCamPoints(csCam, D_80120430 | 0x1000, camCrawlTimer, D_80120308, D_80120398);
} else {
if (GameInteractor_Should(VB_CRAWL_SPEED_EXIT_CS, true, csCam, csId, D_80120430, D_8012042C, D_80120308,
D_80120398)) {
OnePointCutscene_SetCsCamPoints(csCam, D_80120430 | 0x1000, D_8012042C, D_80120308, D_80120398);
}
break;
case 9602:
// #region SOH [Enhancement]
if (CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1) > 1) {
Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3);
Play_CameraChangeSetting(play, MAIN_CAM, mainCam->prevSetting);
OnePointCutscene_SetCsCamPoints(csCam, D_80120430 | 0x1000, camCrawlTimer, D_80120308, D_80120434);
break;
// #endregion
} else {
Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3);
Play_CameraChangeSetting(play, MAIN_CAM, mainCam->prevSetting);
Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3);
Play_CameraChangeSetting(play, MAIN_CAM, mainCam->prevSetting);
if (GameInteractor_Should(VB_CRAWL_SPEED_EXIT_CS, true, csCam, csId, D_80120430, D_8012042C, D_80120308,
D_80120434)) {
OnePointCutscene_SetCsCamPoints(csCam, D_80120430 | 0x1000, D_8012042C, D_80120308, D_80120434);
break;
}
break;
case 4175:
csInfo->keyFrames = D_8012147C;
csInfo->keyFrameCnt = 4;

View file

@ -7,6 +7,8 @@
#include "z_obj_makekinsuta.h"
#include "vt.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
void ObjMakekinsuta_Init(Actor* thisx, PlayState* play);
@ -47,7 +49,7 @@ void ObjMakekinsuta_Init(Actor* thisx, PlayState* play) {
void func_80B98320(ObjMakekinsuta* this, PlayState* play) {
if (this->unk_152 != 0) {
if (this->timer >= 60 && !func_8002DEEC(GET_PLAYER(play))) {
if (GameInteractor_Should(VB_SPAWN_BEAN_SKULLTULA, this->timer >= 60) && !func_8002DEEC(GET_PLAYER(play))) {
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_SW, this->actor.world.pos.x, this->actor.world.pos.y,
this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0, (this->actor.params | 0x8000), true);
this->actionFunc = ObjMakekinsuta_DoNothing;

View file

@ -7679,19 +7679,10 @@ s32 Player_TryEnteringCrawlspace(Player* this, PlayState* play, u32 interactWall
this->actor.world.pos.z = zVertex1 + (distToInteractWall * wallPolyNormZ);
func_80832224(this);
this->actor.prevPos = this->actor.world.pos;
// #region SOH [Enhancement]
if (CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1) > 1) {
// increase animation speed when entering a tunnel
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_start,
((CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1) + 1.0f) / 2.0f), 0.0f,
Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_start), ANIMMODE_ONCE,
0.0f);
Player_StartAnimMovement(play, this, 0x9D);
// #endregion
} else {
if (GameInteractor_Should(VB_CRAWL_SPEED_ENTER, true)) {
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_child_tunnel_start);
Player_StartAnimMovement(play, this, 0x9D);
}
Player_StartAnimMovement(play, this, 0x9D);
return true;
}
}
@ -7773,36 +7764,16 @@ s32 Player_TryLeavingCrawlspace(Player* this, PlayState* play) {
if (ABS(yawToWall) > 0x4000) {
Player_SetupAction(play, this, Player_Action_8084C81C, 0);
if (this->linearVelocity > 0.0f) {
// Leaving a crawlspace forwards
this->actor.shape.rot.y = this->actor.wallYaw + 0x8000;
// #region SOH [Enhancement]
if (CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1) > 1) {
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_end,
((CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1) + 1.0f) / 2.0f), 0.0f,
Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_end), ANIMMODE_ONCE,
0.0f);
Player_StartAnimMovement(play, this, 0x9D);
OnePointCutscene_Init(play, 9601, 999, NULL, MAIN_CAM);
// #endregion
} else {
if (GameInteractor_Should(VB_CRAWL_SPEED_EXIT, true)) {
if (this->linearVelocity > 0.0f) {
// Leaving a crawlspace forwards
this->actor.shape.rot.y = this->actor.wallYaw + 0x8000;
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_child_tunnel_end);
Player_StartAnimMovement(play, this, 0x9D);
OnePointCutscene_Init(play, 9601, 999, NULL, MAIN_CAM);
}
} else {
// Leaving a crawlspace backwards
this->actor.shape.rot.y = this->actor.wallYaw;
// #region SOH [Enhancement]
if (CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1) > 1) {
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_start,
-1.0f * ((CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1) + 1.0f) / 2.0f),
Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_start), 0.0f,
ANIMMODE_ONCE, 0.0f);
Player_StartAnimMovement(play, this, 0x9D);
OnePointCutscene_Init(play, 9602, 999, NULL, MAIN_CAM);
// #endregion
} else {
// Leaving a crawlspace backwards
this->actor.shape.rot.y = this->actor.wallYaw;
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_start, -1.0f,
Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_start), 0.0f,
ANIMMODE_ONCE, 0.0f);
@ -13587,12 +13558,7 @@ void Player_Action_8084C760(Player* this, PlayState* play) {
// player speed in a tunnel
if (!Player_TryLeavingCrawlspace(this, play)) {
// #region SOH [Enhancement]
if (CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1) > 1) {
this->linearVelocity =
sControlInput->rel.stick_y * 0.03f * CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1);
// #endregion
} else {
if (GameInteractor_Should(VB_CRAWL_SPEED_INCREASE, true)) {
this->linearVelocity = sControlInput->rel.stick_y * 0.03f;
}
}
@ -14786,6 +14752,8 @@ static AnimSfxEntry D_80854A34[] = {
void Player_Action_8084EFC0(Player* this, PlayState* play) {
Player_DecelerateToZero(this);
GameInteractor_Should(VB_EMPTYING_BOTTLE, true, this);
if (LinkAnimation_Update(play, &this->skelAnime)) {
func_8083C0E8(this, play);
func_8005B1A4(Play_GetCamera(play, 0));