More cleanup
This commit is contained in:
parent
aa2c05b08b
commit
9fc9037960
4 changed files with 74 additions and 77 deletions
|
|
@ -75,10 +75,9 @@ struct Outfit {
|
|||
bool hasShield() const;
|
||||
std::unordered_set<RE::TESObjectARMO*> computeDisplaySet(const std::unordered_set<RE::TESObjectARMO*>& equippedSet);
|
||||
|
||||
SlotPolicy::Mode effectivePolicyForSlot(RE::BIPED_OBJECT slot);
|
||||
void setSlotPolicy(RE::BIPED_OBJECT slot, std::optional<SlotPolicy::Mode> policy);
|
||||
void setBlanketSlotPolicy(SlotPolicy::Mode policy);
|
||||
void setDefaultSlotPolicy();
|
||||
void setAllSlotPolicy(SlotPolicy::Mode policy);
|
||||
|
||||
void load(const proto::Outfit& proto, const SKSE::SerializationInterface*);
|
||||
void load_legacy(const SKSE::SerializationInterface* intfc, std::uint32_t version);// can throw ArmorAddonOverrideService::load_error
|
||||
|
|
|
|||
|
|
@ -53,8 +53,8 @@ namespace RE {
|
|||
}// namespace TESObjectARMOAugments
|
||||
|
||||
namespace BIPED_OBJECTS_META {
|
||||
inline constexpr std::uint32_t firstSlot = RE::BIPED_OBJECTS::kHead;
|
||||
inline constexpr std::uint32_t numSlots = RE::BIPED_OBJECTS::kEditorTotal;
|
||||
inline constexpr std::uint32_t kFirstSlot = RE::BIPED_OBJECTS::kHead;
|
||||
inline constexpr std::uint32_t kNumSlots = RE::BIPED_OBJECTS::kEditorTotal;
|
||||
}// namespace BIPED_OBJECTS_META
|
||||
}// namespace RE
|
||||
|
||||
|
|
|
|||
|
|
@ -36,28 +36,14 @@ bool Outfit::hasShield() const {
|
|||
return false;
|
||||
};
|
||||
|
||||
SlotPolicy::Mode Outfit::effectivePolicyForSlot(RE::BIPED_OBJECT slot) {
|
||||
auto policy = slotPolicies.find(slot);
|
||||
if (policy != slotPolicies.end()) return policy->second;
|
||||
return slotPolicy;
|
||||
}
|
||||
|
||||
void Outfit::setDefaultSlotPolicy() {
|
||||
slotPolicies.clear();
|
||||
slotPolicies[RE::BIPED_OBJECTS::kShield] = SlotPolicy::Mode::XEXO;
|
||||
slotPolicy = SlotPolicy::Mode::XXOO;
|
||||
}
|
||||
|
||||
void Outfit::setAllSlotPolicy(SlotPolicy::Mode preference) {
|
||||
if (preference >= SlotPolicy::Mode::MAX) {
|
||||
LOG(err, "Invalid slot preference {}.", preference);
|
||||
return;
|
||||
}
|
||||
slotPolicy = preference;
|
||||
}
|
||||
|
||||
void Outfit::setSlotPolicy(RE::BIPED_OBJECT slot, std::optional<SlotPolicy::Mode> policy) {
|
||||
if (slot >= RE::BIPED_OBJECTS_META::numSlots) {
|
||||
if (slot >= RE::BIPED_OBJECTS_META::kNumSlots) {
|
||||
LOG(err, "Invalid slot {}.", static_cast<std::uint32_t>(slot));
|
||||
return;
|
||||
}
|
||||
|
|
@ -72,30 +58,41 @@ void Outfit::setSlotPolicy(RE::BIPED_OBJECT slot, std::optional<SlotPolicy::Mode
|
|||
}
|
||||
}
|
||||
|
||||
void Outfit::setBlanketSlotPolicy(SlotPolicy::Mode policy) {
|
||||
if (policy >= SlotPolicy::Mode::MAX) {
|
||||
LOG(err, "Invalid slot preference {}.", policy);
|
||||
return;
|
||||
}
|
||||
slotPolicy = policy;
|
||||
}
|
||||
|
||||
std::unordered_set<RE::TESObjectARMO*> Outfit::computeDisplaySet(const std::unordered_set<RE::TESObjectARMO*>& equippedSet) {
|
||||
std::unordered_set<RE::TESObjectARMO*> result;
|
||||
|
||||
std::array<RE::TESObjectARMO*, RE::BIPED_OBJECTS_META::numSlots> equipped{nullptr};
|
||||
std::array<RE::TESObjectARMO*, RE::BIPED_OBJECTS_META::numSlots> outfit{nullptr};
|
||||
std::uint32_t occupiedMask = 0;
|
||||
// Helper function that assigns the armor's to the positions in an array that match the armor's slot mask.
|
||||
auto assignToMatchingSlots = [](std::array<RE::TESObjectARMO*, RE::BIPED_OBJECTS_META::kNumSlots>& dest, RE::TESObjectARMO* armor) {
|
||||
auto mask = static_cast<uint32_t>(armor->GetSlotMask());
|
||||
for (auto slot = RE::BIPED_OBJECTS_META::kFirstSlot; slot < RE::BIPED_OBJECTS_META::kNumSlots; slot++) {
|
||||
if (mask & (1 << slot)) dest[slot] = armor;
|
||||
}
|
||||
};
|
||||
|
||||
// Get the list with the equipped armor in each slot
|
||||
std::array<RE::TESObjectARMO*, RE::BIPED_OBJECTS_META::kNumSlots> equipped{nullptr};
|
||||
for (auto armor : equippedSet) {
|
||||
if (!armor) continue;
|
||||
auto mask = static_cast<uint32_t>(armor->GetSlotMask());
|
||||
for (auto slot = RE::BIPED_OBJECTS_META::firstSlot; slot < RE::BIPED_OBJECTS_META::numSlots; slot++) {
|
||||
if (mask & (1 << slot)) equipped[slot] = armor;
|
||||
}
|
||||
assignToMatchingSlots(equipped, armor);
|
||||
}
|
||||
|
||||
// Get the list with the outfit armor in each slot
|
||||
std::array<RE::TESObjectARMO*, RE::BIPED_OBJECTS_META::kNumSlots> outfit{nullptr};
|
||||
for (auto armor : armors) {
|
||||
if (!armor) continue;
|
||||
auto mask = static_cast<uint32_t>(armor->GetSlotMask());
|
||||
for (auto slot = RE::BIPED_OBJECTS_META::firstSlot; slot < RE::BIPED_OBJECTS_META::numSlots; slot++) {
|
||||
if (mask & (1 << slot)) outfit[slot] = armor;
|
||||
}
|
||||
assignToMatchingSlots(outfit, armor);
|
||||
}
|
||||
|
||||
for (auto slot = RE::BIPED_OBJECTS_META::firstSlot; slot < RE::BIPED_OBJECTS_META::numSlots; slot++) {
|
||||
// Go pairwise through the two lists and select what goes in the results slot
|
||||
std::unordered_set<RE::TESObjectARMO*> result;
|
||||
std::uint32_t occupiedMask = 0;
|
||||
for (auto slot = RE::BIPED_OBJECTS_META::kFirstSlot; slot < RE::BIPED_OBJECTS_META::kNumSlots; slot++) {
|
||||
// Someone before us already got this slot.
|
||||
if (occupiedMask & (1 << slot)) continue;
|
||||
// Select the slot's policy, falling back to the outfit's policy if none.
|
||||
|
|
@ -105,14 +102,14 @@ std::unordered_set<RE::TESObjectARMO*> Outfit::computeDisplaySet(const std::unor
|
|||
auto selection = SlotPolicy::select(preference, equipped[slot], outfit[slot]);
|
||||
RE::TESObjectARMO* selectedArmor = nullptr;
|
||||
switch (selection) {
|
||||
case SlotPolicy::Selection::EMPTY:
|
||||
break;
|
||||
case SlotPolicy::Selection::EQUIPPED:
|
||||
selectedArmor = equipped[slot];
|
||||
break;
|
||||
case SlotPolicy::Selection::OUTFIT:
|
||||
selectedArmor = outfit[slot];
|
||||
break;
|
||||
case SlotPolicy::Selection::EMPTY:
|
||||
break;
|
||||
}
|
||||
if (!selectedArmor) continue;
|
||||
occupiedMask |= static_cast<uint32_t>(selectedArmor->GetSlotMask());
|
||||
|
|
@ -157,7 +154,7 @@ void Outfit::load(const proto::Outfit& proto, const SKSE::SerializationInterface
|
|||
for (const auto& pair : proto.slot_policies()) {
|
||||
auto slot = static_cast<RE::BIPED_OBJECT>(pair.first);
|
||||
auto policy = static_cast<SlotPolicy::Mode>(pair.second);
|
||||
if (slot >= RE::BIPED_OBJECTS_META::numSlots) {
|
||||
if (slot >= RE::BIPED_OBJECTS_META::kNumSlots) {
|
||||
LOG(err, "Invalid slot {}.", static_cast<std::uint32_t>(slot));
|
||||
continue;
|
||||
}
|
||||
|
|
@ -588,44 +585,45 @@ void ArmorAddonOverrideService::dump() const {
|
|||
LOG(info, "All state has been dumped.");
|
||||
}
|
||||
|
||||
// Negative values mean "advanced option"
|
||||
std::array<SlotPolicy::Metadata, SlotPolicy::MAX> SlotPolicy::g_policiesMetadata = {
|
||||
SlotPolicy::Metadata{"XXXX", 100, true}, // Never show anything
|
||||
SlotPolicy::Metadata{"XXXE", 101, true}, // If outfit and equipped, show equipped
|
||||
SlotPolicy::Metadata{"XXXO", 2, false}, // If outfit and equipped, show outfit (require equipped, no passthrough)
|
||||
SlotPolicy::Metadata{"XXOX", 102, true}, // If only outfit, show outfit
|
||||
SlotPolicy::Metadata{"XXOE", 103, true}, // If only outfit, show outfit. If both, show equipped
|
||||
SlotPolicy::Metadata{"XXOO", 1, false}, // If outfit, show outfit (always show outfit, no passthough)
|
||||
SlotPolicy::Metadata{"XEXX", 104, true}, // If only equipped, show equipped
|
||||
SlotPolicy::Metadata{"XEXE", 105, true}, // If equipped, show equipped
|
||||
SlotPolicy::Metadata{"XEXO", 3, false}, // If only equipped, show equipped. If both, show outfit
|
||||
SlotPolicy::Metadata{"XEOX", 106, true}, // If only equipped, show equipped. If only outfit, show outfit
|
||||
SlotPolicy::Metadata{"XEOE", 107, true}, // If only equipped, show equipped. If only outfit, show outfit. If both, show equipped
|
||||
SlotPolicy::Metadata{"XEOO", 108, true} // If only equipped, show equipped. If only outfit, show outfit. If both, show outfit
|
||||
};
|
||||
namespace SlotPolicy {
|
||||
// Negative values mean "advanced option"
|
||||
std::array<Metadata, MAX> g_policiesMetadata = {
|
||||
Metadata{"XXXX", 100, true}, // Never show anything
|
||||
Metadata{"XXXE", 101, true}, // If outfit and equipped, show equipped
|
||||
Metadata{"XXXO", 2, false}, // If outfit and equipped, show outfit (require equipped, no passthrough)
|
||||
Metadata{"XXOX", 102, true}, // If only outfit, show outfit
|
||||
Metadata{"XXOE", 103, true}, // If only outfit, show outfit. If both, show equipped
|
||||
Metadata{"XXOO", 1, false}, // If outfit, show outfit (always show outfit, no passthough)
|
||||
Metadata{"XEXX", 104, true}, // If only equipped, show equipped
|
||||
Metadata{"XEXE", 105, true}, // If equipped, show equipped
|
||||
Metadata{"XEXO", 3, false}, // If only equipped, show equipped. If both, show outfit
|
||||
Metadata{"XEOX", 106, true}, // If only equipped, show equipped. If only outfit, show outfit
|
||||
Metadata{"XEOE", 107, true}, // If only equipped, show equipped. If only outfit, show outfit. If both, show equipped
|
||||
Metadata{"XEOO", 108, true} // If only equipped, show equipped. If only outfit, show outfit. If both, show outfit
|
||||
};
|
||||
|
||||
SlotPolicy::Selection SlotPolicy::select(SlotPolicy::Mode policy, bool hasEquipped, bool hasOutfit) {
|
||||
if (policy >= Mode::MAX) {
|
||||
LOG(err, "Invalid slot preference {}", policy);
|
||||
policy = Mode::XXXX;
|
||||
}
|
||||
char out = 'X';
|
||||
if (!hasEquipped && !hasOutfit) {
|
||||
out = g_policiesMetadata[policy].code[0];
|
||||
} else if (hasEquipped && !hasOutfit) {
|
||||
out = g_policiesMetadata[policy].code[1];
|
||||
} else if (!hasEquipped && hasOutfit) {
|
||||
out = g_policiesMetadata[policy].code[2];
|
||||
} else if (hasEquipped && hasOutfit) {
|
||||
out = g_policiesMetadata[policy].code[3];
|
||||
}
|
||||
if (out == 'X') {
|
||||
return SlotPolicy::Selection::EMPTY;
|
||||
} else if (out == 'E') {
|
||||
return SlotPolicy::Selection::EQUIPPED;
|
||||
} else if (out == 'O') {
|
||||
return SlotPolicy::Selection::OUTFIT;
|
||||
} else {
|
||||
return SlotPolicy::Selection::EMPTY;
|
||||
Selection select(Mode policy, bool hasEquipped, bool hasOutfit) {
|
||||
if (policy >= Mode::MAX) {
|
||||
LOG(err, "Invalid slot preference {}", policy);
|
||||
policy = Mode::XXXX;
|
||||
}
|
||||
char out;
|
||||
if (!hasEquipped && !hasOutfit) {
|
||||
out = g_policiesMetadata[policy].code[0];
|
||||
} else if (hasEquipped && !hasOutfit) {
|
||||
out = g_policiesMetadata[policy].code[1];
|
||||
} else if (!hasEquipped && hasOutfit) {
|
||||
out = g_policiesMetadata[policy].code[2];
|
||||
} else if (hasEquipped && hasOutfit) {
|
||||
out = g_policiesMetadata[policy].code[3];
|
||||
}
|
||||
switch (out) {
|
||||
case 'E':
|
||||
return Selection::EQUIPPED;
|
||||
case 'O':
|
||||
return Selection::OUTFIT;
|
||||
default:
|
||||
return Selection::EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -372,7 +372,7 @@ namespace OutfitSystem {
|
|||
std::vector<RE::BSFixedString> result;
|
||||
auto& service = ArmorAddonOverrideService::GetInstance();
|
||||
auto& outfit = service.getOutfit(name.data());
|
||||
for (auto slot = RE::BIPED_OBJECTS_META::firstSlot; slot < RE::BIPED_OBJECTS_META::numSlots; slot++) {
|
||||
for (auto slot = RE::BIPED_OBJECTS_META::kFirstSlot; slot < RE::BIPED_OBJECTS_META::kNumSlots; slot++) {
|
||||
auto slotSpecificPolicy = outfit.slotPolicies.find(static_cast<RE::BIPED_OBJECT>(slot));
|
||||
if (slotSpecificPolicy != outfit.slotPolicies.end()) {
|
||||
result.emplace_back(SlotPolicy::g_policiesMetadata.at(static_cast<char>(slotSpecificPolicy->second)).translationKey());
|
||||
|
|
@ -393,7 +393,7 @@ namespace OutfitSystem {
|
|||
LogExit exitPrint("BodySlotPolicy.SetBodySlotPoliciesForOutfit"sv);
|
||||
auto& service = ArmorAddonOverrideService::GetInstance();
|
||||
auto& outfit = service.getOutfit(name.data());
|
||||
if (slot >= RE::BIPED_OBJECTS_META::numSlots) {
|
||||
if (slot >= RE::BIPED_OBJECTS_META::kNumSlots) {
|
||||
LOG(err, "Invalid slot {}.", static_cast<std::uint32_t>(slot));
|
||||
return;
|
||||
}
|
||||
|
|
@ -421,7 +421,7 @@ namespace OutfitSystem {
|
|||
return first.code == codeString;
|
||||
});
|
||||
if (found == SlotPolicy::g_policiesMetadata.end()) return;
|
||||
outfit.setAllSlotPolicy(static_cast<SlotPolicy::Mode>(found - SlotPolicy::g_policiesMetadata.begin()));
|
||||
outfit.setBlanketSlotPolicy(static_cast<SlotPolicy::Mode>(found - SlotPolicy::g_policiesMetadata.begin()));
|
||||
}
|
||||
void SetBodySlotPolicyToDefaultForOutfit(RE::BSScript::IVirtualMachine* registry,
|
||||
std::uint32_t stackId,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue