Skip to content

Commit

Permalink
Merge pull request #31 from powerof3/23-local-and-global-linked-items
Browse files Browse the repository at this point in the history
Scope for Linked Forms.
  • Loading branch information
adya authored Mar 31, 2024
2 parents ef8594d + f16ce03 commit f54e8a5
Show file tree
Hide file tree
Showing 11 changed files with 336 additions and 246 deletions.
2 changes: 2 additions & 0 deletions SPID/include/Defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ struct Traits
std::optional<bool> teammate{};
};

using Path = std::string;

using Index = std::int32_t;
using Count = std::int32_t;
using RandomCount = Range<Count>;
Expand Down
36 changes: 22 additions & 14 deletions SPID/include/Distribute.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ namespace Distribute
void add_item(RE::Actor* a_actor, RE::TESBoundObject* a_item, std::uint32_t a_itemCount);
}

using namespace Forms;

#pragma region Packages, Death Items
// old method (distributing one by one)
// for now, only packages/death items use this
Expand All @@ -79,12 +81,12 @@ namespace Distribute
Forms::DataVec<Form>& forms,
const PCLevelMult::Input& a_input,
std::function<bool(Form*, IndexOrCount)> a_callback,
std::set<RE::TESForm*>* accumulatedForms = nullptr)
DistributedForms* accumulatedForms = nullptr)
{
for (auto& formData : forms) {
if (!a_npcData.HasMutuallyExclusiveForm(formData.form) && detail::passed_filters(a_npcData, a_input, formData)) {
if (accumulatedForms) {
accumulatedForms->insert(formData.form);
accumulatedForms->insert({ formData.form, formData.path });
}
a_callback(formData.form, formData.idxOrCount);
++formData.npcCount;
Expand All @@ -100,12 +102,12 @@ namespace Distribute
Forms::DataVec<Form>& forms,
const PCLevelMult::Input& a_input,
std::function<bool(Form*)> a_callback,
std::set<RE::TESForm*>* accumulatedForms = nullptr)
DistributedForms* accumulatedForms = nullptr)
{
for (auto& formData : forms) { // Vector is reversed in FinishLookupForms
if (!a_npcData.HasMutuallyExclusiveForm(formData.form) && detail::passed_filters(a_npcData, a_input, formData) && a_callback(formData.form)) {
if (accumulatedForms) {
accumulatedForms->insert(formData.form);
accumulatedForms->insert({ formData.form, formData.path });
}
++formData.npcCount;
break;
Expand All @@ -121,14 +123,14 @@ namespace Distribute
const NPCData& a_npcData,
Forms::Distributables<Form>& a_distributables,
std::function<bool(Form*)> a_callback,
std::set<RE::TESForm*>* accumulatedForms = nullptr)
DistributedForms* accumulatedForms = nullptr)
{
auto& vec = a_distributables.GetForms(false);

for (auto& formData : vec) { // Vector is reversed in FinishLookupForms
if (!a_npcData.HasMutuallyExclusiveForm(formData.form) && detail::passed_filters(a_npcData, formData) && a_callback(formData.form)) {
if (accumulatedForms) {
accumulatedForms->insert(formData.form);
accumulatedForms->insert({ formData.form, formData.path });
}
++formData.npcCount;
break;
Expand All @@ -144,7 +146,7 @@ namespace Distribute
Forms::DataVec<Form>& forms,
const PCLevelMult::Input& a_input,
std::function<bool(std::map<Form*, Count>&)> a_callback,
std::set<RE::TESForm*>* accumulatedForms = nullptr)
DistributedForms* accumulatedForms = nullptr)
{
std::map<Form*, Count> collectedForms{};

Expand All @@ -159,18 +161,21 @@ namespace Distribute
leveledItem->CalculateCurrentFormList(level, count, calcedObjects, 0, true);
for (auto& calcObj : calcedObjects) {
collectedForms[static_cast<RE::TESBoundObject*>(calcObj.form)] += calcObj.count;
if (accumulatedForms) {
accumulatedForms->insert({ calcObj.form, formData.path });
}
}
} else {
collectedForms[formData.form] += count;
if (accumulatedForms) {
accumulatedForms->insert({ formData.form, formData.path });
}
}
++formData.npcCount;
}
}

if (!collectedForms.empty()) {
if (accumulatedForms) {
std::ranges::copy(collectedForms | std::views::keys, std::inserter(*accumulatedForms, accumulatedForms->end()));
}
a_callback(collectedForms);
}
}
Expand All @@ -185,7 +190,7 @@ namespace Distribute
Forms::DataVec<Form>& forms,
const PCLevelMult::Input& a_input,
std::function<void(const std::vector<Form*>&)> a_callback,
std::set<RE::TESForm*>* accumulatedForms = nullptr)
DistributedForms* accumulatedForms = nullptr)
{
const auto npc = a_npcData.GetNPC();

Expand All @@ -210,6 +215,9 @@ namespace Distribute
if (formData.filters.HasLevelFilters()) {
collectedLeveledFormIDs.emplace(formID);
}
if (accumulatedForms) {
accumulatedForms->insert({ form, formData.path });
}
++formData.npcCount;
}
} else {
Expand All @@ -218,15 +226,15 @@ namespace Distribute
if (formData.filters.HasLevelFilters()) {
collectedLeveledFormIDs.emplace(formID);
}
if (accumulatedForms) {
accumulatedForms->insert({ form, formData.path });
}
++formData.npcCount;
}
}
}

if (!collectedForms.empty()) {
if (accumulatedForms) {
accumulatedForms->insert(collectedForms.begin(), collectedForms.end());
}
a_callback(collectedForms);
if (!collectedLeveledFormIDs.empty()) {
PCLevelMult::Manager::GetSingleton()->InsertDistributedEntry(a_input, Form::FORMTYPE, collectedLeveledFormIDs);
Expand Down
25 changes: 24 additions & 1 deletion SPID/include/ExclusiveGroups.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,27 @@

namespace ExclusiveGroups
{
namespace INI
{
struct RawExclusiveGroup
{
std::string name{};

/// Raw filters in RawExclusiveGroup only use NOT and MATCH, there is no meaning for ALL, so it's ignored.
Filters<FormOrEditorID> formIDs{};
Path path{};
};

using ExclusiveGroupsVec = std::vector<RawExclusiveGroup>;

/// <summary>
/// A list of RawExclusiveGroups that will be processed along with configs.
/// </summary>
inline ExclusiveGroupsVec exclusiveGroups{};

bool TryParse(const std::string& a_key, const std::string& a_value, const Path& a_path);
}

using GroupName = std::string;
using LinkedGroups = std::unordered_map<RE::TESForm*, std::unordered_set<GroupName>>;
using Groups = std::unordered_map<GroupName, std::unordered_set<RE::TESForm*>>;
Expand All @@ -17,7 +38,9 @@ namespace ExclusiveGroups
/// </summary>
/// <param name="dataHandler">A DataHandler that will perform the actual lookup.</param>
/// <param name="rawExclusiveGroups">A raw exclusive group entries that should be processed.</param>
void LookupExclusiveGroups(RE::TESDataHandler* const dataHandler, INI::ExclusiveGroupsVec& rawExclusiveGroups);
void LookupExclusiveGroups(RE::TESDataHandler* const dataHandler, INI::ExclusiveGroupsVec& rawExclusiveGroups = INI::exclusiveGroups);

void LogExclusiveGroupsLookup();

/// <summary>
/// Gets a set of all forms that are in the same exclusive group as the given form.
Expand Down
Loading

0 comments on commit f54e8a5

Please sign in to comment.