mirror of
https://github.com/Milxnor/Project-Reboot-3.0.git
synced 2026-01-13 02:42:22 +01:00
i broke the whole project but its fine
complete pickup rewrite, idle pawns
This commit is contained in:
@@ -54,10 +54,10 @@ public:
|
|||||||
this->ProcessEvent(fn, &UAbilitySystemComponent_ClientActivateAbilityFailed_Params);
|
this->ProcessEvent(fn, &UAbilitySystemComponent_ClientActivateAbilityFailed_Params);
|
||||||
}
|
}
|
||||||
|
|
||||||
TArray<UObject*>& GetSpawnedAttributes()
|
TArray<UAttributeSet*>& GetSpawnedAttributes()
|
||||||
{
|
{
|
||||||
static auto SpawnedAttributesOffset = GetOffset("SpawnedAttributes");
|
static auto SpawnedAttributesOffset = GetOffset("SpawnedAttributes");
|
||||||
return Get<TArray<UObject*>>(SpawnedAttributesOffset);
|
return Get<TArray<UAttributeSet*>>(SpawnedAttributesOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
FGameplayAbilitySpecContainer* GetActivatableAbilities()
|
FGameplayAbilitySpecContainer* GetActivatableAbilities()
|
||||||
|
|||||||
@@ -52,6 +52,37 @@ public:
|
|||||||
return DefaultCalculateSlackReserve(NumElements, NumBytesPerElement, false);
|
return DefaultCalculateSlackReserve(NumElements, NumBytesPerElement, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResizeArray(SizeType NewNum, SIZE_T NumBytesPerElement)
|
||||||
|
{
|
||||||
|
const SizeType CurrentMax = ArrayMax;
|
||||||
|
SizeType v3 = NewNum;
|
||||||
|
if (NewNum)
|
||||||
|
{
|
||||||
|
/* SizeType v6 = (unsigned __int64)FMemory::QuantizeSize(4 * NewNum, 0) >> 2;
|
||||||
|
// if (v3 > (int)v6)
|
||||||
|
// LODWORD(v6) = 0x7FFFFFFF;
|
||||||
|
v3 = v6; */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v3 != CurrentMax && (Data || v3))
|
||||||
|
Data = (InElementType*)FMemory::Realloc(Data, NumBytesPerElement * v3, 0);
|
||||||
|
|
||||||
|
ArrayNum = v3; // ?
|
||||||
|
ArrayMax = v3;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CopyFromArray(TArray<InElementType>& OtherArray, SIZE_T NumBytesPerElement = sizeof(InElementType))
|
||||||
|
{
|
||||||
|
if (!OtherArray.ArrayNum && !ArrayMax)
|
||||||
|
{
|
||||||
|
ArrayMax = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResizeArray(OtherArray.ArrayNum, NumBytesPerElement);
|
||||||
|
memcpy(this->Data, OtherArray.Data, NumBytesPerElement * OtherArray.ArrayNum);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
FORCENOINLINE void ResizeForCopy(SizeType NewMax, SizeType PrevMax, int ElementSize = sizeof(InElementType))
|
FORCENOINLINE void ResizeForCopy(SizeType NewMax, SizeType PrevMax, int ElementSize = sizeof(InElementType))
|
||||||
{
|
{
|
||||||
@@ -303,6 +334,7 @@ public:
|
|||||||
// VirtualFree(Data, 0, MEM_RELEASE);
|
// VirtualFree(Data, 0, MEM_RELEASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Data = nullptr;
|
||||||
ArrayNum = 0;
|
ArrayNum = 0;
|
||||||
ArrayMax = 0;
|
ArrayMax = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,26 @@ public:
|
|||||||
struct FGameplayAttribute
|
struct FGameplayAttribute
|
||||||
{
|
{
|
||||||
FString AttributeName;
|
FString AttributeName;
|
||||||
void* Attribute;
|
void* Attribute; // Property
|
||||||
UStruct* AttributeOwner;
|
UStruct* AttributeOwner;
|
||||||
|
|
||||||
|
std::string GetAttributeName()
|
||||||
|
{
|
||||||
|
return AttributeName.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetAttributePropertyName()
|
||||||
|
{
|
||||||
|
if (!Attribute)
|
||||||
|
return "INVALIDATTRIBUTE";
|
||||||
|
|
||||||
|
FName* NamePrivate = nullptr;
|
||||||
|
|
||||||
|
if (Engine_Version >= 425)
|
||||||
|
NamePrivate = (FName*)(__int64(Attribute) + 0x28);
|
||||||
|
else
|
||||||
|
NamePrivate = &((UField*)Attribute)->NamePrivate;
|
||||||
|
|
||||||
|
return NamePrivate->ToString();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
@@ -5,8 +5,9 @@
|
|||||||
#include "FortLootPackage.h"
|
#include "FortLootPackage.h"
|
||||||
#include "FortPickup.h"
|
#include "FortPickup.h"
|
||||||
#include "BuildingGameplayActor.h"
|
#include "BuildingGameplayActor.h"
|
||||||
|
#include "KismetSystemLibrary.h"
|
||||||
|
|
||||||
void SpawnBGAs() // hahah not "proper", there's a function that we can hook and it gets called on each spawner whenever playlist gets set, but it's fine.
|
static inline void SpawnBGAs() // hahah not "proper", there's a function that we can hook and it gets called on each spawner whenever playlist gets set, but it's fine.
|
||||||
{
|
{
|
||||||
static auto BGAConsumableSpawnerClass = FindObject<UClass>("/Script/FortniteGame.BGAConsumableSpawner");
|
static auto BGAConsumableSpawnerClass = FindObject<UClass>("/Script/FortniteGame.BGAConsumableSpawner");
|
||||||
|
|
||||||
@@ -24,6 +25,9 @@ void SpawnBGAs() // hahah not "proper", there's a function that we can hook and
|
|||||||
auto BGAConsumableSpawner = AllBGAConsumableSpawners.at(i);
|
auto BGAConsumableSpawner = AllBGAConsumableSpawners.at(i);
|
||||||
auto SpawnLocation = BGAConsumableSpawner->GetActorLocation();
|
auto SpawnLocation = BGAConsumableSpawner->GetActorLocation();
|
||||||
|
|
||||||
|
static auto bAlignSpawnedActorsToSurfaceOffset = BGAConsumableSpawner->GetOffset("bAlignSpawnedActorsToSurface");
|
||||||
|
const bool bAlignSpawnedActorsToSurface = BGAConsumableSpawner->Get<bool>(bAlignSpawnedActorsToSurfaceOffset);
|
||||||
|
|
||||||
FTransform SpawnTransform{};
|
FTransform SpawnTransform{};
|
||||||
SpawnTransform.Translation = SpawnLocation;
|
SpawnTransform.Translation = SpawnLocation;
|
||||||
SpawnTransform.Scale3D = FVector{ 1, 1, 1 };
|
SpawnTransform.Scale3D = FVector{ 1, 1, 1 };
|
||||||
@@ -55,20 +59,63 @@ void SpawnBGAs() // hahah not "proper", there's a function that we can hook and
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bDeferConstruction = false; // hm?
|
bool bDeferConstruction = true; // hm?
|
||||||
|
|
||||||
FActorSpawnParameters SpawnParameters{};
|
FActorSpawnParameters SpawnParameters{};
|
||||||
// SpawnParameters.ObjectFlags = RF_Transactional; // idk fortnite does this i think
|
// SpawnParameters.ObjectFlags = RF_Transactional; // idk fortnite does this i think // i think its acutally suppsoed to be |= RF_Transient
|
||||||
SpawnParameters.bDeferConstruction = bDeferConstruction;
|
SpawnParameters.bDeferConstruction = bDeferConstruction;
|
||||||
|
|
||||||
auto ConsumableActor = GetWorld()->SpawnActor<ABuildingGameplayActor>(StrongConsumableClass, SpawnTransform, SpawnParameters);
|
auto ConsumableActor = GetWorld()->SpawnActor<ABuildingGameplayActor>(StrongConsumableClass, SpawnTransform, SpawnParameters);
|
||||||
|
|
||||||
if (ConsumableActor)
|
if (ConsumableActor)
|
||||||
{
|
{
|
||||||
if (bDeferConstruction)
|
FTransform FinalSpawnTransform = SpawnTransform;
|
||||||
UGameplayStatics::FinishSpawningActor(ConsumableActor, SpawnTransform); // what
|
|
||||||
|
|
||||||
ConsumableActor->InitializeBuildingActor(nullptr, nullptr, true); // idk UFortKismetLibrary::SpawnBuildingGameplayActor does this
|
if (bAlignSpawnedActorsToSurface)
|
||||||
|
{
|
||||||
|
// I DONT KNOW
|
||||||
|
|
||||||
|
/* FHitResult* NewHit = Alloc<FHitResult>(FHitResult::GetStructSize());
|
||||||
|
|
||||||
|
FVector StartLocation = FinalSpawnTransform.Translation;
|
||||||
|
FVector EndLocation = StartLocation - FVector(0, 0, 1000);
|
||||||
|
|
||||||
|
bool bTraceComplex = true; // idk
|
||||||
|
FName ProfileName = UKismetStringLibrary::Conv_StringToName(L"FindGroundLocationAt");
|
||||||
|
|
||||||
|
UKismetSystemLibrary::LineTraceSingleByProfile(ConsumableActor, StartLocation, EndLocation, ProfileName, bTraceComplex,
|
||||||
|
TArray<AActor*>(), EDrawDebugTrace::None, &NewHit, true, FLinearColor(), FLinearColor(), 0);
|
||||||
|
|
||||||
|
// UKismetSystemLibrary::LineTraceSingle(ConsumableActor, StartLocation, EndLocation,
|
||||||
|
// ETraceTypeQuery::TraceTypeQuery1, bTraceComplex, TArray<AActor*>(), EDrawDebugTrace::None, true, FLinearColor(), FLinearColor(), 0, &NewHit);
|
||||||
|
|
||||||
|
bool IsBlockingHit = NewHit && NewHit->IsBlockingHit(); // Should we check ret of linetracesingle?
|
||||||
|
|
||||||
|
if (IsBlockingHit)
|
||||||
|
{
|
||||||
|
FinalSpawnTransform.Translation = NewHit->GetLocation();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FinalSpawnTransform.Translation = FVector(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FinalSpawnTransform.Translation == FVector(0, 0, 0))
|
||||||
|
{
|
||||||
|
LOG_WARN(LogGame, "Invalid BGA spawn location!");
|
||||||
|
// ConsumableActor->K2_DestroyActor(); // ??
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bDeferConstruction)
|
||||||
|
UGameplayStatics::FinishSpawningActor(ConsumableActor, FinalSpawnTransform);
|
||||||
|
|
||||||
|
// ConsumableActor->InitializeBuildingActor(nullptr, nullptr, true); // idk UFortKismetLibrary::SpawnBuildingGameplayActor does this
|
||||||
|
|
||||||
|
LOG_INFO(LogDev, "Spawned BGA {} at {} {} {}", ConsumableActor->GetName(), FinalSpawnTransform.Translation.X, FinalSpawnTransform.Translation.Y, FinalSpawnTransform.Translation.Z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,11 @@
|
|||||||
|
|
||||||
bool ABuildingContainer::SpawnLoot(AFortPawn* Pawn)
|
bool ABuildingContainer::SpawnLoot(AFortPawn* Pawn)
|
||||||
{
|
{
|
||||||
|
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
|
||||||
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");
|
||||||
auto RedirectedLootTier = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode())->RedirectLootTier(this->Get<FName>(SearchLootTierGroupOffset));
|
auto RedirectedLootTier = GameMode->RedirectLootTier(this->Get<FName>(SearchLootTierGroupOffset));
|
||||||
|
|
||||||
// LOG_INFO(LogInteraction, "RedirectedLootTier: {}", RedirectedLootTier.ToString());
|
// LOG_INFO(LogInteraction, "RedirectedLootTier: {}", RedirectedLootTier.ToString());
|
||||||
|
|
||||||
@@ -20,7 +21,17 @@ bool ABuildingContainer::SpawnLoot(AFortPawn* Pawn)
|
|||||||
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);
|
||||||
AFortPickup::SpawnPickup(lootDrop->GetItemDefinition(), LocationToSpawnLoot, lootDrop->GetCount(), EFortPickupSourceTypeFlag::Container, EFortPickupSpawnSource::Unset, lootDrop->GetLoadedAmmo());
|
|
||||||
|
PickupCreateData CreateData{};
|
||||||
|
CreateData.bToss = true;
|
||||||
|
// CreateData.PawnOwner = Pawn;
|
||||||
|
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(lootDrop->GetItemDefinition(), lootDrop->GetCount(), lootDrop->GetLoadedAmmo());
|
||||||
|
CreateData.SpawnLocation = LocationToSpawnLoot;
|
||||||
|
CreateData.SourceType = EFortPickupSourceTypeFlag::GetContainerValue();
|
||||||
|
CreateData.bRandomRotation = true;
|
||||||
|
CreateData.bShouldFreeItemEntryWhenDeconstructed = true;
|
||||||
|
|
||||||
|
auto NewPickup = AFortPickup::SpawnPickup(CreateData);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
|
|
||||||
#include "addresses.h"
|
#include "addresses.h"
|
||||||
|
#include "UnrealString.h"
|
||||||
|
#include "Map.h"
|
||||||
|
|
||||||
struct UField : UObject
|
struct UField : UObject
|
||||||
{
|
{
|
||||||
@@ -28,3 +30,24 @@ class UFunction : public UStruct
|
|||||||
public:
|
public:
|
||||||
void*& GetFunc() { return *(void**)(__int64(this) + Offsets::Func); }
|
void*& GetFunc() { return *(void**)(__int64(this) + Offsets::Func); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class UEnum : public UField
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int64 GetValue(const std::string& EnumMemberName)
|
||||||
|
{
|
||||||
|
auto Names = (TArray<TPair<FName, __int64>>*)(__int64(this) + sizeof(UField) + sizeof(FString));
|
||||||
|
|
||||||
|
for (int i = 0; i < Names->Num(); i++)
|
||||||
|
{
|
||||||
|
auto& Pair = Names->At(i);
|
||||||
|
auto& Name = Pair.Key();
|
||||||
|
auto Value = Pair.Value();
|
||||||
|
|
||||||
|
if (Name.ComparisonIndex.Value && Name.ToString().contains(EnumMemberName))
|
||||||
|
return Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -12,3 +12,22 @@ int FHitResult::GetStructSize()
|
|||||||
{
|
{
|
||||||
return GetStruct()->GetPropertiesSize();
|
return GetStruct()->GetPropertiesSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FHitResult::IsBlockingHit()
|
||||||
|
{
|
||||||
|
// return true;
|
||||||
|
static auto bBlockingHitOffset = FindOffsetStruct("/Script/Engine.HitResult", "bBlockingHit");
|
||||||
|
static auto bBlockingHitFieldMask = GetFieldMask(FindPropertyStruct("/Script/Engine.HitResult", "bBlockingHit"));
|
||||||
|
return ReadBitfield((PlaceholderBitfield*)(__int64(this) + bBlockingHitOffset), bBlockingHitFieldMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
FVector& FHitResult::GetLocation()
|
||||||
|
{
|
||||||
|
static auto LocationOffset = FindOffsetStruct("/Script/Engine.HitResult", "Location");
|
||||||
|
return *(FVector*)(__int64(this) + LocationOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FHitResult::CopyFromHitResult(FHitResult* Other)
|
||||||
|
{
|
||||||
|
this->GetLocation() = Other->GetLocation();
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
|
#include "Vector.h"
|
||||||
|
|
||||||
#include "DelegateCombinations.h"
|
#include "DelegateCombinations.h"
|
||||||
|
|
||||||
@@ -17,6 +18,10 @@ struct FHitResult
|
|||||||
{
|
{
|
||||||
static class UStruct* GetStruct();
|
static class UStruct* GetStruct();
|
||||||
static int GetStructSize();
|
static int GetStructSize();
|
||||||
|
|
||||||
|
bool IsBlockingHit();
|
||||||
|
FVector& GetLocation();
|
||||||
|
void CopyFromHitResult(FHitResult* Other);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FTimerHandle
|
struct FTimerHandle
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ public:
|
|||||||
if (!AbilityClass)
|
if (!AbilityClass)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
LOG_INFO(LogDev, "Giving AbilityClass {}", AbilityClass->GetFullName());
|
// LOG_INFO(LogDev, "Giving AbilityClass {}", AbilityClass->GetFullName());
|
||||||
|
|
||||||
AbilitySystemComponent->GiveAbilityEasy(AbilityClass, SourceObject);
|
AbilitySystemComponent->GiveAbilityEasy(AbilityClass, SourceObject);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,14 @@ AFortPickup* AFortAthenaSupplyDrop::SpawnGameModePickupHook(UObject* Context, FF
|
|||||||
|
|
||||||
LOG_INFO(LogDev, "Spawning GameModePickup with ItemDefinition: {}", ItemDefinition->GetFullName());
|
LOG_INFO(LogDev, "Spawning GameModePickup with ItemDefinition: {}", ItemDefinition->GetFullName());
|
||||||
|
|
||||||
*Ret = AFortPickup::SpawnPickup(ItemDefinition, Position, NumberToSpawn, EFortPickupSourceTypeFlag::Other, EFortPickupSpawnSource::SupplyDrop, -1, TriggeringPawn, PickupClass);
|
PickupCreateData CreateData;
|
||||||
|
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(ItemDefinition, NumberToSpawn, -1);
|
||||||
|
CreateData.SpawnLocation = Position;
|
||||||
|
CreateData.PawnOwner = TriggeringPawn;
|
||||||
|
CreateData.Source = EFortPickupSpawnSource::GetSupplyDropValue();
|
||||||
|
CreateData.OverrideClass = PickupClass;
|
||||||
|
|
||||||
|
*Ret = AFortPickup::SpawnPickup(CreateData);
|
||||||
return *Ret;
|
return *Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +74,13 @@ AFortPickup* AFortAthenaSupplyDrop::SpawnPickupHook(UObject* Context, FFrame& St
|
|||||||
if (!ItemDefinition)
|
if (!ItemDefinition)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
*Ret = AFortPickup::SpawnPickup(ItemDefinition, Position, NumberToSpawn, EFortPickupSourceTypeFlag::Other, EFortPickupSpawnSource::SupplyDrop, -1, TriggeringPawn);
|
PickupCreateData CreateData;
|
||||||
|
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(ItemDefinition, NumberToSpawn, -1);
|
||||||
|
CreateData.SpawnLocation = Position;
|
||||||
|
CreateData.PawnOwner = TriggeringPawn;
|
||||||
|
CreateData.Source = EFortPickupSpawnSource::GetSupplyDropValue();
|
||||||
|
|
||||||
|
*Ret = AFortPickup::SpawnPickup(CreateData);
|
||||||
return *Ret;
|
return *Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,12 @@ public:
|
|||||||
return ReadBitfieldValue(bDestroyGadgetWhenTrackedAttributesIsZeroOffset, bDestroyGadgetWhenTrackedAttributesIsZeroFieldMask);
|
return ReadBitfieldValue(bDestroyGadgetWhenTrackedAttributesIsZeroOffset, bDestroyGadgetWhenTrackedAttributesIsZeroFieldMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TArray<FGameplayAttribute>& GetTrackedAttributes()
|
||||||
|
{
|
||||||
|
static auto TrackedAttributesOffset = GetOffset("TrackedAttributes");
|
||||||
|
return Get<TArray<FGameplayAttribute>>(TrackedAttributesOffset);
|
||||||
|
}
|
||||||
|
|
||||||
UAttributeSet* GetAttributeSet()
|
UAttributeSet* GetAttributeSet()
|
||||||
{
|
{
|
||||||
static auto AttributeSetOffset = this->GetOffset("AttributeSet", false);
|
static auto AttributeSetOffset = this->GetOffset("AttributeSet", false);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "FortLootPackage.h"
|
#include "FortLootPackage.h"
|
||||||
#include "FortPlayerPawn.h"
|
#include "FortPlayerPawn.h"
|
||||||
#include "FortPickup.h"
|
#include "FortPickup.h"
|
||||||
|
#include "bots.h"
|
||||||
|
|
||||||
#include "FortAbilitySet.h"
|
#include "FortAbilitySet.h"
|
||||||
#include "NetSerialization.h"
|
#include "NetSerialization.h"
|
||||||
@@ -553,6 +554,11 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
|
|||||||
|
|
||||||
GetWorld()->Listen();
|
GetWorld()->Listen();
|
||||||
|
|
||||||
|
if (AmountOfBotsToSpawn != 0)
|
||||||
|
{
|
||||||
|
Bots::SpawnBotsAtPlayerStarts(AmountOfBotsToSpawn);
|
||||||
|
}
|
||||||
|
|
||||||
// GameState->OnRep_CurrentPlaylistInfo();
|
// GameState->OnRep_CurrentPlaylistInfo();
|
||||||
|
|
||||||
// return false;
|
// return false;
|
||||||
@@ -698,6 +704,15 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
|
|||||||
|
|
||||||
int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint8 preferredTeam, AActor* Controller)
|
int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint8 preferredTeam, AActor* Controller)
|
||||||
{
|
{
|
||||||
|
bool bIsBot = false;
|
||||||
|
|
||||||
|
auto PlayerState = ((APlayerController*)Controller)->GetPlayerState();
|
||||||
|
|
||||||
|
if (PlayerState)
|
||||||
|
{
|
||||||
|
bIsBot = PlayerState->IsBot();
|
||||||
|
}
|
||||||
|
|
||||||
// VERY BASIC IMPLEMENTATION
|
// VERY BASIC IMPLEMENTATION
|
||||||
|
|
||||||
LOG_INFO(LogTeams, "PickTeam called!");
|
LOG_INFO(LogTeams, "PickTeam called!");
|
||||||
@@ -939,7 +954,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
|||||||
|
|
||||||
float UpZ = 50;
|
float UpZ = 50;
|
||||||
|
|
||||||
EFortPickupSourceTypeFlag SpawnFlag = EFortPickupSourceTypeFlag::Container;
|
uint8 SpawnFlag = EFortPickupSourceTypeFlag::GetContainerValue();
|
||||||
|
|
||||||
bool bTest = false;
|
bool bTest = false;
|
||||||
bool bPrintWarmup = false;
|
bool bPrintWarmup = false;
|
||||||
@@ -947,25 +962,22 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
|||||||
for (int i = 0; i < SpawnIsland_FloorLoot_Actors.Num(); i++)
|
for (int i = 0; i < SpawnIsland_FloorLoot_Actors.Num(); i++)
|
||||||
{
|
{
|
||||||
ABuildingContainer* CurrentActor = (ABuildingContainer*)SpawnIsland_FloorLoot_Actors.at(i);
|
ABuildingContainer* CurrentActor = (ABuildingContainer*)SpawnIsland_FloorLoot_Actors.at(i);
|
||||||
|
auto Location = CurrentActor->GetActorLocation();
|
||||||
|
Location.Z += UpZ;
|
||||||
|
|
||||||
|
std::vector<LootDrop> LootDrops = PickLootDrops(SpawnIslandTierGroup, bPrintWarmup);
|
||||||
|
|
||||||
|
for (auto& LootDrop : LootDrops)
|
||||||
{
|
{
|
||||||
auto Location = CurrentActor->GetActorLocation();
|
PickupCreateData CreateData;
|
||||||
Location.Z += UpZ;
|
CreateData.bToss = true;
|
||||||
|
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(LootDrop->GetItemDefinition(), LootDrop->GetCount(), LootDrop->GetLoadedAmmo());
|
||||||
|
CreateData.SpawnLocation = Location;
|
||||||
|
CreateData.SourceType = SpawnFlag;
|
||||||
|
CreateData.bRandomRotation = true;
|
||||||
|
CreateData.bShouldFreeItemEntryWhenDeconstructed = true;
|
||||||
|
|
||||||
std::vector<LootDrop> LootDrops = PickLootDrops(SpawnIslandTierGroup, bPrintWarmup);
|
auto Pickup = AFortPickup::SpawnPickup(CreateData);
|
||||||
|
|
||||||
if (bPrintWarmup)
|
|
||||||
{
|
|
||||||
std::cout << "\n\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LootDrops.size())
|
|
||||||
{
|
|
||||||
for (auto& LootDrop : LootDrops)
|
|
||||||
{
|
|
||||||
auto Pickup = AFortPickup::SpawnPickup(LootDrop->GetItemDefinition(), Location, LootDrop->GetCount(), SpawnFlag, EFortPickupSpawnSource::Unset, LootDrop->GetLoadedAmmo());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bTest)
|
if (!bTest)
|
||||||
@@ -979,33 +991,31 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
|||||||
for (int i = 0; i < BRIsland_FloorLoot_Actors.Num(); i++)
|
for (int i = 0; i < BRIsland_FloorLoot_Actors.Num(); i++)
|
||||||
{
|
{
|
||||||
ABuildingContainer* CurrentActor = (ABuildingContainer*)BRIsland_FloorLoot_Actors.at(i);
|
ABuildingContainer* CurrentActor = (ABuildingContainer*)BRIsland_FloorLoot_Actors.at(i);
|
||||||
|
|
||||||
// CurrentActor->K2_DestroyActor();
|
|
||||||
spawned++;
|
spawned++;
|
||||||
// continue;
|
|
||||||
|
|
||||||
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, bPrint);
|
||||||
|
|
||||||
if (bPrint)
|
for (auto& LootDrop : LootDrops)
|
||||||
std::cout << "\n";
|
|
||||||
|
|
||||||
if (LootDrops.size())
|
|
||||||
{
|
{
|
||||||
for (auto& LootDrop : LootDrops)
|
PickupCreateData CreateData;
|
||||||
{
|
CreateData.bToss = true;
|
||||||
auto Pickup = AFortPickup::SpawnPickup(LootDrop->GetItemDefinition(), Location, LootDrop->GetCount(), SpawnFlag, EFortPickupSpawnSource::Unset, LootDrop->GetLoadedAmmo());
|
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(LootDrop->GetItemDefinition(), LootDrop->GetCount(), LootDrop->GetLoadedAmmo());
|
||||||
}
|
CreateData.SpawnLocation = Location;
|
||||||
|
CreateData.SourceType = SpawnFlag;
|
||||||
|
CreateData.bRandomRotation = true;
|
||||||
|
CreateData.bShouldFreeItemEntryWhenDeconstructed = true;
|
||||||
|
|
||||||
|
auto Pickup = AFortPickup::SpawnPickup(CreateData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bTest)
|
if (!bTest)
|
||||||
CurrentActor->K2_DestroyActor();
|
CurrentActor->K2_DestroyActor();
|
||||||
}
|
}
|
||||||
|
|
||||||
// SpawnIsland_FloorLoot_Actors.Free();
|
SpawnIsland_FloorLoot_Actors.Free();
|
||||||
// BRIsland_FloorLoot_Actors.Free();
|
BRIsland_FloorLoot_Actors.Free();
|
||||||
|
|
||||||
LOG_INFO(LogDev, "Spawned loot!");
|
LOG_INFO(LogDev, "Spawned loot!");
|
||||||
}
|
}
|
||||||
@@ -1058,7 +1068,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
|||||||
static auto SquadIdOffset = PlayerStateAthena->GetOffset("SquadId", false);
|
static auto SquadIdOffset = PlayerStateAthena->GetOffset("SquadId", false);
|
||||||
|
|
||||||
if (SquadIdOffset != -1)
|
if (SquadIdOffset != -1)
|
||||||
PlayerStateAthena->GetSquadId() = PlayerStateAthena->GetTeamIndex() - 2;
|
PlayerStateAthena->GetSquadId() = PlayerStateAthena->GetTeamIndex() - 2; // wrong place to do this
|
||||||
|
|
||||||
// idk if this is needed
|
// idk if this is needed
|
||||||
|
|
||||||
@@ -1075,9 +1085,6 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
|||||||
static auto OnRep_bHasStartedPlayingFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerState.OnRep_bHasStartedPlaying");
|
static auto OnRep_bHasStartedPlayingFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerState.OnRep_bHasStartedPlaying");
|
||||||
PlayerStateAthena->ProcessEvent(OnRep_bHasStartedPlayingFn);
|
PlayerStateAthena->ProcessEvent(OnRep_bHasStartedPlayingFn);
|
||||||
|
|
||||||
LOG_INFO(LogDev, "Old ID: {}", PlayerStateAthena->GetWorldPlayerId());
|
|
||||||
LOG_INFO(LogDev, "PlayerID: {}", PlayerStateAthena->GetPlayerID());
|
|
||||||
|
|
||||||
PlayerStateAthena->GetWorldPlayerId() = PlayerStateAthena->GetPlayerID();
|
PlayerStateAthena->GetWorldPlayerId() = PlayerStateAthena->GetPlayerID();
|
||||||
|
|
||||||
auto PlayerAbilitySet = GetPlayerAbilitySet();
|
auto PlayerAbilitySet = GetPlayerAbilitySet();
|
||||||
@@ -1088,9 +1095,15 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
|||||||
PlayerAbilitySet->GiveToAbilitySystem(AbilitySystemComponent);
|
PlayerAbilitySet->GiveToAbilitySystem(AbilitySystemComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FUniqueNetIdReplExperimental
|
struct FUniqueNetIdWrapper
|
||||||
{
|
{
|
||||||
unsigned char ahh[0x0028];
|
unsigned char UnknownData00[0x1]; // 0x0000(0x0001) MISSED OFFSET
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FUniqueNetIdReplExperimental : public FUniqueNetIdWrapper
|
||||||
|
{
|
||||||
|
unsigned char UnknownData00[0x17]; // 0x0001(0x0017) MISSED OFFSET
|
||||||
|
TArray<unsigned char> ReplicationBytes; // 0x0018(0x0010) (ZeroConstructor, Transient, Protected, NativeAccessSpecifierProtected)
|
||||||
};
|
};
|
||||||
|
|
||||||
static auto PlayerCameraManagerOffset = NewPlayer->GetOffset("PlayerCameraManager");
|
static auto PlayerCameraManagerOffset = NewPlayer->GetOffset("PlayerCameraManager");
|
||||||
@@ -1105,12 +1118,10 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
|||||||
PlayerCameraManager->Get<float>(ViewRollMaxOffset) = 0;
|
PlayerCameraManager->Get<float>(ViewRollMaxOffset) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FUniqueNetIdReplExperimental Bugha{}; */
|
|
||||||
static auto UniqueIdOffset = PlayerStateAthena->GetOffset("UniqueId");
|
static auto UniqueIdOffset = PlayerStateAthena->GetOffset("UniqueId");
|
||||||
auto PlayerStateUniqueId = PlayerStateAthena->GetPtr<FUniqueNetIdRepl>(UniqueIdOffset);
|
auto PlayerStateUniqueId = PlayerStateAthena->GetPtr<FUniqueNetIdRepl>(UniqueIdOffset);
|
||||||
|
|
||||||
{
|
{
|
||||||
LOG_INFO(LogDev, "bruh");
|
|
||||||
static auto GameMemberInfoArrayOffset = GameState->GetOffset("GameMemberInfoArray", false);
|
static auto GameMemberInfoArrayOffset = GameState->GetOffset("GameMemberInfoArray", false);
|
||||||
|
|
||||||
// if (false)
|
// if (false)
|
||||||
@@ -1150,7 +1161,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
|||||||
((FGameMemberInfo*)GameMemberInfo)->SquadId = PlayerStateAthena->GetSquadId();
|
((FGameMemberInfo*)GameMemberInfo)->SquadId = PlayerStateAthena->GetSquadId();
|
||||||
((FGameMemberInfo*)GameMemberInfo)->TeamIndex = PlayerStateAthena->GetTeamIndex();
|
((FGameMemberInfo*)GameMemberInfo)->TeamIndex = PlayerStateAthena->GetTeamIndex();
|
||||||
// GameMemberInfo->MemberUniqueId = PlayerStateUniqueId;
|
// GameMemberInfo->MemberUniqueId = PlayerStateUniqueId;
|
||||||
CopyStruct(&((FGameMemberInfo*)GameMemberInfo)->MemberUniqueId, PlayerStateUniqueId, FUniqueNetIdRepl::GetSizeOfStruct());
|
((FUniqueNetIdRepl*)&((FGameMemberInfo*)GameMemberInfo)->MemberUniqueId)->CopyFromAnotherUniqueId(PlayerStateUniqueId);
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto GameMemberInfoArray_MembersOffset = FindOffsetStruct("/Script/FortniteGame.GameMemberInfoArray", "Members");
|
static auto GameMemberInfoArray_MembersOffset = FindOffsetStruct("/Script/FortniteGame.GameMemberInfoArray", "Members");
|
||||||
@@ -1260,7 +1271,8 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
|||||||
if (LevelSaveComponent)
|
if (LevelSaveComponent)
|
||||||
{
|
{
|
||||||
static auto AccountIdOfOwnerOffset = LevelSaveComponent->GetOffset("AccountIdOfOwner");
|
static auto AccountIdOfOwnerOffset = LevelSaveComponent->GetOffset("AccountIdOfOwner");
|
||||||
CopyStruct(LevelSaveComponent->GetPtr<FUniqueNetIdReplExperimental>(AccountIdOfOwnerOffset), PlayerStateUniqueId, FUniqueNetIdRepl::GetSizeOfStruct());
|
LevelSaveComponent->GetPtr<FUniqueNetIdRepl>(AccountIdOfOwnerOffset)->CopyFromAnotherUniqueId(PlayerStateUniqueId);
|
||||||
|
// CopyStruct(LevelSaveComponent->GetPtr<FUniqueNetIdReplExperimental>(AccountIdOfOwnerOffset), PlayerStateUniqueId, FUniqueNetIdRepl::GetSizeOfStruct());
|
||||||
// LevelSaveComponent->Get<FUniqueNetIdReplExperimental>(AccountIdOfOwnerOffset) = PlayerStateUniqueId;
|
// LevelSaveComponent->Get<FUniqueNetIdReplExperimental>(AccountIdOfOwnerOffset) = PlayerStateUniqueId;
|
||||||
|
|
||||||
static auto bIsLoadedOffset = LevelSaveComponent->GetOffset("bIsLoaded");
|
static auto bIsLoadedOffset = LevelSaveComponent->GetOffset("bIsLoaded");
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "FortSafeZoneIndicator.h"
|
#include "FortSafeZoneIndicator.h"
|
||||||
#include "GameplayStatics.h"
|
#include "GameplayStatics.h"
|
||||||
#include "FortAbilitySet.h"
|
#include "FortAbilitySet.h"
|
||||||
|
#include "FortPlayerControllerAthena.h"
|
||||||
#include "FortItemDefinition.h"
|
#include "FortItemDefinition.h"
|
||||||
|
|
||||||
struct FAircraftFlightInfo
|
struct FAircraftFlightInfo
|
||||||
@@ -233,6 +234,12 @@ public:
|
|||||||
return Get<TArray<FItemAndCount>>(StartingItemsOffset);
|
return Get<TArray<FItemAndCount>>(StartingItemsOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TArray<AFortPlayerControllerAthena*>& GetAlivePlayers()
|
||||||
|
{
|
||||||
|
static auto AlivePlayersOffset = GetOffset("AlivePlayers");
|
||||||
|
return Get<TArray<AFortPlayerControllerAthena*>>(AlivePlayersOffset);
|
||||||
|
}
|
||||||
|
|
||||||
FName RedirectLootTier(const FName& LootTier);
|
FName RedirectLootTier(const FName& LootTier);
|
||||||
UClass* GetVehicleClassOverride(UClass* DefaultClass);
|
UClass* GetVehicleClassOverride(UClass* DefaultClass);
|
||||||
|
|
||||||
|
|||||||
@@ -244,3 +244,13 @@ void AFortGameStateAthena::OnRep_CurrentPlaylistInfo()
|
|||||||
this->ProcessEvent(OnRep_CurrentPlaylistInfo);
|
this->ProcessEvent(OnRep_CurrentPlaylistInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AFortGameStateAthena::OnRep_PlayersLeft()
|
||||||
|
{
|
||||||
|
static auto OnRep_PlayersLeftFn = FindObject<UFunction>("/Script/FortniteGame.FortGameStateAthena.OnRep_PlayersLeft");
|
||||||
|
|
||||||
|
if (!OnRep_PlayersLeftFn)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this->ProcessEvent(OnRep_PlayersLeftFn);
|
||||||
|
}
|
||||||
@@ -104,6 +104,7 @@ public:
|
|||||||
bool IsPlayerBuildableClass(UClass* Class);
|
bool IsPlayerBuildableClass(UClass* Class);
|
||||||
void OnRep_GamePhase();
|
void OnRep_GamePhase();
|
||||||
void OnRep_CurrentPlaylistInfo();
|
void OnRep_CurrentPlaylistInfo();
|
||||||
|
void OnRep_PlayersLeft();
|
||||||
};
|
};
|
||||||
|
|
||||||
static void* ConstructOnGamePhaseStepChangedParams(EAthenaGamePhaseStep GamePhaseStep)
|
static void* ConstructOnGamePhaseStepChangedParams(EAthenaGamePhaseStep GamePhaseStep)
|
||||||
|
|||||||
@@ -110,7 +110,13 @@ std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AFortInventory::AddI
|
|||||||
if (!Pawn)
|
if (!Pawn)
|
||||||
return std::make_pair(NewItemInstances, ModifiedItemInstances);
|
return std::make_pair(NewItemInstances, ModifiedItemInstances);
|
||||||
|
|
||||||
AFortPickup::SpawnPickup(ItemDefinition, Pawn->GetActorLocation(), Count, EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset, -1, Cast<AFortPawn>(Pawn));
|
PickupCreateData CreateData;
|
||||||
|
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(ItemDefinition, Count, -1);
|
||||||
|
CreateData.SpawnLocation = Pawn->GetActorLocation();
|
||||||
|
CreateData.PawnOwner = Cast<AFortPawn>(Pawn);
|
||||||
|
CreateData.SourceType = EFortPickupSourceTypeFlag::GetPlayerValue();
|
||||||
|
|
||||||
|
AFortPickup::SpawnPickup(CreateData);
|
||||||
return std::make_pair(NewItemInstances, ModifiedItemInstances);
|
return std::make_pair(NewItemInstances, ModifiedItemInstances);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,21 +132,21 @@ std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AFortInventory::AddI
|
|||||||
|
|
||||||
NewItemInstances.push_back(NewItemInstance);
|
NewItemInstances.push_back(NewItemInstance);
|
||||||
|
|
||||||
static auto FortItemEntryStruct = FindObject(L"/Script/FortniteGame.FortItemEntry");
|
|
||||||
static auto FortItemEntrySize = *(int*)(__int64(FortItemEntryStruct) + Offsets::PropertiesSize);
|
|
||||||
|
|
||||||
bool bEnableStateValues = false; // Addresses::FreeEntry;
|
bool bEnableStateValues = false; // Addresses::FreeEntry;
|
||||||
|
|
||||||
if (bEnableStateValues)
|
if (bEnableStateValues)
|
||||||
{
|
{
|
||||||
FFortItemEntryStateValue* StateValue = Alloc<FFortItemEntryStateValue>(FFortItemEntryStateValue::GetStructSize(), true);
|
// FFortItemEntryStateValue* StateValue = Alloc<FFortItemEntryStateValue>(FFortItemEntryStateValue::GetStructSize(), true);
|
||||||
StateValue->GetIntValue() = bShowItemToast;
|
PadHexA8 StateValue{};
|
||||||
StateValue->GetStateType() = EFortItemEntryState::ShouldShowItemToast;
|
((FFortItemEntryStateValue*)&StateValue)->GetIntValue() = bShowItemToast;
|
||||||
NewItemInstance->GetItemEntry()->GetStateValues().AddPtr(StateValue, FFortItemEntryStateValue::GetStructSize());
|
((FFortItemEntryStateValue*)&StateValue)->GetStateType() = EFortItemEntryState::ShouldShowItemToast;
|
||||||
|
((FFortItemEntryStateValue*)&StateValue)->GetNameValue() = FName(0);
|
||||||
|
|
||||||
|
NewItemInstance->GetItemEntry()->GetStateValues().AddPtr((FFortItemEntryStateValue*)&StateValue, FFortItemEntryStateValue::GetStructSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemInstances.Add(NewItemInstance);
|
ItemInstances.Add(NewItemInstance);
|
||||||
auto ReplicatedEntryIdx = GetItemList().GetReplicatedEntries().Add(*NewItemInstance->GetItemEntry(), FortItemEntrySize);
|
auto ReplicatedEntryIdx = GetItemList().GetReplicatedEntries().Add(*NewItemInstance->GetItemEntry(), FFortItemEntry::GetStructSize());
|
||||||
// GetItemList().GetReplicatedEntries().AtPtr(ReplicatedEntryIdx, FFortItemEntry::GetStructSize())->GetIsReplicatedCopy() = true;
|
// GetItemList().GetReplicatedEntries().AtPtr(ReplicatedEntryIdx, FFortItemEntry::GetStructSize())->GetIsReplicatedCopy() = true;
|
||||||
|
|
||||||
if (FortPlayerController && WorldItemDefinition->IsValidLowLevel())
|
if (FortPlayerController && WorldItemDefinition->IsValidLowLevel())
|
||||||
@@ -267,55 +273,61 @@ bool AFortInventory::RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int
|
|||||||
|
|
||||||
int OldCount = Count;
|
int OldCount = Count;
|
||||||
|
|
||||||
|
bool bLikeReallyForce = false;
|
||||||
|
|
||||||
if (Count < 0) // idk why i have this
|
if (Count < 0) // idk why i have this
|
||||||
{
|
{
|
||||||
Count = 0;
|
Count = 0;
|
||||||
bForceRemoval = true;
|
bForceRemoval = true;
|
||||||
|
bLikeReallyForce = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto NewCount = ReplicatedEntry->GetCount() - Count;
|
|
||||||
|
|
||||||
auto& ItemInstances = GetItemList().GetItemInstances();
|
auto& ItemInstances = GetItemList().GetItemInstances();
|
||||||
auto& ReplicatedEntries = GetItemList().GetReplicatedEntries();
|
auto& ReplicatedEntries = GetItemList().GetReplicatedEntries();
|
||||||
|
|
||||||
bool bOverrideChangeStackSize = false;
|
if (!bLikeReallyForce)
|
||||||
|
|
||||||
if (ItemDefinition->ShouldPersistWhenFinalStackEmpty() && !bForceRemoval)
|
|
||||||
{
|
{
|
||||||
bool bIsFinalStack = true;
|
auto NewCount = ReplicatedEntry->GetCount() - Count;
|
||||||
|
|
||||||
for (int i = 0; i < ItemInstances.Num(); i++)
|
bool bOverrideChangeStackSize = false;
|
||||||
|
|
||||||
|
if (ItemDefinition->ShouldPersistWhenFinalStackEmpty())
|
||||||
{
|
{
|
||||||
auto ItemInstance = ItemInstances.at(i);
|
bool bIsFinalStack = true;
|
||||||
|
|
||||||
if (ItemInstance->GetItemEntry()->GetItemDefinition() == ItemDefinition && ItemInstance->GetItemEntry()->GetItemGuid() != ItemGuid)
|
for (int i = 0; i < ItemInstances.Num(); i++)
|
||||||
{
|
{
|
||||||
bIsFinalStack = false;
|
auto ItemInstance = ItemInstances.at(i);
|
||||||
break;
|
|
||||||
|
if (ItemInstance->GetItemEntry()->GetItemDefinition() == ItemDefinition && ItemInstance->GetItemEntry()->GetItemGuid() != ItemGuid)
|
||||||
|
{
|
||||||
|
bIsFinalStack = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bIsFinalStack)
|
||||||
|
{
|
||||||
|
NewCount = NewCount < 0 ? 0 : NewCount; // min(NewCount, 0) or something i forgot
|
||||||
|
bOverrideChangeStackSize = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bIsFinalStack)
|
if (OldCount != -1 && (NewCount > 0 || bOverrideChangeStackSize))
|
||||||
{
|
{
|
||||||
NewCount = NewCount < 0 ? 0 : NewCount; // min(NewCount, 0) or something i forgot
|
ItemInstance->GetItemEntry()->GetCount() = NewCount;
|
||||||
bOverrideChangeStackSize = true;
|
ReplicatedEntry->GetCount() = NewCount;
|
||||||
|
|
||||||
|
GetItemList().MarkItemDirty(ItemInstance->GetItemEntry());
|
||||||
|
GetItemList().MarkItemDirty(ReplicatedEntry);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NewCount < 0) // Hm
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OldCount != -1 && (NewCount > 0 || bOverrideChangeStackSize))
|
|
||||||
{
|
|
||||||
ItemInstance->GetItemEntry()->GetCount() = NewCount;
|
|
||||||
ReplicatedEntry->GetCount() = NewCount;
|
|
||||||
|
|
||||||
GetItemList().MarkItemDirty(ItemInstance->GetItemEntry());
|
|
||||||
GetItemList().MarkItemDirty(ReplicatedEntry);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NewCount < 0) // Hm
|
|
||||||
return false;
|
|
||||||
|
|
||||||
static auto FortItemEntryStruct = FindObject<UStruct>(L"/Script/FortniteGame.FortItemEntry");
|
static auto FortItemEntryStruct = FindObject<UStruct>(L"/Script/FortniteGame.FortItemEntry");
|
||||||
static auto FortItemEntrySize = FortItemEntryStruct->GetPropertiesSize();
|
static auto FortItemEntrySize = FortItemEntryStruct->GetPropertiesSize();
|
||||||
|
|
||||||
@@ -557,3 +569,9 @@ FFortItemEntry* AFortInventory::FindReplicatedEntry(const FGuid& Guid)
|
|||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* UClass* AFortInventory::StaticClass()
|
||||||
|
{
|
||||||
|
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortInventory");
|
||||||
|
return Class;
|
||||||
|
} */
|
||||||
@@ -110,4 +110,6 @@ public:
|
|||||||
|
|
||||||
UFortItem* FindItemInstance(const FGuid& Guid);
|
UFortItem* FindItemInstance(const FGuid& Guid);
|
||||||
FFortItemEntry* FindReplicatedEntry(const FGuid& Guid);
|
FFortItemEntry* FindReplicatedEntry(const FGuid& Guid);
|
||||||
|
|
||||||
|
// static UClass* StaticClass();
|
||||||
};
|
};
|
||||||
@@ -1,5 +1,40 @@
|
|||||||
#include "FortItem.h"
|
#include "FortItem.h"
|
||||||
|
|
||||||
|
#include "FortWeaponItemDefinition.h"
|
||||||
|
|
||||||
|
FFortItemEntry* FFortItemEntry::MakeItemEntry(UFortItemDefinition* ItemDefinition, int Count, int LoadedAmmo, float Durability)
|
||||||
|
{
|
||||||
|
auto Entry = // (FFortItemEntry*)FMemory::Realloc(0, GetStructSize(), 0);
|
||||||
|
Alloc<FFortItemEntry>(GetStructSize());
|
||||||
|
|
||||||
|
if (!Entry)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (LoadedAmmo == -1)
|
||||||
|
{
|
||||||
|
if (auto WeaponDef = Cast<UFortWeaponItemDefinition>(ItemDefinition)) // bPreventDefaultPreload ?
|
||||||
|
LoadedAmmo = WeaponDef->GetClipSize();
|
||||||
|
else
|
||||||
|
LoadedAmmo = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry->MostRecentArrayReplicationKey = -1; // idk if we need to set this
|
||||||
|
Entry->ReplicationID = -1;
|
||||||
|
Entry->ReplicationKey = -1;
|
||||||
|
|
||||||
|
Entry->GetItemDefinition() = ItemDefinition;
|
||||||
|
Entry->GetCount() = Count;
|
||||||
|
Entry->GetLoadedAmmo() = LoadedAmmo;
|
||||||
|
Entry->GetDurability() = Durability;
|
||||||
|
Entry->GetGameplayAbilitySpecHandle() = FGameplayAbilitySpecHandle(-1);
|
||||||
|
Entry->GetParentInventory().ObjectIndex = -1;
|
||||||
|
// We want to add StateValues.Add(DurabilityInitialized); orwnatefc erwgearf yk
|
||||||
|
// CoCreateGuid((GUID*)&Entry->GetItemGuid());
|
||||||
|
// Entry->DoesUpdateStatsOnCollection() = true; // I think fortnite does this?
|
||||||
|
|
||||||
|
return Entry;
|
||||||
|
}
|
||||||
|
|
||||||
void UFortItem::SetOwningControllerForTemporaryItem(UObject* Controller)
|
void UFortItem::SetOwningControllerForTemporaryItem(UObject* Controller)
|
||||||
{
|
{
|
||||||
static auto SOCFTIFn = FindObject<UFunction>(L"/Script/FortniteGame.FortItem.SetOwningControllerForTemporaryItem");
|
static auto SOCFTIFn = FindObject<UFunction>(L"/Script/FortniteGame.FortItem.SetOwningControllerForTemporaryItem");
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include "reboot.h"
|
#include "reboot.h"
|
||||||
|
|
||||||
enum class EFortItemEntryState : uint8_t // idk if this changes
|
enum class EFortItemEntryState : uint8_t // this changes but its fineee
|
||||||
{
|
{
|
||||||
NoneState = 0,
|
NoneState = 0,
|
||||||
NewItemCount = 1,
|
NewItemCount = 1,
|
||||||
@@ -74,6 +74,13 @@ struct FFortItemEntry : FFastArraySerializerItem
|
|||||||
return *(bool*)(__int64(this) + bIsReplicatedCopyOffset);
|
return *(bool*)(__int64(this) + bIsReplicatedCopyOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool& DoesUpdateStatsOnCollection()
|
||||||
|
{
|
||||||
|
// added like s8+ or somethingf idsk it was on 10.40 but not 7.40
|
||||||
|
static auto bUpdateStatsOnCollectionOffset = FindOffsetStruct("/Script/FortniteGame.FortItemEntry", "bUpdateStatsOnCollection");
|
||||||
|
return *(bool*)(__int64(this) + bUpdateStatsOnCollectionOffset);
|
||||||
|
}
|
||||||
|
|
||||||
class UFortItemDefinition*& GetItemDefinition()
|
class UFortItemDefinition*& GetItemDefinition()
|
||||||
{
|
{
|
||||||
static auto ItemDefinitionOffset = FindOffsetStruct("/Script/FortniteGame.FortItemEntry", "ItemDefinition");
|
static auto ItemDefinitionOffset = FindOffsetStruct("/Script/FortniteGame.FortItemEntry", "ItemDefinition");
|
||||||
@@ -116,6 +123,12 @@ struct FFortItemEntry : FFastArraySerializerItem
|
|||||||
return *(FGameplayAbilitySpecHandle*)(__int64(this) + GameplayAbilitySpecHandleOffset);
|
return *(FGameplayAbilitySpecHandle*)(__int64(this) + GameplayAbilitySpecHandleOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TArray<float>& GetGenericAttributeValues()
|
||||||
|
{
|
||||||
|
static auto GenericAttributeValuesOffset = FindOffsetStruct("/Script/FortniteGame.FortItemEntry", "GenericAttributeValues");
|
||||||
|
return *(TArray<float>*)(__int64(this) + GenericAttributeValuesOffset);
|
||||||
|
}
|
||||||
|
|
||||||
TWeakObjectPtr<class AFortInventory>& GetParentInventory()
|
TWeakObjectPtr<class AFortInventory>& GetParentInventory()
|
||||||
{
|
{
|
||||||
static auto ParentInventoryOffset = FindOffsetStruct("/Script/FortniteGame.FortItemEntry", "ParentInventory");
|
static auto ParentInventoryOffset = FindOffsetStruct("/Script/FortniteGame.FortItemEntry", "ParentInventory");
|
||||||
@@ -144,6 +157,20 @@ struct FFortItemEntry : FFastArraySerializerItem
|
|||||||
if (!bCopyGuid)
|
if (!bCopyGuid)
|
||||||
this->GetItemGuid() = OldGuid;
|
this->GetItemGuid() = OldGuid;
|
||||||
|
|
||||||
|
static auto GenericAttributeValuesOffset = FindOffsetStruct("/Script/FortniteGame.FortItemEntry", "GenericAttributeValues", false);
|
||||||
|
|
||||||
|
if (GenericAttributeValuesOffset != -1)
|
||||||
|
{
|
||||||
|
// proper copying
|
||||||
|
|
||||||
|
this->GetGenericAttributeValues().CopyFromArray(OtherItemEntry->GetGenericAttributeValues());
|
||||||
|
|
||||||
|
/* for (int i = 0; i < OtherItemEntry->GetGenericAttributeValues().Num(); i++)
|
||||||
|
{
|
||||||
|
this->GetGenericAttributeValues().Add(OtherItemEntry->GetGenericAttributeValues().at(i));
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
|
||||||
// should we do this?
|
// should we do this?
|
||||||
|
|
||||||
this->MostRecentArrayReplicationKey = -1;
|
this->MostRecentArrayReplicationKey = -1;
|
||||||
@@ -163,29 +190,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);
|
||||||
{
|
|
||||||
auto Entry = // (FFortItemEntry*)FMemory::Realloc(0, GetStructSize(), 0);
|
|
||||||
Alloc<FFortItemEntry>(GetStructSize());
|
|
||||||
|
|
||||||
if (!Entry)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
Entry->MostRecentArrayReplicationKey = -1; // idk if we need to set this
|
|
||||||
Entry->ReplicationID = -1;
|
|
||||||
Entry->ReplicationKey = -1;
|
|
||||||
|
|
||||||
Entry->GetItemDefinition() = ItemDefinition;
|
|
||||||
Entry->GetCount() = Count;
|
|
||||||
Entry->GetLoadedAmmo() = LoadedAmmo;
|
|
||||||
Entry->GetDurability() = Durability;
|
|
||||||
Entry->GetGameplayAbilitySpecHandle() = FGameplayAbilitySpecHandle(-1);
|
|
||||||
Entry->GetParentInventory().ObjectIndex = -1;
|
|
||||||
// CoCreateGuid((GUID*)&Entry->GetItemGuid());
|
|
||||||
// Entry->bUpdateStatsOnCollection = true; // Idk what this does but fortnite does it i think
|
|
||||||
|
|
||||||
return Entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.
|
||||||
|
|
||||||
@@ -196,6 +201,19 @@ struct FFortItemEntry : FFastArraySerializerItem
|
|||||||
static __int64 (*FreeEntryOriginal)(__int64 Entry) = decltype(FreeEntryOriginal)(Addresses::FreeEntry);
|
static __int64 (*FreeEntryOriginal)(__int64 Entry) = decltype(FreeEntryOriginal)(Addresses::FreeEntry);
|
||||||
FreeEntryOriginal(__int64(Entry));
|
FreeEntryOriginal(__int64(Entry));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static auto GenericAttributeValuesOffset = FindOffsetStruct("/Script/FortniteGame.FortItemEntry", "GenericAttributeValues", false);
|
||||||
|
|
||||||
|
if (GenericAttributeValuesOffset != -1)
|
||||||
|
{
|
||||||
|
Entry->GetGenericAttributeValues().Free();
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry->GetStateValues().Free();
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlZeroMemory(Entry, FFortItemEntry::GetStructSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FreeArrayOfEntries(TArray<FFortItemEntry>& tarray)
|
static void FreeArrayOfEntries(TArray<FFortItemEntry>& tarray)
|
||||||
|
|||||||
@@ -136,7 +136,11 @@ void UFortKismetLibrary::SpawnItemVariantPickupInWorldHook(UObject* Context, FFr
|
|||||||
|
|
||||||
LOG_INFO(LogDev, "{} {} {}", Position.X, Position.Y, Position.Z);
|
LOG_INFO(LogDev, "{} {} {}", Position.X, Position.Y, Position.Z);
|
||||||
|
|
||||||
auto Pickup = AFortPickup::SpawnPickup(ItemDefinition, Position, ParamsPtr->GetNumberToSpawn(), ParamsPtr->GetSourceType(), ParamsPtr->GetSource());
|
PickupCreateData CreateData{};
|
||||||
|
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(ItemDefinition, ParamsPtr->GetNumberToSpawn(), -1);
|
||||||
|
CreateData.SourceType = ParamsPtr->GetSourceType();
|
||||||
|
CreateData.Source = ParamsPtr->GetSource();
|
||||||
|
auto Pickup = AFortPickup::SpawnPickup(CreateData);
|
||||||
|
|
||||||
return SpawnItemVariantPickupInWorldOriginal(Context, Stack, Ret);
|
return SpawnItemVariantPickupInWorldOriginal(Context, Stack, Ret);
|
||||||
}
|
}
|
||||||
@@ -165,7 +169,13 @@ bool UFortKismetLibrary::SpawnInstancedPickupInWorldHook(UObject* Context, FFram
|
|||||||
Stack.StepCompiledIn(&bRandomRotation);
|
Stack.StepCompiledIn(&bRandomRotation);
|
||||||
Stack.StepCompiledIn(&bBlockedFromAutoPickup);
|
Stack.StepCompiledIn(&bBlockedFromAutoPickup);
|
||||||
|
|
||||||
auto Pickup = AFortPickup::SpawnPickup(ItemDefinition, Position, NumberToSpawn, EFortPickupSourceTypeFlag::Other, EFortPickupSpawnSource::Unset, -1, nullptr, nullptr, bToss);
|
PickupCreateData CreateData;
|
||||||
|
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(ItemDefinition, NumberToSpawn, -1);
|
||||||
|
CreateData.SpawnLocation = Position;
|
||||||
|
CreateData.bToss = bToss;
|
||||||
|
CreateData.bShouldFreeItemEntryWhenDeconstructed = true;
|
||||||
|
|
||||||
|
auto Pickup = AFortPickup::SpawnPickup(CreateData);
|
||||||
|
|
||||||
*Ret = Pickup;
|
*Ret = Pickup;
|
||||||
return *Ret;
|
return *Ret;
|
||||||
@@ -192,8 +202,8 @@ void UFortKismetLibrary::CreateTossAmmoPickupForWeaponItemDefinitionAtLocationHo
|
|||||||
UFortWeaponItemDefinition* WeaponItemDefinition;
|
UFortWeaponItemDefinition* WeaponItemDefinition;
|
||||||
FGameplayTagContainer SourceTags;
|
FGameplayTagContainer SourceTags;
|
||||||
FVector Location;
|
FVector Location;
|
||||||
EFortPickupSourceTypeFlag SourceTypeFlag;
|
uint8 SourceTypeFlag;
|
||||||
EFortPickupSpawnSource SpawnSource;
|
uint8 SpawnSource;
|
||||||
|
|
||||||
Stack.StepCompiledIn(&WorldContextObject);
|
Stack.StepCompiledIn(&WorldContextObject);
|
||||||
Stack.StepCompiledIn(&WeaponItemDefinition);
|
Stack.StepCompiledIn(&WeaponItemDefinition);
|
||||||
@@ -213,7 +223,13 @@ void UFortKismetLibrary::CreateTossAmmoPickupForWeaponItemDefinitionAtLocationHo
|
|||||||
if (!AmmoDefinition)
|
if (!AmmoDefinition)
|
||||||
return CreateTossAmmoPickupForWeaponItemDefinitionAtLocationOriginal(Context, Stack, Ret);
|
return CreateTossAmmoPickupForWeaponItemDefinitionAtLocationOriginal(Context, Stack, Ret);
|
||||||
|
|
||||||
auto AmmoPickup = AFortPickup::SpawnPickup(AmmoDefinition, Location, Count, SourceTypeFlag, SpawnSource);
|
PickupCreateData CreateData;
|
||||||
|
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(AmmoDefinition, Count, 0);
|
||||||
|
CreateData.SourceType = SourceTypeFlag;
|
||||||
|
CreateData.Source = SpawnSource;
|
||||||
|
CreateData.SpawnLocation = Location;
|
||||||
|
|
||||||
|
auto AmmoPickup = AFortPickup::SpawnPickup(CreateData);
|
||||||
|
|
||||||
return CreateTossAmmoPickupForWeaponItemDefinitionAtLocationOriginal(Context, Stack, Ret);
|
return CreateTossAmmoPickupForWeaponItemDefinitionAtLocationOriginal(Context, Stack, Ret);
|
||||||
}
|
}
|
||||||
@@ -460,8 +476,8 @@ AFortPickup* UFortKismetLibrary::K2_SpawnPickupInWorldWithClassHook(UObject* Con
|
|||||||
bool bRandomRotation; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
bool bRandomRotation; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
bool bBlockedFromAutoPickup; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
bool bBlockedFromAutoPickup; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
int PickupInstigatorHandle; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
int PickupInstigatorHandle; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
EFortPickupSourceTypeFlag SourceType; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
uint8 SourceType; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
EFortPickupSpawnSource Source; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
uint8 Source; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
AFortPlayerController* OptionalOwnerPC; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
AFortPlayerController* OptionalOwnerPC; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
bool bPickupOnlyRelevantToOwner; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
bool bPickupOnlyRelevantToOwner; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
|
||||||
@@ -488,11 +504,19 @@ AFortPickup* UFortKismetLibrary::K2_SpawnPickupInWorldWithClassHook(UObject* Con
|
|||||||
|
|
||||||
LOG_INFO(LogDev, __FUNCTION__);
|
LOG_INFO(LogDev, __FUNCTION__);
|
||||||
|
|
||||||
auto aa = AFortPickup::SpawnPickup(ItemDefinition, Position, NumberToSpawn, SourceType, Source, -1, nullptr, PickupClass, bToss);
|
PickupCreateData CreateData;
|
||||||
|
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(ItemDefinition, NumberToSpawn, -1);
|
||||||
|
CreateData.Source = Source;
|
||||||
|
CreateData.SourceType = SourceType;
|
||||||
|
CreateData.OverrideClass = PickupClass;
|
||||||
|
CreateData.bToss = bToss;
|
||||||
|
CreateData.bRandomRotation = bRandomRotation;
|
||||||
|
|
||||||
|
auto NewPickup = AFortPickup::SpawnPickup(CreateData);
|
||||||
|
|
||||||
K2_SpawnPickupInWorldWithClassOriginal(Context, Stack, Ret);
|
K2_SpawnPickupInWorldWithClassOriginal(Context, Stack, Ret);
|
||||||
|
|
||||||
*Ret = aa;
|
*Ret = NewPickup;
|
||||||
return *Ret;
|
return *Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -508,8 +532,8 @@ AFortPickup* UFortKismetLibrary::K2_SpawnPickupInWorldHook(UObject* Context, FFr
|
|||||||
bool bRandomRotation; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
bool bRandomRotation; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
bool bBlockedFromAutoPickup; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
bool bBlockedFromAutoPickup; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
int PickupInstigatorHandle; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
int PickupInstigatorHandle; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
EFortPickupSourceTypeFlag SourceType; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
uint8 SourceType; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
EFortPickupSpawnSource Source; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
uint8 Source; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
AFortPlayerController* OptionalOwnerPC; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
AFortPlayerController* OptionalOwnerPC; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
bool bPickupOnlyRelevantToOwner; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
bool bPickupOnlyRelevantToOwner; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
|
||||||
@@ -535,11 +559,19 @@ AFortPickup* UFortKismetLibrary::K2_SpawnPickupInWorldHook(UObject* Context, FFr
|
|||||||
|
|
||||||
auto Pawn = OptionalOwnerPC ? OptionalOwnerPC->GetMyFortPawn() : nullptr;
|
auto Pawn = OptionalOwnerPC ? OptionalOwnerPC->GetMyFortPawn() : nullptr;
|
||||||
|
|
||||||
auto aa = AFortPickup::SpawnPickup(ItemDefinition, Position, NumberToSpawn, SourceType, Source, -1, Pawn, AFortPickup::StaticClass(), bToss);
|
PickupCreateData CreateData;
|
||||||
|
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(ItemDefinition, NumberToSpawn, -1);
|
||||||
|
CreateData.SpawnLocation = Position;
|
||||||
|
CreateData.bToss = bToss;
|
||||||
|
CreateData.bRandomRotation = bRandomRotation;
|
||||||
|
CreateData.PawnOwner = Pawn;
|
||||||
|
CreateData.bShouldFreeItemEntryWhenDeconstructed = true;
|
||||||
|
|
||||||
|
auto NewPickup = AFortPickup::SpawnPickup(CreateData);
|
||||||
|
|
||||||
K2_SpawnPickupInWorldOriginal(Context, Stack, Ret);
|
K2_SpawnPickupInWorldOriginal(Context, Stack, Ret);
|
||||||
|
|
||||||
*Ret = aa;
|
*Ret = NewPickup;
|
||||||
return *Ret;
|
return *Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,16 +35,16 @@ struct FSpawnItemVariantParams
|
|||||||
return *(int*)(__int64(this) + NumberToSpawnOffset);
|
return *(int*)(__int64(this) + NumberToSpawnOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
EFortPickupSourceTypeFlag& GetSourceType()
|
uint8& GetSourceType()
|
||||||
{
|
{
|
||||||
static auto SourceTypeOffset = FindOffsetStruct("/Script/FortniteGame.SpawnItemVariantParams", "SourceType");
|
static auto SourceTypeOffset = FindOffsetStruct("/Script/FortniteGame.SpawnItemVariantParams", "SourceType");
|
||||||
return *(EFortPickupSourceTypeFlag*)(__int64(this) + SourceTypeOffset);
|
return *(uint8*)(__int64(this) + SourceTypeOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
EFortPickupSpawnSource& GetSource()
|
uint8& GetSource()
|
||||||
{
|
{
|
||||||
static auto SourceOffset = FindOffsetStruct("/Script/FortniteGame.SpawnItemVariantParams", "Source");
|
static auto SourceOffset = FindOffsetStruct("/Script/FortniteGame.SpawnItemVariantParams", "Source");
|
||||||
return *(EFortPickupSpawnSource*)(__int64(this) + SourceOffset);
|
return *(uint8*)(__int64(this) + SourceOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
FVector& GetDirection()
|
FVector& GetDirection()
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ static T* PickWeightedElement(const std::map<FName, T*>& Elements, std::function
|
|||||||
TotalWeight = std::accumulate(Elements.begin(), Elements.end(), 0.0f, [&](float acc, const std::pair<FName, T*>& p) {
|
TotalWeight = std::accumulate(Elements.begin(), Elements.end(), 0.0f, [&](float acc, const std::pair<FName, T*>& p) {
|
||||||
auto Weight = GetWeightFn(p.second);
|
auto Weight = GetWeightFn(p.second);
|
||||||
|
|
||||||
if (bPrint)
|
if (bPrint && Weight != 0)
|
||||||
{
|
{
|
||||||
LOG_INFO(LogLoot, "Adding weight: {}", Weight);
|
LOG_INFO(LogLoot, "Adding weight: {}", Weight);
|
||||||
}
|
}
|
||||||
@@ -282,7 +282,7 @@ void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, cons
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (bPrint)
|
if (bPrint)
|
||||||
LOG_INFO(LogLoot, "PickLootDropsFromLootPackage selected package {} with loot package category {} from LootPackageIDMap of size: {}", PickedPackageRowName.ToString(), LootPackageCategory, LootPackageIDMap.size());
|
LOG_INFO(LogLoot, "PickLootDropsFromLootPackage selected package {} with loot package category {} with weight {} from LootPackageIDMap of size: {}", PickedPackageRowName.ToString(), LootPackageCategory, PickedPackage->GetWeight(), LootPackageIDMap.size());
|
||||||
|
|
||||||
if (PickedPackage->GetLootPackageCall().Data.Num() > 1)
|
if (PickedPackage->GetLootPackageCall().Data.Num() > 1)
|
||||||
{
|
{
|
||||||
@@ -358,12 +358,20 @@ void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, cons
|
|||||||
{
|
{
|
||||||
auto AmmoData = WeaponItemDefinition->GetAmmoData();
|
auto AmmoData = WeaponItemDefinition->GetAmmoData();
|
||||||
|
|
||||||
int AmmoCount = AmmoData->GetDropCount(); // idk about this one
|
if (AmmoData)
|
||||||
|
{
|
||||||
|
int AmmoCount = AmmoData->GetDropCount(); // idk about this one
|
||||||
|
|
||||||
OutEntries->push_back(LootDrop(FFortItemEntry::MakeItemEntry(WeaponItemDefinition->GetAmmoData(), AmmoCount)));
|
OutEntries->push_back(LootDrop(FFortItemEntry::MakeItemEntry(AmmoData, AmmoCount)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bPrint)
|
||||||
|
{
|
||||||
|
LOG_INFO(LogLoot, "Adding Item: {}", ItemDefinition->GetPathName());
|
||||||
|
}
|
||||||
|
|
||||||
FinalCount -= CurrentCountForEntry;
|
FinalCount -= CurrentCountForEntry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,16 @@ void AFortPawn::SetHealth(float NewHealth)
|
|||||||
this->ProcessEvent(SetHealthFn, &NewHealth);
|
this->ProcessEvent(SetHealthFn, &NewHealth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AFortPawn::SetMaxHealth(float NewHealthVal)
|
||||||
|
{
|
||||||
|
static auto SetMaxHealthFn = FindObject<UFunction>("/Script/FortniteGame.FortPawn.SetMaxHealth");
|
||||||
|
|
||||||
|
if (!SetMaxHealthFn)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this->ProcessEvent(SetMaxHealthFn, &NewHealthVal);
|
||||||
|
}
|
||||||
|
|
||||||
void AFortPawn::SetShield(float NewShield)
|
void AFortPawn::SetShield(float NewShield)
|
||||||
{
|
{
|
||||||
static auto SetShieldFn = FindObject<UFunction>("/Script/FortniteGame.FortPawn.SetShield");
|
static auto SetShieldFn = FindObject<UFunction>("/Script/FortniteGame.FortPawn.SetShield");
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SetHealth(float NewHealth);
|
void SetHealth(float NewHealth);
|
||||||
|
void SetMaxHealth(float NewHealthVal);
|
||||||
void SetShield(float NewShield);
|
void SetShield(float NewShield);
|
||||||
static void NetMulticast_Athena_BatchedDamageCuesHook(UObject* Context, FFrame* Stack, void* Ret);
|
static void NetMulticast_Athena_BatchedDamageCuesHook(UObject* Context, FFrame* Stack, void* Ret);
|
||||||
static void MovingEmoteStoppedHook(UObject* Context, FFrame* Stack, void* Ret);
|
static void MovingEmoteStoppedHook(UObject* Context, FFrame* Stack, void* Ret);
|
||||||
|
|||||||
@@ -10,12 +10,12 @@
|
|||||||
#include "GameplayStatics.h"
|
#include "GameplayStatics.h"
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
|
|
||||||
void AFortPickup::TossPickup(FVector FinalLocation, AFortPawn* ItemOwner, int OverrideMaxStackCount, bool bToss, EFortPickupSourceTypeFlag InPickupSourceTypeFlags, EFortPickupSpawnSource InPickupSpawnSource)
|
void AFortPickup::TossPickup(FVector FinalLocation, AFortPawn* ItemOwner, int OverrideMaxStackCount, bool bToss, uint8 InPickupSourceTypeFlags, uint8 InPickupSpawnSource)
|
||||||
{
|
{
|
||||||
static auto fn = FindObject<UFunction>(L"/Script/FortniteGame.FortPickup.TossPickup");
|
static auto fn = FindObject<UFunction>(L"/Script/FortniteGame.FortPickup.TossPickup");
|
||||||
|
|
||||||
struct { FVector FinalLocation; AFortPawn* ItemOwner; int OverrideMaxStackCount; bool bToss;
|
struct { FVector FinalLocation; AFortPawn* ItemOwner; int OverrideMaxStackCount; bool bToss;
|
||||||
EFortPickupSourceTypeFlag InPickupSourceTypeFlags; EFortPickupSpawnSource InPickupSpawnSource; }
|
uint8 InPickupSourceTypeFlags; uint8 InPickupSpawnSource; }
|
||||||
AFortPickup_TossPickup_Params{FinalLocation, ItemOwner, OverrideMaxStackCount, bToss, InPickupSourceTypeFlags, InPickupSpawnSource};
|
AFortPickup_TossPickup_Params{FinalLocation, ItemOwner, OverrideMaxStackCount, bToss, InPickupSourceTypeFlags, InPickupSpawnSource};
|
||||||
|
|
||||||
this->ProcessEvent(fn, &AFortPickup_TossPickup_Params);
|
this->ProcessEvent(fn, &AFortPickup_TossPickup_Params);
|
||||||
@@ -29,145 +29,151 @@ void AFortPickup::SpawnMovementComponent()
|
|||||||
this->Get(MovementComponentOffset) = UGameplayStatics::SpawnObject(ProjectileMovementComponentClass, this);
|
this->Get(MovementComponentOffset) = UGameplayStatics::SpawnObject(ProjectileMovementComponentClass, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
AFortPickup* AFortPickup::SpawnPickup(FFortItemEntry* ItemEntry, FVector Location,
|
AFortPickup* AFortPickup::SpawnPickup(PickupCreateData& PickupData)
|
||||||
EFortPickupSourceTypeFlag PickupSource, EFortPickupSpawnSource SpawnSource,
|
|
||||||
class AFortPawn* Pawn, UClass* OverrideClass, bool bToss, int OverrideCount, AFortPickup* IgnoreCombinePickup)
|
|
||||||
{
|
{
|
||||||
if (bToss)
|
if (PickupData.Source == -1)
|
||||||
{
|
PickupData.Source = 0;
|
||||||
PickupSource |= EFortPickupSourceTypeFlag::Tossed;
|
if (PickupData.SourceType == -1)
|
||||||
}
|
PickupData.SourceType = -1;
|
||||||
|
|
||||||
|
/* if (PickupData.bToss)
|
||||||
|
{
|
||||||
|
PickupData.SourceType |= EFortPickupSourceTypeFlag::Tossed;
|
||||||
|
} */
|
||||||
|
|
||||||
// static auto FortPickupClass = FindObject<UClass>(L"/Script/FortniteGame.FortPickup");
|
|
||||||
static auto FortPickupAthenaClass = FindObject<UClass>(L"/Script/FortniteGame.FortPickupAthena");
|
static auto FortPickupAthenaClass = FindObject<UClass>(L"/Script/FortniteGame.FortPickupAthena");
|
||||||
auto PlayerState = Pawn ? Cast<AFortPlayerState>(Pawn->GetPlayerState()) : nullptr;
|
auto PlayerState = PickupData.PawnOwner ? Cast<AFortPlayerState>(PickupData.PawnOwner->GetPlayerState()) : nullptr;
|
||||||
|
|
||||||
FActorSpawnParameters SpawnParameters{};
|
FActorSpawnParameters SpawnParameters{};
|
||||||
// SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
|
// SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
|
||||||
|
|
||||||
if (auto Pickup = GetWorld()->SpawnActor<AFortPickup>(OverrideClass ? OverrideClass : FortPickupAthenaClass, Location, FQuat(), FVector(1, 1, 1), SpawnParameters))
|
auto Pickup = GetWorld()->SpawnActor<AFortPickup>(PickupData.OverrideClass ? PickupData.OverrideClass : FortPickupAthenaClass, PickupData.SpawnLocation, FQuat(), FVector(1, 1, 1), SpawnParameters);
|
||||||
|
|
||||||
|
if (!Pickup)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
static auto bRandomRotationOffset = Pickup->GetOffset("bRandomRotation", false);
|
||||||
|
|
||||||
|
if (bRandomRotationOffset != -1)
|
||||||
|
Pickup->Get<bool>(bRandomRotationOffset) = PickupData.bRandomRotation;
|
||||||
|
|
||||||
|
static auto PawnWhoDroppedPickupOffset = Pickup->GetOffset("PawnWhoDroppedPickup");
|
||||||
|
Pickup->Get<AFortPawn*>(PawnWhoDroppedPickupOffset) = PickupData.PawnOwner;
|
||||||
|
|
||||||
|
auto PrimaryPickupItemEntry = Pickup->GetPrimaryPickupItemEntry();
|
||||||
|
|
||||||
|
if (Addresses::PickupInitialize)
|
||||||
{
|
{
|
||||||
static auto PawnWhoDroppedPickupOffset = Pickup->GetOffset("PawnWhoDroppedPickup");
|
static void (*SetupPickup)(AFortPickup * Pickup, __int64 ItemEntry, TArray<FFortItemEntry> MultiItemPickupEntriesIGuess, bool bSplitOnPickup)
|
||||||
Pickup->Get<AFortPawn*>(PawnWhoDroppedPickupOffset) = Pawn;
|
= decltype(SetupPickup)(Addresses::PickupInitialize);
|
||||||
|
|
||||||
auto PrimaryPickupItemEntry = Pickup->GetPrimaryPickupItemEntry();
|
TArray<FFortItemEntry> MultiItemPickupEntriesIGuess{};
|
||||||
|
SetupPickup(Pickup, __int64(PickupData.ItemEntry), MultiItemPickupEntriesIGuess, false);
|
||||||
|
FFortItemEntry::FreeArrayOfEntries(MultiItemPickupEntriesIGuess);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PrimaryPickupItemEntry->CopyFromAnotherItemEntry(PickupData.ItemEntry);
|
||||||
|
}
|
||||||
|
|
||||||
if (Addresses::PickupInitialize)
|
static auto PickupSourceTypeFlagsOffset = Pickup->GetOffset("PickupSourceTypeFlags", false);
|
||||||
|
|
||||||
|
if (PickupSourceTypeFlagsOffset != -1)
|
||||||
|
{
|
||||||
|
// Pickup->Get<int32>(PickupSourceTypeFlagsOffset) |= (int)PickupData.SourceType; // Assuming its the same enum on older versions. // (it is not the same)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Pickup->Get<AFortPawn*>(PawnWhoDroppedPickupOffset))
|
||||||
|
{
|
||||||
|
// TODO Add EFortItemEntryState::DroppedFromPickup or whatever if it isn't found already.
|
||||||
|
}
|
||||||
|
|
||||||
|
PrimaryPickupItemEntry->GetCount() = PickupData.OverrideCount == -1 ? PickupData.ItemEntry->GetCount() : PickupData.OverrideCount;
|
||||||
|
|
||||||
|
auto PickupLocationData = Pickup->GetPickupLocationData();
|
||||||
|
|
||||||
|
auto CanCombineWithPickup = [&](AActor* OtherPickupActor) -> bool
|
||||||
|
{
|
||||||
|
auto OtherPickup = (AFortPickup*)OtherPickupActor;
|
||||||
|
|
||||||
|
if (OtherPickup == PickupData.IgnoreCombineTarget || Pickup->GetPickupLocationData()->GetCombineTarget())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (OtherPickup->GetPickupLocationData()->GetTossState() != EFortPickupTossState::AtRest)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (PrimaryPickupItemEntry->GetItemDefinition() == OtherPickup->GetPrimaryPickupItemEntry()->GetItemDefinition())
|
||||||
{
|
{
|
||||||
static void (*SetupPickup)(AFortPickup* Pickup, __int64 ItemEntry, TArray<FFortItemEntry> MultiItemPickupEntriesIGuess, bool bSplitOnPickup)
|
if (OtherPickup->GetPrimaryPickupItemEntry()->GetCount() >= PrimaryPickupItemEntry->GetItemDefinition()->GetMaxStackSize()) // Other pickup is already at the max size.
|
||||||
= decltype(SetupPickup)(Addresses::PickupInitialize);
|
|
||||||
|
|
||||||
TArray<FFortItemEntry> MultiItemPickupEntriesIGuess{};
|
|
||||||
SetupPickup(Pickup, __int64(ItemEntry), MultiItemPickupEntriesIGuess, false);
|
|
||||||
FFortItemEntry::FreeArrayOfEntries(MultiItemPickupEntriesIGuess);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PrimaryPickupItemEntry->CopyFromAnotherItemEntry(ItemEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto PickupSourceTypeFlagsOffset = Pickup->GetOffset("PickupSourceTypeFlags", false);
|
|
||||||
|
|
||||||
if (PickupSourceTypeFlagsOffset != -1)
|
|
||||||
Pickup->Get<int32>(PickupSourceTypeFlagsOffset) |= (int)PickupSource; // Assuming its the same enum on older versions.
|
|
||||||
|
|
||||||
PrimaryPickupItemEntry->GetCount() = OverrideCount == -1 ? ItemEntry->GetCount() : OverrideCount;
|
|
||||||
|
|
||||||
// PrimaryPickupItemEntry->GetItemGuid() = OldGuid;
|
|
||||||
|
|
||||||
// Pickup->OnRep_PrimaryPickupItemEntry();
|
|
||||||
|
|
||||||
// static auto OptionalOwnerIDOffset = Pickup->GetOffset("OptionalOwnerID");
|
|
||||||
// Pickup->Get<int>(OptionalOwnerIDOffset) = PlayerState ? PlayerState->GetWorldPlayerId() : -1;
|
|
||||||
|
|
||||||
auto PickupLocationData = Pickup->GetPickupLocationData();
|
|
||||||
|
|
||||||
auto CanCombineWithPickup = [&](AActor* OtherPickupActor) -> bool
|
|
||||||
{
|
|
||||||
auto OtherPickup = (AFortPickup*)OtherPickupActor;
|
|
||||||
|
|
||||||
if (OtherPickup == IgnoreCombinePickup || OtherPickup->GetPickupLocationData()->GetCombineTarget())
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (PrimaryPickupItemEntry->GetItemDefinition() == OtherPickup->GetPrimaryPickupItemEntry()->GetItemDefinition())
|
return true;
|
||||||
{
|
|
||||||
// auto IncomingCount = OtherPickup->GetPrimaryPickupItemEntry()->GetCount();
|
|
||||||
|
|
||||||
// if (PrimaryPickupItemEntry->GetCount() + IncomingCount == PrimaryPickupItemEntry->GetItemDefinition()->GetMaxStackSize())
|
|
||||||
// return false;
|
|
||||||
|
|
||||||
if (OtherPickup->GetPrimaryPickupItemEntry()->GetCount() == PrimaryPickupItemEntry->GetItemDefinition()->GetMaxStackSize()) // Other pickup is already at the max size.
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (Addresses::CombinePickupLea)
|
|
||||||
{
|
|
||||||
PickupLocationData->GetCombineTarget() = (AFortPickup*)Pickup->GetClosestActor(AFortPickup::StaticClass(), 4, CanCombineWithPickup);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PickupLocationData->GetCombineTarget()) // I don't think we should call TossPickup for every pickup anyways.
|
return false;
|
||||||
{
|
};
|
||||||
Pickup->TossPickup(Location, Pawn, 0, bToss, PickupSource, SpawnSource);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto ActorLocation = Pickup->GetActorLocation();
|
|
||||||
auto CurrentActorLocation = PickupLocationData->GetCombineTarget()->GetActorLocation();
|
|
||||||
|
|
||||||
int Dist = float(sqrtf(powf(CurrentActorLocation.X - ActorLocation.X, 2.0) + powf(CurrentActorLocation.Y - ActorLocation.Y, 2.0) + powf(CurrentActorLocation.Z - ActorLocation.Z, 2.0))) / 100.f;
|
if (Addresses::CombinePickupLea && bEnableCombinePickup)
|
||||||
|
{
|
||||||
// LOG_INFO(LogDev, "Distance: {}", Dist);
|
PickupLocationData->GetCombineTarget() = (AFortPickup*)Pickup->GetClosestActor(AFortPickup::StaticClass(), 4, CanCombineWithPickup);
|
||||||
|
|
||||||
// our little remake of tosspickup
|
|
||||||
|
|
||||||
PickupLocationData->GetLootFinalPosition() = Location;
|
|
||||||
PickupLocationData->GetLootInitialPosition() = Pickup->GetActorLocation();
|
|
||||||
PickupLocationData->GetFlyTime() = 1.f / Dist; // Higher the dist quicker it should be. // not right
|
|
||||||
PickupLocationData->GetItemOwner() = Pawn;
|
|
||||||
PickupLocationData->GetFinalTossRestLocation() = PickupLocationData->GetCombineTarget()->GetActorLocation(); // Pickup->GetActorLocation() // ong ong proper
|
|
||||||
|
|
||||||
Pickup->OnRep_PickupLocationData();
|
|
||||||
Pickup->ForceNetUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PickupSource == EFortPickupSourceTypeFlag::Container) // crashes if we do this then tosspickup
|
|
||||||
{
|
|
||||||
static auto bTossedFromContainerOffset = Pickup->GetOffset("bTossedFromContainer");
|
|
||||||
Pickup->Get<bool>(bTossedFromContainerOffset) = true;
|
|
||||||
// Pickup->OnRep_TossedFromContainer();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Fortnite_Version < 6)
|
|
||||||
{
|
|
||||||
Pickup->SpawnMovementComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Pickup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
if (!PickupLocationData->GetCombineTarget()) // I don't think we should call TossPickup for every pickup anyways.
|
||||||
|
{
|
||||||
|
Pickup->TossPickup(PickupData.SpawnLocation, PickupData.PawnOwner, 0, PickupData.bToss, PickupData.SourceType, PickupData.Source);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto ActorLocation = Pickup->GetActorLocation();
|
||||||
|
auto CurrentActorLocation = PickupLocationData->GetCombineTarget()->GetActorLocation();
|
||||||
|
|
||||||
|
int Dist = float(sqrtf(powf(CurrentActorLocation.X - ActorLocation.X, 2.0) + powf(CurrentActorLocation.Y - ActorLocation.Y, 2.0) + powf(CurrentActorLocation.Z - ActorLocation.Z, 2.0))) / 100.f;
|
||||||
|
|
||||||
|
// LOG_INFO(LogDev, "Distance: {}", Dist);
|
||||||
|
|
||||||
|
// our little remake of tosspickup
|
||||||
|
|
||||||
|
PickupLocationData->GetLootFinalPosition() = PickupData.SpawnLocation;
|
||||||
|
PickupLocationData->GetLootInitialPosition() = Pickup->GetActorLocation();
|
||||||
|
PickupLocationData->GetFlyTime() = 1.f / Dist; // Higher the dist quicker it should be. // not right
|
||||||
|
PickupLocationData->GetItemOwner() = PickupData.PawnOwner;
|
||||||
|
PickupLocationData->GetFinalTossRestLocation() = PickupLocationData->GetCombineTarget()->GetActorLocation();
|
||||||
|
|
||||||
|
Pickup->OnRep_PickupLocationData();
|
||||||
|
Pickup->ForceNetUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EFortPickupSourceTypeFlag::GetEnum() && PickupData.SourceType == EFortPickupSourceTypeFlag::GetContainerValue()) // crashes if we do this then tosspickup
|
||||||
|
{
|
||||||
|
static auto bTossedFromContainerOffset = Pickup->GetOffset("bTossedFromContainer");
|
||||||
|
Pickup->Get<bool>(bTossedFromContainerOffset) = true;
|
||||||
|
// Pickup->OnRep_TossedFromContainer();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Fortnite_Version < 6)
|
||||||
|
{
|
||||||
|
Pickup->SpawnMovementComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Pickup;
|
||||||
}
|
}
|
||||||
|
|
||||||
AFortPickup* AFortPickup::SpawnPickup(UFortItemDefinition* ItemDef, FVector Location, int Count, EFortPickupSourceTypeFlag PickupSource, EFortPickupSpawnSource SpawnSource,
|
AFortPickup* AFortPickup::SpawnPickup(FFortItemEntry* ItemEntry, FVector Location,
|
||||||
int LoadedAmmo, AFortPawn* Pawn, UClass* OverrideClass, bool bToss, AFortPickup* IgnoreCombinePickup)
|
uint8 PickupSource, uint8 SpawnSource,
|
||||||
|
class AFortPawn* Pawn, UClass* OverrideClass, bool bToss, int OverrideCount, AFortPickup* IgnoreCombinePickup)
|
||||||
{
|
{
|
||||||
if (LoadedAmmo == -1)
|
PickupCreateData CreateData;
|
||||||
{
|
CreateData.ItemEntry = ItemEntry;
|
||||||
if (auto WeaponDef = Cast<UFortWeaponItemDefinition>(ItemDef)) // bPreventDefaultPreload ?
|
CreateData.SpawnLocation = Location;
|
||||||
LoadedAmmo = WeaponDef->GetClipSize();
|
CreateData.Source = SpawnSource;
|
||||||
else
|
CreateData.SourceType = PickupSource;
|
||||||
LoadedAmmo = 0;
|
CreateData.PawnOwner = Pawn;
|
||||||
}
|
CreateData.OverrideClass = OverrideClass;
|
||||||
|
CreateData.bToss = bToss;
|
||||||
|
CreateData.IgnoreCombineTarget = IgnoreCombinePickup;
|
||||||
|
CreateData.OverrideCount = OverrideCount;
|
||||||
|
|
||||||
auto ItemEntry = FFortItemEntry::MakeItemEntry(ItemDef, Count, LoadedAmmo);
|
return AFortPickup::SpawnPickup(CreateData);
|
||||||
auto Pickup = SpawnPickup(ItemEntry, Location, PickupSource, SpawnSource, Pawn, OverrideClass, bToss, -1, IgnoreCombinePickup);
|
|
||||||
// VirtualFree(ItemEntry);
|
|
||||||
return Pickup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AFortPickup::CombinePickupHook(AFortPickup* Pickup)
|
void AFortPickup::CombinePickupHook(AFortPickup* Pickup)
|
||||||
@@ -195,8 +201,14 @@ void AFortPickup::CombinePickupHook(AFortPickup* Pickup)
|
|||||||
|
|
||||||
auto ItemOwner = Pickup->GetPickupLocationData()->GetItemOwner();
|
auto ItemOwner = Pickup->GetPickupLocationData()->GetItemOwner();
|
||||||
|
|
||||||
auto NewOverStackPickup = AFortPickup::SpawnPickup(ItemDefinition, PickupToCombineInto->GetActorLocation(), OverStackCount,
|
PickupCreateData CreateData;
|
||||||
EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset, -1, ItemOwner, nullptr, false, PickupToCombineInto);
|
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(ItemDefinition, OverStackCount, 0);
|
||||||
|
CreateData.SpawnLocation = PickupToCombineInto->GetActorLocation();
|
||||||
|
CreateData.PawnOwner = ItemOwner;
|
||||||
|
CreateData.SourceType = EFortPickupSourceTypeFlag::GetPlayerValue();
|
||||||
|
CreateData.IgnoreCombineTarget = PickupToCombineInto;
|
||||||
|
|
||||||
|
auto NewOverStackPickup = AFortPickup::SpawnPickup(CreateData);
|
||||||
}
|
}
|
||||||
|
|
||||||
PickupToCombineInto->GetPrimaryPickupItemEntry()->GetCount() += CountToAdd;
|
PickupToCombineInto->GetPrimaryPickupItemEntry()->GetCount() += CountToAdd;
|
||||||
@@ -300,7 +312,7 @@ char AFortPickup::CompletePickupAnimationHook(AFortPickup* Pickup)
|
|||||||
if (ItemInstanceToSwap && ItemDefinitionToSwap->CanBeDropped() && !bHasSwapped && ItemDefGoingInPrimary) // swap
|
if (ItemInstanceToSwap && ItemDefinitionToSwap->CanBeDropped() && !bHasSwapped && ItemDefGoingInPrimary) // swap
|
||||||
{
|
{
|
||||||
auto SwappedPickup = SpawnPickup(ItemEntryToSwap, PawnLoc,
|
auto SwappedPickup = SpawnPickup(ItemEntryToSwap, PawnLoc,
|
||||||
EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset, Pawn);
|
EFortPickupSourceTypeFlag::GetPlayerValue(), 0, Pawn);
|
||||||
|
|
||||||
auto CurrentWeapon = Pawn->GetCurrentWeapon();
|
auto CurrentWeapon = Pawn->GetCurrentWeapon();
|
||||||
|
|
||||||
@@ -373,7 +385,7 @@ char AFortPickup::CompletePickupAnimationHook(AFortPickup* Pickup)
|
|||||||
int LoadedAmmo = 0;
|
int LoadedAmmo = 0;
|
||||||
|
|
||||||
// SpawnPickup(ItemDefinitionToSpawn, PawnLoc, AmountToSpawn, EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset, -1, Pawn);
|
// SpawnPickup(ItemDefinitionToSpawn, PawnLoc, AmountToSpawn, EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset, -1, Pawn);
|
||||||
SpawnPickup(PickupEntry, PawnLoc, EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset, Pawn, nullptr, true, AmountToSpawn);
|
SpawnPickup(PickupEntry, PawnLoc, EFortPickupSourceTypeFlag::GetPlayerValue(), 0, Pawn, nullptr, true, AmountToSpawn);
|
||||||
cpyCount -= AmountToSpawn;
|
cpyCount -= AmountToSpawn;
|
||||||
bForceOverflow = false;
|
bForceOverflow = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,33 +2,99 @@
|
|||||||
|
|
||||||
#include "Actor.h"
|
#include "Actor.h"
|
||||||
#include "FortPawn.h"
|
#include "FortPawn.h"
|
||||||
|
#include "Class.h"
|
||||||
|
|
||||||
enum class EFortPickupSourceTypeFlag : uint8_t
|
namespace EFortPickupSourceTypeFlag
|
||||||
{
|
{
|
||||||
Other = 0,
|
static inline UEnum* GetEnum()
|
||||||
Player = 1,
|
{
|
||||||
Destruction = 2,
|
static auto Enum = FindObject<UEnum>("/Script/FortniteGame.EFortPickupSourceTypeFlag");
|
||||||
Container = 3,
|
return Enum;
|
||||||
AI = 4,
|
}
|
||||||
Tossed = 5,
|
|
||||||
FloorLoot = 6,
|
static inline int64 GetPlayerValue()
|
||||||
EFortPickupSourceTypeFlag_MAX = 7
|
{
|
||||||
|
static auto PlayerValue = GetEnum() ? GetEnum()->GetValue("Player") : -1;
|
||||||
|
return PlayerValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int64 GetContainerValue()
|
||||||
|
{
|
||||||
|
static auto ContainerValue = GetEnum() ? GetEnum()->GetValue("Container") : -1;
|
||||||
|
return ContainerValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int64 GetFloorLootValue()
|
||||||
|
{
|
||||||
|
static auto FloorLootValue = GetEnum() ? GetEnum()->GetValue("FloorLoot") : -1;
|
||||||
|
return FloorLootValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int64 GetOtherValue()
|
||||||
|
{
|
||||||
|
static auto OtherValue = GetEnum() ? GetEnum()->GetValue("Other") : -1;
|
||||||
|
return OtherValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int64 GetTossedValue()
|
||||||
|
{
|
||||||
|
static auto TossedValue = GetEnum() ? GetEnum()->GetValue("Tossed") : -1;
|
||||||
|
return TossedValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace EFortPickupSpawnSource
|
||||||
|
{
|
||||||
|
static inline UEnum* GetEnum()
|
||||||
|
{
|
||||||
|
static auto Enum = FindObject<UEnum>("/Script/FortniteGame.EFortPickupSpawnSource");
|
||||||
|
return Enum;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int64 GetPlayerEliminationValue()
|
||||||
|
{
|
||||||
|
static auto PlayerEliminationValue = GetEnum() ? GetEnum()->GetValue("PlayerElimination") : -1;
|
||||||
|
return PlayerEliminationValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int64 GetSupplyDropValue()
|
||||||
|
{
|
||||||
|
static auto SupplyDropValue = GetEnum() ? GetEnum()->GetValue("SupplyDrop") : -1;
|
||||||
|
return SupplyDropValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PickupCreateData
|
||||||
|
{
|
||||||
|
FFortItemEntry* ItemEntry = nullptr;
|
||||||
|
AFortPawn* PawnOwner = nullptr;
|
||||||
|
int OverrideCount = -1;
|
||||||
|
UClass* OverrideClass = nullptr;
|
||||||
|
bool bToss = false;
|
||||||
|
class AFortPickup* IgnoreCombineTarget = nullptr;
|
||||||
|
bool bRandomRotation = false;
|
||||||
|
uint8 SourceType = 0;
|
||||||
|
uint8 Source = 0;
|
||||||
|
FVector SpawnLocation = FVector(0, 0, 0);
|
||||||
|
bool bShouldFreeItemEntryWhenDeconstructed = false;
|
||||||
|
|
||||||
|
~PickupCreateData()
|
||||||
|
{
|
||||||
|
if (bShouldFreeItemEntryWhenDeconstructed)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class EFortPickupSpawnSource : uint8_t
|
enum class EFortPickupTossState : uint8
|
||||||
{
|
{
|
||||||
Unset = 0,
|
NotTossed = 0,
|
||||||
PlayerElimination = 1,
|
InProgress = 1,
|
||||||
Chest = 2,
|
AtRest = 2,
|
||||||
SupplyDrop = 3,
|
EFortPickupTossState_MAX = 3,
|
||||||
AmmoBox = 4,
|
|
||||||
Drone = 5,
|
|
||||||
ItemSpawner = 6,
|
|
||||||
EFortPickupSpawnSource_MAX = 7
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ENUM_CLASS_FLAGS(EFortPickupSourceTypeFlag)
|
|
||||||
|
|
||||||
struct FFortPickupLocationData
|
struct FFortPickupLocationData
|
||||||
{
|
{
|
||||||
AFortPawn*& GetPickupTarget()
|
AFortPawn*& GetPickupTarget()
|
||||||
@@ -43,6 +109,12 @@ struct FFortPickupLocationData
|
|||||||
return *(float*)(__int64(this) + FlyTimeOffset);
|
return *(float*)(__int64(this) + FlyTimeOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EFortPickupTossState& GetTossState()
|
||||||
|
{
|
||||||
|
static auto TossStateOffset = FindOffsetStruct("/Script/FortniteGame.FortPickupLocationData", "TossState");
|
||||||
|
return *(EFortPickupTossState*)(__int64(this) + TossStateOffset);
|
||||||
|
}
|
||||||
|
|
||||||
AFortPawn*& GetItemOwner()
|
AFortPawn*& GetItemOwner()
|
||||||
{
|
{
|
||||||
static auto ItemOwnerOffset = FindOffsetStruct("/Script/FortniteGame.FortPickupLocationData", "ItemOwner");
|
static auto ItemOwnerOffset = FindOffsetStruct("/Script/FortniteGame.FortPickupLocationData", "ItemOwner");
|
||||||
@@ -91,7 +163,7 @@ class AFortPickup : public AActor
|
|||||||
public:
|
public:
|
||||||
static inline char (*CompletePickupAnimationOriginal)(AFortPickup* Pickup);
|
static inline char (*CompletePickupAnimationOriginal)(AFortPickup* Pickup);
|
||||||
|
|
||||||
void TossPickup(FVector FinalLocation, class AFortPawn* ItemOwner, int OverrideMaxStackCount, bool bToss, EFortPickupSourceTypeFlag InPickupSourceTypeFlags, EFortPickupSpawnSource InPickupSpawnSource);
|
void TossPickup(FVector FinalLocation, class AFortPawn* ItemOwner, int OverrideMaxStackCount, bool bToss, uint8 InPickupSourceTypeFlags, uint8 InPickupSpawnSource);
|
||||||
void SpawnMovementComponent(); // BAD You probably don't wanna use unless absolutely necessary
|
void SpawnMovementComponent(); // BAD You probably don't wanna use unless absolutely necessary
|
||||||
|
|
||||||
void OnRep_PrimaryPickupItemEntry()
|
void OnRep_PrimaryPickupItemEntry()
|
||||||
@@ -118,13 +190,11 @@ public:
|
|||||||
this->ProcessEvent(OnRep_PickupLocationDataFn);
|
this->ProcessEvent(OnRep_PickupLocationDataFn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static AFortPickup* SpawnPickup(FFortItemEntry* ItemEntry, FVector Location,
|
static AFortPickup* SpawnPickup(PickupCreateData& PickupData);
|
||||||
EFortPickupSourceTypeFlag PickupSource = EFortPickupSourceTypeFlag::Other, EFortPickupSpawnSource SpawnSource = EFortPickupSpawnSource::Unset,
|
|
||||||
class AFortPawn* Pawn = nullptr, UClass* OverrideClass = nullptr, bool bToss = true, int OverrideCount = -1, AFortPickup* IgnoreCombinePickup = nullptr);
|
|
||||||
|
|
||||||
static AFortPickup* SpawnPickup(class UFortItemDefinition* ItemDef, FVector Location, int Count,
|
static AFortPickup* SpawnPickup(FFortItemEntry* ItemEntry, FVector Location,
|
||||||
EFortPickupSourceTypeFlag PickupSource = EFortPickupSourceTypeFlag::Other, EFortPickupSpawnSource SpawnSource = EFortPickupSpawnSource::Unset,
|
uint8 PickupSource = 0, uint8 SpawnSource = 0,
|
||||||
int LoadedAmmo = -1, class AFortPawn* Pawn = nullptr, UClass* OverrideClass = nullptr, bool bToss = true, AFortPickup* IgnoreCombinePickup = nullptr);
|
class AFortPawn* Pawn = nullptr, UClass* OverrideClass = nullptr, bool bToss = true, int OverrideCount = -1, AFortPickup* IgnoreCombinePickup = nullptr);
|
||||||
|
|
||||||
static void CombinePickupHook(AFortPickup* Pickup);
|
static void CombinePickupHook(AFortPickup* Pickup);
|
||||||
static char CompletePickupAnimationHook(AFortPickup* Pickup);
|
static char CompletePickupAnimationHook(AFortPickup* Pickup);
|
||||||
|
|||||||
@@ -111,8 +111,12 @@ void AFortPlayerController::DropAllItems(const std::vector<UFortItemDefinition*>
|
|||||||
if (bRemoveIfNotDroppable && !WorldItemDefinition->CanBeDropped())
|
if (bRemoveIfNotDroppable && !WorldItemDefinition->CanBeDropped())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
AFortPickup::SpawnPickup(WorldItemDefinition, Location, ItemEntry->GetCount(), EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset,
|
PickupCreateData CreateData;
|
||||||
ItemEntry->GetLoadedAmmo());
|
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(WorldItemDefinition, ItemEntry->GetCount(), ItemEntry->GetLoadedAmmo());
|
||||||
|
CreateData.SpawnLocation = Location;
|
||||||
|
CreateData.SourceType = EFortPickupSourceTypeFlag::GetPlayerValue();
|
||||||
|
|
||||||
|
AFortPickup::SpawnPickup(CreateData);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& Pair : GuidAndCountsToRemove)
|
for (auto& Pair : GuidAndCountsToRemove)
|
||||||
@@ -587,8 +591,12 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame*
|
|||||||
{
|
{
|
||||||
auto Entry = ItemCollection->GetOutputItemEntry()->AtPtr(z, FFortItemEntry::GetStructSize());
|
auto Entry = ItemCollection->GetOutputItemEntry()->AtPtr(z, FFortItemEntry::GetStructSize());
|
||||||
|
|
||||||
AFortPickup::SpawnPickup(Entry->GetItemDefinition(), LocationToSpawnLoot, Entry->GetCount(),
|
PickupCreateData CreateData;
|
||||||
EFortPickupSourceTypeFlag::Other, EFortPickupSpawnSource::Unset, Entry->GetLoadedAmmo(), PlayerController->GetMyFortPawn());
|
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(Entry->GetItemDefinition(), Entry->GetCount(), Entry->GetLoadedAmmo());
|
||||||
|
CreateData.SpawnLocation = LocationToSpawnLoot;
|
||||||
|
CreateData.PawnOwner = PlayerController->GetMyFortPawn(); // hmm
|
||||||
|
|
||||||
|
AFortPickup::SpawnPickup(CreateData);
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto bCurrentInteractionSuccessOffset = ItemCollector->GetOffset("bCurrentInteractionSuccess", false);
|
static auto bCurrentInteractionSuccessOffset = ItemCollector->GetOffset("bCurrentInteractionSuccess", false);
|
||||||
@@ -840,6 +848,8 @@ void AFortPlayerController::ServerCreateBuildingActorHook(UObject* Context, FFra
|
|||||||
|
|
||||||
bool bBuildFree = PlayerController->DoesBuildFree();
|
bool bBuildFree = PlayerController->DoesBuildFree();
|
||||||
|
|
||||||
|
LOG_INFO(LogDev, "MatInstance->GetItemEntry()->GetCount(): {}", MatInstance->GetItemEntry()->GetCount());
|
||||||
|
|
||||||
bool bShouldDestroy = MatInstance && MatInstance->GetItemEntry() ? MatInstance->GetItemEntry()->GetCount() < 10 : true;
|
bool bShouldDestroy = MatInstance && MatInstance->GetItemEntry() ? MatInstance->GetItemEntry()->GetCount() < 10 : true;
|
||||||
|
|
||||||
if (bShouldDestroy && !bBuildFree)
|
if (bShouldDestroy && !bBuildFree)
|
||||||
@@ -950,6 +960,7 @@ void AFortPlayerController::ServerAttemptInventoryDropHook(AFortPlayerController
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO If the player is in a vehicle and has a vehicle weapon, don't let them drop.
|
||||||
|
|
||||||
auto WorldInventory = PlayerController->GetWorldInventory();
|
auto WorldInventory = PlayerController->GetWorldInventory();
|
||||||
auto ReplicatedEntry = WorldInventory->FindReplicatedEntry(ItemGuid);
|
auto ReplicatedEntry = WorldInventory->FindReplicatedEntry(ItemGuid);
|
||||||
@@ -966,8 +977,25 @@ 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 (auto GadgetItemDefintiion = Cast<UFortGadgetItemDefinition>(ItemDefinition))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < GadgetItemDefintiion->GetTrackedAttributes().Num(); i++)
|
||||||
|
{
|
||||||
|
LOG_INFO(LogDev, "[{}] TrackedAttribute Attribute Name {}", i, GadgetItemDefintiion->GetTrackedAttributes().at(i).GetAttributePropertyName());
|
||||||
|
|
||||||
|
PadHexA8 StateValue{}; // Alloc<FFortItemEntryStateValue>(FFortItemEntryStateValue::GetStructSize(), true);
|
||||||
|
((FFortItemEntryStateValue*)&StateValue)->GetIntValue() = 1;
|
||||||
|
((FFortItemEntryStateValue*)&StateValue)->GetStateType() = EFortItemEntryState::GenericAttributeValueSet;
|
||||||
|
((FFortItemEntryStateValue*)&StateValue)->GetNameValue() = FName(0);
|
||||||
|
|
||||||
|
ReplicatedEntry->GetStateValues().AddPtr((FFortItemEntryStateValue*)&StateValue, FFortItemEntryStateValue::GetStructSize());
|
||||||
|
|
||||||
|
ReplicatedEntry->GetGenericAttributeValues().Add(9);
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
auto Pickup = AFortPickup::SpawnPickup(ReplicatedEntry, Pawn->GetActorLocation(),
|
auto Pickup = AFortPickup::SpawnPickup(ReplicatedEntry, Pawn->GetActorLocation(),
|
||||||
EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset, Pawn, nullptr, true, Count);
|
EFortPickupSourceTypeFlag::GetPlayerValue(), 0, Pawn, nullptr, true, Count);
|
||||||
|
|
||||||
if (!Pickup)
|
if (!Pickup)
|
||||||
return;
|
return;
|
||||||
@@ -1338,8 +1366,13 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
|
|||||||
if (!ShouldBeDropped)
|
if (!ShouldBeDropped)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
AFortPickup::SpawnPickup(WorldItemDefinition, DeathLocation, ItemEntry->GetCount(), EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::PlayerElimination,
|
PickupCreateData CreateData;
|
||||||
ItemEntry->GetLoadedAmmo());
|
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(WorldItemDefinition, ItemEntry->GetCount(), ItemEntry->GetLoadedAmmo());
|
||||||
|
CreateData.SourceType = EFortPickupSourceTypeFlag::GetPlayerValue();
|
||||||
|
CreateData.Source = EFortPickupSpawnSource::GetPlayerEliminationValue();
|
||||||
|
CreateData.SpawnLocation = DeathLocation;
|
||||||
|
|
||||||
|
AFortPickup::SpawnPickup(CreateData);
|
||||||
|
|
||||||
GuidAndCountsToRemove.push_back({ ItemEntry->GetItemGuid(), ItemEntry->GetCount() });
|
GuidAndCountsToRemove.push_back({ ItemEntry->GetItemGuid(), ItemEntry->GetCount() });
|
||||||
// WorldInventory->RemoveItem(ItemEntry->GetItemGuid(), nullptr, ItemEntry->GetCount());
|
// WorldInventory->RemoveItem(ItemEntry->GetItemGuid(), nullptr, ItemEntry->GetCount());
|
||||||
@@ -1433,29 +1466,39 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
|
|||||||
{
|
{
|
||||||
// wtf
|
// wtf
|
||||||
|
|
||||||
auto AllPlayerStates = UGameplayStatics::GetAllActorsOfClass(GetWorld(), AFortPlayerStateAthena::StaticClass());
|
if (GameState->GetGamePhase() > EAthenaGamePhase::Warmup)
|
||||||
|
|
||||||
bool bDidSomeoneWin = AllPlayerStates.Num() == 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < AllPlayerStates.Num(); i++)
|
|
||||||
{
|
{
|
||||||
if (((AFortPlayerStateAthena*)AllPlayerStates.at(i))->GetPlace() <= 1)
|
auto AllPlayerStates = UGameplayStatics::GetAllActorsOfClass(GetWorld(), AFortPlayerStateAthena::StaticClass());
|
||||||
|
|
||||||
|
bool bDidSomeoneWin = AllPlayerStates.Num() == 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < AllPlayerStates.Num(); i++)
|
||||||
{
|
{
|
||||||
bDidSomeoneWin = true;
|
auto CurrentPlayerState = (AFortPlayerStateAthena*)AllPlayerStates.at(i);
|
||||||
break;
|
|
||||||
|
if (CurrentPlayerState->GetPlace() <= 1)
|
||||||
|
{
|
||||||
|
bDidSomeoneWin = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO(LogDev, "bDidSomeoneWin: {}", bDidSomeoneWin);
|
||||||
|
|
||||||
|
// if (GameState->GetGamePhase() == EAthenaGamePhase::EndGame)
|
||||||
|
if (bDidSomeoneWin)
|
||||||
|
{
|
||||||
|
CreateThread(0, 0, RestartThread, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO(LogDev, "bDidSomeoneWin: {}", bDidSomeoneWin);
|
|
||||||
|
|
||||||
// if (GameState->GetGamePhase() == EAthenaGamePhase::EndGame)
|
|
||||||
if (bDidSomeoneWin)
|
|
||||||
{
|
|
||||||
CreateThread(0, 0, RestartThread, 0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DeadPlayerState->IsBot())
|
||||||
|
{
|
||||||
|
// AllPlayerBotsToTick.
|
||||||
|
}
|
||||||
|
|
||||||
return ClientOnPawnDiedOriginal(PlayerController, DeathReport);
|
return ClientOnPawnDiedOriginal(PlayerController, DeathReport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -108,6 +108,20 @@ public:
|
|||||||
return NewAndModifiedInstances.first.size() > 0 ? NewAndModifiedInstances.first[0] : nullptr;
|
return NewAndModifiedInstances.first.size() > 0 ? NewAndModifiedInstances.first[0] : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TSet<FGuid>& GetGadgetTrackedAttributeItemInstanceIds() // actually in zone
|
||||||
|
{
|
||||||
|
static auto GadgetTrackedAttributeItemInstanceIdsOffset = GetOffset("GadgetTrackedAttributeItemInstanceIds");
|
||||||
|
return Get<TSet<FGuid>>(GadgetTrackedAttributeItemInstanceIdsOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsPlayingEmote()
|
||||||
|
{
|
||||||
|
static auto IsPlayingEmoteFn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerController.IsPlayingEmote");
|
||||||
|
bool Ret;
|
||||||
|
this->ProcessEvent(IsPlayingEmoteFn, &Ret);
|
||||||
|
return Ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool& ShouldTryPickupSwap()
|
bool& ShouldTryPickupSwap()
|
||||||
{
|
{
|
||||||
static auto bTryPickupSwapOffset = GetOffset("bTryPickupSwap");
|
static auto bTryPickupSwapOffset = GetOffset("bTryPickupSwap");
|
||||||
|
|||||||
@@ -105,6 +105,9 @@ void AFortPlayerControllerAthena::EndGhostModeHook(AFortPlayerControllerAthena*
|
|||||||
auto PickaxeInstance = PlayerController->AddPickaxeToInventory();
|
auto PickaxeInstance = PlayerController->AddPickaxeToInventory();
|
||||||
WorldInventory->Update();
|
WorldInventory->Update();
|
||||||
|
|
||||||
|
WorldInventory->ForceNetUpdate();
|
||||||
|
PlayerController->ForceNetUpdate();
|
||||||
|
|
||||||
if (PickaxeInstance)
|
if (PickaxeInstance)
|
||||||
{
|
{
|
||||||
PlayerController->ClientEquipItem(PickaxeInstance->GetItemEntry()->GetItemGuid(), true);
|
PlayerController->ClientEquipItem(PickaxeInstance->GetItemEntry()->GetItemGuid(), true);
|
||||||
|
|||||||
@@ -6,7 +6,10 @@
|
|||||||
|
|
||||||
FFortAthenaLoadout* AFortPlayerPawn::GetCosmeticLoadout()
|
FFortAthenaLoadout* AFortPlayerPawn::GetCosmeticLoadout()
|
||||||
{
|
{
|
||||||
static auto CosmeticLoadoutOffset = GetOffset("CosmeticLoadout");
|
static auto CosmeticLoadoutOffset = GetOffset("CosmeticLoadout", false);
|
||||||
|
|
||||||
|
if (CosmeticLoadoutOffset == -1)
|
||||||
|
CosmeticLoadoutOffset = GetOffset("CustomizationLoadout");
|
||||||
|
|
||||||
if (CosmeticLoadoutOffset == -1)
|
if (CosmeticLoadoutOffset == -1)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@@ -26,6 +26,20 @@ public:
|
|||||||
return Get<int>(PlaceOffset);
|
return Get<int>(PlaceOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsInAircraft()
|
||||||
|
{
|
||||||
|
static auto bInAircraftOffset = GetOffset("bInAircraft");
|
||||||
|
static auto bInAircraftFieldMask = GetFieldMask(GetProperty("bInAircraft"));
|
||||||
|
return ReadBitfieldValue(bInAircraftOffset, bInAircraftFieldMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasThankedBusDriver()
|
||||||
|
{
|
||||||
|
static auto bThankedBusDriverOffset = GetOffset("bThankedBusDriver");
|
||||||
|
static auto bThankedBusDriverFieldMask = GetFieldMask(GetProperty("bThankedBusDriver"));
|
||||||
|
return ReadBitfieldValue(bThankedBusDriverOffset, bThankedBusDriverFieldMask);
|
||||||
|
}
|
||||||
|
|
||||||
void ClientReportKill(AFortPlayerStateAthena* Player)
|
void ClientReportKill(AFortPlayerStateAthena* Player)
|
||||||
{
|
{
|
||||||
static auto ClientReportKillFn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerStateAthena.ClientReportKill");
|
static auto ClientReportKillFn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerStateAthena.ClientReportKill");
|
||||||
|
|||||||
@@ -23,9 +23,39 @@ UClass* AGameModeBase::GetDefaultPawnClassForController(AController* InControlle
|
|||||||
return AGameModeBase_GetDefaultPawnClassForController_Params.ReturnValue;
|
return AGameModeBase_GetDefaultPawnClassForController_Params.ReturnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AGameModeBase::ChangeName(AController* Controller, const FString& NewName, bool bNameChange)
|
||||||
|
{
|
||||||
|
static auto ChangeNameFn = FindObject<UFunction>("/Script/Engine.GameModeBase.ChangeName");
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
AController* Controller; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
struct FString NewName; // (Parm, ZeroConstructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
bool bNameChange; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
} AGameModeBase_ChangeName_Params{ Controller, NewName, bNameChange };
|
||||||
|
|
||||||
|
this->ProcessEvent(ChangeNameFn, &AGameModeBase_ChangeName_Params);
|
||||||
|
}
|
||||||
|
|
||||||
|
AActor* AGameModeBase::K2_FindPlayerStart(AController* Player, FString IncomingName)
|
||||||
|
{
|
||||||
|
static auto K2_FindPlayerStartFn = FindObject<UFunction>("/Script/Engine.GameModeBase.K2_FindPlayerStart");
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
AController* Player; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
FString IncomingName; // (Parm, ZeroConstructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
AActor* ReturnValue; // (Parm, OutParm, ZeroConstructor, ReturnParm, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
} AGameModeBase_K2_FindPlayerStart_Params{ Player, IncomingName };
|
||||||
|
|
||||||
|
this->ProcessEvent(K2_FindPlayerStartFn, &AGameModeBase_K2_FindPlayerStart_Params);
|
||||||
|
|
||||||
|
return AGameModeBase_K2_FindPlayerStart_Params.ReturnValue;
|
||||||
|
}
|
||||||
|
|
||||||
APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AController* NewPlayer, AActor* StartSpot)
|
APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AController* NewPlayer, AActor* StartSpot)
|
||||||
{
|
{
|
||||||
LOG_INFO(LogDev, "SpawnDefaultPawnFor: 0x{:x}!", __int64(_ReturnAddress()) - __int64(GetModuleHandleW(0)));
|
// LOG_INFO(LogDev, "SpawnDefaultPawnFor: 0x{:x}!", __int64(_ReturnAddress()) - __int64(GetModuleHandleW(0)));
|
||||||
|
|
||||||
// auto PawnClass = GameMode->GetDefaultPawnClassForController(NewPlayer);
|
// auto PawnClass = GameMode->GetDefaultPawnClassForController(NewPlayer);
|
||||||
// LOG_INFO(LogDev, "PawnClass: {}", PawnClass->GetFullName());
|
// LOG_INFO(LogDev, "PawnClass: {}", PawnClass->GetFullName());
|
||||||
|
|||||||
@@ -4,11 +4,14 @@
|
|||||||
|
|
||||||
#include "Controller.h"
|
#include "Controller.h"
|
||||||
#include "Pawn.h"
|
#include "Pawn.h"
|
||||||
|
#include "UnrealString.h"
|
||||||
|
|
||||||
class AGameModeBase : public AActor // AInfo
|
class AGameModeBase : public AActor // AInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UClass* GetDefaultPawnClassForController(AController* InController);
|
UClass* GetDefaultPawnClassForController(AController* InController);
|
||||||
|
void ChangeName(AController* Controller, const FString& NewName, bool bNameChange);
|
||||||
|
AActor* K2_FindPlayerStart(AController* Player, FString IncomingName);
|
||||||
|
|
||||||
static APawn* SpawnDefaultPawnForHook(AGameModeBase* GameMode, AController* NewPlayer, AActor* StartSpot);
|
static APawn* SpawnDefaultPawnForHook(AGameModeBase* GameMode, AController* NewPlayer, AActor* StartSpot);
|
||||||
};
|
};
|
||||||
@@ -5,6 +5,73 @@
|
|||||||
|
|
||||||
#include "reboot.h"
|
#include "reboot.h"
|
||||||
|
|
||||||
|
enum class EDrawDebugTrace : uint8_t
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
ForOneFrame = 1,
|
||||||
|
ForDuration = 2,
|
||||||
|
Persistent = 3,
|
||||||
|
EDrawDebugTrace_MAX = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ETraceTypeQuery : uint8_t
|
||||||
|
{
|
||||||
|
TraceTypeQuery1 = 0,
|
||||||
|
TraceTypeQuery2 = 1,
|
||||||
|
TraceTypeQuery3 = 2,
|
||||||
|
TraceTypeQuery4 = 3,
|
||||||
|
TraceTypeQuery5 = 4,
|
||||||
|
TraceTypeQuery6 = 5,
|
||||||
|
TraceTypeQuery7 = 6,
|
||||||
|
TraceTypeQuery8 = 7,
|
||||||
|
TraceTypeQuery9 = 8,
|
||||||
|
TraceTypeQuery10 = 9,
|
||||||
|
TraceTypeQuery11 = 10,
|
||||||
|
TraceTypeQuery12 = 11,
|
||||||
|
TraceTypeQuery13 = 12,
|
||||||
|
TraceTypeQuery14 = 13,
|
||||||
|
TraceTypeQuery15 = 14,
|
||||||
|
TraceTypeQuery16 = 15,
|
||||||
|
TraceTypeQuery17 = 16,
|
||||||
|
TraceTypeQuery18 = 17,
|
||||||
|
TraceTypeQuery19 = 18,
|
||||||
|
TraceTypeQuery20 = 19,
|
||||||
|
TraceTypeQuery21 = 20,
|
||||||
|
TraceTypeQuery22 = 21,
|
||||||
|
TraceTypeQuery23 = 22,
|
||||||
|
TraceTypeQuery24 = 23,
|
||||||
|
TraceTypeQuery25 = 24,
|
||||||
|
TraceTypeQuery26 = 25,
|
||||||
|
TraceTypeQuery27 = 26,
|
||||||
|
TraceTypeQuery28 = 27,
|
||||||
|
TraceTypeQuery29 = 28,
|
||||||
|
TraceTypeQuery30 = 29,
|
||||||
|
TraceTypeQuery31 = 30,
|
||||||
|
TraceTypeQuery32 = 31,
|
||||||
|
TraceTypeQuery_MAX = 32,
|
||||||
|
ETraceTypeQuery_MAX = 33
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FLinearColor
|
||||||
|
{
|
||||||
|
float R; // 0x0000(0x0004) (Edit, BlueprintVisible, ZeroConstructor, SaveGame, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
float G; // 0x0004(0x0004) (Edit, BlueprintVisible, ZeroConstructor, SaveGame, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
float B; // 0x0008(0x0004) (Edit, BlueprintVisible, ZeroConstructor, SaveGame, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
float A; // 0x000C(0x0004) (Edit, BlueprintVisible, ZeroConstructor, SaveGame, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
|
||||||
|
inline FLinearColor()
|
||||||
|
: R(0), G(0), B(0), A(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
inline FLinearColor(float r, float g, float b, float a)
|
||||||
|
: R(r),
|
||||||
|
G(g),
|
||||||
|
B(b),
|
||||||
|
A(a)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class UKismetSystemLibrary : public UObject
|
class UKismetSystemLibrary : public UObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -35,4 +102,109 @@ public:
|
|||||||
|
|
||||||
KismetSystemLibrary->ProcessEvent(fn, &UKismetSystemLibrary_ExecuteConsoleCommand_Params);
|
KismetSystemLibrary->ProcessEvent(fn, &UKismetSystemLibrary_ExecuteConsoleCommand_Params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool LineTraceSingle(UObject* WorldContextObject, FVector Start, FVector End, ETraceTypeQuery TraceChannel, bool bTraceComplex,
|
||||||
|
TArray<AActor*> ActorsToIgnore, EDrawDebugTrace DrawDebugType, bool bIgnoreSelf, FLinearColor TraceColor, FLinearColor TraceHitColor,
|
||||||
|
float DrawTime, FHitResult** OutHit)
|
||||||
|
{
|
||||||
|
static auto LineTraceSingleFn = FindObject<UFunction>("/Script/Engine.KismetSystemLibrary.LineTraceSingle");
|
||||||
|
|
||||||
|
if (!LineTraceSingleFn)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
struct UKismetSystemLibrary_LineTraceSingle_Params
|
||||||
|
{
|
||||||
|
UObject* WorldContextObject; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
FVector Start; // (ConstParm, Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
FVector End; // (ConstParm, Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
ETraceTypeQuery TraceChannel; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
bool bTraceComplex; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
TArray<AActor*> ActorsToIgnore; // (ConstParm, Parm, OutParm, ZeroConstructor, ReferenceParm, NativeAccessSpecifierPublic)
|
||||||
|
EDrawDebugTrace DrawDebugType; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
FHitResult OutHit; // (Parm, OutParm, IsPlainOldData, NoDestructor, ContainsInstancedReference, NativeAccessSpecifierPublic)
|
||||||
|
bool bIgnoreSelf; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
FLinearColor TraceColor; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, AdvancedDisplay, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
FLinearColor TraceHitColor; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, AdvancedDisplay, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
float DrawTime; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, AdvancedDisplay, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
bool ReturnValue; // (Parm, OutParm, ZeroConstructor, ReturnParm, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
};
|
||||||
|
|
||||||
|
static auto ReturnValueOffset = FindOffsetStruct("/Script/Engine.KismetSystemLibrary.LineTraceSingle", "ReturnValue");
|
||||||
|
static auto OutHitOffset = FindOffsetStruct("/Script/Engine.KismetSystemLibrary.LineTraceSingle", "OutHit");
|
||||||
|
static auto bIgnoreSelfOffset = FindOffsetStruct("/Script/Engine.KismetSystemLibrary.LineTraceSingle", "bIgnoreSelf");
|
||||||
|
|
||||||
|
static auto ParamsSize = LineTraceSingleFn->GetPropertiesSize();
|
||||||
|
auto Params = Alloc(ParamsSize);
|
||||||
|
|
||||||
|
((UKismetSystemLibrary_LineTraceSingle_Params*)Params)->WorldContextObject = WorldContextObject;
|
||||||
|
((UKismetSystemLibrary_LineTraceSingle_Params*)Params)->Start = Start;
|
||||||
|
((UKismetSystemLibrary_LineTraceSingle_Params*)Params)->End = End;
|
||||||
|
((UKismetSystemLibrary_LineTraceSingle_Params*)Params)->TraceChannel = TraceChannel;
|
||||||
|
((UKismetSystemLibrary_LineTraceSingle_Params*)Params)->bTraceComplex = bTraceComplex;
|
||||||
|
*(bool*)(__int64(Params) + bIgnoreSelfOffset) = bIgnoreSelf;
|
||||||
|
|
||||||
|
static auto KismetSystemLibrary = FindObject("/Script/Engine.Default__KismetSystemLibrary");
|
||||||
|
KismetSystemLibrary->ProcessEvent(LineTraceSingleFn, Params);
|
||||||
|
|
||||||
|
if (OutHit)
|
||||||
|
*OutHit = (FHitResult*)(__int64(Params) + OutHitOffset);
|
||||||
|
|
||||||
|
return *(bool*)(__int64(Params) + ReturnValueOffset);
|
||||||
|
|
||||||
|
// free params frfr
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool LineTraceSingleByProfile(UObject* WorldContextObject, const FVector& Start, const FVector& End, FName ProfileName, bool bTraceComplex,
|
||||||
|
const TArray<AActor*>& ActorsToIgnore, EDrawDebugTrace DrawDebugType, FHitResult** OutHit, bool bIgnoreSelf, const FLinearColor& TraceColor,
|
||||||
|
const FLinearColor& TraceHitColor, float DrawTime)
|
||||||
|
{
|
||||||
|
auto LineTraceSingleByProfileFn = FindObject<UFunction>("/Script/Engine.KismetSystemLibrary.LineTraceSingleByProfile");
|
||||||
|
|
||||||
|
if (!LineTraceSingleByProfileFn)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
struct UKismetSystemLibrary_LineTraceSingleByProfile_Params
|
||||||
|
{
|
||||||
|
UObject* WorldContextObject; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
FVector Start; // (ConstParm, Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
FVector End; // (ConstParm, Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
FName ProfileName; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
bool bTraceComplex; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
TArray<AActor*> ActorsToIgnore; // (ConstParm, Parm, OutParm, ZeroConstructor, ReferenceParm, NativeAccessSpecifierPublic)
|
||||||
|
EDrawDebugTrace DrawDebugType; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
FHitResult OutHit; // (Parm, OutParm, IsPlainOldData, NoDestructor, ContainsInstancedReference, NativeAccessSpecifierPublic)
|
||||||
|
bool bIgnoreSelf; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
FLinearColor TraceColor; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, AdvancedDisplay, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
FLinearColor TraceHitColor; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, AdvancedDisplay, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
float DrawTime; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, AdvancedDisplay, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
bool ReturnValue; // (Parm, OutParm, ZeroConstructor, ReturnParm, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
};
|
||||||
|
|
||||||
|
static auto ParamSize = LineTraceSingleByProfileFn->GetPropertiesSize();
|
||||||
|
auto Params = Alloc(ParamSize);
|
||||||
|
|
||||||
|
static auto WorldContextObjectOffset = FindOffsetStruct("/Script/Engine.KismetSystemLibrary.LineTraceSingleByProfile", "WorldContextObject");
|
||||||
|
static auto StartOffset = FindOffsetStruct("/Script/Engine.KismetSystemLibrary.LineTraceSingleByProfile", "Start");
|
||||||
|
static auto EndOffset = FindOffsetStruct("/Script/Engine.KismetSystemLibrary.LineTraceSingleByProfile", "End");
|
||||||
|
static auto ProfileNameOffset = FindOffsetStruct("/Script/Engine.KismetSystemLibrary.LineTraceSingleByProfile", "ProfileName");
|
||||||
|
static auto bTraceComplexOffset = FindOffsetStruct("/Script/Engine.KismetSystemLibrary.LineTraceSingleByProfile", "bTraceComplex");
|
||||||
|
static auto ReturnValueOffset = FindOffsetStruct("/Script/Engine.KismetSystemLibrary.LineTraceSingleByProfile", "ReturnValue");
|
||||||
|
static auto OutHitOffset = FindOffsetStruct("/Script/Engine.KismetSystemLibrary.LineTraceSingleByProfile", "OutHit");
|
||||||
|
static auto bIgnoreSelfOffset = FindOffsetStruct("/Script/Engine.KismetSystemLibrary.LineTraceSingleByProfile", "bIgnoreSelf");
|
||||||
|
|
||||||
|
*(UObject**)(__int64(Params) + WorldContextObjectOffset) = WorldContextObject;
|
||||||
|
*(FVector*)(__int64(Params) + StartOffset) = Start;
|
||||||
|
*(FVector*)(__int64(Params) + EndOffset) = End;
|
||||||
|
*(FName*)(__int64(Params) + ProfileNameOffset) = ProfileName;
|
||||||
|
*(bool*)(__int64(Params) + bTraceComplexOffset) = bTraceComplex;
|
||||||
|
*(bool*)(__int64(Params) + bIgnoreSelfOffset) = bIgnoreSelf;
|
||||||
|
|
||||||
|
static auto KismetSystemLibrary = FindObject("/Script/Engine.Default__KismetSystemLibrary");
|
||||||
|
KismetSystemLibrary->ProcessEvent(LineTraceSingleByProfileFn, Params);
|
||||||
|
|
||||||
|
if (OutHit)
|
||||||
|
*OutHit = (FHitResult*)(__int64(Params) + OutHitOffset);
|
||||||
|
|
||||||
|
return *(bool*)(__int64(Params) + ReturnValueOffset);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
@@ -18,5 +18,27 @@ struct FUniqueNetIdRepl // : public FUniqueNetIdWrapper
|
|||||||
return Size;
|
return Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TArray<uint8>& GetReplicationBytes()
|
||||||
|
{
|
||||||
|
static auto ReplicationBytesOffset = FindOffsetStruct("/Script/Engine.UniqueNetIdRepl", "ReplicationBytes");
|
||||||
|
return *(TArray<uint8>*)(__int64(this) + ReplicationBytesOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CopyFromAnotherUniqueId(FUniqueNetIdRepl* OtherUniqueId)
|
||||||
|
{
|
||||||
|
CopyStruct(this, OtherUniqueId, GetSizeOfStruct(), GetStruct());
|
||||||
|
|
||||||
|
auto& ReplicationBytes = GetReplicationBytes();
|
||||||
|
|
||||||
|
ReplicationBytes.Free();
|
||||||
|
|
||||||
|
// Now this is what we call 1 to 1 array copying.
|
||||||
|
|
||||||
|
for (int i = 0; i < OtherUniqueId->GetReplicationBytes().Num(); i++)
|
||||||
|
{
|
||||||
|
ReplicationBytes.Add(OtherUniqueId->GetReplicationBytes().at(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* bool IsEqual(FUniqueNetIdRepl* Other) */
|
/* bool IsEqual(FUniqueNetIdRepl* Other) */
|
||||||
};
|
};
|
||||||
@@ -3,6 +3,12 @@
|
|||||||
|
|
||||||
#include "reboot.h"
|
#include "reboot.h"
|
||||||
|
|
||||||
|
void APlayerController::ServerChangeName(FString& S)
|
||||||
|
{
|
||||||
|
static auto ServerChangeNameFn = FindObject<UFunction>("/Script/Engine.PlayerController.ServerChangeName");
|
||||||
|
this->ProcessEvent(ServerChangeNameFn, &S);
|
||||||
|
}
|
||||||
|
|
||||||
UCheatManager*& APlayerController::SpawnCheatManager(UClass* CheatManagerClass)
|
UCheatManager*& APlayerController::SpawnCheatManager(UClass* CheatManagerClass)
|
||||||
{
|
{
|
||||||
GetCheatManager() = UGameplayStatics::SpawnObject<UCheatManager>(CheatManagerClass, this, true);
|
GetCheatManager() = UGameplayStatics::SpawnObject<UCheatManager>(CheatManagerClass, this, true);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "Controller.h"
|
#include "Controller.h"
|
||||||
#include "CheatManager.h"
|
#include "CheatManager.h"
|
||||||
|
|
||||||
|
#include "UnrealString.h"
|
||||||
#include "Rotator.h"
|
#include "Rotator.h"
|
||||||
|
|
||||||
class APlayerController : public AController
|
class APlayerController : public AController
|
||||||
@@ -39,6 +40,7 @@ public:
|
|||||||
return this->Get<UCheatManager*>(CheatManagerOffset);
|
return this->Get<UCheatManager*>(CheatManagerOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServerChangeName(FString& S);
|
||||||
UCheatManager*& SpawnCheatManager(UClass* CheatManagerClass);
|
UCheatManager*& SpawnCheatManager(UClass* CheatManagerClass);
|
||||||
FRotator GetControlRotation();
|
FRotator GetControlRotation();
|
||||||
void Possess(class APawn* Pawn);
|
void Possess(class APawn* Pawn);
|
||||||
|
|||||||
@@ -29,3 +29,23 @@ int& APlayerState::GetPlayerID()
|
|||||||
|
|
||||||
return Get<int>(PlayerIDOffset);
|
return Get<int>(PlayerIDOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool APlayerState::IsBot()
|
||||||
|
{
|
||||||
|
static auto bIsABotOffset = GetOffset("bIsABot");
|
||||||
|
static auto bIsABotFieldMask = GetFieldMask(GetProperty("bIsABot"));
|
||||||
|
return ReadBitfieldValue(bIsABotOffset, bIsABotFieldMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void APlayerState::SetIsBot(bool NewValue)
|
||||||
|
{
|
||||||
|
static auto bIsABotOffset = GetOffset("bIsABot");
|
||||||
|
static auto bIsABotFieldMask = GetFieldMask(GetProperty("bIsABot"));
|
||||||
|
return SetBitfieldValue(bIsABotOffset, bIsABotFieldMask, NewValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void APlayerState::OnRep_PlayerName()
|
||||||
|
{
|
||||||
|
static auto OnRep_PlayerNameFn = FindObject<UFunction>("/Script/Engine.PlayerState.OnRep_PlayerName");
|
||||||
|
this->ProcessEvent(OnRep_PlayerNameFn);
|
||||||
|
}
|
||||||
@@ -9,4 +9,7 @@ class APlayerState : public AActor
|
|||||||
public:
|
public:
|
||||||
FString GetPlayerName();
|
FString GetPlayerName();
|
||||||
int& GetPlayerID(); // for future me to deal with (this is a short on some versions).
|
int& GetPlayerID(); // for future me to deal with (this is a short on some versions).
|
||||||
|
bool IsBot();
|
||||||
|
void SetIsBot(bool NewValue);
|
||||||
|
void OnRep_PlayerName();
|
||||||
};
|
};
|
||||||
@@ -274,6 +274,7 @@
|
|||||||
<ClInclude Include="BGA.h" />
|
<ClInclude Include="BGA.h" />
|
||||||
<ClInclude Include="BinaryHeap.h" />
|
<ClInclude Include="BinaryHeap.h" />
|
||||||
<ClInclude Include="BitArray.h" />
|
<ClInclude Include="BitArray.h" />
|
||||||
|
<ClInclude Include="bots.h" />
|
||||||
<ClInclude Include="BuildingActor.h" />
|
<ClInclude Include="BuildingActor.h" />
|
||||||
<ClInclude Include="BuildingContainer.h" />
|
<ClInclude Include="BuildingContainer.h" />
|
||||||
<ClInclude Include="BuildingFoundation.h" />
|
<ClInclude Include="BuildingFoundation.h" />
|
||||||
|
|||||||
@@ -712,9 +712,6 @@
|
|||||||
<ClInclude Include="AttributeSet.h">
|
<ClInclude Include="AttributeSet.h">
|
||||||
<Filter>Engine\Plugins\Runtime\GameplayAbilities\Source\GameplayAbilities\Public</Filter>
|
<Filter>Engine\Plugins\Runtime\GameplayAbilities\Source\GameplayAbilities\Public</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="gui.h">
|
|
||||||
<Filter>Reboot\Public\GUI</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="FortWeaponRangedMountedCannon.h">
|
<ClInclude Include="FortWeaponRangedMountedCannon.h">
|
||||||
<Filter>FortniteGame\Source\FortniteGame\Public\Athena\Vehicle</Filter>
|
<Filter>FortniteGame\Source\FortniteGame\Public\Athena\Vehicle</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -851,6 +848,12 @@
|
|||||||
<ClInclude Include="FortLootLevel.h">
|
<ClInclude Include="FortLootLevel.h">
|
||||||
<Filter>FortniteGame\Source\FortniteGame\Public\Items</Filter>
|
<Filter>FortniteGame\Source\FortniteGame\Public\Items</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="bots.h">
|
||||||
|
<Filter>Reboot\Public</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="gui.h">
|
||||||
|
<Filter>Reboot\Public</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="Engine">
|
<Filter Include="Engine">
|
||||||
@@ -1051,9 +1054,6 @@
|
|||||||
<Filter Include="Engine\Source\Runtime\Core\Public\Algo\Impl">
|
<Filter Include="Engine\Source\Runtime\Core\Public\Algo\Impl">
|
||||||
<UniqueIdentifier>{74e42db4-bdac-4e42-bb7e-58f1ab17b738}</UniqueIdentifier>
|
<UniqueIdentifier>{74e42db4-bdac-4e42-bb7e-58f1ab17b738}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter Include="Reboot\Public\GUI">
|
|
||||||
<UniqueIdentifier>{15a7e32e-0505-49cc-9f6a-89d3e5c865b5}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Libaries">
|
<Filter Include="Libaries">
|
||||||
<UniqueIdentifier>{c0586029-3b4a-48f9-8de9-5b48a972cb5e}</UniqueIdentifier>
|
<UniqueIdentifier>{c0586029-3b4a-48f9-8de9-5b48a972cb5e}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
|
|
||||||
MS_ALIGN(16) struct FTransform
|
MS_ALIGN(16) struct FTransform
|
||||||
{
|
{
|
||||||
FQuat Rotation; // 0x0000(0x0010) (Edit, BlueprintVisible, SaveGame, IsPlainOldData, NoDestructor, NativeAccessSpecifierPublic)
|
FQuat Rotation = FQuat(0, 0, 0, 0); // 0x0000(0x0010) (Edit, BlueprintVisible, SaveGame, IsPlainOldData, NoDestructor, NativeAccessSpecifierPublic)
|
||||||
FVector Translation; // 0x0010(0x000C) (Edit, BlueprintVisible, ZeroConstructor, SaveGame, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
FVector Translation = FVector(0, 0, 0); // 0x0010(0x000C) (Edit, BlueprintVisible, ZeroConstructor, SaveGame, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
unsigned char UnknownData00[0x4]; // 0x001C(0x0004) MISSED OFFSET
|
unsigned char UnknownData00[0x4]; // 0x001C(0x0004) MISSED OFFSET
|
||||||
FVector Scale3D; // 0x0020(0x000C) (Edit, BlueprintVisible, ZeroConstructor, SaveGame, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
FVector Scale3D = FVector(0, 0, 0); // 0x0020(0x000C) (Edit, BlueprintVisible, ZeroConstructor, SaveGame, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
unsigned char UnknownData01[0x4]; // 0x002C(0x0004) MISSED OFFSET
|
unsigned char UnknownData01[0x4]; // 0x002C(0x0004) MISSED OFFSET
|
||||||
};
|
};
|
||||||
@@ -19,12 +19,12 @@ public:
|
|||||||
|
|
||||||
struct FActorSpawnParameters
|
struct FActorSpawnParameters
|
||||||
{
|
{
|
||||||
FName Name;
|
FName Name = FName(0);
|
||||||
UObject* Template;
|
UObject* Template = nullptr;
|
||||||
UObject* Owner;
|
UObject* Owner = nullptr;
|
||||||
UObject** Instigator;
|
UObject** Instigator = nullptr;
|
||||||
UObject* OverrideLevel;
|
UObject* OverrideLevel = nullptr;
|
||||||
ESpawnActorCollisionHandlingMethod SpawnCollisionHandlingOverride;
|
ESpawnActorCollisionHandlingMethod SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::Undefined;
|
||||||
uint16 bRemoteOwned : 1;
|
uint16 bRemoteOwned : 1;
|
||||||
uint16 bNoFail : 1;
|
uint16 bNoFail : 1;
|
||||||
uint16 bDeferConstruction : 1;
|
uint16 bDeferConstruction : 1;
|
||||||
|
|||||||
248
Project Reboot 3.0/bots.h
Normal file
248
Project Reboot 3.0/bots.h
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "FortGameModeAthena.h"
|
||||||
|
#include "OnlineReplStructs.h"
|
||||||
|
#include "BuildingContainer.h"
|
||||||
|
|
||||||
|
class PlayerBot
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AFortPlayerControllerAthena* PlayerController = nullptr;
|
||||||
|
float NextJumpTime = 1.0f;
|
||||||
|
|
||||||
|
void Initialize(FTransform SpawnTransform)
|
||||||
|
{
|
||||||
|
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
||||||
|
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
|
||||||
|
|
||||||
|
static auto PawnClass = FindObject<UClass>("/Game/Athena/PlayerPawn_Athena.PlayerPawn_Athena_C");
|
||||||
|
|
||||||
|
FActorSpawnParameters PawnSpawnParameters{};
|
||||||
|
PawnSpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
|
||||||
|
|
||||||
|
PlayerController = GetWorld()->SpawnActor<AFortPlayerControllerAthena>(AFortPlayerControllerAthena::StaticClass());
|
||||||
|
AFortPlayerPawnAthena* Pawn = GetWorld()->SpawnActor<AFortPlayerPawnAthena>(PawnClass, SpawnTransform, PawnSpawnParameters);
|
||||||
|
AFortPlayerStateAthena* PlayerState = Cast<AFortPlayerStateAthena>(PlayerController->GetPlayerState());
|
||||||
|
|
||||||
|
if (!Pawn || !PlayerState)
|
||||||
|
return;
|
||||||
|
|
||||||
|
static int CurrentBotNum = 1;
|
||||||
|
|
||||||
|
auto BotNumWStr = std::to_wstring(CurrentBotNum++);
|
||||||
|
|
||||||
|
FString NewName = (L"RebootBot" + BotNumWStr).c_str();
|
||||||
|
|
||||||
|
PlayerController->ServerChangeName(NewName);
|
||||||
|
PlayerState->OnRep_PlayerName();
|
||||||
|
|
||||||
|
PlayerState->GetTeamIndex() = GameMode->Athena_PickTeamHook(GameMode, 0, PlayerController);
|
||||||
|
|
||||||
|
static auto SquadIdOffset = PlayerState->GetOffset("SquadId", false);
|
||||||
|
|
||||||
|
if (SquadIdOffset != -1)
|
||||||
|
PlayerState->GetSquadId() = PlayerState->GetTeamIndex() - 2;
|
||||||
|
|
||||||
|
PlayerState->SetIsBot(true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
static auto FortRegisteredPlayerInfoClass = FindObject<UClass>("/Script/FortniteGame.FortRegisteredPlayerInfo");
|
||||||
|
static auto MyPlayerInfoOffset = PlayerController->GetOffset("MyPlayerInfo");
|
||||||
|
PlayerController->Get(MyPlayerInfoOffset) = UGameplayStatics::SpawnObject(FortRegisteredPlayerInfoClass, PlayerController);
|
||||||
|
|
||||||
|
if (!PlayerController->Get(MyPlayerInfoOffset))
|
||||||
|
{
|
||||||
|
LOG_ERROR(LogBots, "Failed to spawn PlayerInfo!");
|
||||||
|
|
||||||
|
Pawn->K2_DestroyActor();
|
||||||
|
PlayerController->K2_DestroyActor();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& PlayerInfo = PlayerController->Get(MyPlayerInfoOffset);
|
||||||
|
|
||||||
|
static auto UniqueIdOffset = PlayerState->GetOffset("UniqueId");
|
||||||
|
static auto PlayerInfo_PlayerNameOffset = PlayerInfo->GetOffset("PlayerName");
|
||||||
|
static auto PlayerIDOffset = PlayerInfo->GetOffset("PlayerID");
|
||||||
|
PlayerInfo->GetPtr<FUniqueNetIdRepl>(PlayerIDOffset)->CopyFromAnotherUniqueId(PlayerState->GetPtr<FUniqueNetIdRepl>(UniqueIdOffset));
|
||||||
|
PlayerInfo->Get<FString>(PlayerInfo_PlayerNameOffset) = PlayerState->GetPlayerName();
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
PlayerController->Possess(Pawn);
|
||||||
|
|
||||||
|
Pawn->SetHealth(100);
|
||||||
|
Pawn->SetMaxHealth(100);
|
||||||
|
|
||||||
|
FActorSpawnParameters WorldInventorySpawnParameters{};
|
||||||
|
WorldInventorySpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
|
||||||
|
WorldInventorySpawnParameters.Owner = PlayerController;
|
||||||
|
|
||||||
|
FTransform WorldInventorySpawnTransform{};
|
||||||
|
|
||||||
|
static auto FortInventoryClass = FindObject<UClass>("/Script/FortniteGame.FortInventory"); // AFortInventory::StaticClass()
|
||||||
|
PlayerController->GetWorldInventory() = GetWorld()->SpawnActor<AFortInventory>(FortInventoryClass, WorldInventorySpawnTransform, WorldInventorySpawnParameters);
|
||||||
|
|
||||||
|
if (!PlayerController->GetWorldInventory())
|
||||||
|
{
|
||||||
|
LOG_ERROR(LogBots, "Failed to spawn WorldInventory!");
|
||||||
|
|
||||||
|
Pawn->K2_DestroyActor();
|
||||||
|
PlayerController->K2_DestroyActor();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerController->GetWorldInventory()->GetInventoryType() = EFortInventoryType::World;
|
||||||
|
|
||||||
|
static auto bHasInitializedWorldInventoryOffset = PlayerController->GetOffset("bHasInitializedWorldInventory");
|
||||||
|
PlayerController->Get<bool>(bHasInitializedWorldInventoryOffset) = true;
|
||||||
|
|
||||||
|
auto& StartingItems = GameMode->GetStartingItems();
|
||||||
|
|
||||||
|
auto PickaxeInstance = PlayerController->AddPickaxeToInventory();
|
||||||
|
|
||||||
|
for (int i = 0; i < StartingItems.Num(); i++)
|
||||||
|
{
|
||||||
|
auto& StartingItem = StartingItems.at(i);
|
||||||
|
|
||||||
|
PlayerController->GetWorldInventory()->AddItem(StartingItem.GetItem(), nullptr, StartingItem.GetCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PickaxeInstance)
|
||||||
|
{
|
||||||
|
PlayerController->ServerExecuteInventoryItemHook(PlayerController, PickaxeInstance->GetItemEntry()->GetItemGuid());
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerController->GetWorldInventory()->Update();
|
||||||
|
|
||||||
|
/* static auto HeroType = FindObject(L"/Game/Athena/Heroes/HID_115_Athena_Commando_M_CarbideBlue.HID_115_Athena_Commando_M_CarbideBlue");
|
||||||
|
|
||||||
|
static auto HeroTypeOffset = PlayerState->GetOffset("HeroType");
|
||||||
|
|
||||||
|
if (HeroTypeOffset != -1)
|
||||||
|
PlayerState->Get(HeroTypeOffset) = HeroType; */
|
||||||
|
|
||||||
|
auto PlayerAbilitySet = GetPlayerAbilitySet();
|
||||||
|
auto AbilitySystemComponent = PlayerState->GetAbilitySystemComponent();
|
||||||
|
|
||||||
|
if (PlayerAbilitySet)
|
||||||
|
{
|
||||||
|
PlayerAbilitySet->GiveToAbilitySystem(AbilitySystemComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerController->GetCosmeticLoadout()->GetCharacter() = FindObject("/Game/Athena/Items/Cosmetics/Characters/CID_263_Athena_Commando_F_MadCommander.CID_263_Athena_Commando_F_MadCommander");
|
||||||
|
Pawn->GetCosmeticLoadout()->GetCharacter() = PlayerController->GetCosmeticLoadout()->GetCharacter();
|
||||||
|
|
||||||
|
PlayerController->ApplyCosmeticLoadout();
|
||||||
|
|
||||||
|
GameState->GetPlayersLeft()++;
|
||||||
|
GameState->OnRep_PlayersLeft();
|
||||||
|
|
||||||
|
GameMode->GetAlivePlayers().Add(PlayerController);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::vector<PlayerBot> AllPlayerBotsToTick;
|
||||||
|
|
||||||
|
namespace Bots
|
||||||
|
{
|
||||||
|
static AFortPlayerControllerAthena* SpawnBot(FTransform SpawnTransform)
|
||||||
|
{
|
||||||
|
auto playerBot = PlayerBot();
|
||||||
|
playerBot.Initialize(SpawnTransform);
|
||||||
|
AllPlayerBotsToTick.push_back(playerBot);
|
||||||
|
return playerBot.PlayerController;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SpawnBotsAtPlayerStarts(int AmountOfBots)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
||||||
|
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
|
||||||
|
|
||||||
|
for (int i = 0; i < AmountOfBots; i++)
|
||||||
|
{
|
||||||
|
FTransform SpawnTransform{};
|
||||||
|
SpawnTransform.Translation = FVector(1, 1, 10000);
|
||||||
|
SpawnTransform.Rotation = FQuat();
|
||||||
|
SpawnTransform.Scale3D = FVector(1, 1, 1);
|
||||||
|
|
||||||
|
auto NewBot = SpawnBot(SpawnTransform);
|
||||||
|
auto PlayerStart = GameMode->K2_FindPlayerStart(NewBot, NewBot->GetPlayerState()->GetPlayerName()); // i dont think this works
|
||||||
|
|
||||||
|
if (!PlayerStart)
|
||||||
|
{
|
||||||
|
LOG_ERROR(LogBots, "Failed to find PlayerStart for bot!");
|
||||||
|
NewBot->GetPawn()->K2_DestroyActor();
|
||||||
|
NewBot->K2_DestroyActor();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
NewBot->TeleportTo(PlayerStart->GetActorLocation(), FRotator());
|
||||||
|
NewBot->SetCanBeDamaged(Fortnite_Version < 7); // idk lol for spawn island
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Tick()
|
||||||
|
{
|
||||||
|
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
||||||
|
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
|
||||||
|
|
||||||
|
auto AllBuildingContainers = UGameplayStatics::GetAllActorsOfClass(GetWorld(), ABuildingContainer::StaticClass());
|
||||||
|
|
||||||
|
// for (int i = 0; i < GameMode->GetAlivePlayers().Num(); i++)
|
||||||
|
for (auto& PlayerBot : AllPlayerBotsToTick)
|
||||||
|
{
|
||||||
|
auto CurrentPlayer = PlayerBot.PlayerController;
|
||||||
|
|
||||||
|
if (CurrentPlayer->IsActorBeingDestroyed())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto CurrentPawn = CurrentPlayer->GetMyFortPawn();
|
||||||
|
|
||||||
|
auto CurrentPlayerState = Cast<AFortPlayerStateAthena>(CurrentPlayer->GetPlayerState());
|
||||||
|
|
||||||
|
if (!CurrentPlayerState || !CurrentPlayerState->IsBot())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (GameState->GetGamePhase() == EAthenaGamePhase::Warmup)
|
||||||
|
{
|
||||||
|
/* if (!CurrentPlayer->IsPlayingEmote())
|
||||||
|
{
|
||||||
|
static auto AthenaDanceItemDefinitionClass = FindObject<UClass>("/Script/FortniteGame.AthenaDanceItemDefinition");
|
||||||
|
auto RandomDanceID = GetRandomObjectOfClass(AthenaDanceItemDefinitionClass);
|
||||||
|
|
||||||
|
CurrentPlayer->ServerPlayEmoteItemHook(CurrentPlayer, RandomDanceID);
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CurrentPlayerState->IsInAircraft() && !CurrentPlayerState->HasThankedBusDriver())
|
||||||
|
{
|
||||||
|
static auto ServerThankBusDriverFn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerControllerAthena.ServerThankBusDriver");
|
||||||
|
CurrentPlayer->ProcessEvent(ServerThankBusDriverFn);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CurrentPawn)
|
||||||
|
{
|
||||||
|
if (PlayerBot.NextJumpTime <= UGameplayStatics::GetTimeSeconds(GetWorld()))
|
||||||
|
{
|
||||||
|
static auto JumpFn = FindObject<UFunction>("/Script/Engine.Character.Jump");
|
||||||
|
|
||||||
|
CurrentPawn->ProcessEvent(JumpFn);
|
||||||
|
PlayerBot.NextJumpTime = UGameplayStatics::GetTimeSeconds(GetWorld()) + (rand() % 4 + 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bool bShouldJumpFromBus = CurrentPlayerState->IsInAircraft(); // TODO (Milxnor) add a random percent thing
|
||||||
|
|
||||||
|
if (bShouldJumpFromBus)
|
||||||
|
{
|
||||||
|
CurrentPlayer->ServerAttemptAircraftJumpHook(CurrentPlayer, FRotator());
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
|
||||||
|
AllBuildingContainers.Free();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,8 @@
|
|||||||
#include "FortAthenaMutator_Barrier.h"
|
#include "FortAthenaMutator_Barrier.h"
|
||||||
#include "FortWeaponMeleeItemDefinition.h"
|
#include "FortWeaponMeleeItemDefinition.h"
|
||||||
#include "builder.h"
|
#include "builder.h"
|
||||||
|
#include "FortLootPackage.h"
|
||||||
|
#include "bots.h"
|
||||||
|
|
||||||
bool IsOperator(APlayerState* PlayerState, AFortPlayerController* PlayerController)
|
bool IsOperator(APlayerState* PlayerState, AFortPlayerController* PlayerController)
|
||||||
{
|
{
|
||||||
@@ -200,6 +202,25 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg)
|
|||||||
|
|
||||||
SendMessageToConsole(PlayerController, L"Granted item!");
|
SendMessageToConsole(PlayerController, L"Granted item!");
|
||||||
}
|
}
|
||||||
|
else if (Command == "printsimulatelootdrops")
|
||||||
|
{
|
||||||
|
if (NumArgs < 1)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Please provide a LootTierGroup!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& lootTierGroup = Arguments[1];
|
||||||
|
|
||||||
|
auto LootDrops = PickLootDrops(UKismetStringLibrary::Conv_StringToName(std::wstring(lootTierGroup.begin(), lootTierGroup.end()).c_str()), true);
|
||||||
|
|
||||||
|
for (int i = 0; i < LootDrops.size(); i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SendMessageToConsole(PlayerController, L"Printed!");
|
||||||
|
}
|
||||||
else if (Command == "setpickaxe")
|
else if (Command == "setpickaxe")
|
||||||
{
|
{
|
||||||
if (NumArgs < 1)
|
if (NumArgs < 1)
|
||||||
@@ -348,7 +369,12 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto Location = Pawn->GetActorLocation();
|
auto Location = Pawn->GetActorLocation();
|
||||||
AFortPickup::SpawnPickup(WID, Location, count);
|
|
||||||
|
PickupCreateData CreateData;
|
||||||
|
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(WID, count, -1);
|
||||||
|
CreateData.SpawnLocation = Location;
|
||||||
|
|
||||||
|
AFortPickup::SpawnPickup(CreateData);
|
||||||
}
|
}
|
||||||
else if (Command == "listplayers")
|
else if (Command == "listplayers")
|
||||||
{
|
{
|
||||||
@@ -547,6 +573,60 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg)
|
|||||||
SendMessageToConsole(PlayerController, L"Not a valid class!");
|
SendMessageToConsole(PlayerController, L"Not a valid class!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (Command == "spawnbot")
|
||||||
|
{
|
||||||
|
auto Pawn = ReceivingController->GetPawn();
|
||||||
|
|
||||||
|
if (!Pawn)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"No pawn to spawn bot at!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Count = 1;
|
||||||
|
|
||||||
|
if (Arguments.size() >= 2)
|
||||||
|
{
|
||||||
|
try { Count = std::stod(Arguments[1]); }
|
||||||
|
catch (...) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr int Max = 99;
|
||||||
|
|
||||||
|
if (Count > Max)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, (std::wstring(L"You went over the limit! Only spawning ") + std::to_wstring(Max) + L".").c_str());
|
||||||
|
Count = Max;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AmountSpawned = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < Count; i++)
|
||||||
|
{
|
||||||
|
FActorSpawnParameters SpawnParameters{};
|
||||||
|
// SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
|
||||||
|
|
||||||
|
auto Loc = Pawn->GetActorLocation();
|
||||||
|
Loc.Z += 1000;
|
||||||
|
|
||||||
|
FTransform Transform;
|
||||||
|
Transform.Translation = Loc;
|
||||||
|
Transform.Scale3D = FVector(1, 1, 1);
|
||||||
|
|
||||||
|
auto NewActor = Bots::SpawnBot(Transform);
|
||||||
|
|
||||||
|
if (!NewActor)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Failed to spawn an actor!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AmountSpawned++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SendMessageToConsole(PlayerController, L"Summoned!");
|
||||||
|
}
|
||||||
else if (Command == "sethealth")
|
else if (Command == "sethealth")
|
||||||
{
|
{
|
||||||
auto Pawn = ReceivingController->GetMyFortPawn();
|
auto Pawn = ReceivingController->GetMyFortPawn();
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "KismetStringLibrary.h"
|
#include "KismetStringLibrary.h"
|
||||||
#include "DataTableFunctionLibrary.h"
|
#include "DataTableFunctionLibrary.h"
|
||||||
#include "FortPlaysetItemDefinition.h"
|
#include "FortPlaysetItemDefinition.h"
|
||||||
|
#include "gui.h"
|
||||||
|
|
||||||
static inline void (*SetZoneToIndexOriginal)(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK);
|
static inline void (*SetZoneToIndexOriginal)(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK);
|
||||||
|
|
||||||
@@ -178,6 +179,11 @@ void ProcessEventHook(UObject* Object, UFunction* Function, void* Parameters)
|
|||||||
if (!Object || !Function)
|
if (!Object || !Function)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (bEnableBotTick)
|
||||||
|
{
|
||||||
|
Bots::Tick();
|
||||||
|
}
|
||||||
|
|
||||||
if (Globals::bLogProcessEvent)
|
if (Globals::bLogProcessEvent)
|
||||||
{
|
{
|
||||||
auto FunctionName = Function->GetName(); // UKismetSystemLibrary::GetPathName(Function).ToString();
|
auto FunctionName = Function->GetName(); // UKismetSystemLibrary::GetPathName(Function).ToString();
|
||||||
|
|||||||
@@ -513,9 +513,6 @@ DWORD WINAPI Main(LPVOID)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerGameplay.EndGhostMode"),
|
|
||||||
// AFortPlayerControllerAthena::EndGhostModeHook, (PVOID*)&AFortPlayerControllerAthena::EndGhostModeOriginal, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -627,7 +627,7 @@ static inline uint64 FindUpdateTrackedAttributesLea() // kill me
|
|||||||
|
|
||||||
static inline uint64 FindCombinePickupLea() // kill me
|
static inline uint64 FindCombinePickupLea() // kill me
|
||||||
{
|
{
|
||||||
return 0;
|
// return 0;
|
||||||
|
|
||||||
/* uint64 OnRep_PickupLocationDataAddr = 0; // TODO (Idea: Find SetupCombinePickupDelegates from this).
|
/* uint64 OnRep_PickupLocationDataAddr = 0; // TODO (Idea: Find SetupCombinePickupDelegates from this).
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
#include "FortWeaponItemDefinition.h"
|
#include "FortWeaponItemDefinition.h"
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
#include "FortAthenaMutator_Heist.h"
|
#include "FortAthenaMutator_Heist.h"
|
||||||
|
#include "BGA.h"
|
||||||
|
|
||||||
#define GAME_TAB 1
|
#define GAME_TAB 1
|
||||||
#define PLAYERS_TAB 2
|
#define PLAYERS_TAB 2
|
||||||
@@ -64,6 +65,9 @@ extern inline float AutoBusStartSeconds = 60;
|
|||||||
extern inline int NumRequiredPlayersToStart = 2;
|
extern inline int NumRequiredPlayersToStart = 2;
|
||||||
extern inline bool bDebugPrintLooting = false;
|
extern inline bool bDebugPrintLooting = false;
|
||||||
extern inline bool bDebugPrintSwapping = false;
|
extern inline bool bDebugPrintSwapping = false;
|
||||||
|
extern inline bool bEnableBotTick = false;
|
||||||
|
extern inline bool bEnableCombinePickup = false;
|
||||||
|
extern inline int AmountOfBotsToSpawn = 0;
|
||||||
|
|
||||||
// THE BASE CODE IS FROM IMGUI GITHUB
|
// THE BASE CODE IS FROM IMGUI GITHUB
|
||||||
|
|
||||||
@@ -279,6 +283,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);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ImGui::Checkbox("Infinite Ammo", &Globals::bInfiniteAmmo);
|
ImGui::Checkbox("Infinite Ammo", &Globals::bInfiniteAmmo);
|
||||||
@@ -470,6 +475,11 @@ static inline void MainUI()
|
|||||||
UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), cmd, nullptr);
|
UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), cmd, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui::Button("Spawn BGAs"))
|
||||||
|
{
|
||||||
|
SpawnBGAs();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (ImGui::Button("New"))
|
if (ImGui::Button("New"))
|
||||||
{
|
{
|
||||||
@@ -897,6 +907,8 @@ static inline void MainUI()
|
|||||||
static std::string FunctionNameToDump;
|
static std::string FunctionNameToDump;
|
||||||
|
|
||||||
ImGui::Checkbox("Fill Vending Machines", &Globals::bFillVendingMachines);
|
ImGui::Checkbox("Fill Vending Machines", &Globals::bFillVendingMachines);
|
||||||
|
ImGui::Checkbox("Enable Bot Tick", &bEnableBotTick);
|
||||||
|
ImGui::Checkbox("Enable Combine Pickup", &bEnableCombinePickup);
|
||||||
ImGui::InputText("Class Name to mess with", &ClassNameToDump);
|
ImGui::InputText("Class Name to mess with", &ClassNameToDump);
|
||||||
|
|
||||||
ImGui::InputText("Function Name to mess with", &FunctionNameToDump);
|
ImGui::InputText("Function Name to mess with", &FunctionNameToDump);
|
||||||
@@ -1001,7 +1013,8 @@ static inline void PregameUI()
|
|||||||
if (!bSwitchedInitialLevel)
|
if (!bSwitchedInitialLevel)
|
||||||
ImGui::SliderInt("Seconds until load into map", &SecondsUntilTravel, 1, 100);
|
ImGui::SliderInt("Seconds until load into map", &SecondsUntilTravel, 1, 100);
|
||||||
|
|
||||||
ImGui::InputText("Playlist", &PlaylistName);
|
if (!Globals::bCreative)
|
||||||
|
ImGui::InputText("Playlist", &PlaylistName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline DWORD WINAPI GuiThread(LPVOID)
|
static inline DWORD WINAPI GuiThread(LPVOID)
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ inline void InitLogger()
|
|||||||
MakeLogger("LogReplication");
|
MakeLogger("LogReplication");
|
||||||
MakeLogger("LogMutator");
|
MakeLogger("LogMutator");
|
||||||
MakeLogger("LogVehicles");
|
MakeLogger("LogVehicles");
|
||||||
|
MakeLogger("LogBots");
|
||||||
MakeLogger("LogCosmetics");
|
MakeLogger("LogCosmetics");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -240,6 +240,14 @@ inline std::vector<T*> GetAllObjectsOfClass(UClass* Class)
|
|||||||
return Objects;
|
return Objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T = UObject>
|
||||||
|
inline T* GetRandomObjectOfClass(UClass* Class)
|
||||||
|
{
|
||||||
|
auto AllObjectsVec = GetAllObjectsOfClass<T>(Class);
|
||||||
|
|
||||||
|
return AllObjectsVec.size() > 0 ? AllObjectsVec.at(std::rand() % AllObjectsVec.size()) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
inline void* FindPropertyStruct(const std::string& StructName, const std::string& MemberName, bool bWarnIfNotFound = true)
|
inline void* FindPropertyStruct(const std::string& StructName, const std::string& MemberName, bool bWarnIfNotFound = true)
|
||||||
{
|
{
|
||||||
UObject* Struct = FindObject(StructName);
|
UObject* Struct = FindObject(StructName);
|
||||||
@@ -377,9 +385,9 @@ static void CopyStruct(void* Dest, void* Src, size_t Size, UStruct* Struct = nul
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T = __int64>
|
template <typename T = __int64>
|
||||||
static T* Alloc(size_t Size = sizeof(T), bool bUseRealloc = false)
|
static T* Alloc(size_t Size = sizeof(T), bool bUseFMemoryRealloc = false)
|
||||||
{
|
{
|
||||||
return bUseRealloc ? (T*)FMemory::Realloc(0, Size, 0) : (T*)VirtualAlloc(0, Size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
return bUseFMemoryRealloc ? (T*)FMemory::Realloc(0, Size, 0) : (T*)VirtualAlloc(0, Size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MemberOffsets
|
namespace MemberOffsets
|
||||||
|
|||||||
Reference in New Issue
Block a user