mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-20 13:23:45 -07:00
Merge remote-tracking branch 'master/develop' into SpiritShared
This commit is contained in:
commit
a05d24cef4
21 changed files with 190 additions and 100 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -457,3 +457,4 @@ soh/properties.h
|
||||||
# Tools
|
# Tools
|
||||||
/clang-format
|
/clang-format
|
||||||
/clang-format.exe
|
/clang-format.exe
|
||||||
|
*.o2r
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
#include <libultraship/bridge.h>
|
|
||||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
#include "soh/ShipInit.hpp"
|
#include "soh/ShipInit.hpp"
|
||||||
#include "z64save.h"
|
|
||||||
|
|
||||||
extern "C" SaveContext gSaveContext;
|
extern "C" {
|
||||||
|
#include "z64save.h"
|
||||||
|
extern SaveContext gSaveContext;
|
||||||
|
}
|
||||||
|
|
||||||
#define CVAR_INFINITE_MAGIC_NAME CVAR_CHEAT("InfiniteMagic")
|
#define CVAR_INFINITE_MAGIC_NAME CVAR_CHEAT("InfiniteMagic")
|
||||||
#define CVAR_INFINITE_MAGIC_DEFAULT 0
|
#define CVAR_INFINITE_MAGIC_DEFAULT 0
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
#include <libultraship/bridge.h>
|
|
||||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
#include "soh/ShipInit.hpp"
|
#include "soh/ShipInit.hpp"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
#include "variables.h"
|
#include "variables.h"
|
||||||
|
extern PlayState* gPlayState;
|
||||||
extern "C" PlayState* gPlayState;
|
}
|
||||||
|
|
||||||
static constexpr int32_t CVAR_RUPEE_DASH_DEFAULT = 0;
|
static constexpr int32_t CVAR_RUPEE_DASH_DEFAULT = 0;
|
||||||
#define CVAR_RUPEE_DASH_NAME CVAR_ENHANCEMENT("RupeeDash")
|
#define CVAR_RUPEE_DASH_NAME CVAR_ENHANCEMENT("RupeeDash")
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
std::array<std::string, LANGUAGE_MAX> RandomizerSettingsMenuText[RSM_MAX] = {
|
std::array<std::string, LANGUAGE_MAX> RandomizerSettingsMenuText[RSM_MAX] = {
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
#include <libultraship/bridge.h>
|
|
||||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
#include "soh/ShipInit.hpp"
|
#include "soh/ShipInit.hpp"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
#include "variables.h"
|
#include "variables.h"
|
||||||
#include "z64save.h"
|
#include "z64save.h"
|
||||||
|
extern PlayState* gPlayState;
|
||||||
extern "C" PlayState* gPlayState;
|
}
|
||||||
|
|
||||||
static constexpr int32_t CVAR_BGS_FIX_DEFAULT = 0;
|
static constexpr int32_t CVAR_BGS_FIX_DEFAULT = 0;
|
||||||
#define CVAR_BGS_FIX_NAME CVAR_ENHANCEMENT("FixBrokenGiantsKnife")
|
#define CVAR_BGS_FIX_NAME CVAR_ENHANCEMENT("FixBrokenGiantsKnife")
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
#include <libultraship/bridge.h>
|
|
||||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
#include "soh/ShipInit.hpp"
|
#include "soh/ShipInit.hpp"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
#include "variables.h"
|
#include "variables.h"
|
||||||
#include "z64save.h"
|
#include "z64save.h"
|
||||||
|
extern PlayState* gPlayState;
|
||||||
extern "C" PlayState* gPlayState;
|
}
|
||||||
|
|
||||||
static constexpr int32_t CVAR_NUT_UPGRADE_FIX_DEFAULT = 0;
|
static constexpr int32_t CVAR_NUT_UPGRADE_FIX_DEFAULT = 0;
|
||||||
#define CVAR_NUT_UPGRADE_FIX_NAME CVAR_ENHANCEMENT("DekuNutUpgradeFix")
|
#define CVAR_NUT_UPGRADE_FIX_NAME CVAR_ENHANCEMENT("DekuNutUpgradeFix")
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
#include <libultraship/bridge.h>
|
|
||||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
#include "soh/ShipInit.hpp"
|
#include "soh/ShipInit.hpp"
|
||||||
#include "functions.h"
|
|
||||||
#include "macros.h"
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
#include "functions.h"
|
||||||
|
#include "macros.h"
|
||||||
extern PlayState* gPlayState;
|
extern PlayState* gPlayState;
|
||||||
extern SaveContext gSaveContext;
|
extern SaveContext gSaveContext;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,7 @@
|
||||||
#include "bootcommands.h"
|
#include <stddef.h>
|
||||||
#include "gameconsole.h"
|
#include <stdbool.h>
|
||||||
#include <macros.h>
|
|
||||||
#include <z64.h>
|
|
||||||
#include <libultraship/libultra.h>
|
|
||||||
#include <libultraship/bridge.h>
|
#include <libultraship/bridge.h>
|
||||||
#include <functions.h>
|
#include "bootcommands.h"
|
||||||
#include <variables.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <z64.h>
|
|
||||||
#include "soh/OTRGlobals.h"
|
|
||||||
#include "soh/cvar_prefixes.h"
|
#include "soh/cvar_prefixes.h"
|
||||||
|
|
||||||
void BootCommands_Init() {
|
void BootCommands_Init() {
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#ifndef _BOOTCOMMANDS_H_
|
#ifndef _BOOTCOMMANDS_H_
|
||||||
#define _BOOTCOMMANDS_H_
|
#define _BOOTCOMMANDS_H_
|
||||||
#include <libultraship/libultra.h>
|
|
||||||
#include <z64.h>
|
|
||||||
|
|
||||||
void BootCommands_Init();
|
void BootCommands_Init();
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <libultraship/bridge.h>
|
|
||||||
#include <libultraship/libultraship.h>
|
|
||||||
#include "soh/OTRGlobals.h"
|
#include "soh/OTRGlobals.h"
|
||||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
#include <libultraship/bridge.h>
|
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
#include "z64.h"
|
|
||||||
#include "macros.h"
|
|
||||||
#include "functions.h"
|
|
||||||
#include "variables.h"
|
|
||||||
#include "soh/OTRGlobals.h"
|
#include "soh/OTRGlobals.h"
|
||||||
#include "soh/cvar_prefixes.h"
|
#include "soh/cvar_prefixes.h"
|
||||||
#include "randomizerTypes.h"
|
#include "randomizerTypes.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include "soh_assets.h"
|
||||||
|
#include "soh/Enhancements/cosmetics/cosmeticsTypes.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "z64.h"
|
||||||
|
#include "macros.h"
|
||||||
|
#include "functions.h"
|
||||||
|
#include "variables.h"
|
||||||
|
#include "dungeon.h"
|
||||||
#include "objects/object_gi_key/object_gi_key.h"
|
#include "objects/object_gi_key/object_gi_key.h"
|
||||||
#include "objects/object_gi_bosskey/object_gi_bosskey.h"
|
#include "objects/object_gi_bosskey/object_gi_bosskey.h"
|
||||||
#include "objects/object_gi_compass/object_gi_compass.h"
|
#include "objects/object_gi_compass/object_gi_compass.h"
|
||||||
|
@ -30,11 +34,6 @@
|
||||||
#include "overlays/ovl_Boss_Sst/ovl_Boss_Sst.h"
|
#include "overlays/ovl_Boss_Sst/ovl_Boss_Sst.h"
|
||||||
#include "objects/object_tw/object_tw.h"
|
#include "objects/object_tw/object_tw.h"
|
||||||
#include "objects/object_ganon2/object_ganon2.h"
|
#include "objects/object_ganon2/object_ganon2.h"
|
||||||
#include "soh_assets.h"
|
|
||||||
#include "dungeon.h"
|
|
||||||
#include "soh/Enhancements/cosmetics/cosmeticsTypes.h"
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
extern PlayState* gPlayState;
|
extern PlayState* gPlayState;
|
||||||
extern SaveContext gSaveContext;
|
extern SaveContext gSaveContext;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,8 +45,6 @@ std::string Entrance::GetName() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entrance::printAgeTimeAccess() {
|
void Entrance::printAgeTimeAccess() {
|
||||||
// CitraPrint("Name: ");
|
|
||||||
// CitraPrint(name);
|
|
||||||
auto message = "Child Day: " + std::to_string(CheckConditionAtAgeTime(logic->IsChild, logic->AtDay)) +
|
auto message = "Child Day: " + std::to_string(CheckConditionAtAgeTime(logic->IsChild, logic->AtDay)) +
|
||||||
"\t"
|
"\t"
|
||||||
"Child Night: " +
|
"Child Night: " +
|
||||||
|
@ -57,7 +55,6 @@ void Entrance::printAgeTimeAccess() {
|
||||||
"\t"
|
"\t"
|
||||||
"Adult Night: " +
|
"Adult Night: " +
|
||||||
std::to_string(CheckConditionAtAgeTime(logic->IsAdult, logic->AtNight));
|
std::to_string(CheckConditionAtAgeTime(logic->IsAdult, logic->AtNight));
|
||||||
// CitraPrint(message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Entrance::ConditionsMet(bool allAgeTimes) const {
|
bool Entrance::ConditionsMet(bool allAgeTimes) const {
|
||||||
|
@ -276,8 +273,8 @@ void SetAllEntrancesData() {
|
||||||
{ EntranceType::Dungeon, RR_BOTTOM_OF_THE_WELL_ENTRYWAY, RR_KAK_WELL, ENTR_KAKARIKO_VILLAGE_OUTSIDE_BOTTOM_OF_THE_WELL } },
|
{ EntranceType::Dungeon, RR_BOTTOM_OF_THE_WELL_ENTRYWAY, RR_KAK_WELL, ENTR_KAKARIKO_VILLAGE_OUTSIDE_BOTTOM_OF_THE_WELL } },
|
||||||
{ { EntranceType::Dungeon, RR_ZF_LEDGE, RR_ICE_CAVERN_ENTRYWAY, ENTR_ICE_CAVERN_ENTRANCE },
|
{ { EntranceType::Dungeon, RR_ZF_LEDGE, RR_ICE_CAVERN_ENTRYWAY, ENTR_ICE_CAVERN_ENTRANCE },
|
||||||
{ EntranceType::Dungeon, RR_ICE_CAVERN_ENTRYWAY, RR_ZF_LEDGE, ENTR_ZORAS_FOUNTAIN_OUTSIDE_ICE_CAVERN } },
|
{ EntranceType::Dungeon, RR_ICE_CAVERN_ENTRYWAY, RR_ZF_LEDGE, ENTR_ZORAS_FOUNTAIN_OUTSIDE_ICE_CAVERN } },
|
||||||
{ { EntranceType::Dungeon, RR_GF_OUTSIDE_GTG, RR_GERUDO_TRAINING_GROUND_ENTRYWAY, ENTR_GERUDO_TRAINING_GROUND_ENTRANCE },
|
{ { EntranceType::Dungeon, RR_GF_TO_GTG, RR_GERUDO_TRAINING_GROUND_ENTRYWAY, ENTR_GERUDO_TRAINING_GROUND_ENTRANCE },
|
||||||
{ EntranceType::Dungeon, RR_GERUDO_TRAINING_GROUND_ENTRYWAY, RR_GF_OUTSIDE_GTG, ENTR_GERUDOS_FORTRESS_OUTSIDE_GERUDO_TRAINING_GROUND } },
|
{ EntranceType::Dungeon, RR_GERUDO_TRAINING_GROUND_ENTRYWAY, RR_GF_EXITING_GTG, ENTR_GERUDOS_FORTRESS_OUTSIDE_GERUDO_TRAINING_GROUND } },
|
||||||
{ { EntranceType::GanonDungeon, RR_GANONS_CASTLE_LEDGE, RR_GANONS_CASTLE_ENTRYWAY, ENTR_INSIDE_GANONS_CASTLE_ENTRANCE },
|
{ { EntranceType::GanonDungeon, RR_GANONS_CASTLE_LEDGE, RR_GANONS_CASTLE_ENTRYWAY, ENTR_INSIDE_GANONS_CASTLE_ENTRANCE },
|
||||||
{ EntranceType::GanonDungeon, RR_GANONS_CASTLE_ENTRYWAY, RR_CASTLE_GROUNDS_FROM_GANONS_CASTLE, ENTR_CASTLE_GROUNDS_RAINBOW_BRIDGE_EXIT } },
|
{ EntranceType::GanonDungeon, RR_GANONS_CASTLE_ENTRYWAY, RR_CASTLE_GROUNDS_FROM_GANONS_CASTLE, ENTR_CASTLE_GROUNDS_RAINBOW_BRIDGE_EXIT } },
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,18 @@ extern PlayState* gPlayState;
|
||||||
// generic grotto event list
|
// generic grotto event list
|
||||||
std::vector<EventAccess> grottoEvents;
|
std::vector<EventAccess> grottoEvents;
|
||||||
|
|
||||||
|
bool EventAccess::CheckConditionAtAgeTime(bool& age, bool& time) {
|
||||||
|
logic->IsChild = false;
|
||||||
|
logic->IsAdult = false;
|
||||||
|
logic->AtDay = false;
|
||||||
|
logic->AtNight = false;
|
||||||
|
|
||||||
|
time = true;
|
||||||
|
age = true;
|
||||||
|
|
||||||
|
return ConditionsMet();
|
||||||
|
}
|
||||||
|
|
||||||
// set the logic to be a specific age and time of day and see if the condition still holds
|
// set the logic to be a specific age and time of day and see if the condition still holds
|
||||||
bool LocationAccess::CheckConditionAtAgeTime(bool& age, bool& time) const {
|
bool LocationAccess::CheckConditionAtAgeTime(bool& age, bool& time) const {
|
||||||
logic->IsChild = false;
|
logic->IsChild = false;
|
||||||
|
@ -466,7 +478,7 @@ bool Region::UpdateEvents() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Region::AddExit(RandomizerRegion parentKey, RandomizerRegion newExitKey, ConditionFn condition) {
|
void Region::AddExit(RandomizerRegion parentKey, RandomizerRegion newExitKey, ConditionFn condition) {
|
||||||
Rando::Entrance newExit = Rando::Entrance(newExitKey, { condition });
|
Rando::Entrance newExit = Rando::Entrance(newExitKey, condition);
|
||||||
newExit.SetParentRegion(parentKey);
|
newExit.SetParentRegion(parentKey);
|
||||||
exits.push_front(newExit);
|
exits.push_front(newExit);
|
||||||
}
|
}
|
||||||
|
@ -551,6 +563,110 @@ void Region::ResetVariables() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This logic covers checks that exist in the shared areas of MQ spirit from a glitchless standpoint.
|
||||||
|
* This room has Quantum logic that I am currently handling with this function, however this is NOT suitable for
|
||||||
|
glitch logic as it relies on specific ages
|
||||||
|
* In this chunk there are 3 possibilities for passing a check, but first I have to talk about parallel universes.
|
||||||
|
|
||||||
|
* In MQ Spirit key logic, we mostly care about 2 possibilities for how the player can spend keys, creating 2
|
||||||
|
Parralel universes
|
||||||
|
* In the first universe, the player did not enter spirit as adult until after climbing as child, thus child spends
|
||||||
|
keys linearly, only needing 2 to reach statue room.
|
||||||
|
* In the second universe, the player went in as adult, possibly out of logic, and started wasting the keys to lock
|
||||||
|
child out.
|
||||||
|
* These Universes converge when the player has 7 keys (meaning adult can no longer lock child out) and adult is
|
||||||
|
known to be able to reach Statue room. This creates "Certain Access", which is tracked seperatly for each age.
|
||||||
|
* Child Certain Access is simple, if we have 7 keys and child access, it's Certain Access.
|
||||||
|
* Adult Certain Access is also simple, adult is not key locked, so if they make it to a location, it's Certain
|
||||||
|
Access.
|
||||||
|
* Things get complicated when we handle the overlap of the 2 universes,
|
||||||
|
* though an important detail is that if we have Certain Access as either age, we don't need to checked the overlap
|
||||||
|
because overlap logic is strictly stricter than either Certain Access.
|
||||||
|
|
||||||
|
* In order to track the first universe, the logic allows technical child access with the minimum number of keys,
|
||||||
|
and then checks in this function for if we have 7 keys to determine if that is Certain or not.
|
||||||
|
* This is for technical reasons, as areas with no access at all will simply not be checked.
|
||||||
|
* Normally we would need to do similar shenanigans to track the second universe, however adult must have go through
|
||||||
|
statue room to waste keys,
|
||||||
|
* so can go back there and get new keys for Child to use if they do, and the navigation logic for shared MQ spirit
|
||||||
|
from Statue Room is very simple for Adult.
|
||||||
|
* Additionally, we don't need to know if adult can actually reach spirit temple or climb to statue room, because if
|
||||||
|
the player can't do that, then universe 2 can't happen anyway,
|
||||||
|
* and if the player does so out of logic, they can do it again, as the only consumable used sets a permanent flag.
|
||||||
|
|
||||||
|
* The Adult Navigation logic is as such:
|
||||||
|
* - Broken Wall room is 6 key locked, because if the player tries to spend 6 keys in a way that would block adults
|
||||||
|
access, they would have to give child access instead.
|
||||||
|
* - The child side hammer switch for the time travelling chest is 7 key locked for adult
|
||||||
|
* - Reaching gauntlets hand is 7 key locked
|
||||||
|
* - Going back into big block room is complex, but the only check there is child only so not a concern
|
||||||
|
* - Everything else is possible with basic adult movement, or is impossible for child to reach glitchlessly
|
||||||
|
* Anything 7 key locked does not need to be checked as shared, as all child access is Certain and because of this
|
||||||
|
workaround we don't need to fake Adult access, meaning that is also Certain.
|
||||||
|
* All of this combined means that when checking if adult can reach a location in universe 2, we only have to ask if
|
||||||
|
it is a 6 key locked location or not.
|
||||||
|
|
||||||
|
* Knowing all of this this, we can confirm things are logical in 3 different ways:
|
||||||
|
* - If we have Adult Access, we know it is Certain Access, so they can get checks alone.
|
||||||
|
* - If we have 7 keys, child has Certain Access as we know they cannot be locked out, so can get checks alone,
|
||||||
|
otherwise we check the logical overlap
|
||||||
|
* - If Child and Adult can get the check (ignoring actual adult access to the location), and the location is either
|
||||||
|
not 6 key locked or we have 6 keys, we can get the check with the overlap
|
||||||
|
*/
|
||||||
|
bool Region::MQSpiritShared(ConditionFn condition, bool IsBrokenWall, bool anyAge) {
|
||||||
|
// if we have Certain Access as child, we can check anyAge and if true, resolve a condition with Here as if
|
||||||
|
// adult is here it's also Certain Access
|
||||||
|
if (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)) {
|
||||||
|
if (anyAge) {
|
||||||
|
return Here(condition);
|
||||||
|
}
|
||||||
|
return condition();
|
||||||
|
// else, if we are here as adult, we have Certain Access from that and don't need special handling for
|
||||||
|
// checking adult
|
||||||
|
} else if (Adult() && logic->IsAdult) {
|
||||||
|
return condition();
|
||||||
|
// if we do not have Certain Access, we need to check the overlap by seeing if we are both here as child and
|
||||||
|
// meet the adult universe's access condition We only need to do it as child, as only child access matters
|
||||||
|
// for this check, as adult access is assumed based on keys
|
||||||
|
} else if (Child() && logic->IsChild && (!IsBrokenWall || logic->SmallKeys(RR_SPIRIT_TEMPLE, 6))) {
|
||||||
|
bool result = false;
|
||||||
|
// store current age variables
|
||||||
|
bool pastAdult = logic->IsAdult;
|
||||||
|
bool pastChild = logic->IsChild;
|
||||||
|
|
||||||
|
// First check if the check is possible as child
|
||||||
|
logic->IsChild = true;
|
||||||
|
logic->IsAdult = false;
|
||||||
|
result = condition();
|
||||||
|
// If so, check again as adult. both have to be true for result to be true
|
||||||
|
if (result) {
|
||||||
|
logic->IsChild = false;
|
||||||
|
logic->IsAdult = true;
|
||||||
|
result = condition();
|
||||||
|
}
|
||||||
|
|
||||||
|
// set back age variables
|
||||||
|
logic->IsChild = pastChild;
|
||||||
|
logic->IsAdult = pastAdult;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Region::printAgeTimeAccess() {
|
||||||
|
auto message = "Child Day: " + std::to_string(childDay) +
|
||||||
|
"\t"
|
||||||
|
"Child Night: " +
|
||||||
|
std::to_string(childNight) +
|
||||||
|
"\t"
|
||||||
|
"Adult Day: " +
|
||||||
|
std::to_string(adultDay) +
|
||||||
|
"\t"
|
||||||
|
"Adult Night: " +
|
||||||
|
std::to_string(adultNight);
|
||||||
|
}
|
||||||
|
|
||||||
std::array<Region, RR_MAX> areaTable;
|
std::array<Region, RR_MAX> areaTable;
|
||||||
|
|
||||||
bool Here(const RandomizerRegion region, ConditionFn condition) {
|
bool Here(const RandomizerRegion region, ConditionFn condition) {
|
||||||
|
|
|
@ -35,17 +35,7 @@ class EventAccess {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckConditionAtAgeTime(bool& age, bool& time) {
|
bool CheckConditionAtAgeTime(bool& age, bool& time);
|
||||||
logic->IsChild = false;
|
|
||||||
logic->IsAdult = false;
|
|
||||||
logic->AtDay = false;
|
|
||||||
logic->AtNight = false;
|
|
||||||
|
|
||||||
time = true;
|
|
||||||
age = true;
|
|
||||||
|
|
||||||
return ConditionsMet();
|
|
||||||
}
|
|
||||||
|
|
||||||
void EventOccurred() {
|
void EventOccurred() {
|
||||||
*event = true;
|
*event = true;
|
||||||
|
@ -232,7 +222,7 @@ class Region {
|
||||||
logic->IsChild = Child();
|
logic->IsChild = Child();
|
||||||
logic->IsAdult = Adult();
|
logic->IsAdult = Adult();
|
||||||
|
|
||||||
// heck condition as well as having at least child or adult access
|
// check condition as well as having at least child or adult access
|
||||||
bool hereVal = condition() && (logic->IsAdult || logic->IsChild);
|
bool hereVal = condition() && (logic->IsAdult || logic->IsChild);
|
||||||
|
|
||||||
// set back age variables
|
// set back age variables
|
||||||
|
@ -244,23 +234,11 @@ class Region {
|
||||||
|
|
||||||
bool CanPlantBeanCheck() const;
|
bool CanPlantBeanCheck() const;
|
||||||
bool AllAccountedFor() const;
|
bool AllAccountedFor() const;
|
||||||
|
bool MQSpiritShared(ConditionFn condition, bool IsBrokenWall, bool anyAge = false);
|
||||||
|
|
||||||
void ResetVariables();
|
void ResetVariables();
|
||||||
|
|
||||||
void printAgeTimeAccess() const {
|
void printAgeTimeAccess();
|
||||||
auto message = "Child Day: " + std::to_string(childDay) +
|
|
||||||
"\t"
|
|
||||||
"Child Night: " +
|
|
||||||
std::to_string(childNight) +
|
|
||||||
"\t"
|
|
||||||
"Adult Day: " +
|
|
||||||
std::to_string(adultDay) +
|
|
||||||
"\t"
|
|
||||||
"Adult Night: " +
|
|
||||||
std::to_string(adultNight);
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::map<RandomizerRegion, SpiritLogicData> spiritLogicData;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::array<Region, RR_MAX> areaTable;
|
extern std::array<Region, RR_MAX> areaTable;
|
||||||
|
|
|
@ -11,7 +11,7 @@ void RegionTable_Init_GerudoTrainingGround() {
|
||||||
//Exits
|
//Exits
|
||||||
Entrance(RR_GERUDO_TRAINING_GROUND_LOBBY, []{return ctx->GetDungeon(GERUDO_TRAINING_GROUND)->IsVanilla();}),
|
Entrance(RR_GERUDO_TRAINING_GROUND_LOBBY, []{return ctx->GetDungeon(GERUDO_TRAINING_GROUND)->IsVanilla();}),
|
||||||
Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, []{return ctx->GetDungeon(GERUDO_TRAINING_GROUND)->IsMQ();}),
|
Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, []{return ctx->GetDungeon(GERUDO_TRAINING_GROUND)->IsMQ();}),
|
||||||
Entrance(RR_GF_OUTSIDE_GTG, []{return true;}),
|
Entrance(RR_GF_EXITING_GTG, []{return true;}),
|
||||||
});
|
});
|
||||||
|
|
||||||
#pragma region Vanilla
|
#pragma region Vanilla
|
||||||
|
|
|
@ -49,15 +49,26 @@ void RegionTable_Init_GerudoFortress() {
|
||||||
EventAccess(&logic->GtG_GateOpen, []{return (logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->HasItem(RG_CHILD_WALLET));}),
|
EventAccess(&logic->GtG_GateOpen, []{return (logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->HasItem(RG_CHILD_WALLET));}),
|
||||||
}, {}, {
|
}, {}, {
|
||||||
//Exits
|
//Exits
|
||||||
Entrance(RR_GERUDO_TRAINING_GROUND_ENTRYWAY, []{return logic->GtG_GateOpen && (logic->IsAdult || ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES));}),
|
Entrance(RR_GF_TO_GTG, []{return logic->GtG_GateOpen && (logic->IsAdult || ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES));}),
|
||||||
//Jail
|
//Jail
|
||||||
|
Entrance(RR_GF_JAIL_WINDOW, []{return logic->CanUse(RG_HOOKSHOT);}),
|
||||||
|
Entrance(RR_GF_OUTSKIRTS, []{return true;}),
|
||||||
|
Entrance(RR_GF_NEAR_GROTTO, []{return logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD);}),
|
||||||
|
// RANDTODO: Add tricks for getting past the gerudo guarding the hba range
|
||||||
|
Entrance(RR_GF_ABOVE_GTG, []{return logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD);}),
|
||||||
|
Entrance(RR_GF_TOP_OF_UPPER_VINES, []{return logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_LONGSHOT);}),
|
||||||
|
Entrance(RR_GF_HBA_RANGE, []{return logic->IsChild || logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD);}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_GF_TO_GTG] = Region("GF to GTG", SCENE_GERUDOS_FORTRESS, {}, {}, {
|
||||||
|
Entrance(RR_GERUDO_TRAINING_GROUND_ENTRYWAY, []{return true;}),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Split out to handle adult being immediately captured without card
|
||||||
|
areaTable[RR_GF_EXITING_GTG] = Region("GF Exiting GTG", SCENE_GERUDOS_FORTRESS, {}, {}, {
|
||||||
|
Entrance(RR_GF_OUTSIDE_GTG, []{return logic->IsChild || logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD);}),
|
||||||
Entrance(RR_GF_JAIL_WINDOW, []{return logic->CanUse(RG_HOOKSHOT);}),
|
Entrance(RR_GF_JAIL_WINDOW, []{return logic->CanUse(RG_HOOKSHOT);}),
|
||||||
Entrance(RR_GF_OUTSKIRTS, []{return true;}),
|
Entrance(RR_GF_OUTSKIRTS, []{return true;}),
|
||||||
Entrance(RR_GF_NEAR_GROTTO, []{return logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD);}),
|
|
||||||
// RANDTODO: Add tricks for getting past the gerudo guarding the hba range
|
|
||||||
Entrance(RR_GF_ABOVE_GTG, []{return logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD);}),
|
|
||||||
Entrance(RR_GF_TOP_OF_UPPER_VINES, []{return logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_LONGSHOT);}),
|
|
||||||
Entrance(RR_GF_HBA_RANGE, []{return logic->IsChild || logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD);}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
@ -123,6 +134,7 @@ void RegionTable_Init_GerudoFortress() {
|
||||||
Entrance(RR_GF_TOP_OF_LOWER_VINES, []{return true;}),
|
Entrance(RR_GF_TOP_OF_LOWER_VINES, []{return true;}),
|
||||||
Entrance(RR_GF_SLOPED_ROOF, []{return logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS);}),
|
Entrance(RR_GF_SLOPED_ROOF, []{return logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS);}),
|
||||||
Entrance(RR_GF_TOP_OF_UPPER_VINES, []{return true /* logic->CanClimb() */;}),
|
Entrance(RR_GF_TOP_OF_UPPER_VINES, []{return true /* logic->CanClimb() */;}),
|
||||||
|
Entrance(RR_GF_TO_GTG, []{return logic->IsAdult && ctx->GetTrickOption(RT_GF_LEDGE_CLIP_INTO_GTG).Get();}),
|
||||||
});
|
});
|
||||||
|
|
||||||
areaTable[RR_GF_TOP_OF_UPPER_VINES] = Region("GF Top of Upper Vines", SCENE_GERUDOS_FORTRESS, {}, {
|
areaTable[RR_GF_TOP_OF_UPPER_VINES] = Region("GF Top of Upper Vines", SCENE_GERUDOS_FORTRESS, {}, {
|
||||||
|
|
|
@ -423,6 +423,8 @@ typedef enum {
|
||||||
RR_GF_OUTSKIRTS,
|
RR_GF_OUTSKIRTS,
|
||||||
RR_GF_NEAR_GROTTO,
|
RR_GF_NEAR_GROTTO,
|
||||||
RR_GF_OUTSIDE_GTG,
|
RR_GF_OUTSIDE_GTG,
|
||||||
|
RR_GF_TO_GTG,
|
||||||
|
RR_GF_EXITING_GTG,
|
||||||
RR_GF_ABOVE_GTG,
|
RR_GF_ABOVE_GTG,
|
||||||
RR_GF_BOTTOM_OF_LOWER_VINES,
|
RR_GF_BOTTOM_OF_LOWER_VINES,
|
||||||
RR_GF_TOP_OF_LOWER_VINES,
|
RR_GF_TOP_OF_LOWER_VINES,
|
||||||
|
@ -3634,6 +3636,7 @@ typedef enum {
|
||||||
RT_PASS_GUARDS_WITH_NOTHING,
|
RT_PASS_GUARDS_WITH_NOTHING,
|
||||||
RT_GF_JUMP,
|
RT_GF_JUMP,
|
||||||
RT_GF_WARRIOR_WITH_DIFFICULT_WEAPON,
|
RT_GF_WARRIOR_WITH_DIFFICULT_WEAPON,
|
||||||
|
RT_GF_LEDGE_CLIP_INTO_GTG,
|
||||||
RT_HW_BUNNY_CROSSING,
|
RT_HW_BUNNY_CROSSING,
|
||||||
RT_HW_CROSSING,
|
RT_HW_CROSSING,
|
||||||
RT_LENS_HW,
|
RT_LENS_HW,
|
||||||
|
|
|
@ -696,9 +696,9 @@ void DrawQuest(ItemTrackerItem item) {
|
||||||
bool hasQuestItem = HasQuestItem(item);
|
bool hasQuestItem = HasQuestItem(item);
|
||||||
float iconSize = static_cast<float>(CVarGetInteger(CVAR_TRACKER_ITEM("IconSize"), 36));
|
float iconSize = static_cast<float>(CVarGetInteger(CVAR_TRACKER_ITEM("IconSize"), 36));
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(
|
ImGui::ImageWithBg(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(
|
||||||
hasQuestItem && IsValidSaveFile() ? item.name : item.nameFaded),
|
hasQuestItem && IsValidSaveFile() ? item.name : item.nameFaded),
|
||||||
ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1));
|
ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1));
|
||||||
|
|
||||||
if (item.id == QUEST_SKULL_TOKEN) {
|
if (item.id == QUEST_SKULL_TOKEN) {
|
||||||
DrawItemCount(item, false);
|
DrawItemCount(item, false);
|
||||||
|
@ -1231,7 +1231,7 @@ void DrawItemsInACircle(std::vector<ItemTrackerItem> items) {
|
||||||
float radius = (iconSize + iconSpacing) * 2.0f;
|
float radius = (iconSize + iconSpacing) * 2.0f;
|
||||||
|
|
||||||
for (int i = 0; i < items.size(); i++) {
|
for (int i = 0; i < items.size(); i++) {
|
||||||
float angle = static_cast<float>(i / items.size() * 2.0f * M_PI);
|
float angle = static_cast<float>(i) / items.size() * 2.0f * M_PIf;
|
||||||
float x = (radius / 2.0f) * cos(angle) + max.x / 2.0f;
|
float x = (radius / 2.0f) * cos(angle) + max.x / 2.0f;
|
||||||
float y = (radius / 2.0f) * sin(angle) + max.y / 2.0f;
|
float y = (radius / 2.0f) * sin(angle) + max.y / 2.0f;
|
||||||
ImGui::SetCursorPos(ImVec2(x - (CVarGetInteger(CVAR_TRACKER_ITEM("IconSize"), 36) - 8) / 2.0f, y + 4));
|
ImGui::SetCursorPos(ImVec2(x - (CVarGetInteger(CVAR_TRACKER_ITEM("IconSize"), 36) - 8) / 2.0f, y + 4));
|
||||||
|
|
|
@ -595,6 +595,9 @@ void Settings::CreateOptions() {
|
||||||
OPT_TRICK(RT_GF_WARRIOR_WITH_DIFFICULT_WEAPON, RCQUEST_BOTH, RA_GERUDO_FORTRESS, { Tricks::Tag::NOVICE },
|
OPT_TRICK(RT_GF_WARRIOR_WITH_DIFFICULT_WEAPON, RCQUEST_BOTH, RA_GERUDO_FORTRESS, { Tricks::Tag::NOVICE },
|
||||||
"Gerudo\'s Fortress Warriors with Difficult Weapons",
|
"Gerudo\'s Fortress Warriors with Difficult Weapons",
|
||||||
"Warriors can be defeated with Slingshot or Bombchus.");
|
"Warriors can be defeated with Slingshot or Bombchus.");
|
||||||
|
OPT_TRICK(RT_GF_LEDGE_CLIP_INTO_GTG, RCQUEST_BOTH, RA_GERUDO_FORTRESS, { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH },
|
||||||
|
"Ledge Clip into Training Ground",
|
||||||
|
"Adult Link can use a ledge clip to enter Gerudo Training Ground without Gerudo Card.");
|
||||||
// disabled for now, can't check for being able to use bunny hood & bunny hood speedup is currently completely
|
// disabled for now, can't check for being able to use bunny hood & bunny hood speedup is currently completely
|
||||||
// decoupled from rando OPT_TRICK(RT_HW_BUNNY_CROSSING, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, {Tricks::Tag::NOVICE},
|
// decoupled from rando OPT_TRICK(RT_HW_BUNNY_CROSSING, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, {Tricks::Tag::NOVICE},
|
||||||
// "Wasteland Crossing with Bunny Hood", "You can beat the quicksand by using the increased speed of the Bunny Hood.
|
// "Wasteland Crossing with Bunny Hood", "You can beat the quicksand by using the increased speed of the Bunny Hood.
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
|
#include <vector>
|
||||||
|
#include <fstream>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
#include "TimeSplits.h"
|
#include "TimeSplits.h"
|
||||||
#include "soh/Enhancements/gameplaystats.h"
|
#include "soh/Enhancements/gameplaystats.h"
|
||||||
#include "soh/SaveManager.h"
|
#include "soh/SaveManager.h"
|
||||||
#include "soh/util.h"
|
#include "soh/util.h"
|
||||||
#include <vector>
|
|
||||||
#include "include/z64item.h"
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
#include "soh/OTRGlobals.h"
|
#include "soh/OTRGlobals.h"
|
||||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||||
|
@ -17,6 +16,7 @@
|
||||||
#include "soh/SohGui/UIWidgets.hpp"
|
#include "soh/SohGui/UIWidgets.hpp"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
#include "z64item.h"
|
||||||
extern SaveContext gSaveContext;
|
extern SaveContext gSaveContext;
|
||||||
extern PlayState* gPlayState;
|
extern PlayState* gPlayState;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,17 +3,6 @@
|
||||||
#define TIMESPLITS_H
|
#define TIMESPLITS_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // TIMESPLITS_H
|
|
||||||
|
|
||||||
#include <libultraship/libultraship.h>
|
#include <libultraship/libultraship.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -66,3 +55,5 @@ typedef struct {
|
||||||
} SplitObject;
|
} SplitObject;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif // TIMESPLITS_H
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue