mirror of
https://github.com/Milxnor/Project-Reboot-3.0.git
synced 2026-01-13 02:42:22 +01:00
a good update
Added a very useful debugging tool, made looting even more proper
This commit is contained in:
@@ -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);
|
auto LootDrops = PickLootDrops(SpawnLootTierGroup, GameState->GetWorldLevel());
|
||||||
|
|
||||||
for (int z = 0; z < LootDrops.size(); z++)
|
for (int z = 0; z < LootDrops.size(); z++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
bool ABuildingContainer::SpawnLoot(AFortPawn* Pawn)
|
bool ABuildingContainer::SpawnLoot(AFortPawn* Pawn)
|
||||||
{
|
{
|
||||||
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
|
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
|
||||||
|
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
||||||
|
|
||||||
FVector LocationToSpawnLoot = this->GetActorLocation() + this->GetActorRightVector() * 70.f + FVector{ 0, 0, 50 };
|
FVector LocationToSpawnLoot = this->GetActorLocation() + this->GetActorRightVector() * 70.f + FVector{ 0, 0, 50 };
|
||||||
|
|
||||||
static auto SearchLootTierGroupOffset = this->GetOffset("SearchLootTierGroup");
|
static auto SearchLootTierGroupOffset = this->GetOffset("SearchLootTierGroup");
|
||||||
@@ -14,18 +16,16 @@ bool ABuildingContainer::SpawnLoot(AFortPawn* Pawn)
|
|||||||
|
|
||||||
// LOG_INFO(LogInteraction, "RedirectedLootTier: {}", RedirectedLootTier.ToString());
|
// LOG_INFO(LogInteraction, "RedirectedLootTier: {}", RedirectedLootTier.ToString());
|
||||||
|
|
||||||
auto LootDrops = PickLootDrops(RedirectedLootTier, -1, bDebugPrintLooting);
|
auto LootDrops = PickLootDrops(RedirectedLootTier, GameState->GetWorldLevel(), -1, bDebugPrintLooting);
|
||||||
|
|
||||||
// LOG_INFO(LogInteraction, "LootDrops.size(): {}", LootDrops.size());
|
// LOG_INFO(LogInteraction, "LootDrops.size(): {}", LootDrops.size());
|
||||||
|
|
||||||
for (int i = 0; i < LootDrops.size(); i++)
|
for (auto& LootDrop : LootDrops)
|
||||||
{
|
{
|
||||||
auto& lootDrop = LootDrops.at(i);
|
|
||||||
|
|
||||||
PickupCreateData CreateData{};
|
PickupCreateData CreateData{};
|
||||||
CreateData.bToss = true;
|
CreateData.bToss = true;
|
||||||
// CreateData.PawnOwner = Pawn;
|
// CreateData.PawnOwner = Pawn;
|
||||||
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(lootDrop->GetItemDefinition(), lootDrop->GetCount(), lootDrop->GetLoadedAmmo());
|
CreateData.ItemEntry = LootDrop.ItemEntry;
|
||||||
CreateData.SpawnLocation = LocationToSpawnLoot;
|
CreateData.SpawnLocation = LocationToSpawnLoot;
|
||||||
CreateData.SourceType = EFortPickupSourceTypeFlag::GetContainerValue();
|
CreateData.SourceType = EFortPickupSourceTypeFlag::GetContainerValue();
|
||||||
CreateData.bRandomRotation = true;
|
CreateData.bRandomRotation = true;
|
||||||
@@ -34,5 +34,17 @@ bool ABuildingContainer::SpawnLoot(AFortPawn* Pawn)
|
|||||||
auto NewPickup = AFortPickup::SpawnPickup(CreateData);
|
auto NewPickup = AFortPickup::SpawnPickup(CreateData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static auto SearchAnimationCountOffset = FindOffsetStruct("/Script/FortniteGame.FortSearchBounceData", "SearchAnimationCount");
|
||||||
|
static auto SearchBounceDataOffset = this->GetOffset("SearchBounceData");
|
||||||
|
|
||||||
|
auto SearchBounceData = this->GetPtr<void>(SearchBounceDataOffset);
|
||||||
|
|
||||||
|
(*(int*)(__int64(SearchBounceData) + SearchAnimationCountOffset))++;
|
||||||
|
|
||||||
|
static auto OnRep_bAlreadySearchedFn = FindObject<UFunction>(L"/Script/FortniteGame.BuildingContainer.OnRep_bAlreadySearched");
|
||||||
|
this->ProcessEvent(OnRep_bAlreadySearchedFn);
|
||||||
|
|
||||||
|
// Now there is some function called here but idk what it is, it calls OnLoot though.
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
|
#include "reboot.h"
|
||||||
|
|
||||||
#include "Map.h"
|
#include "Map.h"
|
||||||
|
|
||||||
|
struct FTableRowBase
|
||||||
|
{
|
||||||
|
unsigned char UnknownData00[0x8]; // this is actually structural padding
|
||||||
|
};
|
||||||
|
|
||||||
class UDataTable : public UObject
|
class UDataTable : public UObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -40,4 +46,63 @@ struct FDataTableCategoryHandle
|
|||||||
UDataTable* DataTable; // 0x0000(0x0008) (Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
UDataTable* DataTable; // 0x0000(0x0008) (Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
FName ColumnName; // 0x0008(0x0008) (Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
FName ColumnName; // 0x0008(0x0008) (Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
FName RowContents; // 0x0010(0x0008) (Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
FName RowContents; // 0x0010(0x0008) (Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void GetRows(std::vector<T*>& OutRows, const FString& ContextString) const
|
||||||
|
{
|
||||||
|
OutRows.clear();
|
||||||
|
|
||||||
|
if (DataTable == nullptr)
|
||||||
|
{
|
||||||
|
if (RowContents.ComparisonIndex.Value != 0)
|
||||||
|
{
|
||||||
|
// UE_LOG(LogDataTable, Warning, TEXT("FDataTableCategoryHandle::FindRow : No DataTable for row %s (%s)."), *RowContents.ToString(), *ContextString);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ColumnName.ComparisonIndex.Value == 0)
|
||||||
|
{
|
||||||
|
if (RowContents.ComparisonIndex.Value != 0)
|
||||||
|
{
|
||||||
|
// UE_LOG(LogDataTable, Warning, TEXT("FDataTableCategoryHandle::FindRow : No Column selected for row %s (%s)."), *RowContents.ToString(), *ContextString);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
// unreal trippin
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Find the property that matches the desired column (ColumnName)
|
||||||
|
UProperty* Property = DataTable->FindTableProperty(ColumnName);
|
||||||
|
if (Property == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check each row to see if the value in the Property element is the one we're looking for (RowContents). If it is, add the row to OutRows
|
||||||
|
FString RowContentsAsString = RowContents.ToString();
|
||||||
|
|
||||||
|
for (auto RowIt = DataTable->RowMap.CreateConstIterator(); RowIt; ++RowIt)
|
||||||
|
{
|
||||||
|
uint8* RowData = RowIt.Value();
|
||||||
|
|
||||||
|
FString PropertyValue(TEXT(""));
|
||||||
|
|
||||||
|
Property->ExportText_InContainer(0, PropertyValue, RowData, RowData, nullptr, PPF_None);
|
||||||
|
|
||||||
|
if (RowContentsAsString == PropertyValue)
|
||||||
|
{
|
||||||
|
OutRows.Add((T*)RowData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,18 +6,49 @@
|
|||||||
#include "FortWorldItemDefinition.h"
|
#include "FortWorldItemDefinition.h"
|
||||||
#include "FortInventory.h"
|
#include "FortInventory.h"
|
||||||
|
|
||||||
|
enum class ERespawnRequirements : uint8_t
|
||||||
|
{
|
||||||
|
RespawnOnly = 0,
|
||||||
|
NoRespawnOnly = 1,
|
||||||
|
Both = 2,
|
||||||
|
ERespawnRequirements_MAX = 3
|
||||||
|
};
|
||||||
|
|
||||||
struct FItemsToDropOnDeath
|
struct FItemsToDropOnDeath
|
||||||
{
|
{
|
||||||
UFortWorldItemDefinition* ItemToDrop; // 0x0000(0x0008) (Edit, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
static UStruct* GetStruct()
|
||||||
FScalableFloat NumberToDrop; // 0x0008(0x0020) (Edit, NativeAccessSpecifierPublic)
|
{
|
||||||
|
static auto Struct = FindObject<UStruct>("/Script/FortniteGame.ItemsToDropOnDeath");
|
||||||
|
return Struct;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int GetStructSize() { return GetStruct()->GetPropertiesSize(); }
|
||||||
|
|
||||||
|
UFortWorldItemDefinition*& GetItemToDrop()
|
||||||
|
{
|
||||||
|
static auto ItemToDropOffset = FindOffsetStruct("/Script/FortniteGame.ItemsToDropOnDeath", "ItemToDrop");
|
||||||
|
return *(UFortWorldItemDefinition**)(__int64(this) + ItemToDropOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
FScalableFloat* GetNumberToDrop()
|
||||||
|
{
|
||||||
|
static auto NumberToDropOffset = FindOffsetStruct("/Script/FortniteGame.ItemsToDropOnDeath", "NumberToDrop");
|
||||||
|
return (FScalableFloat*)(__int64(this) + NumberToDropOffset);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class AFortAthenaMutator_ItemDropOnDeath : public AFortAthenaMutator
|
class AFortAthenaMutator_ItemDropOnDeath : public AFortAthenaMutator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
ERespawnRequirements/*&*/ GetRespawnRequirements()
|
||||||
|
{
|
||||||
|
static auto RespawnRequirementsOffset = GetOffset("RespawnRequirements");
|
||||||
|
return Get<ERespawnRequirements>(RespawnRequirementsOffset);
|
||||||
|
}
|
||||||
|
|
||||||
TArray<FItemsToDropOnDeath>& GetItemsToDrop()
|
TArray<FItemsToDropOnDeath>& GetItemsToDrop()
|
||||||
{
|
{
|
||||||
static auto ItemsToDropOffset = GetOffset("ItemsToDrop");
|
static auto ItemsToDropOffset = GetOffset("ItemsToDrop");
|
||||||
return Get<TArray<FItemsToDropOnDeath>>(ItemsToDropoOffset);
|
return Get<TArray<FItemsToDropOnDeath>>(ItemsToDropOffset);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "FortGameMode.h"
|
#include "FortGameMode.h"
|
||||||
|
|
||||||
void AFortGameMode::SetCurrentPlaylistName(UObject* Playlist) // Techinally it takes in a fname
|
void AFortGameMode::SetCurrentPlaylistName(UFortPlaylist* Playlist) // Techinally it takes in a fname
|
||||||
{
|
{
|
||||||
if (!Playlist)
|
if (!Playlist)
|
||||||
{
|
{
|
||||||
@@ -9,11 +9,10 @@ void AFortGameMode::SetCurrentPlaylistName(UObject* Playlist) // Techinally it t
|
|||||||
}
|
}
|
||||||
|
|
||||||
static auto PlaylistNameOffset = Playlist->GetOffset("PlaylistName");
|
static auto PlaylistNameOffset = Playlist->GetOffset("PlaylistName");
|
||||||
static auto PlaylistIdOffset = Playlist->GetOffset("PlaylistId");
|
|
||||||
|
|
||||||
static auto CurrentPlaylistNameOffset = GetOffset("CurrentPlaylistName");
|
static auto CurrentPlaylistNameOffset = GetOffset("CurrentPlaylistName");
|
||||||
static auto CurrentPlaylistIdOffset = GetOffset("CurrentPlaylistId");
|
static auto CurrentPlaylistIdOffset = GetOffset("CurrentPlaylistId");
|
||||||
|
|
||||||
Get<FName>(CurrentPlaylistNameOffset) = Playlist->Get<FName>(PlaylistNameOffset);
|
Get<FName>(CurrentPlaylistNameOffset) = Playlist->Get<FName>(PlaylistNameOffset);
|
||||||
Get<int>(CurrentPlaylistIdOffset) = Playlist->Get<int>(PlaylistIdOffset);
|
Get<int>(CurrentPlaylistIdOffset) = Playlist->GetPlaylistId();
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "GameMode.h"
|
#include "GameMode.h"
|
||||||
|
#include "FortPlaylist.h"
|
||||||
|
|
||||||
class AFortGameMode : public AGameMode
|
class AFortGameMode : public AGameMode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void SetCurrentPlaylistName(UObject* Playlist); // Techinally it takes in a fname
|
void SetCurrentPlaylistName(UFortPlaylist* Playlist); // Techinally it takes in a fname
|
||||||
};
|
};
|
||||||
@@ -161,21 +161,12 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
|
|||||||
(*(int*)(__int64(CurrentPlaylistInfo) + PlaylistReplicationKeyOffset))++;
|
(*(int*)(__int64(CurrentPlaylistInfo) + PlaylistReplicationKeyOffset))++;
|
||||||
CurrentPlaylistInfo->MarkArrayDirty();
|
CurrentPlaylistInfo->MarkArrayDirty();
|
||||||
|
|
||||||
auto aeuh = *(UObject**)(__int64(CurrentPlaylistInfo) + BasePlaylistOffset);
|
auto currentBasePlaylist = *(UFortPlaylist**)(__int64(CurrentPlaylistInfo) + BasePlaylistOffset);
|
||||||
|
|
||||||
if (aeuh)
|
if (currentBasePlaylist)
|
||||||
{
|
{
|
||||||
GameMode->SetCurrentPlaylistName(aeuh);
|
GameMode->SetCurrentPlaylistName(currentBasePlaylist);
|
||||||
|
GameState->SetPlaylistId(currentBasePlaylist);
|
||||||
/* if (Fortnite_Version >= 13)
|
|
||||||
{
|
|
||||||
static auto LastSafeZoneIndexOffset = aeuh->GetOffset("LastSafeZoneIndex");
|
|
||||||
|
|
||||||
if (LastSafeZoneIndexOffset != -1)
|
|
||||||
{
|
|
||||||
*(int*)(__int64(aeuh) + LastSafeZoneIndexOffset) = 0;
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -183,7 +174,15 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
|
|||||||
static auto CurrentPlaylistDataOffset = GameState->GetOffset("CurrentPlaylistData", false);
|
static auto CurrentPlaylistDataOffset = GameState->GetOffset("CurrentPlaylistData", false);
|
||||||
|
|
||||||
if (CurrentPlaylistDataOffset != -1)
|
if (CurrentPlaylistDataOffset != -1)
|
||||||
|
{
|
||||||
GameState->Get(CurrentPlaylistDataOffset) = Playlist;
|
GameState->Get(CurrentPlaylistDataOffset) = Playlist;
|
||||||
|
|
||||||
|
if (GameState->Get(CurrentPlaylistDataOffset))
|
||||||
|
{
|
||||||
|
GameMode->SetCurrentPlaylistName(GameState->Get<UFortPlaylist*>(CurrentPlaylistDataOffset));
|
||||||
|
GameState->SetPlaylistId(GameState->Get<UFortPlaylist*>(CurrentPlaylistDataOffset));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bOnRep)
|
if (bOnRep)
|
||||||
@@ -550,13 +549,23 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
|
|||||||
LastNum3 = AmountOfRestarts;
|
LastNum3 = AmountOfRestarts;
|
||||||
++Globals::AmountOfListens;
|
++Globals::AmountOfListens;
|
||||||
|
|
||||||
LOG_INFO(LogNet, "Attempting to listen!");
|
// LOG_INFO(LogNet, "Attempting to listen!");
|
||||||
|
|
||||||
GetWorld()->Listen();
|
GetWorld()->Listen();
|
||||||
|
|
||||||
|
LOG_INFO(LogDev, "WorldLevel: {}", GameState->GetWorldLevel());
|
||||||
|
|
||||||
SetupAIDirector();
|
SetupAIDirector();
|
||||||
SetupServerBotManager();
|
SetupServerBotManager();
|
||||||
|
|
||||||
|
bool bPrintCommonObjectPaths = true;
|
||||||
|
|
||||||
|
if (bPrintCommonObjectPaths)
|
||||||
|
{
|
||||||
|
LOG_INFO(LogGame, "GameState PathName: {}", GetWorld()->GetGameState()->GetPathName());
|
||||||
|
LOG_INFO(LogGame, "GameMode PathName: {}", GetWorld()->GetGameMode()->GetPathName());
|
||||||
|
}
|
||||||
|
|
||||||
if (AmountOfBotsToSpawn != 0)
|
if (AmountOfBotsToSpawn != 0)
|
||||||
{
|
{
|
||||||
Bots::SpawnBotsAtPlayerStarts(AmountOfBotsToSpawn);
|
Bots::SpawnBotsAtPlayerStarts(AmountOfBotsToSpawn);
|
||||||
@@ -968,13 +977,13 @@ 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, -1, bPrintWarmup);
|
std::vector<LootDrop> LootDrops = PickLootDrops(SpawnIslandTierGroup, GameState->GetWorldLevel(), -1, bPrintWarmup);
|
||||||
|
|
||||||
for (auto& LootDrop : LootDrops)
|
for (auto& LootDrop : LootDrops)
|
||||||
{
|
{
|
||||||
PickupCreateData CreateData;
|
PickupCreateData CreateData;
|
||||||
CreateData.bToss = true;
|
CreateData.bToss = true;
|
||||||
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(LootDrop->GetItemDefinition(), LootDrop->GetCount(), LootDrop->GetLoadedAmmo());
|
CreateData.ItemEntry = LootDrop.ItemEntry;
|
||||||
CreateData.SpawnLocation = Location;
|
CreateData.SpawnLocation = Location;
|
||||||
CreateData.SourceType = SpawnFlag;
|
CreateData.SourceType = SpawnFlag;
|
||||||
CreateData.bRandomRotation = true;
|
CreateData.bRandomRotation = true;
|
||||||
@@ -998,13 +1007,13 @@ 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, -1, bPrint);
|
std::vector<LootDrop> LootDrops = PickLootDrops(BRIslandTierGroup, GameState->GetWorldLevel(), -1, bPrint);
|
||||||
|
|
||||||
for (auto& LootDrop : LootDrops)
|
for (auto& LootDrop : LootDrops)
|
||||||
{
|
{
|
||||||
PickupCreateData CreateData;
|
PickupCreateData CreateData;
|
||||||
CreateData.bToss = true;
|
CreateData.bToss = true;
|
||||||
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(LootDrop->GetItemDefinition(), LootDrop->GetCount(), LootDrop->GetLoadedAmmo());
|
CreateData.ItemEntry = LootDrop.ItemEntry;
|
||||||
CreateData.SpawnLocation = Location;
|
CreateData.SpawnLocation = Location;
|
||||||
CreateData.SourceType = SpawnFlag;
|
CreateData.SourceType = SpawnFlag;
|
||||||
CreateData.bRandomRotation = true;
|
CreateData.bRandomRotation = true;
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ static void SetFoundationTransform(AActor* BuildingFoundation, const FTransform&
|
|||||||
|
|
||||||
static inline UFortAbilitySet* GetPlayerAbilitySet()
|
static inline UFortAbilitySet* GetPlayerAbilitySet()
|
||||||
{
|
{
|
||||||
// There are some variables that contain this but it changes through versions soo..
|
// There are some variables that contain this but it changes through versions soo.. // GenericPlayerAbilitySet and PlayerAbilitySetBR
|
||||||
|
|
||||||
static auto GameplayAbilitySet = (UFortAbilitySet*)(Fortnite_Version >= 8.30
|
static auto GameplayAbilitySet = (UFortAbilitySet*)(Fortnite_Version >= 8.30
|
||||||
? LoadObject(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_AthenaPlayer.GAS_AthenaPlayer", UFortAbilitySet::StaticClass())
|
? LoadObject(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_AthenaPlayer.GAS_AthenaPlayer", UFortAbilitySet::StaticClass())
|
||||||
|
|||||||
@@ -80,6 +80,12 @@ UFortPlaylist*& AFortGameStateAthena::GetCurrentPlaylist()
|
|||||||
return *(UFortPlaylist**)(__int64(CurrentPlaylistInfo) + BasePlaylistOffset);
|
return *(UFortPlaylist**)(__int64(CurrentPlaylistInfo) + BasePlaylistOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AFortGameStateAthena::SetPlaylistId(UFortPlaylist* Playlist)
|
||||||
|
{
|
||||||
|
static auto CurrentPlaylistIdOffset = GetOffset("CurrentPlaylistId");
|
||||||
|
this->Get<int>(CurrentPlaylistIdOffset) = Playlist->GetPlaylistId();
|
||||||
|
}
|
||||||
|
|
||||||
int AFortGameStateAthena::GetAircraftIndex(AFortPlayerState* PlayerState)
|
int AFortGameStateAthena::GetAircraftIndex(AFortPlayerState* PlayerState)
|
||||||
{
|
{
|
||||||
// The function has a string in it but we can just remake lol
|
// The function has a string in it but we can just remake lol
|
||||||
|
|||||||
@@ -68,6 +68,12 @@ public:
|
|||||||
return Get<EAthenaGamePhase>(GamePhaseOffset);
|
return Get<EAthenaGamePhase>(GamePhaseOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int& GetWorldLevel() // Actually in AFortGameState
|
||||||
|
{
|
||||||
|
static auto WorldLevelOffset = GetOffset("WorldLevel");
|
||||||
|
return Get<int>(WorldLevelOffset);
|
||||||
|
}
|
||||||
|
|
||||||
UBuildingStructuralSupportSystem* GetStructuralSupportSystem() // actually in FortGameModeZone
|
UBuildingStructuralSupportSystem* GetStructuralSupportSystem() // actually in FortGameModeZone
|
||||||
{
|
{
|
||||||
static auto StructuralSupportSystemOffset = GetOffset("StructuralSupportSystem");
|
static auto StructuralSupportSystemOffset = GetOffset("StructuralSupportSystem");
|
||||||
@@ -99,6 +105,7 @@ public:
|
|||||||
|
|
||||||
// void AddPlayerStateToGameMemberInfo(class AFortPlayerStateAthena* PlayerState);
|
// void AddPlayerStateToGameMemberInfo(class AFortPlayerStateAthena* PlayerState);
|
||||||
|
|
||||||
|
void SetPlaylistId(UFortPlaylist* Playlist);
|
||||||
int GetAircraftIndex(AFortPlayerState* PlayerState);
|
int GetAircraftIndex(AFortPlayerState* PlayerState);
|
||||||
bool IsRespawningAllowed(AFortPlayerState* PlayerState); // actually in zone
|
bool IsRespawningAllowed(AFortPlayerState* PlayerState); // actually in zone
|
||||||
bool IsPlayerBuildableClass(UClass* Class);
|
bool IsPlayerBuildableClass(UClass* Class);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ void FFortItemEntry::SetStateValue(EFortItemEntryState StateType, int IntValue)
|
|||||||
// ItemEntry->bIsDirty = true;
|
// ItemEntry->bIsDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
FFortItemEntry* FFortItemEntry::MakeItemEntry(UFortItemDefinition* ItemDefinition, int Count, int LoadedAmmo, float Durability)
|
FFortItemEntry* FFortItemEntry::MakeItemEntry(UFortItemDefinition* ItemDefinition, int Count, int LoadedAmmo, float Durability, int Level)
|
||||||
{
|
{
|
||||||
auto Entry = Alloc<FFortItemEntry>(GetStructSize(), bUseFMemoryRealloc);
|
auto Entry = Alloc<FFortItemEntry>(GetStructSize(), bUseFMemoryRealloc);
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ FFortItemEntry* FFortItemEntry::MakeItemEntry(UFortItemDefinition* ItemDefinitio
|
|||||||
LoadedAmmo = 0;
|
LoadedAmmo = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entry->MostRecentArrayReplicationKey = -1; // idk if we need to set this
|
Entry->MostRecentArrayReplicationKey = -1; // idk if we need to set this one
|
||||||
Entry->ReplicationID = -1;
|
Entry->ReplicationID = -1;
|
||||||
Entry->ReplicationKey = -1;
|
Entry->ReplicationKey = -1;
|
||||||
|
|
||||||
@@ -50,6 +50,7 @@ FFortItemEntry* FFortItemEntry::MakeItemEntry(UFortItemDefinition* ItemDefinitio
|
|||||||
Entry->GetDurability() = Durability;
|
Entry->GetDurability() = Durability;
|
||||||
Entry->GetGameplayAbilitySpecHandle() = FGameplayAbilitySpecHandle(-1);
|
Entry->GetGameplayAbilitySpecHandle() = FGameplayAbilitySpecHandle(-1);
|
||||||
Entry->GetParentInventory().ObjectIndex = -1;
|
Entry->GetParentInventory().ObjectIndex = -1;
|
||||||
|
Entry->GetLevel() = Level;
|
||||||
// We want to add StateValues.Add(DurabilityInitialized); orwnatefc erwgearf yk
|
// We want to add StateValues.Add(DurabilityInitialized); orwnatefc erwgearf yk
|
||||||
// CoCreateGuid((GUID*)&Entry->GetItemGuid());
|
// CoCreateGuid((GUID*)&Entry->GetItemGuid());
|
||||||
// Entry->DoesUpdateStatsOnCollection() = true; // I think fortnite does this?
|
// Entry->DoesUpdateStatsOnCollection() = true; // I think fortnite does this?
|
||||||
|
|||||||
@@ -143,18 +143,12 @@ struct FFortItemEntry : FFastArraySerializerItem
|
|||||||
|
|
||||||
FGuid OldGuid = this->GetItemGuid();
|
FGuid OldGuid = this->GetItemGuid();
|
||||||
|
|
||||||
if (false)
|
this->GetCount() = OtherItemEntry->GetCount();
|
||||||
{
|
this->GetItemDefinition() = OtherItemEntry->GetItemDefinition();
|
||||||
CopyStruct(this, OtherItemEntry, FFortItemEntry::GetStructSize(), FFortItemEntry::GetStruct());
|
this->GetDurability() = OtherItemEntry->GetDurability();
|
||||||
}
|
this->GetLevel() = OtherItemEntry->GetLevel();
|
||||||
else
|
this->GetLoadedAmmo() = OtherItemEntry->GetLoadedAmmo();
|
||||||
{
|
this->GetItemGuid() = OtherItemEntry->GetItemGuid();
|
||||||
this->GetItemDefinition() = OtherItemEntry->GetItemDefinition();
|
|
||||||
this->GetCount() = OtherItemEntry->GetCount();
|
|
||||||
this->GetLoadedAmmo() = OtherItemEntry->GetLoadedAmmo();
|
|
||||||
this->GetItemGuid() = OtherItemEntry->GetItemGuid();
|
|
||||||
this->GetLevel() = OtherItemEntry->GetLevel();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bCopyGuid)
|
if (!bCopyGuid)
|
||||||
this->GetItemGuid() = OldGuid;
|
this->GetItemGuid() = OldGuid;
|
||||||
@@ -189,7 +183,7 @@ struct FFortItemEntry : FFastArraySerializerItem
|
|||||||
return StructSize;
|
return StructSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FFortItemEntry* MakeItemEntry(UFortItemDefinition* ItemDefinition, int Count = 1, int LoadedAmmo = 0, float Durability = 0x3F800000);
|
static FFortItemEntry* MakeItemEntry(UFortItemDefinition* ItemDefinition, int Count = 1, int LoadedAmmo = 0, float Durability = 0x3F800000, int Level = 0);
|
||||||
|
|
||||||
// We need to find a better way for below... Especially since we can't do either method for season 5 or 6.
|
// We need to find a better way for below... Especially since we can't do either method for season 5 or 6.
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "FortPickup.h"
|
#include "FortPickup.h"
|
||||||
#include "FortLootPackage.h"
|
#include "FortLootPackage.h"
|
||||||
#include "AbilitySystemComponent.h"
|
#include "AbilitySystemComponent.h"
|
||||||
|
#include "FortGameStateAthena.h"
|
||||||
|
|
||||||
UFortResourceItemDefinition* UFortKismetLibrary::K2_GetResourceItemDefinition(EFortResourceType ResourceType)
|
UFortResourceItemDefinition* UFortKismetLibrary::K2_GetResourceItemDefinition(EFortResourceType ResourceType)
|
||||||
{
|
{
|
||||||
@@ -601,13 +602,15 @@ 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, -1, true);
|
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
||||||
|
|
||||||
|
auto LootDrops = PickLootDrops(TierGroupName, GameState->GetWorldLevel(), -1, true);
|
||||||
|
|
||||||
for (int i = 0; i < LootDrops.size(); i++)
|
for (int i = 0; i < LootDrops.size(); i++)
|
||||||
{
|
{
|
||||||
auto& LootDrop = LootDrops.at(i);
|
auto& LootDrop = LootDrops.at(i);
|
||||||
|
|
||||||
auto NewEntry = FFortItemEntry::MakeItemEntry(LootDrop->GetItemDefinition(), LootDrop->GetCount(), LootDrop->GetLoadedAmmo());
|
auto NewEntry = LootDrop.ItemEntry;
|
||||||
|
|
||||||
OutLootToDrop.AddPtr(NewEntry, FFortItemEntry::GetStructSize());
|
OutLootToDrop.AddPtr(NewEntry, FFortItemEntry::GetStructSize());
|
||||||
}
|
}
|
||||||
|
|||||||
71
Project Reboot 3.0/FortLootLevel.cpp
Normal file
71
Project Reboot 3.0/FortLootLevel.cpp
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
#include "FortLootLevel.h"
|
||||||
|
#include "FortWorldItemDefinition.h"
|
||||||
|
|
||||||
|
int UFortLootLevel::GetItemLevel(const FDataTableCategoryHandle& LootLevelData, int WorldLevel)
|
||||||
|
{
|
||||||
|
// OMG IM GONNA DIE
|
||||||
|
|
||||||
|
// we should use GetRows but L
|
||||||
|
|
||||||
|
auto DataTable = LootLevelData.DataTable;
|
||||||
|
|
||||||
|
if (!DataTable)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!LootLevelData.ColumnName.ComparisonIndex.Value)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!LootLevelData.RowContents.ComparisonIndex.Value)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
std::vector<FFortLootLevelData*> OurLootLevelDatas;
|
||||||
|
|
||||||
|
for (auto& LootLevelDataPair : LootLevelData.DataTable->GetRowMap<FFortLootLevelData>())
|
||||||
|
{
|
||||||
|
if (LootLevelDataPair.Second->Category != LootLevelData.RowContents)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
OurLootLevelDatas.push_back(LootLevelDataPair.Second);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OurLootLevelDatas.size() > 0)
|
||||||
|
{
|
||||||
|
int PickedIndex = -1;
|
||||||
|
int PickedLootLevel = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < OurLootLevelDatas.size(); i++)
|
||||||
|
{
|
||||||
|
auto CurrentLootLevelData = OurLootLevelDatas.at(i);
|
||||||
|
|
||||||
|
if (CurrentLootLevelData->LootLevel <= WorldLevel && CurrentLootLevelData->LootLevel > PickedLootLevel)
|
||||||
|
{
|
||||||
|
PickedLootLevel = CurrentLootLevelData->LootLevel;
|
||||||
|
PickedIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PickedIndex != -1)
|
||||||
|
{
|
||||||
|
auto PickedLootLevelData = OurLootLevelDatas.at(PickedIndex);
|
||||||
|
|
||||||
|
const auto PickedMinItemLevel = PickedLootLevelData->MinItemLevel;
|
||||||
|
const auto PickedMaxItemLevel = PickedLootLevelData->MaxItemLevel;
|
||||||
|
auto v15 = PickedMaxItemLevel - PickedMinItemLevel;
|
||||||
|
|
||||||
|
if (v15 + 1 <= 0)
|
||||||
|
{
|
||||||
|
v15 = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto v16 = (int)(float)((float)((float)rand() * 0.000030518509) * (float)(v15 + 1));
|
||||||
|
if (v16 <= v15)
|
||||||
|
v15 = v16;
|
||||||
|
}
|
||||||
|
|
||||||
|
return v15 + PickedMinItemLevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
class UFortLootLevel
|
class UFortLootLevel
|
||||||
{
|
{
|
||||||
int GetItemLevel(FDataTableCategoryHandle LootLevelData, int WorldLevel)
|
public:
|
||||||
{
|
static int GetItemLevel(const FDataTableCategoryHandle& LootLevelData, int WorldLevel);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "UObjectArray.h"
|
#include "UObjectArray.h"
|
||||||
#include "GameplayTagContainer.h"
|
#include "GameplayTagContainer.h"
|
||||||
#include "FortGameModeAthena.h"
|
#include "FortGameModeAthena.h"
|
||||||
|
#include "FortLootLevel.h"
|
||||||
|
|
||||||
struct FFortGameFeatureLootTableData
|
struct FFortGameFeatureLootTableData
|
||||||
{
|
{
|
||||||
@@ -51,11 +52,6 @@ void CollectDataTablesRows(std::vector<UDataTable*> DataTables, std::map<FName,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetItemLevel(const FDataTableCategoryHandle& LootLevelData, int WorldLevel)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
float GetAmountOfLootPackagesToDrop(FFortLootTierData* LootTierData, int OriginalNumberLootDrops)
|
float GetAmountOfLootPackagesToDrop(FFortLootTierData* LootTierData, int OriginalNumberLootDrops)
|
||||||
{
|
{
|
||||||
if (LootTierData->GetLootPackageCategoryMinArray().Num() != LootTierData->GetLootPackageCategoryWeightArray().Num()
|
if (LootTierData->GetLootPackageCategoryMinArray().Num() != LootTierData->GetLootPackageCategoryWeightArray().Num()
|
||||||
@@ -183,7 +179,7 @@ FFortLootTierData* PickLootTierData(const std::vector<UDataTable*>& LTDTables, F
|
|||||||
return ChosenRowLootTierData;
|
return ChosenRowLootTierData;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, const FName& LootPackageName, std::vector<LootDrop>* OutEntries, int LootPackageCategory = -1, bool bPrint = false)
|
void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, const FName& LootPackageName, std::vector<LootDrop>* OutEntries, int LootPackageCategory = -1, int WorldLevel = 0, bool bPrint = false)
|
||||||
{
|
{
|
||||||
if (!OutEntries)
|
if (!OutEntries)
|
||||||
return;
|
return;
|
||||||
@@ -201,14 +197,16 @@ void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, cons
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if (WorldLevel >= 0)
|
// todo add required tag?
|
||||||
|
|
||||||
|
if (WorldLevel >= 0)
|
||||||
{
|
{
|
||||||
if (LootPackage->MaxWorldLevel >= 0 && WorldLevel > LootPackage->MaxWorldLevel)
|
if (LootPackage->GetMaxWorldLevel() >= 0 && WorldLevel > LootPackage->GetMaxWorldLevel())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (LootPackage->MinWorldLevel >= 0 && WorldLevel < LootPackage->MinWorldLevel)
|
if (LootPackage->GetMinWorldLevel() >= 0 && WorldLevel < LootPackage->GetMinWorldLevel())
|
||||||
return 0;
|
return 0;
|
||||||
} */
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
@@ -242,7 +240,7 @@ void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, cons
|
|||||||
|
|
||||||
PickLootDropsFromLootPackage(LPTables,
|
PickLootDropsFromLootPackage(LPTables,
|
||||||
PickedPackage->GetLootPackageCall().Data.Data ? UKismetStringLibrary::Conv_StringToName(PickedPackage->GetLootPackageCall()) : FName(0),
|
PickedPackage->GetLootPackageCall().Data.Data ? UKismetStringLibrary::Conv_StringToName(PickedPackage->GetLootPackageCall()) : FName(0),
|
||||||
OutEntries, LootPackageCategoryToUseForLPCall, bPrint
|
OutEntries, LootPackageCategoryToUseForLPCall, WorldLevel, bPrint
|
||||||
);
|
);
|
||||||
|
|
||||||
v9++;
|
v9++;
|
||||||
@@ -260,15 +258,15 @@ void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, cons
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ItemLevel = 0;
|
|
||||||
|
|
||||||
auto WeaponItemDefinition = Cast<UFortWeaponItemDefinition>(ItemDefinition);
|
auto WeaponItemDefinition = Cast<UFortWeaponItemDefinition>(ItemDefinition);
|
||||||
int LoadedAmmo = WeaponItemDefinition ? WeaponItemDefinition->GetClipSize() : 0; // we shouldnt set loaded ammo here techinally
|
int LoadedAmmo = WeaponItemDefinition ? WeaponItemDefinition->GetClipSize() : 0; // we shouldnt set loaded ammo here techinally
|
||||||
|
|
||||||
if (auto WorldItemDefinition = Cast<UFortWorldItemDefinition>(ItemDefinition))
|
auto WorldItemDefinition = Cast<UFortWorldItemDefinition>(ItemDefinition);
|
||||||
{
|
|
||||||
ItemLevel = 0; // GetItemLevel(WorldItemDefinition->LootLevelData, 0);
|
if (!WorldItemDefinition) // hahahah not proper!!
|
||||||
}
|
return;
|
||||||
|
|
||||||
|
int ItemLevel = UFortLootLevel::GetItemLevel(WorldItemDefinition->GetLootLevelData(), WorldLevel);
|
||||||
|
|
||||||
int CountMultiplier = 1;
|
int CountMultiplier = 1;
|
||||||
int FinalCount = CountMultiplier * PickedPackage->GetCount();
|
int FinalCount = CountMultiplier * PickedPackage->GetCount();
|
||||||
@@ -282,15 +280,30 @@ void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, cons
|
|||||||
|
|
||||||
while (FinalCount > 0)
|
while (FinalCount > 0)
|
||||||
{
|
{
|
||||||
int CurrentCountForEntry = PickedPackage->GetCount(); // Idk calls some itemdefinition vfunc
|
int MaxStackSize = ItemDefinition->GetMaxStackSize();
|
||||||
|
|
||||||
OutEntries->push_back(LootDrop(FFortItemEntry::MakeItemEntry(ItemDefinition, CurrentCountForEntry, LoadedAmmo)));
|
int CurrentCountForEntry = MaxStackSize;
|
||||||
|
|
||||||
|
if (FinalCount <= MaxStackSize)
|
||||||
|
CurrentCountForEntry = FinalCount;
|
||||||
|
|
||||||
|
if (CurrentCountForEntry <= 0)
|
||||||
|
CurrentCountForEntry = 0;
|
||||||
|
|
||||||
|
auto ActualItemLevel = WorldItemDefinition->PickLevel(FinalItemLevel);
|
||||||
|
|
||||||
|
OutEntries->push_back(LootDrop(FFortItemEntry::MakeItemEntry(ItemDefinition, CurrentCountForEntry, LoadedAmmo, 0x3F800000, ActualItemLevel)));
|
||||||
|
|
||||||
|
/* if (bPrint)
|
||||||
|
{
|
||||||
|
LOG_INFO(LogDev, "ActualItemLevel: {} FinalItemLevel: {} ItemLevel: {}", ActualItemLevel, FinalItemLevel, ItemLevel);
|
||||||
|
} */
|
||||||
|
|
||||||
if (Engine_Version >= 424)
|
if (Engine_Version >= 424)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Alright, so Fortnite literally doesn't reference the first loot package category for chests and floor loot (didnt check rest).
|
Alright, so Fortnite literally doesn't reference the first loot package category for chests and floor loot on chapter two and above (didnt check rest).
|
||||||
Usually the first loot package category in our case is ammo, so this is quite weird.
|
Usually the first loot package category in our case is ammo, so this is quite weird.
|
||||||
I have no clue how Fortnite would actually add the ammo.
|
I have no clue how Fortnite would actually add the ammo.
|
||||||
|
|
||||||
@@ -306,7 +319,7 @@ void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, cons
|
|||||||
|
|
||||||
if (AmmoData)
|
if (AmmoData)
|
||||||
{
|
{
|
||||||
int AmmoCount = AmmoData->GetDropCount(); // idk about this one
|
int AmmoCount = AmmoData->GetDropCount(); // uhh???
|
||||||
|
|
||||||
OutEntries->push_back(LootDrop(FFortItemEntry::MakeItemEntry(AmmoData, AmmoCount)));
|
OutEntries->push_back(LootDrop(FFortItemEntry::MakeItemEntry(AmmoData, AmmoCount)));
|
||||||
}
|
}
|
||||||
@@ -323,7 +336,7 @@ void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<LootDrop> PickLootDrops(FName TierGroupName, int ForcedLootTier, bool bPrint, int recursive)
|
std::vector<LootDrop> PickLootDrops(FName TierGroupName, int WorldLevel, int ForcedLootTier, bool bPrint, int recursive)
|
||||||
{
|
{
|
||||||
std::vector<LootDrop> LootDrops;
|
std::vector<LootDrop> LootDrops;
|
||||||
|
|
||||||
@@ -659,7 +672,7 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, int ForcedLootTier, boo
|
|||||||
|
|
||||||
int LootPackageCategory = i;
|
int LootPackageCategory = i;
|
||||||
|
|
||||||
PickLootDropsFromLootPackage(LPTables, ChosenRowLootTierData->GetLootPackage(), &LootDrops, LootPackageCategory, bPrint);
|
PickLootDropsFromLootPackage(LPTables, ChosenRowLootTierData->GetLootPackage(), &LootDrops, LootPackageCategory, WorldLevel, bPrint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,18 @@ public:
|
|||||||
return *(int*)(__int64(this) + CountOffset);
|
return *(int*)(__int64(this) + CountOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int& GetMinWorldLevel()
|
||||||
|
{
|
||||||
|
static auto MinWorldLevelOffset = FindOffsetStruct("/Script/FortniteGame.FortLootPackageData", "MinWorldLevel");
|
||||||
|
return *(int*)(__int64(this) + MinWorldLevelOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
int& GetMaxWorldLevel()
|
||||||
|
{
|
||||||
|
static auto MaxWorldLevelOffset = FindOffsetStruct("/Script/FortniteGame.FortLootPackageData", "MaxWorldLevel");
|
||||||
|
return *(int*)(__int64(this) + MaxWorldLevelOffset);
|
||||||
|
}
|
||||||
|
|
||||||
int& GetLootPackageCategory()
|
int& GetLootPackageCategory()
|
||||||
{
|
{
|
||||||
static auto LootPackageCategoryOffset = FindOffsetStruct("/Script/FortniteGame.FortLootPackageData", "LootPackageCategory");
|
static auto LootPackageCategoryOffset = FindOffsetStruct("/Script/FortniteGame.FortLootPackageData", "LootPackageCategory");
|
||||||
@@ -183,4 +195,4 @@ FORCEINLINE static ValueType PickWeightedElement(const std::map<KeyType, ValueTy
|
|||||||
return ValueType();
|
return ValueType();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<LootDrop> PickLootDrops(FName TierGroupName, int ForcedLootTier = -1, bool bPrint = false, int recursive = 0);
|
std::vector<LootDrop> PickLootDrops(FName TierGroupName, int WorldLevel, int ForcedLootTier = -1, bool bPrint = false, int recursive = 0);
|
||||||
@@ -34,7 +34,7 @@ AFortPickup* AFortPickup::SpawnPickup(PickupCreateData& PickupData)
|
|||||||
if (PickupData.Source == -1)
|
if (PickupData.Source == -1)
|
||||||
PickupData.Source = 0;
|
PickupData.Source = 0;
|
||||||
if (PickupData.SourceType == -1)
|
if (PickupData.SourceType == -1)
|
||||||
PickupData.SourceType = -1;
|
PickupData.SourceType = 0;
|
||||||
|
|
||||||
/* if (PickupData.bToss)
|
/* if (PickupData.bToss)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -430,15 +430,11 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame*
|
|||||||
FVector LocationToSpawnLoot = ReceivingActor->GetActorLocation() + ReceivingActor->GetActorRightVector() * 70.f + FVector{ 0, 0, 50 };
|
FVector LocationToSpawnLoot = ReceivingActor->GetActorLocation() + ReceivingActor->GetActorRightVector() * 70.f + FVector{ 0, 0, 50 };
|
||||||
|
|
||||||
static auto FortAthenaVehicleClass = FindObject<UClass>(L"/Script/FortniteGame.FortAthenaVehicle");
|
static auto FortAthenaVehicleClass = FindObject<UClass>(L"/Script/FortniteGame.FortAthenaVehicle");
|
||||||
static auto SearchAnimationCountOffset = FindOffsetStruct("/Script/FortniteGame.FortSearchBounceData", "SearchAnimationCount");
|
|
||||||
|
|
||||||
if (auto BuildingContainer = Cast<ABuildingContainer>(ReceivingActor))
|
if (auto BuildingContainer = Cast<ABuildingContainer>(ReceivingActor))
|
||||||
{
|
{
|
||||||
static auto bAlreadySearchedOffset = BuildingContainer->GetOffset("bAlreadySearched");
|
static auto bAlreadySearchedOffset = BuildingContainer->GetOffset("bAlreadySearched");
|
||||||
static auto SearchBounceDataOffset = BuildingContainer->GetOffset("SearchBounceData");
|
|
||||||
static auto bAlreadySearchedFieldMask = GetFieldMask(BuildingContainer->GetProperty("bAlreadySearched"));
|
static auto bAlreadySearchedFieldMask = GetFieldMask(BuildingContainer->GetProperty("bAlreadySearched"));
|
||||||
|
|
||||||
auto SearchBounceData = BuildingContainer->GetPtr<void>(SearchBounceDataOffset);
|
|
||||||
|
|
||||||
if (BuildingContainer->ReadBitfieldValue(bAlreadySearchedOffset, bAlreadySearchedFieldMask))
|
if (BuildingContainer->ReadBitfieldValue(bAlreadySearchedOffset, bAlreadySearchedFieldMask))
|
||||||
return;
|
return;
|
||||||
@@ -446,10 +442,6 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame*
|
|||||||
// LOG_INFO(LogInteraction, "bAlreadySearchedFieldMask: {}", bAlreadySearchedFieldMask);
|
// LOG_INFO(LogInteraction, "bAlreadySearchedFieldMask: {}", bAlreadySearchedFieldMask);
|
||||||
|
|
||||||
BuildingContainer->SetBitfieldValue(bAlreadySearchedOffset, bAlreadySearchedFieldMask, true);
|
BuildingContainer->SetBitfieldValue(bAlreadySearchedOffset, bAlreadySearchedFieldMask, true);
|
||||||
(*(int*)(__int64(SearchBounceData) + SearchAnimationCountOffset))++;
|
|
||||||
|
|
||||||
static auto OnRep_bAlreadySearchedFn = FindObject<UFunction>(L"/Script/FortniteGame.BuildingContainer.OnRep_bAlreadySearched");
|
|
||||||
BuildingContainer->ProcessEvent(OnRep_bAlreadySearchedFn);
|
|
||||||
|
|
||||||
BuildingContainer->SpawnLoot(PlayerController->GetMyFortPawn());
|
BuildingContainer->SpawnLoot(PlayerController->GetMyFortPawn());
|
||||||
|
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ void AFortPlayerPawn::ServerHandlePickupHook(AFortPlayerPawn* Pawn, AFortPickup*
|
|||||||
|
|
||||||
static auto bPickedUpOffset = Pickup->GetOffset("bPickedUp");
|
static auto bPickedUpOffset = Pickup->GetOffset("bPickedUp");
|
||||||
|
|
||||||
LOG_INFO(LogDev, "InFlyTime: {}", InFlyTime);
|
// LOG_INFO(LogDev, "InFlyTime: {}", InFlyTime);
|
||||||
|
|
||||||
if (Pickup->Get<bool>(bPickedUpOffset))
|
if (Pickup->Get<bool>(bPickedUpOffset))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "BuildingActor.h"
|
#include "BuildingActor.h"
|
||||||
#include "FortPlayerPawnAthena.h"
|
#include "FortPlayerPawnAthena.h"
|
||||||
#include "GameplayAbilityTypes.h"
|
#include "GameplayAbilityTypes.h"
|
||||||
|
#include "FortPlayerState.h"
|
||||||
|
|
||||||
struct FGameplayTagRequirements
|
struct FGameplayTagRequirements
|
||||||
{
|
{
|
||||||
@@ -275,6 +276,12 @@ struct FWinConditionScoreData
|
|||||||
class UFortPlaylist : public UObject
|
class UFortPlaylist : public UObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
int& GetPlaylistId()
|
||||||
|
{
|
||||||
|
static auto PlaylistIdOffset = GetOffset("PlaylistId");
|
||||||
|
return Get<int>(PlaylistIdOffset);
|
||||||
|
}
|
||||||
|
|
||||||
TArray<TSoftObjectPtr<UFortGameplayModifierItemDefinition>>& GetModifierList()
|
TArray<TSoftObjectPtr<UFortGameplayModifierItemDefinition>>& GetModifierList()
|
||||||
{
|
{
|
||||||
static auto ModifierListOffset = this->GetOffset("ModifierList");
|
static auto ModifierListOffset = this->GetOffset("ModifierList");
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "FortItemDefinition.h"
|
#include "FortItemDefinition.h"
|
||||||
|
#include "DataTable.h"
|
||||||
|
|
||||||
enum class EWorldItemDropBehavior : uint8_t
|
enum class EWorldItemDropBehavior : uint8_t
|
||||||
{
|
{
|
||||||
@@ -10,6 +11,16 @@ enum class EWorldItemDropBehavior : uint8_t
|
|||||||
EWorldItemDropBehavior_MAX = 3
|
EWorldItemDropBehavior_MAX = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FFortLootLevelData : public FTableRowBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FName Category; // 0x8(0x8)(Edit, BlueprintVisible, BlueprintReadOnly, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
int32 LootLevel; // 0x10(0x4)(Edit, BlueprintVisible, BlueprintReadOnly, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
int32 MinItemLevel; // 0x14(0x4)(Edit, BlueprintVisible, BlueprintReadOnly, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
int32 MaxItemLevel; // 0x18(0x4)(Edit, BlueprintVisible, BlueprintReadOnly, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
uint8 Pad_B94[0x4]; // Fixing Size Of Struct [ Dumper-7 ]
|
||||||
|
};
|
||||||
|
|
||||||
class UFortWorldItemDefinition : public UFortItemDefinition
|
class UFortWorldItemDefinition : public UFortItemDefinition
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -20,6 +31,35 @@ public:
|
|||||||
return ReadBitfieldValue(bCanBeDroppedOffset, bCanBeDroppedFieldMask);
|
return ReadBitfieldValue(bCanBeDroppedOffset, bCanBeDroppedFieldMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PickLevel(int PreferredLevel) // well min level and maxlevel is sometimes in ufortowrlditemdeifnit9 then on older versions ufortitemdefinitoj so idk wher tyo put this
|
||||||
|
{
|
||||||
|
static auto MinLevelOffset = GetOffset("MinLevel");
|
||||||
|
static auto MaxLevelOffset = GetOffset("MaxLevel");
|
||||||
|
|
||||||
|
const int MinLevel = Get<int>(MinLevelOffset);
|
||||||
|
const int MaxLevel = Get<int>(MaxLevelOffset);
|
||||||
|
|
||||||
|
int PickedLevel = 0;
|
||||||
|
|
||||||
|
if (PreferredLevel >= MinLevel)
|
||||||
|
PickedLevel = PreferredLevel;
|
||||||
|
|
||||||
|
if (MaxLevel >= 0)
|
||||||
|
{
|
||||||
|
if (PickedLevel <= MaxLevel)
|
||||||
|
return PickedLevel;
|
||||||
|
return MaxLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PickedLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
FDataTableCategoryHandle& GetLootLevelData()
|
||||||
|
{
|
||||||
|
static auto LootLevelDataOffset = GetOffset("LootLevelData");
|
||||||
|
return Get<FDataTableCategoryHandle>(LootLevelDataOffset);
|
||||||
|
}
|
||||||
|
|
||||||
int& GetDropCount()
|
int& GetDropCount()
|
||||||
{
|
{
|
||||||
static auto DropCountOffset = GetOffset("DropCount");
|
static auto DropCountOffset = GetOffset("DropCount");
|
||||||
|
|||||||
@@ -214,6 +214,7 @@
|
|||||||
<ClCompile Include="FortItem.cpp" />
|
<ClCompile Include="FortItem.cpp" />
|
||||||
<ClCompile Include="FortItemDefinition.cpp" />
|
<ClCompile Include="FortItemDefinition.cpp" />
|
||||||
<ClCompile Include="FortKismetLibrary.cpp" />
|
<ClCompile Include="FortKismetLibrary.cpp" />
|
||||||
|
<ClCompile Include="FortLootLevel.cpp" />
|
||||||
<ClCompile Include="FortLootPackage.cpp" />
|
<ClCompile Include="FortLootPackage.cpp" />
|
||||||
<ClCompile Include="FortMinigame.cpp" />
|
<ClCompile Include="FortMinigame.cpp" />
|
||||||
<ClCompile Include="FortOctopusVehicle.cpp" />
|
<ClCompile Include="FortOctopusVehicle.cpp" />
|
||||||
@@ -287,6 +288,7 @@
|
|||||||
<ClInclude Include="Channel.h" />
|
<ClInclude Include="Channel.h" />
|
||||||
<ClInclude Include="CheatManager.h" />
|
<ClInclude Include="CheatManager.h" />
|
||||||
<ClInclude Include="Class.h" />
|
<ClInclude Include="Class.h" />
|
||||||
|
<ClInclude Include="objectviewer.h" />
|
||||||
<ClInclude Include="commands.h" />
|
<ClInclude Include="commands.h" />
|
||||||
<ClInclude Include="ContainerAllocationPolicies.h" />
|
<ClInclude Include="ContainerAllocationPolicies.h" />
|
||||||
<ClInclude Include="Controller.h" />
|
<ClInclude Include="Controller.h" />
|
||||||
|
|||||||
@@ -271,6 +271,9 @@
|
|||||||
<ClCompile Include="inc.cpp">
|
<ClCompile Include="inc.cpp">
|
||||||
<Filter>Reboot\Private</Filter>
|
<Filter>Reboot\Private</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="FortLootLevel.cpp">
|
||||||
|
<Filter>FortniteGame\Source\FortniteGame\Private\Items</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="log.h" />
|
<ClInclude Include="log.h" />
|
||||||
@@ -859,6 +862,9 @@
|
|||||||
<ClInclude Include="inc.h">
|
<ClInclude Include="inc.h">
|
||||||
<Filter>Reboot\Public</Filter>
|
<Filter>Reboot\Public</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="objectviewer.h">
|
||||||
|
<Filter>Reboot\Public</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="Engine">
|
<Filter Include="Engine">
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ void UWorld::Listen()
|
|||||||
*(UNetDriver**)(__int64(LevelCollections.AtPtr(0, LevelCollectionSize)) + 0x10) = NewNetDriver;
|
*(UNetDriver**)(__int64(LevelCollections.AtPtr(0, LevelCollectionSize)) + 0x10) = NewNetDriver;
|
||||||
*(UNetDriver**)(__int64(LevelCollections.AtPtr(1, LevelCollectionSize)) + 0x10) = NewNetDriver;
|
*(UNetDriver**)(__int64(LevelCollections.AtPtr(1, LevelCollectionSize)) + 0x10) = NewNetDriver;
|
||||||
|
|
||||||
LOG_INFO(LogNet, "Listening on port {}!", Port + Globals::AmountOfListens - 1);
|
LOG_INFO(LogNet, "Listening on port {}{}!", Port + Globals::AmountOfListens - 1, Engine_Version <= 419 ? " (Wait like 10 seconds before joining though)" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
AWorldSettings* UWorld::GetWorldSettings(const bool bCheckStreamingPersistent, const bool bChecked) const
|
AWorldSettings* UWorld::GetWorldSettings(const bool bCheckStreamingPersistent, const bool bChecked) const
|
||||||
|
|||||||
@@ -386,6 +386,9 @@ void Offsets::FindAll()
|
|||||||
Engine_Version == 424 ? (Fortnite_Version >= 11.00 && Fortnite_Version <= 11.10 ? 0x57 :
|
Engine_Version == 424 ? (Fortnite_Version >= 11.00 && Fortnite_Version <= 11.10 ? 0x57 :
|
||||||
(Fortnite_Version == 11.30 || Fortnite_Version == 11.31 ? 0x59 : 0x5A)) : 0x56;
|
(Fortnite_Version == 11.30 || Fortnite_Version == 11.31 ? 0x59 : 0x5A)) : 0x56;
|
||||||
|
|
||||||
|
if (Engine_Version == 421)
|
||||||
|
Offsets::PropertyClass = 0x70;
|
||||||
|
|
||||||
// ^ I know this makes no sense, 7.40-8.40 is 0x57, other 7-10 is 0x56, 11.00-11.10 = 0x57, 11.30-11.31 = 0x59, other S11 is 0x5A
|
// ^ I know this makes no sense, 7.40-8.40 is 0x57, other 7-10 is 0x56, 11.00-11.10 = 0x57, 11.30-11.31 = 0x59, other S11 is 0x5A
|
||||||
|
|
||||||
else if (std::floor(Fortnite_Version) == 12 || std::floor(Fortnite_Version) == 13)
|
else if (std::floor(Fortnite_Version) == 12 || std::floor(Fortnite_Version) == 13)
|
||||||
@@ -437,18 +440,23 @@ void Offsets::FindAll()
|
|||||||
}
|
}
|
||||||
|
|
||||||
Offsets::IsNetRelevantFor = FindIsNetRelevantForOffset();
|
Offsets::IsNetRelevantFor = FindIsNetRelevantForOffset();
|
||||||
|
Offsets::UnderlyingType = Offsets::PropertyClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Offsets::Print()
|
void Offsets::Print()
|
||||||
{
|
{
|
||||||
LOG_INFO(LogDev, "Offset_Internal: 0x{:x}", Offset_Internal);
|
|
||||||
LOG_INFO(LogDev, "SuperStruct: 0x{:x}", SuperStruct);
|
|
||||||
LOG_INFO(LogDev, "Children: 0x{:x}", Children);
|
|
||||||
LOG_INFO(LogDev, "PropertiesSize: 0x{:x}", PropertiesSize);
|
|
||||||
LOG_INFO(LogDev, "Func: 0x{:x}", Func);
|
LOG_INFO(LogDev, "Func: 0x{:x}", Func);
|
||||||
|
LOG_INFO(LogDev, "PropertiesSize: 0x{:x}", PropertiesSize);
|
||||||
|
LOG_INFO(LogDev, "Children: 0x{:x}", Children);
|
||||||
|
LOG_INFO(LogDev, "SuperStruct: 0x{:x}", SuperStruct);
|
||||||
|
LOG_INFO(LogDev, "PropertyClass: 0x{:x}", PropertyClass);
|
||||||
|
LOG_INFO(LogDev, "UnderlyingType: 0x{:x}", UnderlyingType);
|
||||||
|
LOG_INFO(LogDev, "Offset_Internal: 0x{:x}", Offset_Internal);
|
||||||
LOG_INFO(LogDev, "ServerReplicateActors: 0x{:x}", ServerReplicateActors);
|
LOG_INFO(LogDev, "ServerReplicateActors: 0x{:x}", ServerReplicateActors);
|
||||||
LOG_INFO(LogDev, "ReplicationFrame: 0x{:x}", ReplicationFrame);
|
LOG_INFO(LogDev, "ReplicationFrame: 0x{:x}", ReplicationFrame);
|
||||||
LOG_INFO(LogDev, "IsNetRelevantFor: 0x{:x}", IsNetRelevantFor);
|
LOG_INFO(LogDev, "IsNetRelevantFor: 0x{:x}", IsNetRelevantFor);
|
||||||
|
LOG_INFO(LogDev, "NetworkObjectList: 0x{:x}", NetworkObjectList);
|
||||||
|
LOG_INFO(LogDev, "ClientWorldPackageName: 0x{:x}", ClientWorldPackageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Addresses::Init()
|
void Addresses::Init()
|
||||||
|
|||||||
@@ -84,6 +84,8 @@ namespace Offsets
|
|||||||
extern inline uint64 PropertiesSize = 0;
|
extern inline uint64 PropertiesSize = 0;
|
||||||
extern inline uint64 Children = 0;
|
extern inline uint64 Children = 0;
|
||||||
extern inline uint64 SuperStruct = 0;
|
extern inline uint64 SuperStruct = 0;
|
||||||
|
extern inline uint64 PropertyClass = 0;
|
||||||
|
extern inline uint64 UnderlyingType = 0;
|
||||||
extern inline uint64 Offset_Internal = 0;
|
extern inline uint64 Offset_Internal = 0;
|
||||||
extern inline uint64 ServerReplicateActors = 0;
|
extern inline uint64 ServerReplicateActors = 0;
|
||||||
extern inline uint64 ReplicationFrame = 0;
|
extern inline uint64 ReplicationFrame = 0;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "builder.h"
|
#include "builder.h"
|
||||||
#include "FortLootPackage.h"
|
#include "FortLootPackage.h"
|
||||||
#include "bots.h"
|
#include "bots.h"
|
||||||
|
#include "FortLootLevel.h"
|
||||||
|
|
||||||
bool IsOperator(APlayerState* PlayerState, AFortPlayerController* PlayerController)
|
bool IsOperator(APlayerState* PlayerState, AFortPlayerController* PlayerController)
|
||||||
{
|
{
|
||||||
@@ -200,6 +201,12 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg)
|
|||||||
if (bShouldUpdate)
|
if (bShouldUpdate)
|
||||||
WorldInventory->Update();
|
WorldInventory->Update();
|
||||||
|
|
||||||
|
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
||||||
|
|
||||||
|
auto ItemLevel = UFortLootLevel::GetItemLevel(WID->GetLootLevelData(), GameState->GetWorldLevel());
|
||||||
|
|
||||||
|
LOG_INFO(LogDev, "ItemLevel: {}", ItemLevel);
|
||||||
|
LOG_INFO(LogDev, "PickLevel: {}", WID->PickLevel(ItemLevel));
|
||||||
SendMessageToConsole(PlayerController, L"Granted item!");
|
SendMessageToConsole(PlayerController, L"Granted item!");
|
||||||
}
|
}
|
||||||
else if (Command == "printsimulatelootdrops")
|
else if (Command == "printsimulatelootdrops")
|
||||||
@@ -211,8 +218,9 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto& lootTierGroup = Arguments[1];
|
auto& lootTierGroup = Arguments[1];
|
||||||
|
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
||||||
|
|
||||||
auto LootDrops = PickLootDrops(UKismetStringLibrary::Conv_StringToName(std::wstring(lootTierGroup.begin(), lootTierGroup.end()).c_str()), -1, true);
|
auto LootDrops = PickLootDrops(UKismetStringLibrary::Conv_StringToName(std::wstring(lootTierGroup.begin(), lootTierGroup.end()).c_str()), GameState->GetWorldLevel(), -1, true);
|
||||||
|
|
||||||
for (int i = 0; i < LootDrops.size(); i++)
|
for (int i = 0; i < LootDrops.size(); i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -81,6 +81,20 @@ static __int64 DispatchRequestHook(__int64 a1, __int64* a2, int a3)
|
|||||||
return DispatchRequestOriginal(a1, a2, 3);
|
return DispatchRequestOriginal(a1, a2, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool (*CanCreateInCurrentContextOriginal)(UObject* Template);
|
||||||
|
|
||||||
|
bool CanCreateInCurrentContextHook(UObject* Template)
|
||||||
|
{
|
||||||
|
auto Original = CanCreateInCurrentContextOriginal(Template);
|
||||||
|
|
||||||
|
if (!Original)
|
||||||
|
{
|
||||||
|
LOG_INFO(LogDev, "CanCreateInCurrentContext returned false, but we will return true.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void (*ApplyHomebaseEffectsOnPlayerSetupOriginal)(
|
void (*ApplyHomebaseEffectsOnPlayerSetupOriginal)(
|
||||||
__int64* GameState,
|
__int64* GameState,
|
||||||
__int64 a2,
|
__int64 a2,
|
||||||
@@ -426,6 +440,8 @@ DWORD WINAPI Main(LPVOID)
|
|||||||
nullptr, false);
|
nullptr, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hooking::MinHook::Hook(FortPlayerControllerZoneDefault->VFTable[0xD0 / 8], CanCreateInCurrentContextHook, (PVOID*)&CanCreateInCurrentContextOriginal);
|
||||||
|
|
||||||
HookInstruction(Addresses::UpdateTrackedAttributesLea, (PVOID)UFortGadgetItemDefinition::UpdateTrackedAttributesHook, "/Script/FortniteGame.FortPlayerController.Suicide", ERelativeOffsets::LEA, FortPlayerControllerAthenaDefault);
|
HookInstruction(Addresses::UpdateTrackedAttributesLea, (PVOID)UFortGadgetItemDefinition::UpdateTrackedAttributesHook, "/Script/FortniteGame.FortPlayerController.Suicide", ERelativeOffsets::LEA, FortPlayerControllerAthenaDefault);
|
||||||
HookInstruction(Addresses::CombinePickupLea, (PVOID)AFortPickup::CombinePickupHook, "/Script/Engine.PlayerController.SetVirtualJoystickVisibility", ERelativeOffsets::LEA, FortPlayerControllerAthenaDefault);
|
HookInstruction(Addresses::CombinePickupLea, (PVOID)AFortPickup::CombinePickupHook, "/Script/Engine.PlayerController.SetVirtualJoystickVisibility", ERelativeOffsets::LEA, FortPlayerControllerAthenaDefault);
|
||||||
|
|
||||||
|
|||||||
@@ -144,6 +144,8 @@ static inline uint64 FindObjectArray()
|
|||||||
|
|
||||||
static inline uint64 FindPickupInitialize()
|
static inline uint64 FindPickupInitialize()
|
||||||
{
|
{
|
||||||
|
if (Engine_Version == 419)
|
||||||
|
return Memcury::Scanner::FindPattern("48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 20 80 B9 ? ? ? ? ? 41 0F B6 E9").Get(); // 1.11
|
||||||
if (Engine_Version == 420)
|
if (Engine_Version == 420)
|
||||||
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 41 56 48 83 EC 20 80 B9 ? ? ? ? ? 45 0F B6 F1 49 8B E8").Get(); // 4.1
|
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 41 56 48 83 EC 20 80 B9 ? ? ? ? ? 45 0F B6 F1 49 8B E8").Get(); // 4.1
|
||||||
if (Engine_Version == 421)
|
if (Engine_Version == 421)
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
#include "events.h"
|
#include "events.h"
|
||||||
#include "FortAthenaMutator_Heist.h"
|
#include "FortAthenaMutator_Heist.h"
|
||||||
#include "BGA.h"
|
#include "BGA.h"
|
||||||
|
#include "objectviewer.h"
|
||||||
|
|
||||||
#define GAME_TAB 1
|
#define GAME_TAB 1
|
||||||
#define PLAYERS_TAB 2
|
#define PLAYERS_TAB 2
|
||||||
@@ -283,7 +284,7 @@ static inline void StaticUI()
|
|||||||
|
|
||||||
#ifndef PROD
|
#ifndef PROD
|
||||||
ImGui::Checkbox("Log ProcessEvent", &Globals::bLogProcessEvent);
|
ImGui::Checkbox("Log ProcessEvent", &Globals::bLogProcessEvent);
|
||||||
ImGui::InputInt("Amount of bots to spawn", &AmountOfBotsToSpawn);
|
// ImGui::InputInt("Amount of bots to spawn", &AmountOfBotsToSpawn);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ImGui::Checkbox("Infinite Ammo", &Globals::bInfiniteAmmo);
|
ImGui::Checkbox("Infinite Ammo", &Globals::bInfiniteAmmo);
|
||||||
@@ -480,40 +481,6 @@ static inline void MainUI()
|
|||||||
SpawnBGAs();
|
SpawnBGAs();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
if (ImGui::Button("New"))
|
|
||||||
{
|
|
||||||
static auto NextFn = FindObject<UFunction>("/Game/Athena/Prototype/Blueprints/Cube/CUBE.CUBE_C.Next");
|
|
||||||
static auto NewFn = FindObject<UFunction>("/Game/Athena/Prototype/Blueprints/Cube/CUBE.CUBE_C.New");
|
|
||||||
auto Loader = GetEventLoader("/Game/Athena/Prototype/Blueprints/Cube/CUBE.CUBE_C");
|
|
||||||
|
|
||||||
LOG_INFO(LogDev, "Loader: {}", __int64(Loader));
|
|
||||||
|
|
||||||
if (Loader)
|
|
||||||
{
|
|
||||||
int32 NewParam = 1;
|
|
||||||
// Loader->ProcessEvent(NextFn, &NewParam);
|
|
||||||
Loader->ProcessEvent(NewFn, &NewParam);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::Button("Next"))
|
|
||||||
{
|
|
||||||
static auto NextFn = FindObject<UFunction>("/Game/Athena/Prototype/Blueprints/Cube/CUBE.CUBE_C.Next");
|
|
||||||
static auto NewFn = FindObject<UFunction>("/Game/Athena/Prototype/Blueprints/Cube/CUBE.CUBE_C.New");
|
|
||||||
auto Loader = GetEventLoader("/Game/Athena/Prototype/Blueprints/Cube/CUBE.CUBE_C");
|
|
||||||
|
|
||||||
LOG_INFO(LogDev, "Loader: {}", __int64(Loader));
|
|
||||||
|
|
||||||
if (Loader)
|
|
||||||
{
|
|
||||||
int32 NewParam = 1;
|
|
||||||
Loader->ProcessEvent(NextFn, &NewParam);
|
|
||||||
// Loader->ProcessEvent(NewFn, &NewParam);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!bIsInAutoRestart && (Engine_Version < 424 && ImGui::Button("Restart")))
|
if (!bIsInAutoRestart && (Engine_Version < 424 && ImGui::Button("Restart")))
|
||||||
{
|
{
|
||||||
if (Engine_Version < 424)
|
if (Engine_Version < 424)
|
||||||
@@ -526,45 +493,6 @@ static inline void MainUI()
|
|||||||
LOG_ERROR(LogGame, "Restarting is not supported on chapter 2 and above!");
|
LOG_ERROR(LogGame, "Restarting is not supported on chapter 2 and above!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if (ImGui::Button("TEST"))
|
|
||||||
{
|
|
||||||
auto GameMode = (AFortGameMode*)GetWorld()->GetGameMode();
|
|
||||||
auto GameState = GameMode->GetGameState();
|
|
||||||
|
|
||||||
static auto mutatorClass = FindObject<UClass>("/Script/FortniteGame.FortAthenaMutator");
|
|
||||||
auto AllMutators = UGameplayStatics::GetAllActorsOfClass(GetWorld(), mutatorClass);
|
|
||||||
|
|
||||||
for (int i = 0; i < AllMutators.Num(); i++)
|
|
||||||
{
|
|
||||||
auto Mutator = AllMutators.at(i);
|
|
||||||
|
|
||||||
LOG_INFO(LogDev, "[{}] Mutator: {}", i, Mutator->GetFullName());
|
|
||||||
|
|
||||||
if (auto DiscoMutator = Cast<AFortAthenaMutator_Disco>(Mutator))
|
|
||||||
{
|
|
||||||
auto& ControlPointSpawnData = DiscoMutator->GetControlPointSpawnData();
|
|
||||||
|
|
||||||
LOG_INFO(LogDev, "ControlPointSpawnData.Num(): {}", ControlPointSpawnData.Num());
|
|
||||||
}
|
|
||||||
else if (auto HeistMutator = Cast<AFortAthenaMutator_Heist>(Mutator))
|
|
||||||
{
|
|
||||||
auto& HeistExitCraftSpawnData = HeistMutator->GetHeistExitCraftSpawnData();
|
|
||||||
|
|
||||||
LOG_INFO(LogDev, "HeistExitCraftSpawnData.Num(): {}", HeistExitCraftSpawnData.Num());
|
|
||||||
|
|
||||||
for (int j = 0; j < HeistExitCraftSpawnData.Num(); j++)
|
|
||||||
{
|
|
||||||
auto& CurrentHeistExitCraftSpawnData = HeistExitCraftSpawnData.at(j);
|
|
||||||
auto CurveTable = CurrentHeistExitCraftSpawnData.SpawnDelayTime.GetCurve().CurveTable;
|
|
||||||
|
|
||||||
// LOG_INFO(LogDev, "{} {}", CurveTable ? CurveTable->GetFullName() : "InvalidTable",
|
|
||||||
// CurrentHeistExitCraftSpawnData.SpawnDelayTime.GetCurve().RowName.IsValid() ? CurrentHeistExitCraftSpawnData.SpawnDelayTime.GetCurve().RowName.ToString() : "InvalidName");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!bStartedBus)
|
if (!bStartedBus)
|
||||||
{
|
{
|
||||||
@@ -905,13 +833,29 @@ static inline void MainUI()
|
|||||||
{
|
{
|
||||||
static std::string ClassNameToDump;
|
static std::string ClassNameToDump;
|
||||||
static std::string FunctionNameToDump;
|
static std::string FunctionNameToDump;
|
||||||
|
static std::string ObjectToDump;
|
||||||
|
static std::string FileNameToDumpTo;
|
||||||
|
static bool bExcludeUnhandled;
|
||||||
|
|
||||||
ImGui::Checkbox("Fill Vending Machines", &Globals::bFillVendingMachines);
|
ImGui::Checkbox("Fill Vending Machines", &Globals::bFillVendingMachines);
|
||||||
ImGui::Checkbox("Enable Bot Tick", &bEnableBotTick);
|
ImGui::Checkbox("Enable Bot Tick", &bEnableBotTick);
|
||||||
ImGui::Checkbox("Enable Combine Pickup", &bEnableCombinePickup);
|
ImGui::Checkbox("Enable Combine Pickup", &bEnableCombinePickup);
|
||||||
ImGui::InputText("Class Name to mess with", &ClassNameToDump);
|
ImGui::InputText("Class Name to mess with", &ClassNameToDump);
|
||||||
|
ImGui::InputText("Object to dump", &ObjectToDump);
|
||||||
ImGui::InputText("Function Name to mess with", &FunctionNameToDump);
|
ImGui::InputText("Function Name to mess with", &FunctionNameToDump);
|
||||||
|
ImGui::InputText("File name to dump to", &FileNameToDumpTo);
|
||||||
|
ImGui::Checkbox("Exclude unhandled", &bExcludeUnhandled);
|
||||||
|
|
||||||
|
if (ImGui::Button("Dump Object Info"))
|
||||||
|
{
|
||||||
|
auto Object = FindObject(ObjectToDump);
|
||||||
|
|
||||||
|
LOG_INFO(LogDev, "r: {}", __int64(Object));
|
||||||
|
|
||||||
|
// null check is already handled
|
||||||
|
|
||||||
|
ObjectViewer::DumpContentsToFile(Object, FileNameToDumpTo, bExcludeUnhandled);
|
||||||
|
}
|
||||||
|
|
||||||
if (ImGui::Button("Print Class VFT"))
|
if (ImGui::Button("Print Class VFT"))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ inline void InitLogger()
|
|||||||
MakeLogger("LogVehicles");
|
MakeLogger("LogVehicles");
|
||||||
MakeLogger("LogBots");
|
MakeLogger("LogBots");
|
||||||
MakeLogger("LogCosmetics");
|
MakeLogger("LogCosmetics");
|
||||||
|
MakeLogger("LogObjectViewer");
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LOG_DEBUG(loggerName, ...) \
|
#define LOG_DEBUG(loggerName, ...) \
|
||||||
|
|||||||
193
Project Reboot 3.0/objectviewer.h
Normal file
193
Project Reboot 3.0/objectviewer.h
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "reboot.h"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
static inline FName* GetNamePrivateOfProperty(void* Property)
|
||||||
|
{
|
||||||
|
FName* NamePrivate = nullptr;
|
||||||
|
|
||||||
|
if (Engine_Version >= 425)
|
||||||
|
NamePrivate = (FName*)(__int64(Property) + 0x28);
|
||||||
|
else
|
||||||
|
NamePrivate = &((UField*)Property)->NamePrivate;
|
||||||
|
|
||||||
|
return NamePrivate;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline bool IsPropertyA(void* Property, UClass* Class)
|
||||||
|
{
|
||||||
|
if (Engine_Version < 425)
|
||||||
|
{
|
||||||
|
if (((UField*)Property)->IsA(Class))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ObjectViewer
|
||||||
|
{
|
||||||
|
static inline void DumpContentsToFile(UObject* Object, const std::string& FileName, bool bExcludeUnhandled = false)
|
||||||
|
{
|
||||||
|
if (!Object/*->IsValidLowLevel()*/)
|
||||||
|
{
|
||||||
|
LOG_ERROR(LogObjectViewer, "Invalid object passed into DumpContentsToFile!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto ClassClass = FindObject<UClass>(L"/Script/CoreUObject.Class");
|
||||||
|
|
||||||
|
if (Object->IsA(ClassClass))
|
||||||
|
{
|
||||||
|
LOG_ERROR(LogObjectViewer, "Object passed into DumpContentsToFile was a class!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto BytePropertyClass = FindObject<UClass>(L"/Script/CoreUObject.ByteProperty");
|
||||||
|
static auto ObjectPropertyClass = FindObject<UClass>(L"/Script/CoreUObject.ObjectProperty");
|
||||||
|
static auto ClassPropertyClass = FindObject<UClass>(L"/Script/CoreUObject.ClassProperty");
|
||||||
|
static auto DoublePropertyClass = FindObject<UClass>(L"/Script/CoreUObject.DoubleProperty");
|
||||||
|
static auto FloatPropertyClass = FindObject<UClass>(L"/Script/CoreUObject.FloatProperty");
|
||||||
|
static auto Int8PropertyClass = FindObject<UClass>(L"/Script/CoreUObject.Int8Property");
|
||||||
|
static auto EnumPropertyClass = FindObject<UClass>(L"/Script/CoreUObject.EnumProperty");
|
||||||
|
static auto ArrayPropertyClass = FindObject<UClass>(L"/Script/CoreUObject.ArrayProperty");
|
||||||
|
static auto Int64PropertyClass = FindObject<UClass>(L"/Script/CoreUObject.Int64Property");
|
||||||
|
static auto UInt16PropertyClass = FindObject<UClass>(L"/Script/CoreUObject.UInt16Property");
|
||||||
|
static auto BoolPropertyClass = FindObject<UClass>(L"/Script/CoreUObject.BoolProperty");
|
||||||
|
static auto NamePropertyClass = FindObject<UClass>(L"/Script/CoreUObject.NameProperty");
|
||||||
|
static auto UInt32PropertyClass = FindObject<UClass>(L"/Script/CoreUObject.UInt32Property");
|
||||||
|
static auto FunctionClass = FindObject<UClass>(L"/Script/CoreUObject.Function");
|
||||||
|
static auto IntPropertyClass = FindObject<UClass>(L"/Script/CoreUObject.IntProperty");
|
||||||
|
static auto UInt64PropertyClass = FindObject<UClass>(L"/Script/CoreUObject.UInt64Property");
|
||||||
|
static auto StrPropertyClass = FindObject<UClass>(L"/Script/CoreUObject.StrProperty");
|
||||||
|
static auto SoftObjectPropertyClass = FindObject<UClass>(L"/Script/CoreUObject.SoftObjectProperty");
|
||||||
|
|
||||||
|
std::ofstream Stream(FileName);
|
||||||
|
|
||||||
|
if (!Stream.is_open())
|
||||||
|
{
|
||||||
|
LOG_ERROR(LogObjectViewer, "Failed to open file {}!", FileName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto CurrentClass = Object->ClassPrivate; CurrentClass; CurrentClass = CurrentClass->GetSuperStruct())
|
||||||
|
{
|
||||||
|
void* Property = *(void**)(__int64(CurrentClass) + Offsets::Children);
|
||||||
|
|
||||||
|
while (Property)
|
||||||
|
{
|
||||||
|
std::string PropertyName = GetNamePrivateOfProperty(Property)->ToString();
|
||||||
|
int Offset = *(int*)(__int64(Property) + Offsets::Offset_Internal);
|
||||||
|
|
||||||
|
if (Offsets::PropertyClass)
|
||||||
|
{
|
||||||
|
if (IsPropertyA(Property, ObjectPropertyClass))
|
||||||
|
{
|
||||||
|
auto PropertyClass = *(UClass**)(__int64(Property) + Offsets::PropertyClass);
|
||||||
|
|
||||||
|
if (PropertyClass->IsValidLowLevel())
|
||||||
|
Stream << std::format("{} Object: {}\n", PropertyName, PropertyClass->GetPathName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
else if (IsPropertyA(Property, SoftObjectPropertyClass))
|
||||||
|
{
|
||||||
|
auto PropertyClass = *(UClass**)(__int64(Property) + Offsets::PropertyClass);
|
||||||
|
|
||||||
|
if (PropertyClass->IsValidLowLevel())
|
||||||
|
{
|
||||||
|
auto SoftObjectPtr = *(TSoftObjectPtr<UObject>*)(__int64(Object) + Offset);
|
||||||
|
auto SoftObjectPtrObject = SoftObjectPtr.Get(PropertyClass);
|
||||||
|
Stream << std::format("{} SoftObjectPtr (type: {}): {}\n", PropertyName, PropertyClass->GetName(), SoftObjectPtrObject ? SoftObjectPtrObject->GetPathName() : "BadRead");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsPropertyA(Property, BytePropertyClass))
|
||||||
|
{
|
||||||
|
Stream << std::format("{} Byte: {}\n", PropertyName, *(uint8*)(__int64(Object) + Offset));
|
||||||
|
}
|
||||||
|
else if (IsPropertyA(Property, DoublePropertyClass))
|
||||||
|
{
|
||||||
|
Stream << std::format("{} Double: {}\n", PropertyName, *(double*)(__int64(Object) + Offset));
|
||||||
|
}
|
||||||
|
else if (IsPropertyA(Property, UInt16PropertyClass))
|
||||||
|
{
|
||||||
|
Stream << std::format("{} UInt16: {}\n", PropertyName, *(uint16*)(__int64(Object) + Offset));
|
||||||
|
}
|
||||||
|
else if (IsPropertyA(Property, Int8PropertyClass))
|
||||||
|
{
|
||||||
|
Stream << std::format("{} Int8: {}\n", PropertyName, *(int8*)(__int64(Object) + Offset));
|
||||||
|
}
|
||||||
|
else if (IsPropertyA(Property, NamePropertyClass))
|
||||||
|
{
|
||||||
|
Stream << std::format("{} Name: {}\n", PropertyName, (*(FName*)(__int64(Object) + Offset)).ToString());
|
||||||
|
}
|
||||||
|
else if (IsPropertyA(Property, StrPropertyClass))
|
||||||
|
{
|
||||||
|
Stream << std::format("{} String: {}\n", PropertyName, (*(FString*)(__int64(Object) + Offset)).ToString());
|
||||||
|
}
|
||||||
|
else if (IsPropertyA(Property, FloatPropertyClass))
|
||||||
|
{
|
||||||
|
Stream << std::format("{} Float: {}\n", PropertyName, *(float*)(__int64(Object) + Offset));
|
||||||
|
}
|
||||||
|
else if (IsPropertyA(Property, BoolPropertyClass))
|
||||||
|
{
|
||||||
|
auto FieldMask = GetFieldMask(Property);
|
||||||
|
|
||||||
|
Stream << std::format("{} Bool: {}\n", PropertyName, ReadBitfield((PlaceholderBitfield*)(__int64(Object) + Offset), FieldMask));
|
||||||
|
}
|
||||||
|
else if (IsPropertyA(Property, IntPropertyClass))
|
||||||
|
{
|
||||||
|
Stream << std::format("{} Int32: {}\n", PropertyName, *(int*)(__int64(Object) + Offset));
|
||||||
|
}
|
||||||
|
else if (IsPropertyA(Property, UInt32PropertyClass))
|
||||||
|
{
|
||||||
|
Stream << std::format("{} UInt32: {}\n", PropertyName, *(uint32*)(__int64(Object) + Offset));
|
||||||
|
}
|
||||||
|
else if (IsPropertyA(Property, UInt64PropertyClass))
|
||||||
|
{
|
||||||
|
Stream << std::format("{} UInt64: {}\n", PropertyName, *(uint64*)(__int64(Object) + Offset));
|
||||||
|
}
|
||||||
|
else if (IsPropertyA(Property, Int64PropertyClass))
|
||||||
|
{
|
||||||
|
Stream << std::format("{} Int64: {}\n", PropertyName, *(int64*)(__int64(Object) + Offset));
|
||||||
|
}
|
||||||
|
else if (IsPropertyA(Property, ArrayPropertyClass))
|
||||||
|
{
|
||||||
|
Stream << std::format("{} Array\n", PropertyName);
|
||||||
|
}
|
||||||
|
else if (IsPropertyA(Property, EnumPropertyClass))
|
||||||
|
{
|
||||||
|
using UNumericProperty = UObject;
|
||||||
|
|
||||||
|
auto EnumValueIg = *(uint8*)(__int64(Property) + Offset);
|
||||||
|
auto UnderlyingType = *(UNumericProperty**)(__int64(Property) + Offsets::UnderlyingType);
|
||||||
|
// Stream << std::format("{} Enum: {}\n", PropertyName, (int)EnumValueIg);
|
||||||
|
Stream << std::format("{} Enum\n", PropertyName);
|
||||||
|
}
|
||||||
|
else if (IsPropertyA(Property, FunctionClass))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (!bExcludeUnhandled)
|
||||||
|
{
|
||||||
|
// Stream << std::format("{}: {}\n", PropertyName, "UNHANDLED");
|
||||||
|
Stream << std::format("{}: {} {}\n", PropertyName, "UNHANDLED", ""/*, ((UObject*)Property)->GetName()*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
Property = Engine_Version >= 425 ? *(void**)(__int64(Property) + 0x20) : ((UField*)Property)->Next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void DumpContentsToFile(const std::string& ObjectName, const std::string& FileName, bool bExcludeUnhandled = false) { return DumpContentsToFile(FindObject(ObjectName), FileName, bExcludeUnhandled); }
|
||||||
|
}
|
||||||
@@ -124,7 +124,7 @@ static inline void FillItemCollector(ABuildingItemCollectorActor* ItemCollector,
|
|||||||
|
|
||||||
constexpr bool bPrint = false;
|
constexpr bool bPrint = false;
|
||||||
|
|
||||||
std::vector<LootDrop> LootDrops = PickLootDrops(LootTierGroup, LootTier, bPrint);
|
std::vector<LootDrop> LootDrops = PickLootDrops(LootTierGroup, GameState->GetWorldLevel(), LootTier, bPrint);
|
||||||
|
|
||||||
if (LootDrops.size() == 0)
|
if (LootDrops.size() == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user