-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduced Linked Distribution initial outline.
- Loading branch information
Showing
7 changed files
with
174 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
#pragma once | ||
#include "FormData.h" | ||
|
||
namespace LinkedDistribution | ||
{ | ||
namespace INI { | ||
|
||
struct RawLinkedItem | ||
{ | ||
FormOrEditorID rawForm{}; | ||
|
||
/// Raw filters in RawLinkedItem only use MATCH, there is no meaning for ALL or NOT, so they are ignored. | ||
Filters<FormOrEditorID> rawFormFilters{}; | ||
|
||
RandomCount count{ 1, 1 }; | ||
Chance chance{ 100 }; | ||
|
||
std::string path{}; | ||
}; | ||
|
||
using LinkedItemsVec = std::vector<RawLinkedItem>; | ||
|
||
inline LinkedItemsVec linkedItems{}; | ||
|
||
namespace Parser | ||
{ | ||
bool TryParse(const std::string& a_key, const std::string& a_value, const std::string& a_path); | ||
} | ||
} | ||
|
||
template<class Form> | ||
using DataSet = std::set<Forms::Data<Form>>; | ||
|
||
template<class T> | ||
using LinkedForms = std::unordered_map<RE::TESForm*, DataSet<T>>; | ||
|
||
class Manager : public ISingleton<Manager> | ||
{ | ||
private: | ||
template <class Form> | ||
const DataSet<Form>& LinkedFormsForForm(const RE::TESForm* form, const LinkedForms<Form>& linkedForms) const | ||
{ | ||
if (const auto it = linkedForms.find(form); it != linkedForms.end()) { | ||
return it->second; | ||
} else { | ||
static std::set<RE::TESForm*> empty{}; | ||
return empty; | ||
} | ||
} | ||
|
||
public: | ||
/// <summary> | ||
/// Does a forms lookup similar to what Filters do. | ||
/// | ||
/// As a result this method configures Manager with discovered valid linked items. | ||
/// </summary> | ||
/// <param name="dataHandler">A DataHandler that will perform the actual lookup.</param> | ||
/// <param name="rawLinkedDistribution">A raw linked item entries that should be processed.</param> | ||
void LookupLinkedItems(RE::TESDataHandler* const dataHandler, INI::LinkedItemsVec& rawLinkedItems); | ||
|
||
|
||
|
||
private: | ||
|
||
LinkedForms<RE::SpellItem> spells{ RECORD::kSpell }; | ||
LinkedForms<RE::BGSPerk> perks{ RECORD::kPerk }; | ||
LinkedForms<RE::TESBoundObject> items{ RECORD::kItem }; | ||
LinkedForms<RE::TESShout> shouts{ RECORD::kShout }; | ||
LinkedForms<RE::TESLevSpell> levSpells{ RECORD::kLevSpell }; | ||
LinkedForms<RE::TESForm> packages{ RECORD::kPackage }; | ||
LinkedForms<RE::BGSOutfit> outfits{ RECORD::kOutfit }; | ||
LinkedForms<RE::BGSKeyword> keywords{ RECORD::kKeyword }; | ||
LinkedForms<RE::TESBoundObject> deathItems{ RECORD::kDeathItem }; | ||
LinkedForms<RE::TESFaction> factions{ RECORD::kFaction }; | ||
LinkedForms<RE::BGSOutfit> sleepOutfits{ RECORD::kSleepOutfit }; | ||
LinkedForms<RE::TESObjectARMO> skins{ RECORD::kSkin }; | ||
|
||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#include "LinkedDistribution.h" | ||
#include "FormData.h" | ||
|
||
#pragma region Parsing | ||
bool LinkedDistribution::INI::Parser::TryParse(const std::string& a_key, const std::string& a_value, const std::string& a_path) | ||
{ | ||
if (a_key != "LinkedItem") { | ||
return false; | ||
} | ||
|
||
const auto sections = string::split(a_value, "|"); | ||
const auto size = sections.size(); | ||
|
||
if (size < 2) { | ||
logger::warn("IGNORED: LinkedItem must have a form and at least one filter name: {} = {}"sv, a_key, a_value); | ||
return false; | ||
} | ||
|
||
auto split_IDs = distribution::split_entry(sections[1]); | ||
|
||
if (split_IDs.empty()) { | ||
logger::warn("ExclusiveGroup must have at least one Form Filter : {} = {}"sv, a_key, a_value); | ||
return false; | ||
} | ||
|
||
LinkedDistribution::INI::RawLinkedItem item{}; | ||
item.rawForm = sections[0]; | ||
item.path = a_path; | ||
|
||
for (auto& IDs : split_IDs) { | ||
item.rawFormFilters.MATCH.push_back(distribution::get_record(IDs)); | ||
} | ||
} | ||
#pragma endregion | ||
|
||
#pragma region Lookup | ||
void LinkedDistribution::Manager::LookupLinkedItems(RE::TESDataHandler* const dataHandler, INI::LinkedItemsVec& rawLinkedItems) | ||
{ | ||
using namespace Forms; | ||
|
||
// TODO: Figure out templates here. | ||
|
||
|
||
for (auto& [rawForm, filterIDs, count, chance, path] : rawLinkedItems) { | ||
try { | ||
if (const auto form = Forms::detail::get_form(dataHandler, rawForm, path); form) { | ||
/*auto& forms = linkedForms[form]; | ||
FormVec match{}; | ||
if (Forms::detail::formID_to_form(dataHandler, filterIDs.MATCH, match, path, false, false)) { | ||
for (const auto& form : match) { | ||
if (std::holds_alternative<RE::TESForm*>(form)) { | ||
forms.insert(std::get<RE::TESForm*>(form)); | ||
} | ||
} | ||
}*/ | ||
} | ||
} catch (const Lookup::UnknownFormIDException& e) { | ||
buffered_logger::error("\t[{}] [0x{:X}] ({}) FAIL - formID doesn't exist", e.path, e.formID, e.modName.value_or("")); | ||
} catch (const Lookup::InvalidKeywordException& e) { | ||
buffered_logger::error("\t[{}] [0x{:X}] ({}) FAIL - keyword does not have a valid editorID", e.path, e.formID, e.modName.value_or("")); | ||
} catch (const Lookup::KeywordNotFoundException& e) { | ||
if (e.isDynamic) { | ||
buffered_logger::critical("\t[{}] {} FAIL - couldn't create keyword", e.path, e.editorID); | ||
} else { | ||
buffered_logger::critical("\t[{}] {} FAIL - couldn't get existing keyword", e.path, e.editorID); | ||
} | ||
} catch (const Lookup::UnknownEditorIDException& e) { | ||
buffered_logger::error("\t[{}] ({}) FAIL - editorID doesn't exist", e.path, e.editorID); | ||
} catch (const Lookup::MalformedEditorIDException& e) { | ||
buffered_logger::error("\t[{}] FAIL - editorID can't be empty", e.path); | ||
} catch (const Lookup::InvalidFormTypeException& e) { | ||
// Whitelisting is disabled, so this should not occur | ||
} catch (const Lookup::UnknownPluginException& e) { | ||
// Likewise, we don't expect plugin names in linked forms. | ||
} | ||
} | ||
|
||
// Remove empty linked forms | ||
//std::erase_if(linkedForms, [](const auto& pair) { return pair.second.empty(); }); | ||
} | ||
#pragma endregion |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters