mirror of
https://github.com/Milxnor/Project-Reboot-3.0.git
synced 2026-01-13 02:42:22 +01:00
a bit
proper vending machines like fully, performance
This commit is contained in:
@@ -71,15 +71,31 @@ public:
|
|||||||
ArrayMax = v3;
|
ArrayMax = v3;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AddUnitialized2(SIZE_T NumBytesPerElement = sizeof(InElementType))
|
void RefitArray(SIZE_T NumBytesPerElement = sizeof(InElementType))
|
||||||
|
{
|
||||||
|
auto newNum = ArrayNum;
|
||||||
|
|
||||||
|
// newNum = FMemory::QuantizeSize(NumBytesPerElement * newNum, 0) >> 4
|
||||||
|
|
||||||
|
ArrayMax = newNum;
|
||||||
|
|
||||||
|
if (Data || ArrayNum)
|
||||||
|
{
|
||||||
|
Data = false ? (InElementType*)VirtualAlloc(0, newNum * NumBytesPerElement, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE) :
|
||||||
|
(InElementType*)FMemory::Realloc(Data, newNum * NumBytesPerElement, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int AddUninitialized2(SIZE_T NumBytesPerElement = sizeof(InElementType))
|
||||||
{
|
{
|
||||||
const int OldArrayNum = ArrayNum;
|
const int OldArrayNum = ArrayNum;
|
||||||
|
|
||||||
ArrayNum = OldArrayNum + 1;
|
ArrayNum = OldArrayNum + 1;
|
||||||
|
|
||||||
if (ArrayNum > ArrayMax)
|
if (OldArrayNum + 1 > ArrayMax)
|
||||||
{
|
{
|
||||||
ResizeArray(ArrayNum, NumBytesPerElement);
|
RefitArray(NumBytesPerElement);
|
||||||
|
// ResizeArray(ArrayNum, NumBytesPerElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
return OldArrayNum;
|
return OldArrayNum;
|
||||||
@@ -87,7 +103,7 @@ public:
|
|||||||
|
|
||||||
void CopyFromArray(TArray<InElementType>& OtherArray, SIZE_T NumBytesPerElement = sizeof(InElementType))
|
void CopyFromArray(TArray<InElementType>& OtherArray, SIZE_T NumBytesPerElement = sizeof(InElementType))
|
||||||
{
|
{
|
||||||
if (!OtherArray.ArrayNum && !ArrayMax)
|
if (!OtherArray.ArrayNum && !ArrayMax) // so if the new array has nothing, and we currently have nothing allocated, then we can just return
|
||||||
{
|
{
|
||||||
ArrayMax = 0;
|
ArrayMax = 0;
|
||||||
return;
|
return;
|
||||||
@@ -235,7 +251,7 @@ public:
|
|||||||
ArrayMax = ArrayNum; // CalculateSlackGrow(/* ArrayNum */ OldNum, ArrayMax, Size);
|
ArrayMax = ArrayNum; // CalculateSlackGrow(/* ArrayNum */ OldNum, ArrayMax, Size);
|
||||||
// AllocatorInstance.ResizeAllocation(OldNum, ArrayMax, sizeof(ElementType));
|
// AllocatorInstance.ResizeAllocation(OldNum, ArrayMax, sizeof(ElementType));
|
||||||
// LOG_INFO(LogMemory, "ArrayMax: {} Size: {}", ArrayMax, Size);
|
// LOG_INFO(LogMemory, "ArrayMax: {} Size: {}", ArrayMax, Size);
|
||||||
Data = (InElementType*)FMemory::Realloc(Data, ArrayMax * Size, 0);
|
Data = (InElementType*)FMemory::Realloc(Data, ArrayNum * Size, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE int32 AddUninitialized(int32 Count = 1, size_t Size = sizeof(InElementType))
|
FORCEINLINE int32 AddUninitialized(int32 Count = 1, size_t Size = sizeof(InElementType))
|
||||||
@@ -308,10 +324,17 @@ public:
|
|||||||
|
|
||||||
void FreeGood(SizeType Size = sizeof(InElementType))
|
void FreeGood(SizeType Size = sizeof(InElementType))
|
||||||
{
|
{
|
||||||
static void (*FreeOriginal)(void* Original) = decltype(FreeOriginal)(Addresses::Free);
|
if (true)
|
||||||
|
{
|
||||||
|
static void (*FreeOriginal)(void* Original) = decltype(FreeOriginal)(Addresses::Free);
|
||||||
|
|
||||||
if (FreeOriginal)
|
if (FreeOriginal)
|
||||||
FreeOriginal(Data);
|
FreeOriginal(Data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VirtualFree(Data, 0, MEM_RELEASE);
|
||||||
|
}
|
||||||
|
|
||||||
Data = nullptr;
|
Data = nullptr;
|
||||||
ArrayNum = 0;
|
ArrayNum = 0;
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ static inline void SpawnBGAs() // hahah not "proper", there's a function that we
|
|||||||
static auto SpawnLootTierGroupOffset = BGAConsumableSpawner->GetOffset("SpawnLootTierGroup");
|
static auto SpawnLootTierGroupOffset = BGAConsumableSpawner->GetOffset("SpawnLootTierGroup");
|
||||||
auto& SpawnLootTierGroup = BGAConsumableSpawner->Get<FName>(SpawnLootTierGroupOffset);
|
auto& SpawnLootTierGroup = BGAConsumableSpawner->Get<FName>(SpawnLootTierGroupOffset);
|
||||||
|
|
||||||
auto LootDrops = PickLootDrops(SpawnLootTierGroup, false);
|
auto LootDrops = PickLootDrops(SpawnLootTierGroup);
|
||||||
|
|
||||||
for (int z = 0; z < LootDrops.size(); z++)
|
for (int z = 0; z < LootDrops.size(); z++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ bool ABuildingContainer::SpawnLoot(AFortPawn* Pawn)
|
|||||||
|
|
||||||
// LOG_INFO(LogInteraction, "RedirectedLootTier: {}", RedirectedLootTier.ToString());
|
// LOG_INFO(LogInteraction, "RedirectedLootTier: {}", RedirectedLootTier.ToString());
|
||||||
|
|
||||||
auto LootDrops = PickLootDrops(RedirectedLootTier, bDebugPrintLooting);
|
auto LootDrops = PickLootDrops(RedirectedLootTier, -1, bDebugPrintLooting);
|
||||||
|
|
||||||
// LOG_INFO(LogInteraction, "LootDrops.size(): {}", LootDrops.size());
|
// LOG_INFO(LogInteraction, "LootDrops.size(): {}", LootDrops.size());
|
||||||
|
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ AFortPickup* AFortAthenaSupplyDrop::SpawnPickupHook(UObject* Context, FFrame& St
|
|||||||
CreateData.SpawnLocation = Position;
|
CreateData.SpawnLocation = Position;
|
||||||
CreateData.PawnOwner = TriggeringPawn;
|
CreateData.PawnOwner = TriggeringPawn;
|
||||||
CreateData.Source = EFortPickupSpawnSource::GetSupplyDropValue();
|
CreateData.Source = EFortPickupSpawnSource::GetSupplyDropValue();
|
||||||
|
CreateData.bShouldFreeItemEntryWhenDeconstructed = true;
|
||||||
|
|
||||||
*Ret = AFortPickup::SpawnPickup(CreateData);
|
*Ret = AFortPickup::SpawnPickup(CreateData);
|
||||||
return *Ret;
|
return *Ret;
|
||||||
|
|||||||
@@ -968,7 +968,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
|||||||
auto Location = CurrentActor->GetActorLocation();
|
auto Location = CurrentActor->GetActorLocation();
|
||||||
Location.Z += UpZ;
|
Location.Z += UpZ;
|
||||||
|
|
||||||
std::vector<LootDrop> LootDrops = PickLootDrops(SpawnIslandTierGroup, bPrintWarmup);
|
std::vector<LootDrop> LootDrops = PickLootDrops(SpawnIslandTierGroup, -1, bPrintWarmup);
|
||||||
|
|
||||||
for (auto& LootDrop : LootDrops)
|
for (auto& LootDrop : LootDrops)
|
||||||
{
|
{
|
||||||
@@ -998,7 +998,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
|||||||
auto Location = CurrentActor->GetActorLocation();
|
auto Location = CurrentActor->GetActorLocation();
|
||||||
Location.Z += UpZ;
|
Location.Z += UpZ;
|
||||||
|
|
||||||
std::vector<LootDrop> LootDrops = PickLootDrops(BRIslandTierGroup, bPrint);
|
std::vector<LootDrop> LootDrops = PickLootDrops(BRIslandTierGroup, -1, bPrint);
|
||||||
|
|
||||||
for (auto& LootDrop : LootDrops)
|
for (auto& LootDrop : LootDrops)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AFortInventory::AddI
|
|||||||
CreateData.SpawnLocation = Pawn->GetActorLocation();
|
CreateData.SpawnLocation = Pawn->GetActorLocation();
|
||||||
CreateData.PawnOwner = Cast<AFortPawn>(Pawn);
|
CreateData.PawnOwner = Cast<AFortPawn>(Pawn);
|
||||||
CreateData.SourceType = EFortPickupSourceTypeFlag::GetPlayerValue();
|
CreateData.SourceType = EFortPickupSourceTypeFlag::GetPlayerValue();
|
||||||
|
CreateData.bShouldFreeItemEntryWhenDeconstructed = true;
|
||||||
|
|
||||||
AFortPickup::SpawnPickup(CreateData);
|
AFortPickup::SpawnPickup(CreateData);
|
||||||
return std::make_pair(NewItemInstances, ModifiedItemInstances);
|
return std::make_pair(NewItemInstances, ModifiedItemInstances);
|
||||||
@@ -238,7 +239,13 @@ std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AFortInventory::AddI
|
|||||||
|
|
||||||
auto ItemEntry = FFortItemEntry::MakeItemEntry(ItemDefinition, Count, LoadedAmmo);
|
auto ItemEntry = FFortItemEntry::MakeItemEntry(ItemDefinition, Count, LoadedAmmo);
|
||||||
auto Ret = AddItem(ItemEntry, bShouldUpdate, bShowItemToast);
|
auto Ret = AddItem(ItemEntry, bShouldUpdate, bShowItemToast);
|
||||||
// VirtualFree(ItemEntry);
|
|
||||||
|
if (!bUseFMemoryRealloc)
|
||||||
|
{
|
||||||
|
FFortItemEntry::FreeItemEntry(ItemEntry);
|
||||||
|
VirtualFree(ItemEntry, 0, MEM_RELEASE);
|
||||||
|
}
|
||||||
|
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ void FFortItemEntry::SetStateValue(EFortItemEntryState StateType, int IntValue)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto idx = GetStateValues().AddUnitialized2(FFortItemEntryStateValue::GetStructSize());
|
auto idx = GetStateValues().AddUninitialized2(FFortItemEntryStateValue::GetStructSize()); // AddUninitialized?
|
||||||
|
|
||||||
GetStateValues().AtPtr(idx, FFortItemEntryStateValue::GetStructSize())->GetIntValue() = IntValue;
|
GetStateValues().AtPtr(idx, FFortItemEntryStateValue::GetStructSize())->GetIntValue() = IntValue;
|
||||||
GetStateValues().AtPtr(idx, FFortItemEntryStateValue::GetStructSize())->GetStateType() = StateType;
|
GetStateValues().AtPtr(idx, FFortItemEntryStateValue::GetStructSize())->GetStateType() = StateType;
|
||||||
@@ -27,7 +27,6 @@ void FFortItemEntry::SetStateValue(EFortItemEntryState StateType, int IntValue)
|
|||||||
|
|
||||||
FFortItemEntry* FFortItemEntry::MakeItemEntry(UFortItemDefinition* ItemDefinition, int Count, int LoadedAmmo, float Durability)
|
FFortItemEntry* FFortItemEntry::MakeItemEntry(UFortItemDefinition* ItemDefinition, int Count, int LoadedAmmo, float Durability)
|
||||||
{
|
{
|
||||||
bool bUseFMemoryRealloc = false; // I don't think this works because sometimes we don't free it (oops).
|
|
||||||
auto Entry = Alloc<FFortItemEntry>(GetStructSize(), bUseFMemoryRealloc);
|
auto Entry = Alloc<FFortItemEntry>(GetStructSize(), bUseFMemoryRealloc);
|
||||||
|
|
||||||
if (!Entry)
|
if (!Entry)
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#include "reboot.h"
|
#include "reboot.h"
|
||||||
|
|
||||||
|
constexpr inline bool bUseFMemoryRealloc = false; // This is for allocating our own Item entries, I don't know why this doesn't work
|
||||||
|
|
||||||
enum class EFortItemEntryState : uint8_t // this changes but its fineee
|
enum class EFortItemEntryState : uint8_t // this changes but its fineee
|
||||||
{
|
{
|
||||||
NoneState = 0,
|
NoneState = 0,
|
||||||
@@ -32,7 +34,7 @@ struct FFortItemEntryStateValue
|
|||||||
{
|
{
|
||||||
static UStruct* GetStruct()
|
static UStruct* GetStruct()
|
||||||
{
|
{
|
||||||
static auto Struct = FindObject<UStruct>("/Script/FortniteGame.FortItemEntryStateValue");
|
static auto Struct = FindObject<UStruct>(L"/Script/FortniteGame.FortItemEntryStateValue");
|
||||||
return Struct;
|
return Struct;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,10 +163,10 @@ struct FFortItemEntry : FFastArraySerializerItem
|
|||||||
|
|
||||||
if (GenericAttributeValuesOffset != -1)
|
if (GenericAttributeValuesOffset != -1)
|
||||||
{
|
{
|
||||||
this->GetGenericAttributeValues().CopyFromArray(OtherItemEntry->GetGenericAttributeValues());
|
// this->GetGenericAttributeValues().CopyFromArray(OtherItemEntry->GetGenericAttributeValues());
|
||||||
}
|
}
|
||||||
|
|
||||||
this->GetStateValues().CopyFromArray(OtherItemEntry->GetStateValues(), FFortItemEntryStateValue::GetStructSize());
|
// this->GetStateValues().CopyFromArray(OtherItemEntry->GetStateValues(), FFortItemEntryStateValue::GetStructSize()); // broooooooooooooooooooo
|
||||||
|
|
||||||
// should we do this?
|
// should we do this?
|
||||||
|
|
||||||
@@ -177,7 +179,7 @@ struct FFortItemEntry : FFastArraySerializerItem
|
|||||||
|
|
||||||
static UStruct* GetStruct()
|
static UStruct* GetStruct()
|
||||||
{
|
{
|
||||||
static auto Struct = FindObject<UStruct>("/Script/FortniteGame.FortItemEntry");
|
static auto Struct = FindObject<UStruct>(L"/Script/FortniteGame.FortItemEntry");
|
||||||
return Struct;
|
return Struct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -140,6 +140,8 @@ void UFortKismetLibrary::SpawnItemVariantPickupInWorldHook(UObject* Context, FFr
|
|||||||
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(ItemDefinition, ParamsPtr->GetNumberToSpawn(), -1);
|
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(ItemDefinition, ParamsPtr->GetNumberToSpawn(), -1);
|
||||||
CreateData.SourceType = ParamsPtr->GetSourceType();
|
CreateData.SourceType = ParamsPtr->GetSourceType();
|
||||||
CreateData.Source = ParamsPtr->GetSource();
|
CreateData.Source = ParamsPtr->GetSource();
|
||||||
|
CreateData.bShouldFreeItemEntryWhenDeconstructed = true;
|
||||||
|
|
||||||
auto Pickup = AFortPickup::SpawnPickup(CreateData);
|
auto Pickup = AFortPickup::SpawnPickup(CreateData);
|
||||||
|
|
||||||
return SpawnItemVariantPickupInWorldOriginal(Context, Stack, Ret);
|
return SpawnItemVariantPickupInWorldOriginal(Context, Stack, Ret);
|
||||||
@@ -228,6 +230,7 @@ void UFortKismetLibrary::CreateTossAmmoPickupForWeaponItemDefinitionAtLocationHo
|
|||||||
CreateData.SourceType = SourceTypeFlag;
|
CreateData.SourceType = SourceTypeFlag;
|
||||||
CreateData.Source = SpawnSource;
|
CreateData.Source = SpawnSource;
|
||||||
CreateData.SpawnLocation = Location;
|
CreateData.SpawnLocation = Location;
|
||||||
|
CreateData.bShouldFreeItemEntryWhenDeconstructed = true;
|
||||||
|
|
||||||
auto AmmoPickup = AFortPickup::SpawnPickup(CreateData);
|
auto AmmoPickup = AFortPickup::SpawnPickup(CreateData);
|
||||||
|
|
||||||
@@ -511,6 +514,7 @@ AFortPickup* UFortKismetLibrary::K2_SpawnPickupInWorldWithClassHook(UObject* Con
|
|||||||
CreateData.OverrideClass = PickupClass;
|
CreateData.OverrideClass = PickupClass;
|
||||||
CreateData.bToss = bToss;
|
CreateData.bToss = bToss;
|
||||||
CreateData.bRandomRotation = bRandomRotation;
|
CreateData.bRandomRotation = bRandomRotation;
|
||||||
|
CreateData.bShouldFreeItemEntryWhenDeconstructed = true;
|
||||||
|
|
||||||
auto NewPickup = AFortPickup::SpawnPickup(CreateData);
|
auto NewPickup = AFortPickup::SpawnPickup(CreateData);
|
||||||
|
|
||||||
@@ -597,7 +601,7 @@ bool UFortKismetLibrary::PickLootDropsHook(UObject* Context, FFrame& Stack, bool
|
|||||||
|
|
||||||
LOG_INFO(LogDev, "Picking loot for {}.", TierGroupName.ComparisonIndex.Value ? TierGroupName.ToString() : "InvalidName");
|
LOG_INFO(LogDev, "Picking loot for {}.", TierGroupName.ComparisonIndex.Value ? TierGroupName.ToString() : "InvalidName");
|
||||||
|
|
||||||
auto LootDrops = PickLootDrops(TierGroupName, true);
|
auto LootDrops = PickLootDrops(TierGroupName, -1, true);
|
||||||
|
|
||||||
for (int i = 0; i < LootDrops.size(); i++)
|
for (int i = 0; i < LootDrops.size(); i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,10 +7,6 @@
|
|||||||
#include "GameplayTagContainer.h"
|
#include "GameplayTagContainer.h"
|
||||||
#include "FortGameModeAthena.h"
|
#include "FortGameModeAthena.h"
|
||||||
|
|
||||||
#include <random>
|
|
||||||
#include <map>
|
|
||||||
#include <numeric>
|
|
||||||
|
|
||||||
struct FFortGameFeatureLootTableData
|
struct FFortGameFeatureLootTableData
|
||||||
{
|
{
|
||||||
TSoftObjectPtr<UDataTable> LootTierData;
|
TSoftObjectPtr<UDataTable> LootTierData;
|
||||||
@@ -18,10 +14,6 @@ struct FFortGameFeatureLootTableData
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_LOOTING
|
#ifdef EXPERIMENTAL_LOOTING
|
||||||
float RandomFloatForLoot(float AllWeightsSum)
|
|
||||||
{
|
|
||||||
return (rand() * 0.000030518509) * AllWeightsSum;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename RowStructType = uint8>
|
template <typename RowStructType = uint8>
|
||||||
void CollectDataTablesRows(std::vector<UDataTable*> DataTables, std::map<FName, RowStructType*>* OutMap, std::function<bool(FName, RowStructType*)> Check = []() { return true; })
|
void CollectDataTablesRows(std::vector<UDataTable*> DataTables, std::map<FName, RowStructType*>* OutMap, std::function<bool(FName, RowStructType*)> Check = []() { return true; })
|
||||||
@@ -59,54 +51,6 @@ void CollectDataTablesRows(std::vector<UDataTable*> DataTables, std::map<FName,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static T* PickWeightedElement(const std::map<FName, T*>& Elements, std::function<float(T*)> GetWeightFn, float TotalWeightParam = -1, bool bCheckIfWeightIsZero = false, int RandMultiplier = 1, FName* OutName = nullptr, bool bPrint = false)
|
|
||||||
{
|
|
||||||
float TotalWeight = TotalWeightParam;
|
|
||||||
|
|
||||||
if (TotalWeight == -1)
|
|
||||||
{
|
|
||||||
TotalWeight = std::accumulate(Elements.begin(), Elements.end(), 0.0f, [&](float acc, const std::pair<FName, T*>& 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 * RandomFloatForLoot(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
int GetItemLevel(const FDataTableCategoryHandle& LootLevelData, int WorldLevel)
|
int GetItemLevel(const FDataTableCategoryHandle& LootLevelData, int WorldLevel)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@@ -200,18 +144,20 @@ float GetAmountOfLootPackagesToDrop(FFortLootTierData* LootTierData, int Origina
|
|||||||
|
|
||||||
FFortLootTierData* PickLootTierData(const std::vector<UDataTable*>& LTDTables, FName LootTierGroup, int WorldLevel = 0, int ForcedLootTier = -1, FName* OutRowName = nullptr) // Fortnite returns the row name and then finds the tier data again, but I really don't see the point of this.
|
FFortLootTierData* PickLootTierData(const std::vector<UDataTable*>& LTDTables, FName LootTierGroup, int WorldLevel = 0, int ForcedLootTier = -1, FName* OutRowName = nullptr) // Fortnite returns the row name and then finds the tier data again, but I really don't see the point of this.
|
||||||
{
|
{
|
||||||
|
// This like isn't right, at all.
|
||||||
|
|
||||||
float LootTier = ForcedLootTier;
|
float LootTier = ForcedLootTier;
|
||||||
|
|
||||||
if (LootTier == -1)
|
if (LootTier == -1)
|
||||||
{
|
{
|
||||||
LootTier = 0;
|
// LootTier = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// buncha code im too lazy to reverse
|
// buncha code im too lazy to reverse
|
||||||
}
|
}
|
||||||
|
|
||||||
LootTier = 1; // ONG PROPER
|
// IDIakuuyg8712u091fj120gvik
|
||||||
|
|
||||||
// if (fabs(LootTier) <= 0.0000000099999999)
|
// if (fabs(LootTier) <= 0.0000000099999999)
|
||||||
// return 0;
|
// return 0;
|
||||||
@@ -219,7 +165,7 @@ FFortLootTierData* PickLootTierData(const std::vector<UDataTable*>& LTDTables, F
|
|||||||
std::map<FName, FFortLootTierData*> TierGroupLTDs;
|
std::map<FName, FFortLootTierData*> TierGroupLTDs;
|
||||||
|
|
||||||
CollectDataTablesRows<FFortLootTierData>(LTDTables, &TierGroupLTDs, [&](FName RowName, FFortLootTierData* TierData) -> bool {
|
CollectDataTablesRows<FFortLootTierData>(LTDTables, &TierGroupLTDs, [&](FName RowName, FFortLootTierData* TierData) -> bool {
|
||||||
if (LootTierGroup == TierData->GetTierGroup())
|
if (LootTierGroup == TierData->GetTierGroup() && (LootTier == -1 ? true : LootTier == TierData->GetLootTier()))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -227,9 +173,9 @@ FFortLootTierData* PickLootTierData(const std::vector<UDataTable*>& LTDTables, F
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
FFortLootTierData* ChosenRowLootTierData = PickWeightedElement<FFortLootTierData>(TierGroupLTDs,
|
FFortLootTierData* ChosenRowLootTierData = PickWeightedElement<FName, FFortLootTierData*>(TierGroupLTDs,
|
||||||
[](FFortLootTierData* LootTierData) -> float { return LootTierData->GetWeight(); }, -1,
|
[](FFortLootTierData* LootTierData) -> float { return LootTierData->GetWeight(); }, RandomFloatForLoot, -1,
|
||||||
true, LootTier, OutRowName);
|
true, LootTier == -1 ? 1 : LootTier, OutRowName);
|
||||||
|
|
||||||
if (!ChosenRowLootTierData)
|
if (!ChosenRowLootTierData)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -274,8 +220,8 @@ void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
FName PickedPackageRowName;
|
FName PickedPackageRowName;
|
||||||
FFortLootPackageData* PickedPackage = PickWeightedElement<FFortLootPackageData>(LootPackageIDMap,
|
FFortLootPackageData* PickedPackage = PickWeightedElement<FName, FFortLootPackageData*>(LootPackageIDMap,
|
||||||
[](FFortLootPackageData* LootPackageData) -> float { return LootPackageData->GetWeight(); },
|
[](FFortLootPackageData* LootPackageData) -> float { return LootPackageData->GetWeight(); }, RandomFloatForLoot,
|
||||||
-1, true, 1, &PickedPackageRowName, bPrint);
|
-1, true, 1, &PickedPackageRowName, bPrint);
|
||||||
|
|
||||||
if (!PickedPackage)
|
if (!PickedPackage)
|
||||||
@@ -377,7 +323,7 @@ void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recursive)
|
std::vector<LootDrop> PickLootDrops(FName TierGroupName, int ForcedLootTier, bool bPrint, int recursive)
|
||||||
{
|
{
|
||||||
std::vector<LootDrop> LootDrops;
|
std::vector<LootDrop> LootDrops;
|
||||||
|
|
||||||
@@ -659,7 +605,7 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recurs
|
|||||||
}
|
}
|
||||||
|
|
||||||
FName LootTierRowName;
|
FName LootTierRowName;
|
||||||
auto ChosenRowLootTierData = PickLootTierData(LTDTables, TierGroupName, 0, -1, &LootTierRowName);
|
auto ChosenRowLootTierData = PickLootTierData(LTDTables, TierGroupName, 0, ForcedLootTier, &LootTierRowName);
|
||||||
|
|
||||||
if (!ChosenRowLootTierData)
|
if (!ChosenRowLootTierData)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <random>
|
||||||
|
#include <map>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
#include "Array.h"
|
#include "Array.h"
|
||||||
#include "FortWorldItemDefinition.h"
|
#include "FortWorldItemDefinition.h"
|
||||||
@@ -70,6 +73,12 @@ public:
|
|||||||
return *(FName*)(__int64(this) + TierGroupOffset);
|
return *(FName*)(__int64(this) + TierGroupOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int& GetLootTier()
|
||||||
|
{
|
||||||
|
static auto LootTierOffset = FindOffsetStruct("/Script/FortniteGame.FortLootTierData", "LootTier");
|
||||||
|
return *(int*)(__int64(this) + LootTierOffset);
|
||||||
|
}
|
||||||
|
|
||||||
float& GetWeight()
|
float& GetWeight()
|
||||||
{
|
{
|
||||||
static auto WeightOffset = FindOffsetStruct("/Script/FortniteGame.FortLootTierData", "Weight");
|
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);
|
||||||
@@ -78,6 +78,72 @@ AFortPickup* AFortPickup::SpawnPickup(PickupCreateData& PickupData)
|
|||||||
PrimaryPickupItemEntry->CopyFromAnotherItemEntry(PickupData.ItemEntry);
|
PrimaryPickupItemEntry->CopyFromAnotherItemEntry(PickupData.ItemEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (false && PlayerState)
|
||||||
|
{
|
||||||
|
if (auto GadgetItemDefinition = Cast<UFortGadgetItemDefinition>(PrimaryPickupItemEntry->GetItemDefinition()))
|
||||||
|
{
|
||||||
|
auto ASC = PlayerState->GetAbilitySystemComponent();
|
||||||
|
|
||||||
|
if (GadgetItemDefinition->GetTrackedAttributes().Num() > 0)
|
||||||
|
{
|
||||||
|
PrimaryPickupItemEntry->SetStateValue(EFortItemEntryState::GenericAttributeValueSet, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<float> AttributeValueVector;
|
||||||
|
|
||||||
|
for (int i = 0; i < GadgetItemDefinition->GetTrackedAttributes().Num(); i++)
|
||||||
|
{
|
||||||
|
auto& CurrentTrackedAttribute = GadgetItemDefinition->GetTrackedAttributes().at(i);
|
||||||
|
|
||||||
|
// LOG_INFO(LogDev, "[{}] TrackedAttribute Attribute Property Name {}", i, GadgetItemDefinition->GetTrackedAttributes().at(i).GetAttributePropertyName());
|
||||||
|
// LOG_INFO(LogDev, "[{}] TrackedAttribute Attribute Name {}", i, GadgetItemDefinition->GetTrackedAttributes().at(i).GetAttributeName());
|
||||||
|
// LOG_INFO(LogDev, "[{}] TrackedAttribute Attribute Owner {}", i, GadgetItemDefinition->GetTrackedAttributes().at(i).AttributeOwner->GetPathName());
|
||||||
|
|
||||||
|
if (!ASC)
|
||||||
|
break;
|
||||||
|
|
||||||
|
int CurrentAttributeValue = -1;
|
||||||
|
|
||||||
|
for (int i = 0; i < ASC->GetSpawnedAttributes().Num(); i++)
|
||||||
|
{
|
||||||
|
auto CurrentSpawnedAttribute = ASC->GetSpawnedAttributes().at(i);
|
||||||
|
|
||||||
|
if (CurrentSpawnedAttribute->IsA(CurrentTrackedAttribute.AttributeOwner))
|
||||||
|
{
|
||||||
|
auto PropertyOffset = CurrentSpawnedAttribute->GetOffset(CurrentTrackedAttribute.GetAttributePropertyName());
|
||||||
|
|
||||||
|
if (PropertyOffset != -1)
|
||||||
|
{
|
||||||
|
CurrentAttributeValue = CurrentSpawnedAttribute->GetPtr<FFortGameplayAttributeData>(PropertyOffset)->GetCurrentValue();
|
||||||
|
break; // hm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LOG_INFO(LogDev, "CurrentAttributeValue: {}", CurrentAttributeValue);
|
||||||
|
|
||||||
|
if (CurrentAttributeValue != -1) // Found the attribute.
|
||||||
|
{
|
||||||
|
// im so smart
|
||||||
|
|
||||||
|
AttributeValueVector.push_back(CurrentAttributeValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int z = 0; z < PrimaryPickupItemEntry->GetGenericAttributeValues().Num(); z++) // First value must be the current value // dont ask me why fortnite keeps the old values in it too..
|
||||||
|
{
|
||||||
|
AttributeValueVector.push_back(PrimaryPickupItemEntry->GetGenericAttributeValues().at(z));
|
||||||
|
}
|
||||||
|
|
||||||
|
PrimaryPickupItemEntry->GetGenericAttributeValues().Free();
|
||||||
|
|
||||||
|
for (auto& AttributeValue : AttributeValueVector)
|
||||||
|
{
|
||||||
|
// ReplicatedEntry->GetGenericAttributeValues().Add(AttributeValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static auto PickupSourceTypeFlagsOffset = Pickup->GetOffset("PickupSourceTypeFlags", false);
|
static auto PickupSourceTypeFlagsOffset = Pickup->GetOffset("PickupSourceTypeFlags", false);
|
||||||
|
|
||||||
if (PickupSourceTypeFlagsOffset != -1)
|
if (PickupSourceTypeFlagsOffset != -1)
|
||||||
@@ -209,6 +275,7 @@ void AFortPickup::CombinePickupHook(AFortPickup* Pickup)
|
|||||||
CreateData.PawnOwner = ItemOwner;
|
CreateData.PawnOwner = ItemOwner;
|
||||||
CreateData.SourceType = EFortPickupSourceTypeFlag::GetPlayerValue();
|
CreateData.SourceType = EFortPickupSourceTypeFlag::GetPlayerValue();
|
||||||
CreateData.IgnoreCombineTarget = PickupToCombineInto;
|
CreateData.IgnoreCombineTarget = PickupToCombineInto;
|
||||||
|
CreateData.bShouldFreeItemEntryWhenDeconstructed = true;
|
||||||
|
|
||||||
auto NewOverStackPickup = AFortPickup::SpawnPickup(CreateData);
|
auto NewOverStackPickup = AFortPickup::SpawnPickup(CreateData);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,20 @@ struct PickupCreateData
|
|||||||
if (bShouldFreeItemEntryWhenDeconstructed)
|
if (bShouldFreeItemEntryWhenDeconstructed)
|
||||||
{
|
{
|
||||||
// real
|
// real
|
||||||
|
|
||||||
|
FFortItemEntry::FreeItemEntry(ItemEntry);
|
||||||
|
|
||||||
|
if (bUseFMemoryRealloc)
|
||||||
|
{
|
||||||
|
static void (*FreeOriginal)(void* Original) = decltype(FreeOriginal)(Addresses::Free);
|
||||||
|
|
||||||
|
if (FreeOriginal)
|
||||||
|
FreeOriginal(ItemEntry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VirtualFree(ItemEntry, 0, MEM_RELEASE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ void AFortPlayerController::DropAllItems(const std::vector<UFortItemDefinition*>
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
PickupCreateData CreateData;
|
PickupCreateData CreateData;
|
||||||
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(WorldItemDefinition, ItemEntry->GetCount(), ItemEntry->GetLoadedAmmo());
|
CreateData.ItemEntry = ItemEntry;
|
||||||
CreateData.SpawnLocation = Location;
|
CreateData.SpawnLocation = Location;
|
||||||
CreateData.SourceType = EFortPickupSourceTypeFlag::GetPlayerValue();
|
CreateData.SourceType = EFortPickupSourceTypeFlag::GetPlayerValue();
|
||||||
|
|
||||||
@@ -595,6 +595,7 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame*
|
|||||||
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(Entry->GetItemDefinition(), Entry->GetCount(), Entry->GetLoadedAmmo());
|
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(Entry->GetItemDefinition(), Entry->GetCount(), Entry->GetLoadedAmmo());
|
||||||
CreateData.SpawnLocation = LocationToSpawnLoot;
|
CreateData.SpawnLocation = LocationToSpawnLoot;
|
||||||
CreateData.PawnOwner = PlayerController->GetMyFortPawn(); // hmm
|
CreateData.PawnOwner = PlayerController->GetMyFortPawn(); // hmm
|
||||||
|
CreateData.bShouldFreeItemEntryWhenDeconstructed = true;
|
||||||
|
|
||||||
AFortPickup::SpawnPickup(CreateData);
|
AFortPickup::SpawnPickup(CreateData);
|
||||||
}
|
}
|
||||||
@@ -977,72 +978,6 @@ void AFortPlayerController::ServerAttemptInventoryDropHook(AFortPlayerController
|
|||||||
|
|
||||||
if (!ItemDefinition->ShouldIgnoreRespawningOnDrop() && (DropBehaviorOffset != -1 ? ItemDefinition->GetDropBehavior() != EWorldItemDropBehavior::DestroyOnDrop : true))
|
if (!ItemDefinition->ShouldIgnoreRespawningOnDrop() && (DropBehaviorOffset != -1 ? ItemDefinition->GetDropBehavior() != EWorldItemDropBehavior::DestroyOnDrop : true))
|
||||||
{
|
{
|
||||||
if (false)
|
|
||||||
{
|
|
||||||
if (auto GadgetItemDefinition = Cast<UFortGadgetItemDefinition>(ItemDefinition))
|
|
||||||
{
|
|
||||||
auto PlayerState = Cast<AFortPlayerState>(PlayerController->GetPlayerState());
|
|
||||||
auto ASC = PlayerState->GetAbilitySystemComponent();
|
|
||||||
|
|
||||||
if (GadgetItemDefinition->GetTrackedAttributes().Num() > 0)
|
|
||||||
{
|
|
||||||
ReplicatedEntry->SetStateValue(EFortItemEntryState::GenericAttributeValueSet, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<float> AttributeValueVector;
|
|
||||||
|
|
||||||
for (int i = 0; i < GadgetItemDefinition->GetTrackedAttributes().Num(); i++)
|
|
||||||
{
|
|
||||||
auto& CurrentTrackedAttribute = GadgetItemDefinition->GetTrackedAttributes().at(i);
|
|
||||||
|
|
||||||
// LOG_INFO(LogDev, "[{}] TrackedAttribute Attribute Property Name {}", i, GadgetItemDefinition->GetTrackedAttributes().at(i).GetAttributePropertyName());
|
|
||||||
// LOG_INFO(LogDev, "[{}] TrackedAttribute Attribute Name {}", i, GadgetItemDefinition->GetTrackedAttributes().at(i).GetAttributeName());
|
|
||||||
// LOG_INFO(LogDev, "[{}] TrackedAttribute Attribute Owner {}", i, GadgetItemDefinition->GetTrackedAttributes().at(i).AttributeOwner->GetPathName());
|
|
||||||
|
|
||||||
auto AbilitySystemComponent = PlayerState->GetAbilitySystemComponent();
|
|
||||||
|
|
||||||
int CurrentAttributeValue = -1;
|
|
||||||
|
|
||||||
for (int i = 0; i < AbilitySystemComponent->GetSpawnedAttributes().Num(); i++)
|
|
||||||
{
|
|
||||||
auto CurrentSpawnedAttribute = AbilitySystemComponent->GetSpawnedAttributes().at(i);
|
|
||||||
|
|
||||||
if (CurrentSpawnedAttribute->IsA(CurrentTrackedAttribute.AttributeOwner))
|
|
||||||
{
|
|
||||||
auto PropertyOffset = CurrentSpawnedAttribute->GetOffset(CurrentTrackedAttribute.GetAttributePropertyName());
|
|
||||||
|
|
||||||
if (PropertyOffset != -1)
|
|
||||||
{
|
|
||||||
CurrentAttributeValue = CurrentSpawnedAttribute->GetPtr<FFortGameplayAttributeData>(PropertyOffset)->GetCurrentValue();
|
|
||||||
break; // hm
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// LOG_INFO(LogDev, "CurrentAttributeValue: {}", CurrentAttributeValue);
|
|
||||||
|
|
||||||
if (CurrentAttributeValue != -1) // Found the attribute.
|
|
||||||
{
|
|
||||||
// im so smart
|
|
||||||
|
|
||||||
AttributeValueVector.push_back(CurrentAttributeValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int z = 0; z < ReplicatedEntry->GetGenericAttributeValues().Num(); z++) // First value must be the current value // dont ask me why fortnite keeps the old values in it too..
|
|
||||||
{
|
|
||||||
AttributeValueVector.push_back(ReplicatedEntry->GetGenericAttributeValues().at(z));
|
|
||||||
}
|
|
||||||
|
|
||||||
ReplicatedEntry->GetGenericAttributeValues().Free();
|
|
||||||
|
|
||||||
for (auto& AttributeValue : AttributeValueVector)
|
|
||||||
{
|
|
||||||
ReplicatedEntry->GetGenericAttributeValues().Add(AttributeValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Pickup = AFortPickup::SpawnPickup(ReplicatedEntry, Pawn->GetActorLocation(), EFortPickupSourceTypeFlag::GetPlayerValue(), 0, Pawn, nullptr, true, Count);
|
auto Pickup = AFortPickup::SpawnPickup(ReplicatedEntry, Pawn->GetActorLocation(), EFortPickupSourceTypeFlag::GetPlayerValue(), 0, Pawn, nullptr, true, Count);
|
||||||
|
|
||||||
if (!Pickup)
|
if (!Pickup)
|
||||||
@@ -1414,7 +1349,7 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
PickupCreateData CreateData;
|
PickupCreateData CreateData;
|
||||||
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(WorldItemDefinition, ItemEntry->GetCount(), ItemEntry->GetLoadedAmmo());
|
CreateData.ItemEntry = ItemEntry;
|
||||||
CreateData.SourceType = EFortPickupSourceTypeFlag::GetPlayerValue();
|
CreateData.SourceType = EFortPickupSourceTypeFlag::GetPlayerValue();
|
||||||
CreateData.Source = EFortPickupSpawnSource::GetPlayerEliminationValue();
|
CreateData.Source = EFortPickupSpawnSource::GetPlayerEliminationValue();
|
||||||
CreateData.SpawnLocation = DeathLocation;
|
CreateData.SpawnLocation = DeathLocation;
|
||||||
|
|||||||
@@ -234,6 +234,7 @@
|
|||||||
<ClCompile Include="GameplayStatics.cpp" />
|
<ClCompile Include="GameplayStatics.cpp" />
|
||||||
<ClCompile Include="GameState.cpp" />
|
<ClCompile Include="GameState.cpp" />
|
||||||
<ClCompile Include="GenericPlatformMath.cpp" />
|
<ClCompile Include="GenericPlatformMath.cpp" />
|
||||||
|
<ClCompile Include="inc.cpp" />
|
||||||
<ClCompile Include="InventoryManagementLibrary.cpp" />
|
<ClCompile Include="InventoryManagementLibrary.cpp" />
|
||||||
<ClCompile Include="KismetMathLibrary.cpp" />
|
<ClCompile Include="KismetMathLibrary.cpp" />
|
||||||
<ClCompile Include="KismetStringLibrary.cpp" />
|
<ClCompile Include="KismetStringLibrary.cpp" />
|
||||||
|
|||||||
@@ -268,11 +268,13 @@
|
|||||||
<ClCompile Include="FortAthenaMutator_Disco.cpp">
|
<ClCompile Include="FortAthenaMutator_Disco.cpp">
|
||||||
<Filter>FortniteGame\Source\FortniteGame\Private\Athena\Modifiers</Filter>
|
<Filter>FortniteGame\Source\FortniteGame\Private\Athena\Modifiers</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="inc.cpp">
|
||||||
|
<Filter>Reboot\Private</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="log.h" />
|
<ClInclude Include="log.h" />
|
||||||
<ClInclude Include="finder.h" />
|
<ClInclude Include="finder.h" />
|
||||||
<ClInclude Include="inc.h" />
|
|
||||||
<ClInclude Include="Array.h">
|
<ClInclude Include="Array.h">
|
||||||
<Filter>Engine\Source\Runtime\Core\Public\Containers</Filter>
|
<Filter>Engine\Source\Runtime\Core\Public\Containers</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -854,6 +856,9 @@
|
|||||||
<ClInclude Include="FortAthenaMutator_LoadoutSwap.h">
|
<ClInclude Include="FortAthenaMutator_LoadoutSwap.h">
|
||||||
<Filter>FortniteGame\Source\FortniteGame\Public\Athena\Modifiers</Filter>
|
<Filter>FortniteGame\Source\FortniteGame\Public\Athena\Modifiers</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="inc.h">
|
||||||
|
<Filter>Reboot\Public</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="Engine">
|
<Filter Include="Engine">
|
||||||
|
|||||||
@@ -353,6 +353,8 @@ void Addresses::Print()
|
|||||||
LOG_INFO(LogDev, "EnterAircraft: 0x{:x}", EnterAircraft - Base);
|
LOG_INFO(LogDev, "EnterAircraft: 0x{:x}", EnterAircraft - Base);
|
||||||
LOG_INFO(LogDev, "SetTimer: 0x{:x}", SetTimer - Base);
|
LOG_INFO(LogDev, "SetTimer: 0x{:x}", SetTimer - Base);
|
||||||
LOG_INFO(LogDev, "PickupInitialize: 0x{:x}", PickupInitialize - Base);
|
LOG_INFO(LogDev, "PickupInitialize: 0x{:x}", PickupInitialize - Base);
|
||||||
|
LOG_INFO(LogDev, "FreeEntry: 0x{:x}", FreeEntry - Base);
|
||||||
|
LOG_INFO(LogDev, "FreeArrayOfEntries: 0x{:x}", FreeArrayOfEntries - Base);
|
||||||
LOG_INFO(LogDev, "UpdateTrackedAttributesLea: 0x{:x}", UpdateTrackedAttributesLea - Base);
|
LOG_INFO(LogDev, "UpdateTrackedAttributesLea: 0x{:x}", UpdateTrackedAttributesLea - Base);
|
||||||
LOG_INFO(LogDev, "CombinePickupLea: 0x{:x}", CombinePickupLea - Base);
|
LOG_INFO(LogDev, "CombinePickupLea: 0x{:x}", CombinePickupLea - Base);
|
||||||
LOG_INFO(LogDev, "CreateBuildingActorCallForDeco: 0x{:x}", CreateBuildingActorCallForDeco - Base);
|
LOG_INFO(LogDev, "CreateBuildingActorCallForDeco: 0x{:x}", CreateBuildingActorCallForDeco - Base);
|
||||||
|
|||||||
@@ -15,13 +15,30 @@ public:
|
|||||||
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
||||||
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
|
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
|
||||||
|
|
||||||
#if 0
|
static UClass* PawnClass = nullptr;
|
||||||
static auto PawnClass = FindObject<UClass>("/Game/Athena/PlayerPawn_Athena.PlayerPawn_Athena_C");
|
static UClass* ControllerClass = nullptr;
|
||||||
static auto ControllerClass = AFortPlayerControllerAthena::StaticClass();
|
|
||||||
#else
|
if (!PawnClass)
|
||||||
static auto PawnClass = FindObject<UClass>("/Game/Athena/AI/Phoebe/BP_PlayerPawn_Athena_Phoebe.BP_PlayerPawn_Athena_Phoebe_C");
|
{
|
||||||
static auto ControllerClass = FindObject<UClass>("/Game/Athena/AI/Phoebe/BP_PhoebePlayerController.BP_PhoebePlayerController_C");
|
if (true)
|
||||||
#endif
|
PawnClass = FindObject<UClass>("/Game/Athena/PlayerPawn_Athena.PlayerPawn_Athena_C");
|
||||||
|
else
|
||||||
|
PawnClass = FindObject<UClass>("/Game/Athena/AI/Phoebe/BP_PlayerPawn_Athena_Phoebe.BP_PlayerPawn_Athena_Phoebe_C");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ControllerClass)
|
||||||
|
{
|
||||||
|
if (true)
|
||||||
|
ControllerClass = AFortPlayerControllerAthena::StaticClass();
|
||||||
|
else
|
||||||
|
ControllerClass = FindObject<UClass>("/Game/Athena/AI/Phoebe/BP_PhoebePlayerController.BP_PhoebePlayerController_C");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ControllerClass || !PawnClass)
|
||||||
|
{
|
||||||
|
LOG_ERROR(LogBots, "Failed to find a class for the bots!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static auto FortAthenaAIBotControllerClass = FindObject<UClass>("/Script/FortniteGame.FortAthenaAIBotController");
|
static auto FortAthenaAIBotControllerClass = FindObject<UClass>("/Script/FortniteGame.FortAthenaAIBotController");
|
||||||
|
|
||||||
@@ -135,14 +152,12 @@ public:
|
|||||||
FortPlayerController->Get<bool>(bHasInitializedWorldInventoryOffset) = true;
|
FortPlayerController->Get<bool>(bHasInitializedWorldInventoryOffset) = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (false)
|
// if (false)
|
||||||
{
|
{
|
||||||
if (Inventory)
|
if (Inventory)
|
||||||
{
|
{
|
||||||
auto& StartingItems = GameMode->GetStartingItems();
|
auto& StartingItems = GameMode->GetStartingItems();
|
||||||
|
|
||||||
UFortItem* PickaxeInstance = nullptr; // PlayerController->AddPickaxeToInventory();
|
|
||||||
|
|
||||||
for (int i = 0; i < StartingItems.Num(); i++)
|
for (int i = 0; i < StartingItems.Num(); i++)
|
||||||
{
|
{
|
||||||
auto& StartingItem = StartingItems.at(i);
|
auto& StartingItem = StartingItems.at(i);
|
||||||
@@ -150,9 +165,15 @@ public:
|
|||||||
(*Inventory)->AddItem(StartingItem.GetItem(), nullptr, StartingItem.GetCount());
|
(*Inventory)->AddItem(StartingItem.GetItem(), nullptr, StartingItem.GetCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PickaxeInstance)
|
if (auto FortPlayerController = Cast<AFortPlayerController>(Controller))
|
||||||
{
|
{
|
||||||
// PlayerController->ServerExecuteInventoryItemHook(PlayerController, PickaxeInstance->GetItemEntry()->GetItemGuid());
|
UFortItem* PickaxeInstance = FortPlayerController->AddPickaxeToInventory();
|
||||||
|
|
||||||
|
if (PickaxeInstance)
|
||||||
|
{
|
||||||
|
FortPlayerController->ServerExecuteInventoryItemHook(FortPlayerController, PickaxeInstance->GetItemEntry()->GetItemGuid());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(*Inventory)->Update();
|
(*Inventory)->Update();
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg)
|
|||||||
|
|
||||||
auto& lootTierGroup = Arguments[1];
|
auto& lootTierGroup = Arguments[1];
|
||||||
|
|
||||||
auto LootDrops = PickLootDrops(UKismetStringLibrary::Conv_StringToName(std::wstring(lootTierGroup.begin(), lootTierGroup.end()).c_str()), true);
|
auto LootDrops = PickLootDrops(UKismetStringLibrary::Conv_StringToName(std::wstring(lootTierGroup.begin(), lootTierGroup.end()).c_str()), -1, true);
|
||||||
|
|
||||||
for (int i = 0; i < LootDrops.size(); i++)
|
for (int i = 0; i < LootDrops.size(); i++)
|
||||||
{
|
{
|
||||||
@@ -442,6 +442,7 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg)
|
|||||||
PickupCreateData CreateData;
|
PickupCreateData CreateData;
|
||||||
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(WID, count, -1);
|
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(WID, count, -1);
|
||||||
CreateData.SpawnLocation = Location;
|
CreateData.SpawnLocation = Location;
|
||||||
|
CreateData.bShouldFreeItemEntryWhenDeconstructed = true;
|
||||||
|
|
||||||
AFortPickup::SpawnPickup(CreateData);
|
AFortPickup::SpawnPickup(CreateData);
|
||||||
}
|
}
|
||||||
|
|||||||
20
Project Reboot 3.0/inc.cpp
Normal file
20
Project Reboot 3.0/inc.cpp
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#include "inc.h"
|
||||||
|
|
||||||
|
#include "Array.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
void* InstancedAllocator::Allocate(AllocatorType type, size_t Size)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case AllocatorType::VIRTUALALLOC:
|
||||||
|
return VirtualAlloc(0, Size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||||
|
case AllocatorType::FMEMORY:
|
||||||
|
return FMemory::Realloc(0, Size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
@@ -56,3 +56,26 @@ inline bool IsRestartingSupported()
|
|||||||
{
|
{
|
||||||
return Engine_Version >= 419 && Engine_Version < 424;
|
return Engine_Version >= 419 && Engine_Version < 424;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
enum class AllocatorType
|
||||||
|
{
|
||||||
|
VIRTUALALLOC,
|
||||||
|
FMEMORY
|
||||||
|
};
|
||||||
|
|
||||||
|
class InstancedAllocator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AllocatorType allocatorType;
|
||||||
|
|
||||||
|
static void* Allocate(AllocatorType type, size_t Size);
|
||||||
|
|
||||||
|
void* Allocate(size_t Size)
|
||||||
|
{
|
||||||
|
return Allocate(allocatorType, Size);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
*/
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "GameplayStatics.h"
|
#include "GameplayStatics.h"
|
||||||
#include "FortLootPackage.h"
|
#include "FortLootPackage.h"
|
||||||
#include "GameplayAbilityTypes.h"
|
#include "GameplayAbilityTypes.h"
|
||||||
|
#include "KismetMathLibrary.h"
|
||||||
|
|
||||||
using ABuildingItemCollectorActor = ABuildingGameplayActor;
|
using ABuildingItemCollectorActor = ABuildingGameplayActor;
|
||||||
|
|
||||||
@@ -12,7 +13,7 @@ struct FCollectorUnitInfo
|
|||||||
{
|
{
|
||||||
static std::string GetStructName()
|
static std::string GetStructName()
|
||||||
{
|
{
|
||||||
static std::string StructName = FindObject<UStruct>("/Script/FortniteGame.CollectorUnitInfo") ? "/Script/FortniteGame.CollectorUnitInfo" : "/Script/FortniteGame.ColletorUnitInfo"; // nice one fortnite
|
static std::string StructName = FindObject<UStruct>(L"/Script/FortniteGame.CollectorUnitInfo") ? "/Script/FortniteGame.CollectorUnitInfo" : "/Script/FortniteGame.ColletorUnitInfo"; // nice one fortnite
|
||||||
return StructName;
|
return StructName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,16 +53,9 @@ struct FCollectorUnitInfo
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void FillItemCollector(ABuildingItemCollectorActor* ItemCollector, FName& LootTierGroup, bool bUseInstanceLootValueOverrides, bool bEnsureRarity = false, int recursive = 0)
|
static inline UCurveTable* GetGameData()
|
||||||
{
|
{
|
||||||
if (recursive >= 10)
|
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
||||||
return;
|
|
||||||
|
|
||||||
auto GameModeAthena = (AFortGameModeAthena*)GetWorld()->GetGameMode();
|
|
||||||
auto GameState = Cast<AFortGameStateAthena>(GameModeAthena->GetGameState());
|
|
||||||
|
|
||||||
static auto ItemCollectionsOffset = ItemCollector->GetOffset("ItemCollections");
|
|
||||||
auto& ItemCollections = ItemCollector->Get<TArray<FCollectorUnitInfo>>(ItemCollectionsOffset);
|
|
||||||
|
|
||||||
UCurveTable* FortGameData = nullptr;
|
UCurveTable* FortGameData = nullptr;
|
||||||
|
|
||||||
@@ -74,7 +68,23 @@ static inline void FillItemCollector(ABuildingItemCollectorActor* ItemCollector,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!FortGameData)
|
if (!FortGameData)
|
||||||
FortGameData = FindObject<UCurveTable>("/Game/Athena/Balance/AthenaGameData.AthenaGameData"); // uhm so theres one without athena and on newer versions that has it so idk
|
FortGameData = FindObject<UCurveTable>(L"/Game/Athena/Balance/DataTables/AthenaGameData.AthenaGameData"); // uhm so theres one without athena and on newer versions that has it so idk // after i wrote this cokmment idk what i meant
|
||||||
|
|
||||||
|
return FortGameData;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void FillItemCollector(ABuildingItemCollectorActor* ItemCollector, FName& LootTierGroup, bool bUseInstanceLootValueOverrides, int LootTier, int recursive = 0)
|
||||||
|
{
|
||||||
|
if (recursive >= 10)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto GameModeAthena = (AFortGameModeAthena*)GetWorld()->GetGameMode();
|
||||||
|
auto GameState = Cast<AFortGameStateAthena>(GameModeAthena->GetGameState());
|
||||||
|
|
||||||
|
static auto ItemCollectionsOffset = ItemCollector->GetOffset("ItemCollections");
|
||||||
|
auto& ItemCollections = ItemCollector->Get<TArray<FCollectorUnitInfo>>(ItemCollectionsOffset);
|
||||||
|
|
||||||
|
UCurveTable* FortGameData = GetGameData();
|
||||||
|
|
||||||
auto WoodName = UKismetStringLibrary::Conv_StringToName(L"Default.VendingMachine.Cost.Wood");
|
auto WoodName = UKismetStringLibrary::Conv_StringToName(L"Default.VendingMachine.Cost.Wood");
|
||||||
auto StoneName = UKismetStringLibrary::Conv_StringToName(L"Default.VendingMachine.Cost.Stone");
|
auto StoneName = UKismetStringLibrary::Conv_StringToName(L"Default.VendingMachine.Cost.Stone");
|
||||||
@@ -83,8 +93,6 @@ static inline void FillItemCollector(ABuildingItemCollectorActor* ItemCollector,
|
|||||||
static auto StoneItemData = FindObject<UFortResourceItemDefinition>("/Game/Items/ResourcePickups/StoneItemData.StoneItemData");
|
static auto StoneItemData = FindObject<UFortResourceItemDefinition>("/Game/Items/ResourcePickups/StoneItemData.StoneItemData");
|
||||||
static auto MetalItemData = FindObject<UFortResourceItemDefinition>("/Game/Items/ResourcePickups/MetalItemData.MetalItemData");
|
static auto MetalItemData = FindObject<UFortResourceItemDefinition>("/Game/Items/ResourcePickups/MetalItemData.MetalItemData");
|
||||||
|
|
||||||
uint8_t RarityToUse = 69;
|
|
||||||
|
|
||||||
// TODO: Pull prices from datatables.
|
// TODO: Pull prices from datatables.
|
||||||
|
|
||||||
bool bLowerPrices = Fortnite_Version >= 5.20;
|
bool bLowerPrices = Fortnite_Version >= 5.20;
|
||||||
@@ -116,18 +124,7 @@ static inline void FillItemCollector(ABuildingItemCollectorActor* ItemCollector,
|
|||||||
|
|
||||||
constexpr bool bPrint = false;
|
constexpr bool bPrint = false;
|
||||||
|
|
||||||
std::vector<LootDrop> LootDrops = PickLootDrops(LootTierGroup, bPrint);
|
std::vector<LootDrop> LootDrops = PickLootDrops(LootTierGroup, LootTier, bPrint);
|
||||||
|
|
||||||
int tries = 0;
|
|
||||||
|
|
||||||
while (LootDrops.size() == 0)
|
|
||||||
{
|
|
||||||
tries++;
|
|
||||||
LootDrops = PickLootDrops(LootTierGroup, bPrint);
|
|
||||||
|
|
||||||
if (tries >= 10)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LootDrops.size() == 0)
|
if (LootDrops.size() == 0)
|
||||||
continue;
|
continue;
|
||||||
@@ -139,20 +136,9 @@ static inline void FillItemCollector(ABuildingItemCollectorActor* ItemCollector,
|
|||||||
if (!WorldItemDefinition)
|
if (!WorldItemDefinition)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!IsPrimaryQuickbar(WorldItemDefinition))
|
if (!IsPrimaryQuickbar(WorldItemDefinition)) // i dont think we need this check
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (bEnsureRarity)
|
|
||||||
{
|
|
||||||
static auto RarityOffset = WorldItemDefinition->GetOffset("Rarity");
|
|
||||||
|
|
||||||
if (RarityToUse == 69)
|
|
||||||
RarityToUse = WorldItemDefinition->Get<uint8_t>(RarityOffset);
|
|
||||||
|
|
||||||
if (WorldItemDefinition->Get<uint8_t>(RarityOffset) != RarityToUse)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bItemAlreadyInCollector = false;
|
bool bItemAlreadyInCollector = false;
|
||||||
|
|
||||||
for (int ItemCollectorIt2 = 0; ItemCollectorIt2 < ItemCollections.Num(); ItemCollectorIt2++)
|
for (int ItemCollectorIt2 = 0; ItemCollectorIt2 < ItemCollections.Num(); ItemCollectorIt2++)
|
||||||
@@ -196,11 +182,11 @@ static inline void FillItemCollector(ABuildingItemCollectorActor* ItemCollector,
|
|||||||
|
|
||||||
ItemCollection->GetInputCount()->GetCurve().CurveTable = bShouldBeNullTable ? nullptr : FortGameData; // scuffed idc
|
ItemCollection->GetInputCount()->GetCurve().CurveTable = bShouldBeNullTable ? nullptr : FortGameData; // scuffed idc
|
||||||
ItemCollection->GetInputCount()->GetCurve().RowName = bShouldBeNullTable ? FName(0) : WoodName; // Scuffed idc
|
ItemCollection->GetInputCount()->GetCurve().RowName = bShouldBeNullTable ? FName(0) : WoodName; // Scuffed idc
|
||||||
ItemCollection->GetInputCount()->GetValue() = RarityToUse == 0 ? CommonPrice
|
ItemCollection->GetInputCount()->GetValue() = LootTier == 0 ? CommonPrice
|
||||||
: RarityToUse == 1 ? UncommonPrice
|
: LootTier == 1 ? UncommonPrice
|
||||||
: RarityToUse == 2 ? RarePrice
|
: LootTier == 2 ? RarePrice
|
||||||
: RarityToUse == 3 ? EpicPrice
|
: LootTier == 3 ? EpicPrice
|
||||||
: RarityToUse == 4 ? LegendaryPrice
|
: LootTier == 4 ? LegendaryPrice
|
||||||
: -1;
|
: -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,12 +195,12 @@ static inline void FillItemCollector(ABuildingItemCollectorActor* ItemCollector,
|
|||||||
if (bUseInstanceLootValueOverridesOffset != -1)
|
if (bUseInstanceLootValueOverridesOffset != -1)
|
||||||
ItemCollector->Get<bool>(bUseInstanceLootValueOverridesOffset) = bUseInstanceLootValueOverrides;
|
ItemCollector->Get<bool>(bUseInstanceLootValueOverridesOffset) = bUseInstanceLootValueOverrides;
|
||||||
|
|
||||||
LOG_INFO(LogDev, "RarityToUse: {}", (int)RarityToUse);
|
// LOG_INFO(LogDev, "LootTier: {}", LootTier);
|
||||||
|
|
||||||
static auto StartingGoalLevelOffset = ItemCollector->GetOffset("StartingGoalLevel");
|
static auto StartingGoalLevelOffset = ItemCollector->GetOffset("StartingGoalLevel");
|
||||||
|
|
||||||
if (StartingGoalLevelOffset != -1)
|
if (StartingGoalLevelOffset != -1)
|
||||||
ItemCollector->Get<int32>(StartingGoalLevelOffset) = (int)RarityToUse;
|
ItemCollector->Get<int32>(StartingGoalLevelOffset) = LootTier;
|
||||||
|
|
||||||
static auto VendingMachineClass = FindObject<UClass>("/Game/Athena/Items/Gameplay/VendingMachine/B_Athena_VendingMachine.B_Athena_VendingMachine_C");
|
static auto VendingMachineClass = FindObject<UClass>("/Game/Athena/Items/Gameplay/VendingMachine/B_Athena_VendingMachine.B_Athena_VendingMachine_C");
|
||||||
|
|
||||||
@@ -223,17 +209,17 @@ static inline void FillItemCollector(ABuildingItemCollectorActor* ItemCollector,
|
|||||||
static auto OverrideVendingMachineRarityOffset = ItemCollector->GetOffset("OverrideVendingMachineRarity", false);
|
static auto OverrideVendingMachineRarityOffset = ItemCollector->GetOffset("OverrideVendingMachineRarity", false);
|
||||||
|
|
||||||
if (OverrideVendingMachineRarityOffset != -1)
|
if (OverrideVendingMachineRarityOffset != -1)
|
||||||
ItemCollector->Get<uint8_t>(OverrideVendingMachineRarityOffset) = RarityToUse;
|
ItemCollector->Get<uint8_t>(OverrideVendingMachineRarityOffset) = LootTier;
|
||||||
|
|
||||||
static auto OverrideGoalOffset = ItemCollector->GetOffset("OverrideGoal", false);
|
static auto OverrideGoalOffset = ItemCollector->GetOffset("OverrideGoal", false);
|
||||||
|
|
||||||
if (OverrideGoalOffset != -1)
|
if (OverrideGoalOffset != -1)
|
||||||
{
|
{
|
||||||
ItemCollector->Get<int32>(OverrideGoalOffset) = RarityToUse == 0 ? CommonPrice
|
ItemCollector->Get<int32>(OverrideGoalOffset) = LootTier == 0 ? CommonPrice
|
||||||
: RarityToUse == 1 ? UncommonPrice
|
: LootTier == 1 ? UncommonPrice
|
||||||
: RarityToUse == 2 ? RarePrice
|
: LootTier == 2 ? RarePrice
|
||||||
: RarityToUse == 3 ? EpicPrice
|
: LootTier == 3 ? EpicPrice
|
||||||
: RarityToUse == 4 ? LegendaryPrice
|
: LootTier == 4 ? LegendaryPrice
|
||||||
: -1;
|
: -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -246,6 +232,28 @@ static inline void FillVendingMachines()
|
|||||||
|
|
||||||
auto OverrideLootTierGroup = UKismetStringLibrary::Conv_StringToName(L"Loot_AthenaVending"); // ItemCollector->GetLootTierGroupOverride();
|
auto OverrideLootTierGroup = UKismetStringLibrary::Conv_StringToName(L"Loot_AthenaVending"); // ItemCollector->GetLootTierGroupOverride();
|
||||||
|
|
||||||
|
std::map<int, float> ThingAndWeights; // Bro IDK WHat to name it!
|
||||||
|
|
||||||
|
auto RarityWeightsName = UKismetStringLibrary::Conv_StringToName(L"Default.VendingMachine.RarityWeights");
|
||||||
|
|
||||||
|
auto FortGameData = GetGameData();
|
||||||
|
|
||||||
|
float WeightSum = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
auto Weight = UDataTableFunctionLibrary::EvaluateCurveTableRow(FortGameData, RarityWeightsName, i);
|
||||||
|
ThingAndWeights[i] = Weight;
|
||||||
|
WeightSum += Weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < ThingAndWeights.size(); i++)
|
||||||
|
{
|
||||||
|
LOG_INFO(LogDev, "[{}] bruh: {}", i, ThingAndWeights.at(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<int, int> PickedRarities;
|
||||||
|
|
||||||
for (int i = 0; i < AllVendingMachines.Num(); i++)
|
for (int i = 0; i < AllVendingMachines.Num(); i++)
|
||||||
{
|
{
|
||||||
auto VendingMachine = (ABuildingItemCollectorActor*)AllVendingMachines.at(i);
|
auto VendingMachine = (ABuildingItemCollectorActor*)AllVendingMachines.at(i);
|
||||||
@@ -253,8 +261,39 @@ static inline void FillVendingMachines()
|
|||||||
if (!VendingMachine)
|
if (!VendingMachine)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
FillItemCollector(VendingMachine, OverrideLootTierGroup, true, true);
|
auto randomFloatGenerator = [&](float Max) -> float { return UKismetMathLibrary::RandomFloatInRange(0, Max); };
|
||||||
|
|
||||||
|
int Out;
|
||||||
|
PickWeightedElement<int, float>(ThingAndWeights, [&](float Weight) -> float { return Weight; }, randomFloatGenerator, WeightSum, false, 1, &Out, false, true);
|
||||||
|
|
||||||
|
PickedRarities[Out]++;
|
||||||
|
|
||||||
|
if (Out == 0)
|
||||||
|
{
|
||||||
|
VendingMachine->K2_DestroyActor();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FillItemCollector(VendingMachine, OverrideLootTierGroup, Out - 1, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto AllVendingMachinesNum = AllVendingMachines.Num();
|
||||||
|
|
||||||
AllVendingMachines.Free();
|
AllVendingMachines.Free();
|
||||||
|
|
||||||
|
bool bPrintDebug = true;
|
||||||
|
|
||||||
|
if (bPrintDebug)
|
||||||
|
{
|
||||||
|
LOG_INFO(LogGame, "Destroyed {}/{} vending machines.", PickedRarities[0], AllVendingMachinesNum);
|
||||||
|
LOG_INFO(LogGame, "Filled {}/{} vending machines with common items.", PickedRarities[1], AllVendingMachinesNum);
|
||||||
|
LOG_INFO(LogGame, "Filled {}/{} vending machines with uncommon items.", PickedRarities[2], AllVendingMachinesNum);
|
||||||
|
LOG_INFO(LogGame, "Filled {}/{} vending machines with rare items.", PickedRarities[3], AllVendingMachinesNum);
|
||||||
|
LOG_INFO(LogGame, "Filled {}/{} vending machines with epic items.", PickedRarities[4], AllVendingMachinesNum);
|
||||||
|
LOG_INFO(LogGame, "Filled {}/{} vending machines with legendary items.", PickedRarities[5], AllVendingMachinesNum);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_INFO(LogGame, "Filled {} vending machines!", AllVendingMachinesNum);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user