<feat: New project structure>

<feat: New release>
This commit is contained in:
Alessandro Autiero
2023-09-02 15:34:15 +02:00
parent 64b33102f4
commit b41e22adeb
953 changed files with 1373072 additions and 0 deletions

View File

@@ -0,0 +1,103 @@
#pragma once
#include "Object.h"
#include "GameplayAbilitySpec.h"
#include "AttributeSet.h"
struct PadHex10 { char Pad[0x10]; };
struct PadHex18 { char Pad[0x18]; };
struct PadHexA8 { char Pad[0xA8]; };
struct PadHexB0 { char Pad[0xB0]; };
// using FPredictionKey = PadHex18;
// using FGameplayEventData = PadHexA8;
// using FPredictionKey = PadHex10;
using FGameplayEventData = PadHexB0;
// using FGameplayEventData = __int64;
struct FPredictionKey // todo move
{
// __int64 real;
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>("/Script/GameplayAbilities.PredictionKey");
return Struct;
}
static int GetStructSize() { return GetStruct()->GetPropertiesSize(); }
};
struct FGameplayEffectContextHandle
{
unsigned char UnknownData00[0x18]; // 0x0000(0x0018) MISSED OFFSET
};
struct FActiveGameplayEffectHandle
{
int Handle; // 0x0000(0x0004) (ZeroConstructor, IsPlainOldData)
bool bPassedFiltersAndWasExecuted; // 0x0004(0x0001) (ZeroConstructor, IsPlainOldData)
unsigned char UnknownData00[0x3]; // 0x0005(0x0003) MISSED OFFSET
};
struct FGameplayAbilitySpecContainer : public FFastArraySerializer
{
TArray<FGameplayAbilitySpec>& GetItems()
{
static auto ItemsOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpecContainer", "Items");
return *(TArray<FGameplayAbilitySpec>*)(__int64(this) + ItemsOffset);
}
};
class UAbilitySystemComponent : public UObject
{
public:
static inline FGameplayAbilitySpecHandle* (*GiveAbilityOriginal)(UAbilitySystemComponent*, FGameplayAbilitySpecHandle*, __int64 inSpec);
static inline bool (*InternalTryActivateAbilityOriginal)(UAbilitySystemComponent*, FGameplayAbilitySpecHandle Handle, PadHex10 InPredictionKey, UObject** OutInstancedAbility, void* OnGameplayAbilityEndedDelegate, const FGameplayEventData* TriggerEventData);
static inline bool (*InternalTryActivateAbilityOriginal2)(UAbilitySystemComponent*, FGameplayAbilitySpecHandle Handle, PadHex18 InPredictionKey, UObject** OutInstancedAbility, void* OnGameplayAbilityEndedDelegate, const FGameplayEventData* TriggerEventData);
void ClientActivateAbilityFailed(FGameplayAbilitySpecHandle AbilityToActivate, int16_t PredictionKey)
{
struct { FGameplayAbilitySpecHandle AbilityToActivate; int16_t PredictionKey; } UAbilitySystemComponent_ClientActivateAbilityFailed_Params{ AbilityToActivate, PredictionKey };
static auto fn = FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.ClientActivateAbilityFailed");
this->ProcessEvent(fn, &UAbilitySystemComponent_ClientActivateAbilityFailed_Params);
}
TArray<UAttributeSet*>& GetSpawnedAttributes()
{
static auto SpawnedAttributesOffset = GetOffset("SpawnedAttributes");
return Get<TArray<UAttributeSet*>>(SpawnedAttributesOffset);
}
FGameplayAbilitySpecContainer* GetActivatableAbilities()
{
static auto ActivatableAbilitiesOffset = this->GetOffset("ActivatableAbilities");
return GetPtr<FGameplayAbilitySpecContainer>(ActivatableAbilitiesOffset);
}
UAttributeSet* AddDefaultSubobjectSet(UAttributeSet* Subobject)
{
GetSpawnedAttributes().Add(Subobject);
return Subobject;
}
void ServerEndAbility(FGameplayAbilitySpecHandle AbilityToEnd, FGameplayAbilityActivationInfo* ActivationInfo, FPredictionKey* PredictionKey);
void ClientEndAbility(FGameplayAbilitySpecHandle AbilityToEnd, FGameplayAbilityActivationInfo* ActivationInfo);
void ClientCancelAbility(FGameplayAbilitySpecHandle AbilityToCancel, FGameplayAbilityActivationInfo* ActivationInfo);
bool HasAbility(UObject* DefaultAbility);
FActiveGameplayEffectHandle ApplyGameplayEffectToSelf(UClass* GameplayEffectClass, float Level, const FGameplayEffectContextHandle& EffectContext = FGameplayEffectContextHandle());
// FGameplayEffectContextHandle MakeEffectContext();
void RemoveActiveGameplayEffectBySourceEffect(UClass* GEClass, int StacksToRemove, UAbilitySystemComponent* Instigator);
void ConsumeAllReplicatedData(FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey* AbilityOriginalPredictionKey);
FGameplayAbilitySpecHandle GiveAbilityEasy(UClass* AbilityClass, UObject* SourceObject = nullptr, bool bDoNotRegive = true);
FGameplayAbilitySpec* FindAbilitySpecFromHandle(FGameplayAbilitySpecHandle Handle);
void RemoveActiveGameplayEffectBySourceEffect(UClass* GameplayEffect, UAbilitySystemComponent* InstigatorAbilitySystemComponent, int StacksToRemove);
void ClearAbility(const FGameplayAbilitySpecHandle& Handle);
static void InternalServerTryActivateAbilityHook(UAbilitySystemComponent* AbilitySystemComponent, FGameplayAbilitySpecHandle Handle, bool InputPressed, const FPredictionKey* PredictionKey, const FGameplayEventData* TriggerEventData);
};
void LoopSpecs(UAbilitySystemComponent* AbilitySystemComponent, std::function<void(FGameplayAbilitySpec*)> func);

View File

@@ -0,0 +1,270 @@
#include "AbilitySystemComponent.h"
#include "NetSerialization.h"
#include "Actor.h"
#include "FortPawn.h"
#include "FortPlayerController.h"
#include "FortPlayerStateAthena.h"
void LoopSpecs(UAbilitySystemComponent* AbilitySystemComponent, std::function<void(FGameplayAbilitySpec*)> func)
{
static auto ActivatableAbilitiesOffset = AbilitySystemComponent->GetOffset("ActivatableAbilities");
auto ActivatableAbilities = AbilitySystemComponent->GetPtr<FFastArraySerializer>(ActivatableAbilitiesOffset);
static auto ItemsOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpecContainer", "Items");
auto Items = (TArray<FGameplayAbilitySpec>*)(__int64(ActivatableAbilities) + ItemsOffset);
static auto SpecSize = FGameplayAbilitySpec::GetStructSize();
if (ActivatableAbilities && Items)
{
for (int i = 0; i < Items->Num(); ++i)
{
auto CurrentSpec = Items->AtPtr(i, SpecSize); // (FGameplayAbilitySpec*)(__int64(Items->Data) + (static_cast<long long>(SpecSize) * i));
func(CurrentSpec);
}
}
}
FActiveGameplayEffectHandle UAbilitySystemComponent::ApplyGameplayEffectToSelf(UClass* GameplayEffectClass, float Level, const FGameplayEffectContextHandle& EffectContext)
{
static auto BP_ApplyGameplayEffectToSelfFn = FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.BP_ApplyGameplayEffectToSelf");
struct
{
UClass* GameplayEffectClass; // (Parm, ZeroConstructor, IsPlainOldData)
float Level; // (Parm, ZeroConstructor, IsPlainOldData)
FGameplayEffectContextHandle EffectContext; // (Parm)
FActiveGameplayEffectHandle ReturnValue; // (Parm, OutParm, ReturnParm)
}UAbilitySystemComponent_BP_ApplyGameplayEffectToSelf_Params{GameplayEffectClass, Level, EffectContext};
this->ProcessEvent(BP_ApplyGameplayEffectToSelfFn, &UAbilitySystemComponent_BP_ApplyGameplayEffectToSelf_Params);
return UAbilitySystemComponent_BP_ApplyGameplayEffectToSelf_Params.ReturnValue;
}
/* FGameplayEffectContextHandle UAbilitySystemComponent::MakeEffectContext()
{
static auto MakeEffectContextFn = FindObject<UFunction>("/Script/GameplayAbilities.AbilitySystemComponent.MakeEffectContext");
FGameplayEffectContextHandle ContextHandle;
this->ProcessEvent(MakeEffectContextFn, &ContextHandle);
return ContextHandle;
} */
void UAbilitySystemComponent::ServerEndAbility(FGameplayAbilitySpecHandle AbilityToEnd, FGameplayAbilityActivationInfo* ActivationInfo, FPredictionKey* PredictionKey)
{
static auto ServerEndAbilityFn = FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerEndAbility");
auto Params = Alloc<void>(ServerEndAbilityFn->GetPropertiesSize());
if (!Params)
return;
static auto AbilityToEndOffset = FindOffsetStruct("/Script/GameplayAbilities.AbilitySystemComponent.ServerEndAbility", "AbilityToEnd");
static auto ActivationInfoOffset = FindOffsetStruct("/Script/GameplayAbilities.AbilitySystemComponent.ServerEndAbility", "ActivationInfo");
static auto PredictionKeyOffset = FindOffsetStruct("/Script/GameplayAbilities.AbilitySystemComponent.ServerEndAbility", "PredictionKey");
*(FGameplayAbilitySpecHandle*)(__int64(Params) + AbilityToEndOffset) = AbilityToEnd;
CopyStruct((FGameplayAbilityActivationInfo*)(__int64(Params) + ActivationInfoOffset), ActivationInfo, FGameplayAbilityActivationInfo::GetStructSize());
CopyStruct((FPredictionKey*)(__int64(Params) + PredictionKeyOffset), PredictionKey, FPredictionKey::GetStructSize());
this->ProcessEvent(ServerEndAbilityFn, Params);
VirtualFree(Params, 0, MEM_RELEASE);
}
void UAbilitySystemComponent::ClientEndAbility(FGameplayAbilitySpecHandle AbilityToEnd, FGameplayAbilityActivationInfo* ActivationInfo)
{
static auto ClientEndAbilityFn = FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.ClientEndAbility");
auto Params = Alloc(ClientEndAbilityFn->GetPropertiesSize());
static auto AbilityToEndOffset = FindOffsetStruct("/Script/GameplayAbilities.AbilitySystemComponent.ClientEndAbility", "AbilityToEnd");
static auto ActivationInfoOffset = FindOffsetStruct("/Script/GameplayAbilities.AbilitySystemComponent.ClientEndAbility", "ActivationInfo");
*(FGameplayAbilitySpecHandle*)(__int64(Params) + AbilityToEndOffset) = AbilityToEnd;
CopyStruct((FGameplayAbilityActivationInfo*)(__int64(Params) + ActivationInfoOffset), ActivationInfo, FGameplayAbilityActivationInfo::GetStructSize());
this->ProcessEvent(ClientEndAbilityFn, Params);
VirtualFree(Params, 0, MEM_RELEASE);
}
void UAbilitySystemComponent::ClientCancelAbility(FGameplayAbilitySpecHandle AbilityToCancel, FGameplayAbilityActivationInfo* ActivationInfo)
{
static auto ClientCancelAbilityFn = FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.ClientCancelAbility");
auto Params = Alloc(ClientCancelAbilityFn->GetPropertiesSize());
static auto AbilityToCancelOffset = FindOffsetStruct("/Script/GameplayAbilities.AbilitySystemComponent.ClientCancelAbility", "AbilityToCancel");
static auto ActivationInfoOffset = FindOffsetStruct("/Script/GameplayAbilities.AbilitySystemComponent.ClientCancelAbility", "ActivationInfo");
*(FGameplayAbilitySpecHandle*)(__int64(Params) + AbilityToCancelOffset) = AbilityToCancel;
CopyStruct((FGameplayAbilityActivationInfo*)(__int64(Params) + ActivationInfoOffset), ActivationInfo, FGameplayAbilityActivationInfo::GetStructSize());
this->ProcessEvent(ClientCancelAbilityFn, Params);
VirtualFree(Params, 0, MEM_RELEASE);
}
bool UAbilitySystemComponent::HasAbility(UObject* DefaultAbility)
{
auto ActivatableAbilities = GetActivatableAbilities();
auto& Items = ActivatableAbilities->GetItems();
for (int i = 0; i < Items.Num(); ++i)
{
auto Spec = Items.AtPtr(i, FGameplayAbilitySpec::GetStructSize());
if (Spec->GetAbility() == DefaultAbility)
return true;
}
return false;
}
void UAbilitySystemComponent::RemoveActiveGameplayEffectBySourceEffect(UClass* GEClass, int StacksToRemove, UAbilitySystemComponent* Instigator)
{
static auto RemoveActiveGameplayEffectBySourceEffectFn = FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.RemoveActiveGameplayEffectBySourceEffect");
struct { UClass* GameplayEffect; UObject* InstigatorAbilitySystemComponent; int StacksToRemove; } UAbilitySystemComponent_RemoveActiveGameplayEffectBySourceEffect_Params{ GEClass, Instigator, StacksToRemove };
this->ProcessEvent(RemoveActiveGameplayEffectBySourceEffectFn, &UAbilitySystemComponent_RemoveActiveGameplayEffectBySourceEffect_Params);
}
void UAbilitySystemComponent::ConsumeAllReplicatedData(FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey* AbilityOriginalPredictionKey)
{
// static auto AbilityTargetDataMapOffset = ActivatableAbilitiesOffset + FGameplayAbilitySpecContainerSize ?
return;
}
void UAbilitySystemComponent::InternalServerTryActivateAbilityHook(UAbilitySystemComponent* AbilitySystemComponent, FGameplayAbilitySpecHandle Handle, bool InputPressed, const FPredictionKey* PredictionKey, const FGameplayEventData* TriggerEventData) // https://github.com/EpicGames/UnrealEngine/blob/4.23/Engine/Plugins/Runtime/GameplayAbilities/Source/GameplayAbilities/Private/AbilitySystemComponent_Abilities.cpp#L1445
{
using UGameplayAbility = UObject;
auto Spec = AbilitySystemComponent->FindAbilitySpecFromHandle(Handle);
static auto PredictionKeyStruct = FindObject<UStruct>(L"/Script/GameplayAbilities.PredictionKey");
static auto PredictionKeySize = PredictionKeyStruct->GetPropertiesSize();
static auto CurrentOffset = FindOffsetStruct("/Script/GameplayAbilities.PredictionKey", "Current");
if (!Spec)
{
LOG_INFO(LogAbilities, "InternalServerTryActivateAbility. Rejecting ClientActivation of ability with invalid SpecHandle!");
AbilitySystemComponent->ClientActivateAbilityFailed(Handle, *(int16_t*)(__int64(PredictionKey) + CurrentOffset));
return;
}
AbilitySystemComponent->ConsumeAllReplicatedData(Handle, (FPredictionKey*)PredictionKey);
/* const */ UGameplayAbility * AbilityToActivate = Spec->GetAbility();
if (!AbilityToActivate)
{
LOG_ERROR(LogAbilities, "InternalServerTryActiveAbility. Rejecting ClientActivation of unconfigured spec ability!");
AbilitySystemComponent->ClientActivateAbilityFailed(Handle, *(int16_t*)(__int64(PredictionKey) + CurrentOffset));
return;
}
static auto InputPressedOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpec", "InputPressed");
UGameplayAbility* InstancedAbility = nullptr;
SetBitfield((PlaceholderBitfield*)(__int64(Spec) + InputPressedOffset), 1, true); // InputPressed = true
bool res = false;
if (PredictionKeySize == 0x10)
res = UAbilitySystemComponent::InternalTryActivateAbilityOriginal(AbilitySystemComponent, Handle, *(PadHex10*)PredictionKey, &InstancedAbility, nullptr, TriggerEventData);
else if (PredictionKeySize == 0x18)
res = UAbilitySystemComponent::InternalTryActivateAbilityOriginal2(AbilitySystemComponent, Handle, *(PadHex18*)PredictionKey, &InstancedAbility, nullptr, TriggerEventData);
else
LOG_ERROR(LogAbilities, "Prediction key size does not match with any of them!");
if (!res)
{
LOG_INFO(LogAbilities, "InternalServerTryActivateAbility. Rejecting ClientActivation of {}. InternalTryActivateAbility failed: ", AbilityToActivate->GetName());
AbilitySystemComponent->ClientActivateAbilityFailed(Handle, *(int16_t*)(__int64(PredictionKey) + CurrentOffset));
SetBitfield((PlaceholderBitfield*)(__int64(Spec) + InputPressedOffset), 1, false); // InputPressed = false
AbilitySystemComponent->GetActivatableAbilities()->MarkItemDirty(Spec);
}
else
{
// LOG_INFO(LogAbilities, "InternalServerTryActivateAbility. Activated {}", AbilityToActivate->GetName());
}
}
FGameplayAbilitySpecHandle UAbilitySystemComponent::GiveAbilityEasy(UClass* AbilityClass, UObject* SourceObject, bool bDoNotRegive)
{
if (!AbilityClass)
{
LOG_WARN(LogAbilities, "Invalid AbilityClass passed into GiveAbilityEasy!");
return FGameplayAbilitySpecHandle();
}
// LOG_INFO(LogDev, "Making spec!");
auto DefaultAbility = AbilityClass->CreateDefaultObject();
if (!DefaultAbility)
return FGameplayAbilitySpecHandle();
if (bDoNotRegive && HasAbility(DefaultAbility))
return FGameplayAbilitySpecHandle();
auto NewSpec = MakeNewSpec((UClass*)DefaultAbility, SourceObject, true);
// LOG_INFO(LogDev, "Made spec!");
FGameplayAbilitySpecHandle Handle;
GiveAbilityOriginal(this, &Handle, __int64(NewSpec));
return Handle;
}
FGameplayAbilitySpec* UAbilitySystemComponent::FindAbilitySpecFromHandle(FGameplayAbilitySpecHandle Handle)
{
FGameplayAbilitySpec* SpecToReturn = nullptr;
auto compareHandles = [&Handle, &SpecToReturn](FGameplayAbilitySpec* Spec) {
auto& CurrentHandle = Spec->GetHandle();
if (CurrentHandle.Handle == Handle.Handle)
{
SpecToReturn = Spec;
return;
}
};
LoopSpecs(this, compareHandles);
return SpecToReturn;
}
void UAbilitySystemComponent::RemoveActiveGameplayEffectBySourceEffect(UClass* GameplayEffect, UAbilitySystemComponent* InstigatorAbilitySystemComponent, int StacksToRemove)
{
static auto RemoveActiveGameplayEffectBySourceEffectFn = FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.RemoveActiveGameplayEffectBySourceEffect");
struct
{
UClass* GameplayEffect; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, UObjectWrapper, HasGetValueTypeHash, NativeAccessSpecifierPublic)
UAbilitySystemComponent* InstigatorAbilitySystemComponent; // (Parm, ZeroConstructor, InstancedReference, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
int StacksToRemove; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
} UAbilitySystemComponent_RemoveActiveGameplayEffectBySourceEffect_Params{GameplayEffect, InstigatorAbilitySystemComponent, StacksToRemove};
this->ProcessEvent(RemoveActiveGameplayEffectBySourceEffectFn, &UAbilitySystemComponent_RemoveActiveGameplayEffectBySourceEffect_Params);
}
void UAbilitySystemComponent::ClearAbility(const FGameplayAbilitySpecHandle& Handle)
{
if (!Addresses::ClearAbility)
{
LOG_INFO(LogDev, "Invalid clear ability!");
return;
}
static void (*ClearAbilityOriginal)(UAbilitySystemComponent* AbilitySystemComponent, const FGameplayAbilitySpecHandle& Handle) = decltype(ClearAbilityOriginal)(Addresses::ClearAbility);
ClearAbilityOriginal(this, Handle);
}

View File

@@ -0,0 +1,314 @@
#include "Actor.h"
#include "Transform.h"
#include "reboot.h"
#include "GameplayStatics.h"
bool AActor::HasAuthority()
{
static auto RoleOffset = GetOffset("Role");
return Get<uint8_t>(RoleOffset) == 3;
}
bool AActor::IsTearOff()
{
static auto bTearOffOffset = GetOffset("bTearOff");
static auto bTearOffFieldMask = GetFieldMask(GetProperty("bTearOff"));
return ReadBitfieldValue(bTearOffOffset, bTearOffFieldMask);
}
/* FORCEINLINE */ ENetDormancy& AActor::GetNetDormancy()
{
static auto NetDormancyOffset = GetOffset("NetDormancy");
return Get<ENetDormancy>(NetDormancyOffset);
}
int32& AActor::GetNetTag()
{
static auto NetTagOffset = GetOffset("NetTag");
return Get<int32>(NetTagOffset);
}
FTransform AActor::GetTransform()
{
FTransform Ret;
static auto fn = FindObject<UFunction>(L"/Script/Engine.Actor.GetTransform");
this->ProcessEvent(fn, &Ret);
return Ret;
}
/*
UWorld* AActor::GetWorld()
{
return GetWorld(); // for real
}
*/
void AActor::SetNetDormancy(ENetDormancy Dormancy)
{
static auto SetNetDormancyFn = FindObject<UFunction>(L"/Script/Engine.Actor.SetNetDormancy");
this->ProcessEvent(SetNetDormancyFn, &Dormancy);
}
AActor* AActor::GetOwner()
{
static auto GetOwnerFunction = FindObject<UFunction>(L"/Script/Engine.Actor.GetOwner");
AActor* Owner = nullptr;
this->ProcessEvent(GetOwnerFunction, &Owner);
return Owner;
}
void AActor::K2_DestroyActor()
{
static auto DestroyActorFn = FindObject<UFunction>("/Script/Engine.Actor.K2_DestroyActor");
this->ProcessEvent(DestroyActorFn);
}
UActorComponent* AActor::GetComponentByClass(class UClass* ComponentClass)
{
static auto fn = FindObject<UFunction>("/Script/Engine.Actor.GetComponentByClass");
struct
{
class UClass* ComponentClass; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, UObjectWrapper, HasGetValueTypeHash, NativeAccessSpecifierPublic)
UActorComponent* ReturnValue; // (ExportObject, Parm, OutParm, ZeroConstructor, ReturnParm, InstancedReference, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
} AActor_GetComponentByClass_Params{ComponentClass};
this->ProcessEvent(fn, &AActor_GetComponentByClass_Params);
return AActor_GetComponentByClass_Params.ReturnValue;
}
float AActor::GetDistanceTo(AActor* OtherActor)
{
static auto fn = FindObject<UFunction>("/Script/Engine.Actor.GetDistanceTo");
struct { AActor* OtherActor; float ReturnValue; } AActor_GetDistanceTo_Params{OtherActor};
this->ProcessEvent(fn, &AActor_GetDistanceTo_Params);
return AActor_GetDistanceTo_Params.ReturnValue;
}
FVector AActor::GetActorScale3D()
{
static auto GetActorScale3DFn = FindObject<UFunction>("/Script/Engine.Actor.GetActorScale3D");
FVector Scale3D;
this->ProcessEvent(GetActorScale3DFn, &Scale3D);
return Scale3D;
}
FVector AActor::GetActorLocation()
{
static auto K2_GetActorLocationFn = FindObject<UFunction>("/Script/Engine.Actor.K2_GetActorLocation");
FVector ret;
this->ProcessEvent(K2_GetActorLocationFn, &ret);
return ret;
}
FVector AActor::GetActorForwardVector()
{
static auto GetActorForwardVectorFn = FindObject<UFunction>("/Script/Engine.Actor.GetActorForwardVector");
FVector ret;
this->ProcessEvent(GetActorForwardVectorFn, &ret);
return ret;
}
FVector AActor::GetActorRightVector()
{
static auto GetActorRightVectorFn = FindObject<UFunction>("/Script/Engine.Actor.GetActorRightVector");
FVector ret;
this->ProcessEvent(GetActorRightVectorFn, &ret);
return ret;
}
FVector AActor::GetActorUpVector()
{
static auto GetActorUpVectorFn = FindObject<UFunction>("/Script/Engine.Actor.GetActorUpVector");
FVector ret;
this->ProcessEvent(GetActorUpVectorFn, &ret);
return ret;
}
FRotator AActor::GetActorRotation()
{
static auto K2_GetActorRotationFn = FindObject<UFunction>(L"/Script/Engine.Actor.K2_GetActorRotation");
FRotator ret;
this->ProcessEvent(K2_GetActorRotationFn, &ret);
return ret;
}
void AActor::FlushNetDormancy()
{
static auto fn = FindObject<UFunction>(L"/Script/Engine.Actor.FlushNetDormancy");
this->ProcessEvent(fn);
}
bool AActor::TeleportTo(const FVector& DestLocation, const FRotator& DestRotation)
{
static auto fn = FindObject<UFunction>(L"/Script/Engine.Actor.K2_TeleportTo");
struct
{
struct FVector DestLocation; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
struct FRotator DestRotation; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, NativeAccessSpecifierPublic)
bool ReturnValue; // (Parm, OutParm, ZeroConstructor, ReturnParm, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
} AActor_K2_TeleportTo_Params{DestLocation, DestRotation};
this->ProcessEvent(fn, &AActor_K2_TeleportTo_Params);
return AActor_K2_TeleportTo_Params.ReturnValue;
}
bool AActor::IsActorBeingDestroyed()
{
static auto bActorIsBeingDestroyedOffset = GetOffset("bActorIsBeingDestroyed");
static auto bActorIsBeingDestroyedFieldMask = GetFieldMask(GetProperty("bActorIsBeingDestroyed"));
return ReadBitfieldValue(bActorIsBeingDestroyedOffset, bActorIsBeingDestroyedFieldMask);
}
bool AActor::IsNetStartup()
{
static auto bNetStartupOffset = GetOffset("bNetStartup");
static auto bNetStartupFieldMask = GetFieldMask(GetProperty("bNetStartup"));
return ReadBitfieldValue(bNetStartupOffset, bNetStartupFieldMask);
}
void AActor::SetOwner(AActor* Owner)
{
static auto SetOwnerFn = FindObject<UFunction>(L"/Script/Engine.Actor.SetOwner");
this->ProcessEvent(SetOwnerFn, &Owner);
}
void AActor::ForceNetUpdate()
{
static auto ForceNetUpdateFn = FindObject<UFunction>(L"/Script/Engine.Actor.ForceNetUpdate");
this->ProcessEvent(ForceNetUpdateFn);
}
bool AActor::IsNetStartupActor()
{
return IsNetStartup(); // The implementation on this function depends on the version.
}
bool AActor::IsPendingKillPending()
{
return IsActorBeingDestroyed() || !IsValidChecked(this);
}
float& AActor::GetNetUpdateFrequency()
{
static auto NetUpdateFrequencyOffset = GetOffset("NetUpdateFrequency");
return Get<float>(NetUpdateFrequencyOffset);
}
float& AActor::GetMinNetUpdateFrequency()
{
static auto MinNetUpdateFrequencyOffset = GetOffset("MinNetUpdateFrequency");
return Get<float>(MinNetUpdateFrequencyOffset);
}
const AActor* AActor::GetNetOwner() const
{
static int GetNetOwnerOffset = 0x448; // 1.11
const AActor* (*GetNetOwnerOriginal)(const AActor*) = decltype(GetNetOwnerOriginal)(this->VFTable[GetNetOwnerOffset / 8]);
return GetNetOwnerOriginal(this);
}
void AActor::GetActorEyesViewPoint(FVector* OutLocation, FRotator* OutRotation) const
{
static auto GetActorEyesViewPointFn = FindObject<UFunction>(L"/Script/Engine.Actor.GetActorEyesViewPoint");
struct
{
FVector OutLocation; // (Parm, OutParm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FRotator OutRotation; // (Parm, OutParm, ZeroConstructor, IsPlainOldData, NoDestructor, NativeAccessSpecifierPublic)
} AActor_GetActorEyesViewPoint_Params{};
this->ProcessEvent(GetActorEyesViewPointFn, &AActor_GetActorEyesViewPoint_Params);
*OutLocation = AActor_GetActorEyesViewPoint_Params.OutLocation;
*OutRotation = AActor_GetActorEyesViewPoint_Params.OutRotation;
}
AActor* AActor::GetClosestActor(UClass* ActorClass, float DistMax, std::function<bool(AActor*)> AdditionalCheck)
{
float TargetDist = FLT_MAX;
AActor* TargetActor = nullptr;
TArray<AActor*> AllActors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), ActorClass);
auto ActorLocation = GetActorLocation();
for (int i = 0; i < AllActors.Num(); ++i)
{
auto Actor = AllActors.at(i);
if (!Actor || Actor == this)
continue;
if (!AdditionalCheck(Actor))
continue;
auto CurrentActorLocation = Actor->GetActorLocation();
int Dist = float(sqrtf(powf(CurrentActorLocation.X - ActorLocation.X, 2.0) + powf(CurrentActorLocation.Y - ActorLocation.Y, 2.0) + powf(CurrentActorLocation.Z - ActorLocation.Z, 2.0))) / 100.f;
if (Dist <= DistMax && Dist < TargetDist)
{
TargetDist = Dist;
TargetActor = Actor;
}
}
AllActors.Free();
return TargetActor;
}
bool AActor::IsAlwaysRelevant()
{
static auto bAlwaysRelevantOffset = GetOffset("bAlwaysRelevant");
static auto bAlwaysRelevantFieldMask = GetFieldMask(GetProperty("bAlwaysRelevant"));
return ReadBitfieldValue(bAlwaysRelevantOffset, bAlwaysRelevantFieldMask);
}
bool AActor::UsesOwnerRelevancy()
{
static auto bNetUseOwnerRelevancyOffset = GetOffset("bNetUseOwnerRelevancy");
static auto bNetUseOwnerRelevancyFieldMask = GetFieldMask(GetProperty("bNetUseOwnerRelevancy"));
return ReadBitfieldValue(bNetUseOwnerRelevancyOffset, bNetUseOwnerRelevancyFieldMask);
}
bool AActor::IsOnlyRelevantToOwner()
{
static auto bOnlyRelevantToOwnerOffset = GetOffset("bOnlyRelevantToOwner");
static auto bOnlyRelevantToOwnerFieldMask = GetFieldMask(GetProperty("bOnlyRelevantToOwner"));
return ReadBitfieldValue(bOnlyRelevantToOwnerOffset, bOnlyRelevantToOwnerFieldMask);
}
bool AActor::CanBeDamaged()
{
static auto bCanBeDamagedOffset = GetOffset("bCanBeDamaged");
static auto bCanBeDamagedFieldMask = GetFieldMask(GetProperty("bCanBeDamaged"));
return ReadBitfieldValue(bCanBeDamagedOffset, bCanBeDamagedFieldMask);
}
void AActor::SetCanBeDamaged(bool NewValue)
{
static auto bCanBeDamagedOffset = GetOffset("bCanBeDamaged");
static auto bCanBeDamagedFieldMask = GetFieldMask(GetProperty("bCanBeDamaged"));
SetBitfieldValue(bCanBeDamagedOffset, bCanBeDamagedFieldMask, NewValue);
}
UClass* AActor::StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/Engine.Actor");
return Class;
}

View File

@@ -0,0 +1,70 @@
#pragma once
#include "Object.h"
#include "anticheat.h"
enum class ENetDormancy : uint8_t
{
DORM_Never = 0,
DORM_Awake = 1,
DORM_DormantAll = 2,
DORM_DormantPartial = 3,
DORM_Initial = 4,
DORN_MAX = 5,
ENetDormancy_MAX = 6
};
class AActor : public UObject
{
public:
struct FTransform GetTransform();
// class UWorld* GetWorld();
bool HasAuthority();
bool IsTearOff();
/* FORCEINLINE */ ENetDormancy& GetNetDormancy();
int32& GetNetTag();
void SetNetDormancy(ENetDormancy Dormancy);
AActor* GetOwner();
struct FVector GetActorScale3D();
struct FVector GetActorLocation();
struct FVector GetActorForwardVector();
struct FVector GetActorRightVector();
struct FVector GetActorUpVector();
void K2_DestroyActor();
class UActorComponent* GetComponentByClass(class UClass* ComponentClass);
float GetDistanceTo(AActor* OtherActor);
struct FRotator GetActorRotation();
void FlushNetDormancy();
bool TeleportTo(const FVector& DestLocation, const FRotator& DestRotation);
bool IsActorBeingDestroyed();
bool IsNetStartup();
bool IsAlwaysRelevant();
bool UsesOwnerRelevancy();
bool IsOnlyRelevantToOwner();
bool CanBeDamaged();
void SetCanBeDamaged(bool NewValue);
void SetOwner(AActor* Owner);
void ForceNetUpdate();
bool IsNetStartupActor();
bool IsPendingKillPending();
float& GetNetUpdateFrequency();
float& GetMinNetUpdateFrequency();
const AActor* GetNetOwner() const;
void GetActorEyesViewPoint(FVector* OutLocation, FRotator* OutRotation) const;
AActor* GetClosestActor(UClass* ActorClass, float DistMax, std::function<bool(AActor*)> AdditionalCheck = [&](AActor*) { return true; });
bool IsRelevancyOwnerFor(const AActor* ReplicatedActor, const AActor* ActorOwner, const AActor* ConnectionActor) const
{
// we should call virtual function but eh
// return (ActorOwner == this);
static auto IsRelevancyOwnerForOffset = 0x428;
bool (*IsRelevancyOwnerForOriginal)(const AActor* Actor, const AActor * ReplicatedActor, const AActor * ActorOwner, const AActor * ConnectionActor) =
decltype(IsRelevancyOwnerForOriginal)(this->VFTable[IsRelevancyOwnerForOffset / 8]);
return IsRelevancyOwnerForOriginal(this, ReplicatedActor, ActorOwner, ConnectionActor);
}
static class UClass* StaticClass();
};

View File

@@ -0,0 +1,32 @@
#pragma once
#include "Channel.h"
#include "NetworkGuid.h"
class UActorChannel : public UChannel
{
public:
double& GetLastUpdateTime()
{
static auto LastUpdateTimeOffset = GetOffset("Actor") + 8 + 4 + 4 + 8; // checked on 4.19
return Get<double>(LastUpdateTimeOffset);
}
double& GetRelevantTime()
{
static auto RelevantTimeOffset = GetOffset("Actor") + 8 + 4 + 4; // checked on 4.19
return Get<double>(RelevantTimeOffset);
}
AActor*& GetActor()
{
static auto ActorOffset = GetOffset("Actor");
return Get<AActor*>(ActorOffset);
}
void Close()
{
static void (*ActorChannelClose)(UActorChannel*) = decltype(ActorChannelClose)(Addresses::ActorChannelClose);
ActorChannelClose(this);
}
};

View File

@@ -0,0 +1,11 @@
#include "ActorComponent.h"
#include "reboot.h"
AActor* UActorComponent::GetOwner()
{
auto GetOwnerFn = FindObject<UFunction>(L"/Script/Engine.ActorComponent.GetOwner");
AActor* Owner;
this->ProcessEvent(GetOwnerFn, &Owner);
return Owner;
}

View File

@@ -0,0 +1,9 @@
#pragma once
#include "Actor.h"
class UActorComponent : public UObject
{
public:
AActor* GetOwner();
};

View File

@@ -0,0 +1,73 @@
// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "inc.h"
/**
* Does a boolean AND of the ::Value static members of each type, but short-circuits if any Type::Value == false.
*/
template <typename... Types>
struct TAnd;
template <bool LHSValue, typename... RHS>
struct TAndValue
{
enum { Value = TAnd<RHS...>::Value };
};
template <typename... RHS>
struct TAndValue<false, RHS...>
{
enum { Value = false };
};
template <typename LHS, typename... RHS>
struct TAnd<LHS, RHS...> : TAndValue<LHS::Value, RHS...>
{
};
template <>
struct TAnd<>
{
enum { Value = true };
};
/**
* Does a boolean OR of the ::Value static members of each type, but short-circuits if any Type::Value == true.
*/
template <typename... Types>
struct TOr;
template <bool LHSValue, typename... RHS>
struct TOrValue
{
enum { Value = TOr<RHS...>::Value };
};
template <typename... RHS>
struct TOrValue<true, RHS...>
{
enum { Value = true };
};
template <typename LHS, typename... RHS>
struct TOr<LHS, RHS...> : TOrValue<LHS::Value, RHS...>
{
};
template <>
struct TOr<>
{
enum { Value = false };
};
/**
* Does a boolean NOT of the ::Value static members of the type.
*/
template <typename Type>
struct TNot
{
enum { Value = !Type::Value };
};

View File

@@ -0,0 +1,415 @@
#pragma once
#include "inc.h"
#include "addresses.h"
#include "MemoryOps.h"
#include "ContainerAllocationPolicies.h"
struct FMemory
{
static inline void* (*Realloc)(void* Original, SIZE_T Count, uint32_t Alignment /* = DEFAULT_ALIGNMENT */);
};
template <typename T = __int64>
static T* AllocUnreal(size_t Size)
{
return (T*)FMemory::Realloc(0, Size, 0);
}
template<typename InElementType> //, typename InAllocatorType>
class TArray
{
// protected:
public:
friend class FString;
using ElementAllocatorType = InElementType*;
using SizeType = int32;
ElementAllocatorType Data = nullptr; // AllocatorInstance;
SizeType ArrayNum;
SizeType ArrayMax;
public:
inline InElementType& At(int i, size_t Size = sizeof(InElementType)) const { return *(InElementType*)(__int64(Data) + (static_cast<long long>(Size) * i)); }
inline InElementType& at(int i, size_t Size = sizeof(InElementType)) const { return *(InElementType*)(__int64(Data) + (static_cast<long long>(Size) * i)); }
inline InElementType* AtPtr(int i, size_t Size = sizeof(InElementType)) const { return (InElementType*)(__int64(Data) + (static_cast<long long>(Size) * i)); }
bool IsValidIndex(int i) { return i > 0 && i < ArrayNum; }
ElementAllocatorType& GetData() const { return Data; }
ElementAllocatorType& GetData() { return Data; }
void Reserve(int Number, size_t Size = sizeof(InElementType))
{
// LOG_INFO(LogDev, "ArrayNum {}", ArrayNum);
// Data = (InElementType*)FMemory::Realloc(Data, (ArrayMax = ArrayNum + Number) * Size, 0);
Data = /* (ArrayMax - ArrayNum) >= ArrayNum ? Data : */ (InElementType*)FMemory::Realloc(Data, (ArrayMax = Number + ArrayNum) * Size, 0);
}
int CalculateSlackReserve(SizeType NumElements, SIZE_T NumBytesPerElement) const
{
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 RefitArray(SIZE_T NumBytesPerElement = sizeof(InElementType))
{
auto newNum = ArrayNum;
// newNum = FMemory::QuantizeSize(NumBytesPerElement * newNum, 0) >> 4
ArrayMax = newNum;
if (Data || ArrayNum)
{
Data = false ? (InElementType*)VirtualAlloc(0, newNum * NumBytesPerElement, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE) :
(InElementType*)FMemory::Realloc(Data, newNum * NumBytesPerElement, 0);
}
}
int AddUninitialized2(SIZE_T NumBytesPerElement = sizeof(InElementType))
{
const int OldArrayNum = ArrayNum;
ArrayNum = OldArrayNum + 1;
if (OldArrayNum + 1 > ArrayMax)
{
RefitArray(NumBytesPerElement);
// ResizeArray(ArrayNum, NumBytesPerElement);
}
return OldArrayNum;
}
void CopyFromArray(TArray<InElementType>& OtherArray, SIZE_T NumBytesPerElement = sizeof(InElementType))
{
if (!OtherArray.ArrayNum && !ArrayMax) // so if the new array has nothing, and we currently have nothing allocated, then we can just return
{
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))
{
if (NewMax)
{
NewMax = CalculateSlackReserve(NewMax, ElementSize);
}
if (NewMax != PrevMax)
{
int ReserveCount = NewMax - PrevMax; // IDK TODO Milxnor
Reserve(ReserveCount, ElementSize);
// AllocatorInstance.ResizeAllocation(0, NewMax, ElementSize);
}
ArrayMax = NewMax;
}
template <typename OtherElementType, typename OtherSizeType>
void CopyToEmpty(const OtherElementType* OtherData, OtherSizeType OtherNum, SizeType PrevMax, SizeType ExtraSlack, int ElementSize = sizeof(InElementType))
{
SizeType NewNum = (SizeType)OtherNum;
// checkf((OtherSizeType)NewNum == OtherNum, TEXT("Invalid number of elements to add to this array type: %llu"), (unsigned long long)NewNum);
// checkSlow(ExtraSlack >= 0);
ArrayNum = NewNum;
if (OtherNum || ExtraSlack || PrevMax)
{
ResizeForCopy(NewNum + ExtraSlack, PrevMax);
ConstructItems<InElementType>(GetData(), OtherData, OtherNum);
}
else
{
ArrayMax = 0; // AllocatorInstance.GetInitialCapacity();
}
}
FORCEINLINE TArray(const TArray& Other)
{
CopyToEmpty(Other.Data, Other.Num(), 0, 0);
}
*/
TArray() : Data(nullptr), ArrayNum(0), ArrayMax(0) {}
inline int Num() const { return ArrayNum; }
inline int size() const { return ArrayNum; }
/* FORCENOINLINE void ResizeTo(int32 NewMax)
{
if (NewMax)
{
NewMax = AllocatorInstance.CalculateSlackReserve(NewMax, sizeof(ElementType));
}
if (NewMax != ArrayMax)
{
ArrayMax = NewMax;
AllocatorInstance.ResizeAllocation(ArrayNum, ArrayMax, sizeof(ElementType));
}
}
void Empty(int32 Slack = 0)
{
// DestructItems(GetData(), ArrayNum);
// checkSlow(Slack >= 0);
ArrayNum = 0;
if (ArrayMax != Slack)
{
ResizeTo(Slack);
}
}
void Reset(int32 NewSize = 0)
{
// If we have space to hold the excepted size, then don't reallocate
if (NewSize <= ArrayMax)
{
// DestructItems(GetData(), ArrayNum);
ArrayNum = 0;
}
else
{
Empty(NewSize);
}
} */
void RemoveAtImpl(int32 Index, int32 Count, bool bAllowShrinking)
{
if (Count)
{
// CheckInvariants();
// checkSlow((Count >= 0) & (Index >= 0) & (Index + Count <= ArrayNum));
// DestructItems(GetData() + Index, Count); // TODO milxnor
// Skip memmove in the common case that there is nothing to move.
int32 NumToMove = ArrayNum - Index - Count;
if (NumToMove)
{
/* FMemory::Memmove
(
(uint8*)AllocatorInstance.GetAllocation() + (Index) * sizeof(ElementType),
(uint8*)AllocatorInstance.GetAllocation() + (Index + Count) * sizeof(ElementType),
NumToMove * sizeof(ElementType)
); */
// memmove(Data + (Index) * sizeof(InElementType), Data + (Index + Count) * sizeof(InElementType), NumToMove * sizeof(InElementType)); // i think this wrong
}
ArrayNum -= Count;
if (bAllowShrinking)
{
// ResizeShrink(); // TODO milxnor
}
}
}
FORCEINLINE SizeType CalculateSlackGrow(SizeType NumElements, SizeType NumAllocatedElements, SIZE_T NumBytesPerElement) const
{
return ArrayMax - NumElements;
}
template <typename CountType>
FORCEINLINE void RemoveAt(int32 Index, CountType Count, bool bAllowShrinking = true)
{
// static_assert(!TAreTypesEqual<CountType, bool>::Value, "TArray::RemoveAt: unexpected bool passed as the Count argument");
RemoveAtImpl(Index, Count, bAllowShrinking);
}
FORCENOINLINE void ResizeGrow(int32 OldNum, size_t Size = sizeof(InElementType))
{
// LOG_INFO(LogMemory, "FMemory::Realloc: {}", __int64(FMemory::Realloc));
ArrayMax = ArrayNum; // CalculateSlackGrow(/* ArrayNum */ OldNum, ArrayMax, Size);
// AllocatorInstance.ResizeAllocation(OldNum, ArrayMax, sizeof(ElementType));
// LOG_INFO(LogMemory, "ArrayMax: {} Size: {}", ArrayMax, Size);
Data = (InElementType*)FMemory::Realloc(Data, ArrayNum * Size, 0);
}
FORCEINLINE int32 AddUninitialized(int32 Count = 1, size_t Size = sizeof(InElementType))
{
// CheckInvariants();
if (Count < 0)
{
return 0;
}
const int32 OldNum = ArrayNum;
if ((ArrayNum += Count) > ArrayMax)
{
ResizeGrow(OldNum, Size);
}
return OldNum;
}
FORCEINLINE int32 Emplace(const InElementType& New, size_t Size = sizeof(InElementType))
{
const int32 Index = AddUninitialized(1, Size); // resizes array
memcpy_s((InElementType*)(__int64(Data) + (Index * Size)), Size, (void*)&New, Size);
// new(GetData() + Index) ElementType(Forward<ArgsType>(Args)...);
return Index;
}
/* int Add(const InElementType& New, int Size = sizeof(InElementType))
{
return Emplace(New, Size);
} */
int AddPtr(InElementType* New, size_t Size = sizeof(InElementType))
{
// LOG_INFO(LogDev, "ArrayMax: {}", ArrayMax);
if ((ArrayNum + 1) > ArrayMax)
{
Reserve(1, Size);
}
if (Data)
{
memcpy_s((InElementType*)(__int64(Data) + (ArrayNum * Size)), Size, (void*)New, Size);
++ArrayNum;
return ArrayNum; // - 1;
}
return -1;
}
int Add(const InElementType& New, size_t Size = sizeof(InElementType))
{
// LOG_INFO(LogDev, "ArrayMax: {}", ArrayMax);
if ((ArrayNum + 1) > ArrayMax)
{
Reserve(1, Size);
}
if (Data)
{
memcpy_s((InElementType*)(__int64(Data) + (ArrayNum * Size)), Size, (void*)&New, Size);
++ArrayNum;
return ArrayNum; // - 1;
}
return -1;
}
void FreeGood(SizeType Size = sizeof(InElementType))
{
if (Data)
{
if (true)
{
static void (*FreeOriginal)(void* Original) = decltype(FreeOriginal)(Addresses::Free);
if (FreeOriginal)
FreeOriginal(Data);
}
else
{
VirtualFree(Data, 0, MEM_RELEASE);
}
}
Data = nullptr;
ArrayNum = 0;
ArrayMax = 0;
}
void FreeReal(SizeType Size = sizeof(InElementType))
{
if (!IsBadReadPtr(Data, 8) && ArrayNum > 0 && sizeof(InElementType) > 0)
{
for (int i = 0; i < ArrayNum; ++i)
{
auto current = AtPtr(i, Size);
RtlSecureZeroMemory(current, Size);
}
// VirtualFree(Data, _msize(Data), MEM_RELEASE);
// VirtualFree(Data, sizeof(InElementType) * ArrayNum, MEM_RELEASE); // ik this does nothing
/* static void (*FreeOriginal)(void*) = decltype(FreeOriginal)(Addresses::Free);
if (FreeOriginal)
{
FreeOriginal(Data);
}
else */
{
auto res = VirtualFree(Data, 0, MEM_RELEASE);
// auto res = VirtualFree(Data, sizeof(InElementType) * ArrayNum, MEM_RELEASE);
LOG_INFO(LogDev, "Free: {} aa: 0x{:x}", res, res ? 0 : GetLastError());
}
}
Data = nullptr;
ArrayNum = 0;
ArrayMax = 0;
}
void Free()
{
if (Data && ArrayNum > 0 && sizeof(InElementType) > 0)
{
// VirtualFree(Data, _msize(Data), MEM_RELEASE);
VirtualFree(Data, sizeof(InElementType) * ArrayNum, MEM_RELEASE); // ik this does nothing
// VirtualFree(Data, 0, MEM_RELEASE);
}
Data = nullptr;
ArrayNum = 0;
ArrayMax = 0;
}
bool Remove(const int Index, size_t Size = sizeof(InElementType))
{
// return false;
if (Index < ArrayNum)
{
if (Index != ArrayNum - 1)
{
memcpy_s(&at(Index, Size), Size, &at(ArrayNum - 1, Size), Size);
// Data[Index] = Data[ArrayNum - 1];
}
--ArrayNum;
return true;
}
return false;
}
};

View File

@@ -0,0 +1,61 @@
#pragma once
#include "log.h"
#include "inc.h"
/*
#ifdef PROD
#define UE_DEBUG_BREAK() ((void)0)
#else
#define UE_DEBUG_BREAK() ((void)(FWindowsPlatformMisc::IsDebuggerPresent() && (__debugbreak(), 1)))
#endif
#ifndef PROD
#define _DebugBreakAndPromptForRemote() \
if (!FPlatformMisc::IsDebuggerPresent()) { FPlatformMisc::PromptForRemoteDebugging(false); } UE_DEBUG_BREAK();
#else
#define _DebugBreakAndPromptForRemote()
#endif
#define CA_ASSUME( Expr ) // Todo move to Misc/CoreMiscDefines.h
namespace FDebug
{
template <typename FmtType, typename... Types>
static void LogAssertFailedMessage(const char* Expr, const char* File, int32 Line, const FmtType& Fmt, Types... Args)
{
// static_assert(TIsArrayOrRefOfType<FmtType, TCHAR>::Value, "Formatting string must be a TCHAR array.");
// tatic_assert(TAnd<TIsValidVariadicFunctionArg<Types>...>::Value, "Invalid argument(s) passed to FDebug::LogAssertFailedMessage");
LOG_ERROR(LogDev, "Assert failed message {} {}", File, Line);
// LogAssertFailedMessageImpl(Expr, File, Line, Fmt, Args...);
}
void __cdecl AssertFailed(const char* Expr, const char* File, int32 Line, const wchar_t* Format = TEXT(""), ...)
{
LOG_ERROR(LogDev, "Assert failed {} {}", File, Line);
/*
if (GIsCriticalError)
{
return;
}
// This is not perfect because another thread might crash and be handled before this assert
// but this static varible will report the crash as an assert. Given complexity of a thread
// aware solution, this should be good enough. If crash reports are obviously wrong we can
// look into fixing this.
bHasAsserted = true;
TCHAR DescriptionString[4096];
GET_VARARGS(DescriptionString, ARRAY_COUNT(DescriptionString), ARRAY_COUNT(DescriptionString) - 1, Format, Format);
TCHAR ErrorString[MAX_SPRINTF];
FCString::Sprintf(ErrorString, TEXT("%s"), ANSI_TO_TCHAR(Expr));
GError->Logf(TEXT("Assertion failed: %s") FILE_LINE_DESC TEXT("\n%s\n"), ErrorString, ANSI_TO_TCHAR(File), Line, DescriptionString);
}
}
*/
// #define check(expr) { if(UNLIKELY(!(expr))) { FDebug::LogAssertFailedMessage( #expr, __FILE__, __LINE__, TEXT("") ); _DebugBreakAndPromptForRemote(); FDebug::AssertFailed( #expr, __FILE__, __LINE__ ); CA_ASSUME(false); } }

View File

@@ -0,0 +1,26 @@
#pragma once
#include "PersistentObjectPtr.h"
#include "StringAssetReference.h"
#include "reboot.h"
class FAssetPtr : public TPersistentObjectPtr<FStringAssetReference>
{
public:
};
template<class T = UObject>
class TAssetPtr
{
public:
FAssetPtr AssetPtr;
T* Get()
{
if (!AssetPtr.ObjectID.AssetLongPathname.IsValid())
return nullptr;
return FindObject<T>(AssetPtr.ObjectID.AssetLongPathname.ToString());
}
};

View File

@@ -0,0 +1,44 @@
#pragma once
#include "BuildingGameplayActor.h"
#include "AthenaBarrierObjective.h"
struct FBarrierFlagDisplayData
{
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>("/Script/FortniteGame.BarrierFlagDisplayData");
return Struct;
}
static int GetStructSize() { return GetStruct()->GetPropertiesSize(); }
UStaticMesh* GetHeadMesh()
{
static auto HeadMeshOffset = FindOffsetStruct("/Script/FortniteGame.BarrierFlagDisplayData", "HeadMesh");
return *(UStaticMesh**)(__int64(this) + HeadMeshOffset);
}
FVector& GetMeshScale()
{
static auto MeshScaleOffset = FindOffsetStruct("/Script/FortniteGame.BarrierFlagDisplayData", "MeshScale");
return *(FVector*)(__int64(this) + MeshScaleOffset);
}
};
class AAthenaBarrierFlag : public ABuildingGameplayActor
{
public:
EBarrierFoodTeam& GetFoodTeam()
{
static auto FoodTeamOffset = GetOffset("FoodTeam");
return Get<EBarrierFoodTeam>(FoodTeamOffset);
}
FBarrierFlagDisplayData* GetDisplayData(EBarrierFoodTeam FoodTeam)
{
static auto FoodDisplayDataOffset = GetOffset("FoodDisplayData");
auto FoodDisplayData = Get<FBarrierFlagDisplayData*>(FoodDisplayDataOffset); // Array of size 2
return &FoodDisplayData[(int)FoodTeam];
}
};

View File

@@ -0,0 +1,59 @@
#pragma once
#include "BuildingGameplayActor.h"
using UStaticMesh = UObject;
using UMaterialInterface = UObject;
enum class EBarrierFoodTeam : uint8_t
{
Burger = 0,
Tomato = 1,
MAX = 2
};
struct FBarrierObjectiveDisplayData
{
UStaticMesh* HeadMesh; // 0x0000(0x0008) (Edit, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FVector MeshScale; // 0x0008(0x000C) (Edit, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FVector MeshRelativeOffset; // 0x0014(0x000C) (Edit, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
TArray<UMaterialInterface*> MaterialsToSwap; // 0x0020(0x0010) (Edit, ZeroConstructor, NativeAccessSpecifierPublic)
};
class AAthenaBarrierObjective : public ABuildingGameplayActor
{
public:
void SetHeadMesh(UStaticMesh* NewMesh, const FVector& NewScale, const FVector& NewOffset, const TArray<UMaterialInterface*>& MaterialsToSwap)
{
static auto SetHeadMeshFn = FindObject<UFunction>("/Script/FortniteGame.AthenaBarrierObjective.SetHeadMesh");
struct
{
UStaticMesh* NewMesh; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FVector NewScale; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FVector NewOffset; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
TArray<UMaterialInterface*> MaterialsToSwap; // (ConstParm, Parm, OutParm, ZeroConstructor, ReferenceParm, NativeAccessSpecifierPublic)
} AAthenaBarrierObjective_SetHeadMesh_Params{ NewMesh, NewScale, NewOffset, MaterialsToSwap };
this->ProcessEvent(SetHeadMeshFn, &AAthenaBarrierObjective_SetHeadMesh_Params);
}
EBarrierFoodTeam& GetFoodTeam()
{
static auto FoodTeamOffset = GetOffset("FoodTeam");
return Get<EBarrierFoodTeam>(FoodTeamOffset);
}
FBarrierObjectiveDisplayData* GetFoodDisplayData(EBarrierFoodTeam FoodTeam)
{
static auto FoodDisplayDataOffset = GetOffset("FoodDisplayData");
auto FoodDisplayData = Get<FBarrierObjectiveDisplayData*>(FoodDisplayDataOffset); // Array size of 2
return &FoodDisplayData[(int)FoodTeam];
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.AthenaBarrierObjective");
return Class;
}
};

View File

@@ -0,0 +1,8 @@
#pragma once
#include "BuildingGameplayActor.h"
class AAthenaBigBaseWall : public ABuildingGameplayActor
{
public:
};

View File

@@ -0,0 +1,161 @@
#include "AthenaMarkerComponent.h"
#include "FortPlayerControllerAthena.h"
#include "Text.h"
#include "KismetTextLibrary.h"
void UAthenaMarkerComponent::ServerAddMapMarkerHook(UAthenaMarkerComponent* MarkerComponent, FFortClientMarkerRequest MarkerRequest)
{
auto Owner = MarkerComponent->GetOwner();
AFortPlayerControllerAthena* PlayerController = Cast<AFortPlayerControllerAthena>(Owner);
if (!PlayerController)
return;
AFortPlayerStateAthena* PlayerState = Cast<AFortPlayerStateAthena>(PlayerController->GetPlayerState());
if (!PlayerState)
return;
auto MarkerRequestPtr = &MarkerRequest;
bool useRealloc = false;
auto MarkerData = Alloc<FFortWorldMarkerData>(FFortWorldMarkerData::GetStructSize(), useRealloc);
static auto IconOffset = FindOffsetStruct("/Script/FortniteGame.MarkedActorDisplayInfo", "Icon");
static auto DisplayNameOffset = FindOffsetStruct("/Script/FortniteGame.MarkedActorDisplayInfo", "DisplayName");
static auto WorldPositionOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "WorldPosition", false);
static auto bIncludeSquadOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "bIncludeSquad", false);
static auto WorldPositionOffsetOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "WorldPositionOffset", false);
FMarkerID MarkerID{};
MarkerID.PlayerID = PlayerState->GetPlayerID();
MarkerID.InstanceID = MarkerRequestPtr->GetInstanceID();
MarkerData->GetMarkerType() = MarkerRequestPtr->GetMarkerType();
MarkerData->GetOwner() = PlayerState;
MarkerData->GetWorldNormal() = MarkerRequestPtr->GetWorldNormal();
if (WorldPositionOffset != -1)
MarkerData->GetWorldPosition() = MarkerRequestPtr->GetWorldPosition();
if (WorldPositionOffset != -1)
MarkerData->GetWorldPositionOffset() = MarkerRequestPtr->GetWorldPositionOffset();
if (bIncludeSquadOffset != -1)
MarkerData->DoesIncludeSquad() = MarkerRequestPtr->DoesIncludeSquad();
MarkerData->GetMarkerID() = MarkerID;
MarkerData->GetMarkedActorClass().SoftObjectPtr.WeakPtr.ObjectIndex = -1;
MarkerData->GetMarkedActorClass().SoftObjectPtr.TagAtLastTest = 0;
MarkerData->GetMarkedActorClass().SoftObjectPtr.WeakPtr.ObjectSerialNumber = 0;
MarkerData->GetMarkedActor().SoftObjectPtr.WeakPtr.ObjectIndex = -1;
MarkerData->GetMarkedActor().SoftObjectPtr.TagAtLastTest = 0;
MarkerData->GetMarkedActor().SoftObjectPtr.WeakPtr.ObjectSerialNumber = 0;
((TSoftObjectPtr<UObject>*)(__int64(MarkerData->GetCustomDisplayInfo()) + IconOffset))->SoftObjectPtr.WeakPtr.ObjectIndex = -1;
((TSoftObjectPtr<UObject>*)(__int64(MarkerData->GetCustomDisplayInfo()) + IconOffset))->SoftObjectPtr.TagAtLastTest = 0;
((TSoftObjectPtr<UObject>*)(__int64(MarkerData->GetCustomDisplayInfo()) + IconOffset))->SoftObjectPtr.WeakPtr.ObjectSerialNumber = 0;
*(FText*)(__int64(MarkerData->GetCustomDisplayInfo()) + DisplayNameOffset) = UKismetTextLibrary::Conv_StringToText(L"");
static auto PlayerTeamOffset = PlayerState->GetOffset("PlayerTeam");
auto PlayerTeam = PlayerState->Get<UObject*>(PlayerTeamOffset);
if (!PlayerTeam)
return;
static auto TeamMembersOffset = PlayerTeam->GetOffset("TeamMembers");
auto& TeamMembers = PlayerTeam->Get<TArray<AController*>>(TeamMembersOffset);
for (int i = 0; i < TeamMembers.Num(); ++i)
{
if (TeamMembers.at(i) == PlayerController)
continue;
auto CurrentTeamMemberPC = Cast<AFortPlayerControllerAthena>(TeamMembers.at(i));
if (!CurrentTeamMemberPC)
continue;
auto CurrentTeamMemberMarkerComponent = CurrentTeamMemberPC->GetMarkerComponent();// (UAthenaMarkerComponent*)CurrentTeamMemberPC->GetComponentByClass(UAthenaMarkerComponent::StaticClass());
if (!CurrentTeamMemberMarkerComponent)
continue;
static auto ClientAddMarkerFn = FindObject<UFunction>(L"/Script/FortniteGame.AthenaMarkerComponent.ClientAddMarker");
if (ClientAddMarkerFn)
{
CurrentTeamMemberMarkerComponent->ProcessEvent(ClientAddMarkerFn, MarkerData);
}
else
{
// We are assuming it is not the TArray and it is FFortWorldMarkerContainer
static auto MarkerStreamOffset = CurrentTeamMemberMarkerComponent->GetOffset("MarkerStream");
auto MarkerStream = CurrentTeamMemberMarkerComponent->GetPtr<FFastArraySerializer>(MarkerStreamOffset);
static auto MarkersOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerContainer", "Markers");
if (MarkersOffset != -1)
{
// We are assuming it is a FFastArraySerializerItem
((FFastArraySerializerItem*)MarkerData)->MostRecentArrayReplicationKey = -1;
((FFastArraySerializerItem*)MarkerData)->ReplicationID = -1;
((FFastArraySerializerItem*)MarkerData)->ReplicationKey = -1;
auto Markers = (TArray<FFortWorldMarkerData>*)(__int64(MarkerStream) + MarkersOffset);
Markers->AddPtr(MarkerData, FFortWorldMarkerData::GetStructSize());
MarkerStream->MarkArrayDirty();
}
}
}
}
void UAthenaMarkerComponent::ServerRemoveMapMarkerHook(UAthenaMarkerComponent* MarkerComponent, FMarkerID MarkerID, uint8_t CancelReason)
{
auto Owner = MarkerComponent->GetOwner();
AFortPlayerControllerAthena* PlayerController = Cast<AFortPlayerControllerAthena>(Owner);
if (!PlayerController)
return;
AFortPlayerStateAthena* PlayerState = Cast<AFortPlayerStateAthena>(PlayerController->GetPlayerState());
if (!PlayerState)
return;
static auto PlayerTeamOffset = PlayerState->GetOffset("PlayerTeam");
auto PlayerTeam = PlayerState->Get<UObject*>(PlayerTeamOffset);
if (!PlayerTeam)
return;
static auto TeamMembersOffset = PlayerTeam->GetOffset("TeamMembers");
auto& TeamMembers = PlayerTeam->Get<TArray<AController*>>(TeamMembersOffset);
for (int i = 0; i < TeamMembers.Num(); ++i)
{
if (TeamMembers.at(i) == PlayerController)
continue;
auto CurrentTeamMemberPC = Cast<AFortPlayerControllerAthena>(TeamMembers.at(i));
if (!CurrentTeamMemberPC)
continue;
auto CurrentTeamMemberMarkerComponent = CurrentTeamMemberPC->GetMarkerComponent();
if (!CurrentTeamMemberMarkerComponent)
continue;
static auto ClientCancelMarkerFn = FindObject<UFunction>("/Script/FortniteGame.AthenaMarkerComponent.ClientCancelMarker");
if (ClientCancelMarkerFn)
{
CurrentTeamMemberMarkerComponent->ProcessEvent(ClientCancelMarkerFn, &MarkerID);
}
else
{
// UnmarkActorOnClient ?
}
}
}

View File

@@ -0,0 +1,141 @@
#pragma once
#include "ActorComponent.h"
#include "Vector.h"
#include "SoftObjectPtr.h"
#include "FortPlayerState.h"
struct FMarkerID { int PlayerID; int InstanceID; };
struct FFortClientMarkerRequest
{
char pad[0x20]; // real idk
int& GetInstanceID()
{
static auto InstanceIDOffset = FindOffsetStruct("/Script/FortniteGame.FortClientMarkerRequest", "InstanceID", false) == -1 ?
FindOffsetStruct("/Script/FortniteGame.FortClientMarkerRequest", "InstanceId") : FindOffsetStruct("/Script/FortniteGame.FortClientMarkerRequest", "InstanceID");
return *(int*)(__int64(this) + InstanceIDOffset);
}
bool& DoesIncludeSquad()
{
static auto bIncludeSquadOffset = FindOffsetStruct("/Script/FortniteGame.FortClientMarkerRequest", "bIncludeSquad");
return *(bool*)(__int64(this) + bIncludeSquadOffset);
}
bool& UsesHoveredMarkerDetail()
{
static auto bUseHoveredMarkerDetailOffset = FindOffsetStruct("/Script/FortniteGame.FortClientMarkerRequest", "bUseHoveredMarkerDetail");
return *(bool*)(__int64(this) + bUseHoveredMarkerDetailOffset);
}
FVector& GetWorldPosition()
{
static auto WorldPositionOffset = FindOffsetStruct("/Script/FortniteGame.FortClientMarkerRequest", "WorldPosition");
return *(FVector*)(__int64(this) + WorldPositionOffset);
}
uint8_t& GetMarkerType()
{
static auto MarkerTypeOffset = FindOffsetStruct("/Script/FortniteGame.FortClientMarkerRequest", "MarkerType");
return *(uint8_t*)(__int64(this) + MarkerTypeOffset);
}
FVector& GetWorldPositionOffset()
{
static auto WorldPositionOffsetOffset = FindOffsetStruct("/Script/FortniteGame.FortClientMarkerRequest", "WorldPositionOffset");
return *(FVector*)(__int64(this) + WorldPositionOffsetOffset);
}
FVector& GetWorldNormal()
{
static auto WorldNormalOffset = FindOffsetStruct("/Script/FortniteGame.FortClientMarkerRequest", "WorldNormal");
return *(FVector*)(__int64(this) + WorldNormalOffset);
}
};
struct FFortWorldMarkerData
{
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>(L"/Script/FortniteGame.FortWorldMarkerData");
return Struct;
}
static int GetStructSize() { return GetStruct()->GetPropertiesSize(); }
FMarkerID& GetMarkerID()
{
static auto MarkerIDOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "MarkerID");
return *(FMarkerID*)(__int64(this) + MarkerIDOffset);
}
UObject*& GetMarkerInstance()
{
static auto MarkerInstanceOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "MarkerInstance");
return *(UObject**)(__int64(this) + MarkerInstanceOffset);
}
FVector& GetWorldPosition()
{
static auto WorldPositionOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "WorldPosition");
return *(FVector*)(__int64(this) + WorldPositionOffset);
}
bool& DoesIncludeSquad()
{
static auto bIncludeSquadOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "bIncludeSquad");
return *(bool*)(__int64(this) + bIncludeSquadOffset);
}
FVector& GetWorldPositionOffset()
{
static auto WorldPositionOffsetOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "WorldPositionOffset");
return *(FVector*)(__int64(this) + WorldPositionOffsetOffset);
}
FVector& GetWorldNormal()
{
static auto WorldNormalOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "WorldNormal");
return *(FVector*)(__int64(this) + WorldNormalOffset);
}
TSoftObjectPtr<AActor>& GetMarkedActor()
{
static auto MarkedActorOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "MarkedActor");
return *(TSoftObjectPtr<AActor>*)(__int64(this) + MarkedActorOffset);
}
uint8_t& GetMarkerType()
{
static auto MarkerTypeOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "MarkerType");
return *(uint8_t*)(__int64(this) + MarkerTypeOffset);
}
TSoftObjectPtr<UClass>& GetMarkedActorClass()
{
static auto MarkedActorClassOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "MarkedActorClass");
return *(TSoftObjectPtr<UClass>*)(__int64(this) + MarkedActorClassOffset);
}
AFortPlayerState*& GetOwner()
{
static auto OwnerOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "Owner");
return *(AFortPlayerState**)(__int64(this) + OwnerOffset);
}
void* GetCustomDisplayInfo()
{
static auto CustomDisplayInfoOffset = FindOffsetStruct("/Script/FortniteGame.FortWorldMarkerData", "CustomDisplayInfo");
return (void*)(__int64(this) + CustomDisplayInfoOffset);
}
};
class UAthenaMarkerComponent : public UActorComponent
{
public:
static void ServerAddMapMarkerHook(UAthenaMarkerComponent* MarkerComponent, FFortClientMarkerRequest MarkerRequest);
static void ServerRemoveMapMarkerHook(UAthenaMarkerComponent* MarkerComponent, FMarkerID MarkerID, uint8_t CancelReason);
};

View File

@@ -0,0 +1,55 @@
#pragma once
#include "reboot.h"
struct FAthenaMatchTeamStats
{
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>(L"/Script/FortniteGame.AthenaMatchTeamStats");
return Struct;
}
static auto GetStructSize() { return GetStruct()->GetPropertiesSize(); }
int Place; // 0x0000(0x0004) (Edit, BlueprintVisible, BlueprintReadOnly, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
int TotalPlayers; // 0x0004(0x0004) (Edit, BlueprintVisible, BlueprintReadOnly, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
int& GetPlace()
{
return Place;
}
int& GetTotalPlayers()
{
return TotalPlayers;
}
};
class UAthenaPlayerMatchReport : public UObject
{
public:
bool& HasTeamStats()
{
static auto bHasTeamStatsOffset = GetOffset("bHasTeamStats");
return Get<bool>(bHasTeamStatsOffset);
}
bool& HasMatchStats()
{
static auto bHasMatchStatsOffset = GetOffset("bHasMatchStats");
return Get<bool>(bHasMatchStatsOffset);
}
FAthenaMatchTeamStats* GetTeamStats()
{
static auto TeamStatsOffset = GetOffset("TeamStats");
return GetPtr<FAthenaMatchTeamStats>(TeamStatsOffset);
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.AthenaPlayerMatchReport");
return Class;
}
};

View File

@@ -0,0 +1,21 @@
#pragma once
#include "ActorComponent.h"
#include "reboot.h"
class UAthenaResurrectionComponent : public UActorComponent
{
public:
TWeakObjectPtr<AActor>& GetResurrectionLocation()
{
static auto ResurrectionLocationOffset = GetOffset("ResurrectionLocation");
return Get<TWeakObjectPtr<AActor>>(ResurrectionLocationOffset);
}
int& GetClosestSpawnMachineIndex()
{
static auto ClosestSpawnMachineIndexOffset = GetOffset("ClosestSpawnMachineIndex");
return Get<int>(ClosestSpawnMachineIndexOffset);
}
};

View File

@@ -0,0 +1,48 @@
#pragma once
#include "reboot.h"
class UAttributeSet : public UObject
{
public:
};
struct FGameplayAttribute
{
FString AttributeName;
void* Attribute; // Property
UStruct* AttributeOwner;
std::string GetAttributeName()
{
return AttributeName.ToString();
}
std::string GetAttributePropertyName()
{
if (!Attribute)
return "INVALIDATTRIBUTE";
return GetFNameOfProp(Attribute)->ToString();
}
};
struct FGameplayAttributeData
{
float& GetBaseValue()
{
static auto BaseValueOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAttributeData", "BaseValue");
return *(float*)(__int64(this) + BaseValueOffset);
}
float& GetCurrentValue()
{
static auto CurrentValueOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAttributeData", "CurrentValue");
return *(float*)(__int64(this) + CurrentValueOffset);
}
};
struct FFortGameplayAttributeData : public FGameplayAttributeData
{
};

View File

@@ -0,0 +1,125 @@
#pragma once
#include "reboot.h"
#include "GameplayStatics.h"
#include "FortLootPackage.h"
#include "FortPickup.h"
#include "BuildingGameplayActor.h"
#include "KismetSystemLibrary.h"
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>(L"/Script/FortniteGame.BGAConsumableSpawner");
if (!BGAConsumableSpawnerClass)
return;
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
auto AllBGAConsumableSpawners = UGameplayStatics::GetAllActorsOfClass(GetWorld(), BGAConsumableSpawnerClass);
LOG_INFO(LogDev, "AllBGAConsumableSpawners.Num(): {}", (int)AllBGAConsumableSpawners.Num());
for (int i = 0; i < AllBGAConsumableSpawners.Num(); ++i)
{
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 };
SpawnTransform.Rotation = FQuat();
if (FBuildingGameplayActorSpawnDetails::GetStruct())
{
// todo handle?
auto MapInfo = GameState->GetMapInfo();
}
static auto SpawnLootTierGroupOffset = BGAConsumableSpawner->GetOffset("SpawnLootTierGroup");
auto& SpawnLootTierGroup = BGAConsumableSpawner->Get<FName>(SpawnLootTierGroupOffset);
auto LootDrops = PickLootDrops(SpawnLootTierGroup, GameState->GetWorldLevel());
for (int z = 0; z < LootDrops.size(); z++)
{
auto& LootDrop = LootDrops.at(z);
static auto ConsumableClassOffset = LootDrop->GetItemDefinition()->GetOffset("ConsumableClass");
auto ConsumableClassSoft = LootDrop->GetItemDefinition()->GetPtr<TSoftObjectPtr<UClass>>(ConsumableClassOffset);
static auto BlueprintGeneratedClassClass = FindObject<UClass>(L"/Script/Engine.BlueprintGeneratedClass");
auto StrongConsumableClass = ConsumableClassSoft->Get(BlueprintGeneratedClassClass, true);
if (!StrongConsumableClass)
{
LOG_INFO(LogDev, "Invalid consumable class!");
continue;
}
bool bDeferConstruction = true; // hm?
auto ConsumableActor = GetWorld()->SpawnActor<ABuildingGameplayActor>(StrongConsumableClass, SpawnTransform, CreateSpawnParameters(ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn, bDeferConstruction));
if (ConsumableActor)
{
FTransform FinalSpawnTransform = SpawnTransform;
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.CompareVectors(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 {} {} {}", z, LootDrops.size(), ConsumableActor->GetName(), FinalSpawnTransform.Translation.X, FinalSpawnTransform.Translation.Y, FinalSpawnTransform.Translation.Z);
break; // ?
}
}
}
AllBGAConsumableSpawners.Free();
LOG_INFO(LogDev, "Spawned BGAS!");
}

View File

@@ -0,0 +1,26 @@
#include "BP_IslandScripting.h"
void ABP_IslandScripting_C::Initialize()
{
static auto UpdateMapOffset = GetOffset("UpdateMap", false);
if (UpdateMapOffset != -1)
{
Get<bool>(UpdateMapOffset) = true;
this->OnRep_UpdateMap();
}
/*
// This spawns the beam.
this->IsDeimosActive() = true;
this->OnRep_IsDeimosActive();
*/
}
ABP_IslandScripting_C* ABP_IslandScripting_C::GetIslandScripting()
{
auto AllIslandScriptings = UGameplayStatics::GetAllActorsOfClass(GetWorld(), StaticClass());
return AllIslandScriptings.Num() > 0 ? (ABP_IslandScripting_C*)AllIslandScriptings.at(0) : nullptr;
}

View File

@@ -0,0 +1,37 @@
#pragma once
#include "reboot.h"
#include "GameplayStatics.h"
class ABP_IslandScripting_C : public AActor // AFortAlwaysRelevantReplicatedActor
{
public:
bool& IsDeimosActive()
{
static auto IsDeimosActiveOffset = GetOffset("IsDeimosActive");
return Get<bool>(IsDeimosActiveOffset);
}
void OnRep_IsDeimosActive()
{
static auto OnRep_IsDeimosActiveFn = FindObject<UFunction>("/Game/Athena/Prototype/Blueprints/Island/BP_IslandScripting.BP_IslandScripting_C.OnRep_IsDeimosActive");
this->ProcessEvent(OnRep_IsDeimosActiveFn);
}
void OnRep_UpdateMap()
{
static auto OnRep_UpdateMapFn = FindObject<UFunction>("/Game/Athena/Prototype/Blueprints/Island/BP_IslandScripting.BP_IslandScripting_C.OnRep_UpdateMap");
this->ProcessEvent(OnRep_UpdateMapFn);
}
void Initialize();
static ABP_IslandScripting_C* GetIslandScripting();
static UClass* StaticClass()
{
/* static */ auto Class = FindObject<UClass>("/Game/Athena/Prototype/Blueprints/Island/BP_IslandScripting.BP_IslandScripting_C");
return Class;
}
};

View File

@@ -0,0 +1,143 @@
#pragma once
#include "inc.h"
#include "ReversePredicate.h"
namespace AlgoImpl
{
/**
* Gets the index of the left child of node at Index.
*
* @param Index Node for which the left child index is to be returned.
* @returns Index of the left child.
*/
FORCEINLINE int32 HeapGetLeftChildIndex(int32 Index)
{
return Index * 2 + 1;
}
/**
* Checks if node located at Index is a leaf or not.
*
* @param Index Node index.
* @returns true if node is a leaf, false otherwise.
*/
FORCEINLINE bool HeapIsLeaf(int32 Index, int32 Count)
{
return HeapGetLeftChildIndex(Index) >= Count;
}
/**
* Gets the parent index for node at Index.
*
* @param Index node index.
* @returns Parent index.
*/
FORCEINLINE int32 HeapGetParentIndex(int32 Index)
{
return (Index - 1) / 2;
}
/**
* Fixes a possible violation of order property between node at Index and a child.
*
* @param Heap Pointer to the first element of a binary heap.
* @param Index Node index.
* @param Count Size of the heap.
* @param Projection The projection to apply to the elements.
* @param Predicate A binary predicate object used to specify if one element should precede another.
*/
template <typename RangeValueType, typename ProjectionType, typename PredicateType>
FORCEINLINE void HeapSiftDown(RangeValueType* Heap, int32 Index, const int32 Count, const ProjectionType& Projection, const PredicateType& Predicate)
{
while (!HeapIsLeaf(Index, Count))
{
const int32 LeftChildIndex = HeapGetLeftChildIndex(Index);
const int32 RightChildIndex = LeftChildIndex + 1;
int32 MinChildIndex = LeftChildIndex;
if (RightChildIndex < Count)
{
MinChildIndex = Predicate(Invoke(Projection, Heap[LeftChildIndex]), Invoke(Projection, Heap[RightChildIndex])) ? LeftChildIndex : RightChildIndex;
}
if (!Predicate(Invoke(Projection, Heap[MinChildIndex]), Invoke(Projection, Heap[Index])))
{
break;
}
Swap(Heap[Index], Heap[MinChildIndex]);
Index = MinChildIndex;
}
}
/**
* Fixes a possible violation of order property between node at NodeIndex and a parent.
*
* @param Heap Pointer to the first element of a binary heap.
* @param RootIndex How far to go up?
* @param NodeIndex Node index.
* @param Projection The projection to apply to the elements.
* @param Predicate A binary predicate object used to specify if one element should precede another.
*
* @return The new index of the node that was at NodeIndex
*/
template <class RangeValueType, typename ProjectionType, class PredicateType>
FORCEINLINE int32 HeapSiftUp(RangeValueType* Heap, int32 RootIndex, int32 NodeIndex, const ProjectionType& Projection, const PredicateType& Predicate)
{
while (NodeIndex > RootIndex)
{
int32 ParentIndex = HeapGetParentIndex(NodeIndex);
if (!Predicate(Invoke(Projection, Heap[NodeIndex]), Invoke(Projection, Heap[ParentIndex])))
{
break;
}
Swap(Heap[NodeIndex], Heap[ParentIndex]);
NodeIndex = ParentIndex;
}
return NodeIndex;
}
/**
* Builds an implicit min-heap from a range of elements.
* This is the internal function used by Heapify overrides.
*
* @param First pointer to the first element to heapify
* @param Num the number of items to heapify
* @param Projection The projection to apply to the elements.
* @param Predicate A binary predicate object used to specify if one element should precede another.
*/
template <typename RangeValueType, typename ProjectionType, typename PredicateType>
FORCEINLINE void HeapifyInternal(RangeValueType* First, SIZE_T Num, ProjectionType Projection, PredicateType Predicate)
{
for (int32 Index = HeapGetParentIndex(Num - 1); Index >= 0; Index--)
{
HeapSiftDown(First, Index, Num, Projection, Predicate);
}
}
/**
* Performs heap sort on the elements.
* This is the internal sorting function used by HeapSort overrides.
*
* @param First pointer to the first element to sort
* @param Num the number of elements to sort
* @param Predicate predicate class
*/
template <typename RangeValueType, typename ProjectionType, class PredicateType>
void HeapSortInternal(RangeValueType* First, SIZE_T Num, ProjectionType Projection, PredicateType Predicate)
{
TReversePredicate< PredicateType > ReversePredicateWrapper(Predicate); // Reverse the predicate to build a max-heap instead of a min-heap
HeapifyInternal(First, Num, Projection, ReversePredicateWrapper);
for (int32 Index = Num - 1; Index > 0; Index--)
{
Swap(First[0], First[Index]);
HeapSiftDown(First, 0, Index, Projection, ReversePredicateWrapper);
}
}
}

View File

@@ -0,0 +1,329 @@
#pragma once
#include "ContainerAllocationPolicies.h"
static FORCEINLINE uint32 CountLeadingZeros(uint32 Value)
{
unsigned long Log2;
if (_BitScanReverse(&Log2, Value) != 0)
{
return 31 - Log2;
}
return 32;
}
#define NumBitsPerDWORD ((int32)32)
#define NumBitsPerDWORDLogTwo ((int32)5)
class TBitArray
{
public:
TInlineAllocator<4>::ForElementType<unsigned int> Data;
int NumBits;
int MaxBits;
struct FRelativeBitReference
{
public:
FORCEINLINE explicit FRelativeBitReference(int32 BitIndex)
: DWORDIndex(BitIndex >> NumBitsPerDWORDLogTwo)
, Mask(1 << (BitIndex & (NumBitsPerDWORD -1)))
{
}
int32 DWORDIndex;
uint32 Mask;
};
public:
struct FBitReference
{
FORCEINLINE FBitReference(uint32& InData, uint32 InMask)
: Data(InData)
, Mask(InMask)
{
}
FORCEINLINE const FBitReference(const uint32& InData, const uint32 InMask)
: Data(const_cast<uint32&>(InData))
, Mask(InMask)
{
}
FORCEINLINE void SetBit(const bool Value)
{
Value ? Data |= Mask : Data &= ~Mask;
// 10011101 - Data // 10011101 - Data
// 00000010 - Mask - true | // 00000010 - Mask - false
// 10011111 - |= // 11111101 - ~
// // 10011111 - &=
}
FORCEINLINE operator bool() const
{
return (Data & Mask) != 0;
}
FORCEINLINE void operator=(const bool Value)
{
this->SetBit(Value);
}
private:
uint32& Data;
uint32 Mask;
};
public:
class FBitIterator : public FRelativeBitReference
{
private:
int32 Index;
const TBitArray& IteratedArray;
public:
FORCEINLINE const FBitIterator(const TBitArray& ToIterate, const int32 StartIndex) // Begin
: IteratedArray(ToIterate)
, Index(StartIndex)
, FRelativeBitReference(StartIndex)
{
}
FORCEINLINE const FBitIterator(const TBitArray& ToIterate) // End
: IteratedArray(ToIterate)
, Index(ToIterate.NumBits)
, FRelativeBitReference(ToIterate.NumBits)
{
}
FORCEINLINE explicit operator bool() const
{
return Index < IteratedArray.Num();
}
FORCEINLINE FBitIterator& operator++()
{
++Index;
this->Mask <<= 1;
if (!this->Mask)
{
this->Mask = 1;
++this->DWORDIndex;
}
return *this;
}
FORCEINLINE bool operator*() const
{
// Thesis: Once there are more elements in the BitArray than InlineData can hold it'll just allocate all of
// them through SecondaryElements, leaving InlineData all true
if (IteratedArray.NumBits < IteratedArray.Data.NumInlineBits())
{
return (bool)FBitReference(IteratedArray.Data.GetInlineElement(this->DWORDIndex), this->Mask);
}
else
{
return (bool)FBitReference(IteratedArray.Data.GetSecondaryElement(this->DWORDIndex), this->Mask);
}
}
FORCEINLINE bool operator==(const FBitIterator& OtherIt) const
{
return Index == OtherIt.Index;
}
FORCEINLINE bool operator!=(const FBitIterator& OtherIt) const
{
return Index </*=*/ OtherIt.Index;
}
FORCEINLINE bool operator < (const int32 Other) const
{
return Index < Other;
}
FORCEINLINE bool operator > (const int32 Other) const
{
return Index < Other;
}
FORCEINLINE int32 GetIndex() const
{
return Index;
}
};
class FSetBitIterator : public FRelativeBitReference
{
private:
const TBitArray& IteratedArray;
uint32 UnvisitedBitMask;
int32 CurrentBitIndex;
int32 BaseBitIndex;
public:
FORCEINLINE FSetBitIterator(const TBitArray& ToIterate, int32 StartIndex)
: FRelativeBitReference(StartIndex)
, IteratedArray(const_cast<TBitArray&>(ToIterate))
, UnvisitedBitMask((~0U) << (StartIndex & (NumBitsPerDWORD - 1)))
, CurrentBitIndex(StartIndex)
, BaseBitIndex(StartIndex & ~(NumBitsPerDWORD - 1))
{
if (StartIndex != IteratedArray.NumBits)
{
FindNextSetBit();
}
}
FORCEINLINE FSetBitIterator(const TBitArray& ToIterate)
: FRelativeBitReference(ToIterate.NumBits)
, IteratedArray(const_cast<TBitArray&>(ToIterate))
, UnvisitedBitMask(0)
, CurrentBitIndex(ToIterate.NumBits)
, BaseBitIndex(ToIterate.NumBits)
{
}
FORCEINLINE FSetBitIterator& operator++()
{
UnvisitedBitMask &= ~this->Mask;
FindNextSetBit();
return *this;
}
FORCEINLINE bool operator*() const
{
return true;
}
FORCEINLINE bool operator==(const FSetBitIterator& Other) const
{
return CurrentBitIndex == Other.CurrentBitIndex;
}
FORCEINLINE bool operator!=(const FSetBitIterator& Other) const
{
return CurrentBitIndex </*=*/ Other.CurrentBitIndex;
}
FORCEINLINE explicit operator bool() const
{
return CurrentBitIndex < IteratedArray.NumBits;
}
FORCEINLINE int32 GetIndex() const
{
return CurrentBitIndex;
}
private:
void FindNextSetBit()
{
//InlineData is the first 16-bytes of TBitArray
const uint32* ArrayData = (IteratedArray.Data.SecondaryData ? IteratedArray.Data.SecondaryData : (uint32*)&IteratedArray.Data.InlineData);
if (!ArrayData)
return;
const int32 ArrayNum = IteratedArray.NumBits;
const int32 LastDWORDIndex = (ArrayNum - 1) / NumBitsPerDWORD;
uint32 RemainingBitMask = ArrayData[this->DWORDIndex] & UnvisitedBitMask;
while (!RemainingBitMask)
{
++this->DWORDIndex;
BaseBitIndex += NumBitsPerDWORD;
if (this->DWORDIndex > LastDWORDIndex)
{
CurrentBitIndex = ArrayNum;
return;
}
RemainingBitMask = ArrayData[this->DWORDIndex];
UnvisitedBitMask = ~0;
}
const uint32 NewRemainingBitMask = RemainingBitMask & (RemainingBitMask - 1);
this->Mask = NewRemainingBitMask ^ RemainingBitMask;
CurrentBitIndex = BaseBitIndex + NumBitsPerDWORD - 1 - CountLeadingZeros(this->Mask);
if (CurrentBitIndex > ArrayNum)
{
CurrentBitIndex = ArrayNum;
}
}
};
public:
FORCEINLINE FBitIterator Iterator(int32 StartIndex)
{
return FBitIterator(*this, StartIndex);
}
FORCEINLINE FSetBitIterator SetBitIterator(int32 StartIndex)
{
return FSetBitIterator(*this, StartIndex);
}
FORCEINLINE FBitIterator begin()
{
return FBitIterator(*this, 0);
}
FORCEINLINE const FBitIterator begin() const
{
return FBitIterator(*this, 0);
}
FORCEINLINE FBitIterator end()
{
return FBitIterator(*this);
}
FORCEINLINE const FBitIterator end() const
{
return FBitIterator(*this);
}
FORCEINLINE FSetBitIterator SetBitsItBegin()
{
return FSetBitIterator(*this, 0);
}
FORCEINLINE const FSetBitIterator SetBitsItBegin() const
{
return FSetBitIterator(*this, 0);
}
FORCEINLINE const FSetBitIterator SetBitsItEnd()
{
return FSetBitIterator(*this);
}
FORCEINLINE const FSetBitIterator SetBitsItEnd() const
{
return FSetBitIterator(*this);
}
FORCEINLINE int32 Num() const
{
return NumBits;
}
FORCEINLINE int32 Max() const
{
return MaxBits;
}
FORCEINLINE bool IsSet(int32 Index) const
{
return *FBitIterator(*this, Index);
}
FORCEINLINE void Set(const int32 Index, const bool Value, bool bIsSettingAllZero = false)
{
const int32 DWORDIndex = (Index >> ((int32)5));
const int32 Mask = (1 << (Index & (((int32)32) - 1)));
if (!bIsSettingAllZero)
NumBits = Index >= NumBits ? Index < MaxBits ? Index + 1 : NumBits : NumBits;
FBitReference(Data[DWORDIndex], Mask).SetBit(Value);
}
FORCEINLINE void ZeroAll()
{
for (int i = 0; i < MaxBits; ++i)
{
Set(i, false, true);
}
}
};

View File

@@ -0,0 +1,120 @@
#include "BuildingActor.h"
#include "FortWeapon.h"
#include "BuildingSMActor.h"
#include "FortPlayerControllerAthena.h"
#include "FortPawn.h"
#include "FortWeaponMeleeItemDefinition.h"
#include "CurveTable.h"
#include "DataTable.h"
#include "FortResourceItemDefinition.h"
#include "FortKismetLibrary.h"
#include "DataTableFunctionLibrary.h"
void ABuildingActor::OnDamageServerHook(ABuildingActor* BuildingActor, float Damage, FGameplayTagContainer DamageTags,
FVector Momentum, /* FHitResult */ __int64 HitInfo, APlayerController* InstigatedBy, AActor* DamageCauser,
/* FGameplayEffectContextHandle */ __int64 EffectContext)
{
// LOG_INFO(LogDev, "Befor3e");
auto BuildingSMActor = Cast<ABuildingSMActor>(BuildingActor);
auto PlayerController = Cast<AFortPlayerControllerAthena>(InstigatedBy);
// auto Pawn = PlayerController ? PlayerController->GetMyFortPawn() : nullptr;
auto Weapon = Cast<AFortWeapon>(DamageCauser);
if (!BuildingSMActor)
return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
if (BuildingSMActor->IsDestroyed())
return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
/*
static auto LastDamageAmountOffset = BuildingSMActor->GetOffset("LastDamageAmount");
static auto LastDamageHitOffset = BuildingSMActor->GetOffset("LastDamageHit", false) != -1 ? BuildingSMActor->GetOffset("LastDamageHit") : BuildingSMActor->GetOffset("LastDamageHitImpulseDir"); // idc
const float PreviousLastDamageAmount = BuildingSMActor->Get<float>(LastDamageAmountOffset);
const float PreviousLastDamageHit = BuildingSMActor->Get<float>(LastDamageHitOffset);
const float CurrentBuildingHealth = BuildingActor->GetHealth();
BuildingSMActor->Get<float>(LastDamageAmountOffset) = Damage;
BuildingSMActor->Get<float>(LastDamageHitOffset) = CurrentBuildingHealth;
*/
if (!PlayerController || !Weapon)
return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
// if (!Pawn)
// return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
auto WorldInventory = PlayerController->GetWorldInventory();
if (!WorldInventory)
return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
auto WeaponData = Cast<UFortWeaponMeleeItemDefinition>(Weapon->GetWeaponData());
if (!WeaponData)
return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
UFortResourceItemDefinition* ItemDef = UFortKismetLibrary::K2_GetResourceItemDefinition(BuildingSMActor->GetResourceType());
if (!ItemDef)
return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
static auto BuildingResourceAmountOverrideOffset = BuildingSMActor->GetOffset("BuildingResourceAmountOverride");
auto& BuildingResourceAmountOverride = BuildingSMActor->Get<FCurveTableRowHandle>(BuildingResourceAmountOverrideOffset);
int ResourceCount = 0;
if (BuildingResourceAmountOverride.RowName.IsValid())
{
// auto AssetManager = Cast<UFortAssetManager>(GEngine->AssetManager);
// auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameStateAthena);
UCurveTable* CurveTable = nullptr; // GameState->CurrentPlaylistInfo.BasePlaylist ? GameState->CurrentPlaylistInfo.BasePlaylist->ResourceRates.Get() : nullptr;
// LOG_INFO(LogDev, "Before1");
if (!CurveTable)
CurveTable = FindObject<UCurveTable>(L"/Game/Athena/Balance/DataTables/AthenaResourceRates.AthenaResourceRates");
{
// auto curveMap = ((UDataTable*)CurveTable)->GetRowMap();
// LOG_INFO(LogDev, "Before {}", __int64(CurveTable));
float Out = UDataTableFunctionLibrary::EvaluateCurveTableRow(CurveTable, BuildingResourceAmountOverride.RowName, 0.f);
// LOG_INFO(LogDev, "Out: {}", Out);
const float DamageThatWillAffect = /* PreviousLastDamageHit > 0 && Damage > PreviousLastDamageHit ? PreviousLastDamageHit : */ Damage;
float skid = Out / (BuildingActor->GetMaxHealth() / DamageThatWillAffect);
ResourceCount = round(skid);
}
}
if (ResourceCount <= 0)
{
return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
}
bool bIsWeakspot = Damage == 100.0f;
PlayerController->ClientReportDamagedResourceBuilding(BuildingSMActor, BuildingSMActor->GetResourceType(), ResourceCount, false, bIsWeakspot);
bool bShouldUpdate = false;
WorldInventory->AddItem(ItemDef, &bShouldUpdate, ResourceCount);
if (bShouldUpdate)
WorldInventory->Update();
return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
}
UClass* ABuildingActor::StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/FortniteGame.BuildingActor");
return Class;
}

View File

@@ -0,0 +1,99 @@
#pragma once
#include "Actor.h"
#include "reboot.h" // we want to prevent this but im to lazy to make cpp file
#include "PlayerController.h"
#include "GameplayTagContainer.h"
class ABuildingActor : public AActor
{
public:
void InitializeBuildingActor(UObject* Controller, ABuildingActor* BuildingOwner, bool bUsePlayerBuildAnimations, UObject* ReplacedBuilding = nullptr)
{
struct {
UObject* BuildingOwner; // ABuildingActor
UObject* SpawningController;
bool bUsePlayerBuildAnimations; // I think this is not on some versions
UObject* ReplacedBuilding; // this also not on like below 18.00
} IBAParams{ BuildingOwner, Controller, bUsePlayerBuildAnimations, ReplacedBuilding };
static auto fn = FindObject<UFunction>("/Script/FortniteGame.BuildingActor.InitializeKismetSpawnedBuildingActor");
this->ProcessEvent(fn, &IBAParams);
}
bool IsDestroyed()
{
static auto bDestroyedOffset = GetOffset("bDestroyed");
static auto bDestroyedFieldMask = GetFieldMask(GetProperty("bDestroyed"));
return ReadBitfieldValue(bDestroyedOffset, bDestroyedFieldMask);
}
void SilentDie()
{
static auto SilentDieFn = FindObject<UFunction>(L"/Script/FortniteGame.BuildingActor.SilentDie");
bool bPropagateSilentDeath = false; // idfk
this->ProcessEvent(SilentDieFn, &bPropagateSilentDeath);
}
float GetMaxHealth()
{
float MaxHealth = 0;
static auto fn = FindObject<UFunction>(L"/Script/FortniteGame.BuildingActor.GetMaxHealth");
this->ProcessEvent(fn, &MaxHealth);
return MaxHealth;
}
float GetHealthPercent() // aka GetHealth() / GetMaxHealth()
{
float HealthPercent = 0;
static auto fn = FindObject<UFunction>(L"/Script/FortniteGame.BuildingActor.GetHealthPercent");
this->ProcessEvent(fn, &HealthPercent);
return HealthPercent;
}
float GetHealth()
{
float Health = 0;
static auto fn = FindObject<UFunction>("/Script/FortniteGame.BuildingActor.GetHealth");
this->ProcessEvent(fn, &Health);
return Health;
}
void SetTeam(unsigned char InTeam)
{
static auto fn = nullptr; // FindObject<UFunction>(L"/Script/FortniteGame.BuildingActor.SetTeam");
if (!fn)
{
static auto TeamOffset = GetOffset("Team");
Get<uint8_t>(TeamOffset) = InTeam;
static auto TeamIndexOffset = GetOffset("TeamIndex", false);
if (TeamIndexOffset != -1)
Get<uint8_t>(TeamIndexOffset) = InTeam;
}
else
{
this->ProcessEvent(fn, &InTeam);
}
}
bool IsPlayerBuildable()
{
static auto bIsPlayerBuildableOffset = GetOffset("bIsPlayerBuildable");
static auto bIsPlayerBuildableFieldMask = GetFieldMask(GetProperty("bIsPlayerBuildable"));
return ReadBitfieldValue(bIsPlayerBuildableOffset, bIsPlayerBuildableFieldMask);
}
static inline void (*OnDamageServerOriginal)(ABuildingActor* BuildingActor, float Damage, FGameplayTagContainer DamageTags,
FVector Momentum, /* FHitResult */ __int64 HitInfo, APlayerController* InstigatedBy, AActor* DamageCauser,
/* FGameplayEffectContextHandle */ __int64 EffectContext);
static void OnDamageServerHook(ABuildingActor* BuildingActor, float Damage, FGameplayTagContainer DamageTags,
FVector Momentum, /* FHitResult */ __int64 HitInfo, APlayerController* InstigatedBy, AActor* DamageCauser,
/* FGameplayEffectContextHandle */ __int64 EffectContext);
static UClass* StaticClass();
};

View File

@@ -0,0 +1,49 @@
#include "BuildingContainer.h"
#include "FortPickup.h"
#include "FortLootPackage.h"
#include "FortGameModeAthena.h"
#include "gui.h"
bool ABuildingContainer::SpawnLoot(AFortPawn* Pawn)
{
if (!Pawn)
return false;
this->ForceNetUpdate();
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
FVector LocationToSpawnLoot = this->GetActorLocation() + this->GetActorForwardVector() * this->GetLootSpawnLocation_Athena().X + this->GetActorRightVector() * this->GetLootSpawnLocation_Athena().Y + this->GetActorUpVector() * this->GetLootSpawnLocation_Athena().Z;
auto RedirectedLootTier = GameMode->RedirectLootTier(GetSearchLootTierGroup());
// LOG_INFO(LogInteraction, "RedirectedLootTier: {}", RedirectedLootTier.ToString());
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
auto LootDrops = PickLootDrops(RedirectedLootTier, GameState->GetWorldLevel(), -1, bDebugPrintLooting);
// LOG_INFO(LogInteraction, "LootDrops.size(): {}", LootDrops.size());
for (auto& lootDrop : LootDrops)
{
PickupCreateData CreateData;
CreateData.bToss = true;
// CreateData.PawnOwner = Pawn;
CreateData.ItemEntry = lootDrop.ItemEntry;
CreateData.SpawnLocation = LocationToSpawnLoot;
CreateData.SourceType = EFortPickupSourceTypeFlag::GetContainerValue();
CreateData.bRandomRotation = true;
CreateData.bShouldFreeItemEntryWhenDeconstructed = true;
auto NewPickup = AFortPickup::SpawnPickup(CreateData);
}
if (!this->IsDestroyed())
{
this->ForceNetUpdate();
// a buncha other stuff
}
return true;
}

View File

@@ -0,0 +1,73 @@
#pragma once
#include "BuildingSMActor.h"
#include "FortPawn.h"
class ABuildingContainer : public ABuildingSMActor
{
public:
bool ShouldDestroyOnSearch()
{
static auto bDestroyContainerOnSearchOffset = GetOffset("bDestroyContainerOnSearch");
static auto bDestroyContainerOnSearchFieldMask = GetFieldMask(GetProperty("bDestroyContainerOnSearch"));
return this->ReadBitfieldValue(bDestroyContainerOnSearchOffset, bDestroyContainerOnSearchFieldMask);
}
FName& GetSearchLootTierGroup()
{
static auto SearchLootTierGroupOffset = this->GetOffset("SearchLootTierGroup");
return Get<FName>(SearchLootTierGroupOffset);
}
bool IsAlreadySearched()
{
static auto bAlreadySearchedOffset = this->GetOffset("bAlreadySearched");
static auto bAlreadySearchedFieldMask = GetFieldMask(this->GetProperty("bAlreadySearched"));
return this->ReadBitfieldValue(bAlreadySearchedOffset, bAlreadySearchedFieldMask);
}
FVector& GetLootSpawnLocation_Athena()
{
static auto LootSpawnLocation_AthenaOffset = this->GetOffset("LootSpawnLocation_Athena");
return this->Get<FVector>(LootSpawnLocation_AthenaOffset);
}
void SetAlreadySearched(bool bNewValue, bool bOnRep = true)
{
static auto bAlreadySearchedOffset = this->GetOffset("bAlreadySearched");
static auto bAlreadySearchedFieldMask = GetFieldMask(this->GetProperty("bAlreadySearched"));
this->SetBitfieldValue(bAlreadySearchedOffset, bAlreadySearchedFieldMask, bNewValue);
if (bOnRep)
{
static auto OnRep_bAlreadySearchedFn = FindObject<UFunction>(L"/Script/FortniteGame.BuildingContainer.OnRep_bAlreadySearched");
this->ProcessEvent(OnRep_bAlreadySearchedFn);
}
}
FVector& GetLootSpawnLocation()
{
static auto LootSpawnLocationOffset = GetOffset("LootSpawnLocation");
return Get<FVector>(LootSpawnLocationOffset);
}
float& GetLootNoiseRange()
{
static auto LootNoiseRangeOffset = GetOffset("LootNoiseRange");
return Get<float>(LootNoiseRangeOffset);
}
void BounceContainer()
{
static auto BounceContainerFn = FindObject<UFunction>("/Script/FortniteGame.BuildingContainer.BounceContainer");
this->ProcessEvent(BounceContainerFn);
}
bool SpawnLoot(AFortPawn* Pawn);
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.BuildingContainer");
return Class;
}
};

View File

@@ -0,0 +1,30 @@
#include "BuildingFoundation.h"
#include "FortGameModeAthena.h"
void ABuildingFoundation::SetDynamicFoundationTransformHook(UObject* Context, FFrame& Stack, void* Ret)
{
FTransform NewTransform;
Stack.StepCompiledIn(&NewTransform);
auto BuildingFoundation = (ABuildingFoundation*)Context;
LOG_INFO(LogDev, "Bruh: {}", BuildingFoundation->GetName());
SetFoundationTransform(BuildingFoundation, NewTransform);
return SetDynamicFoundationTransformOriginal(Context, Stack, Ret);
}
void ABuildingFoundation::SetDynamicFoundationEnabledHook(UObject* Context, FFrame& Stack, void* Ret)
{
bool bEnabled;
Stack.StepCompiledIn(&bEnabled);
// LOG_INFO(LogDev, "{} TELL MILXNOR IF THIS PRINTS: {}", Context->GetFullName(), bEnabled);
auto BuildingFoundation = (ABuildingFoundation*)Context;
ShowFoundation(BuildingFoundation, bEnabled);
return SetDynamicFoundationEnabledOriginal(Context, Stack, Ret);
}

View File

@@ -0,0 +1,40 @@
#pragma once
#include "BuildingSMActor.h"
#include "Stack.h"
/* enum class EDynamicFoundationType : uint8
{
Static = 0,
StartEnabled_Stationary = 1,
StartEnabled_Dynamic = 2,
StartDisabled = 3,
EDynamicFoundationType_MAX = 4,
};
enum class EDynamicFoundationEnabledState : uint8_t
{
Unknown = 0,
Enabled = 1,
Disabled = 2,
EDynamicFoundationEnabledState_MAX = 3
};
enum class EDynamicFoundationType : uint8_t
{
Static = 0,
StartEnabled_Stationary = 1,
StartEnabled_Dynamic = 2,
StartDisabled = 3,
EDynamicFoundationType_MAX = 4
}; */
class ABuildingFoundation : public ABuildingSMActor
{
public:
static inline void (*SetDynamicFoundationEnabledOriginal)(UObject* Context, FFrame& Stack, void* Ret);
static inline void (*SetDynamicFoundationTransformOriginal)(UObject* Context, FFrame& Stack, void* Ret);
static void SetDynamicFoundationTransformHook(UObject* Context, FFrame& Stack, void* Ret);
static void SetDynamicFoundationEnabledHook(UObject* Context, FFrame& Stack, void* Ret);
};

View File

@@ -0,0 +1,8 @@
#pragma once
#include "BuildingActor.h"
class ABuildingGameplayActor : public ABuildingActor
{
public:
};

View File

@@ -0,0 +1,139 @@
#include "BuildingGameplayActorSpawnMachine.h"
#include "FortPlayerControllerAthena.h"
#include "GameplayStatics.h"
#include "AthenaResurrectionComponent.h"
#include "FortGameStateAthena.h"
#include "FortGameModeAthena.h"
void ABuildingGameplayActorSpawnMachine::FinishResurrection(int SquadId)
{
static void (*FinishResurrectionOriginal)(ABuildingGameplayActorSpawnMachine* SpawnMachine, int SquadId) = decltype(FinishResurrectionOriginal)(Addresses::FinishResurrection);
if (FinishResurrectionOriginal)
{
FinishResurrectionOriginal(this, SquadId);
}
else
{
}
}
void ABuildingGameplayActorSpawnMachine::RebootingDelegateHook(ABuildingGameplayActorSpawnMachine* SpawnMachine)
{
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
LOG_INFO(LogDev, "RebootingDelegateHook!");
if (!SpawnMachine->GetResurrectLocation())
{
LOG_WARN(LogRebooting, "Reboot van did not have a resurrection location!");
return;
}
LOG_INFO(LogDev, "PlayerIdsForResurrection.Num(): {}", SpawnMachine->GetPlayerIdsForResurrection().Num());
if (SpawnMachine->GetPlayerIdsForResurrection().Num() <= 0)
return;
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
AFortPlayerControllerAthena* PlayerController = nullptr;
if (auto TeamArrayContainer = GameState->GetTeamsArrayContainer())
{
auto& SquadArray = TeamArrayContainer->SquadsArray.at(SpawnMachine->GetSquadId());
for (int i = 0; i < SquadArray.Num(); ++i)
{
auto StrongPlayerState = SquadArray.at(i).Get();
if (!StrongPlayerState)
continue;
PlayerController = Cast<AFortPlayerControllerAthena>(StrongPlayerState->GetOwner());
if (!PlayerController)
continue;
if (PlayerController->InternalIndex == SpawnMachine->GetInstigatorPC().ObjectIndex)
continue;
break;
}
}
if (!PlayerController)
return;
auto PlayerState = Cast<AFortPlayerStateAthena>(PlayerController->GetPlayerState());
if (!PlayerState)
return;
auto ResurrectionComponent = PlayerController->GetResurrectionComponent();
if (!ResurrectionComponent)
return;
static auto FortPlayerStartClass = FindObject<UClass>(L"/Script/FortniteGame.FortPlayerStart");
if (true) // i dont think we actually need this
{
ResurrectionComponent->GetResurrectionLocation().ObjectIndex = SpawnMachine->GetResurrectLocation()->InternalIndex;
ResurrectionComponent->GetResurrectionLocation().ObjectSerialNumber = GetItemByIndex(SpawnMachine->GetResurrectLocation()->InternalIndex)->SerialNumber;
}
auto StrongResurrectionLocation = ResurrectionComponent->GetResurrectionLocation().Get();
LOG_INFO(LogDev, "StrongResurrectionLocation: {} IsRespawnDataAvailable: {}", __int64(StrongResurrectionLocation), PlayerState->GetRespawnData()->IsRespawnDataAvailable());
if (!StrongResurrectionLocation)
return;
PlayerState->GetRespawnData()->IsRespawnDataAvailable() = false;
PlayerController->SetPlayerIsWaiting(true);
// PlayerController->ServerRestartPlayer();
bool bEnterSkydiving = false; // TODO get from like curve table iirc idk or the variable
PlayerController->RespawnPlayerAfterDeath(bEnterSkydiving);
AFortPlayerPawn* NewPawn = Cast<AFortPlayerPawn>(PlayerController->GetMyFortPawn());
LOG_INFO(LogDev, "NewPawn: {}", __int64(NewPawn));
if (!NewPawn) // Failed to restart player
{
LOG_INFO(LogRebooting, "Failed to restart the player!");
return;
}
PlayerController->ClientClearDeathNotification();
NewPawn->SetHealth(100);
NewPawn->SetMaxHealth(100);
static auto RebootCounterOffset = PlayerState->GetOffset("RebootCounter");
PlayerState->Get<int>(RebootCounterOffset)++;
static auto OnRep_RebootCounterFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerStateAthena.OnRep_RebootCounter");
PlayerState->ProcessEvent(OnRep_RebootCounterFn);
auto OnPlayerPawnResurrectedFn = SpawnMachine->FindFunction("OnPlayerPawnResurrected");
SpawnMachine->ProcessEvent(OnPlayerPawnResurrectedFn, &NewPawn);
static void (*AddToAlivePlayersOriginal)(AFortGameModeAthena* GameMode, AFortPlayerControllerAthena* Player) = decltype(AddToAlivePlayersOriginal)(Addresses::AddToAlivePlayers);
if (AddToAlivePlayersOriginal)
{
AddToAlivePlayersOriginal(GameMode, PlayerController);
}
bool IsFinalPlayerToBeRebooted = true;
if (IsFinalPlayerToBeRebooted)
{
SpawnMachine->FinishResurrection(PlayerState->GetSquadId());
}
}

View File

@@ -0,0 +1,49 @@
#pragma once
#include "BuildingGameplayActor.h"
#include "OnlineReplStructs.h"
#include "WeakObjectPtr.h"
class ABuildingGameplayActorSpawnMachine : public ABuildingGameplayActor
{
public:
TArray<FUniqueNetIdRepl>& GetPlayerIdsForResurrection()
{
static auto PlayerIdsForResurrectionOffset = GetOffset("PlayerIdsForResurrection");
return Get<TArray<FUniqueNetIdRepl>>(PlayerIdsForResurrectionOffset);
}
AActor*& GetResurrectLocation() // actually AFortPlayerStart
{
static auto ResurrectLocationOffset = GetOffset("ResurrectLocation");
return Get<AActor*>(ResurrectLocationOffset);
}
uint8& GetActiveTeam()
{
static auto ActiveTeamOffset = GetOffset("ActiveTeam");
return Get<uint8>(ActiveTeamOffset);
}
uint8& GetSquadId()
{
static auto SquadIdOffset = GetOffset("SquadId");
return Get<uint8>(SquadIdOffset);
}
TWeakObjectPtr<class AFortPlayerControllerAthena> GetInstigatorPC()
{
static auto InstigatorPCOffset = GetOffset("InstigatorPC");
return Get<TWeakObjectPtr<class AFortPlayerControllerAthena>>(InstigatorPCOffset);
}
void FinishResurrection(int SquadId);
static void RebootingDelegateHook(ABuildingGameplayActorSpawnMachine* SpawnMachine);
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/FortniteGame.BuildingGameplayActorSpawnMachine");
return Class;
}
};

View File

@@ -0,0 +1,14 @@
#pragma once
#include "BuildingGameplayActor.h"
class ABuildingItemWeaponUpgradeActor : public ABuildingGameplayActor // ABuildingItemCollectorActor
{
public:
static class UClass* StaticClass()
{
static UClass* Class = FindObject<UClass>(L"/Script/FortniteGame.BuildingItemWeaponUpgradeActor");
return Class;
}
};

View File

@@ -0,0 +1,8 @@
#pragma once
#include "BuildingActor.h"
class ABuildingRift : public ABuildingActor
{
public:
};

View File

@@ -0,0 +1,7 @@
#include "BuildingSMActor.h"
UClass* ABuildingSMActor::StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/FortniteGame.BuildingSMActor");
return Class;
}

View File

@@ -0,0 +1,64 @@
#pragma once
#include "BuildingActor.h"
#include "PlayerState.h"
enum class EFortResourceType : uint8_t
{
Wood = 0,
Stone = 1,
Metal = 2,
Permanite = 3,
None = 4,
EFortResourceType_MAX = 5
};
class ABuildingSMActor : public ABuildingActor
{
public:
bool IsPlayerPlaced()
{
static auto bPlayerPlacedOffset = GetOffset("bPlayerPlaced");
static auto bPlayerPlacedFieldMask = GetFieldMask(this->GetProperty("bPlayerPlaced"));
return ReadBitfieldValue(bPlayerPlacedOffset, bPlayerPlacedFieldMask);
}
void SetPlayerPlaced(bool NewValue)
{
static auto bPlayerPlacedOffset = GetOffset("bPlayerPlaced");
static auto bPlayerPlacedFieldMask = GetFieldMask(this->GetProperty("bPlayerPlaced"));
this->SetBitfieldValue(bPlayerPlacedOffset, bPlayerPlacedFieldMask, NewValue);
}
APlayerState*& GetEditingPlayer()
{
static auto EditingPlayerOffset = GetOffset("EditingPlayer");
return Get<APlayerState*>(EditingPlayerOffset);
}
int& GetCurrentBuildingLevel()
{
static auto CurrentBuildingLevelOffset = GetOffset("CurrentBuildingLevel");
return Get<int>(CurrentBuildingLevelOffset);
}
EFortResourceType& GetResourceType()
{
static auto ResourceTypeOffset = GetOffset("ResourceType");
return Get<EFortResourceType>(ResourceTypeOffset);
}
void SetEditingPlayer(APlayerState* NewEditingPlayer) // actually AFortPlayerStateZone
{
if (// AActor::HasAuthority() &&
(!GetEditingPlayer() || !NewEditingPlayer)
)
{
SetNetDormancy((ENetDormancy)(2 - (NewEditingPlayer != 0)));
// they do something here
GetEditingPlayer() = NewEditingPlayer;
}
}
static UClass* StaticClass();
};

View File

@@ -0,0 +1,17 @@
#include "BuildingStructuralSupportSystem.h"
#include "reboot.h"
bool UBuildingStructuralSupportSystem::IsWorldLocValid(const FVector& WorldLoc)
{
static auto IsWorldLocValidFn = FindObject<UFunction>("/Script/FortniteGame.BuildingStructuralSupportSystem.IsWorldLocValid");
if (!IsWorldLocValidFn)
return true;
struct { FVector WorldLoc; bool Ret; } Params{ WorldLoc };
this->ProcessEvent(IsWorldLocValidFn, &Params);
return Params.Ret;
}

View File

@@ -0,0 +1,10 @@
#pragma once
#include "Object.h"
#include "Vector.h"
class UBuildingStructuralSupportSystem : public UObject
{
public:
bool IsWorldLocValid(const FVector& WorldLoc);
};

View File

@@ -0,0 +1,4 @@
#include "BuildingTrap.h"
#include "GameplayStatics.h"
#include "FortPlayerStateAthena.h"

View File

@@ -0,0 +1,9 @@
#pragma once
#include "BuildingSMActor.h"
class ABuildingTrap : public ABuildingSMActor
{
public:
};

View File

@@ -0,0 +1,15 @@
#include "BuildingWeapons.h"
#include "reboot.h"
void AFortWeap_EditingTool::OnRep_EditActor()
{
static auto OnRep_EditActorFn = FindObject<UFunction>("/Script/FortniteGame.FortWeap_EditingTool.OnRep_EditActor");
this->ProcessEvent(OnRep_EditActorFn);
}
UClass* AFortWeap_EditingTool::StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/FortniteGame.FortWeap_EditingTool");
return Class;
}

View File

@@ -0,0 +1,26 @@
#pragma once
#include "BuildingSMActor.h"
#include "FortWeapon.h"
class AFortWeap_BuildingToolBase : public AFortWeapon
{
};
class AFortWeap_BuildingTool : public AFortWeap_BuildingToolBase
{
};
class AFortWeap_EditingTool : public AFortWeap_BuildingToolBase
{
public:
ABuildingSMActor*& GetEditActor()
{
static auto EditActorOffset = GetOffset("EditActor");
return Get<ABuildingSMActor*>(EditActorOffset);
}
void OnRep_EditActor();
static UClass* StaticClass();
};

View File

@@ -0,0 +1,27 @@
#pragma once
#include "Object.h"
class UChannel : public UObject
{
public:
void StartBecomingDormant()
{
void (*StartBecomingDormantOriginal)(UChannel* Channel) = decltype(StartBecomingDormantOriginal)(this->VFTable[0x298 / 8]);
StartBecomingDormantOriginal(this);
}
bool IsPendingDormancy()
{
static auto BitfieldOffset = GetOffset("Connection") + 8;
return ((PlaceholderBitfield*)(__int64(this) + BitfieldOffset))->Seventh;
}
bool IsDormant()
{
static auto BitfieldOffset = GetOffset("Connection") + 8;
return ((PlaceholderBitfield*)(__int64(this) + BitfieldOffset))->Third;
}
int32 IsNetReady(bool Saturate);
};

View File

@@ -0,0 +1,21 @@
#include "CheatManager.h"
#include "reboot.h"
void UCheatManager::Teleport()
{
static auto TeleportFn = FindObject<UFunction>(L"/Script/Engine.CheatManager.Teleport");
this->ProcessEvent(TeleportFn);
}
void UCheatManager::DestroyTarget()
{
static auto DestroyTargetFn = FindObject<UFunction>("/Script/Engine.CheatManager.DestroyTarget");
this->ProcessEvent(DestroyTargetFn);
}
UClass* UCheatManager::StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/Engine.CheatManager");
return Class;
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include "Object.h"
class UCheatManager : public UObject
{
public:
void Teleport();
void DestroyTarget();
static UClass* StaticClass();
};

View File

@@ -0,0 +1,53 @@
#pragma once
#include "Class.h"
#include "reboot.h"
UObject* UClass::CreateDefaultObject()
{
static std::unordered_map<std::string, UObject*> defaultAbilities; // normal class name, default ability.
static int LastNum1 = 151;
if (LastNum1 != Globals::AmountOfListens)
{
LastNum1 = Globals::AmountOfListens;
defaultAbilities.clear();
}
auto name = this->GetFullName();
if (name.contains("Default__"))
return this;
auto defaultafqaf = defaultAbilities.find(name);
UObject* DefaultObject = nullptr;
if (defaultafqaf != defaultAbilities.end())
{
DefaultObject = defaultafqaf->second;
}
else
{
// skunked class to default
auto ending = name.substr(name.find_last_of(".") + 1);
auto path = name.substr(0, name.find_last_of(".") + 1);
path = path.substr(path.find_first_of(" ") + 1);
auto DefaultAbilityName = std::format("{0}Default__{1}", path, ending);
// std::cout << "DefaultAbilityName: " << DefaultAbilityName << '\n';
DefaultObject = FindObject(DefaultAbilityName);
defaultAbilities.emplace(name, DefaultObject);
}
return DefaultObject;
}
int UStruct::GetPropertiesSize()
{
return *(int*)(__int64(this) + Offsets::PropertiesSize);
}

View File

@@ -0,0 +1,85 @@
#pragma once
#include "Object.h"
#include "addresses.h"
#include "UnrealString.h"
#include "Map.h"
struct UField : UObject
{
UField* Next;
// void* pad; void* pad2;
};
struct UFieldPadding : UObject
{
UField* Next;
void* pad; void* pad2;
};
template <typename PropertyType = void>
static inline PropertyType* GetNext(void* Field)
{
return Fortnite_Version >= 12.10 ? *(PropertyType**)(__int64(Field) + 0x20) : ((UField*)Field)->Next;
}
static inline FName* GetFNameOfProp(void* Property)
{
FName* NamePrivate = nullptr;
if (Fortnite_Version >= 12.10)
NamePrivate = (FName*)(__int64(Property) + 0x28);
else
NamePrivate = &((UField*)Property)->NamePrivate;
return NamePrivate;
}
class UStruct : public UField
{
public:
int GetPropertiesSize();
UStruct* GetSuperStruct() { return *(UStruct**)(__int64(this) + Offsets::SuperStruct); } // idk if this is in UStruct
TArray<uint8_t> GetScript() { return *(TArray<uint8_t>*)(__int64(this) + Offsets::Script); }
};
class UClass : public UStruct
{
public:
UObject* CreateDefaultObject();
};
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)
{
auto nameStr = Name.ToString();
if (nameStr.contains(EnumMemberName))
return Value;
}
}
return -1;
}
};

View File

@@ -0,0 +1,117 @@
#pragma once
#include "NumericLimits.h"
template <int NumElements>
class TInlineAllocator
{
private:
template <int Size, int Alignment>
struct alignas(Alignment) TAlignedBytes
{
unsigned char Pad[Size];
};
template <typename ElementType>
struct TTypeCompatibleBytes : public TAlignedBytes<sizeof(ElementType), alignof(ElementType)>
{
};
public:
template <typename ElementType>
class ForElementType
{
friend class TBitArray;
private:
TTypeCompatibleBytes<ElementType> InlineData[NumElements];
ElementType* SecondaryData;
public:
FORCEINLINE int32 NumInlineBytes() const
{
return sizeof(ElementType) * NumElements;
}
FORCEINLINE int32 NumInlineBits() const
{
return NumInlineBytes() * 8;
}
FORCEINLINE ElementType& operator[](int32 Index)
{
return *(ElementType*)(&InlineData[Index]);
}
FORCEINLINE const ElementType& operator[](int32 Index) const
{
return *(ElementType*)(&InlineData[Index]);
}
FORCEINLINE void operator=(void* InElements)
{
SecondaryData = InElements;
}
FORCEINLINE ElementType& GetInlineElement(int32 Index)
{
return *(ElementType*)(&InlineData[Index]);
}
FORCEINLINE const ElementType& GetInlineElement(int32 Index) const
{
return *(ElementType*)(&InlineData[Index]);
}
FORCEINLINE ElementType& GetSecondaryElement(int32 Index)
{
return SecondaryData[Index];
}
FORCEINLINE const ElementType& GetSecondaryElement(int32 Index) const
{
return SecondaryData[Index];
}
ElementType* GetInlineElements() const
{
return (ElementType*)InlineData;
}
FORCEINLINE ElementType* GetAllocation() const
{
return IfAThenAElseB<ElementType>(SecondaryData, GetInlineElements());
}
};
};
FORCEINLINE /*FMEMORY_INLINE_FUNCTION_DECORATOR*/ size_t /*FMemory::*/QuantizeSize(SIZE_T Count, uint32 Alignment)
{
return Count;
/*
if (!FMEMORY_INLINE_GMalloc)
{
return Count;
}
return FMEMORY_INLINE_GMalloc->QuantizeSize(Count, Alignment); */
}
enum
{
DEFAULT_ALIGNMENT = 0
};
template <typename SizeType>
FORCEINLINE SizeType DefaultCalculateSlackReserve(SizeType NumElements, SIZE_T BytesPerElement, bool bAllowQuantize, uint32 Alignment = DEFAULT_ALIGNMENT)
{
SizeType Retval = NumElements;
// checkSlow(NumElements > 0);
if (bAllowQuantize)
{
auto Count = SIZE_T(Retval) * SIZE_T(BytesPerElement);
Retval = (SizeType)(QuantizeSize(Count, Alignment) / BytesPerElement);
// NumElements and MaxElements are stored in 32 bit signed integers so we must be careful not to overflow here.
if (NumElements > Retval)
{
Retval = TNumericLimits<SizeType>::Max();
}
}
return Retval;
}

View File

@@ -0,0 +1,17 @@
#include "Controller.h"
#include "reboot.h"
AActor* AController::GetViewTarget()
{
static auto GetViewTargetFn = FindObject<UFunction>("/Script/Engine.Controller.GetViewTarget");
AActor* ViewTarget = nullptr;
this->ProcessEvent(GetViewTargetFn, &ViewTarget);
return ViewTarget;
}
void AController::Possess(class APawn* Pawn)
{
auto PossessFn = FindFunction("Possess");
this->ProcessEvent(PossessFn, &Pawn);
}

View File

@@ -0,0 +1,28 @@
#pragma once
#include "Actor.h"
class AController : public AActor
{
public:
AActor* GetViewTarget();
void Possess(class APawn* Pawn);
FName& GetStateName()
{
static auto StateNameOffset = GetOffset("StateName");
return Get<FName>(StateNameOffset);
}
class APawn*& GetPawn()
{
static auto PawnOffset = this->GetOffset("Pawn");
return this->Get<class APawn*>(PawnOffset);
}
class APlayerState*& GetPlayerState()
{
static auto PlayerStateOffset = this->GetOffset("PlayerState");
return this->Get<class APlayerState*>(PlayerStateOffset);
}
};

View File

@@ -0,0 +1,94 @@
#pragma once
#include "Object.h"
#include "NameTypes.h"
#include "reboot.h"
#include "DataTable.h"
enum class ECurveTableMode : unsigned char
{
Empty,
SimpleCurves,
RichCurves
};
struct FSimpleCurveKey
{
float Time; // 0x0000(0x0004) (Edit, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
float Value; // 0x0004(0x0004) (Edit, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
};
struct FIndexedCurve
{
};
struct FRealCurve : public FIndexedCurve
{
};
struct FSimpleCurve : public FRealCurve
{
TArray<FSimpleCurveKey>& GetKeys()
{
static auto KeysOffset = FindOffsetStruct("/Script/Engine.SimpleCurve", "Keys");
return *(TArray<FSimpleCurveKey>*)(__int64(this) + KeysOffset);
}
};
class UCurveTable : public UObject
{
public:
static int GetCurveTableSize()
{
static auto CurveTableClass = FindObject<UClass>("/Script/Engine.CurveTable");
return CurveTableClass->GetPropertiesSize();
}
ECurveTableMode GetCurveTableMode() const
{
static auto CurveTableModeOffset = GetCurveTableSize() - 8;
return *(ECurveTableMode*)(__int64(this) + CurveTableModeOffset);
}
void* GetKey(const FName& RowName, int Index)
{
auto CurveTableMode = GetCurveTableMode();
// LOG_INFO(LogDev, "RowName {} CurveTableMode {} Size {}", RowName.ComparisonIndex.Value ? RowName.ToString() : "InvalidComparision", (int)CurveTableMode, GetCurveTableSize());
if (CurveTableMode == ECurveTableMode::SimpleCurves)
{
auto& RowMap = ((UDataTable*)this)->GetRowMap<FSimpleCurve>(); // its the same offset so
auto Curve = RowMap.Find(RowName);
auto& Keys = Curve->GetKeys();
return Keys.Num() > Index ? &Curve->GetKeys().at(Index) : nullptr;
}
else if (CurveTableMode == ECurveTableMode::RichCurves)
{
LOG_INFO(LogDev, "RICHCURVE UNIMPLEMENTED!");
}
return nullptr;
}
float GetValueOfKey(void* Key)
{
if (!Key)
return 0.f;
auto CurveTableMode = GetCurveTableMode();
if (CurveTableMode == ECurveTableMode::SimpleCurves) return ((FSimpleCurveKey*)Key)->Value;
else if (CurveTableMode == ECurveTableMode::RichCurves) return 0.f;
return 0.f;
}
};
struct FCurveTableRowHandle
{
UCurveTable* CurveTable;
FName RowName;
};

View File

@@ -0,0 +1,16 @@
#include "Channel.h"
#include "NetConnection.h"
int32 UChannel::IsNetReady(bool Saturate)
{
static auto NumOutRecOffset = 0x4C;
if (*(int*)(__int64(this) + NumOutRecOffset) < 255)
{
static auto ConnectionOffset = GetOffset("Connection");
auto Connection = Get<UNetConnection*>(ConnectionOffset);
return Connection->IsNetReady(Saturate);
}
return 0;
}

View File

@@ -0,0 +1,49 @@
#pragma once
#include "Object.h"
#include "reboot.h"
#include "Map.h"
struct FTableRowBase
{
unsigned char UnknownData00[0x8]; // this is actually structural padding
};
class UDataTable : public UObject
{
public:
template <typename RowDataType = uint8_t>
TMap<FName, RowDataType*>& GetRowMap()
{
static auto RowStructOffset = FindOffsetStruct("/Script/Engine.DataTable", "RowStruct");
return *(TMap<FName, RowDataType*>*)(__int64(this) + (RowStructOffset + sizeof(UObject*))); // because after rowstruct is rowmap
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/Engine.DataTable");
return Class;
}
};
struct FDataTableRowHandle
{
UDataTable* DataTable; // 0x0000(0x0008) (Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FName RowName; // 0x0008(0x0008) (Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
};
template <typename StructType = uint8>
struct RowNameAndRowData
{
FName RowName;
StructType* RowData;
};
struct FDataTableCategoryHandle
{
UDataTable* DataTable; // 0x0000(0x0008) (Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FName ColumnName; // 0x0008(0x0008) (Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FName RowContents; // 0x0010(0x0008) (Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
};

View File

@@ -0,0 +1,29 @@
#include "DataTableFunctionLibrary.h"
#include "reboot.h"
float UDataTableFunctionLibrary::EvaluateCurveTableRow(UCurveTable* CurveTable, FName RowName, float InXY,
const FString& ContextString, EEvaluateCurveTableResult* OutResult)
{
static auto fn = FindObject<UFunction>(L"/Script/Engine.DataTableFunctionLibrary.EvaluateCurveTableRow");
float wtf{};
EEvaluateCurveTableResult wtf1{};
struct { UCurveTable* CurveTable; FName RowName; float InXY; EEvaluateCurveTableResult OutResult; float OutXY; FString ContextString; }
UDataTableFunctionLibrary_EvaluateCurveTableRow_Params{CurveTable, RowName, InXY, wtf1, wtf, ContextString};
static auto DefaultClass = StaticClass();
DefaultClass->ProcessEvent(fn, &UDataTableFunctionLibrary_EvaluateCurveTableRow_Params);
if (OutResult)
*OutResult = UDataTableFunctionLibrary_EvaluateCurveTableRow_Params.OutResult;
return UDataTableFunctionLibrary_EvaluateCurveTableRow_Params.OutXY;
}
UClass* UDataTableFunctionLibrary::StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/Engine.DataTableFunctionLibrary");
return Class;
}

View File

@@ -0,0 +1,21 @@
#pragma once
#include "Object.h"
#include "CurveTable.h"
#include "UnrealString.h"
enum class EEvaluateCurveTableResult : uint8_t
{
RowFound = 0,
RowNotFound = 1,
EEvaluateCurveTableResult_MAX = 2
};
class UDataTableFunctionLibrary : public UObject
{
public:
static float EvaluateCurveTableRow(UCurveTable* CurveTable, FName RowName, float InXY,
const FString& ContextString = FString(), EEvaluateCurveTableResult* OutResult = nullptr);
static UClass* StaticClass();
};

View File

@@ -0,0 +1,39 @@
#pragma once
#include "inc.h"
#include "RemoveReference.h"
#include "RemoveCV.h"
namespace UE4Decay_Private
{
template <typename T>
struct TDecayNonReference
{
typedef typename TRemoveCV<T>::Type Type;
};
template <typename T>
struct TDecayNonReference<T[]>
{
typedef T* Type;
};
template <typename T, uint32 N>
struct TDecayNonReference<T[N]>
{
typedef T* Type;
};
template <typename RetType, typename... Params>
struct TDecayNonReference<RetType(Params...)>
{
typedef RetType(*Type)(Params...);
};
}
template <typename T>
struct TDecay
{
typedef typename UE4Decay_Private::TDecayNonReference<typename TRemoveReference<T>::Type>::Type Type;
};

View File

@@ -0,0 +1,19 @@
#pragma once
#include "DelegateBase.h"
#include "DelegateSignatureImpl.inl"
#define FUNC_CONCAT( ... ) __VA_ARGS__
#define FUNC_DECLARE_DELEGATE( DelegateName, ReturnType, ... ) \
typedef TBaseDelegate/*<__VA_ARGS__>*/ DelegateName;
#define FUNC_DECLARE_DYNAMIC_DELEGATE( TWeakPtr, DynamicDelegateName, ExecFunction, FuncParamList, FuncParamPassThru, ... ) \
class DynamicDelegateName : public TBaseDynamicDelegate<TWeakPtr, __VA_ARGS__> \
{ \
public: \
DynamicDelegateName() \
{ \
} \
\
};

View File

@@ -0,0 +1,28 @@
#pragma once
#include "inc.h"
#include "TypeCompatibleBytes.h"
#include "ContainerAllocationPolicies.h"
#if !defined(_WIN32) || defined(_WIN64)
// Let delegates store up to 32 bytes which are 16-byte aligned before we heap allocate
typedef TAlignedBytes<16, 16> FAlignedInlineDelegateType;
#if USE_SMALL_DELEGATES
typedef FHeapAllocator FDelegateAllocatorType;
#else
typedef TInlineAllocator<2> FDelegateAllocatorType;
#endif
#else
// ... except on Win32, because we can't pass 16-byte aligned types by value, as some delegates are
// so we'll just keep it heap-allocated, which are always sufficiently aligned.
typedef TAlignedBytes<16, 8> FAlignedInlineDelegateType;
typedef FHeapAllocator FDelegateAllocatorType;
#endif
class FDelegateBase
{
public:
FDelegateAllocatorType::ForElementType<FAlignedInlineDelegateType> DelegateAllocator;
int32 DelegateSize;
};

View File

@@ -0,0 +1,7 @@
#pragma once
#include "Delegate.h"
#include "ObjectMacros.h"
#define DECLARE_DELEGATE( DelegateName ) FUNC_DECLARE_DELEGATE( DelegateName, void )
#define DECLARE_DYNAMIC_DELEGATE( DelegateName ) /* BODY_MACRO_COMBINE(CURRENT_FILE_ID,_,__LINE__,_DELEGATE) */ FUNC_DECLARE_DYNAMIC_DELEGATE( FWeakObjectPtr, DelegateName, DelegateName##_DelegateWrapper, , FUNC_CONCAT( *this ), void )

View File

@@ -0,0 +1,16 @@
#pragma once
template <bool Const, typename Class, typename FuncType>
struct TMemFunPtrType;
template <typename Class, typename RetType, typename... ArgTypes>
struct TMemFunPtrType<false, Class, RetType(ArgTypes...)>
{
typedef RetType(Class::* Type)(ArgTypes...);
};
template <typename Class, typename RetType, typename... ArgTypes>
struct TMemFunPtrType<true, Class, RetType(ArgTypes...)>
{
typedef RetType(Class::* Type)(ArgTypes...) const;
};

View File

@@ -0,0 +1,63 @@
#pragma once
#include "DelegateBase.h"
#include "ScriptDelegates.h"
#include "DelegateInstanceInterface.h"
#include "RemoveReference.h"
#include "TypeWrapper.h"
// template <typename WrappedRetValType, typename... ParamTypes> // (Milxnor) IDK IM SCUFFED
class TBaseDelegate : public FDelegateBase
{
public:
// (Milxnor) YEAH NO
/*
typedef typename TUnwrapType<WrappedRetValType>::Type RetValType;
template <typename UserClass, typename... VarTypes>
FUNCTION_CHECK_RETURN_START
inline static TBaseDelegate<RetValType, ParamTypes...> CreateRaw(UserClass* InUserObject, typename TMemFunPtrType<false, UserClass, RetValType(ParamTypes..., VarTypes...)>::Type InFunc, VarTypes... Vars)
FUNCTION_CHECK_RETURN_END
{
// UE_STATIC_DEPRECATE(4.23, TIsConst<UserClass>::Value, "Binding a delegate with a const object pointer and non-const function is deprecated.");
TBaseDelegate<RetValType, ParamTypes...> Result;
TBaseRawMethodDelegateInstance<false, UserClass, TFuncType, VarTypes...>::Create(Result, InUserObject, InFunc, Vars...);
return Result;
}
template <typename UserClass, typename... VarTypes>
FUNCTION_CHECK_RETURN_START
inline static TBaseDelegate<RetValType, ParamTypes...> CreateRaw(UserClass* InUserObject, typename TMemFunPtrType<true, UserClass, RetValType(ParamTypes..., VarTypes...)>::Type InFunc, VarTypes... Vars)
FUNCTION_CHECK_RETURN_END
{
TBaseDelegate<RetValType, ParamTypes...> Result;
TBaseRawMethodDelegateInstance<true, UserClass, TFuncType, VarTypes...>::Create(Result, InUserObject, InFunc, Vars...);
return Result;
}
template <typename UserClass, typename... VarTypes>
inline void BindRaw(UserClass* InUserObject, typename TMemFunPtrType<false, UserClass, RetValType(ParamTypes..., VarTypes...)>::Type InFunc, VarTypes... Vars)
{
// UE_STATIC_DEPRECATE(4.23, TIsConst<UserClass>::Value, "Binding a delegate with a const object pointer and non-const function is deprecated.");
*this = CreateRaw(const_cast<typename TRemoveConst<UserClass>::Type*>(InUserObject), InFunc, Vars...);
}
template <typename UserClass, typename... VarTypes>
inline void BindRaw(UserClass* InUserObject, typename TMemFunPtrType<true, UserClass, RetValType(ParamTypes..., VarTypes...)>::Type InFunc, VarTypes... Vars)
{
*this = CreateRaw(InUserObject, InFunc, Vars...);
} */
};
template <typename TWeakPtr, typename RetValType, typename... ParamTypes>
class TBaseDynamicDelegate : public TScriptDelegate<TWeakPtr>
{
public:
/**
* Default constructor
*/
TBaseDynamicDelegate() { }
};

View File

@@ -0,0 +1,15 @@
#pragma once
template <bool Predicate, typename Result = void>
class TEnableIf;
template <typename Result>
class TEnableIf<true, Result>
{
public:
typedef Result Type;
};
template <typename Result>
class TEnableIf<false, Result>
{ };

View File

@@ -0,0 +1,17 @@
#pragma once
#include "World.h"
#include "NetDriver.h"
#include "UnrealString.h"
class UEngine : public UObject
{
public:
static inline UNetDriver* (*Engine_CreateNetDriver)(UEngine* Engine, UWorld* InWorld, FName NetDriverDefinition);
UNetDriver* CreateNetDriver(UWorld* InWorld, FName NetDriverDefinition) { return Engine_CreateNetDriver(this, InWorld, NetDriverDefinition); }
};
// static inline bool (*CreateNamedNetDriver)(UWorld* InWorld, FName NetDriverName, FName NetDriverDefinition);
// static inline UNetDriver* CreateNetDriver_Local(UEngine* Engine, FWorldContext& Context, FName NetDriverDefinition)

View File

@@ -0,0 +1,33 @@
#include "EngineTypes.h"
#include "reboot.h"
UStruct* FHitResult::GetStruct()
{
static auto Struct = FindObject<UStruct>("/Script/Engine.HitResult");
return Struct;
}
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();
}

View File

@@ -0,0 +1,95 @@
#pragma once
#include "Object.h"
#include "Vector.h"
#include "DelegateCombinations.h"
enum class ESpawnActorCollisionHandlingMethod : uint8
{
Undefined,
AlwaysSpawn,
AdjustIfPossibleButAlwaysSpawn,
AdjustIfPossibleButDontSpawnIfColliding,
DontSpawnIfColliding
};
struct FHitResult
{
static class UStruct* GetStruct();
static int GetStructSize();
bool IsBlockingHit();
FVector& GetLocation();
void CopyFromHitResult(FHitResult* Other);
};
struct FTimerHandle
{
FTimerHandle()
: Handle(0)
{
}
/** True if this handle was ever initialized by the timer manager */
bool IsValid() const
{
return Handle != 0;
}
/** Explicitly clear handle */
void Invalidate()
{
Handle = 0;
}
bool operator==(const FTimerHandle& Other) const
{
return Handle == Other.Handle;
}
bool operator!=(const FTimerHandle& Other) const
{
return Handle != Other.Handle;
}
/* FString ToString() const
{
return FString::Printf(TEXT("%llu"), Handle);
} */
// private:
static const uint32 IndexBits = 24;
static const uint32 SerialNumberBits = 40;
static_assert(IndexBits + SerialNumberBits == 64, "The space for the timer index and serial number should total 64 bits");
static const int32 MaxIndex = (int32)1 << IndexBits;
static const uint64 MaxSerialNumber = (uint64)1 << SerialNumberBits;
void SetIndexAndSerialNumber(int32 Index, uint64 SerialNumber)
{
// check(Index >= 0 && Index < MaxIndex);
// check(SerialNumber < MaxSerialNumber);
Handle = (SerialNumber << IndexBits) | (uint64)(uint32)Index;
}
FORCEINLINE int32 GetIndex() const
{
return (int32)(Handle & (uint64)(MaxIndex - 1));
}
FORCEINLINE uint64 GetSerialNumber() const
{
return Handle >> IndexBits;
}
uint64 Handle;
/* friend uint32 GetTypeHash(const FTimerHandle& InHandle)
{
return GetTypeHash(InHandle.Handle);
} */
};
DECLARE_DYNAMIC_DELEGATE(FTimerDynamicDelegate);

View File

@@ -0,0 +1,8 @@
#pragma once
#include "Object.h"
class UEnvQuery : public UObject // UDataAsset
{
public:
};

View File

@@ -0,0 +1,18 @@
#pragma once
#include "NameTypes.h"
enum class EAIParamType : uint8
{
Float,
Int,
Bool
// MAX UMETA(Hidden)
};
struct FEnvNamedValue // i dont thin kthis ever changes
{
FName ParamName;
EAIParamType ParamType;
float Value;
};

View File

@@ -0,0 +1 @@
#pragma once

View File

@@ -0,0 +1,40 @@
#pragma once
#include "Actor.h"
#include "EnvQuery.h"
#include "reboot.h"
#include "EnvQueryTypes.h"
struct FEncounterEnvironmentQueryInfo // idk what file this actually goes in or if this struct ever actaully changes
{
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>(L"/Script/FortniteGame.EncounterEnvironmentQueryInfo");
return Struct;
}
static int GetPropertiesSize() { return GetStruct()->GetPropertiesSize(); }
UEnvQuery*& GetEnvironmentQuery()
{
static auto EnvironmentQueryOffset = FindOffsetStruct("/Script/FortniteGame.EncounterEnvironmentQueryInfo", "EnvironmentQuery");
return *(UEnvQuery**)(__int64(this) + EnvironmentQueryOffset);
}
TArray<FEnvNamedValue>& GetQueryParams()
{
static auto QueryParamsOffset = FindOffsetStruct("/Script/FortniteGame.EncounterEnvironmentQueryInfo", "QueryParams");
return *(TArray<FEnvNamedValue>*)(__int64(this) + QueryParamsOffset);
}
bool& IsDirectional()
{
static auto bIsDirectionalOffset = FindOffsetStruct("/Script/FortniteGame.EncounterEnvironmentQueryInfo", "bIsDirectional");
return *(bool*)(__int64(this) + bIsDirectionalOffset);
}
};
class UFortAIEncounterInfo : public UObject
{
public:
};

View File

@@ -0,0 +1,99 @@
#pragma once
#include "AbilitySystemComponent.h"
#include "reboot.h"
#include "SoftObjectPtr.h"
struct FGameplayEffectApplicationInfoHard
{
public:
static UStruct* GetStruct()
{
static auto GameplayEffectApplicationInfoHardStruct = FindObject<UStruct>("/Script/FortniteGame.GameplayEffectApplicationInfoHard");
return GameplayEffectApplicationInfoHardStruct;
}
static int GetStructSize()
{
return GetStruct()->GetPropertiesSize();
}
UClass* GameplayEffect; // 0x0(0x8)(Edit, ZeroConstructor, DisableEditOnInstance, IsPlainOldData, NoDestructor, UObjectWrapper, HasGetValueTypeHash, NativeAccessSpecifierPublic)
float Level;
};
struct FGameplayEffectApplicationInfo
{
TSoftObjectPtr<UClass> GameplayEffect; // 0x0000(0x0028) UNKNOWN PROPERTY: SoftClassProperty FortniteGame.GameplayEffectApplicationInfo.GameplayEffect
float Level; // 0x0028(0x0004) (Edit, ZeroConstructor, DisableEditOnInstance, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
unsigned char UnknownData01[0x4]; // 0x002C(0x0004) MISSED OFFSET
};
class UFortAbilitySet : public UObject
{
public:
TArray<UClass*>* GetGameplayAbilities()
{
static auto GameplayAbilitiesOffset = this->GetOffset("GameplayAbilities");
return this->GetPtr<TArray<UClass*>>(GameplayAbilitiesOffset);
}
TArray<FGameplayEffectApplicationInfoHard>* GetGrantedGameplayEffects()
{
static auto GrantedGameplayEffectsOffset = this->GetOffset("GrantedGameplayEffects", false);
if (GrantedGameplayEffectsOffset == -1)
return nullptr;
return this->GetPtr<TArray<FGameplayEffectApplicationInfoHard>>(GrantedGameplayEffectsOffset);
}
void ApplyGrantedGameplayAffectsToAbilitySystem(UAbilitySystemComponent* AbilitySystemComponent) // i dont think this is proper
{
if (!FGameplayEffectApplicationInfoHard::GetStruct())
return;
auto GrantedGameplayEffects = GetGrantedGameplayEffects();
for (int i = 0; i < GrantedGameplayEffects->Num(); i++)
{
auto& EffectToGrant = GrantedGameplayEffects->at(i, FGameplayEffectApplicationInfoHard::GetStructSize());
if (!EffectToGrant.GameplayEffect)
{
continue;
}
LOG_INFO(LogDev, "Giving GameplayEffect {}", EffectToGrant.GameplayEffect->GetFullName());
// UObject* GameplayEffect = EffectToGrant.GameplayEffect->CreateDefaultObject();
FGameplayEffectContextHandle EffectContext{}; // AbilitySystemComponent->MakeEffectContext()
AbilitySystemComponent->ApplyGameplayEffectToSelf(EffectToGrant.GameplayEffect, EffectToGrant.Level, EffectContext);
}
}
void GiveToAbilitySystem(UAbilitySystemComponent* AbilitySystemComponent, UObject* SourceObject = nullptr)
{
auto GameplayAbilities = GetGameplayAbilities();
for (int i = 0; i < GameplayAbilities->Num(); i++)
{
UClass* AbilityClass = GameplayAbilities->At(i);
if (!AbilityClass)
continue;
// LOG_INFO(LogDev, "Giving AbilityClass {}", AbilityClass->GetFullName());
AbilitySystemComponent->GiveAbilityEasy(AbilityClass, SourceObject);
}
ApplyGrantedGameplayAffectsToAbilitySystem(AbilitySystemComponent);
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortAbilitySet");
return Class;
}
};

View File

@@ -0,0 +1,13 @@
#pragma once
#include "Object.h"
class UFortAthenaAIBotCharacterCustomization : public UObject
{
public:
FFortAthenaLoadout* GetCustomizationLoadout()
{
static auto CustomizationLoadoutOffset = GetOffset("CustomizationLoadout");
return GetPtr<FFortAthenaLoadout>(CustomizationLoadoutOffset);
}
};

View File

@@ -0,0 +1,45 @@
#pragma once
#include "reboot.h"
#include "FortAthenaAIBotCharacterCustomization.h"
class UFortAthenaAIBotCustomizationData : public UObject // UPrimaryDataAsset
{
public:
UFortAthenaAIBotCharacterCustomization*& GetCharacterCustomization()
{
static auto CharacterCustomizationOffset = GetOffset("CharacterCustomization");
return Get<UFortAthenaAIBotCharacterCustomization*>(CharacterCustomizationOffset);
}
static void ApplyOverrideCharacterCustomizationHook(UFortAthenaAIBotCustomizationData* InBotData, AFortPlayerPawn* NewBot, __int64 idk)
{
LOG_INFO(LogDev, "ApplyOverrideCharacterCustomizationHook!");
auto CharacterCustomization = InBotData->GetCharacterCustomization();
auto Controller = NewBot->GetController();
LOG_INFO(LogDev, "Controller: {}", Controller->IsValidLowLevel() ? Controller->GetPathName() : "BadRead");
static auto CosmeticLoadoutBCOffset = Controller->GetOffset("CosmeticLoadoutBC");
Controller->GetPtr<FFortAthenaLoadout>(CosmeticLoadoutBCOffset)->GetCharacter() = CharacterCustomization->GetCustomizationLoadout()->GetCharacter();
auto PlayerStateAsFort = Cast<AFortPlayerState>(Controller->GetPlayerState());
static auto UpdatePlayerCustomCharacterPartsVisualizationFn = FindObject<UFunction>(L"/Script/FortniteGame.FortKismetLibrary.UpdatePlayerCustomCharacterPartsVisualization");
PlayerStateAsFort->ProcessEvent(UpdatePlayerCustomCharacterPartsVisualizationFn, &PlayerStateAsFort);
PlayerStateAsFort->ForceNetUpdate();
NewBot->ForceNetUpdate();
Controller->ForceNetUpdate();
// NewBot->GetCosmeticLoadout()->GetCharacter() = CharacterCustomization->GetCustomizationLoadout()->GetCharacter();
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/FortniteGame.FortAthenaAIBotCustomizationData");
return Class;
}
};

View File

@@ -0,0 +1,80 @@
#include "FortAthenaCreativePortal.h"
#include "FortPlayerPawn.h"
#include "FortPlayerControllerAthena.h"
void AFortAthenaCreativePortal::TeleportPlayerToLinkedVolumeHook(UObject* Context, FFrame& Stack, void* Ret)
{
LOG_INFO(LogDev, "TeleportPlayerToLinkedVolumeHook!");
auto Portal = (AFortAthenaCreativePortal*)Context; // Cast?
if (!Portal)
return TeleportPlayerToLinkedVolumeOriginal(Context, Stack, Ret);
AFortPlayerPawn* PlayerPawn = nullptr;
bool bUseSpawnTags;
Stack.StepCompiledIn(&PlayerPawn);
Stack.StepCompiledIn(&bUseSpawnTags);
LOG_INFO(LogDev, "PlayerPawn: {}", __int64(PlayerPawn));
if (!PlayerPawn)
return TeleportPlayerToLinkedVolumeOriginal(Context, Stack, Ret);
auto LinkedVolume = Portal->GetLinkedVolume();
LOG_INFO(LogDev, "LinkedVolume: {}", __int64(LinkedVolume));
if (!LinkedVolume)
return TeleportPlayerToLinkedVolumeOriginal(Context, Stack, Ret);
auto Location = LinkedVolume->GetActorLocation();
// Location.Z -= 10000; // proper 1:1
PlayerPawn->TeleportTo(Location, FRotator());
return TeleportPlayerToLinkedVolumeOriginal(Context, Stack, Ret);
}
void AFortAthenaCreativePortal::TeleportPlayerHook(UObject* Context, FFrame& Stack, void* Ret)
{
auto Portal = (AFortAthenaCreativePortal*)Context; // Cast?
if (!Portal)
return TeleportPlayerOriginal(Context, Stack, Ret);
AFortPlayerPawn* PlayerPawn = nullptr;
FRotator TeleportRotation;
Stack.StepCompiledIn(&PlayerPawn);
Stack.StepCompiledIn(&TeleportRotation);
LOG_INFO(LogDev, "PlayerPawn: {}", __int64(PlayerPawn));
if (!PlayerPawn)
return TeleportPlayerOriginal(Context, Stack, Ret);
static auto bReturnToCreativeHubOffset = Portal->GetOffset("bReturnToCreativeHub");
auto bReturnToCreativeHub = Portal->Get<bool>(bReturnToCreativeHubOffset);
LOG_INFO(LogDev, "bReturnToCreativeHub: {}", bReturnToCreativeHub);
if (bReturnToCreativeHub)
{
auto Controller = Cast<AFortPlayerControllerAthena>(PlayerPawn->GetController());
if (!Controller)
return TeleportPlayerOriginal(Context, Stack, Ret);
AFortPlayerControllerAthena::ServerTeleportToPlaygroundLobbyIslandHook(Controller);
}
else
{
static auto TeleportLocationOffset = Portal->GetOffset("TeleportLocation");
auto& TeleportLocation = Portal->Get<FVector>(TeleportLocationOffset);
PlayerPawn->TeleportTo(TeleportLocation, TeleportRotation);
}
return TeleportPlayerOriginal(Context, Stack, Ret);
}

View File

@@ -0,0 +1,79 @@
#pragma once
#include "BuildingActor.h"
#include "FortVolume.h"
#include "Stack.h"
struct FCreativeLoadedLinkData
{
};
class AFortAthenaCreativePortal : public ABuildingActor // ABuildingGameplayActor
{
public:
static inline void (*TeleportPlayerToLinkedVolumeOriginal)(UObject* Context, FFrame& Stack, void* Ret);
static inline void (*TeleportPlayerOriginal)(UObject* Context, FFrame& Stack, void* Ret);
FCreativeLoadedLinkData* GetIslandInfo()
{
static auto CreativeLoadedLinkDataStruct = FindObject<UStruct>("/Script/FortniteGame.CreativeLoadedLinkData");
if (!CreativeLoadedLinkDataStruct)
return nullptr;
static auto IslandInfoOffset = GetOffset("IslandInfo");
return GetPtr<FCreativeLoadedLinkData>(IslandInfoOffset);
}
void* GetOwningPlayer()
{
static auto OwningPlayerOffset = GetOffset("OwningPlayer", false);
if (OwningPlayerOffset == -1)
return nullptr;
return GetPtr<void>(OwningPlayerOffset);
}
bool& GetPortalOpen()
{
static auto bPortalOpenOffset = GetOffset("bPortalOpen");
return Get<bool>(bPortalOpenOffset);
}
bool& GetUserInitiatedLoad()
{
static auto bUserInitiatedLoadOffset = GetOffset("bUserInitiatedLoad");
return Get<bool>(bUserInitiatedLoadOffset);
}
bool& GetInErrorState()
{
static auto bInErrorStateOffset = GetOffset("bInErrorState");
return Get<bool>(bInErrorStateOffset);
}
AFortVolume*& GetLinkedVolume()
{
static auto LinkedVolumeOffset = GetOffset("LinkedVolume");
return Get<AFortVolume*>(LinkedVolumeOffset);
}
FString& GetCreatorName()
{
auto IslandInfo = GetIslandInfo();
if (!IslandInfo)
{
return *(FString*)0;
}
static auto CreatorNameOffset = FindOffsetStruct("/Script/FortniteGame.CreativeLoadedLinkData", "CreatorName");
return *(FString*)(__int64(IslandInfo) + CreatorNameOffset);
}
static void TeleportPlayerToLinkedVolumeHook(UObject* Context, FFrame& Stack, void* Ret);
static void TeleportPlayerHook(UObject* Context, FFrame& Stack, void* Ret);
// hook TeleportPlayer ?? but do what with it
};

View File

@@ -0,0 +1,86 @@
#include "FortAthenaMapInfo.h"
#include "GameplayStatics.h"
#include "FortAthenaSupplyDrop.h"
#include "FortGameModeAthena.h"
#include "Vector2D.h"
FVector2D GenerateRandomVector2D(float Radius)
{
float v3;
float v4;
do
{
v3 = (float)((float)rand() * 0.000061037019) - 1.0;
v4 = (float)((float)rand() * 0.000061037019) - 1.0;
} while ((float)((float)(v4 * v4) + (float)(v3 * v3)) > 1.0);
return FVector2D(v3 * Radius, v4 * Radius);
}
FVector AFortAthenaMapInfo::PickSupplyDropLocation(FVector Center, float Radius)
{
static FVector* (*PickSupplyDropLocationOriginal)(AFortAthenaMapInfo* MapInfo, FVector* outLocation, __int64 Center, float Radius) = decltype(PickSupplyDropLocationOriginal)(Addresses::PickSupplyDropLocation);
if (!PickSupplyDropLocationOriginal)
return FVector(0, 0, 0);
// LOG_INFO(LogDev, "GetAircraftDropVolume: {}", __int64(GetAircraftDropVolume()));
FVector Out = FVector(0, 0, 0);
auto ahh = PickSupplyDropLocationOriginal(this, &Out, __int64(&Center), Radius);
return Out;
}
void AFortAthenaMapInfo::SpawnLlamas()
{
if (!GetLlamaClass())
{
// LOG_INFO(LogDev, "No Llama Class, is this intended?");
return;
}
int AmountOfLlamasSpawned = 0;
auto AmountOfLlamasToSpawn = CalcuateCurveMinAndMax(GetLlamaQuantityMin(), GetLlamaQuantityMax(), 1);
LOG_INFO(LogDev, "Attempting to spawn {} llamas.", AmountOfLlamasToSpawn);
for (int i = 0; i < AmountOfLlamasToSpawn; i++)
{
int Radius = 100000;
FVector Location = PickSupplyDropLocation(FVector(1, 1, 10000), Radius);
// LOG_INFO(LogDev, "Initial Llama at {} {} {}", Location.X, Location.Y, Location.Z);
if (Location.CompareVectors(FVector(0, 0, 0)))
continue;
FRotator RandomYawRotator = FRotator();
RandomYawRotator.Yaw = (float)rand() * 0.010986663f;
FTransform InitialSpawnTransform;
InitialSpawnTransform.Translation = Location;
InitialSpawnTransform.Rotation = RandomYawRotator.Quaternion();
InitialSpawnTransform.Scale3D = FVector(1, 1, 1);
auto LlamaStart = GetWorld()->SpawnActor<AFortAthenaSupplyDrop>(GetLlamaClass(), InitialSpawnTransform,
CreateSpawnParameters(ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn, true));
// LOG_INFO(LogDev, "LlamaStart: {}", __int64(LlamaStart));
if (!LlamaStart)
continue;
auto GroundLocation = LlamaStart->FindGroundLocationAt(InitialSpawnTransform.Translation);
FTransform FinalSpawnTransform = InitialSpawnTransform;
FinalSpawnTransform.Translation = GroundLocation;
LOG_INFO(LogDev, "Spawning Llama at {} {} {}", GroundLocation.X, GroundLocation.Y, GroundLocation.Z);
UGameplayStatics::FinishSpawningActor(LlamaStart, FinalSpawnTransform);
AmountOfLlamasSpawned++;
}
LOG_INFO(LogGame, "Spawned {} llamas.", AmountOfLlamasSpawned);
}

View File

@@ -0,0 +1,164 @@
#pragma once
#include <random>
#include "Actor.h"
#include "GameplayAbilityTypes.h"
#include "DataTableFunctionLibrary.h"
#include "SoftObjectPtr.h"
static inline float CalcuateCurveMinAndMax(FScalableFloat* Min, FScalableFloat* Max, float Multiplier = 100.f) // returns 000 not 0.00 (forgot techinal name for this)
{
float MinSpawnPercent = UDataTableFunctionLibrary::EvaluateCurveTableRow(Min->GetCurve().CurveTable, Min->GetCurve().RowName, 0);
float MaxSpawnPercent = UDataTableFunctionLibrary::EvaluateCurveTableRow(Max->GetCurve().CurveTable, Max->GetCurve().RowName, 0);
std::random_device MinMaxRd;
std::mt19937 MinMaxGen(MinMaxRd());
std::uniform_int_distribution<> MinMaxDis(MinSpawnPercent * Multiplier, MaxSpawnPercent * Multiplier + 1); // + 1 ?
float SpawnPercent = MinMaxDis(MinMaxGen);
return SpawnPercent;
}
struct FBuildingGameplayActorSpawnDetails
{
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>("/Script/FortniteGame.BuildingGameplayActorSpawnDetails");
return Struct;
}
static int GetStructSize() { return GetStruct()->GetPropertiesSize(); }
FScalableFloat* GetSpawnHeight()
{
static auto SpawnHeightOffset = FindOffsetStruct("/Script/FortniteGame.BuildingGameplayActorSpawnDetails", "SpawnHeight");
return (FScalableFloat*)(__int64(this) + SpawnHeightOffset);
}
UClass*& GetBuildingGameplayActorClass()
{
static auto BuildingGameplayActorClassOffset = FindOffsetStruct("/Script/FortniteGame.BuildingGameplayActorSpawnDetails", "BuildingGameplayActorClass");
return *(UClass**)(__int64(this) + BuildingGameplayActorClassOffset);
}
UClass*& GetTargetActorClass()
{
static auto TargetActorClassOffset = FindOffsetStruct("/Script/FortniteGame.BuildingGameplayActorSpawnDetails", "TargetActorClass");
return *(UClass**)(__int64(this) + TargetActorClassOffset);
}
};
struct FVehicleClassDetails
{
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>(L"/Script/FortniteGame.VehicleClassDetails");
return Struct;
}
static int GetStructSize() { return GetStruct()->GetPropertiesSize(); }
TSoftObjectPtr<UClass>& GetVehicleClass()
{
static auto VehicleClassOffset = FindOffsetStruct("/Script/FortniteGame.VehicleClassDetails", "VehicleClass");
return *(TSoftObjectPtr<UClass>*)(__int64(this) + VehicleClassOffset);
}
FScalableFloat* GetVehicleMinSpawnPercent()
{
static auto VehicleMinSpawnPercentOffset = FindOffsetStruct("/Script/FortniteGame.VehicleClassDetails", "VehicleMinSpawnPercent");
return (FScalableFloat*)(__int64(this) + VehicleMinSpawnPercentOffset);
}
FScalableFloat* GetVehicleMaxSpawnPercent()
{
static auto VehicleMaxSpawnPercentOffset = FindOffsetStruct("/Script/FortniteGame.VehicleClassDetails", "VehicleMaxSpawnPercent");
return (FScalableFloat*)(__int64(this) + VehicleMaxSpawnPercentOffset);
}
};
class AFortAthenaMapInfo : public AActor
{
public:
TArray<FVehicleClassDetails>& GetVehicleClassDetails()
{
static auto VehicleClassDetailsOffset = GetOffset("VehicleClassDetails");
return Get<TArray<FVehicleClassDetails>>(VehicleClassDetailsOffset);
}
UClass*& GetAmmoBoxClass()
{
static auto AmmoBoxClassOffset = GetOffset("AmmoBoxClass");
return Get<UClass*>(AmmoBoxClassOffset);
}
FScalableFloat* GetAmmoBoxMinSpawnPercent()
{
static auto AmmoBoxMinSpawnPercentOffset = GetOffset("AmmoBoxMinSpawnPercent");
return GetPtr<FScalableFloat>(AmmoBoxMinSpawnPercentOffset);
}
FScalableFloat* GetAmmoBoxMaxSpawnPercent()
{
static auto AmmoBoxMaxSpawnPercentOffset = GetOffset("AmmoBoxMaxSpawnPercent");
return GetPtr<FScalableFloat>(AmmoBoxMaxSpawnPercentOffset);
}
UClass*& GetTreasureChestClass()
{
static auto TreasureChestClassOffset = GetOffset("TreasureChestClass");
return Get<UClass*>(TreasureChestClassOffset);
}
FScalableFloat* GetTreasureChestMinSpawnPercent()
{
static auto TreasureChestMinSpawnPercentOffset = GetOffset("TreasureChestMinSpawnPercent");
return GetPtr<FScalableFloat>(TreasureChestMinSpawnPercentOffset);
}
FScalableFloat* GetTreasureChestMaxSpawnPercent()
{
static auto TreasureChestMaxSpawnPercentOffset = GetOffset("TreasureChestMaxSpawnPercent");
return GetPtr<FScalableFloat>(TreasureChestMaxSpawnPercentOffset);
}
TArray<FBuildingGameplayActorSpawnDetails>& GetBuildingGameplayActorSpawnDetails()
{
static auto BuildingGameplayActorSpawnDetailsOffset = GetOffset("BuildingGameplayActorSpawnDetails");
return Get<TArray<FBuildingGameplayActorSpawnDetails>>(BuildingGameplayActorSpawnDetailsOffset);
}
FScalableFloat* GetLlamaQuantityMin()
{
static auto LlamaQuantityMinOffset = GetOffset("LlamaQuantityMin");
return GetPtr<FScalableFloat>(LlamaQuantityMinOffset);
}
FScalableFloat* GetLlamaQuantityMax()
{
static auto LlamaQuantityMaxOffset = GetOffset("LlamaQuantityMax");
return GetPtr<FScalableFloat>(LlamaQuantityMaxOffset);
}
UClass* GetLlamaClass()
{
static auto LlamaClassOffset = GetOffset("LlamaClass", false);
if (LlamaClassOffset == -1)
return nullptr;
return Get<UClass*>(LlamaClassOffset);
}
AActor*& GetAircraftDropVolume() // actually AVolume
{
static auto AircraftDropVolumeOffset = GetOffset("AircraftDropVolume");
return Get<AActor*>(AircraftDropVolumeOffset);
}
FVector PickSupplyDropLocation(FVector Center, float Radius);
void SpawnLlamas();
};

View File

@@ -0,0 +1,44 @@
#pragma once
#include <functional>
#include "Actor.h"
#include "Stack.h"
#include "ScriptInterface.h"
#include "FortGameStateAthena.h"
#include "GameplayStatics.h"
class AFortAthenaMutator : public AActor // AFortGameplayMutator
{
public:
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortAthenaMutator");
return Class;
}
};
static inline void LoopMutators(std::function<void(AFortAthenaMutator*)> Callback)
{
auto AllMutators = UGameplayStatics::GetAllActorsOfClass(GetWorld(), AFortAthenaMutator::StaticClass());
for (int i = 0; i < AllMutators.Num(); i++)
{
Callback((AFortAthenaMutator*)AllMutators.at(i));
}
AllMutators.Free();
}
template <typename MutatorType = AFortAthenaMutator>
static inline MutatorType* FindFirstMutator(UClass* MutatorClass = MutatorType::StaticClass())
{
auto AllMutators = UGameplayStatics::GetAllActorsOfClass(GetWorld(), MutatorClass);
auto FirstMutator = AllMutators.Num() >= 1 ? AllMutators.at(0) : nullptr;
AllMutators.Free();
return (MutatorType*)FirstMutator;
}

View File

@@ -0,0 +1,37 @@
#include "FortAthenaMutator_Barrier.h"
void AFortAthenaMutator_Barrier::OnGamePhaseStepChangedHook(UObject* Context, FFrame& Stack, void* Ret)
{
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
if (!GameState)
return OnGamePhaseStepChangedOriginal(Context, Stack, Ret);
LOG_INFO(LogDev, "OnGamePhaseStepChangedHook gamepadsl gwrigjsafjob fs: {}", (int)GameState->GetGamePhaseStep());
/*
TScriptInterface<UObject> SafeZoneInterface;
EAthenaGamePhaseStep GamePhaseStep;
static auto SafeZoneInterfaceOffset = FindOffsetStruct("/Script/FortniteGame.FortAthenaMutator_Barrier.OnGamePhaseStepChanged", "SafeZoneInterface", false);
if (SafeZoneInterfaceOffset != -1)
Stack.StepCompiledIn(&SafeZoneInterface);
Stack.StepCompiledIn(&GamePhaseStep);
LOG_INFO(LogDev, "{} GamePhaseStep: {}", __FUNCTION__, (int)GamePhaseStep);
if (GamePhaseStep == EAthenaGamePhaseStep::Warmup)
{
// idk when they spawn the barrier could also be warmup or something
}
else if (GamePhaseStep == EAthenaGamePhaseStep::BusLocked)
{
// idk if they spawn the heads on flying or locked
}
*/
return OnGamePhaseStepChangedOriginal(Context, Stack, Ret);
}

View File

@@ -0,0 +1,87 @@
// Food Fight
#pragma once
#include "FortAthenaMutator.h"
#include "AthenaBigBaseWall.h"
#include "AthenaBarrierObjective.h"
#include "AthenaBarrierFlag.h"
/*
EVENT IDS (got on 10.40):
WallComingDown - 1
WallDown - 2
// IDK REST COMPILER WAS TOO SMART
Intro - 9
NoMoreRespawns - 10
*/
struct FBarrierTeamState // Idk if this actually changes
{
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>(L"/Script/FortniteGame.BarrierTeamState");
return Struct;
}
static int GetStructSize() { return GetStruct()->GetPropertiesSize(); }
EBarrierFoodTeam& GetFoodTeam()
{
static auto FoodTeamOffset = FindOffsetStruct("/Script/FortniteGame.BarrierTeamState", "FoodTeam");
return *(EBarrierFoodTeam*)(__int64(this) + FoodTeamOffset);
}
AAthenaBarrierFlag*& GetObjectiveFlag()
{
static auto ObjectiveFlagOffset = FindOffsetStruct("/Script/FortniteGame.BarrierTeamState", "ObjectiveFlag");
return *(AAthenaBarrierFlag**)(__int64(this) + ObjectiveFlagOffset);
}
AAthenaBarrierObjective*& GetObjectiveObject()
{
static auto ObjectiveObjectOffset = FindOffsetStruct("/Script/FortniteGame.BarrierTeamState", "ObjectiveObject");
return *(AAthenaBarrierObjective**)(__int64(this) + ObjectiveObjectOffset);
}
};
class AFortAthenaMutator_Barrier : public AFortAthenaMutator
{
public:
static inline void (*OnGamePhaseStepChangedOriginal)(UObject* Context, FFrame& Stack, void* Ret);
UClass* GetBigBaseWallClass()
{
static auto BigBaseWallClassOffset = GetOffset("BigBaseWallClass");
return Get<UClass*>(BigBaseWallClassOffset);
}
UClass* GetObjectiveFlagClass()
{
static auto ObjectiveFlagOffset = GetOffset("ObjectiveFlag");
return Get<UClass*>(ObjectiveFlagOffset);
}
AAthenaBigBaseWall*& GetBigBaseWall()
{
static auto BigBaseWallOffset = GetOffset("BigBaseWall");
return Get<AAthenaBigBaseWall*>(BigBaseWallOffset);
}
FBarrierTeamState* GetTeam_0_State()
{
static auto Team_0_StateOffset = GetOffset("Team_0_State");
return GetPtr<FBarrierTeamState>(Team_0_StateOffset);
}
FBarrierTeamState* GetTeam_1_State()
{
static auto Team_1_StateOffset = GetOffset("Team_1_State");
return GetPtr<FBarrierTeamState>(Team_1_StateOffset);
}
static void OnGamePhaseStepChangedHook(UObject* Context, FFrame& Stack, void* Ret);
};

View File

@@ -0,0 +1,32 @@
#pragma once
#include "FortAthenaMutator.h"
class AFortAthenaMutator_Bots : public AFortAthenaMutator // AFortAthenaMutator_SpawningPolicyEQS
{
public:
class AFortPlayerPawnAthena* SpawnBot(UClass* BotPawnClass, AActor* InSpawnLocator, const FVector& InSpawnLocation, const FRotator& InSpawnRotation, bool bSnapToGround)
{
static auto SpawnBotFn = FindObject<UFunction>(L"/Script/FortniteGame.FortAthenaMutator_Bots.SpawnBot");
struct
{
UClass* BotPawnClass; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, UObjectWrapper, HasGetValueTypeHash, NativeAccessSpecifierPublic)
AActor* InSpawnLocator; // (ConstParm, Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FVector InSpawnLocation; // (ConstParm, Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FRotator InSpawnRotation; // (ConstParm, Parm, ZeroConstructor, IsPlainOldData, NoDestructor, NativeAccessSpecifierPublic)
bool bSnapToGround; // (ConstParm, Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
AFortPlayerPawnAthena* ReturnValue; // (Parm, OutParm, ZeroConstructor, ReturnParm, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
} AFortAthenaMutator_Bots_SpawnBot_Params{ BotPawnClass, InSpawnLocator, InSpawnLocation, InSpawnRotation, bSnapToGround };
this->ProcessEvent(SpawnBotFn, &AFortAthenaMutator_Bots_SpawnBot_Params);
return AFortAthenaMutator_Bots_SpawnBot_Params.ReturnValue;
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortAthenaMutator_Bots");
return Class;
}
};

View File

@@ -0,0 +1,18 @@
#include "FortAthenaMutator_Disco.h"
void AFortAthenaMutator_Disco::OnGamePhaseStepChangedHook(UObject* Context, FFrame& Stack, void* Ret)
{
/* TScriptInterface<UObject> SafeZoneInterface;
EAthenaGamePhaseStep GamePhaseStep = EAthenaGamePhaseStep::BusFlying;
static auto SafeZoneInterfaceOffset = FindOffsetStruct("/Script/FortniteGame.FortAthenaMutator_Disco.OnGamePhaseStepChanged", "SafeZoneInterface", false);
if (SafeZoneInterfaceOffset != -1)
Stack.StepCompiledIn(&SafeZoneInterface);
Stack.StepCompiledIn(&GamePhaseStep, true); */
// LOG_INFO(LogDev, "{} GamePhaseStep: {}", __FUNCTION__, (int)GamePhaseStep);
return OnGamePhaseStepChangedOriginal(Context, Stack, Ret);
}

View File

@@ -0,0 +1,31 @@
// Disco Domination
#pragma once
#include "FortAthenaMutator.h"
#include "Array.h"
struct FControlPointSpawnData
{
};
class AFortAthenaMutator_Disco : public AFortAthenaMutator
{
public:
static inline void (*OnGamePhaseStepChangedOriginal)(UObject* Context, FFrame& Stack, void* Ret);
TArray<FControlPointSpawnData>& GetControlPointSpawnData()
{
static auto ControlPointSpawnDataOffset = GetOffset("ControlPointSpawnData");
return Get<TArray<FControlPointSpawnData>>(ControlPointSpawnDataOffset);
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/FortniteGame.FortAthenaMutator_Disco");
return Class;
}
static void OnGamePhaseStepChangedHook(UObject* Context, FFrame& Stack, void* Ret);
};

View File

@@ -0,0 +1,93 @@
// Gun Game
#pragma once
#include "Actor.h"
#include "CurveTable.h"
#include "GameplayAbilityTypes.h"
#include "FortWeaponItemDefinition.h"
#include "Stack.h"
#include "FortPlayerStateAthena.h"
#include "FortAthenaMutator.h"
struct FGunGameGunEntry
{
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>("/Script/FortniteGame.GunGameGunEntry");
return Struct;
}
static int GetStructSize() { return GetStruct()->GetPropertiesSize(); }
UFortWeaponItemDefinition*& GetWeapon()
{
static auto WeaponOffset = FindOffsetStruct("/Script/FortniteGame.GunGameGunEntry", "Weapon");
return *(UFortWeaponItemDefinition**)(__int64(this) + WeaponOffset);
}
FScalableFloat& GetEnabled()
{
static auto EnabledOffset = FindOffsetStruct("/Script/FortniteGame.GunGameGunEntry", "Enabled");
return *(FScalableFloat*)(__int64(this) + EnabledOffset);
}
FScalableFloat& GetAwardAtElim()
{
static auto AwardAtElimOffset = FindOffsetStruct("/Script/FortniteGame.GunGameGunEntry", "AwardAtElim");
return *(FScalableFloat*)(__int64(this) + AwardAtElimOffset);
}
};
struct FGunGameGunEntries
{
TArray<FGunGameGunEntry> Entries; // 0x0000(0x0010) (ZeroConstructor, NativeAccessSpecifierPublic)
};
struct FGunGamePlayerData
{
TArray<UFortWeaponItemDefinition*> CurrentlyAssignedWeapons; // 0x0000(0x0010) (ZeroConstructor, NativeAccessSpecifierPublic)
};
class AFortAthenaMutator_GG : public AFortAthenaMutator
{
public:
TArray<FGunGameGunEntry>& GetWeaponEntries()
{
static auto WeaponEntriesOffset = GetOffset("WeaponEntries");
return Get<TArray<FGunGameGunEntry>>(WeaponEntriesOffset);
}
TMap<int, FGunGameGunEntries>& GetAwardEntriesAtElimMap()
{
static auto AwardEntriesAtElimMapOffset = GetOffset("AwardEntriesAtElimMap");
return Get<TMap<int, FGunGameGunEntries>>(AwardEntriesAtElimMapOffset);
}
TMap<AFortPlayerStateAthena*, FGunGamePlayerData>& GetPlayerData()
{
static auto PlayerDataOffset = GetOffset("PlayerData");
return Get<TMap<AFortPlayerStateAthena*, FGunGamePlayerData>>(PlayerDataOffset);
}
FGunGameGunEntries GetEntriesFromAward(const FScalableFloat& AwardAtElim)
{
auto& AwardEntriesAtElimMap = GetAwardEntriesAtElimMap();
float Value = 0; // TODO Get from AwardAtElim
for (auto& AwardEntry : AwardEntriesAtElimMap)
{
if (AwardEntry.First == Value)
{
return AwardEntry.Second;
}
}
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortAthenaMutator_GG");
return Class;
}
};

View File

@@ -0,0 +1,8 @@
#include "FortAthenaMutator_GiveItemsAtGamePhaseStep.h"
void AFortAthenaMutator_GiveItemsAtGamePhaseStep::OnGamePhaseStepChangedHook(UObject* Context, FFrame& Stack, void* Ret)
{
LOG_INFO(LogDev, __FUNCTION__);
return OnGamePhaseStepChangedOriginal(Context, Stack, Ret);
}

View File

@@ -0,0 +1,57 @@
#pragma once
#include "Actor.h"
#include "CurveTable.h"
#include "GameplayAbilityTypes.h"
#include "FortWorldItemDefinition.h"
#include "Stack.h"
#include "FortAthenaMutator.h"
struct FItemsToGive
{
static UStruct* GetStruct()
{
static auto Struct = FindObject<UStruct>("/Script/FortniteGame.ItemsToGive");
return Struct;
}
static int GetStructSize() { return GetStruct()->GetPropertiesSize(); }
UFortWorldItemDefinition*& GetItemToDrop()
{
static auto ItemToDropOffset = FindOffsetStruct("/Script/FortniteGame.ItemsToGive", "ItemToDrop");
return *(UFortWorldItemDefinition**)(__int64(this) + ItemToDropOffset);
}
FScalableFloat& GetNumberToGive()
{
static auto NumberToGiveOffset = FindOffsetStruct("/Script/FortniteGame.ItemsToGive", "NumberToGive");
return *(FScalableFloat*)(__int64(this) + NumberToGiveOffset);
}
};
class AFortAthenaMutator_GiveItemsAtGamePhaseStep : public AFortAthenaMutator
{
public:
static inline void (*OnGamePhaseStepChangedOriginal)(UObject* Context, FFrame& Stack, void* Ret);
uint8_t& GetPhaseToGiveItems()
{
static auto PhaseToGiveItemsOffset = GetOffset("PhaseToGiveItems");
return Get<uint8_t>(PhaseToGiveItemsOffset);
}
TArray<FItemsToGive>& GetItemsToGive()
{
static auto ItemsToGiveOffset = GetOffset("ItemsToGive");
return Get<TArray<FItemsToGive>>(ItemsToGiveOffset);
}
static void OnGamePhaseStepChangedHook(UObject* Context, FFrame& Stack, void* Ret);
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortAthenaMutator_GiveItemsAtGamePhaseStep");
return Class;
}
};

View File

@@ -0,0 +1,42 @@
#pragma once
#include "FortAthenaMutator.h"
#include "GameplayAbilityTypes.h"
#include "reboot.h"
struct FFortPieSliceSpawnData
{
FScalableFloat SpawnDirection; // 0x0000(0x0020) (Edit, BlueprintVisible, DisableEditOnInstance, NativeAccessSpecifierPublic)
FScalableFloat SpawnDirectionDeviation; // 0x0020(0x0020) (Edit, BlueprintVisible, DisableEditOnInstance, NativeAccessSpecifierPublic)
FScalableFloat MinSpawnDistanceFromCenter; // 0x0040(0x0020) (Edit, BlueprintVisible, DisableEditOnInstance, NativeAccessSpecifierPublic)
FScalableFloat MaxSpawnDistanceFromCenter; // 0x0060(0x0020) (Edit, BlueprintVisible, DisableEditOnInstance, NativeAccessSpecifierPublic)
};
struct FHeistExitCraftSpawnData : public FFortPieSliceSpawnData
{
FScalableFloat SpawnDelayTime; // 0x0080(0x0020) (Edit, BlueprintVisible, DisableEditOnInstance, NativeAccessSpecifierPublic)
FScalableFloat SafeZonePhaseWhenToSpawn; // 0x00A0(0x0020) (Edit, BlueprintVisible, DisableEditOnInstance, NativeAccessSpecifierPublic)
FScalableFloat SafeZonePhaseWhereToSpawn; // 0x00C0(0x0020) (Edit, BlueprintVisible, DisableEditOnInstance, NativeAccessSpecifierPublic)
};
class AFortAthenaMutator_Heist : public AFortAthenaMutator
{
public:
/* TArray<FHeistExitCraftSpawnData>& GetHeistExitCraftSpawnData()
{
static auto HeistExitCraftSpawnDataOffset = GetOffset("HeistExitCraftSpawnData");
return Get<TArray<FHeistExitCraftSpawnData>>(HeistExitCraftSpawnDataOffset);
} */
float& GetSpawnExitCraftTime()
{
static auto SpawnExitCraftTimeOffset = GetOffset("SpawnExitCraftTime");
return Get<float>(SpawnExitCraftTimeOffset);
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/FortniteGame.FortAthenaMutator_Heist");
return Class;
}
};

View File

@@ -0,0 +1,131 @@
#pragma once
#include "FortAthenaMutator.h"
enum class EAthenaLootDropOverride : uint8_t
{
NoOverride = 0,
ForceDrop = 1,
ForceKeep = 2,
ForceDestroy = 3,
ForceDropUnlessRespawning = 4,
ForceDestroyUnlessRespawning = 5,
EAthenaLootDropOverride_MAX = 6
};
enum class EAthenaInventorySpawnOverride : uint8_t
{
NoOverride = 0,
Always = 1,
IntialSpawn = 2,
AircraftPhaseOnly = 3,
EAthenaInventorySpawnOverride_MAX = 4
};
struct FItemLoadoutContainer
{
TArray<FItemAndCount> Loadout;
};
struct FItemLoadoutTeamMap
{
unsigned char TeamIndex; // 0x0000(0x0001) (Edit, ZeroConstructor, DisableEditOnInstance, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
unsigned char LoadoutIndex; // 0x0001(0x0001) (Edit, ZeroConstructor, DisableEditOnInstance, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
EAthenaInventorySpawnOverride UpdateOverrideType; // 0x0002(0x0001) (Edit, ZeroConstructor, DisableEditOnInstance, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
EAthenaLootDropOverride DropAllItemsOverride; // 0x0003(0x0001) (Edit, BlueprintVisible, ZeroConstructor, DisableEditOnInstance, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
};
class AFortAthenaMutator_InventoryOverride : public AFortAthenaMutator
{
public:
TArray<FItemLoadoutContainer>& GetInventoryLoadouts()
{
static auto InventoryLoadoutsOffset = GetOffset("InventoryLoadouts");
return Get<TArray<FItemLoadoutContainer>>(InventoryLoadoutsOffset);
}
TArray<FItemLoadoutTeamMap>* GetTeamLoadouts()
{
static auto TeamLoadoutsOffset = GetOffset("TeamLoadouts", false);
if (TeamLoadoutsOffset == -1)
return nullptr;
return GetPtr<TArray<FItemLoadoutTeamMap>>(TeamLoadoutsOffset);
}
FItemLoadoutTeamMap GetLoadoutTeamForTeamIndex(uint8_t TeamIndex)
{
auto TeamLoadouts = GetTeamLoadouts();
if (!TeamLoadouts)
return FItemLoadoutTeamMap();
for (int i = 0; i < TeamLoadouts->Num(); i++)
{
auto& TeamLoadout = TeamLoadouts->at(i);
if (TeamLoadout.TeamIndex == TeamIndex)
return TeamLoadout;
}
return FItemLoadoutTeamMap();
}
FItemLoadoutContainer GetLoadoutContainerForTeamIndex(uint8_t TeamIndex)
{
auto LoadoutTeam = GetLoadoutTeamForTeamIndex(TeamIndex);
if (LoadoutTeam.TeamIndex == TeamIndex)
{
auto& InventoryLoadouts = GetInventoryLoadouts();
if (InventoryLoadouts.Num() - 1 < LoadoutTeam.LoadoutIndex)
return FItemLoadoutContainer();
return InventoryLoadouts.at(LoadoutTeam.LoadoutIndex);
}
return FItemLoadoutContainer();
}
EAthenaInventorySpawnOverride& GetInventoryUpdateOverride(uint8_t TeamIndex = 255)
{
if (TeamIndex != 255)
{
auto LoadoutTeam = GetLoadoutTeamForTeamIndex(TeamIndex);
if (LoadoutTeam.TeamIndex == TeamIndex)
{
if (LoadoutTeam.UpdateOverrideType != EAthenaInventorySpawnOverride::NoOverride)
return LoadoutTeam.UpdateOverrideType;
}
}
static auto InventoryUpdateOverrideOffset = GetOffset("InventoryUpdateOverride");
return Get<EAthenaInventorySpawnOverride>(InventoryUpdateOverrideOffset);
}
EAthenaLootDropOverride& GetDropAllItemsOverride(uint8_t TeamIndex = 255)
{
if (TeamIndex != 255)
{
auto LoadoutTeam = GetLoadoutTeamForTeamIndex(TeamIndex);
if (LoadoutTeam.TeamIndex == TeamIndex)
{
if (LoadoutTeam.DropAllItemsOverride != EAthenaLootDropOverride::NoOverride)
return LoadoutTeam.DropAllItemsOverride;
}
}
static auto DropAllItemsOverrideOffset = GetOffset("DropAllItemsOverride");
return Get<EAthenaLootDropOverride>(DropAllItemsOverrideOffset);
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortAthenaMutator_InventoryOverride");
return Class;
}
};

View File

@@ -0,0 +1,35 @@
#pragma once
#include "FortAthenaMutator_InventoryOverride.h"
#include "GameplayAbilityTypes.h"
#include "CurveTable.h"
#include "FortItemDefinition.h"
#include "FortInventory.h"
struct FHotfixableInventoryOverrideItem
{
public:
FScalableFloat Count; // 0x0(0x20)(Edit, BlueprintVisible, NativeAccessSpecifierPublic)
UFortItemDefinition* Item; // 0x20(0x8)(Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
};
struct FItemLoadoutContainer
{
public:
FScalableFloat bEnabled; // 0x0(0x20)(Edit, DisableEditOnInstance, NativeAccessSpecifierPublic)
TArray<FItemAndCount> Loadout; // 0x20(0x10)(ZeroConstructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
TArray<FHotfixableInventoryOverrideItem> LoadoutList; // 0x30(0x10)(Edit, BlueprintVisible, ZeroConstructor, DisableEditOnInstance, HasGetValueTypeHash, NativeAccessSpecifierPublic)
};
struct FItemLoadoutBucket
{
public:
FScalableFloat bEnabled; // 0x0(0x20)(Edit, DisableEditOnInstance, NativeAccessSpecifierPublic)
TArray<FItemLoadoutContainer> Loadouts; // 0x20(0x10)(Edit, ZeroConstructor, DisableEditOnInstance, HasGetValueTypeHash, NativeAccessSpecifierPublic)
uint8 Pad_3D83[0x8]; // Fixing Size Of Struct [ Dumper-7 ]
};
class AFortAthenaMutator_InventoryOverride_Bucket : public AFortAthenaMutator_InventoryOverride
{
public:
};

View File

@@ -0,0 +1,23 @@
#pragma once
#include "FortAthenaMutator.h"
#include "GameplayAbilityTypes.h"
#include "CurveTable.h"
#include "FortWorldItemDefinition.h"
#include "FortInventory.h"
struct FItemsToDropOnDeath
{
UFortWorldItemDefinition* ItemToDrop; // 0x0000(0x0008) (Edit, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FScalableFloat NumberToDrop; // 0x0008(0x0020) (Edit, NativeAccessSpecifierPublic)
};
class AFortAthenaMutator_ItemDropOnDeath : public AFortAthenaMutator
{
public:
TArray<FItemsToDropOnDeath>& GetItemsToDrop()
{
static auto ItemsToDropOffset = GetOffset("ItemsToDrop");
return Get<TArray<FItemsToDropOnDeath>>(ItemsToDropoOffset);
}
};

View File

@@ -0,0 +1,8 @@
#pragma once
#include "FortAthenaMutator.h"
class AFortAthenaMutator_LoadoutSwap : public AFortAthenaMutator
{
public:
};

View File

@@ -0,0 +1,15 @@
#pragma once
#include "FortAthenaMutator.h"
#include "reboot.h"
class AFortAthenaMutator_TDM : public AFortAthenaMutator
{
public:
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortAthenaMutator_TDM");
return Class;
}
};

View File

@@ -0,0 +1,23 @@
#pragma once
#include "ActorComponent.h"
#include "FortAthenaPatrolPath.h"
#include "reboot.h"
class UFortAthenaNpcPatrollingComponent : public UActorComponent
{
public:
void SetPatrolPath(AFortAthenaPatrolPath* NewPatrolPath)
{
static auto SetPatrolPathFn = FindObject<UFunction>(L"/Script/FortniteGame.FortAthenaNpcPatrollingComponent:SetPatrolPath");
this->ProcessEvent(SetPatrolPathFn, &NewPatrolPath);
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/FortniteGame.FortAthenaNpcPatrollingComponent");
return Class;
}
};

View File

@@ -0,0 +1,8 @@
#pragma once
#include "Actor.h"
class AFortAthenaPatrolPath : public AActor
{
public:
};

View File

@@ -0,0 +1,67 @@
#pragma once
#include "Actor.h"
#include "FortAthenaVehicle.h"
#include "reboot.h"
class AFortAthenaSKPushCannon : public AFortAthenaVehicle // : public AFortAthenaSKPushVehicle
{
public:
bool IsPushCannonBP()
{
static auto PushCannonBP = FindObject<UClass>("/Game/Athena/DrivableVehicles/PushCannon.PushCannon_C"); // We should loadobject it.
return this->IsA(PushCannonBP);
}
void MultiCastPushCannonLaunchedPlayer()
{
static auto MultiCastPushCannonLaunchedPlayerFn = FindObject<UFunction>("/Script/FortniteGame.FortAthenaSKPushCannon.MultiCastPushCannonLaunchedPlayer");
this->ProcessEvent(MultiCastPushCannonLaunchedPlayerFn);
}
void OnLaunchPawn(AFortPlayerPawn* Pawn, FVector LaunchDir)
{
static auto OnLaunchPawnFn = IsPushCannonBP() ? FindObject<UFunction>("/Game/Athena/DrivableVehicles/PushCannon.PushCannon_C.OnLaunchPawn") : FindObject<UFunction>("/Script/FortniteGame.FortAthenaSKPushCannon.OnLaunchPawn");
struct
{
AFortPlayerPawn* Pawn; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
struct FVector LaunchDir; // (ConstParm, Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
} AFortAthenaSKPushCannon_OnLaunchPawn_Params{ Pawn, LaunchDir };
this->ProcessEvent(OnLaunchPawnFn, &AFortAthenaSKPushCannon_OnLaunchPawn_Params);
}
void OnPreLaunchPawn(AFortPlayerPawn* Pawn, FVector LaunchDir)
{
static auto OnPreLaunchPawnFn = IsPushCannonBP() ? FindObject<UFunction>("/Game/Athena/DrivableVehicles/PushCannon.PushCannon_C.OnPreLaunchPawn") : FindObject<UFunction>("/Script/FortniteGame.FortAthenaSKPushCannon.OnPreLaunchPawn");
struct
{
AFortPlayerPawn* Pawn; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FVector LaunchDir; // (ConstParm, Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
} AFortAthenaSKPushCannon_OnPreLaunchPawn_Params{ Pawn, LaunchDir };
this->ProcessEvent(OnPreLaunchPawnFn, &AFortAthenaSKPushCannon_OnPreLaunchPawn_Params);
}
void ShootPawnOut(const FVector& LaunchDir)
{
auto PawnToShoot = this->GetPawnAtSeat(1);
LOG_INFO(LogDev, "PawnToShoot: {}", __int64(PawnToShoot));
if (!PawnToShoot)
return;
this->OnPreLaunchPawn(PawnToShoot, LaunchDir);
PawnToShoot->ServerOnExitVehicle(ETryExitVehicleBehavior::ForceAlways);
this->OnLaunchPawn(PawnToShoot, LaunchDir);
this->MultiCastPushCannonLaunchedPlayer();
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortAthenaSKPushCannon");
return Class;
}
};

View File

@@ -0,0 +1,93 @@
#include "FortAthenaSupplyDrop.h"
#include "FortGameStateAthena.h"
FVector AFortAthenaSupplyDrop::FindGroundLocationAt(FVector InLocation)
{
static auto FindGroundLocationAtFn = FindObject<UFunction>(L"/Script/FortniteGame.FortAthenaSupplyDrop.FindGroundLocationAt");
struct
{
FVector InLocation; // (ConstParm, Parm, OutParm, ZeroConstructor, ReferenceParm, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FVector ReturnValue; // (Parm, OutParm, ZeroConstructor, ReturnParm, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
} AFortAthenaSupplyDrop_FindGroundLocationAt_Params{ InLocation };
this->ProcessEvent(FindGroundLocationAtFn, &AFortAthenaSupplyDrop_FindGroundLocationAt_Params);
return AFortAthenaSupplyDrop_FindGroundLocationAt_Params.ReturnValue;
}
AFortPickup* AFortAthenaSupplyDrop::SpawnPickupFromItemEntryHook(UObject* Context, FFrame& Stack, AFortPickup** Ret)
{
LOG_INFO(LogDev, __FUNCTION__);
return SpawnPickupFromItemEntryOriginal(Context, Stack, Ret);
}
AFortPickup* AFortAthenaSupplyDrop::SpawnGameModePickupHook(UObject* Context, FFrame& Stack, AFortPickup** Ret)
{
UFortWorldItemDefinition* ItemDefinition = nullptr; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
UClass* PickupClass = nullptr; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, UObjectWrapper, HasGetValueTypeHash, NativeAccessSpecifierPublic)
int NumberToSpawn; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
AFortPawn* TriggeringPawn = nullptr; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FVector Position; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FVector Direction;
Stack.StepCompiledIn(&ItemDefinition);
Stack.StepCompiledIn(&PickupClass);
Stack.StepCompiledIn(&NumberToSpawn);
Stack.StepCompiledIn(&TriggeringPawn);
Stack.StepCompiledIn(&Position);
Stack.StepCompiledIn(&Direction);
SpawnGameModePickupOriginal(Context, Stack, Ret);
if (!ItemDefinition || !PickupClass)
return nullptr;
LOG_INFO(LogDev, "Spawning GameModePickup with ItemDefinition: {}", ItemDefinition->GetFullName());
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
PickupCreateData CreateData;
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(ItemDefinition, NumberToSpawn, -1, MAX_DURABILITY, ItemDefinition->GetFinalLevel(GameState->GetWorldLevel()));
CreateData.SpawnLocation = Position;
CreateData.PawnOwner = TriggeringPawn;
CreateData.Source = EFortPickupSpawnSource::GetSupplyDropValue();
CreateData.OverrideClass = PickupClass;
CreateData.bShouldFreeItemEntryWhenDeconstructed = true;
*Ret = AFortPickup::SpawnPickup(CreateData);
return *Ret;
}
AFortPickup* AFortAthenaSupplyDrop::SpawnPickupHook(UObject* Context, FFrame& Stack, AFortPickup** Ret)
{
UFortWorldItemDefinition* ItemDefinition = nullptr; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
int NumberToSpawn; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
AFortPawn* TriggeringPawn = nullptr; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FVector Position; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FVector Direction; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
Stack.StepCompiledIn(&ItemDefinition);
Stack.StepCompiledIn(&NumberToSpawn);
Stack.StepCompiledIn(&TriggeringPawn);
Stack.StepCompiledIn(&Position);
Stack.StepCompiledIn(&Direction);
SpawnPickupOriginal(Context, Stack, Ret);
if (!ItemDefinition)
return nullptr;
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
PickupCreateData CreateData;
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(ItemDefinition, NumberToSpawn, -1, MAX_DURABILITY, ItemDefinition->GetFinalLevel(GameState->GetWorldLevel()));
CreateData.SpawnLocation = Position;
CreateData.PawnOwner = TriggeringPawn;
CreateData.Source = EFortPickupSpawnSource::GetSupplyDropValue();
CreateData.bShouldFreeItemEntryWhenDeconstructed = true;
*Ret = AFortPickup::SpawnPickup(CreateData);
return *Ret;
}

View File

@@ -0,0 +1,20 @@
#pragma once
#include "BuildingGameplayActor.h"
#include "FortPickup.h"
#include "Stack.h"
class AFortAthenaSupplyDrop : public ABuildingGameplayActor
{
public:
static inline AFortPickup* (*SpawnPickupOriginal)(UObject* Context, FFrame& Stack, AFortPickup** Ret);
static inline AFortPickup* (*SpawnGameModePickupOriginal)(UObject* Context, FFrame& Stack, AFortPickup** Ret);
static inline AFortPickup* (*SpawnPickupFromItemEntryOriginal)(UObject* Context, FFrame& Stack, AFortPickup** Ret);
FVector FindGroundLocationAt(FVector InLocation);
static AFortPickup* SpawnPickupFromItemEntryHook(UObject* Context, FFrame& Stack, AFortPickup** Ret);
static AFortPickup* SpawnGameModePickupHook(UObject* Context, FFrame& Stack, AFortPickup** Ret);
static AFortPickup* SpawnPickupHook(UObject* Context, FFrame& Stack, AFortPickup** Ret);
};

View File

@@ -0,0 +1,77 @@
#include "FortAthenaVehicle.h"
UFortWeaponItemDefinition* AFortAthenaVehicle::GetVehicleWeaponForSeat(int SeatIdx)
{
static auto GetSeatWeaponComponentFn = FindObject<UFunction>("/Script/FortniteGame.FortAthenaVehicle.GetSeatWeaponComponent");
UFortWeaponItemDefinition* VehicleWeaponDefinition = nullptr;
LOG_INFO(LogDev, "SeatIndex: {}", SeatIdx);
UObject* WeaponComponent = nullptr;
if (GetSeatWeaponComponentFn)
{
struct { int SeatIndex; UObject* ReturnValue; } AFortAthenaVehicle_GetSeatWeaponComponent_Params{};
this->ProcessEvent(GetSeatWeaponComponentFn, &AFortAthenaVehicle_GetSeatWeaponComponent_Params);
WeaponComponent = AFortAthenaVehicle_GetSeatWeaponComponent_Params.ReturnValue;
if (!WeaponComponent)
return VehicleWeaponDefinition;
static auto WeaponSeatDefinitionStructSize = FindObject<UClass>("/Script/FortniteGame.WeaponSeatDefinition")->GetPropertiesSize();
static auto VehicleWeaponOffset = FindOffsetStruct("/Script/FortniteGame.WeaponSeatDefinition", "VehicleWeapon");
static auto SeatIndexOffset = FindOffsetStruct("/Script/FortniteGame.WeaponSeatDefinition", "SeatIndex");
static auto WeaponSeatDefinitionsOffset = WeaponComponent->GetOffset("WeaponSeatDefinitions");
auto& WeaponSeatDefinitions = WeaponComponent->Get<TArray<__int64>>(WeaponSeatDefinitionsOffset);
for (int i = 0; i < WeaponSeatDefinitions.Num(); i++)
{
auto WeaponSeat = WeaponSeatDefinitions.AtPtr(i, WeaponSeatDefinitionStructSize);
if (*(int*)(__int64(WeaponSeat) + SeatIndexOffset) != SeatIdx)
continue;
VehicleWeaponDefinition = *(UFortWeaponItemDefinition**)(__int64(WeaponSeat) + VehicleWeaponOffset);
break;
}
}
else
{
static auto FerretWeaponItemDefinition = FindObject<UFortWeaponItemDefinition>("/Game/Athena/Items/Weapons/Ferret_Weapon.Ferret_Weapon");
static auto OctopusWeaponItemDefinition = FindObject<UFortWeaponItemDefinition>("/Game/Athena/Items/Weapons/Vehicles/WID_Octopus_Weapon.WID_Octopus_Weapon");
static auto InCannonWeaponItemDefinition = FindObject<UFortWeaponItemDefinition>("/Game/Athena/Items/Weapons/Vehicles/ShipCannon_Weapon_InCannon.ShipCannon_Weapon_InCannon");
static auto CannonWeaponItemDefinition = FindObject<UFortWeaponItemDefinition>("/Game/Athena/Items/Weapons/Vehicles/ShipCannon_Weapon.ShipCannon_Weapon");
static auto TurretWeaponItemDefinition = FindObject<UFortWeaponItemDefinition>("/Game/Athena/Items/Traps/MountedTurret/MountedTurret_Weapon.MountedTurret_Weapon");
auto ReceivingActorName = this->GetName();
if (SeatIdx == 0)
{
if (ReceivingActorName.contains("Ferret")) // plane
{
VehicleWeaponDefinition = FerretWeaponItemDefinition;
}
}
if (ReceivingActorName.contains("Octopus")) // baller
{
VehicleWeaponDefinition = OctopusWeaponItemDefinition;
}
else if (ReceivingActorName.contains("Cannon")) // cannon
{
VehicleWeaponDefinition = SeatIdx == 1 ? InCannonWeaponItemDefinition : CannonWeaponItemDefinition;
}
else if (ReceivingActorName.contains("MountedTurret"))
{
VehicleWeaponDefinition = TurretWeaponItemDefinition;
}
}
return VehicleWeaponDefinition;
}

View File

@@ -0,0 +1,36 @@
#pragma once
#include "Actor.h"
#include "reboot.h"
#include "FortWeaponItemDefinition.h"
class AFortAthenaVehicle : public AActor// : public AFortPhysicsPawn // Super changes based on version
{
public:
class AFortPlayerPawn* GetPawnAtSeat(int SeatIdx)
{
static auto GetPawnAtSeatFn = FindObject<UFunction>("/Script/FortniteGame.FortAthenaVehicle.GetPawnAtSeat");
struct { int SeatIdx; class AFortPlayerPawn* ReturnValue; } GetPawnAtSeat_Params{SeatIdx};
this->ProcessEvent(GetPawnAtSeatFn, &GetPawnAtSeat_Params);
return GetPawnAtSeat_Params.ReturnValue;
}
int FindSeatIndex(class AFortPlayerPawn* PlayerPawn)
{
static auto FindSeatIndexFn = FindObject<UFunction>("/Script/FortniteGame.FortAthenaVehicle.FindSeatIndex");
struct { AFortPlayerPawn* PlayerPawn; int ReturnValue; } AFortAthenaVehicle_FindSeatIndex_Params{ PlayerPawn };
this->ProcessEvent(FindSeatIndexFn, &AFortAthenaVehicle_FindSeatIndex_Params);
return AFortAthenaVehicle_FindSeatIndex_Params.ReturnValue;
}
UFortWeaponItemDefinition* GetVehicleWeaponForSeat(int SeatIdx);
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortAthenaVehicle");
return Class;
}
};

View File

@@ -0,0 +1,11 @@
#include "FortAthenaVehicleSpawner.h"
#include "vehicles.h"
void AFortAthenaVehicleSpawner::SpawnVehicleHook(AFortAthenaVehicleSpawner* VehicleSpawner)
{
// literally doesnt get called!!!!
// LOG_INFO(LogDev, "omgonmg call!!!!\n\n");
// SpawnVehicleFromSpawner(VehicleSpawner);
}

Some files were not shown because too many files have changed in this diff Show More