Skip to content

Commit

Permalink
Fixed indices for packages when inferring form type.
Browse files Browse the repository at this point in the history
  • Loading branch information
adya committed Mar 25, 2024
1 parent a122403 commit 51178fa
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 30 deletions.
12 changes: 8 additions & 4 deletions SPID/include/LinkedDistribution.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace LinkedDistribution
/// Raw filters in RawLinkedForm only use MATCH, there is no meaning for ALL or NOT, so they are ignored.
Filters<FormOrEditorID> formIDs{};

RandomCount count{ 1, 1 };
IndexOrCount idxOrCount { RandomCount(1, 1) };
Chance chance{ 100 };

std::string path{};
Expand Down Expand Up @@ -67,7 +67,7 @@ namespace LinkedDistribution
RECORD::TYPE type;
FormsMap forms{};

void Link(Form* form, const FormVec& linkedForms, const RandomCount& count, const Chance& chance, const std::string& path);
void Link(Form* form, const FormVec& linkedForms, const IndexOrCount& idxOrCount, const Chance& chance, const std::string& path);
};

class Manager : public ISingleton<Manager>
Expand Down Expand Up @@ -99,10 +99,12 @@ namespace LinkedDistribution
LinkedForms<RE::SpellItem> spells{ RECORD::kSpell };
LinkedForms<RE::BGSPerk> perks{ RECORD::kPerk };
LinkedForms<RE::TESBoundObject> items{ RECORD::kItem };
LinkedForms<RE::TESBoundObject> deathItems{ RECORD::kDeathItem };
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::BGSOutfit> sleepingOutfits{ RECORD::kSleepOutfit };
LinkedForms<RE::BGSKeyword> keywords{ RECORD::kKeyword };
LinkedForms<RE::TESFaction> factions{ RECORD::kFaction };
LinkedForms<RE::TESObjectARMO> skins{ RECORD::kSkin };
Expand Down Expand Up @@ -183,7 +185,9 @@ namespace LinkedDistribution
func(perks, std::forward<Args>(args)...);
func(shouts, std::forward<Args>(args)...);
func(items, std::forward<Args>(args)...);
func(deathItems, std::forward<Args>(args)...);
func(outfits, std::forward<Args>(args)...);
func(sleepingOutfits, std::forward<Args>(args)...);
func(factions, std::forward<Args>(args)...);
func(packages, std::forward<Args>(args)...);
func(skins, std::forward<Args>(args)...);
Expand All @@ -203,14 +207,14 @@ namespace LinkedDistribution
}

template <class Form>
void LinkedForms<Form>::Link(Form* form, const FormVec& linkedForms, const RandomCount& count, const Chance& chance, const std::string& path)
void LinkedForms<Form>::Link(Form* form, const FormVec& linkedForms, const IndexOrCount& idxOrCount, const Chance& chance, const std::string& path)
{
for (const auto& linkedForm : linkedForms) {
if (std::holds_alternative<RE::TESForm*>(linkedForm)) {
auto& distributableForms = forms[std::get<RE::TESForm*>(linkedForm)];
// Note that we don't use Data.index here, as these linked forms don't have any leveled filters
// and as such do not to track their index.
distributableForms.emplace_back(0, form, count, FilterData({}, {}, {}, {}, chance), path);
distributableForms.emplace_back(0, form, idxOrCount, FilterData({}, {}, {}, {}, chance), path);
}
}
}
Expand Down
74 changes: 48 additions & 26 deletions SPID/src/LinkedDistribution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace LinkedDistribution
{
kForm = 0,
kLinkedForms,
kCount,
kIdxOrCount,
kChance,

// Minimum required sections
Expand All @@ -26,11 +26,11 @@ namespace LinkedDistribution
if (!a_key.starts_with("Linked"sv)) {
return false;
}

std::string_view rawType = a_key.substr(6);
std::string rawType = a_key.substr(6);
auto type = RECORD::GetType(rawType);
if (type == RECORD::kTotal) {
logger::warn("IGNORED: Invalid Linked Form type: {}"sv, a_key);
logger::warn("IGNORED: Invalid Linked Form type: {}"sv, rawType);
return true;
}

Expand All @@ -57,17 +57,27 @@ namespace LinkedDistribution
item.formIDs.MATCH.push_back(distribution::get_record(IDs));
}

if (kCount < size) {
if (const auto& str = sections[kCount]; distribution::is_valid_entry(str)) {
if (auto countPair = string::split(str, "-"); countPair.size() > 1) {
auto minCount = string::to_num<Count>(countPair[0]);
auto maxCount = string::to_num<Count>(countPair[1]);

item.count = RandomCount(minCount, maxCount);
} else {
auto count = string::to_num<Count>(str);
if (type == RECORD::kPackage) { // reuse item count for package stack index
item.idxOrCount = 0;
}

item.count = RandomCount(count, count); // create the exact match range.
if (kIdxOrCount < size) {
if (type == RECORD::kPackage) {
if (const auto& str = sections[kIdxOrCount]; distribution::is_valid_entry(str)) {
item.idxOrCount = string::to_num<Index>(str);
}
} else {
if (const auto& str = sections[kIdxOrCount]; distribution::is_valid_entry(str)) {
if (auto countPair = string::split(str, "-"); countPair.size() > 1) {
auto minCount = string::to_num<Count>(countPair[0]);
auto maxCount = string::to_num<Count>(countPair[1]);

item.idxOrCount = RandomCount(minCount, maxCount);
} else {
auto count = string::to_num<Count>(str);

item.idxOrCount = RandomCount(count, count); // create the exact match range.
}
}
}
}
Expand Down Expand Up @@ -96,32 +106,44 @@ namespace LinkedDistribution
auto& genericForms = rawLinkedForms[RECORD::kForm];
for (auto& rawForm : genericForms) {
if (auto form = detail::LookupLinkedForm(dataHandler, rawForm); form) {
auto& [formID, parentFormIDs, count, chance, path] = rawForm;
auto& [formID, parentFormIDs, idxOrCount, chance, path] = rawForm;
FormVec parentForms{};
if (!Forms::detail::formID_to_form(dataHandler, parentFormIDs.MATCH, parentForms, path, false, false)) {
continue;
}
// Add to appropriate list.
// Add to appropriate list. (Note that type inferring doesn't recognize SleepingOutfit or DeathItems)
if (const auto keyword = form->As<RE::BGSKeyword>(); keyword) {
keywords.Link(keyword, parentForms, count, chance, path);
keywords.Link(keyword, parentForms, idxOrCount, chance, path);
} else if (const auto spell = form->As<RE::SpellItem>(); spell) {
spells.Link(spell, parentForms, count, chance, path);
spells.Link(spell, parentForms, idxOrCount, chance, path);
} else if (const auto perk = form->As<RE::BGSPerk>(); perk) {
perks.Link(perk, parentForms, count, chance, path);
perks.Link(perk, parentForms, idxOrCount, chance, path);
} else if (const auto shout = form->As<RE::TESShout>(); shout) {
shouts.Link(shout, parentForms, count, chance, path);
shouts.Link(shout, parentForms, idxOrCount, chance, path);
} else if (const auto item = form->As<RE::TESBoundObject>(); item) {
items.Link(item, parentForms, count, chance, path);
items.Link(item, parentForms, idxOrCount, chance, path);
} else if (const auto outfit = form->As<RE::BGSOutfit>(); outfit) {
outfits.Link(outfit, parentForms, count, chance, path);
outfits.Link(outfit, parentForms, idxOrCount, chance, path);
} else if (const auto faction = form->As<RE::TESFaction>(); faction) {
factions.Link(faction, parentForms, count, chance, path);
factions.Link(faction, parentForms, idxOrCount, chance, path);
} else if (const auto skin = form->As<RE::TESObjectARMO>(); skin) {
skins.Link(skin, parentForms, count, chance, path);
skins.Link(skin, parentForms, idxOrCount, chance, path);
} else if (const auto package = form->As<RE::TESForm>(); package) {
auto type = package->GetFormType();
if (type == RE::FormType::Package || type == RE::FormType::FormList)
packages.Link(package, parentForms, count, chance, path);
if (type == RE::FormType::Package || type == RE::FormType::FormList) {
// During type inferring we'll default to RandomCount, so we need to properly convert it to Index if it's a package.
Index packageIndex = 1;
if (std::holds_alternative<RandomCount>(idxOrCount)) {
auto& count = std::get<RandomCount>(idxOrCount);
if (!count.IsExact()) {
logger::warn("Inferred Form is a package, but specifies a random count instead of index. Min value ({}) of the range will be used as an index.", count.min);
}
packageIndex = count.min;
} else {
packageIndex = std::get<Index>(idxOrCount);
}
packages.Link(package, parentForms, packageIndex, chance, path);
}
}
}
}
Expand Down

0 comments on commit 51178fa

Please sign in to comment.