proper vending machines like fully, performance
This commit is contained in:
Milxnor
2023-05-08 22:28:32 -04:00
parent d5c95ac978
commit b64f569551
22 changed files with 399 additions and 221 deletions

View File

@@ -1,6 +1,9 @@
#pragma once
#include <vector>
#include <random>
#include <map>
#include <numeric>
#include "Array.h"
#include "FortWorldItemDefinition.h"
@@ -70,6 +73,12 @@ public:
return *(FName*)(__int64(this) + TierGroupOffset);
}
int& GetLootTier()
{
static auto LootTierOffset = FindOffsetStruct("/Script/FortniteGame.FortLootTierData", "LootTier");
return *(int*)(__int64(this) + LootTierOffset);
}
float& GetWeight()
{
static auto WeightOffset = FindOffsetStruct("/Script/FortniteGame.FortLootTierData", "Weight");
@@ -115,4 +124,63 @@ struct LootDrop
}
};
std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint = false, int recursive = 0);
static inline float RandomFloatForLoot(float AllWeightsSum)
{
return (rand() * 0.000030518509) * AllWeightsSum;
}
template <typename KeyType, typename ValueType>
FORCEINLINE static ValueType PickWeightedElement(const std::map<KeyType, ValueType>& Elements,
std::function<float(ValueType)> GetWeightFn,
std::function<float(float)> RandomFloatGenerator = RandomFloatForLoot,
float TotalWeightParam = -1, bool bCheckIfWeightIsZero = false, int RandMultiplier = 1, KeyType* OutName = nullptr, bool bPrint = false, bool bKeepGoingUntilWeGetValue = false)
{
float TotalWeight = TotalWeightParam;
if (TotalWeight == -1)
{
TotalWeight = std::accumulate(Elements.begin(), Elements.end(), 0.0f, [&](float acc, const std::pair<KeyType, ValueType>& p) {
auto Weight = GetWeightFn(p.second);
if (bPrint && Weight != 0)
{
LOG_INFO(LogLoot, "Adding weight: {}", Weight);
}
return acc + Weight;
});
}
float RandomNumber = // UKismetMathLibrary::RandomFloatInRange(0, TotalWeight);
RandMultiplier * RandomFloatGenerator(TotalWeight);
if (bPrint)
{
LOG_INFO(LogLoot, "RandomNumber: {} TotalWeight: {}", RandomNumber, TotalWeight);
}
for (auto& Element : Elements)
{
float Weight = GetWeightFn(Element.second);
if (bCheckIfWeightIsZero && Weight == 0)
continue;
if (RandomNumber <= Weight)
{
if (OutName)
*OutName = Element.first;
return Element.second;
}
RandomNumber -= Weight;
}
if (bKeepGoingUntilWeGetValue)
return PickWeightedElement<KeyType, ValueType>(Elements, GetWeightFn, RandomFloatGenerator, TotalWeightParam, bCheckIfWeightIsZero, RandMultiplier, OutName, bPrint, bKeepGoingUntilWeGetValue);
return ValueType();
}
std::vector<LootDrop> PickLootDrops(FName TierGroupName, int ForcedLootTier = -1, bool bPrint = false, int recursive = 0);