Files
Shiip-of-Hakinian-Espanol/soh/soh/Enhancements/randomizer/3drando/location_access.hpp
Christopher Leggett 92028aa8d8 Rando Definition Deduplication (#3284)
* Initial StaticData and RandoItem class definitions

* Initial implementation of RandoItem class.

* Rerranges RandoItem Constructor parameters

The parameters were rearranged for easy copy-paste from the GET_ITEM macro calls later on.

* Switches static data from map to static array.

Array is all that is needed, since the item list will be contiguous and indexed by the RandomizerGet Enum values.

* Defines part of the randomizer item list.

* Adds more item class instances to item_list.cpp

Up through bottles, many more items still to go.

* Adds song items

* Adds Maps and Compasses to the item_list

* Added Key Items to item_list

* Added Key Rings to item_list

* Added Dungeon Rewards to item_list

* Adds generic items and refills to item_list

* Adds shop items, triforce, and hints

Also added constructors that put the GET_ITEM_NONE data in for these items, since there is no corresponding GetItemEntry for them.

* Adds in the stages of progressive items

These are present for GetItemEntry purposes, and aren't really meant to be used in seed generation (unless we find a need for it later on.)

* Remove GetItemEntry data from progressive items

* Moves/adds function definitions to item/item_list

* Refactors GetItemEntry data

It's now a pointer to memory instantiated on the heap in the constructor. These are shared pointers so the memory is freed if any of the item instances get deconstructed (which they shouldn't but just in case.)

* Adds item class member for if item is progressive

* Removes unneeded stuff from initializer list macro

* Replaces relevant `uint32_t`s w/ `RandomizerGet`s

Also replaces calls to the ItemTable method with StaticData::RetrieveItem

* Switches our runtime code to use the new itemList.

* Changes just enough hint gen code to compile

* Initial Definition of Location Class

* Initial Implementation of Location

* Fixes some names and definitions.

* Extracts ActorID and SceneID enums to separate files.

This allows importing them without causing weird conflicts in cpp files when importing the z64scene.h and z64actor.h files directly. Now you can just import z64scene_enum.h and z64actor_enum.h instead. The two old files also import these new files so that existing setups still work as expected.

* Replaces the forward definitions with the new imports.

* Adds missing data for RandomizerCheckObjects.

* Definition and first entry of locationTable

* Added Mido's House Locations

* Added locations up through lost woods.

* Adds in Hyrule Field locations.

* Adds Lake Hylia locations

* Adds location name comments

* Adds Gerudo Valley Locations

* Adds Gerudo Fortress locations.

* Adds the Wasteland and Collosus locations

* Adds Market locations

* Adds Hyrule Castle locations.

* Adds Kakariko and Graveyard locations.

* Adds Death Mountain checks.

* Adds Goron City locations

* Adds Death Mountain Crater locations

* Adds Zora's River locations

* Added Zora's Domain Locations.

* Added Zora's Fountain locations

* Adds Lon Lon Ranch locations.

* Adds Deku Tree locations

* Adds Dodongo's Cavern Locations.

* Adds Jabu Jabu's Belly Locations

* Adds Forest Temple Locations

* Adds Fire Temple Locations

* Adds Water Temple Locations

* Added Spirit Temple Locations

* Some of shadow temple locations.

* Adds remaining Shadow Temple locations

* Fixes a leftover merge conflict

* Adds Bottom of the Well locations.

* Adds Ice Cavern locations

* Adds GTG locations.

* Adds Ganon's Castle and Tower locations

* Adds dungeon Gold Skulltula locations.

* Adds Overworld Gold Skulltula locations

* Adds dungeon reward locations

* Adds Heart Container Locations

* Adds Cutscene and Song locations

* Adds Cow locations

* Adds Shop locations.

* Adds hint locations

* Adds function for retrieving the Location data.

* Initial definition of ItemLocation structure for tracking runtime data

* First push on converting code to use new location definitions

* Changes hints to use the new tables

* Further conversion of hints to new definitions.

* Adds new Hint and Location IDs to area tables

* Moves areaTable to use new RandomizerRegion keys

* Removal of 3drando/item_location files.

* Uses new RandomizerRegion keys in entrance.cpp

* Final push for removal of massive keys.hpp enum

* Uses new SceneID Enum Values

* Remove RandomizerCheckObject structs in favor of new location list.

* Fix a few stragglers to successfully build

* Rename of RandoItem to just Item, but in the Rando namespace

* Adds static hints (Light Arrows, Altar text, etc) to the new Hint table.

* More hint related fixes/edits

* small fix for #include path

* Fix various miscellaneous issues related to seed gen and spoiler parsing.

* Handle progressive items correctly.

* Fixes some hint generation logic

* Fix a few GetItemEntry niche bugs.

* Adds missing shop GI Entries

* Formatting fixes

* small formatting fix

* Namespace StaticData under Rando

* Added a note about a potential use-after-free.

I confirmed the actual pointer in question isn't currently being used, but I added the note as a reminder to fix it later and/or as a warning to anyone who changes how the return value is used.

* Fixes missing location table entries

* Fixes LUS submodule and removes now-unused code

* Resolves weird duplicate definition issue

* Fix missing include

It was missed because not being included wasn't an issue on Windows.

* Fixes error present on Linux builds

* Fixes some issues with excluding locations

* Updates the Resolve Exclusion conflicts function

not sure if actually used, will look into that more later

* Removes some duplicate RGs

* More fixes of duplicate RG values.

* Fix a few duplication issues in the check tracker.

* Fix progressive bombchus.

* Minor typo fix, shouldn't really be affecting anything though

* Should fix some of the remaining check tracker issues.

* oops wrong boolean operator

* Fix skulltulas in the check tracker.

* oops, missing comma

* re-formatting of HintStone locations

* Fixes issue when picking up second Progressive Bullet Bag

* Hide bombchu bowling bombchus

* Fixes missed skullScene in location_list

* Reformats shop items

* Re-formats cow checks

* reformat song locations

* reformat "cutscene" checks

* reformat heart container locaitons

* reformat Boss/Dungeon reward checks

* Hide Triforce Completed if not playing Triforce Hunt

* Fixes incorrect chest param

* reformat GS Tokens locations and cuts down on duplicate data

* reformat Ganons Castle checks

* reformat GTG check locations

* Prevents Gift from Raoru from appearing in the check tracker

* more reformatting (botw, ice cavern, shadow temple)

* Should fix a couple more check tracker checks

* reformat spirit temple checks

* reformat water and fire temple checks

* fix RC_ZR_GS_ABOVE_BRIDGE flag typo

* reformat Forest Temple checks

* Fix RC_LW_TRADE_ODD_POTION in check tracker

* reformat child dungeon locations

* reformat overworld locations

* reformat item entries
2023-10-19 18:48:25 -05:00

266 lines
7.4 KiB
C++

#pragma once
#include <string>
#include <vector>
#include <list>
#include "logic.hpp"
#include "hint_list.hpp"
#include "fill.hpp"
typedef bool (*ConditionFn)();
class EventAccess {
public:
explicit EventAccess(bool* event_, std::vector<ConditionFn> conditions_met_)
: event(event_) {
conditions_met.resize(2);
for (size_t i = 0; i < conditions_met_.size(); i++) {
conditions_met[i] = conditions_met_[i];
}
}
bool ConditionsMet() const {
if (Settings::Logic.Is(LOGIC_NONE) || Settings::Logic.Is(LOGIC_VANILLA)) {
return true;
} else if (Settings::Logic.Is(LOGIC_GLITCHLESS)) {
return conditions_met[0]();
} else if (Settings::Logic.Is(LOGIC_GLITCHED)) {
if (conditions_met[0]()) {
return true;
} else if (conditions_met[1] != NULL) {
return conditions_met[1]();
}
}
return false;
}
bool CheckConditionAtAgeTime(bool& age, bool& time) {
Logic::IsChild = false;
Logic::IsAdult = false;
Logic::AtDay = false;
Logic::AtNight = false;
time = true;
age = true;
Logic::UpdateHelpers();
return ConditionsMet();
}
void EventOccurred() {
*event = true;
}
bool GetEvent() const {
return *event;
}
private:
bool* event;
std::vector<ConditionFn> conditions_met;
};
//this class is meant to hold an item location with a boolean function to determine its accessibility from a specific area
class LocationAccess {
public:
explicit LocationAccess(RandomizerCheck location_, std::vector<ConditionFn> conditions_met_)
: location(location_) {
conditions_met.resize(2);
for (size_t i = 0; i < conditions_met_.size(); i++) {
conditions_met[i] = conditions_met_[i];
}
}
bool GetConditionsMet() const {
if (Settings::Logic.Is(LOGIC_NONE) || Settings::Logic.Is(LOGIC_VANILLA)) {
return true;
} else if (Settings::Logic.Is(LOGIC_GLITCHLESS)) {
return conditions_met[0]();
} else if (Settings::Logic.Is(LOGIC_GLITCHED)) {
if (conditions_met[0]()) {
return true;
} else if (conditions_met[1] != NULL) {
return conditions_met[1]();
}
}
return false;
}
bool CheckConditionAtAgeTime(bool& age, bool& time) const;
bool ConditionsMet() const;
RandomizerCheck GetLocation() const {
return location;
}
protected:
RandomizerCheck location;
std::vector<ConditionFn> conditions_met;
//Makes sure shop locations are buyable
bool CanBuy() const;
};
class Entrance;
enum class EntranceType;
class Area {
public:
Area();
Area(std::string regionName_, std::string scene_, RandomizerHintTextKey hintKey_,
bool timePass_,
std::vector<EventAccess> events_,
std::vector<LocationAccess> locations_,
std::list<Entrance> exits_);
~Area();
std::string regionName;
std::string scene;
RandomizerHintTextKey hintKey;
bool timePass;
std::vector<EventAccess> events;
std::vector<LocationAccess> locations;
std::list<Entrance> exits;
std::list<Entrance*> entrances;
//^ The above exits are now stored in a list instead of a vector because
//the entrance randomization algorithm plays around with pointers to these
//entrances a lot. By putting the entrances in a list, we don't have to
//worry about a vector potentially reallocating itself and invalidating all our
//entrance pointers.
bool childDay = false;
bool childNight = false;
bool adultDay = false;
bool adultNight = false;
bool addedToPool = false;
bool UpdateEvents(SearchMode mode);
void AddExit(RandomizerRegion parentKey, RandomizerRegion newExitKey, ConditionFn condition);
void RemoveExit(Entrance* exitToRemove);
void SetAsPrimary(RandomizerRegion exitToBePrimary);
Entrance* GetExit(RandomizerRegion exit);
bool Child() const {
return childDay || childNight;
}
bool Adult() const {
return adultDay || adultNight;
}
bool BothAgesCheck() const {
return Child() && Adult();
}
bool HasAccess() const {
return Child() || Adult();
}
bool AllAccess() const {
return childDay && childNight && adultDay && adultNight;
}
//Check to see if an exit can be access as both ages at both times of day
bool CheckAllAccess(RandomizerRegion exitKey);
const HintText& GetHint() const {
return Hint(hintKey);
}
//Here checks conditional access based on whether or not both ages have
//access to this area. For example: if there are rocks that block a path
//which both child and adult can access, adult having hammer can give
//both child and adult access to the path.
bool HereCheck(ConditionFn condition) {
//store current age variables
bool pastAdult = Logic::IsAdult;
bool pastChild = Logic::IsChild;
//set age access as this areas ages
Logic::IsChild = Child();
Logic::IsAdult = Adult();
//update helpers and check condition as well as having at least child or adult access
Logic::UpdateHelpers();
bool hereVal = condition() && (Logic::IsAdult || Logic::IsChild);
//set back age variables
Logic::IsChild = pastChild;
Logic::IsAdult = pastAdult;
Logic::UpdateHelpers();
return hereVal;
}
bool CanPlantBeanCheck() const;
bool AllAccountedFor() const;
void ResetVariables();
void printAgeTimeAccess() const {
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);
//CitraPrint(message);
}
};
extern std::array<Area, RR_MAX> areaTable;
extern std::vector<EventAccess> grottoEvents;
bool Here(const RandomizerRegion area, ConditionFn condition);
bool CanPlantBean(const RandomizerRegion area);
bool BothAges(const RandomizerRegion area);
bool ChildCanAccess(const RandomizerRegion area);
bool AdultCanAccess(const RandomizerRegion area);
bool HasAccessTo(const RandomizerRegion area);
#define DAY_NIGHT_CYCLE true
#define NO_DAY_NIGHT_CYCLE false
namespace Areas {
extern void AccessReset();
extern void ResetAllLocations();
extern bool HasTimePassAccess(uint8_t age);
extern void DumpWorldGraph(std::string str);
} //namespace Exits
void AreaTable_Init();
Area* AreaTable(const RandomizerRegion areaKey);
std::vector<Entrance*> GetShuffleableEntrances(EntranceType type, bool onlyPrimary = true);
// Overworld
void AreaTable_Init_LostWoods();
void AreaTable_Init_HyruleField();
void AreaTable_Init_CastleTown();
void AreaTable_Init_Kakariko();
void AreaTable_Init_DeathMountain();
void AreaTable_Init_ZorasDomain();
void AreaTable_Init_GerudoValley();
// Dungeons
void AreaTable_Init_DekuTree();
void AreaTable_Init_DodongosCavern();
void AreaTable_Init_JabuJabusBelly();
void AreaTable_Init_ForestTemple();
void AreaTable_Init_FireTemple();
void AreaTable_Init_WaterTemple();
void AreaTable_Init_SpiritTemple();
void AreaTable_Init_ShadowTemple();
void AreaTable_Init_BottomOfTheWell();
void AreaTable_Init_IceCavern();
void AreaTable_Init_GerudoTrainingGrounds();
void AreaTable_Init_GanonsCastle();