mirror of
https://github.com/Milxnor/Project-Reboot-3.0.git
synced 2026-01-13 10:52:22 +01:00
a medium amount
fix some playlist starter loot, cleanup some code, fix death bugs on 1.8 and 1.7.2, fix reloading not taking items on 1.8 and 1.7.2, fix looting on s9, fix some s15 & s16 builds, fix bug with higher version looting
This commit is contained in:
@@ -24,6 +24,11 @@ void SpawnBGAs() // hahah not "proper", there's a function that we can hook and
|
||||
auto BGAConsumableSpawner = AllBGAConsumableSpawners.at(i);
|
||||
auto SpawnLocation = BGAConsumableSpawner->GetActorLocation();
|
||||
|
||||
FTransform SpawnTransform{};
|
||||
SpawnTransform.Translation = SpawnLocation;
|
||||
SpawnTransform.Scale3D = FVector{ 1, 1, 1 };
|
||||
SpawnTransform.Rotation = FQuat();
|
||||
|
||||
if (FBuildingGameplayActorSpawnDetails::GetStruct())
|
||||
{
|
||||
// todo handle?
|
||||
@@ -33,6 +38,7 @@ void SpawnBGAs() // hahah not "proper", there's a function that we can hook and
|
||||
else
|
||||
{
|
||||
// SpawnLocation.Z += 100;
|
||||
// SpawnLocation.Z -= 50; // proper frfr
|
||||
}
|
||||
|
||||
static auto SpawnLootTierGroupOffset = BGAConsumableSpawner->GetOffset("SpawnLootTierGroup");
|
||||
@@ -45,7 +51,7 @@ void SpawnBGAs() // hahah not "proper", there's a function that we can hook and
|
||||
static auto ConsumableClassOffset = LootDrop.ItemDefinition->GetOffset("ConsumableClass");
|
||||
auto ConsumableClassSoft = LootDrop.ItemDefinition->GetPtr<TSoftObjectPtr<UClass>>(ConsumableClassOffset);
|
||||
|
||||
static auto BlueprintGeneratedClassClass = FindObject<UClass>("/Script/Engine.BlueprintGeneratedClass");
|
||||
static auto BlueprintGeneratedClassClass = FindObject<UClass>(L"/Script/Engine.BlueprintGeneratedClass");
|
||||
auto StrongConsumableClass = ConsumableClassSoft->Get(BlueprintGeneratedClassClass, true);
|
||||
|
||||
if (!StrongConsumableClass)
|
||||
@@ -54,12 +60,20 @@ void SpawnBGAs() // hahah not "proper", there's a function that we can hook and
|
||||
continue;
|
||||
}
|
||||
|
||||
auto ConsumableActor = GetWorld()->SpawnActor<ABuildingGameplayActor>(StrongConsumableClass, SpawnLocation);
|
||||
bool bDeferConstruction = false; // hm?
|
||||
|
||||
FActorSpawnParameters SpawnParameters{};
|
||||
// SpawnParameters.ObjectFlags = RF_Transactional; // idk fortnite does this i think
|
||||
SpawnParameters.bDeferConstruction = bDeferConstruction;
|
||||
|
||||
auto ConsumableActor = GetWorld()->SpawnActor<ABuildingGameplayActor>(StrongConsumableClass, SpawnTransform, SpawnParameters);
|
||||
|
||||
if (ConsumableActor)
|
||||
{
|
||||
// BeginDeferredActorSpawnFromClass ??
|
||||
// ConsumableActor->InitializeBuildingActor(nullptr, nullptr, true); // idk UFortKismetLibrary::SpawnBuildingGameplayActor does this
|
||||
if (bDeferConstruction)
|
||||
UGameplayStatics::FinishSpawningActor(ConsumableActor, SpawnTransform); // what
|
||||
|
||||
ConsumableActor->InitializeBuildingActor(nullptr, nullptr, true); // idk UFortKismetLibrary::SpawnBuildingGameplayActor does this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
26
Project Reboot 3.0/BuildingContainer.cpp
Normal file
26
Project Reboot 3.0/BuildingContainer.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "BuildingContainer.h"
|
||||
#include "FortPickup.h"
|
||||
#include "FortLootPackage.h"
|
||||
#include "FortGameModeAthena.h"
|
||||
|
||||
bool ABuildingContainer::SpawnLoot(AFortPawn* Pawn)
|
||||
{
|
||||
FVector LocationToSpawnLoot = this->GetActorLocation() + this->GetActorRightVector() * 70.f + FVector{ 0, 0, 50 };
|
||||
|
||||
static auto SearchLootTierGroupOffset = this->GetOffset("SearchLootTierGroup");
|
||||
auto RedirectedLootTier = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode())->RedirectLootTier(this->Get<FName>(SearchLootTierGroupOffset));
|
||||
|
||||
// LOG_INFO(LogInteraction, "RedirectedLootTier: {}", RedirectedLootTier.ToString());
|
||||
|
||||
auto LootDrops = PickLootDrops(RedirectedLootTier, true);
|
||||
|
||||
// LOG_INFO(LogInteraction, "LootDrops.size(): {}", LootDrops.size());
|
||||
|
||||
for (int i = 0; i < LootDrops.size(); i++)
|
||||
{
|
||||
auto& lootDrop = LootDrops.at(i);
|
||||
AFortPickup::SpawnPickup(lootDrop.ItemDefinition, LocationToSpawnLoot, lootDrop.Count, EFortPickupSourceTypeFlag::Container, EFortPickupSpawnSource::Unset, lootDrop.LoadedAmmo);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "BuildingSMActor.h"
|
||||
#include "FortPawn.h"
|
||||
|
||||
class ABuildingContainer : public ABuildingSMActor
|
||||
{
|
||||
@@ -12,6 +13,8 @@ public:
|
||||
return this->ReadBitfieldValue(bDestroyContainerOnSearchOffset, bDestroyContainerOnSearchFieldMask);
|
||||
}
|
||||
|
||||
bool SpawnLoot(AFortPawn* Pawn);
|
||||
|
||||
static UClass* StaticClass()
|
||||
{
|
||||
static auto Class = FindObject<UClass>("/Script/FortniteGame.BuildingContainer");
|
||||
|
||||
@@ -27,3 +27,10 @@ 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;
|
||||
};
|
||||
8
Project Reboot 3.0/FortAthenaMutator_LoadoutSwap.h
Normal file
8
Project Reboot 3.0/FortAthenaMutator_LoadoutSwap.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "FortAthenaMutator.h"
|
||||
|
||||
class AFortAthenaMutator_LoadoutSwap : public AFortAthenaMutator
|
||||
{
|
||||
public:
|
||||
};
|
||||
15
Project Reboot 3.0/FortAthenaMutator_TDM.h
Normal file
15
Project Reboot 3.0/FortAthenaMutator_TDM.h
Normal 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;
|
||||
}
|
||||
};
|
||||
@@ -103,6 +103,8 @@ struct FFortItemEntry : FFastArraySerializerItem
|
||||
|
||||
void CopyFromAnotherItemEntry(FFortItemEntry* OtherItemEntry, bool bCopyGuid = false)
|
||||
{
|
||||
// We can use FortItemEntryStruct->CopyScriptStruct
|
||||
|
||||
FGuid OldGuid = this->GetItemGuid();
|
||||
|
||||
if (false)
|
||||
|
||||
@@ -74,9 +74,8 @@ static FFortLootPackageData* GetLootPackage(std::vector<FFortLootPackageData*>&
|
||||
|
||||
struct FFortGameFeatureLootTableData
|
||||
{
|
||||
public:
|
||||
TSoftObjectPtr<UDataTable> LootTierData; // 0x0(0x28)(Edit, UObjectWrapper, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
TSoftObjectPtr<UDataTable> LootPackageData; // 0x28(0x28)(Edit, UObjectWrapper, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
TSoftObjectPtr<UDataTable> LootTierData;
|
||||
TSoftObjectPtr<UDataTable> LootPackageData;
|
||||
};
|
||||
|
||||
std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recursive)
|
||||
@@ -203,7 +202,7 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recurs
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
if (bOverrideIsComposite)
|
||||
/* if (bOverrideIsComposite)
|
||||
{
|
||||
static auto ParentTablesOffset = ptr->GetOffset("ParentTables");
|
||||
|
||||
@@ -218,7 +217,7 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recurs
|
||||
LPTables.push_back(ParentTable);
|
||||
}
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
LPTables.push_back(ptr);
|
||||
}
|
||||
@@ -257,7 +256,7 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recurs
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
if (bOverrideIsComposite)
|
||||
/* if (bOverrideIsComposite)
|
||||
{
|
||||
static auto ParentTablesOffset = ptr->GetOffset("ParentTables");
|
||||
|
||||
@@ -272,7 +271,7 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recurs
|
||||
LTDTables.push_back(ParentTable);
|
||||
}
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
LTDTables.push_back(ptr);
|
||||
}
|
||||
@@ -312,7 +311,7 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recurs
|
||||
}
|
||||
}
|
||||
|
||||
if (Fortnite_Version <= 6) // ahhh
|
||||
if (Fortnite_Version <= 6 || std::floor(Fortnite_Version) == 9) // ahhh
|
||||
{
|
||||
LTDTables.clear();
|
||||
LPTables.clear();
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include "vendingmachine.h"
|
||||
#include "KismetSystemLibrary.h"
|
||||
#include "gui.h"
|
||||
#include "FortAthenaMutator_InventoryOverride.h"
|
||||
#include "FortAthenaMutator_TDM.h"
|
||||
|
||||
void AFortPlayerController::ClientReportDamagedResourceBuilding(ABuildingSMActor* BuildingSMActor, EFortResourceType PotentialResourceType, int PotentialResourceCount, bool bDestroyed, bool bJustHitWeakspot)
|
||||
{
|
||||
@@ -416,22 +418,7 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame*
|
||||
static auto OnRep_bAlreadySearchedFn = FindObject<UFunction>(L"/Script/FortniteGame.BuildingContainer.OnRep_bAlreadySearched");
|
||||
BuildingContainer->ProcessEvent(OnRep_bAlreadySearchedFn);
|
||||
|
||||
static auto SearchLootTierGroupOffset = BuildingContainer->GetOffset("SearchLootTierGroup");
|
||||
auto RedirectedLootTier = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode(), false)->RedirectLootTier(BuildingContainer->Get<FName>(SearchLootTierGroupOffset));
|
||||
|
||||
LOG_INFO(LogInteraction, "RedirectedLootTier: {}", RedirectedLootTier.ToString());
|
||||
|
||||
auto LootDrops = PickLootDrops(RedirectedLootTier, true);
|
||||
|
||||
LOG_INFO(LogInteraction, "LootDrops.size(): {}", LootDrops.size());
|
||||
|
||||
for (int i = 0; i < LootDrops.size(); i++)
|
||||
{
|
||||
auto& lootDrop = LootDrops.at(i);
|
||||
AFortPickup::SpawnPickup(lootDrop.ItemDefinition, LocationToSpawnLoot, lootDrop.Count, EFortPickupSourceTypeFlag::Container, EFortPickupSpawnSource::Unset, lootDrop.LoadedAmmo
|
||||
// , (AFortPawn*)PlayerController->GetPawn() // should we put this here?
|
||||
);
|
||||
}
|
||||
BuildingContainer->SpawnLoot(PlayerController->GetMyFortPawn());
|
||||
|
||||
// if (BuildingContainer->ShouldDestroyOnSearch())
|
||||
// BuildingContainer->K2_DestroyActor();
|
||||
@@ -1135,188 +1122,231 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
|
||||
|
||||
static auto FallDamageEnumValue = 1;
|
||||
|
||||
auto DeathInfo = (void*)(__int64(DeadPlayerState) + MemberOffsets::FortPlayerStateAthena::DeathInfo); // Alloc<void>(DeathInfoStructSize);
|
||||
RtlSecureZeroMemory(DeathInfo, DeathInfoStructSize);
|
||||
uint8_t DeathCause = 0;
|
||||
|
||||
auto/*&*/ Tags = MemberOffsets::FortPlayerPawn::CorrectTags == 0 ? FGameplayTagContainer()
|
||||
: DeadPawn->Get<FGameplayTagContainer>(MemberOffsets::FortPlayerPawn::CorrectTags);
|
||||
// *(FGameplayTagContainer*)(__int64(DeathReport) + MemberOffsets::DeathReport::Tags);
|
||||
|
||||
// LOG_INFO(LogDev, "Tags: {}", Tags.ToStringSimple(true));
|
||||
|
||||
auto DeathCause = ToDeathCause(Tags, false, DeadPawn); // DeadPawn->IsDBNO() ??
|
||||
|
||||
LOG_INFO(LogDev, "DeathCause: {}", (int)DeathCause);
|
||||
|
||||
*(bool*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::bDBNO) = DeadPawn->IsDBNO();
|
||||
*(uint8*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::DeathCause) = DeathCause;
|
||||
*(AActor**)(__int64(DeathInfo) + MemberOffsets::DeathInfo::FinisherOrDowner) = KillerPlayerState ? KillerPlayerState : DeadPlayerState;
|
||||
|
||||
if (MemberOffsets::DeathInfo::DeathLocation != -1)
|
||||
*(FVector*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::DeathLocation) = DeathLocation;
|
||||
|
||||
if (MemberOffsets::DeathInfo::DeathTags != -1)
|
||||
*(FGameplayTagContainer*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::DeathTags) = Tags;
|
||||
|
||||
if (MemberOffsets::DeathInfo::bInitialized != -1)
|
||||
*(bool*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::bInitialized) = true;
|
||||
|
||||
if (DeathCause == FallDamageEnumValue)
|
||||
if (Fortnite_Version > 1.8 || Fortnite_Version == 1.11)
|
||||
{
|
||||
if (MemberOffsets::FortPlayerPawnAthena::LastFallDistance != -1)
|
||||
*(float*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::Distance) = DeadPawn->Get<float>(MemberOffsets::FortPlayerPawnAthena::LastFallDistance);
|
||||
auto DeathInfo = (void*)(__int64(DeadPlayerState) + MemberOffsets::FortPlayerStateAthena::DeathInfo); // Alloc<void>(DeathInfoStructSize);
|
||||
RtlSecureZeroMemory(DeathInfo, DeathInfoStructSize);
|
||||
|
||||
auto/*&*/ Tags = MemberOffsets::FortPlayerPawn::CorrectTags == 0 ? FGameplayTagContainer()
|
||||
: DeadPawn->Get<FGameplayTagContainer>(MemberOffsets::FortPlayerPawn::CorrectTags);
|
||||
// *(FGameplayTagContainer*)(__int64(DeathReport) + MemberOffsets::DeathReport::Tags);
|
||||
|
||||
// LOG_INFO(LogDev, "Tags: {}", Tags.ToStringSimple(true));
|
||||
|
||||
DeathCause = ToDeathCause(Tags, false, DeadPawn); // DeadPawn->IsDBNO() ??
|
||||
|
||||
LOG_INFO(LogDev, "DeathCause: {}", (int)DeathCause);
|
||||
|
||||
*(bool*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::bDBNO) = DeadPawn->IsDBNO();
|
||||
*(uint8*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::DeathCause) = DeathCause;
|
||||
*(AActor**)(__int64(DeathInfo) + MemberOffsets::DeathInfo::FinisherOrDowner) = KillerPlayerState ? KillerPlayerState : DeadPlayerState;
|
||||
|
||||
if (MemberOffsets::DeathInfo::DeathLocation != -1)
|
||||
*(FVector*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::DeathLocation) = DeathLocation;
|
||||
|
||||
if (MemberOffsets::DeathInfo::DeathTags != -1)
|
||||
*(FGameplayTagContainer*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::DeathTags) = Tags;
|
||||
|
||||
if (MemberOffsets::DeathInfo::bInitialized != -1)
|
||||
*(bool*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::bInitialized) = true;
|
||||
|
||||
if (DeathCause == FallDamageEnumValue)
|
||||
{
|
||||
if (MemberOffsets::FortPlayerPawnAthena::LastFallDistance != -1)
|
||||
*(float*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::Distance) = DeadPawn->Get<float>(MemberOffsets::FortPlayerPawnAthena::LastFallDistance);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MemberOffsets::DeathInfo::Distance != -1)
|
||||
*(float*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::Distance) = KillerPawn ? KillerPawn->GetDistanceTo(DeadPawn) : 0;
|
||||
}
|
||||
|
||||
if (MemberOffsets::FortPlayerState::PawnDeathLocation != -1)
|
||||
DeadPlayerState->Get<FVector>(MemberOffsets::FortPlayerState::PawnDeathLocation) = DeathLocation;
|
||||
|
||||
static auto OnRep_DeathInfoFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerStateAthena.OnRep_DeathInfo");
|
||||
|
||||
if (OnRep_DeathInfoFn)
|
||||
{
|
||||
DeadPlayerState->ProcessEvent(OnRep_DeathInfoFn);
|
||||
}
|
||||
|
||||
if (KillerPlayerState && KillerPlayerState != DeadPlayerState)
|
||||
{
|
||||
if (MemberOffsets::FortPlayerStateAthena::KillScore != -1)
|
||||
KillerPlayerState->Get<int>(MemberOffsets::FortPlayerStateAthena::KillScore)++;
|
||||
|
||||
if (MemberOffsets::FortPlayerStateAthena::TeamKillScore != -1)
|
||||
KillerPlayerState->Get<int>(MemberOffsets::FortPlayerStateAthena::TeamKillScore)++;
|
||||
|
||||
KillerPlayerState->ClientReportKill(DeadPlayerState);
|
||||
|
||||
/* LoopMutators([&](AFortAthenaMutator* Mutator) {
|
||||
if (auto TDM_Mutator = Cast<AFortAthenaMutator_TDM>(Mutator))
|
||||
{
|
||||
struct
|
||||
{
|
||||
int EventId; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
int EventParam1; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
int EventParam2; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
int EventParam3; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
} AFortAthenaMutator_TDM_OnMutatorGameplayEvent_Params{ 1, 0, 0, 0 };
|
||||
|
||||
static auto TDM_OnMutatorGameplayEventFn = FindObject<UFunction>("/Script/FortniteGame.FortAthenaMutator_TDM.OnMutatorGameplayEvent");
|
||||
TDM_Mutator->ProcessEvent(TDM_OnMutatorGameplayEventFn, &AFortAthenaMutator_TDM_OnMutatorGameplayEvent_Params);
|
||||
}
|
||||
}); */
|
||||
|
||||
// KillerPlayerState->OnRep_Kills();
|
||||
}
|
||||
|
||||
// LOG_INFO(LogDev, "Reported kill.");
|
||||
|
||||
/* if (KillerPawn && KillerPawn != DeadPawn)
|
||||
{
|
||||
KillerPawn->SetHealth(100);
|
||||
KillerPawn->SetShield(100);
|
||||
} */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MemberOffsets::DeathInfo::Distance != -1)
|
||||
*(float*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::Distance) = KillerPawn ? KillerPawn->GetDistanceTo(DeadPawn) : 0;
|
||||
}
|
||||
|
||||
if (MemberOffsets::FortPlayerState::PawnDeathLocation != -1)
|
||||
DeadPlayerState->Get<FVector>(MemberOffsets::FortPlayerState::PawnDeathLocation) = DeathLocation;
|
||||
|
||||
static auto OnRep_DeathInfoFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerStateAthena.OnRep_DeathInfo");
|
||||
|
||||
if (OnRep_DeathInfoFn)
|
||||
{
|
||||
DeadPlayerState->ProcessEvent(OnRep_DeathInfoFn);
|
||||
}
|
||||
|
||||
if (KillerPlayerState && KillerPlayerState != DeadPlayerState)
|
||||
{
|
||||
KillerPlayerState->Get<int>(MemberOffsets::FortPlayerStateAthena::KillScore)++;
|
||||
|
||||
if (MemberOffsets::FortPlayerStateAthena::TeamKillScore != -1)
|
||||
KillerPlayerState->Get<int>(MemberOffsets::FortPlayerStateAthena::TeamKillScore)++;
|
||||
|
||||
KillerPlayerState->ClientReportKill(DeadPlayerState);
|
||||
// KillerPlayerState->OnRep_Kills();
|
||||
}
|
||||
|
||||
LOG_INFO(LogDev, "Reported kill.");
|
||||
|
||||
/* if (KillerPawn && KillerPawn != DeadPawn)
|
||||
{
|
||||
KillerPawn->SetHealth(100);
|
||||
KillerPawn->SetShield(100);
|
||||
} */
|
||||
|
||||
bool bIsRespawningAllowed = GameState->IsRespawningAllowed(DeadPlayerState);
|
||||
|
||||
if (!bIsRespawningAllowed)
|
||||
{
|
||||
auto WorldInventory = PlayerController->GetWorldInventory();
|
||||
bool bDropInventory = true;
|
||||
|
||||
if (!WorldInventory)
|
||||
return ClientOnPawnDiedOriginal(PlayerController, DeathReport);
|
||||
LoopMutators([&](AFortAthenaMutator* Mutator)
|
||||
{
|
||||
if (auto FortAthenaMutator_InventoryOverride = Cast<AFortAthenaMutator_InventoryOverride>(Mutator))
|
||||
{
|
||||
if (FortAthenaMutator_InventoryOverride->GetDropAllItemsOverride(DeadPlayerState->GetTeamIndex()) == EAthenaLootDropOverride::ForceKeep)
|
||||
{
|
||||
bDropInventory = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
auto& ItemInstances = WorldInventory->GetItemList().GetItemInstances();
|
||||
|
||||
std::vector<std::pair<FGuid, int>> GuidAndCountsToRemove;
|
||||
|
||||
for (int i = 0; i < ItemInstances.Num(); i++)
|
||||
if (bDropInventory)
|
||||
{
|
||||
auto ItemInstance = ItemInstances.at(i);
|
||||
auto WorldInventory = PlayerController->GetWorldInventory();
|
||||
|
||||
// LOG_INFO(LogDev, "[{}/{}] CurrentItemInstance {}", i, ItemInstances.Num(), __int64(ItemInstance));
|
||||
if (!WorldInventory)
|
||||
return ClientOnPawnDiedOriginal(PlayerController, DeathReport);
|
||||
|
||||
if (!ItemInstance)
|
||||
continue;
|
||||
auto& ItemInstances = WorldInventory->GetItemList().GetItemInstances();
|
||||
|
||||
auto ItemEntry = ItemInstance->GetItemEntry();
|
||||
auto WorldItemDefinition = Cast<UFortWorldItemDefinition>(ItemEntry->GetItemDefinition());
|
||||
std::vector<std::pair<FGuid, int>> GuidAndCountsToRemove;
|
||||
|
||||
// LOG_INFO(LogDev, "[{}/{}] WorldItemDefinition {}", i, ItemInstances.Num(), WorldItemDefinition ? WorldItemDefinition->GetFullName() : "InvalidObject");
|
||||
for (int i = 0; i < ItemInstances.Num(); i++)
|
||||
{
|
||||
auto ItemInstance = ItemInstances.at(i);
|
||||
|
||||
if (!WorldItemDefinition)
|
||||
continue;
|
||||
// LOG_INFO(LogDev, "[{}/{}] CurrentItemInstance {}", i, ItemInstances.Num(), __int64(ItemInstance));
|
||||
|
||||
auto ShouldBeDropped = WorldItemDefinition->CanBeDropped(); // WorldItemDefinition->ShouldDropOnDeath();
|
||||
if (!ItemInstance)
|
||||
continue;
|
||||
|
||||
// LOG_INFO(LogDev, "[{}/{}] ShouldBeDropped {}", i, ItemInstances.Num(), ShouldBeDropped);
|
||||
auto ItemEntry = ItemInstance->GetItemEntry();
|
||||
auto WorldItemDefinition = Cast<UFortWorldItemDefinition>(ItemEntry->GetItemDefinition());
|
||||
|
||||
if (!ShouldBeDropped)
|
||||
continue;
|
||||
// LOG_INFO(LogDev, "[{}/{}] WorldItemDefinition {}", i, ItemInstances.Num(), WorldItemDefinition ? WorldItemDefinition->GetFullName() : "InvalidObject");
|
||||
|
||||
AFortPickup::SpawnPickup(WorldItemDefinition, DeathLocation, ItemEntry->GetCount(), EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::PlayerElimination,
|
||||
ItemEntry->GetLoadedAmmo());
|
||||
if (!WorldItemDefinition)
|
||||
continue;
|
||||
|
||||
GuidAndCountsToRemove.push_back({ ItemEntry->GetItemGuid(), ItemEntry->GetCount() });
|
||||
// WorldInventory->RemoveItem(ItemEntry->GetItemGuid(), nullptr, ItemEntry->GetCount());
|
||||
auto ShouldBeDropped = WorldItemDefinition->CanBeDropped(); // WorldItemDefinition->ShouldDropOnDeath();
|
||||
|
||||
// LOG_INFO(LogDev, "[{}/{}] ShouldBeDropped {}", i, ItemInstances.Num(), ShouldBeDropped);
|
||||
|
||||
if (!ShouldBeDropped)
|
||||
continue;
|
||||
|
||||
AFortPickup::SpawnPickup(WorldItemDefinition, DeathLocation, ItemEntry->GetCount(), EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::PlayerElimination,
|
||||
ItemEntry->GetLoadedAmmo());
|
||||
|
||||
GuidAndCountsToRemove.push_back({ ItemEntry->GetItemGuid(), ItemEntry->GetCount() });
|
||||
// WorldInventory->RemoveItem(ItemEntry->GetItemGuid(), nullptr, ItemEntry->GetCount());
|
||||
}
|
||||
|
||||
for (auto& Pair : GuidAndCountsToRemove)
|
||||
{
|
||||
WorldInventory->RemoveItem(Pair.first, nullptr, Pair.second, true);
|
||||
}
|
||||
|
||||
WorldInventory->Update();
|
||||
}
|
||||
|
||||
for (auto& Pair : GuidAndCountsToRemove)
|
||||
{
|
||||
WorldInventory->RemoveItem(Pair.first, nullptr, Pair.second, true);
|
||||
}
|
||||
|
||||
WorldInventory->Update();
|
||||
|
||||
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
|
||||
|
||||
if (!DeadPawn->IsDBNO())
|
||||
{
|
||||
static void (*RemoveFromAlivePlayers)(AFortGameModeAthena* GameMode, AFortPlayerController* PlayerController, APlayerState* PlayerState, APawn* FinisherPawn,
|
||||
UFortWeaponItemDefinition* FinishingWeapon, uint8_t DeathCause, char a7)
|
||||
= decltype(RemoveFromAlivePlayers)(Addresses::RemoveFromAlivePlayers);
|
||||
|
||||
AActor* DamageCauser = *(AActor**)(__int64(DeathReport) + MemberOffsets::DeathReport::DamageCauser);
|
||||
UFortWeaponItemDefinition* KillerWeaponDef = nullptr;
|
||||
|
||||
static auto FortProjectileBaseClass = FindObject<UClass>(L"/Script/FortniteGame.FortProjectileBase");
|
||||
LOG_INFO(LogDev, "FortProjectileBaseClass: {}", __int64(FortProjectileBaseClass));
|
||||
|
||||
if (DamageCauser)
|
||||
if (Fortnite_Version > 1.8 || Fortnite_Version == 1.11)
|
||||
{
|
||||
if (DamageCauser->IsA(FortProjectileBaseClass))
|
||||
static void (*RemoveFromAlivePlayers)(AFortGameModeAthena * GameMode, AFortPlayerController * PlayerController, APlayerState * PlayerState, APawn * FinisherPawn,
|
||||
UFortWeaponItemDefinition * FinishingWeapon, uint8_t DeathCause, char a7)
|
||||
= decltype(RemoveFromAlivePlayers)(Addresses::RemoveFromAlivePlayers);
|
||||
|
||||
AActor* DamageCauser = *(AActor**)(__int64(DeathReport) + MemberOffsets::DeathReport::DamageCauser);
|
||||
UFortWeaponItemDefinition* KillerWeaponDef = nullptr;
|
||||
|
||||
static auto FortProjectileBaseClass = FindObject<UClass>(L"/Script/FortniteGame.FortProjectileBase");
|
||||
LOG_INFO(LogDev, "FortProjectileBaseClass: {}", __int64(FortProjectileBaseClass));
|
||||
|
||||
if (DamageCauser)
|
||||
{
|
||||
LOG_INFO(LogDev, "From a projectile!");
|
||||
auto Owner = Cast<AFortWeapon>(DamageCauser->GetOwner());
|
||||
KillerWeaponDef = Owner->IsValidLowLevel() ? Owner->GetWeaponData() : nullptr; // I just added the IsValidLowLevel check because what if the weapon destroys?
|
||||
}
|
||||
if (auto Weapon = Cast<AFortWeapon>(DamageCauser))
|
||||
{
|
||||
LOG_INFO(LogDev, "From a weapon!");
|
||||
KillerWeaponDef = Weapon->GetWeaponData();
|
||||
}
|
||||
}
|
||||
|
||||
// LOG_INFO(LogDev, "KillerWeaponDef: {}", KillerWeaponDef ? KillerWeaponDef->GetFullName() : "InvalidObject");
|
||||
|
||||
RemoveFromAlivePlayers(GameMode, PlayerController, KillerPlayerState == DeadPlayerState ? nullptr : KillerPlayerState, KillerPawn, KillerWeaponDef, DeathCause, 0);
|
||||
|
||||
LOG_INFO(LogDev, "Removed!");
|
||||
|
||||
if (Fortnite_Version < 6) // Spectating
|
||||
{
|
||||
static auto bAllowSpectateAfterDeathOffset = GameMode->GetOffset("bAllowSpectateAfterDeath");
|
||||
|
||||
bool bAllowSpectate = false; // GameMode->Get<bool>(bAllowSpectateAfterDeathOffset);
|
||||
|
||||
LOG_INFO(LogDev, "bAllowSpectate: {}", bAllowSpectate);
|
||||
|
||||
if (bAllowSpectate)
|
||||
{
|
||||
LOG_INFO(LogDev, "Starting Spectating!");
|
||||
|
||||
static auto PlayerToSpectateOnDeathOffset = PlayerController->GetOffset("PlayerToSpectateOnDeath");
|
||||
PlayerController->Get<APawn*>(PlayerToSpectateOnDeathOffset) = KillerPawn;
|
||||
|
||||
PlayerControllersDead.push_back(PlayerController);
|
||||
|
||||
/* if (numValidElements < PlayerControllersDead.size())
|
||||
if (DamageCauser->IsA(FortProjectileBaseClass))
|
||||
{
|
||||
PlayerControllersDead[numValidElements].store(PlayerController);
|
||||
numValidElements.fetch_add(1);
|
||||
} */
|
||||
|
||||
static bool bCreatedThread = false;
|
||||
|
||||
if (!bCreatedThread)
|
||||
LOG_INFO(LogDev, "From a projectile!");
|
||||
auto Owner = Cast<AFortWeapon>(DamageCauser->GetOwner());
|
||||
KillerWeaponDef = Owner->IsValidLowLevel() ? Owner->GetWeaponData() : nullptr; // I just added the IsValidLowLevel check because what if the weapon destroys?
|
||||
}
|
||||
if (auto Weapon = Cast<AFortWeapon>(DamageCauser))
|
||||
{
|
||||
bCreatedThread = true;
|
||||
LOG_INFO(LogDev, "From a weapon!");
|
||||
KillerWeaponDef = Weapon->GetWeaponData();
|
||||
}
|
||||
}
|
||||
|
||||
CreateThread(0, 0, SpectateThread, 0, 0, 0);
|
||||
// LOG_INFO(LogDev, "KillerWeaponDef: {}", KillerWeaponDef ? KillerWeaponDef->GetFullName() : "InvalidObject");
|
||||
|
||||
RemoveFromAlivePlayers(GameMode, PlayerController, KillerPlayerState == DeadPlayerState ? nullptr : KillerPlayerState, KillerPawn, KillerWeaponDef, DeathCause, 0);
|
||||
|
||||
LOG_INFO(LogDev, "Removed!");
|
||||
|
||||
if (Fortnite_Version < 6) // Spectating
|
||||
{
|
||||
static auto bAllowSpectateAfterDeathOffset = GameMode->GetOffset("bAllowSpectateAfterDeath");
|
||||
|
||||
bool bAllowSpectate = false; // GameMode->Get<bool>(bAllowSpectateAfterDeathOffset);
|
||||
|
||||
LOG_INFO(LogDev, "bAllowSpectate: {}", bAllowSpectate);
|
||||
|
||||
if (bAllowSpectate)
|
||||
{
|
||||
LOG_INFO(LogDev, "Starting Spectating!");
|
||||
|
||||
static auto PlayerToSpectateOnDeathOffset = PlayerController->GetOffset("PlayerToSpectateOnDeath");
|
||||
PlayerController->Get<APawn*>(PlayerToSpectateOnDeathOffset) = KillerPawn;
|
||||
|
||||
PlayerControllersDead.push_back(PlayerController);
|
||||
|
||||
/* if (numValidElements < PlayerControllersDead.size())
|
||||
{
|
||||
PlayerControllersDead[numValidElements].store(PlayerController);
|
||||
numValidElements.fetch_add(1);
|
||||
} */
|
||||
|
||||
static bool bCreatedThread = false;
|
||||
|
||||
if (!bCreatedThread)
|
||||
{
|
||||
bCreatedThread = true;
|
||||
|
||||
CreateThread(0, 0, SpectateThread, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ public:
|
||||
|
||||
bool HasTryPickupSwap()
|
||||
{
|
||||
static auto bTryPickupSwapOffset = GetOffset("bTryPickupSwap");
|
||||
static auto bTryPickupSwapOffset = GetOffset("bTryPickupSwap", false);
|
||||
return bTryPickupSwapOffset != -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "hooking.h"
|
||||
#include "FortAthenaMutator_GiveItemsAtGamePhaseStep.h"
|
||||
#include "DataTableFunctionLibrary.h"
|
||||
#include "FortAthenaMutator_InventoryOverride.h"
|
||||
|
||||
void AFortPlayerControllerAthena::StartGhostModeHook(UObject* Context, FFrame* Stack, void* Ret)
|
||||
{
|
||||
@@ -135,20 +136,15 @@ void AFortPlayerControllerAthena::EnterAircraftHook(UObject* PC, AActor* Aircraf
|
||||
|
||||
std::vector<std::pair<AFortAthenaMutator*, UFunction*>> FunctionsToCall;
|
||||
|
||||
for (int i = 0; i < AllMutators.Num(); i++)
|
||||
{
|
||||
auto Mutator = (AFortAthenaMutator*)AllMutators.at(i);
|
||||
|
||||
LOG_INFO(LogDev, "[{}] Mutator: {}", i, Mutator->GetFullName());
|
||||
|
||||
FunctionsToCall.push_back(std::make_pair(Mutator, Mutator->FindFunction("OnGamePhaseStepChanged")));
|
||||
LoopMutators([&](AFortAthenaMutator* Mutator) { FunctionsToCall.push_back(std::make_pair(Mutator, Mutator->FindFunction("OnGamePhaseStepChanged"))); });
|
||||
|
||||
auto HandleGiveItemsAtGamePhaseStepMutator = [&](AFortAthenaMutator* Mutator) {
|
||||
if (auto GiveItemsAtGamePhaseStepMutator = Cast<AFortAthenaMutator_GiveItemsAtGamePhaseStep>(Mutator))
|
||||
{
|
||||
auto PhaseToGive = GiveItemsAtGamePhaseStepMutator->GetPhaseToGiveItems();
|
||||
auto& ItemsToGive = GiveItemsAtGamePhaseStepMutator->GetItemsToGive();
|
||||
|
||||
LOG_INFO(LogDev, "[{}] PhaseToGiveItems: {} ItemsToGive.Num(): {}", i, (int)PhaseToGive, ItemsToGive.Num());
|
||||
// LOG_INFO(LogDev, "[{}] PhaseToGiveItems: {} ItemsToGive.Num(): {}", i, (int)PhaseToGive, ItemsToGive.Num());
|
||||
|
||||
if (PhaseToGive <= 5) // Flying or lower
|
||||
{
|
||||
@@ -166,27 +162,54 @@ void AFortPlayerControllerAthena::EnterAircraftHook(UObject* PC, AActor* Aircraf
|
||||
Out2 = UDataTableFunctionLibrary::EvaluateCurveTableRow(ItemToGive->GetNumberToGive().GetCurve().CurveTable, ItemToGive->GetNumberToGive().GetCurve().RowName, 0.f);
|
||||
}
|
||||
|
||||
LOG_INFO(LogDev, "[{}] [{}] Out2: {} ItemToGive.ItemToDrop: {}", i, j, Out2, ItemToGive->GetItemToDrop()->IsValidLowLevel() ? ItemToGive->GetItemToDrop()->GetFullName() : "BadRead");
|
||||
LOG_INFO(LogDev, "[{}] Out2: {} ItemToGive.ItemToDrop: {}", j, Out2, ItemToGive->GetItemToDrop()->IsValidLowLevel() ? ItemToGive->GetItemToDrop()->GetFullName() : "BadRead");
|
||||
|
||||
if (!Out2)
|
||||
if (!Out2) // ?
|
||||
continue;
|
||||
|
||||
WorldInventory->AddItem(ItemToGive->GetItemToDrop(), nullptr, Out2);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* else if (auto GGMutator = Cast<AFortAthenaMutator_GG>(Mutator))
|
||||
};
|
||||
|
||||
LoopMutators(HandleGiveItemsAtGamePhaseStepMutator);
|
||||
|
||||
/* if (auto GGMutator = Cast<AFortAthenaMutator_GG>(Mutator))
|
||||
{
|
||||
auto& WeaponEntries = GGMutator->GetWeaponEntries();
|
||||
|
||||
LOG_INFO(LogDev, "[{}] WeaponEntries.Num(): {}", i, WeaponEntries.Num());
|
||||
|
||||
for (int j = 0; j < WeaponEntries.Num(); j++)
|
||||
{
|
||||
auto& WeaponEntries = GGMutator->GetWeaponEntries();
|
||||
WorldInventory->AddItem(WeaponEntries.at(j).Weapon, nullptr, 1);
|
||||
}
|
||||
} */
|
||||
|
||||
LOG_INFO(LogDev, "[{}] WeaponEntries.Num(): {}", i, WeaponEntries.Num());
|
||||
auto PlayerStateAthena = Cast<AFortPlayerStateAthena>(PlayerController->GetPlayerState());
|
||||
|
||||
for (int j = 0; j < WeaponEntries.Num(); j++)
|
||||
auto AddInventoryOverrideTeamLoadouts = [&](AFortAthenaMutator* Mutator)
|
||||
{
|
||||
if (auto InventoryOverride = Cast<AFortAthenaMutator_InventoryOverride>(Mutator))
|
||||
{
|
||||
auto TeamIndex = PlayerStateAthena->GetTeamIndex();
|
||||
auto LoadoutTeam = InventoryOverride->GetLoadoutTeamForTeamIndex(TeamIndex);
|
||||
|
||||
if (LoadoutTeam.UpdateOverrideType == EAthenaInventorySpawnOverride::AircraftPhaseOnly)
|
||||
{
|
||||
WorldInventory->AddItem(WeaponEntries.at(j).Weapon, nullptr, 1);
|
||||
auto LoadoutContainer = InventoryOverride->GetLoadoutContainerForTeamIndex(TeamIndex);
|
||||
|
||||
for (int i = 0; i < LoadoutContainer.Loadout.Num(); i++)
|
||||
{
|
||||
auto& ItemAndCount = LoadoutContainer.Loadout.at(i);
|
||||
WorldInventory->AddItem(ItemAndCount.GetItem(), nullptr, ItemAndCount.GetCount());
|
||||
}
|
||||
}
|
||||
} */
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
LoopMutators(AddInventoryOverrideTeamLoadouts);
|
||||
|
||||
static int LastNum1 = 3125;
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "BuildingActor.h"
|
||||
#include "FortPlayerPawnAthena.h"
|
||||
#include "GameplayAbilityTypes.h"
|
||||
|
||||
struct FGameplayTagRequirements
|
||||
{
|
||||
@@ -236,6 +237,41 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct FAthenaScoreData
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
struct FWinConditionScoreData
|
||||
{
|
||||
static UStruct* GetStruct()
|
||||
{
|
||||
static auto Struct = FindObject<UStruct>("/Script/FortniteGame.WinConditionScoreData");
|
||||
return Struct;
|
||||
}
|
||||
|
||||
static int GetStructSize() { return GetStruct()->GetPropertiesSize(); }
|
||||
|
||||
FScalableFloat* GetGoalScore()
|
||||
{
|
||||
static auto GoalScoreOffset = FindOffsetStruct("/Script/FortniteGame.WinConditionScoreData", "GoalScore");
|
||||
return (FScalableFloat*)(__int64(this) + GoalScoreOffset);
|
||||
}
|
||||
|
||||
FScalableFloat* GetBigScoreThreshold()
|
||||
{
|
||||
static auto BigScoreThresholdOffset = FindOffsetStruct("/Script/FortniteGame.WinConditionScoreData", "BigScoreThreshold");
|
||||
return (FScalableFloat*)(__int64(this) + BigScoreThresholdOffset);
|
||||
}
|
||||
|
||||
TArray<FAthenaScoreData>& GetScoreDataList()
|
||||
{
|
||||
static auto ScoreDataListOffset = FindOffsetStruct("/Script/FortniteGame.WinConditionScoreData", "ScoreDataList");
|
||||
return *(TArray<FAthenaScoreData>*)(__int64(this) + ScoreDataListOffset);
|
||||
}
|
||||
};
|
||||
|
||||
class UFortPlaylist : public UObject
|
||||
{
|
||||
public:
|
||||
@@ -245,6 +281,12 @@ public:
|
||||
return this->Get<TArray<TSoftObjectPtr<UFortGameplayModifierItemDefinition>>>(ModifierListOffset);
|
||||
}
|
||||
|
||||
FWinConditionScoreData* GetScoringData()
|
||||
{
|
||||
static auto ScoringDataOffset = GetOffset("ScoringData");
|
||||
return GetPtr<FWinConditionScoreData>(ScoringDataOffset);
|
||||
}
|
||||
|
||||
void ApplyModifiersToActor(AActor* Actor)
|
||||
{
|
||||
if (!Actor)
|
||||
|
||||
@@ -107,20 +107,16 @@ APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AControll
|
||||
auto PickaxeDefinition = CosmeticLoadoutPickaxe ? CosmeticLoadoutPickaxe->Get<UFortItemDefinition*>(WeaponDefinitionOffset)
|
||||
: FindObject<UFortItemDefinition>(L"/Game/Athena/Items/Weapons/WID_Harvest_Pickaxe_Athena_C_T01.WID_Harvest_Pickaxe_Athena_C_T01");
|
||||
|
||||
static UFortItemDefinition* EditToolItemDefinition = FindObject<UFortItemDefinition>(L"/Game/Items/Weapons/BuildingTools/EditTool.EditTool");
|
||||
static UFortItemDefinition* BuildingItemData_Wall = FindObject<UFortItemDefinition>(L"/Game/Items/Weapons/BuildingTools/BuildingItemData_Wall.BuildingItemData_Wall");
|
||||
static UFortItemDefinition* BuildingItemData_Floor = FindObject<UFortItemDefinition>(L"/Game/Items/Weapons/BuildingTools/BuildingItemData_Floor.BuildingItemData_Floor");
|
||||
static UFortItemDefinition* BuildingItemData_Stair_W = FindObject<UFortItemDefinition>(L"/Game/Items/Weapons/BuildingTools/BuildingItemData_Stair_W.BuildingItemData_Stair_W");
|
||||
static UFortItemDefinition* BuildingItemData_RoofS = FindObject<UFortItemDefinition>(L"/Game/Items/Weapons/BuildingTools/BuildingItemData_RoofS.BuildingItemData_RoofS");
|
||||
static UFortItemDefinition* WoodItemData = FindObject<UFortItemDefinition>(L"/Game/Items/ResourcePickups/WoodItemData.WoodItemData");
|
||||
static UFortItemDefinition* DamageTrap = FindObject<UFortItemDefinition>(L"/Game/Athena/Items/Traps/TID_ContextTrap_Athena.TID_ContextTrap_Athena");
|
||||
auto& StartingItems = ((AFortGameModeAthena*)GameMode)->GetStartingItems();
|
||||
|
||||
WorldInventory->AddItem(PickaxeDefinition, nullptr);
|
||||
WorldInventory->AddItem(EditToolItemDefinition, nullptr);
|
||||
WorldInventory->AddItem(BuildingItemData_Wall, nullptr);
|
||||
WorldInventory->AddItem(BuildingItemData_Floor, nullptr);
|
||||
WorldInventory->AddItem(BuildingItemData_Stair_W, nullptr);
|
||||
WorldInventory->AddItem(BuildingItemData_RoofS, nullptr);
|
||||
|
||||
for (int i = 0; i < StartingItems.Num(); i++)
|
||||
{
|
||||
auto& StartingItem = StartingItems.at(i);
|
||||
|
||||
WorldInventory->AddItem(StartingItem.GetItem(), nullptr, StartingItem.GetCount());
|
||||
}
|
||||
|
||||
/* if (Globals::bLateGame)
|
||||
{
|
||||
@@ -142,12 +138,17 @@ APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AControll
|
||||
if (auto InventoryOverride = Cast<AFortAthenaMutator_InventoryOverride>(Mutator))
|
||||
{
|
||||
auto TeamIndex = PlayerStateAthena->GetTeamIndex();
|
||||
auto LoadoutContainer = InventoryOverride->GetLoadoutContainerForTeamIndex(TeamIndex);
|
||||
auto LoadoutTeam = InventoryOverride->GetLoadoutTeamForTeamIndex(TeamIndex);
|
||||
|
||||
for (int i = 0; i < LoadoutContainer.Loadout.Num(); i++)
|
||||
if (LoadoutTeam.UpdateOverrideType == EAthenaInventorySpawnOverride::Always)
|
||||
{
|
||||
auto& ItemAndCount = LoadoutContainer.Loadout.at(i);
|
||||
WorldInventory->AddItem(ItemAndCount.GetItem(), nullptr, ItemAndCount.GetCount());
|
||||
auto LoadoutContainer = InventoryOverride->GetLoadoutContainerForTeamIndex(TeamIndex);
|
||||
|
||||
for (int i = 0; i < LoadoutContainer.Loadout.Num(); i++)
|
||||
{
|
||||
auto& ItemAndCount = LoadoutContainer.Loadout.at(i);
|
||||
WorldInventory->AddItem(ItemAndCount.GetItem(), nullptr, ItemAndCount.GetCount());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -74,6 +74,43 @@ void UGameplayStatics::RemovePlayer(APlayerController* Player, bool bDestroyPawn
|
||||
defaultObj->ProcessEvent(fn, &UGameplayStatics_RemovePlayer_Params);
|
||||
}
|
||||
|
||||
AActor* UGameplayStatics::BeginDeferredActorSpawnFromClass(const UObject* WorldContextObject, UClass* ActorClass, const FTransform& SpawnTransform, ESpawnActorCollisionHandlingMethod CollisionHandlingOverride, AActor* Owner)
|
||||
{
|
||||
static auto fn = FindObject<UFunction>("/Script/Engine.GameplayStatics.BeginDeferredActorSpawnFromClass");
|
||||
|
||||
struct
|
||||
{
|
||||
const UObject* WorldContextObject; // (ConstParm, Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
UClass* ActorClass; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, UObjectWrapper, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
FTransform SpawnTransform; // (ConstParm, Parm, OutParm, ReferenceParm, IsPlainOldData, NoDestructor, NativeAccessSpecifierPublic)
|
||||
ESpawnActorCollisionHandlingMethod CollisionHandlingOverride; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
AActor* Owner; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
AActor* ReturnValue; // (Parm, OutParm, ZeroConstructor, ReturnParm, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
} UGameplayStatics_BeginDeferredActorSpawnFromClass_Params{ WorldContextObject, ActorClass, SpawnTransform, CollisionHandlingOverride, Owner };
|
||||
|
||||
static auto defaultObj = StaticClass();
|
||||
defaultObj->ProcessEvent(fn, &UGameplayStatics_BeginDeferredActorSpawnFromClass_Params);
|
||||
|
||||
return UGameplayStatics_BeginDeferredActorSpawnFromClass_Params.ReturnValue;
|
||||
}
|
||||
|
||||
AActor* UGameplayStatics::FinishSpawningActor(AActor* Actor, const FTransform& SpawnTransform)
|
||||
{
|
||||
static auto FinishSpawningActorFn = FindObject<UFunction>("/Script/Engine.GameplayStatics.FinishSpawningActor");
|
||||
|
||||
struct
|
||||
{
|
||||
AActor* Actor; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
FTransform SpawnTransform; // (ConstParm, Parm, OutParm, ReferenceParm, IsPlainOldData, NoDestructor, NativeAccessSpecifierPublic)
|
||||
AActor* ReturnValue; // (Parm, OutParm, ZeroConstructor, ReturnParm, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
} UGameplayStatics_FinishSpawningActor_Params{ Actor, SpawnTransform };
|
||||
|
||||
static auto defaultObj = StaticClass();
|
||||
defaultObj->ProcessEvent(FinishSpawningActorFn, &UGameplayStatics_FinishSpawningActor_Params);
|
||||
|
||||
return UGameplayStatics_FinishSpawningActor_Params.ReturnValue;
|
||||
}
|
||||
|
||||
void UGameplayStatics::LoadStreamLevel(UObject* WorldContextObject, FName LevelName, bool bMakeVisibleAfterLoad, bool bShouldBlockOnLoad, const FLatentActionInfo& LatentInfo)
|
||||
{
|
||||
static auto LoadStreamLevelFn = FindObject<UFunction>("/Script/Engine.GameplayStatics.LoadStreamLevel");
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "Array.h"
|
||||
#include "Actor.h"
|
||||
#include "LatentActionManager.h"
|
||||
#include "EngineTypes.h"
|
||||
|
||||
class UGameplayStatics : public UObject
|
||||
{
|
||||
@@ -22,6 +23,8 @@ public:
|
||||
|
||||
// static void OpenLevel(UObject* WorldContextObject, FName LevelName, bool bAbsolute, const FString& Options);
|
||||
static void RemovePlayer(class APlayerController* Player, bool bDestroyPawn);
|
||||
static AActor* FinishSpawningActor(AActor* Actor, const FTransform& SpawnTransform);
|
||||
static AActor* BeginDeferredActorSpawnFromClass(const UObject* WorldContextObject, UClass* ActorClass, const FTransform& SpawnTransform, ESpawnActorCollisionHandlingMethod CollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::Undefined, AActor* Owner = nullptr);
|
||||
static void LoadStreamLevel(UObject* WorldContextObject, FName LevelName, bool bMakeVisibleAfterLoad, bool bShouldBlockOnLoad, const FLatentActionInfo& LatentInfo);
|
||||
static void UnloadStreamLevel(UObject* WorldContextObject, FName LevelName, const FLatentActionInfo& LatentInfo, bool bShouldBlockOnUnload);
|
||||
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
<ClCompile Include="addresses.cpp" />
|
||||
<ClCompile Include="AthenaMarkerComponent.cpp" />
|
||||
<ClCompile Include="BuildingActor.cpp" />
|
||||
<ClCompile Include="BuildingContainer.cpp" />
|
||||
<ClCompile Include="BuildingFoundation.cpp" />
|
||||
<ClCompile Include="BuildingSMActor.cpp" />
|
||||
<ClCompile Include="BuildingStructuralSupportSystem.cpp" />
|
||||
@@ -313,6 +314,8 @@
|
||||
<ClInclude Include="FortAthenaMutator_InventoryOverride.h" />
|
||||
<ClInclude Include="FortAthenaMutator_InventoryOverride_Bucket.h" />
|
||||
<ClInclude Include="FortAthenaMutator_ItemDropOnDeath.h" />
|
||||
<ClInclude Include="FortAthenaMutator_LoadoutSwap.h" />
|
||||
<ClInclude Include="FortAthenaMutator_TDM.h" />
|
||||
<ClInclude Include="FortAthenaSKPushCannon.h" />
|
||||
<ClInclude Include="FortAthenaSupplyDrop.h" />
|
||||
<ClInclude Include="FortAthenaVehicle.h" />
|
||||
|
||||
@@ -262,6 +262,9 @@
|
||||
<ClCompile Include="FortAthenaVehicleSpawner.cpp">
|
||||
<Filter>FortniteGame\Source\FortniteGame\Private\Vehicles</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BuildingContainer.cpp">
|
||||
<Filter>FortniteGame\Source\FortniteGame\Private\Building</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="log.h" />
|
||||
@@ -832,6 +835,12 @@
|
||||
<ClInclude Include="FortAthenaVehicleSpawner.h">
|
||||
<Filter>FortniteGame\Source\FortniteGame\Public\Athena\Vehicle</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FortAthenaMutator_TDM.h">
|
||||
<Filter>FortniteGame\Source\FortniteGame\Public\Mutators</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FortAthenaMutator_LoadoutSwap.h">
|
||||
<Filter>FortniteGame\Source\FortniteGame\Public\Mutators</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Engine">
|
||||
|
||||
@@ -279,9 +279,6 @@ void Addresses::FindAll()
|
||||
LOG_INFO(LogDev, "Finding FreeArrayOfEntries");
|
||||
Addresses::FreeArrayOfEntries = FindFreeArrayOfEntries();
|
||||
|
||||
LOG_INFO(LogDev, "Finding ApplyHomebaseEffectsOnPlayerSetup");
|
||||
Addresses::FreeArrayOfEntries = FindApplyHomebaseEffectsOnPlayerSetup();
|
||||
|
||||
LOG_INFO(LogDev, "Finished finding!");
|
||||
}
|
||||
|
||||
@@ -344,7 +341,6 @@ void Addresses::Print()
|
||||
LOG_INFO(LogDev, "EnterAircraft: 0x{:x}", EnterAircraft - Base);
|
||||
LOG_INFO(LogDev, "SetTimer: 0x{:x}", SetTimer - Base);
|
||||
LOG_INFO(LogDev, "PickupInitialize: 0x{:x}", PickupInitialize - Base);
|
||||
LOG_INFO(LogDev, "ApplyHomebaseEffectsOnPlayerSetup: 0x{:x}", ApplyHomebaseEffectsOnPlayerSetup - Base);
|
||||
}
|
||||
|
||||
void Offsets::FindAll()
|
||||
|
||||
@@ -65,7 +65,6 @@ namespace Addresses
|
||||
extern inline uint64 PickupInitialize = 0;
|
||||
extern inline uint64 FreeEntry = 0;
|
||||
extern inline uint64 FreeArrayOfEntries = 0;
|
||||
extern inline uint64 ApplyHomebaseEffectsOnPlayerSetup = 0;
|
||||
|
||||
void SetupVersion(); // Finds Engine Version
|
||||
void FindAll();
|
||||
|
||||
@@ -314,7 +314,8 @@ void ProcessEventHook(UObject* Object, UFunction* Function, void* Parameters)
|
||||
!strstr(FunctionFullName.c_str(), "Primitive_Structure_AmbAudioComponent") &&
|
||||
!strstr(FunctionName.c_str(), "ServerTriggerCombatEvent") &&
|
||||
!strstr(FunctionName.c_str(), "SpinCubeTimeline__UpdateFunc") &&
|
||||
!strstr(ObjectName.c_str(), "FortPhysicsObjectComponent"))
|
||||
!strstr(ObjectName.c_str(), "FortPhysicsObjectComponent") &&
|
||||
!strstr(FunctionName.c_str(), "GetTextValue"))
|
||||
{
|
||||
LOG_INFO(LogDev, "Function called: {} with {}", FunctionFullName, ObjectName);
|
||||
}
|
||||
|
||||
@@ -720,7 +720,7 @@ DWORD WINAPI Main(LPVOID)
|
||||
|
||||
uint64 ServerRemoveInventoryItemFunctionCallBeginFunctionAddr = 0;
|
||||
|
||||
if (Engine_Version >= 419) // Dude idk why but its getting the second ref kms
|
||||
// if (Engine_Version >= 419)
|
||||
{
|
||||
std::vector<uint8_t> ServerRemoveInventoryItemCallFunctionStarts = Engine_Version == 416
|
||||
? std::vector<uint8_t>{ 0x44, 0x88, 0x4C }
|
||||
@@ -729,14 +729,13 @@ DWORD WINAPI Main(LPVOID)
|
||||
: std::vector<uint8_t>{ 0x48, 0x89, 0x5C };
|
||||
|
||||
auto ServerRemoveInventoryItemCallFunctionCall = FindFunctionCall(L"ServerRemoveInventoryItem", ServerRemoveInventoryItemCallFunctionStarts);
|
||||
auto ServerRemoveInventoryItemFunctionCallRef = Memcury::Scanner::FindPointerRef((PVOID)ServerRemoveInventoryItemCallFunctionCall, true);
|
||||
auto ServerRemoveInventoryItemFunctionCallRef = Memcury::Scanner::FindPointerRef((PVOID)ServerRemoveInventoryItemCallFunctionCall, 0, true);
|
||||
|
||||
LOG_INFO(LogDev, "ServerRemoveInventoryItemFunctionCallRef: 0x{:x}", ServerRemoveInventoryItemFunctionCallRef.Get() - __int64(GetModuleHandleW(0)));
|
||||
|
||||
uint64 ServerRemoveInventoryItemFunctionCallBeginFunctionAddr = 0;
|
||||
|
||||
for (int i = 0; i < 400; i++)
|
||||
{
|
||||
// LOG_INFO(LogDev, "[{}] Bugha: 0x{:x}", i, (int)(*(uint8_t*)ServerRemoveInventoryItemFunctionCallRef.Get() - i));
|
||||
if (*(uint8_t*)(uint8_t*)(ServerRemoveInventoryItemFunctionCallRef.Get() - i) == 0x48 && *(uint8_t*)(uint8_t*)(ServerRemoveInventoryItemFunctionCallRef.Get() - i + 1) == 0x89 && *(uint8_t*)(uint8_t*)(ServerRemoveInventoryItemFunctionCallRef.Get() - i + 2) == 0x5C)
|
||||
{
|
||||
ServerRemoveInventoryItemFunctionCallBeginFunctionAddr = ServerRemoveInventoryItemFunctionCallRef.Get() - i;
|
||||
@@ -750,10 +749,6 @@ DWORD WINAPI Main(LPVOID)
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Hooking::MinHook::Hook(Memcury::Scanner(ServerRemoveInventoryItemFunctionCallBeginFunctionAddr).GetAs<PVOID>(), UFortInventoryInterface::RemoveInventoryItemHook);
|
||||
|
||||
@@ -767,11 +762,12 @@ DWORD WINAPI Main(LPVOID)
|
||||
|
||||
AddVehicleHook();
|
||||
|
||||
if (Fortnite_Version > 1.8 || Fortnite_Version == 1.11)
|
||||
// if (Fortnite_Version > 1.8 || Fortnite_Version == 1.11)
|
||||
{
|
||||
auto ClientOnPawnDiedCallAddr = FindFunctionCall(L"ClientOnPawnDied", Engine_Version == 416 ? std::vector<uint8_t>{ 0x48, 0x89, 0x54 } : std::vector<uint8_t>{ 0x48, 0x89, 0x5C });
|
||||
LOG_INFO(LogDev, "ahh!");
|
||||
LOG_INFO(LogDev, "Test: 0x{:x}", FindFunctionCall(L"ClientOnPawnDied") - __int64(GetModuleHandleW(0)));
|
||||
Hooking::MinHook::Hook((PVOID)FindFunctionCall(L"ClientOnPawnDied"), AFortPlayerController::ClientOnPawnDiedHook, (PVOID*)&AFortPlayerController::ClientOnPawnDiedOriginal);
|
||||
LOG_INFO(LogDev, "ClientOnPawnDiedCallAddr: 0x{:x}", ClientOnPawnDiedCallAddr - __int64(GetModuleHandleW(0)));
|
||||
Hooking::MinHook::Hook((PVOID)ClientOnPawnDiedCallAddr, AFortPlayerController::ClientOnPawnDiedHook, (PVOID*)&AFortPlayerController::ClientOnPawnDiedOriginal);
|
||||
}
|
||||
|
||||
LOG_INFO(LogDev, "PredictionKeySize: 0x{:x} {}", PredictionKeySize, PredictionKeySize);
|
||||
@@ -793,8 +789,8 @@ DWORD WINAPI Main(LPVOID)
|
||||
MemberOffsets::FortPlayerPawnAthena::LastFallDistance = FindOffsetStruct("/Script/FortniteGame.FortPlayerPawnAthena", "LastFallDistance", false);
|
||||
|
||||
MemberOffsets::FortPlayerStateAthena::DeathInfo = FindOffsetStruct("/Script/FortniteGame.FortPlayerStateAthena", "DeathInfo");
|
||||
MemberOffsets::FortPlayerStateAthena::KillScore = FindOffsetStruct("/Script/FortniteGame.FortPlayerStateAthena", "KillScore");
|
||||
MemberOffsets::FortPlayerStateAthena::TeamKillScore = FindOffsetStruct("/Script/FortniteGame.FortPlayerStateAthena", "TeamKillScore");
|
||||
MemberOffsets::FortPlayerStateAthena::KillScore = FindOffsetStruct("/Script/FortniteGame.FortPlayerStateAthena", "KillScore", false);
|
||||
MemberOffsets::FortPlayerStateAthena::TeamKillScore = FindOffsetStruct("/Script/FortniteGame.FortPlayerStateAthena", "TeamKillScore", false);
|
||||
|
||||
MemberOffsets::DeathInfo::bDBNO = FindOffsetStruct("/Script/FortniteGame.DeathInfo", "bDBNO");
|
||||
MemberOffsets::DeathInfo::DeathCause = FindOffsetStruct("/Script/FortniteGame.DeathInfo", "DeathCause");
|
||||
|
||||
@@ -414,11 +414,6 @@ static inline uint64 FindIsNetRelevantForOffset()
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline uint64 FindApplyHomebaseEffectsOnPlayerSetup()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline uint64 FindActorChannelClose()
|
||||
{
|
||||
auto StringRef = Memcury::Scanner::FindStringRef(L"UActorChannel::Close: ChIndex: %d, Actor: %s");
|
||||
@@ -1450,7 +1445,14 @@ static inline uint64 FindCanActivateAbility()
|
||||
static inline uint64 FindGiveAbilityAndActivateOnce()
|
||||
{
|
||||
if (Engine_Version == 426)
|
||||
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 40 49 8B 40 10 49 8B D8 48 8B FA 48 8B F1").Get();
|
||||
{
|
||||
auto sig1 = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 40 49 8B 40 10 49 8B D8 48 8B FA 48 8B F1", false).Get();
|
||||
|
||||
if (!sig1)
|
||||
sig1 = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 40 49 8B 40 10 49").Get(); // 15.50
|
||||
|
||||
return sig1;
|
||||
}
|
||||
|
||||
auto Addrr = Memcury::Scanner::FindStringRef(L"GiveAbilityAndActivateOnce called on ability %s on the client, not allowed!", true, 0, Engine_Version >= 500).Get();
|
||||
|
||||
@@ -1602,6 +1604,9 @@ static inline uint64 FindClearAbility()
|
||||
{
|
||||
auto GiveAbilityAndActivateOnce = FindGiveAbilityAndActivateOnce();
|
||||
|
||||
if (!GiveAbilityAndActivateOnce)
|
||||
return 0;
|
||||
|
||||
return Memcury::Scanner(GiveAbilityAndActivateOnce).ScanFor({ 0xE8 }, true, 4).RelativeOffset(1).Get();
|
||||
|
||||
if (Engine_Version == 416)
|
||||
|
||||
@@ -843,9 +843,12 @@ static inline void MainUI()
|
||||
else if (Tab == DEVELOPER_TAB)
|
||||
{
|
||||
static std::string ClassNameToDump;
|
||||
static std::string FunctionNameToDump;
|
||||
|
||||
ImGui::InputText("Class Name to mess with", &ClassNameToDump);
|
||||
|
||||
ImGui::InputText("Function Name to mess with", &FunctionNameToDump);
|
||||
|
||||
if (ImGui::Button("Print Class VFT"))
|
||||
{
|
||||
auto Class = FindObject<UClass>(ClassNameToDump);
|
||||
@@ -861,6 +864,16 @@ static inline void MainUI()
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::Button("Print Function Exec Addy"))
|
||||
{
|
||||
auto Function = FindObject<UFunction>(FunctionNameToDump);
|
||||
|
||||
if (Function)
|
||||
{
|
||||
LOG_INFO(LogDev, "{} Exec: 0x{:x}", Function->GetName(), __int64(Function->GetFunc()) - __int64(GetModuleHandleW(0)));
|
||||
}
|
||||
}
|
||||
|
||||
/* if (ImGui::Button("Load BGA Class (and spawn so no GC)"))
|
||||
{
|
||||
static auto BGAClass = FindObject<UClass>("/Script/Engine.BlueprintGeneratedClass");
|
||||
|
||||
@@ -54,5 +54,5 @@ inline bool AreVehicleWeaponsEnabled()
|
||||
|
||||
inline bool IsRestartingSupported()
|
||||
{
|
||||
return Engine_Version < 424;
|
||||
return Engine_Version >= 419 && Engine_Version < 424;
|
||||
}
|
||||
Reference in New Issue
Block a user