mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-22 14:23:44 -07:00
Merge branch 'Blair' into BossEntryways
This commit is contained in:
commit
7303613adf
14 changed files with 125 additions and 52 deletions
|
@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.26.0 FATAL_ERROR)
|
||||||
|
|
||||||
set(CMAKE_SYSTEM_VERSION 10.0 CACHE STRING "" FORCE)
|
set(CMAKE_SYSTEM_VERSION 10.0 CACHE STRING "" FORCE)
|
||||||
set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
|
set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
|
||||||
|
set(CMAKE_C_STANDARD 17 CACHE STRING "The C standard to use")
|
||||||
|
|
||||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version")
|
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version")
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ set(CMAKE_SYSTEM_VERSION 10.0 CACHE STRING "" FORCE)
|
||||||
|
|
||||||
project(soh LANGUAGES C CXX)
|
project(soh LANGUAGES C CXX)
|
||||||
set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
|
set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
|
||||||
|
set(CMAKE_C_STANDARD 17 CACHE STRING "The C standard to use")
|
||||||
|
|
||||||
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||||
enable_language(OBJCXX)
|
enable_language(OBJCXX)
|
||||||
|
|
|
@ -474,6 +474,14 @@ typedef enum {
|
||||||
// - `*BgHeavyBlock`
|
// - `*BgHeavyBlock`
|
||||||
VB_FREEZE_LINK_FOR_BLOCK_THROW,
|
VB_FREEZE_LINK_FOR_BLOCK_THROW,
|
||||||
|
|
||||||
|
// #### `result`
|
||||||
|
// ```c
|
||||||
|
// true
|
||||||
|
// ```
|
||||||
|
// #### `args`
|
||||||
|
// - None
|
||||||
|
VB_FREEZE_LINK_FOR_FOREST_PILLARS,
|
||||||
|
|
||||||
// #### `result`
|
// #### `result`
|
||||||
// ```c
|
// ```c
|
||||||
// true
|
// true
|
||||||
|
|
|
@ -421,7 +421,7 @@ bool AddCheckToLogic(LocationAccess& locPair, GetAccessibleLocationsStruct& gals
|
||||||
Rando::ItemLocation* location = ctx->GetItemLocation(loc);
|
Rando::ItemLocation* location = ctx->GetItemLocation(loc);
|
||||||
RandomizerGet locItem = location->GetPlacedRandomizerGet();
|
RandomizerGet locItem = location->GetPlacedRandomizerGet();
|
||||||
|
|
||||||
if (!location->IsAddedToPool() && locPair.ConditionsMet(parentRegion, gals.calculatingAvailableChecks)) {
|
if (!location->IsAddedToPool() && locPair.ConditionsMet(parentRegion)) {
|
||||||
if (gals.calculatingAvailableChecks) {
|
if (gals.calculatingAvailableChecks) {
|
||||||
gals.accessibleLocations.push_back(loc);
|
gals.accessibleLocations.push_back(loc);
|
||||||
StopPerformanceTimer(PT_LOCATION_LOGIC);
|
StopPerformanceTimer(PT_LOCATION_LOGIC);
|
||||||
|
|
|
@ -70,4 +70,4 @@ void GeneratePlaythrough();
|
||||||
|
|
||||||
bool CheckBeatable(RandomizerGet ignore=RG_NONE);
|
bool CheckBeatable(RandomizerGet ignore=RG_NONE);
|
||||||
|
|
||||||
void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAccess);
|
void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAccess);
|
||||||
|
|
|
@ -10,9 +10,10 @@
|
||||||
#include "soh/Enhancements/debugger/performanceTimer.h"
|
#include "soh/Enhancements/debugger/performanceTimer.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <soh/OTRGlobals.h>
|
||||||
|
|
||||||
|
#include "3drando/shops.hpp"
|
||||||
extern "C" {
|
extern "C" {
|
||||||
extern SaveContext gSaveContext;
|
|
||||||
extern PlayState* gPlayState;
|
extern PlayState* gPlayState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +33,7 @@ bool LocationAccess::CheckConditionAtAgeTime(bool& age, bool& time) const {
|
||||||
return GetConditionsMet();
|
return GetConditionsMet();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LocationAccess::ConditionsMet(Region* parentRegion, bool calculatingAvailableChecks) const {
|
bool LocationAccess::ConditionsMet(Region* parentRegion) const {
|
||||||
// WARNING enterance validation can run this after resetting the access for sphere 0 validation
|
// WARNING enterance validation can run this after resetting the access for sphere 0 validation
|
||||||
// When refactoring ToD access, either fix the above or do not assume that we
|
// When refactoring ToD access, either fix the above or do not assume that we
|
||||||
// have any access at all just because this is being run
|
// have any access at all just because this is being run
|
||||||
|
@ -45,17 +46,71 @@ bool LocationAccess::ConditionsMet(Region* parentRegion, bool calculatingAvailab
|
||||||
conditionsMet = true;
|
conditionsMet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return conditionsMet &&
|
return conditionsMet && CanBuy();
|
||||||
(calculatingAvailableChecks || CanBuy()); // TODO: run CanBuy when price is known due to settings
|
}
|
||||||
|
|
||||||
|
static uint16_t GetMinimumPrice(const Rando::Location* loc) {
|
||||||
|
extern PriceSettingsStruct shopsanityPrices;
|
||||||
|
extern PriceSettingsStruct scrubPrices;
|
||||||
|
extern PriceSettingsStruct merchantPrices;
|
||||||
|
PriceSettingsStruct priceSettings = loc->GetRCType() == RCTYPE_SHOP ? shopsanityPrices
|
||||||
|
: loc->GetRCType() == RCTYPE_SCRUB ? scrubPrices
|
||||||
|
: merchantPrices;
|
||||||
|
|
||||||
|
auto ctx = Rando::Context::GetInstance();
|
||||||
|
switch (ctx->GetOption(priceSettings.main).Get()) {
|
||||||
|
case RO_PRICE_VANILLA:
|
||||||
|
return loc->GetVanillaPrice();
|
||||||
|
case RO_PRICE_CHEAP_BALANCED:
|
||||||
|
return 0;
|
||||||
|
case RO_PRICE_BALANCED:
|
||||||
|
return 0;
|
||||||
|
case RO_PRICE_FIXED:
|
||||||
|
return ctx->GetOption(priceSettings.fixedPrice).Get() * 5;
|
||||||
|
case RO_PRICE_RANGE: {
|
||||||
|
uint16_t range1 = ctx->GetOption(priceSettings.range1).Get() * 5;
|
||||||
|
uint16_t range2 = ctx->GetOption(priceSettings.range1).Get() * 5;
|
||||||
|
return range1 < range2 ? range1 : range2;
|
||||||
|
}
|
||||||
|
case RO_PRICE_SET_BY_WALLET: {
|
||||||
|
if (ctx->GetOption(priceSettings.noWallet).Get()) {
|
||||||
|
return 0;
|
||||||
|
} else if (ctx->GetOption(priceSettings.childWallet).Get()) {
|
||||||
|
return 1;
|
||||||
|
} else if (ctx->GetOption(priceSettings.adultWallet).Get()) {
|
||||||
|
return 100;
|
||||||
|
} else if (ctx->GetOption(priceSettings.giantWallet).Get()) {
|
||||||
|
return 201;
|
||||||
|
} else {
|
||||||
|
return 501;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LocationAccess::CanBuy() const {
|
bool LocationAccess::CanBuy() const {
|
||||||
return CanBuyAnother(location);
|
const auto& loc = Rando::StaticData::GetLocation(location);
|
||||||
|
const auto& itemLoc = OTRGlobals::Instance->gRandoContext->GetItemLocation(location);
|
||||||
|
|
||||||
|
if (loc->GetRCType() == RCTYPE_SHOP || loc->GetRCType() == RCTYPE_SCRUB || loc->GetRCType() == RCTYPE_MERCHANT) {
|
||||||
|
// Checks should only be identified while playing
|
||||||
|
if (itemLoc->GetCheckStatus() != RCSHOW_IDENTIFIED) {
|
||||||
|
return CanBuyAnother(GetMinimumPrice(loc));
|
||||||
|
} else {
|
||||||
|
return CanBuyAnother(itemLoc->GetPrice());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanBuyAnother(RandomizerCheck rc) {
|
bool CanBuyAnother(RandomizerCheck rc) {
|
||||||
uint16_t price = ctx->GetItemLocation(rc)->GetPrice();
|
return CanBuyAnother(ctx->GetItemLocation(rc)->GetPrice());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CanBuyAnother(uint16_t price) {
|
||||||
if (price > 500) {
|
if (price > 500) {
|
||||||
return logic->HasItem(RG_TYCOON_WALLET);
|
return logic->HasItem(RG_TYCOON_WALLET);
|
||||||
} else if (price > 200) {
|
} else if (price > 200) {
|
||||||
|
@ -275,7 +330,7 @@ bool BeanPlanted(const RandomizerRegion region) {
|
||||||
if (gPlayState != nullptr && gPlayState->sceneNum == sceneID) {
|
if (gPlayState != nullptr && gPlayState->sceneNum == sceneID) {
|
||||||
swch = gPlayState->actorCtx.flags.swch;
|
swch = gPlayState->actorCtx.flags.swch;
|
||||||
} else if (sceneID != SCENE_ID_MAX) {
|
} else if (sceneID != SCENE_ID_MAX) {
|
||||||
swch = gSaveContext.sceneFlags[sceneID].swch;
|
swch = Rando::Context::GetInstance()->GetLogic()->GetSaveContext()->sceneFlags[sceneID].swch;
|
||||||
} else {
|
} else {
|
||||||
swch = 0;
|
swch = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ class LocationAccess {
|
||||||
|
|
||||||
bool CheckConditionAtAgeTime(bool& age, bool& time) const;
|
bool CheckConditionAtAgeTime(bool& age, bool& time) const;
|
||||||
|
|
||||||
bool ConditionsMet(Region* parentRegion, bool calculatingAvailableChecks) const;
|
bool ConditionsMet(Region* parentRegion) const;
|
||||||
|
|
||||||
RandomizerCheck GetLocation() const {
|
RandomizerCheck GetLocation() const {
|
||||||
return location;
|
return location;
|
||||||
|
@ -103,6 +103,7 @@ class LocationAccess {
|
||||||
bool CanBuy() const;
|
bool CanBuy() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool CanBuyAnother(uint16_t price);
|
||||||
bool CanBuyAnother(RandomizerCheck rc);
|
bool CanBuyAnother(RandomizerCheck rc);
|
||||||
|
|
||||||
namespace Rando {
|
namespace Rando {
|
||||||
|
|
|
@ -25,7 +25,6 @@ void RegionTable_Init_BottomOfTheWell() {
|
||||||
}, {
|
}, {
|
||||||
//Locations
|
//Locations
|
||||||
LOCATION(RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, logic->HasExplosives()),
|
LOCATION(RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, logic->HasExplosives()),
|
||||||
LOCATION(RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, (logic->HasItem(RG_BRONZE_SCALE) || logic->LoweredWaterInsideBotw) && logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE)),
|
|
||||||
LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, logic->LoweredWaterInsideBotw),
|
LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, logic->LoweredWaterInsideBotw),
|
||||||
LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, logic->LoweredWaterInsideBotw),
|
LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, logic->LoweredWaterInsideBotw),
|
||||||
LOCATION(RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, logic->CanBreakPots()),
|
LOCATION(RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, logic->CanBreakPots()),
|
||||||
|
|
|
@ -658,7 +658,7 @@ void RegionTable_Init_WaterTemple() {
|
||||||
|
|
||||||
areaTable[RR_WATER_TEMPLE_MQ_DRAGON_ROOM_ALCOVE] = Region("Water Temple MQ Dragon Room Alcove", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
areaTable[RR_WATER_TEMPLE_MQ_DRAGON_ROOM_ALCOVE] = Region("Water Temple MQ Dragon Room Alcove", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||||
//Events
|
//Events
|
||||||
EventAccess(&logic->MQWaterDragonTorches, []{return true;}),
|
EventAccess(&logic->MQWaterDragonTorches, []{return logic->HasFireSource();}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
//Locations
|
//Locations
|
||||||
|
|
|
@ -65,7 +65,7 @@ const std::string Randomizer::NaviRandoMessageTableID = "RandomizerNavi";
|
||||||
const std::string Randomizer::IceTrapRandoMessageTableID = "RandomizerIceTrap";
|
const std::string Randomizer::IceTrapRandoMessageTableID = "RandomizerIceTrap";
|
||||||
const std::string Randomizer::randoMiscHintsTableID = "RandomizerMiscHints";
|
const std::string Randomizer::randoMiscHintsTableID = "RandomizerMiscHints";
|
||||||
|
|
||||||
static const char* englishRupeeNames[190] = {
|
static const char* englishRupeeNames[188] = {
|
||||||
"[P]",
|
"[P]",
|
||||||
"Bad RNG Rolls",
|
"Bad RNG Rolls",
|
||||||
"Baht",
|
"Baht",
|
||||||
|
@ -111,8 +111,6 @@ static const char* englishRupeeNames[190] = {
|
||||||
"Dimes",
|
"Dimes",
|
||||||
"Dinars",
|
"Dinars",
|
||||||
"DNA",
|
"DNA",
|
||||||
"Doge",
|
|
||||||
"Dogecoin",
|
|
||||||
"Doll Hairs",
|
"Doll Hairs",
|
||||||
"Dollars",
|
"Dollars",
|
||||||
"Dollarydoos",
|
"Dollarydoos",
|
||||||
|
@ -258,25 +256,25 @@ static const char* englishRupeeNames[190] = {
|
||||||
"Zorkmids",
|
"Zorkmids",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* germanRupeeNames[80] = {
|
static const char* germanRupeeNames[79] = {
|
||||||
"Baht", "Bananen", "Bitcoin", "Bonbons", "Bratwürste", "Brause UFOs", "Brötchen", "Cent",
|
"Baht", "Bananen", "Bitcoin", "Bonbons", "Bratwürste", "Brause UFOs", "Brötchen", "Cent",
|
||||||
"Diamanten", "Dinar", "Diridari", "Dogecoin", "Dollar", "Draken", "ECU", "Elexit",
|
"Diamanten", "Dinar", "Diridari", "Dollar", "Draken", "ECU", "Elexit", "Erz",
|
||||||
"Erz", "Erzbrocken", "Euro", "EXP", "Forint", "Franken", "Freunde", "Gil",
|
"Erzbrocken", "Euro", "EXP", "Forint", "Franken", "Freunde", "Gil", "Gold",
|
||||||
"Gold", "Groschen", "Gulden", "Gummibären", "Heller", "Juwelen", "Karolin", "Kartoffeln",
|
"Groschen", "Gulden", "Gummibären", "Heller", "Juwelen", "Karolin", "Kartoffeln", "Kies",
|
||||||
"Kies", "Knete", "Knochen", "Kohle", "Kraniche", "Kreuzer", "Kronen", "Kronkorken",
|
"Knete", "Knochen", "Kohle", "Kraniche", "Kreuzer", "Kronen", "Kronkorken", "Kröten",
|
||||||
"Kröten", "Lira", "Mark", "Mäuse", "Monde", "Moorhühner", "Moos", "Münzen",
|
"Lira", "Mark", "Mäuse", "Monde", "Moorhühner", "Moos", "Münzen", "Naira",
|
||||||
"Naira", "Penunze", "Pesa", "Pfandflaschen", "Pfennig", "Pfund", "Pilze", "Plastiks",
|
"Penunze", "Pesa", "Pfandflaschen", "Pfennig", "Pfund", "Pilze", "Plastiks", "Pokédollar",
|
||||||
"Pokédollar", "Radieschen", "Rand", "Rappen", "Real", "Rial", "Riyal", "Rubine",
|
"Radieschen", "Rand", "Rappen", "Real", "Rial", "Riyal", "Rubine", "Rupien",
|
||||||
"Rupien", "Saphire", "Schilling", "Seelen", "Septime", "Smaragde", "Steine", "Sterne",
|
"Saphire", "Schilling", "Seelen", "Septime", "Smaragde", "Steine", "Sterne", "Sternis",
|
||||||
"Sternis", "Tael", "Taler", "Wagenchips", "Won", "Yen", "Yuan", "Zenny",
|
"Tael", "Taler", "Wagenchips", "Won", "Yen", "Yuan", "Zenny",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* frenchRupeeNames[40] = {
|
static const char* frenchRupeeNames[39] = {
|
||||||
"Anneaux", "Baguettes", "Balles", "Bananes", "Bitcoin", "Blés", "Bling", "Capsules",
|
"Anneaux", "Baguettes", "Balles", "Bananes", "Bitcoin", "Blés", "Bling", "Capsules",
|
||||||
"Centimes", "Champignons", "Clochettes", "Crédits", "Croissants", "Diamants", "Dogecoin", "Dollars",
|
"Centimes", "Champignons", "Clochettes", "Crédits", "Croissants", "Diamants", "Dollars", "Émeraudes",
|
||||||
"Émeraudes", "Éthers", "Étoiles", "Euros", "Florens", "Francs", "Galds", "Gils",
|
"Éthers", "Étoiles", "Euros", "Florens", "Francs", "Galds", "Gils", "Grouses",
|
||||||
"Grouses", "Halos", "Joyaux", "Lunes", "Mailles", "Munnies", "Orbes", "Orens",
|
"Halos", "Joyaux", "Lunes", "Mailles", "Munnies", "Orbes", "Orens", "Pépètes",
|
||||||
"Pépètes", "Pièces", "Plastyks", "Pokédollars", "Pokémon", "Radis", "Rubis", "Zennies",
|
"Pièces", "Plastyks", "Pokédollars", "Pokémon", "Radis", "Rubis", "Zennies",
|
||||||
};
|
};
|
||||||
|
|
||||||
Randomizer::Randomizer() {
|
Randomizer::Randomizer() {
|
||||||
|
@ -3726,13 +3724,15 @@ void RandomizerSettingsWindow::DrawElement() {
|
||||||
}
|
}
|
||||||
|
|
||||||
UIWidgets::Spacer(0);
|
UIWidgets::Spacer(0);
|
||||||
ImGui::BeginDisabled((gSaveContext.gameMode != GAMEMODE_FILE_SELECT) || GameInteractor::IsSaveLoaded());
|
UIWidgets::ButtonOptions options = UIWidgets::ButtonOptions().Size(ImVec2(250.f, 0.f)).Color(THEME_COLOR);
|
||||||
if (UIWidgets::Button("Generate Randomizer",
|
options.Disabled((gSaveContext.gameMode != GAMEMODE_FILE_SELECT) || GameInteractor::IsSaveLoaded());
|
||||||
UIWidgets::ButtonOptions().Size(ImVec2(250.f, 0.f)).Color(THEME_COLOR))) {
|
if (options.disabled) {
|
||||||
|
options.DisabledTooltip("Must be on File Select to generate a randomizer seed.");
|
||||||
|
}
|
||||||
|
if (UIWidgets::Button("Generate Randomizer", options)) {
|
||||||
ctx->SetSpoilerLoaded(false);
|
ctx->SetSpoilerLoaded(false);
|
||||||
GenerateRandomizer(CVarGetInteger(CVAR_RANDOMIZER_SETTING("ManualSeedEntry"), 0) ? seedString : "");
|
GenerateRandomizer(CVarGetInteger(CVAR_RANDOMIZER_SETTING("ManualSeedEntry"), 0) ? seedString : "");
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (!CVarGetInteger(CVAR_RANDOMIZER_SETTING("DontGenerateSpoiler"), 0)) {
|
if (!CVarGetInteger(CVAR_RANDOMIZER_SETTING("DontGenerateSpoiler"), 0)) {
|
||||||
|
|
|
@ -1967,7 +1967,7 @@ void RecalculateAvailableChecks() {
|
||||||
StartPerformanceTimer(PT_RECALCULATE_AVAILABLE_CHECKS);
|
StartPerformanceTimer(PT_RECALCULATE_AVAILABLE_CHECKS);
|
||||||
|
|
||||||
std::vector<RandomizerCheck> targetLocations;
|
std::vector<RandomizerCheck> targetLocations;
|
||||||
targetLocations.reserve(RR_MAX);
|
targetLocations.reserve(RC_MAX);
|
||||||
for (auto& location : Rando::StaticData::GetLocationTable()) {
|
for (auto& location : Rando::StaticData::GetLocationTable()) {
|
||||||
RandomizerCheck rc = location.GetRandomizerCheck();
|
RandomizerCheck rc = location.GetRandomizerCheck();
|
||||||
Rando::ItemLocation* itemLocation = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc);
|
Rando::ItemLocation* itemLocation = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc);
|
||||||
|
@ -1979,15 +1979,8 @@ void RecalculateAvailableChecks() {
|
||||||
|
|
||||||
std::vector<RandomizerCheck> availableChecks = ReachabilitySearch(targetLocations, RG_NONE, true);
|
std::vector<RandomizerCheck> availableChecks = ReachabilitySearch(targetLocations, RG_NONE, true);
|
||||||
for (auto& rc : availableChecks) {
|
for (auto& rc : availableChecks) {
|
||||||
const auto& location = Rando::StaticData::GetLocation(rc);
|
|
||||||
const auto& itemLocation = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc);
|
const auto& itemLocation = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc);
|
||||||
if (location->GetRCType() == RCTYPE_SHOP && itemLocation->GetCheckStatus() == RCSHOW_IDENTIFIED) {
|
itemLocation->SetAvailable(true);
|
||||||
if (CanBuyAnother(rc)) {
|
|
||||||
itemLocation->SetAvailable(true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
itemLocation->SetAvailable(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
totalChecksAvailable = 0;
|
totalChecksAvailable = 0;
|
||||||
|
@ -2114,7 +2107,10 @@ void CheckTrackerSettingsWindow::DrawElement() {
|
||||||
"with your current progress.")
|
"with your current progress.")
|
||||||
.Color(THEME_COLOR))) {
|
.Color(THEME_COLOR))) {
|
||||||
enableAvailableChecks = CVarGetInteger(CVAR_TRACKER_CHECK("EnableAvailableChecks"), 0);
|
enableAvailableChecks = CVarGetInteger(CVAR_TRACKER_CHECK("EnableAvailableChecks"), 0);
|
||||||
RecalculateAvailableChecks();
|
|
||||||
|
if (GameInteractor::IsSaveLoaded(true)) {
|
||||||
|
RecalculateAvailableChecks();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
|
|
||||||
|
|
|
@ -269,9 +269,9 @@ extern "C" void Randomizer_InitSaveFile() {
|
||||||
|
|
||||||
// Remove One Time Scrubs with Scrubsanity off
|
// Remove One Time Scrubs with Scrubsanity off
|
||||||
if (Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_OFF) {
|
if (Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_OFF) {
|
||||||
Flags_SetRandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE);
|
Flags_SetItemGetInf(ITEMGETINF_DEKU_SCRUB_HEART_PIECE);
|
||||||
Flags_SetRandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT);
|
Flags_SetInfTable(INFTABLE_BOUGHT_STICK_UPGRADE);
|
||||||
Flags_SetRandomizerInf(RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO);
|
Flags_SetInfTable(INFTABLE_BOUGHT_NUT_UPGRADE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int startingAge = OTRGlobals::Instance->gRandoContext->GetOption(RSK_SELECTED_STARTING_AGE).Get();
|
int startingAge = OTRGlobals::Instance->gRandoContext->GetOption(RSK_SELECTED_STARTING_AGE).Get();
|
||||||
|
|
|
@ -375,6 +375,11 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case VB_FREEZE_LINK_FOR_FOREST_PILLARS:
|
||||||
|
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO)) {
|
||||||
|
*should = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case VB_SHOW_TITLE_CARD:
|
case VB_SHOW_TITLE_CARD:
|
||||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.DisableTitleCard"), IS_RANDO)) {
|
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.DisableTitleCard"), IS_RANDO)) {
|
||||||
*should = false;
|
*should = false;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "z_bg_mori_kaitenkabe.h"
|
#include "z_bg_mori_kaitenkabe.h"
|
||||||
#include "objects/object_mori_objects/object_mori_objects.h"
|
#include "objects/object_mori_objects/object_mori_objects.h"
|
||||||
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
|
|
||||||
#define FLAGS 0
|
#define FLAGS 0
|
||||||
|
|
||||||
|
@ -97,7 +98,9 @@ void BgMoriKaitenkabe_Wait(BgMoriKaitenkabe* this, PlayState* play) {
|
||||||
if ((this->timer > (28 - CVarGetInteger(CVAR_ENHANCEMENT("FasterBlockPush"), 0) * 4)) &&
|
if ((this->timer > (28 - CVarGetInteger(CVAR_ENHANCEMENT("FasterBlockPush"), 0) * 4)) &&
|
||||||
!Player_InCsMode(play)) {
|
!Player_InCsMode(play)) {
|
||||||
BgMoriKaitenkabe_SetupRotate(this);
|
BgMoriKaitenkabe_SetupRotate(this);
|
||||||
Player_SetCsActionWithHaltedActors(play, &this->dyna.actor, 8);
|
if (GameInteractor_Should(VB_FREEZE_LINK_FOR_FOREST_PILLARS, true)) {
|
||||||
|
Player_SetCsActionWithHaltedActors(play, &this->dyna.actor, 8);
|
||||||
|
}
|
||||||
Math_Vec3f_Copy(&this->lockedPlayerPos, &player->actor.world.pos);
|
Math_Vec3f_Copy(&this->lockedPlayerPos, &player->actor.world.pos);
|
||||||
push.x = Math_SinS(this->dyna.unk_158);
|
push.x = Math_SinS(this->dyna.unk_158);
|
||||||
push.y = 0.0f;
|
push.y = 0.0f;
|
||||||
|
@ -131,7 +134,9 @@ void BgMoriKaitenkabe_Rotate(BgMoriKaitenkabe* this, PlayState* play) {
|
||||||
Math_StepToF(&this->rotSpeed, 0.6f, 0.02f);
|
Math_StepToF(&this->rotSpeed, 0.6f, 0.02f);
|
||||||
if (Math_StepToF(&this->rotYdeg, this->rotDirection * 45.0f, this->rotSpeed)) {
|
if (Math_StepToF(&this->rotYdeg, this->rotDirection * 45.0f, this->rotSpeed)) {
|
||||||
BgMoriKaitenkabe_SetupWait(this);
|
BgMoriKaitenkabe_SetupWait(this);
|
||||||
Player_SetCsActionWithHaltedActors(play, thisx, 7);
|
if (GameInteractor_Should(VB_FREEZE_LINK_FOR_FOREST_PILLARS, true)) {
|
||||||
|
Player_SetCsActionWithHaltedActors(play, thisx, 7);
|
||||||
|
}
|
||||||
if (this->rotDirection > 0.0f) {
|
if (this->rotDirection > 0.0f) {
|
||||||
thisx->home.rot.y += 0x2000;
|
thisx->home.rot.y += 0x2000;
|
||||||
} else {
|
} else {
|
||||||
|
@ -148,7 +153,9 @@ void BgMoriKaitenkabe_Rotate(BgMoriKaitenkabe* this, PlayState* play) {
|
||||||
this->dyna.unk_150 = 0.0f;
|
this->dyna.unk_150 = 0.0f;
|
||||||
player->stateFlags2 &= ~PLAYER_STATE2_MOVING_DYNAPOLY;
|
player->stateFlags2 &= ~PLAYER_STATE2_MOVING_DYNAPOLY;
|
||||||
}
|
}
|
||||||
Math_Vec3f_Copy(&player->actor.world.pos, &this->lockedPlayerPos);
|
if (GameInteractor_Should(VB_FREEZE_LINK_FOR_FOREST_PILLARS, true)) {
|
||||||
|
Math_Vec3f_Copy(&player->actor.world.pos, &this->lockedPlayerPos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BgMoriKaitenkabe_Update(Actor* thisx, PlayState* play) {
|
void BgMoriKaitenkabe_Update(Actor* thisx, PlayState* play) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue