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);
|
||||
}
|
||||
|
||||
TArray<UObject*>& GetSpawnedAttributes()
|
||||
TArray<UAttributeSet*>& GetSpawnedAttributes()
|
||||
{
|
||||
static auto SpawnedAttributesOffset = GetOffset("SpawnedAttributes");
|
||||
return Get<TArray<UObject*>>(SpawnedAttributesOffset);
|
||||
return Get<TArray<UAttributeSet*>>(SpawnedAttributesOffset);
|
||||
}
|
||||
|
||||
FGameplayAbilitySpecContainer* GetActivatableAbilities()
|
||||
|
||||
@@ -52,6 +52,37 @@ public:
|
||||
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))
|
||||
{
|
||||
@@ -303,6 +334,7 @@ public:
|
||||
// VirtualFree(Data, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
Data = nullptr;
|
||||
ArrayNum = 0;
|
||||
ArrayMax = 0;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,26 @@ public:
|
||||
struct FGameplayAttribute
|
||||
{
|
||||
FString AttributeName;
|
||||
void* Attribute;
|
||||
void* Attribute; // Property
|
||||
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 "FortPickup.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");
|
||||
|
||||
@@ -24,6 +25,9 @@ void SpawnBGAs() // hahah not "proper", there's a function that we can hook and
|
||||
auto BGAConsumableSpawner = AllBGAConsumableSpawners.at(i);
|
||||
auto SpawnLocation = BGAConsumableSpawner->GetActorLocation();
|
||||
|
||||
static auto bAlignSpawnedActorsToSurfaceOffset = BGAConsumableSpawner->GetOffset("bAlignSpawnedActorsToSurface");
|
||||
const bool bAlignSpawnedActorsToSurface = BGAConsumableSpawner->Get<bool>(bAlignSpawnedActorsToSurfaceOffset);
|
||||
|
||||
FTransform SpawnTransform{};
|
||||
SpawnTransform.Translation = SpawnLocation;
|
||||
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;
|
||||
}
|
||||
|
||||
bool bDeferConstruction = false; // hm?
|
||||
bool bDeferConstruction = true; // hm?
|
||||
|
||||
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;
|
||||
|
||||
auto ConsumableActor = GetWorld()->SpawnActor<ABuildingGameplayActor>(StrongConsumableClass, SpawnTransform, SpawnParameters);
|
||||
|
||||
if (ConsumableActor)
|
||||
{
|
||||
if (bDeferConstruction)
|
||||
UGameplayStatics::FinishSpawningActor(ConsumableActor, SpawnTransform); // what
|
||||
FTransform FinalSpawnTransform = SpawnTransform;
|
||||
|
||||
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)
|
||||
{
|
||||
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
|
||||
FVector LocationToSpawnLoot = this->GetActorLocation() + this->GetActorRightVector() * 70.f + FVector{ 0, 0, 50 };
|
||||
|
||||
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());
|
||||
|
||||
@@ -20,7 +21,17 @@ bool ABuildingContainer::SpawnLoot(AFortPawn* Pawn)
|
||||
for (int i = 0; i < LootDrops.size(); 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;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include "Object.h"
|
||||
|
||||
#include "addresses.h"
|
||||
#include "UnrealString.h"
|
||||
#include "Map.h"
|
||||
|
||||
struct UField : UObject
|
||||
{
|
||||
@@ -28,3 +30,24 @@ class UFunction : public UStruct
|
||||
public:
|
||||
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();
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
#include "Object.h"
|
||||
#include "Vector.h"
|
||||
|
||||
#include "DelegateCombinations.h"
|
||||
|
||||
@@ -17,6 +18,10 @@ struct FHitResult
|
||||
{
|
||||
static class UStruct* GetStruct();
|
||||
static int GetStructSize();
|
||||
|
||||
bool IsBlockingHit();
|
||||
FVector& GetLocation();
|
||||
void CopyFromHitResult(FHitResult* Other);
|
||||
};
|
||||
|
||||
struct FTimerHandle
|
||||
|
||||
@@ -83,7 +83,7 @@ public:
|
||||
if (!AbilityClass)
|
||||
continue;
|
||||
|
||||
LOG_INFO(LogDev, "Giving AbilityClass {}", AbilityClass->GetFullName());
|
||||
// LOG_INFO(LogDev, "Giving AbilityClass {}", AbilityClass->GetFullName());
|
||||
|
||||
AbilitySystemComponent->GiveAbilityEasy(AbilityClass, SourceObject);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,14 @@ AFortPickup* AFortAthenaSupplyDrop::SpawnGameModePickupHook(UObject* Context, FF
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -67,7 +74,13 @@ AFortPickup* AFortAthenaSupplyDrop::SpawnPickupHook(UObject* Context, FFrame& St
|
||||
if (!ItemDefinition)
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,12 @@ public:
|
||||
return ReadBitfieldValue(bDestroyGadgetWhenTrackedAttributesIsZeroOffset, bDestroyGadgetWhenTrackedAttributesIsZeroFieldMask);
|
||||
}
|
||||
|
||||
TArray<FGameplayAttribute>& GetTrackedAttributes()
|
||||
{
|
||||
static auto TrackedAttributesOffset = GetOffset("TrackedAttributes");
|
||||
return Get<TArray<FGameplayAttribute>>(TrackedAttributesOffset);
|
||||
}
|
||||
|
||||
UAttributeSet* GetAttributeSet()
|
||||
{
|
||||
static auto AttributeSetOffset = this->GetOffset("AttributeSet", false);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "FortLootPackage.h"
|
||||
#include "FortPlayerPawn.h"
|
||||
#include "FortPickup.h"
|
||||
#include "bots.h"
|
||||
|
||||
#include "FortAbilitySet.h"
|
||||
#include "NetSerialization.h"
|
||||
@@ -553,6 +554,11 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
|
||||
|
||||
GetWorld()->Listen();
|
||||
|
||||
if (AmountOfBotsToSpawn != 0)
|
||||
{
|
||||
Bots::SpawnBotsAtPlayerStarts(AmountOfBotsToSpawn);
|
||||
}
|
||||
|
||||
// GameState->OnRep_CurrentPlaylistInfo();
|
||||
|
||||
// return false;
|
||||
@@ -698,6 +704,15 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
|
||||
|
||||
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
|
||||
|
||||
LOG_INFO(LogTeams, "PickTeam called!");
|
||||
@@ -939,7 +954,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
||||
|
||||
float UpZ = 50;
|
||||
|
||||
EFortPickupSourceTypeFlag SpawnFlag = EFortPickupSourceTypeFlag::Container;
|
||||
uint8 SpawnFlag = EFortPickupSourceTypeFlag::GetContainerValue();
|
||||
|
||||
bool bTest = false;
|
||||
bool bPrintWarmup = false;
|
||||
@@ -947,25 +962,22 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
||||
for (int i = 0; i < SpawnIsland_FloorLoot_Actors.Num(); 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();
|
||||
Location.Z += UpZ;
|
||||
PickupCreateData CreateData;
|
||||
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);
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
auto Pickup = AFortPickup::SpawnPickup(CreateData);
|
||||
}
|
||||
|
||||
if (!bTest)
|
||||
@@ -979,33 +991,31 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
||||
for (int i = 0; i < BRIsland_FloorLoot_Actors.Num(); i++)
|
||||
{
|
||||
ABuildingContainer* CurrentActor = (ABuildingContainer*)BRIsland_FloorLoot_Actors.at(i);
|
||||
|
||||
// CurrentActor->K2_DestroyActor();
|
||||
spawned++;
|
||||
// continue;
|
||||
|
||||
auto Location = CurrentActor->GetActorLocation();
|
||||
Location.Z += UpZ;
|
||||
|
||||
std::vector<LootDrop> LootDrops = PickLootDrops(BRIslandTierGroup, bPrint);
|
||||
|
||||
if (bPrint)
|
||||
std::cout << "\n";
|
||||
|
||||
if (LootDrops.size())
|
||||
for (auto& LootDrop : LootDrops)
|
||||
{
|
||||
for (auto& LootDrop : LootDrops)
|
||||
{
|
||||
auto Pickup = AFortPickup::SpawnPickup(LootDrop->GetItemDefinition(), Location, LootDrop->GetCount(), SpawnFlag, EFortPickupSpawnSource::Unset, LootDrop->GetLoadedAmmo());
|
||||
}
|
||||
PickupCreateData CreateData;
|
||||
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;
|
||||
|
||||
auto Pickup = AFortPickup::SpawnPickup(CreateData);
|
||||
}
|
||||
|
||||
if (!bTest)
|
||||
CurrentActor->K2_DestroyActor();
|
||||
}
|
||||
|
||||
// SpawnIsland_FloorLoot_Actors.Free();
|
||||
// BRIsland_FloorLoot_Actors.Free();
|
||||
SpawnIsland_FloorLoot_Actors.Free();
|
||||
BRIsland_FloorLoot_Actors.Free();
|
||||
|
||||
LOG_INFO(LogDev, "Spawned loot!");
|
||||
}
|
||||
@@ -1058,7 +1068,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
||||
static auto SquadIdOffset = PlayerStateAthena->GetOffset("SquadId", false);
|
||||
|
||||
if (SquadIdOffset != -1)
|
||||
PlayerStateAthena->GetSquadId() = PlayerStateAthena->GetTeamIndex() - 2;
|
||||
PlayerStateAthena->GetSquadId() = PlayerStateAthena->GetTeamIndex() - 2; // wrong place to do this
|
||||
|
||||
// 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");
|
||||
PlayerStateAthena->ProcessEvent(OnRep_bHasStartedPlayingFn);
|
||||
|
||||
LOG_INFO(LogDev, "Old ID: {}", PlayerStateAthena->GetWorldPlayerId());
|
||||
LOG_INFO(LogDev, "PlayerID: {}", PlayerStateAthena->GetPlayerID());
|
||||
|
||||
PlayerStateAthena->GetWorldPlayerId() = PlayerStateAthena->GetPlayerID();
|
||||
|
||||
auto PlayerAbilitySet = GetPlayerAbilitySet();
|
||||
@@ -1088,9 +1095,15 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
||||
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");
|
||||
@@ -1105,12 +1118,10 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
||||
PlayerCameraManager->Get<float>(ViewRollMaxOffset) = 0;
|
||||
}
|
||||
|
||||
/* FUniqueNetIdReplExperimental Bugha{}; */
|
||||
static auto UniqueIdOffset = PlayerStateAthena->GetOffset("UniqueId");
|
||||
auto PlayerStateUniqueId = PlayerStateAthena->GetPtr<FUniqueNetIdRepl>(UniqueIdOffset);
|
||||
|
||||
{
|
||||
LOG_INFO(LogDev, "bruh");
|
||||
static auto GameMemberInfoArrayOffset = GameState->GetOffset("GameMemberInfoArray", false);
|
||||
|
||||
// if (false)
|
||||
@@ -1150,7 +1161,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
||||
((FGameMemberInfo*)GameMemberInfo)->SquadId = PlayerStateAthena->GetSquadId();
|
||||
((FGameMemberInfo*)GameMemberInfo)->TeamIndex = PlayerStateAthena->GetTeamIndex();
|
||||
// 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");
|
||||
@@ -1260,7 +1271,8 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
||||
if (LevelSaveComponent)
|
||||
{
|
||||
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;
|
||||
|
||||
static auto bIsLoadedOffset = LevelSaveComponent->GetOffset("bIsLoaded");
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "FortSafeZoneIndicator.h"
|
||||
#include "GameplayStatics.h"
|
||||
#include "FortAbilitySet.h"
|
||||
#include "FortPlayerControllerAthena.h"
|
||||
#include "FortItemDefinition.h"
|
||||
|
||||
struct FAircraftFlightInfo
|
||||
@@ -233,6 +234,12 @@ public:
|
||||
return Get<TArray<FItemAndCount>>(StartingItemsOffset);
|
||||
}
|
||||
|
||||
TArray<AFortPlayerControllerAthena*>& GetAlivePlayers()
|
||||
{
|
||||
static auto AlivePlayersOffset = GetOffset("AlivePlayers");
|
||||
return Get<TArray<AFortPlayerControllerAthena*>>(AlivePlayersOffset);
|
||||
}
|
||||
|
||||
FName RedirectLootTier(const FName& LootTier);
|
||||
UClass* GetVehicleClassOverride(UClass* DefaultClass);
|
||||
|
||||
|
||||
@@ -244,3 +244,13 @@ void AFortGameStateAthena::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);
|
||||
void OnRep_GamePhase();
|
||||
void OnRep_CurrentPlaylistInfo();
|
||||
void OnRep_PlayersLeft();
|
||||
};
|
||||
|
||||
static void* ConstructOnGamePhaseStepChangedParams(EAthenaGamePhaseStep GamePhaseStep)
|
||||
|
||||
@@ -110,7 +110,13 @@ std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AFortInventory::AddI
|
||||
if (!Pawn)
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -126,21 +132,21 @@ std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AFortInventory::AddI
|
||||
|
||||
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;
|
||||
|
||||
if (bEnableStateValues)
|
||||
{
|
||||
FFortItemEntryStateValue* StateValue = Alloc<FFortItemEntryStateValue>(FFortItemEntryStateValue::GetStructSize(), true);
|
||||
StateValue->GetIntValue() = bShowItemToast;
|
||||
StateValue->GetStateType() = EFortItemEntryState::ShouldShowItemToast;
|
||||
NewItemInstance->GetItemEntry()->GetStateValues().AddPtr(StateValue, FFortItemEntryStateValue::GetStructSize());
|
||||
// FFortItemEntryStateValue* StateValue = Alloc<FFortItemEntryStateValue>(FFortItemEntryStateValue::GetStructSize(), true);
|
||||
PadHexA8 StateValue{};
|
||||
((FFortItemEntryStateValue*)&StateValue)->GetIntValue() = bShowItemToast;
|
||||
((FFortItemEntryStateValue*)&StateValue)->GetStateType() = EFortItemEntryState::ShouldShowItemToast;
|
||||
((FFortItemEntryStateValue*)&StateValue)->GetNameValue() = FName(0);
|
||||
|
||||
NewItemInstance->GetItemEntry()->GetStateValues().AddPtr((FFortItemEntryStateValue*)&StateValue, FFortItemEntryStateValue::GetStructSize());
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (FortPlayerController && WorldItemDefinition->IsValidLowLevel())
|
||||
@@ -267,55 +273,61 @@ bool AFortInventory::RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int
|
||||
|
||||
int OldCount = Count;
|
||||
|
||||
bool bLikeReallyForce = false;
|
||||
|
||||
if (Count < 0) // idk why i have this
|
||||
{
|
||||
Count = 0;
|
||||
bForceRemoval = true;
|
||||
bLikeReallyForce = true;
|
||||
}
|
||||
|
||||
auto NewCount = ReplicatedEntry->GetCount() - Count;
|
||||
|
||||
auto& ItemInstances = GetItemList().GetItemInstances();
|
||||
auto& ReplicatedEntries = GetItemList().GetReplicatedEntries();
|
||||
|
||||
bool bOverrideChangeStackSize = false;
|
||||
|
||||
if (ItemDefinition->ShouldPersistWhenFinalStackEmpty() && !bForceRemoval)
|
||||
if (!bLikeReallyForce)
|
||||
{
|
||||
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;
|
||||
break;
|
||||
auto ItemInstance = ItemInstances.at(i);
|
||||
|
||||
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
|
||||
bOverrideChangeStackSize = true;
|
||||
ItemInstance->GetItemEntry()->GetCount() = NewCount;
|
||||
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 FortItemEntrySize = FortItemEntryStruct->GetPropertiesSize();
|
||||
|
||||
@@ -557,3 +569,9 @@ FFortItemEntry* AFortInventory::FindReplicatedEntry(const FGuid& Guid)
|
||||
|
||||
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);
|
||||
FFortItemEntry* FindReplicatedEntry(const FGuid& Guid);
|
||||
|
||||
// static UClass* StaticClass();
|
||||
};
|
||||
@@ -1,5 +1,40 @@
|
||||
#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)
|
||||
{
|
||||
static auto SOCFTIFn = FindObject<UFunction>(L"/Script/FortniteGame.FortItem.SetOwningControllerForTemporaryItem");
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include "reboot.h"
|
||||
|
||||
enum class EFortItemEntryState : uint8_t // idk if this changes
|
||||
enum class EFortItemEntryState : uint8_t // this changes but its fineee
|
||||
{
|
||||
NoneState = 0,
|
||||
NewItemCount = 1,
|
||||
@@ -74,6 +74,13 @@ struct FFortItemEntry : FFastArraySerializerItem
|
||||
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()
|
||||
{
|
||||
static auto ItemDefinitionOffset = FindOffsetStruct("/Script/FortniteGame.FortItemEntry", "ItemDefinition");
|
||||
@@ -116,6 +123,12 @@ struct FFortItemEntry : FFastArraySerializerItem
|
||||
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()
|
||||
{
|
||||
static auto ParentInventoryOffset = FindOffsetStruct("/Script/FortniteGame.FortItemEntry", "ParentInventory");
|
||||
@@ -144,6 +157,20 @@ struct FFortItemEntry : FFastArraySerializerItem
|
||||
if (!bCopyGuid)
|
||||
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?
|
||||
|
||||
this->MostRecentArrayReplicationKey = -1;
|
||||
@@ -163,29 +190,7 @@ struct FFortItemEntry : FFastArraySerializerItem
|
||||
return StructSize;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
static FFortItemEntry* MakeItemEntry(UFortItemDefinition* ItemDefinition, int Count = 1, int LoadedAmmo = 0, float Durability = 0x3F800000);
|
||||
|
||||
// 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);
|
||||
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)
|
||||
|
||||
@@ -136,7 +136,11 @@ void UFortKismetLibrary::SpawnItemVariantPickupInWorldHook(UObject* Context, FFr
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -165,7 +169,13 @@ bool UFortKismetLibrary::SpawnInstancedPickupInWorldHook(UObject* Context, FFram
|
||||
Stack.StepCompiledIn(&bRandomRotation);
|
||||
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;
|
||||
return *Ret;
|
||||
@@ -192,8 +202,8 @@ void UFortKismetLibrary::CreateTossAmmoPickupForWeaponItemDefinitionAtLocationHo
|
||||
UFortWeaponItemDefinition* WeaponItemDefinition;
|
||||
FGameplayTagContainer SourceTags;
|
||||
FVector Location;
|
||||
EFortPickupSourceTypeFlag SourceTypeFlag;
|
||||
EFortPickupSpawnSource SpawnSource;
|
||||
uint8 SourceTypeFlag;
|
||||
uint8 SpawnSource;
|
||||
|
||||
Stack.StepCompiledIn(&WorldContextObject);
|
||||
Stack.StepCompiledIn(&WeaponItemDefinition);
|
||||
@@ -213,7 +223,13 @@ void UFortKismetLibrary::CreateTossAmmoPickupForWeaponItemDefinitionAtLocationHo
|
||||
if (!AmmoDefinition)
|
||||
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);
|
||||
}
|
||||
@@ -460,8 +476,8 @@ AFortPickup* UFortKismetLibrary::K2_SpawnPickupInWorldWithClassHook(UObject* Con
|
||||
bool bRandomRotation; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
bool bBlockedFromAutoPickup; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
int PickupInstigatorHandle; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
EFortPickupSourceTypeFlag SourceType; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
EFortPickupSpawnSource Source; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
uint8 SourceType; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
uint8 Source; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
AFortPlayerController* OptionalOwnerPC; // (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__);
|
||||
|
||||
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);
|
||||
|
||||
*Ret = aa;
|
||||
*Ret = NewPickup;
|
||||
return *Ret;
|
||||
}
|
||||
|
||||
@@ -508,8 +532,8 @@ AFortPickup* UFortKismetLibrary::K2_SpawnPickupInWorldHook(UObject* Context, FFr
|
||||
bool bRandomRotation; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
bool bBlockedFromAutoPickup; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
int PickupInstigatorHandle; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
EFortPickupSourceTypeFlag SourceType; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
EFortPickupSpawnSource Source; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
uint8 SourceType; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
uint8 Source; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
AFortPlayerController* OptionalOwnerPC; // (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 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);
|
||||
|
||||
*Ret = aa;
|
||||
*Ret = NewPickup;
|
||||
return *Ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,16 +35,16 @@ struct FSpawnItemVariantParams
|
||||
return *(int*)(__int64(this) + NumberToSpawnOffset);
|
||||
}
|
||||
|
||||
EFortPickupSourceTypeFlag& GetSourceType()
|
||||
uint8& GetSourceType()
|
||||
{
|
||||
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");
|
||||
return *(EFortPickupSpawnSource*)(__int64(this) + SourceOffset);
|
||||
return *(uint8*)(__int64(this) + SourceOffset);
|
||||
}
|
||||
|
||||
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) {
|
||||
auto Weight = GetWeightFn(p.second);
|
||||
|
||||
if (bPrint)
|
||||
if (bPrint && Weight != 0)
|
||||
{
|
||||
LOG_INFO(LogLoot, "Adding weight: {}", Weight);
|
||||
}
|
||||
@@ -282,7 +282,7 @@ void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, cons
|
||||
return;
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -358,12 +358,20 @@ void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, cons
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,16 @@ void AFortPawn::SetHealth(float 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)
|
||||
{
|
||||
static auto SetShieldFn = FindObject<UFunction>("/Script/FortniteGame.FortPawn.SetShield");
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
}
|
||||
|
||||
void SetHealth(float NewHealth);
|
||||
void SetMaxHealth(float NewHealthVal);
|
||||
void SetShield(float NewShield);
|
||||
static void NetMulticast_Athena_BatchedDamageCuesHook(UObject* Context, FFrame* Stack, void* Ret);
|
||||
static void MovingEmoteStoppedHook(UObject* Context, FFrame* Stack, void* Ret);
|
||||
|
||||
@@ -10,12 +10,12 @@
|
||||
#include "GameplayStatics.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");
|
||||
|
||||
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};
|
||||
|
||||
this->ProcessEvent(fn, &AFortPickup_TossPickup_Params);
|
||||
@@ -29,145 +29,151 @@ void AFortPickup::SpawnMovementComponent()
|
||||
this->Get(MovementComponentOffset) = UGameplayStatics::SpawnObject(ProjectileMovementComponentClass, this);
|
||||
}
|
||||
|
||||
AFortPickup* AFortPickup::SpawnPickup(FFortItemEntry* ItemEntry, FVector Location,
|
||||
EFortPickupSourceTypeFlag PickupSource, EFortPickupSpawnSource SpawnSource,
|
||||
class AFortPawn* Pawn, UClass* OverrideClass, bool bToss, int OverrideCount, AFortPickup* IgnoreCombinePickup)
|
||||
AFortPickup* AFortPickup::SpawnPickup(PickupCreateData& PickupData)
|
||||
{
|
||||
if (bToss)
|
||||
{
|
||||
PickupSource |= EFortPickupSourceTypeFlag::Tossed;
|
||||
}
|
||||
if (PickupData.Source == -1)
|
||||
PickupData.Source = 0;
|
||||
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");
|
||||
auto PlayerState = Pawn ? Cast<AFortPlayerState>(Pawn->GetPlayerState()) : nullptr;
|
||||
auto PlayerState = PickupData.PawnOwner ? Cast<AFortPlayerState>(PickupData.PawnOwner->GetPlayerState()) : nullptr;
|
||||
|
||||
FActorSpawnParameters SpawnParameters{};
|
||||
// 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");
|
||||
Pickup->Get<AFortPawn*>(PawnWhoDroppedPickupOffset) = Pawn;
|
||||
static void (*SetupPickup)(AFortPickup * Pickup, __int64 ItemEntry, TArray<FFortItemEntry> MultiItemPickupEntriesIGuess, bool bSplitOnPickup)
|
||||
= 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)
|
||||
= 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())
|
||||
if (OtherPickup->GetPrimaryPickupItemEntry()->GetCount() >= PrimaryPickupItemEntry->GetItemDefinition()->GetMaxStackSize()) // Other pickup is already at the max size.
|
||||
return false;
|
||||
|
||||
if (PrimaryPickupItemEntry->GetItemDefinition() == OtherPickup->GetPrimaryPickupItemEntry()->GetItemDefinition())
|
||||
{
|
||||
// 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);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!PickupLocationData->GetCombineTarget()) // I don't think we should call TossPickup for every pickup anyways.
|
||||
{
|
||||
Pickup->TossPickup(Location, Pawn, 0, bToss, PickupSource, SpawnSource);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto ActorLocation = Pickup->GetActorLocation();
|
||||
auto CurrentActorLocation = PickupLocationData->GetCombineTarget()->GetActorLocation();
|
||||
return false;
|
||||
};
|
||||
|
||||
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() = 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;
|
||||
if (Addresses::CombinePickupLea && bEnableCombinePickup)
|
||||
{
|
||||
PickupLocationData->GetCombineTarget() = (AFortPickup*)Pickup->GetClosestActor(AFortPickup::StaticClass(), 4, CanCombineWithPickup);
|
||||
}
|
||||
|
||||
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,
|
||||
int LoadedAmmo, AFortPawn* Pawn, UClass* OverrideClass, bool bToss, AFortPickup* IgnoreCombinePickup)
|
||||
AFortPickup* AFortPickup::SpawnPickup(FFortItemEntry* ItemEntry, FVector Location,
|
||||
uint8 PickupSource, uint8 SpawnSource,
|
||||
class AFortPawn* Pawn, UClass* OverrideClass, bool bToss, int OverrideCount, AFortPickup* IgnoreCombinePickup)
|
||||
{
|
||||
if (LoadedAmmo == -1)
|
||||
{
|
||||
if (auto WeaponDef = Cast<UFortWeaponItemDefinition>(ItemDef)) // bPreventDefaultPreload ?
|
||||
LoadedAmmo = WeaponDef->GetClipSize();
|
||||
else
|
||||
LoadedAmmo = 0;
|
||||
}
|
||||
PickupCreateData CreateData;
|
||||
CreateData.ItemEntry = ItemEntry;
|
||||
CreateData.SpawnLocation = Location;
|
||||
CreateData.Source = SpawnSource;
|
||||
CreateData.SourceType = PickupSource;
|
||||
CreateData.PawnOwner = Pawn;
|
||||
CreateData.OverrideClass = OverrideClass;
|
||||
CreateData.bToss = bToss;
|
||||
CreateData.IgnoreCombineTarget = IgnoreCombinePickup;
|
||||
CreateData.OverrideCount = OverrideCount;
|
||||
|
||||
auto ItemEntry = FFortItemEntry::MakeItemEntry(ItemDef, Count, LoadedAmmo);
|
||||
auto Pickup = SpawnPickup(ItemEntry, Location, PickupSource, SpawnSource, Pawn, OverrideClass, bToss, -1, IgnoreCombinePickup);
|
||||
// VirtualFree(ItemEntry);
|
||||
return Pickup;
|
||||
return AFortPickup::SpawnPickup(CreateData);
|
||||
}
|
||||
|
||||
void AFortPickup::CombinePickupHook(AFortPickup* Pickup)
|
||||
@@ -195,8 +201,14 @@ void AFortPickup::CombinePickupHook(AFortPickup* Pickup)
|
||||
|
||||
auto ItemOwner = Pickup->GetPickupLocationData()->GetItemOwner();
|
||||
|
||||
auto NewOverStackPickup = AFortPickup::SpawnPickup(ItemDefinition, PickupToCombineInto->GetActorLocation(), OverStackCount,
|
||||
EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset, -1, ItemOwner, nullptr, false, PickupToCombineInto);
|
||||
PickupCreateData CreateData;
|
||||
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;
|
||||
@@ -300,7 +312,7 @@ char AFortPickup::CompletePickupAnimationHook(AFortPickup* Pickup)
|
||||
if (ItemInstanceToSwap && ItemDefinitionToSwap->CanBeDropped() && !bHasSwapped && ItemDefGoingInPrimary) // swap
|
||||
{
|
||||
auto SwappedPickup = SpawnPickup(ItemEntryToSwap, PawnLoc,
|
||||
EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset, Pawn);
|
||||
EFortPickupSourceTypeFlag::GetPlayerValue(), 0, Pawn);
|
||||
|
||||
auto CurrentWeapon = Pawn->GetCurrentWeapon();
|
||||
|
||||
@@ -373,7 +385,7 @@ char AFortPickup::CompletePickupAnimationHook(AFortPickup* Pickup)
|
||||
int LoadedAmmo = 0;
|
||||
|
||||
// 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;
|
||||
bForceOverflow = false;
|
||||
}
|
||||
|
||||
@@ -2,33 +2,99 @@
|
||||
|
||||
#include "Actor.h"
|
||||
#include "FortPawn.h"
|
||||
#include "Class.h"
|
||||
|
||||
enum class EFortPickupSourceTypeFlag : uint8_t
|
||||
namespace EFortPickupSourceTypeFlag
|
||||
{
|
||||
Other = 0,
|
||||
Player = 1,
|
||||
Destruction = 2,
|
||||
Container = 3,
|
||||
AI = 4,
|
||||
Tossed = 5,
|
||||
FloorLoot = 6,
|
||||
EFortPickupSourceTypeFlag_MAX = 7
|
||||
static inline UEnum* GetEnum()
|
||||
{
|
||||
static auto Enum = FindObject<UEnum>("/Script/FortniteGame.EFortPickupSourceTypeFlag");
|
||||
return Enum;
|
||||
}
|
||||
|
||||
static inline int64 GetPlayerValue()
|
||||
{
|
||||
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,
|
||||
PlayerElimination = 1,
|
||||
Chest = 2,
|
||||
SupplyDrop = 3,
|
||||
AmmoBox = 4,
|
||||
Drone = 5,
|
||||
ItemSpawner = 6,
|
||||
EFortPickupSpawnSource_MAX = 7
|
||||
NotTossed = 0,
|
||||
InProgress = 1,
|
||||
AtRest = 2,
|
||||
EFortPickupTossState_MAX = 3,
|
||||
};
|
||||
|
||||
ENUM_CLASS_FLAGS(EFortPickupSourceTypeFlag)
|
||||
|
||||
struct FFortPickupLocationData
|
||||
{
|
||||
AFortPawn*& GetPickupTarget()
|
||||
@@ -43,6 +109,12 @@ struct FFortPickupLocationData
|
||||
return *(float*)(__int64(this) + FlyTimeOffset);
|
||||
}
|
||||
|
||||
EFortPickupTossState& GetTossState()
|
||||
{
|
||||
static auto TossStateOffset = FindOffsetStruct("/Script/FortniteGame.FortPickupLocationData", "TossState");
|
||||
return *(EFortPickupTossState*)(__int64(this) + TossStateOffset);
|
||||
}
|
||||
|
||||
AFortPawn*& GetItemOwner()
|
||||
{
|
||||
static auto ItemOwnerOffset = FindOffsetStruct("/Script/FortniteGame.FortPickupLocationData", "ItemOwner");
|
||||
@@ -91,7 +163,7 @@ class AFortPickup : public AActor
|
||||
public:
|
||||
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 OnRep_PrimaryPickupItemEntry()
|
||||
@@ -118,13 +190,11 @@ public:
|
||||
this->ProcessEvent(OnRep_PickupLocationDataFn);
|
||||
}
|
||||
|
||||
static AFortPickup* SpawnPickup(FFortItemEntry* ItemEntry, FVector Location,
|
||||
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(PickupCreateData& PickupData);
|
||||
|
||||
static AFortPickup* SpawnPickup(class UFortItemDefinition* ItemDef, FVector Location, int Count,
|
||||
EFortPickupSourceTypeFlag PickupSource = EFortPickupSourceTypeFlag::Other, EFortPickupSpawnSource SpawnSource = EFortPickupSpawnSource::Unset,
|
||||
int LoadedAmmo = -1, class AFortPawn* Pawn = nullptr, UClass* OverrideClass = nullptr, bool bToss = true, AFortPickup* IgnoreCombinePickup = nullptr);
|
||||
static AFortPickup* SpawnPickup(FFortItemEntry* ItemEntry, FVector Location,
|
||||
uint8 PickupSource = 0, uint8 SpawnSource = 0,
|
||||
class AFortPawn* Pawn = nullptr, UClass* OverrideClass = nullptr, bool bToss = true, int OverrideCount = -1, AFortPickup* IgnoreCombinePickup = nullptr);
|
||||
|
||||
static void CombinePickupHook(AFortPickup* Pickup);
|
||||
static char CompletePickupAnimationHook(AFortPickup* Pickup);
|
||||
|
||||
@@ -111,8 +111,12 @@ void AFortPlayerController::DropAllItems(const std::vector<UFortItemDefinition*>
|
||||
if (bRemoveIfNotDroppable && !WorldItemDefinition->CanBeDropped())
|
||||
continue;
|
||||
|
||||
AFortPickup::SpawnPickup(WorldItemDefinition, Location, ItemEntry->GetCount(), EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset,
|
||||
ItemEntry->GetLoadedAmmo());
|
||||
PickupCreateData CreateData;
|
||||
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(WorldItemDefinition, ItemEntry->GetCount(), ItemEntry->GetLoadedAmmo());
|
||||
CreateData.SpawnLocation = Location;
|
||||
CreateData.SourceType = EFortPickupSourceTypeFlag::GetPlayerValue();
|
||||
|
||||
AFortPickup::SpawnPickup(CreateData);
|
||||
}
|
||||
|
||||
for (auto& Pair : GuidAndCountsToRemove)
|
||||
@@ -587,8 +591,12 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame*
|
||||
{
|
||||
auto Entry = ItemCollection->GetOutputItemEntry()->AtPtr(z, FFortItemEntry::GetStructSize());
|
||||
|
||||
AFortPickup::SpawnPickup(Entry->GetItemDefinition(), LocationToSpawnLoot, Entry->GetCount(),
|
||||
EFortPickupSourceTypeFlag::Other, EFortPickupSpawnSource::Unset, Entry->GetLoadedAmmo(), PlayerController->GetMyFortPawn());
|
||||
PickupCreateData CreateData;
|
||||
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);
|
||||
@@ -840,6 +848,8 @@ void AFortPlayerController::ServerCreateBuildingActorHook(UObject* Context, FFra
|
||||
|
||||
bool bBuildFree = PlayerController->DoesBuildFree();
|
||||
|
||||
LOG_INFO(LogDev, "MatInstance->GetItemEntry()->GetCount(): {}", MatInstance->GetItemEntry()->GetCount());
|
||||
|
||||
bool bShouldDestroy = MatInstance && MatInstance->GetItemEntry() ? MatInstance->GetItemEntry()->GetCount() < 10 : true;
|
||||
|
||||
if (bShouldDestroy && !bBuildFree)
|
||||
@@ -950,6 +960,7 @@ void AFortPlayerController::ServerAttemptInventoryDropHook(AFortPlayerController
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO If the player is in a vehicle and has a vehicle weapon, don't let them drop.
|
||||
|
||||
auto WorldInventory = PlayerController->GetWorldInventory();
|
||||
auto ReplicatedEntry = WorldInventory->FindReplicatedEntry(ItemGuid);
|
||||
@@ -966,8 +977,25 @@ void AFortPlayerController::ServerAttemptInventoryDropHook(AFortPlayerController
|
||||
|
||||
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(),
|
||||
EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset, Pawn, nullptr, true, Count);
|
||||
EFortPickupSourceTypeFlag::GetPlayerValue(), 0, Pawn, nullptr, true, Count);
|
||||
|
||||
if (!Pickup)
|
||||
return;
|
||||
@@ -1338,8 +1366,13 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
|
||||
if (!ShouldBeDropped)
|
||||
continue;
|
||||
|
||||
AFortPickup::SpawnPickup(WorldItemDefinition, DeathLocation, ItemEntry->GetCount(), EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::PlayerElimination,
|
||||
ItemEntry->GetLoadedAmmo());
|
||||
PickupCreateData CreateData;
|
||||
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() });
|
||||
// WorldInventory->RemoveItem(ItemEntry->GetItemGuid(), nullptr, ItemEntry->GetCount());
|
||||
@@ -1433,29 +1466,39 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
|
||||
{
|
||||
// wtf
|
||||
|
||||
auto AllPlayerStates = UGameplayStatics::GetAllActorsOfClass(GetWorld(), AFortPlayerStateAthena::StaticClass());
|
||||
|
||||
bool bDidSomeoneWin = AllPlayerStates.Num() == 0;
|
||||
|
||||
for (int i = 0; i < AllPlayerStates.Num(); i++)
|
||||
if (GameState->GetGamePhase() > EAthenaGamePhase::Warmup)
|
||||
{
|
||||
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;
|
||||
break;
|
||||
auto CurrentPlayerState = (AFortPlayerStateAthena*)AllPlayerStates.at(i);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -108,6 +108,20 @@ public:
|
||||
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()
|
||||
{
|
||||
static auto bTryPickupSwapOffset = GetOffset("bTryPickupSwap");
|
||||
|
||||
@@ -105,6 +105,9 @@ void AFortPlayerControllerAthena::EndGhostModeHook(AFortPlayerControllerAthena*
|
||||
auto PickaxeInstance = PlayerController->AddPickaxeToInventory();
|
||||
WorldInventory->Update();
|
||||
|
||||
WorldInventory->ForceNetUpdate();
|
||||
PlayerController->ForceNetUpdate();
|
||||
|
||||
if (PickaxeInstance)
|
||||
{
|
||||
PlayerController->ClientEquipItem(PickaxeInstance->GetItemEntry()->GetItemGuid(), true);
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
|
||||
FFortAthenaLoadout* AFortPlayerPawn::GetCosmeticLoadout()
|
||||
{
|
||||
static auto CosmeticLoadoutOffset = GetOffset("CosmeticLoadout");
|
||||
static auto CosmeticLoadoutOffset = GetOffset("CosmeticLoadout", false);
|
||||
|
||||
if (CosmeticLoadoutOffset == -1)
|
||||
CosmeticLoadoutOffset = GetOffset("CustomizationLoadout");
|
||||
|
||||
if (CosmeticLoadoutOffset == -1)
|
||||
return nullptr;
|
||||
|
||||
@@ -26,6 +26,20 @@ public:
|
||||
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)
|
||||
{
|
||||
static auto ClientReportKillFn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerStateAthena.ClientReportKill");
|
||||
|
||||
@@ -23,9 +23,39 @@ UClass* AGameModeBase::GetDefaultPawnClassForController(AController* InControlle
|
||||
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)
|
||||
{
|
||||
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);
|
||||
// LOG_INFO(LogDev, "PawnClass: {}", PawnClass->GetFullName());
|
||||
|
||||
@@ -4,11 +4,14 @@
|
||||
|
||||
#include "Controller.h"
|
||||
#include "Pawn.h"
|
||||
#include "UnrealString.h"
|
||||
|
||||
class AGameModeBase : public AActor // AInfo
|
||||
{
|
||||
public:
|
||||
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);
|
||||
};
|
||||
@@ -5,6 +5,73 @@
|
||||
|
||||
#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
|
||||
{
|
||||
public:
|
||||
@@ -35,4 +102,109 @@ public:
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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) */
|
||||
};
|
||||
@@ -3,6 +3,12 @@
|
||||
|
||||
#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)
|
||||
{
|
||||
GetCheatManager() = UGameplayStatics::SpawnObject<UCheatManager>(CheatManagerClass, this, true);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "Controller.h"
|
||||
#include "CheatManager.h"
|
||||
|
||||
#include "UnrealString.h"
|
||||
#include "Rotator.h"
|
||||
|
||||
class APlayerController : public AController
|
||||
@@ -39,6 +40,7 @@ public:
|
||||
return this->Get<UCheatManager*>(CheatManagerOffset);
|
||||
}
|
||||
|
||||
void ServerChangeName(FString& S);
|
||||
UCheatManager*& SpawnCheatManager(UClass* CheatManagerClass);
|
||||
FRotator GetControlRotation();
|
||||
void Possess(class APawn* Pawn);
|
||||
|
||||
@@ -29,3 +29,23 @@ int& APlayerState::GetPlayerID()
|
||||
|
||||
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:
|
||||
FString GetPlayerName();
|
||||
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="BinaryHeap.h" />
|
||||
<ClInclude Include="BitArray.h" />
|
||||
<ClInclude Include="bots.h" />
|
||||
<ClInclude Include="BuildingActor.h" />
|
||||
<ClInclude Include="BuildingContainer.h" />
|
||||
<ClInclude Include="BuildingFoundation.h" />
|
||||
|
||||
@@ -712,9 +712,6 @@
|
||||
<ClInclude Include="AttributeSet.h">
|
||||
<Filter>Engine\Plugins\Runtime\GameplayAbilities\Source\GameplayAbilities\Public</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="gui.h">
|
||||
<Filter>Reboot\Public\GUI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FortWeaponRangedMountedCannon.h">
|
||||
<Filter>FortniteGame\Source\FortniteGame\Public\Athena\Vehicle</Filter>
|
||||
</ClInclude>
|
||||
@@ -851,6 +848,12 @@
|
||||
<ClInclude Include="FortLootLevel.h">
|
||||
<Filter>FortniteGame\Source\FortniteGame\Public\Items</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="bots.h">
|
||||
<Filter>Reboot\Public</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="gui.h">
|
||||
<Filter>Reboot\Public</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Engine">
|
||||
@@ -1051,9 +1054,6 @@
|
||||
<Filter Include="Engine\Source\Runtime\Core\Public\Algo\Impl">
|
||||
<UniqueIdentifier>{74e42db4-bdac-4e42-bb7e-58f1ab17b738}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Reboot\Public\GUI">
|
||||
<UniqueIdentifier>{15a7e32e-0505-49cc-9f6a-89d3e5c865b5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Libaries">
|
||||
<UniqueIdentifier>{c0586029-3b4a-48f9-8de9-5b48a972cb5e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
|
||||
MS_ALIGN(16) struct FTransform
|
||||
{
|
||||
FQuat Rotation; // 0x0000(0x0010) (Edit, BlueprintVisible, SaveGame, IsPlainOldData, NoDestructor, NativeAccessSpecifierPublic)
|
||||
FVector Translation; // 0x0010(0x000C) (Edit, BlueprintVisible, ZeroConstructor, SaveGame, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
FQuat Rotation = FQuat(0, 0, 0, 0); // 0x0000(0x0010) (Edit, BlueprintVisible, SaveGame, IsPlainOldData, NoDestructor, 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
|
||||
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
|
||||
};
|
||||
@@ -19,12 +19,12 @@ public:
|
||||
|
||||
struct FActorSpawnParameters
|
||||
{
|
||||
FName Name;
|
||||
UObject* Template;
|
||||
UObject* Owner;
|
||||
UObject** Instigator;
|
||||
UObject* OverrideLevel;
|
||||
ESpawnActorCollisionHandlingMethod SpawnCollisionHandlingOverride;
|
||||
FName Name = FName(0);
|
||||
UObject* Template = nullptr;
|
||||
UObject* Owner = nullptr;
|
||||
UObject** Instigator = nullptr;
|
||||
UObject* OverrideLevel = nullptr;
|
||||
ESpawnActorCollisionHandlingMethod SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::Undefined;
|
||||
uint16 bRemoteOwned : 1;
|
||||
uint16 bNoFail : 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 "FortWeaponMeleeItemDefinition.h"
|
||||
#include "builder.h"
|
||||
#include "FortLootPackage.h"
|
||||
#include "bots.h"
|
||||
|
||||
bool IsOperator(APlayerState* PlayerState, AFortPlayerController* PlayerController)
|
||||
{
|
||||
@@ -200,6 +202,25 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg)
|
||||
|
||||
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")
|
||||
{
|
||||
if (NumArgs < 1)
|
||||
@@ -348,7 +369,12 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg)
|
||||
}
|
||||
|
||||
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")
|
||||
{
|
||||
@@ -547,6 +573,60 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg)
|
||||
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")
|
||||
{
|
||||
auto Pawn = ReceivingController->GetMyFortPawn();
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "KismetStringLibrary.h"
|
||||
#include "DataTableFunctionLibrary.h"
|
||||
#include "FortPlaysetItemDefinition.h"
|
||||
#include "gui.h"
|
||||
|
||||
static inline void (*SetZoneToIndexOriginal)(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK);
|
||||
|
||||
@@ -178,6 +179,11 @@ void ProcessEventHook(UObject* Object, UFunction* Function, void* Parameters)
|
||||
if (!Object || !Function)
|
||||
return;
|
||||
|
||||
if (bEnableBotTick)
|
||||
{
|
||||
Bots::Tick();
|
||||
}
|
||||
|
||||
if (Globals::bLogProcessEvent)
|
||||
{
|
||||
auto FunctionName = Function->GetName(); // UKismetSystemLibrary::GetPathName(Function).ToString();
|
||||
|
||||
@@ -513,9 +513,6 @@ DWORD WINAPI Main(LPVOID)
|
||||
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
|
||||
{
|
||||
return 0;
|
||||
// return 0;
|
||||
|
||||
/* uint64 OnRep_PickupLocationDataAddr = 0; // TODO (Idea: Find SetupCombinePickupDelegates from this).
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "FortWeaponItemDefinition.h"
|
||||
#include "events.h"
|
||||
#include "FortAthenaMutator_Heist.h"
|
||||
#include "BGA.h"
|
||||
|
||||
#define GAME_TAB 1
|
||||
#define PLAYERS_TAB 2
|
||||
@@ -64,6 +65,9 @@ extern inline float AutoBusStartSeconds = 60;
|
||||
extern inline int NumRequiredPlayersToStart = 2;
|
||||
extern inline bool bDebugPrintLooting = 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
|
||||
|
||||
@@ -279,6 +283,7 @@ static inline void StaticUI()
|
||||
|
||||
#ifndef PROD
|
||||
ImGui::Checkbox("Log ProcessEvent", &Globals::bLogProcessEvent);
|
||||
ImGui::InputInt("Amount of bots to spawn", &AmountOfBotsToSpawn);
|
||||
#endif
|
||||
|
||||
ImGui::Checkbox("Infinite Ammo", &Globals::bInfiniteAmmo);
|
||||
@@ -470,6 +475,11 @@ static inline void MainUI()
|
||||
UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), cmd, nullptr);
|
||||
}
|
||||
|
||||
if (ImGui::Button("Spawn BGAs"))
|
||||
{
|
||||
SpawnBGAs();
|
||||
}
|
||||
|
||||
/*
|
||||
if (ImGui::Button("New"))
|
||||
{
|
||||
@@ -897,6 +907,8 @@ static inline void MainUI()
|
||||
static std::string FunctionNameToDump;
|
||||
|
||||
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("Function Name to mess with", &FunctionNameToDump);
|
||||
@@ -1001,7 +1013,8 @@ static inline void PregameUI()
|
||||
if (!bSwitchedInitialLevel)
|
||||
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)
|
||||
|
||||
@@ -81,6 +81,7 @@ inline void InitLogger()
|
||||
MakeLogger("LogReplication");
|
||||
MakeLogger("LogMutator");
|
||||
MakeLogger("LogVehicles");
|
||||
MakeLogger("LogBots");
|
||||
MakeLogger("LogCosmetics");
|
||||
}
|
||||
|
||||
|
||||
@@ -240,6 +240,14 @@ inline std::vector<T*> GetAllObjectsOfClass(UClass* Class)
|
||||
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)
|
||||
{
|
||||
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>
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user