11#include " Tweaks.h"
2+ #include " Cache.h"
23
34// removes steal tag if all faction members have appropriate relationship rank
45namespace Tweaks ::FactionStealing
56{
67 struct detail
78 {
8- static std::int32_t GetFavorCost (RE::TESNPC* a_player, RE::TESNPC* a_owner)
9+ static std::int32_t GetRelationshipFavorPointsValue (RE::TESNPC* a_player, RE::TESNPC* a_owner)
910 {
10- using func_t = decltype (&GetFavorCost );
11+ using func_t = decltype (&GetRelationshipFavorPointsValue );
1112 static REL::Relocation<func_t > func{ REL_ID (23626 , 24078 ) };
1213 return func (a_player, a_owner);
1314 }
1415
1516 static bool CanTake (RE::TESNPC* a_playerBase, RE::TESNPC* a_npc, std::int32_t a_cost)
1617 {
17- const auto favorCost = GetFavorCost (a_playerBase, a_npc);
18- return favorCost > 1 ?
19- a_cost <= favorCost :
18+ const auto favorPoints = GetRelationshipFavorPointsValue (a_playerBase, a_npc);
19+ return favorPoints > 1 ?
20+ a_cost <= favorPoints :
2021 false ;
2122 }
2223 };
2324
24- struct CanTake
25+ struct IsFriendAnOwner
2526 {
2627 static bool func (const RE::PlayerCharacter* a_player, RE::TESForm* a_owner, std::int32_t a_cost)
2728 {
@@ -43,21 +44,24 @@ namespace Tweaks::FactionStealing
4344 return true ;
4445 }
4546
46- std::vector<RE::TESNPC*> factionNPCs{};
47-
48- for (auto & npc : RE::TESDataHandler::GetSingleton ()->GetFormArray <RE::TESNPC>()) {
49- if (npc && !npc->IsDeleted ()) {
50- if (npc->IsInFaction (faction)) {
51- factionNPCs.push_back (npc);
52- } else if (auto actor = npc->GetUniqueActor (); actor && actor->IsInFaction (faction)) {
53- factionNPCs.push_back (npc);
47+ static Map<RE::TESFaction*, std::vector<RE::TESNPC*>> factionNPCMap{};
48+ if (factionNPCMap.empty ()) {
49+ for (auto & npc : RE::TESDataHandler::GetSingleton ()->GetFormArray <RE::TESNPC>()) {
50+ if (npc && !npc->IsDeleted ()) {
51+ for (auto & factionRank : npc->factions ) {
52+ if (factionRank.faction ) {
53+ factionNPCMap[factionRank.faction ].push_back (npc);
54+ }
55+ }
5456 }
5557 }
5658 }
5759
58- return std::ranges::all_of (factionNPCs, [&](const auto & npc) {
59- return detail::CanTake (playerBase, npc, a_cost);
60- });
60+ if (auto it = factionNPCMap.find (faction); it != factionNPCMap.end ()) {
61+ return std::ranges::all_of (it->second , [&](const auto & npc) {
62+ return detail::CanTake (playerBase, npc, a_cost);
63+ });
64+ }
6165 }
6266
6367 return false ;
@@ -73,7 +77,7 @@ namespace Tweaks::FactionStealing
7377 void Install ()
7478 {
7579 REL::Relocation<std::uintptr_t > func{ REL_ID (39584 , 40670 ) };
76- stl::asm_replace<CanTake >(func.address ());
80+ stl::asm_replace<IsFriendAnOwner >(func.address ());
7781
7882 logger::info (" \t\t Installed faction stealing tweak" sv);
7983 }
0 commit comments