mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-22 14:23:44 -07:00
Merge branch 'develop' into SplitGF
This commit is contained in:
commit
9b82f62f44
47 changed files with 354 additions and 181 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
110
soh/soh/Enhancements/TimeSavers/CrawlSpeed.cpp
Normal file
110
soh/soh/Enhancements/TimeSavers/CrawlSpeed.cpp
Normal 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 });
|
13
soh/soh/Enhancements/TimeSavers/FasterBeanSkulltula.cpp
Normal file
13
soh/soh/Enhancements/TimeSavers/FasterBeanSkulltula.cpp
Normal 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") });
|
19
soh/soh/Enhancements/TimeSavers/FasterBottleEmpty.cpp
Normal file
19
soh/soh/Enhancements/TimeSavers/FasterBottleEmpty.cpp
Normal 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") });
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()))]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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; }),
|
||||
};
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()),
|
||||
|
|
|
@ -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)),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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))),
|
||||
|
|
|
@ -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()),
|
||||
|
|
|
@ -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)),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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()),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue