mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-10-31 23:55:06 -04:00
fix selection only and make MQ dungeon settings set themselves more smartley (#4232)
This commit is contained in:
parent
a5c0cede12
commit
7595a5a65e
@ -30,6 +30,7 @@ const auto& RandomElement(const Container& container) {
|
||||
}
|
||||
|
||||
//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++)
|
||||
|
@ -8,10 +8,12 @@ namespace Rando {
|
||||
DungeonInfo::DungeonInfo(std::string name_, const RandomizerHintTextKey hintKey_, const RandomizerGet map_,
|
||||
const RandomizerGet compass_, const RandomizerGet smallKey_, const RandomizerGet keyRing_,
|
||||
const RandomizerGet bossKey_, RandomizerArea area_, const uint8_t vanillaKeyCount_, const uint8_t mqKeyCount_,
|
||||
const RandomizerSettingKey mqSetting_,
|
||||
std::vector<RandomizerCheck> vanillaLocations_, std::vector<RandomizerCheck> mqLocations_,
|
||||
std::vector<RandomizerCheck> sharedLocations_, std::vector<RandomizerCheck> bossRoomLocations_)
|
||||
: name(std::move(name_)), hintKey(hintKey_), map(map_), compass(compass_), smallKey(smallKey_), keyRing(keyRing_),
|
||||
bossKey(bossKey_), area(area_), vanillaKeyCount(vanillaKeyCount_), mqKeyCount(mqKeyCount_),
|
||||
mqSetting(mqSetting_),
|
||||
vanillaLocations(std::move(vanillaLocations_)), mqLocations(std::move(mqLocations_)),
|
||||
sharedLocations(std::move(sharedLocations_)), bossRoomLocations(std::move(bossRoomLocations_)) {
|
||||
}
|
||||
@ -83,6 +85,14 @@ RandomizerGet DungeonInfo::GetBossKey() const {
|
||||
return bossKey;
|
||||
}
|
||||
|
||||
RandomizerSettingKey DungeonInfo::GetMQSetting() const {
|
||||
return mqSetting;
|
||||
}
|
||||
|
||||
void DungeonInfo::SetDungeonKnown(bool known) {
|
||||
isDungeonModeKnown = known;
|
||||
}
|
||||
|
||||
void DungeonInfo::PlaceVanillaMap() const {
|
||||
if (map == RG_NONE) {
|
||||
return;
|
||||
@ -152,7 +162,7 @@ std::vector<RandomizerCheck> DungeonInfo::GetEveryLocation() const {
|
||||
|
||||
Dungeons::Dungeons() {
|
||||
dungeonList[DEKU_TREE] =
|
||||
DungeonInfo("Deku Tree", RHT_DEKU_TREE, RG_DEKU_TREE_MAP, RG_DEKU_TREE_COMPASS, RG_NONE, RG_NONE, RG_NONE, RA_DEKU_TREE, 0, 0,
|
||||
DungeonInfo("Deku Tree", RHT_DEKU_TREE, RG_DEKU_TREE_MAP, RG_DEKU_TREE_COMPASS, RG_NONE, RG_NONE, RG_NONE, RA_DEKU_TREE, 0, 0, RSK_MQ_DEKU_TREE,
|
||||
{
|
||||
// Vanilla Locations
|
||||
RC_DEKU_TREE_MAP_CHEST,
|
||||
@ -188,7 +198,7 @@ Dungeons::Dungeons() {
|
||||
RC_QUEEN_GOHMA,
|
||||
});
|
||||
dungeonList[DODONGOS_CAVERN] = DungeonInfo("Dodongo's Cavern", RHT_DODONGOS_CAVERN, RG_DODONGOS_CAVERN_MAP,
|
||||
RG_DODONGOS_CAVERN_COMPASS, RG_NONE, RG_NONE, RG_NONE, RA_DODONGOS_CAVERN, 0, 0,
|
||||
RG_DODONGOS_CAVERN_COMPASS, RG_NONE, RG_NONE, RG_NONE, RA_DODONGOS_CAVERN, 0, 0, RSK_MQ_DODONGOS_CAVERN,
|
||||
{
|
||||
// Vanilla Locations
|
||||
RC_DODONGOS_CAVERN_MAP_CHEST,
|
||||
@ -232,7 +242,7 @@ Dungeons::Dungeons() {
|
||||
RC_KING_DODONGO,
|
||||
});
|
||||
dungeonList[JABU_JABUS_BELLY] = DungeonInfo("Jabu Jabu's Belly", RHT_JABU_JABUS_BELLY, RG_JABU_JABUS_BELLY_MAP,
|
||||
RG_JABU_JABUS_BELLY_COMPASS, RG_NONE, RG_NONE, RG_NONE, RA_JABU_JABUS_BELLY, 0, 0,
|
||||
RG_JABU_JABUS_BELLY_COMPASS, RG_NONE, RG_NONE, RG_NONE, RA_JABU_JABUS_BELLY, 0, 0, RSK_MQ_JABU_JABU,
|
||||
{
|
||||
// Vanilla Locations
|
||||
RC_JABU_JABUS_BELLY_MAP_CHEST,
|
||||
@ -271,7 +281,7 @@ Dungeons::Dungeons() {
|
||||
});
|
||||
dungeonList[FOREST_TEMPLE] =
|
||||
DungeonInfo("Forest Temple", RHT_FOREST_TEMPLE, RG_FOREST_TEMPLE_MAP, RG_FOREST_TEMPLE_COMPASS,
|
||||
RG_FOREST_TEMPLE_SMALL_KEY, RG_FOREST_TEMPLE_KEY_RING, RG_FOREST_TEMPLE_BOSS_KEY, RA_FOREST_TEMPLE, 5, 6,
|
||||
RG_FOREST_TEMPLE_SMALL_KEY, RG_FOREST_TEMPLE_KEY_RING, RG_FOREST_TEMPLE_BOSS_KEY, RA_FOREST_TEMPLE, 5, 6, RSK_MQ_FOREST_TEMPLE,
|
||||
{
|
||||
// Vanilla Locations
|
||||
RC_FOREST_TEMPLE_FIRST_ROOM_CHEST,
|
||||
@ -321,7 +331,7 @@ Dungeons::Dungeons() {
|
||||
});
|
||||
dungeonList[FIRE_TEMPLE] =
|
||||
DungeonInfo("Fire Temple", RHT_FIRE_TEMPLE, RG_FIRE_TEMPLE_MAP, RG_FIRE_TEMPLE_COMPASS,
|
||||
RG_FIRE_TEMPLE_SMALL_KEY, RG_FIRE_TEMPLE_KEY_RING, RG_FIRE_TEMPLE_BOSS_KEY, RA_FIRE_TEMPLE, 8, 5,
|
||||
RG_FIRE_TEMPLE_SMALL_KEY, RG_FIRE_TEMPLE_KEY_RING, RG_FIRE_TEMPLE_BOSS_KEY, RA_FIRE_TEMPLE, 8, 5, RSK_MQ_FIRE_TEMPLE,
|
||||
{
|
||||
// Vanilla Locations
|
||||
RC_FIRE_TEMPLE_NEAR_BOSS_CHEST,
|
||||
@ -372,7 +382,7 @@ Dungeons::Dungeons() {
|
||||
});
|
||||
dungeonList[WATER_TEMPLE] =
|
||||
DungeonInfo("Water Temple", RHT_WATER_TEMPLE, RG_WATER_TEMPLE_MAP, RG_WATER_TEMPLE_COMPASS,
|
||||
RG_WATER_TEMPLE_SMALL_KEY, RG_WATER_TEMPLE_KEY_RING, RG_WATER_TEMPLE_BOSS_KEY, RA_WATER_TEMPLE, 6, 2,
|
||||
RG_WATER_TEMPLE_SMALL_KEY, RG_WATER_TEMPLE_KEY_RING, RG_WATER_TEMPLE_BOSS_KEY, RA_WATER_TEMPLE, 6, 2, RSK_MQ_WATER_TEMPLE,
|
||||
{
|
||||
// Vanilla Locations
|
||||
RC_WATER_TEMPLE_MAP_CHEST,
|
||||
@ -413,7 +423,7 @@ Dungeons::Dungeons() {
|
||||
});
|
||||
dungeonList[SPIRIT_TEMPLE] =
|
||||
DungeonInfo("Spirit Temple", RHT_SPIRIT_TEMPLE, RG_SPIRIT_TEMPLE_MAP, RG_SPIRIT_TEMPLE_COMPASS,
|
||||
RG_SPIRIT_TEMPLE_SMALL_KEY, RG_SPIRIT_TEMPLE_KEY_RING, RG_SPIRIT_TEMPLE_BOSS_KEY, RA_SPIRIT_TEMPLE, 5, 7,
|
||||
RG_SPIRIT_TEMPLE_SMALL_KEY, RG_SPIRIT_TEMPLE_KEY_RING, RG_SPIRIT_TEMPLE_BOSS_KEY, RA_SPIRIT_TEMPLE, 5, 7, RSK_MQ_SPIRIT_TEMPLE,
|
||||
{
|
||||
// Vanilla Locations
|
||||
RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST,
|
||||
@ -479,7 +489,7 @@ Dungeons::Dungeons() {
|
||||
});
|
||||
dungeonList[SHADOW_TEMPLE] =
|
||||
DungeonInfo("Shadow Temple", RHT_SHADOW_TEMPLE, RG_SHADOW_TEMPLE_MAP, RG_SHADOW_TEMPLE_COMPASS,
|
||||
RG_SHADOW_TEMPLE_SMALL_KEY, RG_SHADOW_TEMPLE_KEY_RING, RG_SHADOW_TEMPLE_BOSS_KEY, RA_SHADOW_TEMPLE, 5, 6,
|
||||
RG_SHADOW_TEMPLE_SMALL_KEY, RG_SHADOW_TEMPLE_KEY_RING, RG_SHADOW_TEMPLE_BOSS_KEY, RA_SHADOW_TEMPLE, 5, 6, RSK_MQ_SHADOW_TEMPLE,
|
||||
{
|
||||
// Vanilla Locations
|
||||
RC_SHADOW_TEMPLE_MAP_CHEST,
|
||||
@ -541,7 +551,7 @@ Dungeons::Dungeons() {
|
||||
});
|
||||
dungeonList[BOTTOM_OF_THE_WELL] = DungeonInfo(
|
||||
"Bottom of the Well", RHT_BOTTOM_OF_THE_WELL, RG_BOTTOM_OF_THE_WELL_MAP, RG_BOTTOM_OF_THE_WELL_COMPASS,
|
||||
RG_BOTTOM_OF_THE_WELL_SMALL_KEY, RG_BOTTOM_OF_THE_WELL_KEY_RING, RG_NONE, RA_BOTTOM_OF_THE_WELL, 3, 2,
|
||||
RG_BOTTOM_OF_THE_WELL_SMALL_KEY, RG_BOTTOM_OF_THE_WELL_KEY_RING, RG_NONE, RA_BOTTOM_OF_THE_WELL, 3, 2, RSK_MQ_BOTTOM_OF_THE_WELL,
|
||||
{
|
||||
// Vanilla Locations
|
||||
RC_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST,
|
||||
@ -575,7 +585,7 @@ Dungeons::Dungeons() {
|
||||
},
|
||||
{}, {});
|
||||
dungeonList[ICE_CAVERN] = DungeonInfo("Ice Cavern", RHT_ICE_CAVERN, RG_ICE_CAVERN_MAP, RG_ICE_CAVERN_COMPASS,
|
||||
RG_NONE, RG_NONE, RG_NONE, RA_ICE_CAVERN, 0, 0,
|
||||
RG_NONE, RG_NONE, RG_NONE, RA_ICE_CAVERN, 0, 0, RSK_MQ_ICE_CAVERN,
|
||||
{
|
||||
// Vanilla Locations
|
||||
RC_ICE_CAVERN_MAP_CHEST,
|
||||
@ -603,7 +613,7 @@ Dungeons::Dungeons() {
|
||||
{});
|
||||
dungeonList[GERUDO_TRAINING_GROUNDS] =
|
||||
DungeonInfo("Gerudo Training Grounds", RHT_GERUDO_TRAINING_GROUND, RG_NONE, RG_NONE,
|
||||
RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, RG_GERUDO_TRAINING_GROUNDS_KEY_RING, RG_NONE, RA_GERUDO_TRAINING_GROUND, 9, 3,
|
||||
RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, RG_GERUDO_TRAINING_GROUNDS_KEY_RING, RG_NONE, RA_GERUDO_TRAINING_GROUND, 9, 3, RSK_MQ_GTG,
|
||||
{
|
||||
// Vanilla Locations
|
||||
RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST,
|
||||
@ -652,7 +662,7 @@ Dungeons::Dungeons() {
|
||||
{}, {});
|
||||
dungeonList[GANONS_CASTLE] =
|
||||
DungeonInfo("Ganon's Castle", RHT_GANONS_CASTLE, RG_NONE, RG_NONE, RG_GANONS_CASTLE_SMALL_KEY,
|
||||
RG_GANONS_CASTLE_KEY_RING, RG_GANONS_CASTLE_BOSS_KEY, RA_GANONS_CASTLE, 2, 3,
|
||||
RG_GANONS_CASTLE_KEY_RING, RG_GANONS_CASTLE_BOSS_KEY, RA_GANONS_CASTLE, 2, 3, RSK_MQ_GANONS_CASTLE,
|
||||
{
|
||||
// Vanilla Locations
|
||||
RC_GANONS_CASTLE_FOREST_TRIAL_CHEST,
|
||||
|
@ -12,7 +12,8 @@ class DungeonInfo {
|
||||
public:
|
||||
DungeonInfo(std::string name_, RandomizerHintTextKey hintKey_, RandomizerGet map_, RandomizerGet compass_,
|
||||
RandomizerGet smallKey_, RandomizerGet keyRing_, RandomizerGet bossKey_, RandomizerArea area_,
|
||||
uint8_t vanillaKeyCount_, uint8_t mqKeyCount_, std::vector<RandomizerCheck> vanillaLocations_,
|
||||
uint8_t vanillaKeyCount_, uint8_t mqKeyCount_, RandomizerSettingKey mqSetting_,
|
||||
std::vector<RandomizerCheck> vanillaLocations_,
|
||||
std::vector<RandomizerCheck> mqLocations_, std::vector<RandomizerCheck> sharedLocations_,
|
||||
std::vector<RandomizerCheck> bossRoomLocations_);
|
||||
DungeonInfo();
|
||||
@ -34,6 +35,8 @@ class DungeonInfo {
|
||||
RandomizerGet GetMap() const;
|
||||
RandomizerGet GetCompass() const;
|
||||
RandomizerGet GetBossKey() const;
|
||||
RandomizerSettingKey GetMQSetting() const;
|
||||
void SetDungeonKnown(bool known);
|
||||
void PlaceVanillaMap() const;
|
||||
void PlaceVanillaCompass() const;
|
||||
void PlaceVanillaBossKey() const;
|
||||
@ -50,6 +53,8 @@ class DungeonInfo {
|
||||
RandomizerGet smallKey;
|
||||
RandomizerGet keyRing;
|
||||
RandomizerGet bossKey;
|
||||
RandomizerSettingKey mqSetting;
|
||||
bool isDungeonModeKnown = true;
|
||||
uint8_t vanillaKeyCount{};
|
||||
uint8_t mqKeyCount{};
|
||||
bool masterQuest = false;
|
||||
|
@ -98,7 +98,8 @@ void Settings::CreateOptionDescriptions() {
|
||||
"\n"
|
||||
"Random Number - A Random number and set of dungeons will be their Master Quest varieties.\n"
|
||||
"\n"
|
||||
"Selection Only - Specify which dungeons are Vanilla or Master Quest.";
|
||||
"Selection Only - Specify which dungeons are Vanilla, Master Quest or a 50/50 between the two.\n"
|
||||
"Differs from Random Number in that they are rolled individually, making the exact total a bell curve.";
|
||||
mOptionDescriptions[RSK_MQ_DUNGEON_SET] =
|
||||
"Choose specific Dungeons to be Master Quest or Vanilla.\n"
|
||||
"\n"
|
||||
|
@ -112,12 +112,12 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() {
|
||||
(location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) &&
|
||||
(!RandomizerCheckObjects::AreaIsDungeon(location.GetArea()) || location.GetQuest() == RCQUEST_BOTH ||
|
||||
location.GetQuest() == RCQUEST_MQ &&
|
||||
((CVarGetInteger(CVAR_RANDOMIZER_SETTING("MqDungeons"), RO_MQ_DUNGEONS_NONE) == RO_MQ_DUNGEONS_SET_NUMBER &&
|
||||
(CVarGetInteger(CVAR_RANDOMIZER_SETTING("MqDungeonCount"), 12) > 0) || // at least one MQ dungeon
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("MqDungeons"), RO_MQ_DUNGEONS_NONE) == RO_MQ_DUNGEONS_RANDOM_NUMBER)) ||
|
||||
((CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE) == RO_MQ_DUNGEONS_SET_NUMBER &&
|
||||
(CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeonCount"), 12) > 0) || // at least one MQ dungeon
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE) == RO_MQ_DUNGEONS_RANDOM_NUMBER)) ||
|
||||
location.GetQuest() == RCQUEST_VANILLA &&
|
||||
(CVarGetInteger(CVAR_RANDOMIZER_SETTING("MqDungeons"), RO_MQ_DUNGEONS_NONE) != RO_MQ_DUNGEONS_SET_NUMBER ||
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("MqDungeonCount"), 12) < 12) // at least one vanilla dungeon
|
||||
(CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE) != RO_MQ_DUNGEONS_SET_NUMBER ||
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeonCount"), 12) < 12) // at least one vanilla dungeon
|
||||
) &&
|
||||
(location.GetRCType() != RCTYPE_SHOP ||
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_OFF) > RO_SHOPSANITY_ZERO_ITEMS) &&
|
||||
|
@ -1486,7 +1486,7 @@ void Settings::UpdateOptionProperties() {
|
||||
} else {
|
||||
// If any MQ Options are available, show the MQ Dungeon Randomization Combobox
|
||||
mOptions[RSK_MQ_DUNGEON_RANDOM].Unhide();
|
||||
switch(CVarGetInteger(CVAR_RANDOMIZER_SETTING("MqDungeons"), RO_MQ_DUNGEONS_NONE)) {
|
||||
switch(CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE)) {
|
||||
// If No MQ Dungeons, add a separator after the combobx and hide
|
||||
// the count slider and the toggle for individual dungeon selections.
|
||||
case RO_MQ_DUNGEONS_NONE:
|
||||
@ -1504,17 +1504,22 @@ void Settings::UpdateOptionProperties() {
|
||||
// else if random number or selection only, remove the separator and only show
|
||||
// the individual dungeon selection toggle.
|
||||
case RO_MQ_DUNGEONS_RANDOM_NUMBER:
|
||||
case RO_MQ_DUNGEONS_SELECTION:
|
||||
mOptions[RSK_MQ_DUNGEON_RANDOM].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM);
|
||||
mOptions[RSK_MQ_DUNGEON_COUNT].Hide();
|
||||
mOptions[RSK_MQ_DUNGEON_SET].Unhide();
|
||||
break;
|
||||
case RO_MQ_DUNGEONS_SELECTION:
|
||||
mOptions[RSK_MQ_DUNGEON_RANDOM].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM);
|
||||
mOptions[RSK_MQ_DUNGEON_COUNT].Hide();
|
||||
mOptions[RSK_MQ_DUNGEON_SET].Hide();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Controls whether or not to show the selectors for individual dungeons.
|
||||
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MqDungeons"), RO_MQ_DUNGEONS_NONE) != RO_MQ_DUNGEONS_NONE &&
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("MqDungeonsSelection"), RO_GENERIC_OFF) == RO_GENERIC_ON) {
|
||||
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE) != RO_MQ_DUNGEONS_NONE &&
|
||||
(CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeonsSelection"), RO_GENERIC_OFF) == RO_GENERIC_ON ||
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE) == RO_MQ_DUNGEONS_SELECTION)) {
|
||||
// if showing the dungeon selectors, remove the separator after the Set Dungeons checkbox.
|
||||
mOptions[RSK_MQ_DUNGEON_SET].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM);
|
||||
mOptions[RSK_MQ_DEKU_TREE].Unhide();
|
||||
@ -1546,12 +1551,7 @@ void Settings::UpdateOptionProperties() {
|
||||
mOptions[RSK_MQ_GANONS_CASTLE].Hide();
|
||||
}
|
||||
}
|
||||
// Disable interaction with Set Dungeons checkbox if MQ Dungeon Randomization is set to Selection Only.
|
||||
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MqDungeons"), RO_MQ_DUNGEONS_NONE) == RO_MQ_DUNGEONS_SELECTION) {
|
||||
mOptions[RSK_MQ_DUNGEON_SET].Disable("This option is force-enabled because Master Quest Dungeons is set to Selection Only", UIWidgets::CheckboxGraphics::Checkmark);
|
||||
} else {
|
||||
mOptions[RSK_MQ_DUNGEON_SET].Enable();
|
||||
}
|
||||
|
||||
// Show mixed entrance pool options if mixed entrance pools are enabled at all.
|
||||
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MixedEntrances"), RO_GENERIC_OFF)) {
|
||||
mOptions[RSK_MIXED_ENTRANCE_POOLS].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM);
|
||||
@ -1871,74 +1871,121 @@ void Settings::FinalizeSettings(const std::set<RandomizerCheck>& excludedLocatio
|
||||
// RANDOTODO implement chest shuffle with keysanity
|
||||
// ShuffleChestMinigame.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_CHEST_MINIGAME]);
|
||||
mOptions[RSK_SHUFFLE_CHEST_MINIGAME].SetSelectedIndex(RO_CHEST_GAME_OFF);
|
||||
|
||||
//TODO: RandomizeAllSettings(true) when implementing the ability to randomize the options themselves.
|
||||
std::array<DungeonInfo*, 12> dungeons = ctx->GetDungeons()->GetDungeonList();
|
||||
std::array<bool, 12> dungeonModesKnown{};
|
||||
const std::vector<Option*> dungeonOptions = {
|
||||
&mOptions[RSK_MQ_DEKU_TREE],
|
||||
&mOptions[RSK_MQ_DODONGOS_CAVERN],
|
||||
&mOptions[RSK_MQ_JABU_JABU],
|
||||
&mOptions[RSK_MQ_FOREST_TEMPLE],
|
||||
&mOptions[RSK_MQ_FIRE_TEMPLE],
|
||||
&mOptions[RSK_MQ_WATER_TEMPLE],
|
||||
&mOptions[RSK_MQ_SPIRIT_TEMPLE],
|
||||
&mOptions[RSK_MQ_SHADOW_TEMPLE],
|
||||
&mOptions[RSK_MQ_BOTTOM_OF_THE_WELL],
|
||||
&mOptions[RSK_MQ_ICE_CAVERN],
|
||||
&mOptions[RSK_MQ_GTG],
|
||||
&mOptions[RSK_MQ_GANONS_CASTLE]
|
||||
};
|
||||
auto mqSet = mOptions[RSK_MQ_DUNGEON_COUNT].Value<uint8_t>();
|
||||
if (mOptions[RSK_MQ_DUNGEON_RANDOM].Is(RO_MQ_DUNGEONS_SELECTION)) {
|
||||
mqSet = 0;
|
||||
|
||||
//reset the MQ vars
|
||||
for (auto dungeon: dungeons) {
|
||||
dungeon->ClearMQ();
|
||||
dungeon->SetDungeonKnown(true);
|
||||
}
|
||||
std::vector<uint8_t> randMQOption = {};
|
||||
if (mOptions[RSK_MQ_DUNGEON_SET]) {
|
||||
uint8_t dungeonCount = 0;
|
||||
for (size_t i = 0; i < dungeons.size(); i++) {
|
||||
dungeons[i]->ClearMQ();
|
||||
dungeonModesKnown[i] = true;
|
||||
switch (dungeonOptions[i]->Value<uint8_t>()) {
|
||||
case 1:
|
||||
dungeons[i]->SetMQ();
|
||||
dungeonCount++;
|
||||
//if it's selection mode, process the selection directly
|
||||
if (mOptions[RSK_MQ_DUNGEON_RANDOM].Value<uint8_t>() == RO_MQ_DUNGEONS_SELECTION){
|
||||
mOptions[RSK_MQ_DUNGEON_SET].SetSelectedIndex(RO_GENERIC_ON);
|
||||
//How many dungeons are set to MQ in selection
|
||||
uint8_t mqSet = 0;
|
||||
for (auto dungeon: dungeons) {
|
||||
switch (mOptions[dungeon->GetMQSetting()].Value<uint8_t>()) {
|
||||
case RO_MQ_SET_MQ:
|
||||
dungeon->SetMQ();
|
||||
mqSet += 1;
|
||||
break;
|
||||
case 2:
|
||||
randMQOption.push_back(i);
|
||||
dungeonModesKnown[i] = false;
|
||||
case RO_MQ_SET_RANDOM:
|
||||
//50% per dungeon, rolled seperatly so people can either have a linear distribtuion
|
||||
//or a bell curve for the number of MQ dungeons per seed.
|
||||
if (Random(0,2)){
|
||||
dungeon->SetMQ();
|
||||
mqSet += 1;
|
||||
}
|
||||
dungeon->SetDungeonKnown(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
Shuffle(randMQOption);
|
||||
if (mOptions[RSK_MQ_DUNGEON_RANDOM].Is(RO_MQ_DUNGEONS_RANDOM_NUMBER)) {
|
||||
mqSet = dungeonCount + Random(0, static_cast<int>(randMQOption.size()) + 1);
|
||||
}
|
||||
for (uint8_t i = 0; dungeonCount < mqSet; i++) {
|
||||
if (i > randMQOption.size()) {
|
||||
// This can happen if the amount of MQ Dungeons is specifically
|
||||
// set to a higher number than the amount of Dungeons specifically set to MQ or Random,
|
||||
// break out of the loop and just have fewer MQ dungeons than the Set Count.
|
||||
//override the dungeons set with the ones set by selection, so it's accurate for anything that wants to know MQ dungeon count
|
||||
mOptions[RSK_MQ_DUNGEON_COUNT].SetSelectedIndex(mqSet);
|
||||
//handling set number and random number together
|
||||
} else if (mOptions[RSK_MQ_DUNGEON_RANDOM].Value<uint8_t>() != RO_MQ_DUNGEONS_NONE){
|
||||
// so we don't have to call this repeatedly
|
||||
uint8_t mqCount = mOptions[RSK_MQ_DUNGEON_COUNT].Value<uint8_t>();
|
||||
//How many dungeons are set to MQ in selection
|
||||
uint8_t mqSet = 0;
|
||||
//the number of random
|
||||
uint8_t mqToSet = 0;
|
||||
//store the dungeons to randomly decide between. we use the id instead of a dungeon object to avoid a lot of casting.
|
||||
std::vector<uint8_t> randMQOption = {};
|
||||
//if dungeons have been preset, process them
|
||||
if (mOptions[RSK_MQ_DUNGEON_SET]){
|
||||
for (size_t i = 0; i < dungeons.size(); i++) {
|
||||
switch (mOptions[dungeons[i]->GetMQSetting()].Value<uint8_t>()) {
|
||||
case RO_MQ_SET_MQ:
|
||||
dungeons[i]->SetMQ();
|
||||
mqSet += 1;
|
||||
break;
|
||||
case RO_MQ_SET_RANDOM:
|
||||
randMQOption.push_back(i);
|
||||
dungeons[i]->SetDungeonKnown(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
//otherwise, every dungeon is possible
|
||||
} else {
|
||||
//if the count is fixed to 12, we know everything is MQ, so can skip some setps and do not set Known
|
||||
if (mOptions[RSK_MQ_DUNGEON_RANDOM].Value<uint8_t>() == RO_MQ_DUNGEONS_SET_NUMBER &&
|
||||
mqCount == 12) {
|
||||
randMQOption = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
|
||||
for (auto dungeon: dungeons) {
|
||||
mOptions[dungeon->GetMQSetting()].SetSelectedIndex(RO_MQ_SET_MQ);
|
||||
}
|
||||
//if it's fixed to zero, set it to None instead. the rest is processed after
|
||||
} else if (mOptions[RSK_MQ_DUNGEON_RANDOM].Value<uint8_t>() == RO_MQ_DUNGEONS_SET_NUMBER &&
|
||||
mqCount == 0){
|
||||
mOptions[RSK_MQ_DUNGEON_RANDOM].SetSelectedIndex(RO_MQ_DUNGEONS_NONE);
|
||||
//otherwise, make everything a possibility and unknown
|
||||
} else {
|
||||
for (size_t i = 0; i < dungeons.size(); i++) {
|
||||
randMQOption.push_back(i);
|
||||
dungeons[i]->SetDungeonKnown(false);
|
||||
mOptions[dungeons[i]->GetMQSetting()].SetSelectedIndex(RO_MQ_SET_RANDOM);
|
||||
}
|
||||
}
|
||||
}
|
||||
//if there's no random options, we can skip this
|
||||
if (randMQOption.size() > 0){
|
||||
//Figure out how many dungeons to select, rolling the random number if needed
|
||||
if (mOptions[RSK_MQ_DUNGEON_RANDOM].Is(RO_MQ_DUNGEONS_RANDOM_NUMBER)){
|
||||
mqToSet = Random(0, static_cast<int>(randMQOption.size()) + 1);
|
||||
} else if (mqCount > mqSet) {
|
||||
mqToSet = std::min(mqCount - mqSet, static_cast<int>(randMQOption.size()));
|
||||
}
|
||||
//we only need to shuffle if we're not using them all
|
||||
if (mqToSet <= static_cast<int8_t>(randMQOption.size()) && mqToSet > 0) {
|
||||
Shuffle(randMQOption);
|
||||
}
|
||||
for (uint8_t i = 0; i < mqToSet; i++){
|
||||
dungeons[randMQOption[i]]->SetMQ();
|
||||
dungeonCount++;
|
||||
}
|
||||
} else {
|
||||
Shuffle(dungeons);
|
||||
for (const auto dungeon : dungeons) {
|
||||
dungeon->ClearMQ();
|
||||
//if there's no random options, check if we can collapse the setting into None or Selection
|
||||
if (mqSet == 0){
|
||||
mOptions[RSK_MQ_DUNGEON_RANDOM].SetSelectedIndex(RO_MQ_DUNGEONS_NONE);
|
||||
} else {
|
||||
mOptions[RSK_MQ_DUNGEON_RANDOM].SetSelectedIndex(RO_MQ_DUNGEONS_SELECTION);
|
||||
}
|
||||
const bool allDungeonModesKnown = mqSet == 0 || mqSet == dungeons.size();
|
||||
for (bool & i : dungeonModesKnown) {
|
||||
i = allDungeonModesKnown;
|
||||
}
|
||||
if (mOptions[RSK_MQ_DUNGEON_RANDOM].Is(RO_MQ_DUNGEONS_RANDOM_NUMBER)) {
|
||||
mqSet = Random(0, 13);
|
||||
//reset the value set based on what was actually set
|
||||
mOptions[RSK_MQ_DUNGEON_COUNT].SetSelectedIndex(mqToSet + mqSet);
|
||||
}
|
||||
for (uint8_t i = 0; i < mqSet; i++) {
|
||||
dungeons[i]->SetMQ();
|
||||
//Not an if else as other settings can become None in processing
|
||||
if (mOptions[RSK_MQ_DUNGEON_RANDOM].Value<uint8_t>() == RO_MQ_DUNGEONS_NONE) {
|
||||
mOptions[RSK_MQ_DUNGEON_SET].SetSelectedIndex(RO_GENERIC_OFF);
|
||||
mOptions[RSK_MQ_DUNGEON_COUNT].SetSelectedIndex(0);
|
||||
for (auto dungeon: dungeons) {
|
||||
mOptions[dungeon->GetMQSetting()].SetSelectedIndex(RO_MQ_SET_VANILLA);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user