fix a bug with restarting, clean up some stuff, fix a playlist specific bug, add hold pickup to swap, fix shadow stones and stuff spawn height, code consistency, fix bugs with dropping
This commit is contained in:
Milxnor
2023-04-30 12:15:29 -04:00
parent 891f45f469
commit 18f92ccf52
24 changed files with 401 additions and 236 deletions

View File

@@ -4,6 +4,7 @@
#include "GameplayStatics.h" #include "GameplayStatics.h"
#include "FortLootPackage.h" #include "FortLootPackage.h"
#include "FortPickup.h" #include "FortPickup.h"
#include "BuildingGameplayActor.h"
void SpawnBGAs() // hahah not "proper", there's a function that we can hook and it gets called on each spawner whenever playlist gets set, but it's fine. 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.
{ {
@@ -12,6 +13,8 @@ void SpawnBGAs() // hahah not "proper", there's a function that we can hook and
if (!BGAConsumableSpawnerClass) if (!BGAConsumableSpawnerClass)
return; return;
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
auto AllBGAConsumableSpawners = UGameplayStatics::GetAllActorsOfClass(GetWorld(), BGAConsumableSpawnerClass); auto AllBGAConsumableSpawners = UGameplayStatics::GetAllActorsOfClass(GetWorld(), BGAConsumableSpawnerClass);
LOG_INFO(LogDev, "AllBGAConsumableSpawners.Num(): {}", (int)AllBGAConsumableSpawners.Num()); LOG_INFO(LogDev, "AllBGAConsumableSpawners.Num(): {}", (int)AllBGAConsumableSpawners.Num());
@@ -20,7 +23,17 @@ void SpawnBGAs() // hahah not "proper", there's a function that we can hook and
{ {
auto BGAConsumableSpawner = AllBGAConsumableSpawners.at(i); auto BGAConsumableSpawner = AllBGAConsumableSpawners.at(i);
auto SpawnLocation = BGAConsumableSpawner->GetActorLocation(); auto SpawnLocation = BGAConsumableSpawner->GetActorLocation();
SpawnLocation.Z += 100;
if (FBuildingGameplayActorSpawnDetails::GetStruct())
{
// todo handle?
auto MapInfo = GameState->GetMapInfo();
}
else
{
// SpawnLocation.Z += 100;
}
static auto SpawnLootTierGroupOffset = BGAConsumableSpawner->GetOffset("SpawnLootTierGroup"); static auto SpawnLootTierGroupOffset = BGAConsumableSpawner->GetOffset("SpawnLootTierGroup");
auto& SpawnLootTierGroup = BGAConsumableSpawner->Get<FName>(SpawnLootTierGroupOffset); auto& SpawnLootTierGroup = BGAConsumableSpawner->Get<FName>(SpawnLootTierGroupOffset);
@@ -41,7 +54,13 @@ void SpawnBGAs() // hahah not "proper", there's a function that we can hook and
continue; continue;
} }
auto ConsumableActor = GetWorld()->SpawnActor<AActor>(StrongConsumableClass, SpawnLocation); auto ConsumableActor = GetWorld()->SpawnActor<ABuildingGameplayActor>(StrongConsumableClass, SpawnLocation);
if (ConsumableActor)
{
// BeginDeferredActorSpawnFromClass ??
// ConsumableActor->InitializeBuildingActor(nullptr, nullptr, true); // idk UFortKismetLibrary::SpawnBuildingGameplayActor does this
}
} }
} }

View File

@@ -48,22 +48,8 @@ public:
return this->GetPtr<TArray<FGameplayEffectApplicationInfoHard>>(GrantedGameplayEffectsOffset); return this->GetPtr<TArray<FGameplayEffectApplicationInfoHard>>(GrantedGameplayEffectsOffset);
} }
void GiveToAbilitySystem(UAbilitySystemComponent* AbilitySystemComponent, UObject* SourceObject = nullptr) void ApplyGrantedGameplayAffectsToAbilitySystem(UAbilitySystemComponent* AbilitySystemComponent)
{ {
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);
}
if (!FGameplayEffectApplicationInfoHard::GetStruct()) if (!FGameplayEffectApplicationInfoHard::GetStruct())
return; return;
@@ -86,6 +72,25 @@ public:
} }
} }
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 UClass* StaticClass()
{ {
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortAbilitySet"); static auto Class = FindObject<UClass>("/Script/FortniteGame.FortAbilitySet");

View File

@@ -1,12 +1,93 @@
#pragma once #pragma once
#include <random>
#include "Actor.h" #include "Actor.h"
#include "GameplayAbilityTypes.h" #include "GameplayAbilityTypes.h"
#include "DataTableFunctionLibrary.h"
static inline float CalcuateCurveMinAndMax(FScalableFloat* Min, FScalableFloat* Max) // 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 * 100, MaxSpawnPercent * 100 + 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>("/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 class AFortAthenaMapInfo : public AActor
{ {
public: public:
TArray<FVehicleClassDetails>& GetVehicleClassDetails()
{
static auto VehicleClassDetailsOffset = GetOffset("VehicleClassDetails");
return Get<TArray<FVehicleClassDetails>>(VehicleClassDetailsOffset);
}
UClass*& GetAmmoBoxClass() UClass*& GetAmmoBoxClass()
{ {
static auto AmmoBoxClassOffset = GetOffset("AmmoBoxClass"); static auto AmmoBoxClassOffset = GetOffset("AmmoBoxClass");
@@ -42,4 +123,10 @@ public:
static auto TreasureChestMaxSpawnPercentOffset = GetOffset("TreasureChestMaxSpawnPercent"); static auto TreasureChestMaxSpawnPercentOffset = GetOffset("TreasureChestMaxSpawnPercent");
return GetPtr<FScalableFloat>(TreasureChestMaxSpawnPercentOffset); return GetPtr<FScalableFloat>(TreasureChestMaxSpawnPercentOffset);
} }
TArray<FBuildingGameplayActorSpawnDetails>& GetBuildingGameplayActorSpawnDetails()
{
static auto BuildingGameplayActorSpawnDetailsOffset = GetOffset("BuildingGameplayActorSpawnDetails");
return Get<TArray<FBuildingGameplayActorSpawnDetails>>(BuildingGameplayActorSpawnDetailsOffset);
}
}; };

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);
}

View File

@@ -0,0 +1,9 @@
#pragma once
#include "Actor.h"
class AFortAthenaVehicleSpawner : public AActor
{
public:
static void SpawnVehicleHook(AFortAthenaVehicleSpawner* VehicleSpawner);
};

View File

@@ -195,9 +195,9 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
static int LastNum2 = 1; static int LastNum2 = 1;
if (Globals::AmountOfListens != LastNum2) if (AmountOfRestarts != LastNum2)
{ {
LastNum2 = Globals::AmountOfListens; LastNum2 = AmountOfRestarts;
LOG_INFO(LogDev, "Presetup!"); LOG_INFO(LogDev, "Presetup!");
@@ -432,9 +432,9 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
static int LastNum6 = 1; static int LastNum6 = 1;
if (Globals::AmountOfListens != LastNum6) if (AmountOfRestarts != LastNum6)
{ {
LastNum6 = Globals::AmountOfListens; LastNum6 = AmountOfRestarts;
if (Globals::bGoingToPlayEvent && DoesEventRequireLoading()) if (Globals::bGoingToPlayEvent && DoesEventRequireLoading())
{ {
@@ -448,9 +448,9 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
static int LastNum5 = 1; static int LastNum5 = 1;
if (Globals::AmountOfListens != LastNum5 && LastNum6 == Globals::AmountOfListens) // Make sure we loaded the event. if (AmountOfRestarts != LastNum5 && LastNum6 == AmountOfRestarts) // Make sure we loaded the event.
{ {
LastNum5 = Globals::AmountOfListens; LastNum5 = AmountOfRestarts;
if (Globals::bGoingToPlayEvent) if (Globals::bGoingToPlayEvent)
{ {
@@ -475,13 +475,6 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
return false; return false;
} }
static int LastNum9 = 1;
if (Globals::AmountOfListens != LastNum9)
{
LastNum9 = Globals::AmountOfListens;
}
auto MapInfo = GameState->GetMapInfo(); auto MapInfo = GameState->GetMapInfo();
if (!MapInfo && Engine_Version >= 421) if (!MapInfo && Engine_Version >= 421)
@@ -489,9 +482,9 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
static int LastNum = 1; static int LastNum = 1;
if (Globals::AmountOfListens != LastNum) if (AmountOfRestarts != LastNum)
{ {
LastNum = Globals::AmountOfListens; LastNum = AmountOfRestarts;
float Duration = 10000.f; float Duration = 10000.f;
float EarlyDuration = Duration; float EarlyDuration = Duration;
@@ -552,9 +545,10 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
static int LastNum3 = 1; static int LastNum3 = 1;
if (Globals::AmountOfListens != LastNum3) if (AmountOfRestarts != LastNum3)
{ {
LastNum3 = ++Globals::AmountOfListens; LastNum3 = AmountOfRestarts;
++Globals::AmountOfListens;
LOG_INFO(LogNet, "Attempting to listen!"); LOG_INFO(LogNet, "Attempting to listen!");
@@ -580,8 +574,6 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
} }
} }
LoopMutators([&](AFortAthenaMutator* Mutator) { LOG_INFO(LogGame, "Mutator {}", Mutator->GetPathName()); });
Globals::bStartedListening = true; Globals::bStartedListening = true;
} }
@@ -613,17 +605,10 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
{ {
// We are assuming it successfully became warmup. // We are assuming it successfully became warmup.
static auto mutatorClass = FindObject<UClass>("/Script/FortniteGame.FortAthenaMutator");
auto AllMutators = UGameplayStatics::GetAllActorsOfClass(GetWorld(), mutatorClass);
std::vector<std::pair<AFortAthenaMutator*, UFunction*>> FunctionsToCall; std::vector<std::pair<AFortAthenaMutator*, UFunction*>> FunctionsToCall;
for (int i = 0; i < AllMutators.Num(); i++) LoopMutators([&](AFortAthenaMutator* Mutator) { LOG_INFO(LogGame, "Mutator {}", Mutator->GetPathName()); });
{ LoopMutators([&](AFortAthenaMutator* Mutator) { FunctionsToCall.push_back(std::make_pair(Mutator, Mutator->FindFunction("OnGamePhaseStepChanged"))); });
auto Mutator = (AFortAthenaMutator*)AllMutators.at(i);
FunctionsToCall.push_back(std::make_pair(Mutator, Mutator->FindFunction("OnGamePhaseStepChanged")));
}
static int LastNum1 = 3125; static int LastNum1 = 3125;
@@ -650,9 +635,6 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, a); FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, a);
FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, ConstructOnGamePhaseStepChangedParams(EAthenaGamePhaseStep::Setup)); FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, ConstructOnGamePhaseStepChangedParams(EAthenaGamePhaseStep::Setup));
FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, ConstructOnGamePhaseStepChangedParams(EAthenaGamePhaseStep::Warmup)); FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, ConstructOnGamePhaseStepChangedParams(EAthenaGamePhaseStep::Warmup));
// FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, &StormFormingGamePhaseStep);
// FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, &StormHoldingGamePhaseStep);
// FunctionToCallPair.first->ProcessEvent(FunctionToCallPair.second, &StormShrinkingGamePhaseStep);
} }
} }
} }
@@ -1008,34 +990,14 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
LOG_INFO(LogDev, "Old ID: {}", PlayerStateAthena->GetWorldPlayerId()); LOG_INFO(LogDev, "Old ID: {}", PlayerStateAthena->GetWorldPlayerId());
LOG_INFO(LogDev, "PlayerID: {}", PlayerStateAthena->GetPlayerID()); LOG_INFO(LogDev, "PlayerID: {}", PlayerStateAthena->GetPlayerID());
// if (PlayerStateAthena->GetWorldPlayerId() == -1) PlayerStateAthena->GetWorldPlayerId() = PlayerStateAthena->GetPlayerID();
auto PlayerAbilitySet = GetPlayerAbilitySet();
auto AbilitySystemComponent = PlayerStateAthena->GetAbilitySystemComponent();
if (PlayerAbilitySet)
{ {
static int CurrentPlayerId = 1; PlayerAbilitySet->GiveToAbilitySystem(AbilitySystemComponent);
// static auto PlayerIdOffset = PlayerStateAthena->GetOffset("PlayerId"); // Unable to find tf
PlayerStateAthena->GetWorldPlayerId() = PlayerStateAthena->GetPlayerID(); // ++CurrentPlayerId; // PlayerStateAthena->Get<int>(PlayerIdOffset); //
}
{
static auto GameplayAbilitySet = (UFortAbilitySet*)(Fortnite_Version >= 8.30 ? // LoadObject<UObject>(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_AthenaPlayer.GAS_AthenaPlayer") ?
LoadObject(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_AthenaPlayer.GAS_AthenaPlayer", UFortAbilitySet::StaticClass()) :
LoadObject(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_DefaultPlayer.GAS_DefaultPlayer", UFortAbilitySet::StaticClass()));
LOG_INFO(LogDev, "GameplayAbilitySet {}", __int64(GameplayAbilitySet));
auto AbilitySystemComponent = PlayerStateAthena->GetAbilitySystemComponent();
if (GameplayAbilitySet)
{
LOG_INFO(LogDev, "GameplayAbilitySet Name {}", GameplayAbilitySet->GetName());
GameplayAbilitySet->GiveToAbilitySystem(AbilitySystemComponent);
}
GET_PLAYLIST(GameState);
if (CurrentPlaylist)
{
// CurrentPlaylist->ApplyModifiersToActor(PlayerStateAthena); // scuffed we need to do as pawn spawns
}
} }
struct FUniqueNetIdReplExperimental struct FUniqueNetIdReplExperimental

View File

@@ -7,6 +7,7 @@
#include "BuildingSMActor.h" #include "BuildingSMActor.h"
#include "FortSafeZoneIndicator.h" #include "FortSafeZoneIndicator.h"
#include "GameplayStatics.h" #include "GameplayStatics.h"
#include "FortAbilitySet.h"
#include "FortItemDefinition.h" #include "FortItemDefinition.h"
struct FAircraftFlightInfo struct FAircraftFlightInfo
@@ -77,6 +78,17 @@ static void SetFoundationTransform(AActor* BuildingFoundation, const FTransform&
} }
} }
static inline UFortAbilitySet* GetPlayerAbilitySet()
{
// There are some variables that contain this but it changes through versions soo..
static auto GameplayAbilitySet = (UFortAbilitySet*)(Fortnite_Version >= 8.30
? LoadObject(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_AthenaPlayer.GAS_AthenaPlayer", UFortAbilitySet::StaticClass())
: LoadObject(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_DefaultPlayer.GAS_DefaultPlayer", UFortAbilitySet::StaticClass()));
return GameplayAbilitySet;
}
static void ShowFoundation(AActor* BuildingFoundation, bool bShow = true) static void ShowFoundation(AActor* BuildingFoundation, bool bShow = true)
{ {
if (!BuildingFoundation) if (!BuildingFoundation)

View File

@@ -119,24 +119,7 @@ std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AFortInventory::AddI
if (NewItemInstance) if (NewItemInstance)
{ {
auto OldItemGuid = NewItemInstance->GetItemEntry()->GetItemGuid(); NewItemInstance->GetItemEntry()->CopyFromAnotherItemEntry(ItemEntry);
if (false)
{
CopyStruct(NewItemInstance->GetItemEntry(), ItemEntry, FFortItemEntry::GetStructSize(), FFortItemEntry::GetStruct());
}
else
{
NewItemInstance->GetItemEntry()->GetItemDefinition() = ItemEntry->GetItemDefinition();
NewItemInstance->GetItemEntry()->GetCount() = ItemEntry->GetCount();
NewItemInstance->GetItemEntry()->GetLoadedAmmo() = ItemEntry->GetLoadedAmmo();
}
NewItemInstance->GetItemEntry()->GetItemGuid() = OldItemGuid;
NewItemInstance->GetItemEntry()->MostRecentArrayReplicationKey = -1;
NewItemInstance->GetItemEntry()->ReplicationID = -1;
NewItemInstance->GetItemEntry()->ReplicationKey = -1;
if (OverrideCount != -1) if (OverrideCount != -1)
NewItemInstance->GetItemEntry()->GetCount() = OverrideCount; NewItemInstance->GetItemEntry()->GetCount() = OverrideCount;
@@ -414,6 +397,44 @@ bool AFortInventory::RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int
return true; return true;
} }
void AFortInventory::SwapItem(const FGuid& ItemGuid, FFortItemEntry* NewItemEntry, int OverrideNewCount, std::pair<FFortItemEntry*, FFortItemEntry*>* outEntries)
{
auto NewCount = OverrideNewCount == -1 ? NewItemEntry->GetCount() : OverrideNewCount;
auto ItemInstance = FindItemInstance(ItemGuid);
if (!ItemInstance)
return;
/* RemoveItem(ItemGuid, nullptr, ItemInstance->GetItemEntry()->GetCount(), true);
AddItem(NewItemEntry, nullptr, false, OverrideNewCount);
return; */
// IDK WHY THIS DOESNT WORK
static auto FortItemEntrySize = FFortItemEntry::GetStructSize();
auto& ReplicatedEntries = GetItemList().GetReplicatedEntries();
for (int i = 0; i < ReplicatedEntries.Num(); i++)
{
auto& ReplicatedEntry = ReplicatedEntries.At(i, FortItemEntrySize);
if (ReplicatedEntry.GetItemGuid() == ItemGuid)
{
ReplicatedEntry.CopyFromAnotherItemEntry(NewItemEntry);
ItemInstance->GetItemEntry()->CopyFromAnotherItemEntry(NewItemEntry);
ReplicatedEntry.GetCount() = NewCount;
ItemInstance->GetItemEntry()->GetCount() = NewCount;
if (outEntries)
*outEntries = std::make_pair(ItemInstance->GetItemEntry(), &ReplicatedEntry);
}
}
}
void AFortInventory::ModifyCount(UFortItem* ItemInstance, int New, bool bRemove, std::pair<FFortItemEntry*, FFortItemEntry*>* outEntries, bool bUpdate, bool bShowItemToast) void AFortInventory::ModifyCount(UFortItem* ItemInstance, int New, bool bRemove, std::pair<FFortItemEntry*, FFortItemEntry*>* outEntries, bool bUpdate, bool bShowItemToast)
{ {
auto ReplicatedEntry = FindReplicatedEntry(ItemInstance->GetItemEntry()->GetItemGuid()); auto ReplicatedEntry = FindReplicatedEntry(ItemInstance->GetItemEntry()->GetItemGuid());
@@ -529,8 +550,7 @@ UFortItem* AFortInventory::FindItemInstance(const FGuid& Guid)
FFortItemEntry* AFortInventory::FindReplicatedEntry(const FGuid& Guid) FFortItemEntry* AFortInventory::FindReplicatedEntry(const FGuid& Guid)
{ {
static auto FortItemEntryStruct = FindObject<UStruct>(L"/Script/FortniteGame.FortItemEntry"); static auto FortItemEntrySize = FFortItemEntry::GetStructSize();
static auto FortItemEntrySize = FortItemEntryStruct->GetPropertiesSize();
auto& ReplicatedEntries = GetItemList().GetReplicatedEntries(); auto& ReplicatedEntries = GetItemList().GetReplicatedEntries();

View File

@@ -100,6 +100,7 @@ public:
std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AddItem(FFortItemEntry* ItemEntry, bool* bShouldUpdate, bool bShowItemToast = false, int OverrideCount = -1); std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AddItem(FFortItemEntry* ItemEntry, bool* bShouldUpdate, bool bShowItemToast = false, int OverrideCount = -1);
std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AddItem(UFortItemDefinition* ItemDefinition, bool* bShouldUpdate, int Count = 1, int LoadedAmmo = -1, bool bShowItemToast = false); std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AddItem(UFortItemDefinition* ItemDefinition, bool* bShouldUpdate, int Count = 1, int LoadedAmmo = -1, bool bShowItemToast = false);
bool RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int Count, bool bForceRemoval = false); bool RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int Count, bool bForceRemoval = false);
void SwapItem(const FGuid& ItemGuid, FFortItemEntry* NewItemEntry, int OverrideNewCount = -1, std::pair<FFortItemEntry*, FFortItemEntry*>* outEntries = nullptr);
void ModifyCount(UFortItem* ItemInstance, int New, bool bRemove = false, std::pair<FFortItemEntry*, FFortItemEntry*>* outEntries = nullptr, bool bUpdate = true, bool bShowItemToast = false); void ModifyCount(UFortItem* ItemInstance, int New, bool bRemove = false, std::pair<FFortItemEntry*, FFortItemEntry*>* outEntries = nullptr, bool bUpdate = true, bool bShowItemToast = false);
UFortItem* GetPickaxeInstance(); UFortItem* GetPickaxeInstance();

View File

@@ -83,6 +83,12 @@ struct FFortItemEntry : FFastArraySerializerItem
return *(int*)(__int64(this) + CountOffset); return *(int*)(__int64(this) + CountOffset);
} }
int& GetLevel()
{
static auto LevelOffset = FindOffsetStruct("/Script/FortniteGame.FortItemEntry", "Level");
return *(int*)(__int64(this) + LevelOffset);
}
TArray<FFortItemEntryStateValue>& GetStateValues() TArray<FFortItemEntryStateValue>& GetStateValues()
{ {
static auto StateValuesOffset = FindOffsetStruct("/Script/FortniteGame.FortItemEntry", "StateValues"); static auto StateValuesOffset = FindOffsetStruct("/Script/FortniteGame.FortItemEntry", "StateValues");
@@ -97,7 +103,7 @@ struct FFortItemEntry : FFastArraySerializerItem
void CopyFromAnotherItemEntry(FFortItemEntry* OtherItemEntry, bool bCopyGuid = false) void CopyFromAnotherItemEntry(FFortItemEntry* OtherItemEntry, bool bCopyGuid = false)
{ {
auto OldGuid = this->GetItemGuid(); FGuid OldGuid = this->GetItemGuid();
if (false) if (false)
{ {
@@ -109,10 +115,17 @@ struct FFortItemEntry : FFastArraySerializerItem
this->GetCount() = OtherItemEntry->GetCount(); this->GetCount() = OtherItemEntry->GetCount();
this->GetLoadedAmmo() = OtherItemEntry->GetLoadedAmmo(); this->GetLoadedAmmo() = OtherItemEntry->GetLoadedAmmo();
this->GetItemGuid() = OtherItemEntry->GetItemGuid(); this->GetItemGuid() = OtherItemEntry->GetItemGuid();
this->GetLevel() = OtherItemEntry->GetLevel();
} }
if (!bCopyGuid) if (!bCopyGuid)
this->GetItemGuid() = OldGuid; this->GetItemGuid() = OldGuid;
// should we do this?
this->MostRecentArrayReplicationKey = -1;
this->ReplicationID = -1;
this->ReplicationKey = -1;
} }
static UStruct* GetStruct() static UStruct* GetStruct()

View File

@@ -190,7 +190,7 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recurs
{ {
auto& Tag = GameplayTagContainer->GameplayTags.At(i); auto& Tag = GameplayTagContainer->GameplayTags.At(i);
for (auto Value : PlaylistOverrideLootTableData) for (auto& Value : PlaylistOverrideLootTableData)
{ {
auto CurrentOverrideTag = Value.First; auto CurrentOverrideTag = Value.First;
@@ -504,7 +504,7 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recurs
auto ChosenLootPackageName = ChosenRowLootTierData->GetLootPackage().ToString(); auto ChosenLootPackageName = ChosenRowLootTierData->GetLootPackage().ToString();
if (ChosenLootPackageName.contains(".Empty")) if (ChosenLootPackageName.contains(".Empty")) // I don't think?
{ {
return PickLootDrops(TierGroupName, bPrint); return PickLootDrops(TierGroupName, bPrint);
// return LootDrops; // return LootDrops;
@@ -581,6 +581,11 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recurs
{ {
lootPackageCallsTotalWeight += CurrentLP->GetWeight(); lootPackageCallsTotalWeight += CurrentLP->GetWeight();
lootPackageCalls.push_back(CurrentLP); lootPackageCalls.push_back(CurrentLP);
if (bPrint)
{
LOG_INFO(LogDev, "Adding LootPackage: {}", CurrentLP->GetAnnotation().ToString());
}
} }
} }
} }

View File

@@ -45,6 +45,12 @@ public:
static auto CountOffset = FindOffsetStruct("/Script/FortniteGame.FortLootPackageData", "Count"); static auto CountOffset = FindOffsetStruct("/Script/FortniteGame.FortLootPackageData", "Count");
return *(int*)(__int64(this) + CountOffset); return *(int*)(__int64(this) + CountOffset);
} }
FString& GetAnnotation()
{
static auto AnnotationOffset = FindOffsetStruct("/Script/FortniteGame.FortLootPackageData", "Annotation");
return *(FString*)(__int64(this) + AnnotationOffset);
}
}; };
struct FFortLootTierData struct FFortLootTierData

View File

@@ -9,22 +9,21 @@ AFortWeapon* AFortPawn::EquipWeaponDefinition(UFortWeaponItemDefinition* WeaponD
FGuid TrackerGuid{}; FGuid TrackerGuid{};
struct { UObject* Def; FGuid Guid; AFortWeapon* Wep; } params{ WeaponData, ItemEntryGuid };
struct { UObject* Def; FGuid Guid; FGuid TrackerGuid; AFortWeapon* Wep; } S16_params{ WeaponData, ItemEntryGuid, TrackerGuid };
struct { UObject* Def; FGuid Guid; FGuid TrackerGuid; bool bDisableEquipAnimation; AFortWeapon* Wep; } S17_params{ WeaponData, ItemEntryGuid, TrackerGuid, false };
if (Fortnite_Version < 16) if (Fortnite_Version < 16)
{ {
struct { UObject* Def; FGuid Guid; AFortWeapon* Wep; } params{ WeaponData, ItemEntryGuid };
this->ProcessEvent(EquipWeaponDefinitionFn, &params); this->ProcessEvent(EquipWeaponDefinitionFn, &params);
return params.Wep; return params.Wep;
} }
else if (std::floor(Fortnite_Version) == 16) else if (std::floor(Fortnite_Version) == 16)
{ {
struct { UObject* Def; FGuid Guid; FGuid TrackerGuid; AFortWeapon* Wep; } S16_params{ WeaponData, ItemEntryGuid, TrackerGuid };
this->ProcessEvent(EquipWeaponDefinitionFn, &S16_params); this->ProcessEvent(EquipWeaponDefinitionFn, &S16_params);
return S16_params.Wep; return S16_params.Wep;
} }
else else
{ {
struct { UObject* Def; FGuid Guid; FGuid TrackerGuid; bool bDisableEquipAnimation; AFortWeapon* Wep; } S17_params{ WeaponData, ItemEntryGuid, TrackerGuid, false };
this->ProcessEvent(EquipWeaponDefinitionFn, &S17_params); this->ProcessEvent(EquipWeaponDefinitionFn, &S17_params);
return S17_params.Wep; return S17_params.Wep;
} }

View File

@@ -189,6 +189,7 @@ char AFortPickup::CompletePickupAnimationHook(AFortPickup* Pickup)
FGuid NewSwappedItem = FGuid(-1, -1, -1, -1); FGuid NewSwappedItem = FGuid(-1, -1, -1, -1);
bool bForceDontAddItem = false;
bool bForceOverflow = false; bool bForceOverflow = false;
while (cpyCount > 0) while (cpyCount > 0)
@@ -214,9 +215,12 @@ char AFortPickup::CompletePickupAnimationHook(AFortPickup* Pickup)
bIsInventoryFull = (PrimarySlotsFilled /* - 6 */) >= 5; bIsInventoryFull = (PrimarySlotsFilled /* - 6 */) >= 5;
if (bIsInventoryFull) // probs shouldnt do in loop but alr if (bIsInventoryFull || (PlayerController->HasTryPickupSwap() ? PlayerController->ShouldTryPickupSwap() : false)) // probs shouldnt do in loop but alr
{ {
if (ItemInstanceToSwap && ItemDefinitionToSwap->CanBeDropped() && !bHasSwapped) // swap if (PlayerController->HasTryPickupSwap())
PlayerController->ShouldTryPickupSwap() = false;
if (ItemInstanceToSwap && ItemDefinitionToSwap->CanBeDropped() && !bHasSwapped && ItemDefGoingInPrimary) // swap
{ {
auto SwappedPickup = SpawnPickup(ItemEntryToSwap, PawnLoc, auto SwappedPickup = SpawnPickup(ItemEntryToSwap, PawnLoc,
EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset, Pawn); EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset, Pawn);
@@ -228,13 +232,27 @@ char AFortPickup::CompletePickupAnimationHook(AFortPickup* Pickup)
bWasHoldingSameItemWhenSwap = CurrentWeapon->GetItemEntryGuid() == ItemInstanceToSwap->GetItemEntry()->GetItemGuid(); bWasHoldingSameItemWhenSwap = CurrentWeapon->GetItemEntryGuid() == ItemInstanceToSwap->GetItemEntry()->GetItemGuid();
} }
// THIS IS NOT PROPER! We should use the commented code but there are some bugs idk why.
WorldInventory->RemoveItem(CurrentItemGuid, nullptr, ItemEntryToSwap->GetCount(), true); WorldInventory->RemoveItem(CurrentItemGuid, nullptr, ItemEntryToSwap->GetCount(), true);
/*
auto NewItemCount = cpyCount > PickupItemDefinition->GetMaxStackSize() ? PickupItemDefinition->GetMaxStackSize() : cpyCount;
std::pair<FFortItemEntry*, FFortItemEntry*> Pairs;
WorldInventory->SwapItem(CurrentItemGuid, PickupEntry, cpyCount, &Pairs);
PairsToMarkDirty.push_back(Pairs);
cpyCount -= NewItemCount;
*/
bHasSwapped = true; bHasSwapped = true;
if constexpr (bTestPrinting) if constexpr (bTestPrinting)
LOG_INFO(LogDev, "[{}] Swapping: {}", i, ItemDefinitionToSwap->GetFullName()); LOG_INFO(LogDev, "[{}] Swapping: {}", i, ItemDefinitionToSwap->GetFullName());
// bForceDontAddItem = true;
continue; // ??? continue; // ???
} }
} }
@@ -287,7 +305,7 @@ char AFortPickup::CompletePickupAnimationHook(AFortPickup* Pickup)
break; break;
} }
if (cpyCount > 0 && !bIsInventoryFull) if (cpyCount > 0 && !bIsInventoryFull && !bForceDontAddItem)
{ {
if constexpr (bTestPrinting) if constexpr (bTestPrinting)
LOG_INFO(LogDev, "Attempting to add to inventory."); LOG_INFO(LogDev, "Attempting to add to inventory.");

View File

@@ -885,7 +885,7 @@ void AFortPlayerController::DropSpecificItemHook(UObject* Context, FFrame& Stack
void AFortPlayerController::ServerAttemptInventoryDropHook(AFortPlayerController* PlayerController, FGuid ItemGuid, int Count) void AFortPlayerController::ServerAttemptInventoryDropHook(AFortPlayerController* PlayerController, FGuid ItemGuid, int Count)
{ {
LOG_INFO(LogDev, "ServerAttemptInventoryDropHook!"); LOG_INFO(LogDev, "ServerAttemptInventoryDropHook Dropping: {}", Count);
auto Pawn = PlayerController->GetMyFortPawn(); auto Pawn = PlayerController->GetMyFortPawn();
@@ -895,7 +895,7 @@ void AFortPlayerController::ServerAttemptInventoryDropHook(AFortPlayerController
auto WorldInventory = PlayerController->GetWorldInventory(); auto WorldInventory = PlayerController->GetWorldInventory();
auto ReplicatedEntry = WorldInventory->FindReplicatedEntry(ItemGuid); auto ReplicatedEntry = WorldInventory->FindReplicatedEntry(ItemGuid);
if (!ReplicatedEntry) if (!ReplicatedEntry || ReplicatedEntry->GetCount() < Count)
return; return;
auto ItemDefinition = Cast<UFortWorldItemDefinition>(ReplicatedEntry->GetItemDefinition()); auto ItemDefinition = Cast<UFortWorldItemDefinition>(ReplicatedEntry->GetItemDefinition());
@@ -908,7 +908,7 @@ void AFortPlayerController::ServerAttemptInventoryDropHook(AFortPlayerController
if (!ItemDefinition->ShouldIgnoreRespawningOnDrop() && (DropBehaviorOffset != -1 ? ItemDefinition->GetDropBehavior() != EWorldItemDropBehavior::DestroyOnDrop : true)) if (!ItemDefinition->ShouldIgnoreRespawningOnDrop() && (DropBehaviorOffset != -1 ? ItemDefinition->GetDropBehavior() != EWorldItemDropBehavior::DestroyOnDrop : true))
{ {
auto Pickup = AFortPickup::SpawnPickup(ReplicatedEntry, Pawn->GetActorLocation(), auto Pickup = AFortPickup::SpawnPickup(ReplicatedEntry, Pawn->GetActorLocation(),
EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset, Pawn); EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset, Pawn, nullptr, true, Count);
if (!Pickup) if (!Pickup)
return; return;

View File

@@ -87,6 +87,18 @@ public:
return CosmeticLoadout; return CosmeticLoadout;
} }
bool& ShouldTryPickupSwap()
{
static auto bTryPickupSwapOffset = GetOffset("bTryPickupSwap");
return Get<bool>(bTryPickupSwapOffset);
}
bool HasTryPickupSwap()
{
static auto bTryPickupSwapOffset = GetOffset("bTryPickupSwap");
return bTryPickupSwapOffset != -1;
}
bool DoesBuildFree(); bool DoesBuildFree();
void DropAllItems(const std::vector<UFortItemDefinition*>& IgnoreItemDefs, bool bIgnoreSecondaryQuickbar = false, bool bRemoveIfNotDroppable = false); void DropAllItems(const std::vector<UFortItemDefinition*>& IgnoreItemDefs, bool bIgnoreSecondaryQuickbar = false, bool bRemoveIfNotDroppable = false);
void ApplyCosmeticLoadout(); void ApplyCosmeticLoadout();

View File

@@ -13,6 +13,59 @@ FFortAthenaLoadout* AFortPlayerPawn::GetCosmeticLoadout()
return GetPtr<FFortAthenaLoadout>(CosmeticLoadoutOffset); return GetPtr<FFortAthenaLoadout>(CosmeticLoadoutOffset);
} }
void AFortPlayerPawn::ServerHandlePickupWithRequestedSwapHook(UObject* Context, FFrame* Stack, void* Ret)
{
auto Pawn = (AFortPlayerPawn*)Context;
auto Controller = Cast<AFortPlayerController>(Pawn->GetController());
if (!Controller)
return ServerHandlePickupWithRequestedSwapOriginal(Context, Stack, Ret);
auto Params = Stack->Locals;
static auto PickupOffset = FindOffsetStruct("/Script/FortniteGame.FortPlayerPawn.ServerHandlePickupWithRequestedSwap", "Pickup");
static auto SwapOffset = FindOffsetStruct("/Script/FortniteGame.FortPlayerPawn.ServerHandlePickupWithRequestedSwap", "Swap");
auto Pickup = *(AFortPickup**)(__int64(Params) + PickupOffset);
auto& Swap = *(FGuid*)(__int64(Params) + SwapOffset);
// LOG_INFO(LogDev, "Pickup: {}", Pickup->IsValidLowLevel() ? Pickup->GetFullName() : "BadRead");
if (!Pickup)
return ServerHandlePickupWithRequestedSwapOriginal(Context, Stack, Ret);
static auto bPickedUpOffset = Pickup->GetOffset("bPickedUp");
if (Pickup->Get<bool>(bPickedUpOffset))
{
LOG_INFO(LogDev, "Trying to pickup picked up weapon (Swap)?");
return ServerHandlePickupWithRequestedSwapOriginal(Context, Stack, Ret);
}
static auto IncomingPickupsOffset = Pawn->GetOffset("IncomingPickups");
Pawn->Get<TArray<AFortPickup*>>(IncomingPickupsOffset).Add(Pickup);
auto PickupLocationData = Pickup->GetPickupLocationData();
PickupLocationData->GetPickupTarget() = Pawn;
PickupLocationData->GetFlyTime() = 0.40f;
PickupLocationData->GetItemOwner() = Pawn;
// PickupLocationData->GetStartDirection() = InStartDirection;
PickupLocationData->GetPickupGuid() = Swap;
Controller->ShouldTryPickupSwap() = true;
static auto OnRep_PickupLocationDataFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPickup.OnRep_PickupLocationData");
Pickup->ProcessEvent(OnRep_PickupLocationDataFn);
Pickup->Get<bool>(bPickedUpOffset) = true;
static auto OnRep_bPickedUpFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPickup.OnRep_bPickedUp");
Pickup->ProcessEvent(OnRep_bPickedUpFn);
return ServerHandlePickupWithRequestedSwapOriginal(Context, Stack, Ret);
}
void AFortPlayerPawn::ServerChoosePart(EFortCustomPartType Part, UObject* ChosenCharacterPart) void AFortPlayerPawn::ServerChoosePart(EFortCustomPartType Part, UObject* ChosenCharacterPart)
{ {
static auto fn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerPawn.ServerChoosePart"); static auto fn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerPawn.ServerChoosePart");

View File

@@ -33,6 +33,7 @@ class AFortPlayerPawn : public AFortPawn
public: public:
static inline AActor* (*ServerOnExitVehicleOriginal)(AFortPlayerPawn* Pawn, ETryExitVehicleBehavior ExitForceBehavior); // actually returns AFortAthenaVehicle static inline AActor* (*ServerOnExitVehicleOriginal)(AFortPlayerPawn* Pawn, ETryExitVehicleBehavior ExitForceBehavior); // actually returns AFortAthenaVehicle
static inline void (*StartGhostModeExitOriginal)(UObject* Context, FFrame* Stack, void* Ret); static inline void (*StartGhostModeExitOriginal)(UObject* Context, FFrame* Stack, void* Ret);
static inline void (*ServerHandlePickupWithRequestedSwapOriginal)(UObject* Context, FFrame* Stack, void* Ret);
struct FFortAthenaLoadout* GetCosmeticLoadout(); struct FFortAthenaLoadout* GetCosmeticLoadout();
void ServerChoosePart(EFortCustomPartType Part, class UObject* ChosenCharacterPart); void ServerChoosePart(EFortCustomPartType Part, class UObject* ChosenCharacterPart);
@@ -43,6 +44,7 @@ public:
UFortWeaponItemDefinition* GetVehicleWeaponDefinition(AFortAthenaVehicle* Vehicle); UFortWeaponItemDefinition* GetVehicleWeaponDefinition(AFortAthenaVehicle* Vehicle);
void UnEquipVehicleWeaponDefinition(UFortWeaponItemDefinition* VehicleWeaponDefinition); void UnEquipVehicleWeaponDefinition(UFortWeaponItemDefinition* VehicleWeaponDefinition);
static void ServerHandlePickupWithRequestedSwapHook(UObject* Context, FFrame* Stack, void* Ret); // we could native hook this but idk
static void StartGhostModeExitHook(UObject* Context, FFrame* Stack, void* Ret); // we could native hook this but eh static void StartGhostModeExitHook(UObject* Context, FFrame* Stack, void* Ret); // we could native hook this but eh
static AActor* ServerOnExitVehicleHook(AFortPlayerPawn* Pawn, ETryExitVehicleBehavior ExitForceBehavior); // actually returns AFortAthenaVehicle static AActor* ServerOnExitVehicleHook(AFortPlayerPawn* Pawn, ETryExitVehicleBehavior ExitForceBehavior); // actually returns AFortAthenaVehicle
static void ServerSendZiplineStateHook(AFortPlayerPawn* Pawn, FZiplinePawnState InZiplineState); static void ServerSendZiplineStateHook(AFortPlayerPawn* Pawn, FZiplinePawnState InZiplineState);

View File

@@ -72,11 +72,20 @@ APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AControll
if (!PlayerStateAthena) if (!PlayerStateAthena)
return nullptr; return nullptr;
auto ASC = PlayerStateAthena->GetAbilitySystemComponent();
GET_PLAYLIST(GameState); GET_PLAYLIST(GameState);
if (CurrentPlaylist) if (CurrentPlaylist) // Apply gameplay effects from playlist // We need to move this!
{ {
CurrentPlaylist->ApplyModifiersToActor(PlayerStateAthena); // We need to move this! CurrentPlaylist->ApplyModifiersToActor(PlayerStateAthena);
}
auto PlayerAbilitySet = GetPlayerAbilitySet(); // Apply default gameplay effects // We need to move maybe?
if (PlayerAbilitySet && ASC)
{
PlayerAbilitySet->ApplyGrantedGameplayAffectsToAbilitySystem(ASC);
} }
if (NewPlayerAsAthena) if (NewPlayerAsAthena)
@@ -91,10 +100,8 @@ APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AControll
// TODO Check Playlist->bRequirePickaxeInStartingInventory // TODO Check Playlist->bRequirePickaxeInStartingInventory
auto CosmeticLoadout = NewPlayerAsAthena->GetCosmeticLoadoutOffset() != -1 ? NewPlayerAsAthena->GetCosmeticLoadout() : nullptr; auto CosmeticLoadout = NewPlayerAsAthena->GetCosmeticLoadoutOffset() != -1 ? NewPlayerAsAthena->GetCosmeticLoadout() : nullptr;
// LOG_INFO(LogDev, "CosmeticLoadout: {}", __int64(CosmeticLoadout));
auto CosmeticLoadoutPickaxe = CosmeticLoadout ? CosmeticLoadout->GetPickaxe() : nullptr; auto CosmeticLoadoutPickaxe = CosmeticLoadout ? CosmeticLoadout->GetPickaxe() : nullptr;
// LOG_INFO(LogDev, "CosmeticLoadoutPickaxe: {}", __int64(CosmeticLoadoutPickaxe));
// LOG_INFO(LogDev, "CosmeticLoadoutPickaxe Name: {}", CosmeticLoadoutPickaxe ? CosmeticLoadoutPickaxe->GetFullName() : "InvalidObject");
static auto WeaponDefinitionOffset = FindOffsetStruct("/Script/FortniteGame.AthenaPickaxeItemDefinition", "WeaponDefinition", false); static auto WeaponDefinitionOffset = FindOffsetStruct("/Script/FortniteGame.AthenaPickaxeItemDefinition", "WeaponDefinition", false);
auto PickaxeDefinition = CosmeticLoadoutPickaxe ? CosmeticLoadoutPickaxe->Get<UFortItemDefinition*>(WeaponDefinitionOffset) auto PickaxeDefinition = CosmeticLoadoutPickaxe ? CosmeticLoadoutPickaxe->Get<UFortItemDefinition*>(WeaponDefinitionOffset)
@@ -114,10 +121,6 @@ APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AControll
WorldInventory->AddItem(BuildingItemData_Floor, nullptr); WorldInventory->AddItem(BuildingItemData_Floor, nullptr);
WorldInventory->AddItem(BuildingItemData_Stair_W, nullptr); WorldInventory->AddItem(BuildingItemData_Stair_W, nullptr);
WorldInventory->AddItem(BuildingItemData_RoofS, nullptr); WorldInventory->AddItem(BuildingItemData_RoofS, nullptr);
// WorldInventory->AddItem(WoodItemData, nullptr, 100);
// WorldInventory->AddItem(DamageTrap, nullptr);
// WorldInventory->AddItem(FindObject<UFortItemDefinition>(L"/ParallelGameplay/Items/WestSausage/WID_WestSausage_Parallel.WID_WestSausage_Parallel"), nullptr, 1, 1000);
// WorldInventory->AddItem(FindObject<UFortItemDefinition>(L"/Game/Athena/Items/Consumables/HappyGhost/WID_Athena_HappyGhost.WID_Athena_HappyGhost"), nullptr);
/* if (Globals::bLateGame) /* if (Globals::bLateGame)
{ {

View File

@@ -198,6 +198,7 @@
<ClCompile Include="FortAthenaMutator_GiveItemsAtGamePhaseStep.cpp" /> <ClCompile Include="FortAthenaMutator_GiveItemsAtGamePhaseStep.cpp" />
<ClCompile Include="FortAthenaSupplyDrop.cpp" /> <ClCompile Include="FortAthenaSupplyDrop.cpp" />
<ClCompile Include="FortAthenaVehicle.cpp" /> <ClCompile Include="FortAthenaVehicle.cpp" />
<ClCompile Include="FortAthenaVehicleSpawner.cpp" />
<ClCompile Include="FortDecoItemDefinition.cpp" /> <ClCompile Include="FortDecoItemDefinition.cpp" />
<ClCompile Include="FortGadgetItemDefinition.cpp" /> <ClCompile Include="FortGadgetItemDefinition.cpp" />
<ClCompile Include="FortGameMode.cpp" /> <ClCompile Include="FortGameMode.cpp" />
@@ -315,6 +316,7 @@
<ClInclude Include="FortAthenaSKPushCannon.h" /> <ClInclude Include="FortAthenaSKPushCannon.h" />
<ClInclude Include="FortAthenaSupplyDrop.h" /> <ClInclude Include="FortAthenaSupplyDrop.h" />
<ClInclude Include="FortAthenaVehicle.h" /> <ClInclude Include="FortAthenaVehicle.h" />
<ClInclude Include="FortAthenaVehicleSpawner.h" />
<ClInclude Include="FortDecoItemDefinition.h" /> <ClInclude Include="FortDecoItemDefinition.h" />
<ClInclude Include="FortGadgetItemDefinition.h" /> <ClInclude Include="FortGadgetItemDefinition.h" />
<ClInclude Include="FortGameMode.h" /> <ClInclude Include="FortGameMode.h" />

View File

@@ -259,6 +259,9 @@
<ClCompile Include="SavePackage.cpp"> <ClCompile Include="SavePackage.cpp">
<Filter>Engine\Source\Runtime\CoreUObject\Private</Filter> <Filter>Engine\Source\Runtime\CoreUObject\Private</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="FortAthenaVehicleSpawner.cpp">
<Filter>FortniteGame\Source\FortniteGame\Private\Vehicles</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="log.h" /> <ClInclude Include="log.h" />
@@ -826,6 +829,9 @@
<ClInclude Include="Vector.h"> <ClInclude Include="Vector.h">
<Filter>Engine\Source\Runtime\Core\Public\Misc</Filter> <Filter>Engine\Source\Runtime\Core\Public\Misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="FortAthenaVehicleSpawner.h">
<Filter>FortniteGame\Source\FortniteGame\Public\Athena\Vehicle</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Filter Include="Engine"> <Filter Include="Engine">

View File

@@ -40,6 +40,7 @@
#include "FortAthenaMutator_Barrier.h" #include "FortAthenaMutator_Barrier.h"
#include "PlaysetLevelStreamComponent.h" #include "PlaysetLevelStreamComponent.h"
#include "FortAthenaVehicleSpawner.h"
enum ENetMode enum ENetMode
{ {
@@ -636,6 +637,9 @@ DWORD WINAPI Main(LPVOID)
Hooking::MinHook::Hook(InventoryManagementLibraryDefault, FindObject<UFunction>(L"/Script/FortniteGame.InventoryManagementLibrary.SwapItems"), Hooking::MinHook::Hook(InventoryManagementLibraryDefault, FindObject<UFunction>(L"/Script/FortniteGame.InventoryManagementLibrary.SwapItems"),
UInventoryManagementLibrary::SwapItemsHook, (PVOID*)&UInventoryManagementLibrary::SwapItemsOriginal, false, true); UInventoryManagementLibrary::SwapItemsHook, (PVOID*)&UInventoryManagementLibrary::SwapItemsOriginal, false, true);
Hooking::MinHook::Hook(FindObject("/Script/FortniteGame.Default__FortAthenaVehicleSpawner"), FindObject<UFunction>(L"/Script/FortniteGame.FortAthenaVehicleSpawner.SpawnVehicle"),
AFortAthenaVehicleSpawner::SpawnVehicleHook, nullptr, false);
static auto ServerHandlePickupInfoFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerPawn.ServerHandlePickupInfo"); static auto ServerHandlePickupInfoFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerPawn.ServerHandlePickupInfo");
if (ServerHandlePickupInfoFn) if (ServerHandlePickupInfoFn)
@@ -646,6 +650,8 @@ DWORD WINAPI Main(LPVOID)
{ {
Hooking::MinHook::Hook(FortPlayerPawnAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerPawn.ServerHandlePickup"), Hooking::MinHook::Hook(FortPlayerPawnAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerPawn.ServerHandlePickup"),
AFortPlayerPawn::ServerHandlePickupHook, nullptr, false); AFortPlayerPawn::ServerHandlePickupHook, nullptr, false);
Hooking::MinHook::Hook(FortPlayerPawnAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerPawn.ServerHandlePickupWithRequestedSwap"),
AFortPlayerPawn::ServerHandlePickupWithRequestedSwapHook, (PVOID*)&AFortPlayerPawn::ServerHandlePickupWithRequestedSwapOriginal, false, true);
} }
static auto PredictionKeyStruct = FindObject<UStruct>(L"/Script/GameplayAbilities.PredictionKey"); static auto PredictionKeyStruct = FindObject<UStruct>(L"/Script/GameplayAbilities.PredictionKey");
@@ -712,11 +718,18 @@ DWORD WINAPI Main(LPVOID)
Hooking::MinHook::Hook((PVOID)Addresses::CompletePickupAnimation, (PVOID)AFortPickup::CompletePickupAnimationHook, (PVOID*)&AFortPickup::CompletePickupAnimationOriginal); Hooking::MinHook::Hook((PVOID)Addresses::CompletePickupAnimation, (PVOID)AFortPickup::CompletePickupAnimationHook, (PVOID*)&AFortPickup::CompletePickupAnimationOriginal);
Hooking::MinHook::Hook((PVOID)Addresses::CanActivateAbility, ReturnTrueHook); // ahhh wtf Hooking::MinHook::Hook((PVOID)Addresses::CanActivateAbility, ReturnTrueHook); // ahhh wtf
// if (Fortnite_Version >= 2.5) uint64 ServerRemoveInventoryItemFunctionCallBeginFunctionAddr = 0;
if (Engine_Version >= 419)
if (Engine_Version >= 419) // Dude idk why but its getting the second ref kms
{ {
auto ServerRemoveInventoryItemFunctionCallRef = Memcury::Scanner::FindPointerRef((PVOID)FindFunctionCall(L"ServerRemoveInventoryItem", std::vector<uint8_t> ServerRemoveInventoryItemCallFunctionStarts = Engine_Version == 416
Fortnite_Version >= 16 ? std::vector<uint8_t>{ 0x48, 0x8B, 0xC4 } : std::vector<uint8_t>{ 0x48, 0x89, 0x5C }), 0, true); ? std::vector<uint8_t>{ 0x44, 0x88, 0x4C }
: Fortnite_Version >= 16
? std::vector<uint8_t>{ 0x48, 0x8B, 0xC4 }
: std::vector<uint8_t>{ 0x48, 0x89, 0x5C };
auto ServerRemoveInventoryItemCallFunctionCall = FindFunctionCall(L"ServerRemoveInventoryItem", ServerRemoveInventoryItemCallFunctionStarts);
auto ServerRemoveInventoryItemFunctionCallRef = Memcury::Scanner::FindPointerRef((PVOID)ServerRemoveInventoryItemCallFunctionCall, true);
LOG_INFO(LogDev, "ServerRemoveInventoryItemFunctionCallRef: 0x{:x}", ServerRemoveInventoryItemFunctionCallRef.Get() - __int64(GetModuleHandleW(0))); LOG_INFO(LogDev, "ServerRemoveInventoryItemFunctionCallRef: 0x{:x}", ServerRemoveInventoryItemFunctionCallRef.Get() - __int64(GetModuleHandleW(0)));
@@ -736,12 +749,13 @@ DWORD WINAPI Main(LPVOID)
break; break;
} }
} }
Hooking::MinHook::Hook(
Memcury::Scanner(ServerRemoveInventoryItemFunctionCallBeginFunctionAddr).GetAs<PVOID>(),
UFortInventoryInterface::RemoveInventoryItemHook
);
} }
else
{
}
Hooking::MinHook::Hook(Memcury::Scanner(ServerRemoveInventoryItemFunctionCallBeginFunctionAddr).GetAs<PVOID>(), UFortInventoryInterface::RemoveInventoryItemHook);
// if (Fortnite_Version >= 13) // if (Fortnite_Version >= 13)
Hooking::MinHook::Hook((PVOID)Addresses::SetZoneToIndex, (PVOID)SetZoneToIndexHook, (PVOID*)&SetZoneToIndexOriginal); Hooking::MinHook::Hook((PVOID)Addresses::SetZoneToIndex, (PVOID)SetZoneToIndexHook, (PVOID*)&SetZoneToIndexOriginal);
@@ -799,9 +813,16 @@ DWORD WINAPI Main(LPVOID)
LOG_INFO(LogHook, "Finished!"); LOG_INFO(LogHook, "Finished!");
while (true) if (false)
{ {
Sleep(10000); while (true)
{
Sleep(10000);
}
}
else
{
Sleep(-1);
} }
return 0; return 0;

View File

@@ -223,7 +223,7 @@ static inline uint64 FindInitHost()
{ {
if (Engine_Version == 427) // idk im dumb if (Engine_Version == 427) // idk im dumb
{ {
auto addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 55 57 41 56 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B F1 4C 8D 05").Get(); auto addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 55 57 41 56 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B F1 4C 8D 05", false).Get();
if (!addr) // s18 if (!addr) // s18
addr = Memcury::Scanner::FindPattern("48 8B C4 48 89 58 10 48 89 70 18 48 89 78 20 55 41 56 41 57 48 8D 68 A1 48 81 EC ? ? ? ? 48 8B F1 4C 8D 35 ? ? ? ? 4D").Get(); addr = Memcury::Scanner::FindPattern("48 8B C4 48 89 58 10 48 89 70 18 48 89 78 20 55 41 56 41 57 48 8D 68 A1 48 81 EC ? ? ? ? 48 8B F1 4C 8D 35 ? ? ? ? 4D").Get();
@@ -664,7 +664,7 @@ static inline uint64 FindSetZoneToIndex() // actually StartNewSafeZonePhase
if (Engine_Version == 422) if (Engine_Version == 422)
return Memcury::Scanner::FindPattern("E9 ? ? ? ? 48 8B C1 40 38 B9").RelativeOffset(1).Get(); // 7.40 return Memcury::Scanner::FindPattern("E9 ? ? ? ? 48 8B C1 40 38 B9").RelativeOffset(1).Get(); // 7.40
auto Addr = Memcury::Scanner::FindStringRef(L"FortGameModeAthena: No MegaStorm on SafeZone[%d]. GridCellThickness is less than 1.0.", true, 0, Fortnite_Version >= 16).Get(); auto Addr = Memcury::Scanner::FindStringRef(L"FortGameModeAthena: No MegaStorm on SafeZone[%d]. GridCellThickness is less than 1.0.", true, 0, Engine_Version >= 427).Get();
// return FindBytes(Addr, { 0x40, 0x55 }, 30000, 0, true); // return FindBytes(Addr, { 0x40, 0x55 }, 30000, 0, true);
if (!Addr) if (!Addr)
@@ -859,7 +859,9 @@ static inline uint64 FindActorGetNetMode()
// return 0; // return 0;
if (Engine_Version == 500) if (Engine_Version == 500)
{
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 57 48 83 EC 20 F6 41 08 10 48 8B D9 0F 85 ? ? ? ? 48 8B 41 20 48 85 C0 0F 84 ? ? ? ? F7 40").Get(); return Memcury::Scanner::FindPattern("48 89 5C 24 ? 57 48 83 EC 20 F6 41 08 10 48 8B D9 0F 85 ? ? ? ? 48 8B 41 20 48 85 C0 0F 84 ? ? ? ? F7 40").Get();
}
if (Engine_Version == 427) if (Engine_Version == 427)
{ {
@@ -1132,10 +1134,7 @@ static inline uint64 FindChangeGameSessionId()
if (Engine_Version >= 427) if (Engine_Version >= 427)
{ {
if (Fortnite_Version < 18) return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 55 41 54 41 55 41 56 41 57 48 8B EC 48 83 EC 70 4C 8B FA 4C").Get(); // no work on s18
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 55 41 54 41 55 41 56 41 57 48 8B EC 48 83 EC 70 4C 8B FA 4C").Get();
else
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 55 41 54 41 55 41 56 41 57 48 8B EC 48 83 EC 70 4C 8B FA 4C").Get();
} }
if (Fortnite_Version == 2.5) if (Fortnite_Version == 2.5)

View File

@@ -5,6 +5,8 @@
#include "Actor.h" #include "Actor.h"
#include "hooking.h" #include "hooking.h"
#include "SoftObjectPtr.h" #include "SoftObjectPtr.h"
#include "FortGameModeAthena.h"
#include "GameplayStatics.h"
// Vehicle class name changes multiple times across versions, so I made it it's own file. // Vehicle class name changes multiple times across versions, so I made it it's own file.
@@ -188,107 +190,5 @@ static inline void SpawnVehicles2()
auto Vehicle = SpawnVehicleFromSpawner(VehicleSpawner); auto Vehicle = SpawnVehicleFromSpawner(VehicleSpawner);
} }
AllVehicleSpawners.Free();
}
static inline void SpawnVehicles()
{
static auto FortAthenaVehicleSpawnerClass = FindObject<UClass>("/Script/FortniteGame.FortAthenaVehicleSpawner");
TArray<AActor*> AllVehicleSpawners = UGameplayStatics::GetAllActorsOfClass(GetWorld(), FortAthenaVehicleSpawnerClass);
for (int i = 0; i < AllVehicleSpawners.Num(); i++)
{
auto VehicleSpawner = (AllVehicleSpawners.at(i));
static auto FortVehicleItemDefVariantsOffset = VehicleSpawner->GetOffset("FortVehicleItemDefVariants", false);
bool aa = true;
static auto VIDClass = FindObject<UClass>("/Script/FortniteGame.FortVehicleItemDefinition");
if (FortVehicleItemDefVariantsOffset != -1)
{
struct FVehicleWeightedDef
{
TSoftObjectPtr<UFortItemDefinition> VehicleItemDef;
char pad[0x20]; // FScalableFloat Weight; // 0x0028(0x0020) (Edit, BlueprintVisible, BlueprintReadOnly)
};
auto FortVehicleItemDefVariants = VehicleSpawner->GetPtr<TArray<FVehicleWeightedDef>>(FortVehicleItemDefVariantsOffset);
if (FortVehicleItemDefVariants->Num() > 0)
{
aa = false;
auto& first = FortVehicleItemDefVariants->At(0);
auto AssetPathName = first.VehicleItemDef.SoftObjectPtr.ObjectID.AssetPathName;
if (!AssetPathName.ComparisonIndex.Value)
continue;
auto VehicleItemDef = LoadObject(AssetPathName.ToString(), VIDClass);
if (VehicleItemDef)
{
static auto VehicleActorClassOffset = VehicleItemDef->GetOffset("VehicleActorClass");
auto VehicleActorClassSoft = VehicleItemDef->GetPtr<TSoftObjectPtr<UClass>>(VehicleActorClassOffset);
auto VehicleClassAssetPath = VehicleActorClassSoft->SoftObjectPtr.ObjectID.AssetPathName;
if (!VehicleClassAssetPath.ComparisonIndex.Value)
continue;
static auto BGAClass = FindObject<UClass>("/Script/Engine.BlueprintGeneratedClass");
auto VehicleActorClass = LoadObject<UClass>(VehicleClassAssetPath.ToString(), BGAClass);
;
if (!VehicleActorClass)
continue;
GetWorld()->SpawnActor<AActor>(VehicleActorClass, VehicleSpawner->GetActorLocation(), VehicleSpawner->GetActorRotation().Quaternion());
}
}
}
if (aa)
{
static auto FortVehicleItemDefOffset = VehicleSpawner->GetOffset("FortVehicleItemDef");
if (FortVehicleItemDefOffset == -1)
{
}
auto FortVehicleItemDefSoft = VehicleSpawner->GetPtr<TSoftObjectPtr<UFortItemDefinition>>(FortVehicleItemDefOffset);
auto FortVehicleItemDefAssetPath = FortVehicleItemDefSoft->SoftObjectPtr.ObjectID.AssetPathName;
if (!FortVehicleItemDefAssetPath.ComparisonIndex.Value)
continue;
auto FortVehicleItemDef = LoadObject<UFortItemDefinition>(FortVehicleItemDefAssetPath.ToString(), VIDClass);
if (!FortVehicleItemDef)
continue;
static auto VehicleActorClassOffset = FortVehicleItemDef->GetOffset("VehicleActorClass");
auto VehicleActorClassSoft = FortVehicleItemDef->GetPtr<TSoftObjectPtr<UClass>>(VehicleActorClassOffset);
auto VehicleActorClassAssetPath = VehicleActorClassSoft->SoftObjectPtr.ObjectID.AssetPathName;
if (!VehicleActorClassAssetPath.ComparisonIndex.Value)
continue;
static auto BGAClass = FindObject<UClass>("/Script/Engine.BlueprintGeneratedClass");
auto VehicleActorClass = LoadObject<UClass>(VehicleActorClassAssetPath.ToString(), BGAClass);
if (!VehicleActorClass)
continue;
GetWorld()->SpawnActor<AActor>(VehicleActorClass, VehicleSpawner->GetActorLocation(), VehicleSpawner->GetActorRotation().Quaternion());
}
}
AllVehicleSpawners.Free(); AllVehicleSpawners.Free();
} }