fixed looting

This commit is contained in:
Milxnor
2023-06-28 11:58:20 -04:00
parent feea0e20f3
commit 26abeab332
14 changed files with 244 additions and 161 deletions

View File

@@ -175,6 +175,19 @@ void AFortGameModeAthena::HandleSpawnRateForActorClass(UClass* ActorClass, float
}
}
void AFortGameModeAthena::StartAircraftPhase()
{
if (Addresses::StartAircraftPhase)
{
static void (*StartAircraftPhaseOriginal)(AFortGameModeAthena*, bool bDoNotSpawnAircraft) = decltype(StartAircraftPhaseOriginal)(Addresses::StartAircraftPhase);
StartAircraftPhaseOriginal(this, false); // love the double negative fortnite
}
else
{
UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"startaircraft", nullptr);
}
}
void AFortGameModeAthena::PauseSafeZone(bool bPaused)
{
auto GameState = GetGameStateAthena();

View File

@@ -263,6 +263,7 @@ public:
UClass* GetVehicleClassOverride(UClass* DefaultClass);
void SkipAircraft();
void PauseSafeZone(bool bPaused = true);
void StartAircraftPhase();
static void HandleSpawnRateForActorClass(UClass* ActorClass, float SpawnPercentage); // idk where to put

View File

@@ -249,7 +249,7 @@ std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AFortInventory::AddI
return Ret;
}
bool AFortInventory::RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int Count, bool bForceRemoval)
bool AFortInventory::RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int Count, bool bForceRemoval, bool bIgnoreVariables)
{
if (bShouldUpdate)
*bShouldUpdate = false;
@@ -280,7 +280,7 @@ bool AFortInventory::RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int
bool bOverrideChangeStackSize = false;
if (ItemDefinition->ShouldPersistWhenFinalStackEmpty())
if (!bIgnoreVariables && ItemDefinition->ShouldPersistWhenFinalStackEmpty())
{
bool bIsFinalStack = true;

View File

@@ -101,7 +101,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(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, bool bIgnoreVariables = 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);

View File

@@ -121,11 +121,11 @@ float GetAmountOfLootPackagesToDrop(FFortLootTierData* LootTierData, int Origina
{
// HONESTLY IDEK WHAT FORTNITE DOES HERE
float v29 = (float)rand() * 0.000030518509;
float v29 = (float)rand() * 0.000030518509f;
float v35 = (int)(float)((float)((float)((float)SumLootPackageCategoryWeightArray * v29)
+ (float)((float)SumLootPackageCategoryWeightArray * v29))
+ 0.5) >> 1;
+ 0.5f) >> 1;
// OutLootTierInfo->Hello++;
MinimumLootDrops++;
@@ -153,27 +153,30 @@ float GetAmountOfLootPackagesToDrop(FFortLootTierData* LootTierData, int Origina
FFortLootTierData* PickLootTierData(const std::vector<UDataTable*>& LTDTables, FName LootTierGroup, int ForcedLootTier = -1, FName* OutRowName = nullptr) // Fortnite returns the row name and then finds the tier data again, but I really don't see the point of this.
{
// This like isn't right, at all.
float LootTier = ForcedLootTier;
float IdkForcedWeightorsomething = -1;
if (LootTier == -1)
{
// IdkForcedWeightorsomething = weightofAlltherowsithink // we don't ened to do this since the pickweightedeleent already does that
// LootTier = ??
}
else
{
// ITS SO MUCH TO REVERSE AAAAA
// buncha code im too lazy to reverse
}
// if (fabs(LootTier) <= 0.0000000099999999)
// if (fabs(LootTier) <= 0.0000000099999999f)
// return 0;
int Multiplier = LootTier == -1 ? 1 : LootTier; // Idk i think we need to fill out the code above for this to work properly maybe
LOOTING_MAP_TYPE<FName, FFortLootTierData*> TierGroupLTDs;
CollectDataTablesRows<FFortLootTierData>(LTDTables, &TierGroupLTDs, [&](FName RowName, FFortLootTierData* TierData) -> bool {
if (LootTierGroup == TierData->GetTierGroup())
{
if ((LootTier == -1 ? true : LootTier == TierData->GetLootTier())) // idek if this is proper
if ((LootTier == -1 ? true : LootTier == TierData->GetLootTier()))
{
return true;
}
@@ -186,20 +189,18 @@ FFortLootTierData* PickLootTierData(const std::vector<UDataTable*>& LTDTables, F
FFortLootTierData* ChosenRowLootTierData = PickWeightedElement<FName, FFortLootTierData*>(TierGroupLTDs,
[](FFortLootTierData* LootTierData) -> float { return LootTierData->GetWeight(); }, RandomFloatForLoot, -1,
true, 1, OutRowName, false, false, IdkForcedWeightorsomething);
true, Multiplier, OutRowName);
return ChosenRowLootTierData;
}
void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, FName LootPackageName, std::vector<LootDrop>* OutEntries, int LootPackageCategory = -1, int WorldLevel = 0, bool bPrint = false, bool bCombineDrops = true)
void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, const FName& LootPackageName, std::vector<LootDrop>* OutEntries, int LootPackageCategory = -1, int WorldLevel = 0, bool bPrint = false, bool bCombineDrops = true)
{
if (!OutEntries)
return;
LOOTING_MAP_TYPE<FName, FFortLootPackageData*> LootPackageIDMap;
float TotalWeight = 0;
CollectDataTablesRows<FFortLootPackageData>(LPTables, &LootPackageIDMap, [&](FName RowName, FFortLootPackageData* LootPackage) -> bool {
if (LootPackage->GetLootPackageID() != LootPackageName)
{
@@ -214,18 +215,16 @@ void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, FNam
if (WorldLevel >= 0)
{
if (LootPackage->GetMaxWorldLevel() >= 0 && WorldLevel > LootPackage->GetMaxWorldLevel())
return false;
return 0;
if (LootPackage->GetMinWorldLevel() >= 0 && WorldLevel < LootPackage->GetMinWorldLevel())
return false;
return 0;
}
TotalWeight += LootPackage->GetWeight();
return true;
});
if (TotalWeight == 0)
if (LootPackageIDMap.size() == 0)
{
// std::cout << std::format("Loot Package {} has no valid weights.\n", LootPackageName.ToString());
return;
@@ -233,7 +232,8 @@ void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, FNam
FName PickedPackageRowName;
FFortLootPackageData* PickedPackage = PickWeightedElement<FName, FFortLootPackageData*>(LootPackageIDMap,
[](FFortLootPackageData* LootPackageData) -> float { return LootPackageData->GetWeight(); }, RandomFloatForLoot, -1, true, 1, &PickedPackageRowName, bPrint);
[](FFortLootPackageData* LootPackageData) -> float { return LootPackageData->GetWeight(); }, RandomFloatForLoot,
-1, true, 1, &PickedPackageRowName, bPrint);
if (!PickedPackage)
return;
@@ -366,6 +366,8 @@ void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, FNam
}
}
// #define brudda
std::vector<LootDrop> PickLootDrops(FName TierGroupName, int WorldLevel, int ForcedLootTier, bool bPrint, int recursive, bool bCombineDrops)
{
std::vector<LootDrop> LootDrops;
@@ -509,6 +511,23 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, int WorldLevel, int For
if (ptr)
{
/* if (bOverrideIsComposite)
{
static auto ParentTablesOffset = ptr->GetOffset("ParentTables");
auto ParentTables = ptr->GetPtr<TArray<UDataTable*>>(ParentTablesOffset);
for (int z = 0; z < ParentTables->size(); z++)
{
auto ParentTable = ParentTables->At(z);
if (ParentTable)
{
LPTables.push_back(ParentTable);
}
}
} */
LPTables.push_back(ptr);
}
}
@@ -552,7 +571,7 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, int WorldLevel, int For
auto ParentTables = ptr->GetPtr<TArray<UDataTable*>>(ParentTablesOffset);
for (int z = 0; z < ParentTables->size(); ++z)
for (int z = 0; z < ParentTables->size(); z++)
{
auto ParentTable = ParentTables->At(z);
@@ -685,11 +704,11 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, int WorldLevel, int For
}
else
{
NumberLootDrops = (int)(float)((float)(NumLootPackageDrops + NumLootPackageDrops) - 0.5) >> 1;
NumberLootDrops = (int)(float)((float)(NumLootPackageDrops + NumLootPackageDrops) - 0.5f) >> 1;
float v20 = NumLootPackageDrops - NumberLootDrops;
if (v20 > 0.0000099999997)
if (v20 > 0.0000099999997f)
{
NumberLootDrops += v20 >= (rand() * 0.000030518509);
NumberLootDrops += v20 >= (rand() * 0.000030518509f);
}
}
}

View File

@@ -144,7 +144,7 @@ template <typename KeyType, typename ValueType>
FORCEINLINE static ValueType PickWeightedElement(const std::map<KeyType, ValueType>& Elements,
std::function<float(ValueType)> GetWeightFn,
std::function<float(float)> RandomFloatGenerator = RandomFloatForLoot,
float TotalWeightParam = -1, bool bCheckIfWeightIsZero = false, int RandMultiplier = 1, KeyType* OutName = nullptr, bool bPrint = false, bool bKeepGoingUntilWeGetValue = false, float AHHH = 1)
float TotalWeightParam = -1, bool bCheckIfWeightIsZero = false, int RandMultiplier = 1, KeyType* OutName = nullptr, bool bPrint = false, bool bKeepGoingUntilWeGetValue = false)
{
float TotalWeight = TotalWeightParam;
@@ -165,7 +165,8 @@ FORCEINLINE static ValueType PickWeightedElement(const std::map<KeyType, ValueTy
});
}
float RandomNumber = RandMultiplier * RandomFloatGenerator(AHHH == -1 ? TotalWeight : AHHH);
float RandomNumber = // UKismetMathLibrary::RandomFloatInRange(0, TotalWeight);
RandMultiplier * RandomFloatGenerator(TotalWeight);
if (bPrint)
{

View File

@@ -37,7 +37,9 @@ void AFortPlayerController::ClientReportDamagedResourceBuilding(ABuildingSMActor
void AFortPlayerController::ClientEquipItem(const FGuid& ItemGuid, bool bForceExecution)
{
static auto ClientEquipItemFn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerControllerAthena.ClientEquipItem") ? FindObject<UFunction>("/Script/FortniteGame.FortPlayerControllerAthena.ClientEquipItem") : FindObject<UFunction>("/Script/FortniteGame.FortPlayerController.ClientEquipItem");
static auto ClientEquipItemFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerAthena.ClientEquipItem")
? FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerAthena.ClientEquipItem")
: FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.ClientEquipItem");
if (ClientEquipItemFn)
{
@@ -920,7 +922,9 @@ AActor* AFortPlayerController::SpawnToyInstanceHook(UObject* Context, FFrame* St
if (!ToyClass)
return nullptr;
auto NewToy = GetWorld()->SpawnActor<AActor>(ToyClass, SpawnPosition, CreateSpawnParameters(ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn, false, PlayerController));
auto Params = CreateSpawnParameters(ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn, false, PlayerController);
auto NewToy = GetWorld()->SpawnActor<AActor>(ToyClass, SpawnPosition, Params);
// free(Params); // ?
static auto ActiveToyInstancesOffset = PlayerController->GetOffset("ActiveToyInstances");
auto& ActiveToyInstances = PlayerController->Get<TArray<AActor*>>(ActiveToyInstancesOffset);
@@ -993,7 +997,9 @@ void AFortPlayerController::ServerAttemptInventoryDropHook(AFortPlayerController
static auto DropBehaviorOffset = ItemDefinition->GetOffset("DropBehavior", false);
if (!ItemDefinition->ShouldIgnoreRespawningOnDrop() && (DropBehaviorOffset != -1 ? ItemDefinition->GetDropBehavior() != EWorldItemDropBehavior::DestroyOnDrop : true))
EWorldItemDropBehavior DropBehavior = DropBehaviorOffset != -1 ? ItemDefinition->GetDropBehavior() : EWorldItemDropBehavior::EWorldItemDropBehavior_MAX;
if (!ItemDefinition->ShouldIgnoreRespawningOnDrop() && DropBehavior != EWorldItemDropBehavior::DestroyOnDrop)
{
PickupCreateData CreateData;
CreateData.ItemEntry = ReplicatedEntry;
@@ -1013,7 +1019,7 @@ void AFortPlayerController::ServerAttemptInventoryDropHook(AFortPlayerController
bool bShouldUpdate = false;
if (!WorldInventory->RemoveItem(ItemGuid, &bShouldUpdate, Count, true))
if (!WorldInventory->RemoveItem(ItemGuid, &bShouldUpdate, Count, true, DropBehavior == EWorldItemDropBehavior::DropAsPickupDestroyOnEmpty))
return;
if (bShouldUpdate)
@@ -1171,28 +1177,23 @@ uint8 ToDeathCause(const FGameplayTagContainer& TagContainer, bool bWasDBNO = fa
return sub_7FF7AB499410(TagContainer, bWasDBNO);
}
std::vector<APlayerController*> PlayerControllersDead; // make atomic?
// std::array<std::atomic<APlayerController*>, 100> PlayerControllersDead;
std::atomic<int> numValidElements(0);
DWORD WINAPI SpectateThread(LPVOID)
DWORD WINAPI SpectateThread(LPVOID PC)
{
while (1)
{
for (auto PC : PlayerControllersDead)
// for (int i = 0; i < PlayerControllersDead.size(); ++i)
{
// auto PC = PlayerControllersDead.at(i).load();
auto PlayerController = (UObject*)PC;
static auto SpectateOnDeathFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerZone.SpectateOnDeath") ?
FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerZone.SpectateOnDeath") :
FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerAthena.SpectateOnDeath");
if (!PlayerController->IsValidLowLevel())
return 0;
PC->ProcessEvent(SpectateOnDeathFn);
}
auto SpectatingPC = Cast<AFortPlayerControllerAthena>(PlayerController);
Sleep(4000);
}
if (!SpectatingPC)
return 0;
Sleep(3000);
LOG_INFO(LogDev, "bugha!");
SpectatingPC->SpectateOnDeath();
return 0;
}
@@ -1434,110 +1435,98 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
LOG_INFO(LogDev, "PlayersLeft: {} IsDBNO: {}", GameState->GetPlayersLeft(), DeadPawn->IsDBNO());
if (bHandleDeath && !DeadPawn->IsDBNO())
if (!DeadPawn->IsDBNO())
{
if (Fortnite_Version > 1.8 || Fortnite_Version == 1.11)
if (bHandleDeath)
{
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");
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");
if (DamageCauser)
{
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))
{
KillerWeaponDef = Weapon->GetWeaponData();
}
}
RemoveFromAlivePlayers(GameMode, PlayerController, KillerPlayerState == DeadPlayerState ? nullptr : KillerPlayerState, KillerPawn, KillerWeaponDef, DeathCause, 0);
/*
STATS:
Note: This isn't the exact order relative to other functions.
ClientSendMatchStatsForPlayer
ClientSendTeamStatsForPlayer
ClientSendEndBattleRoyaleMatchForPlayer
*/
// FAthenaMatchStats.Stats[ERewardSource] // hmm
/*
// We need to check if their entire team is dead then I think we send it????
auto DeadControllerAthena = Cast<AFortPlayerControllerAthena>(PlayerController);
if (DeadControllerAthena && FAthenaMatchTeamStats::GetStruct())
{
auto MatchReport = DeadControllerAthena->GetMatchReport();
LOG_INFO(LogDev, "MatchReport: {}", __int64(MatchReport));
if (MatchReport)
{
MatchReport->GetTeamStats()->GetPlace() = DeadPlayerState->GetPlace();
MatchReport->GetTeamStats()->GetTotalPlayers() = AmountOfPlayersWhenBusStart; // hmm
MatchReport->HasTeamStats() = true;
DeadControllerAthena->ClientSendTeamStatsForPlayer(MatchReport->GetTeamStats());
}
}
*/
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)
auto Owner = Cast<AFortWeapon>(DamageCauser->GetOwner());
KillerWeaponDef = Owner->IsValidLowLevel() ? Owner->GetWeaponData() : nullptr; // I just added the IsValidLowLevel check because what if the weapon destroys (idk)?
}
if (auto Weapon = Cast<AFortWeapon>(DamageCauser))
{
bCreatedThread = true;
CreateThread(0, 0, SpectateThread, 0, 0, 0);
KillerWeaponDef = Weapon->GetWeaponData();
}
}
RemoveFromAlivePlayers(GameMode, PlayerController, KillerPlayerState == DeadPlayerState ? nullptr : KillerPlayerState, KillerPawn, KillerWeaponDef, DeathCause, 0);
/*
STATS:
Note: This isn't the exact order relative to other functions.
ClientSendMatchStatsForPlayer
ClientSendTeamStatsForPlayer
ClientSendEndBattleRoyaleMatchForPlayer
*/
// FAthenaMatchStats.Stats[ERewardSource] // hmm
/*
// We need to check if their entire team is dead then I think we send it????
auto DeadControllerAthena = Cast<AFortPlayerControllerAthena>(PlayerController);
if (DeadControllerAthena && FAthenaMatchTeamStats::GetStruct())
{
auto MatchReport = DeadControllerAthena->GetMatchReport();
LOG_INFO(LogDev, "MatchReport: {}", __int64(MatchReport));
if (MatchReport)
{
MatchReport->GetTeamStats()->GetPlace() = DeadPlayerState->GetPlace();
MatchReport->GetTeamStats()->GetTotalPlayers() = AmountOfPlayersWhenBusStart; // hmm
MatchReport->HasTeamStats() = true;
DeadControllerAthena->ClientSendTeamStatsForPlayer(MatchReport->GetTeamStats());
}
}
*/
LOG_INFO(LogDev, "Removed!");
}
// LOG_INFO(LogDev, "KillerPlayerState->Place: {}", KillerPlayerState ? KillerPlayerState->GetPlace() : -1);
}
// LOG_INFO(LogDev, "KillerPlayerState->Place: {}", KillerPlayerState ? KillerPlayerState->GetPlace() : -1);
if (Fortnite_Version < 6) // Spectating (is this the actual build or is it like 6.10 when they added it auto).
{
static auto bAllowSpectateAfterDeathOffset = GameMode->GetOffset("bAllowSpectateAfterDeath");
bool bAllowSpectate = 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;
CreateThread(0, 0, SpectateThread, (LPVOID)PlayerController, 0, 0);
}
}
}
if (IsRestartingSupported() && Globals::bAutoRestart && !bIsInAutoRestart)

View File

@@ -141,6 +141,15 @@ public:
static inline void (*StartGhostModeOriginal)(UObject* Context, FFrame* Stack, void* Ret);
static inline void (*EndGhostModeOriginal)(AFortPlayerControllerAthena* PlayerController);
void SpectateOnDeath() // actually in zone
{
static auto SpectateOnDeathFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerZone.SpectateOnDeath") ?
FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerZone.SpectateOnDeath") :
FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerAthena.SpectateOnDeath");
this->ProcessEvent(SpectateOnDeathFn);
}
class UAthenaResurrectionComponent*& GetResurrectionComponent()
{
static auto ResurrectionComponentOffset = GetOffset("ResurrectionComponent");

View File

@@ -312,6 +312,9 @@ void Addresses::FindAll()
LOG_INFO(LogDev, "Finding AddToAlivePlayers");
Addresses::AddToAlivePlayers = FindAddToAlivePlayers();
LOG_INFO(LogDev, "Finding StartAircraftPhase");
Addresses::StartAircraftPhase = FindStartAircraftPhase();
// LOG_INFO(LogDev, "Finding GetSessionInterface");
// Addresses::GetSessionInterface = FindGetSessionInterface();
@@ -392,6 +395,7 @@ void Addresses::Print()
LOG_INFO(LogDev, "FinishResurrection: 0x{:x}", FinishResurrection - Base);
LOG_INFO(LogDev, "AddToAlivePlayers: 0x{:x}", AddToAlivePlayers - Base);
LOG_INFO(LogDev, "GetSessionInterface: 0x{:x}", GetSessionInterface - Base);
LOG_INFO(LogDev, "StartAircraftPhase: 0x{:x}", StartAircraftPhase - Base);
}
void Offsets::FindAll()

View File

@@ -76,6 +76,7 @@ namespace Addresses
extern inline uint64 AddToAlivePlayers = 0;
extern inline uint64 GameSessionPatch = 0;
extern inline uint64 GetSessionInterface = 0; // Matchmaking
extern inline uint64 StartAircraftPhase = 0;
void SetupVersion(); // Finds Engine Version
void FindAll();

View File

@@ -3,6 +3,47 @@
#include "reboot.h"
#include "FortPlayerControllerAthena.h"
uint64 FindStartAircraftPhase()
{
if (Engine_Version < 427) // they scuf it
{
auto strRef = Memcury::Scanner::FindStringRef(L"STARTAIRCRAFT").Get();
if (!strRef)
return 0;
int NumCalls = 0;
for (int i = 0; i < 150; i++)
{
if (*(uint8_t*)(strRef + i) == 0xE8)
{
LOG_INFO(LogDev, "Found call 0x{:x}", __int64(strRef + i) - __int64(GetModuleHandleW(0)));
NumCalls++;
if (NumCalls == 2) // First is the str compare ig
{
return Memcury::Scanner(strRef + i).RelativeOffset(1).Get();
}
}
}
}
else
{
auto StatAddress = Memcury::Scanner::FindStringRef(L"STAT_StartAircraftPhase").Get();
for (int i = 0; i < 1000; i++)
{
if (*(uint8_t*)(uint8_t*)(StatAddress - i) == 0x48 && *(uint8_t*)(uint8_t*)(StatAddress - i + 1) == 0x8B && *(uint8_t*)(uint8_t*)(StatAddress - i + 2) == 0xC4)
{
return StatAddress - i;
}
}
}
return 0;
}
uint64 FindGetSessionInterface()
{
auto strRef = Memcury::Scanner::FindStringRef(L"OnDestroyReservedSessionComplete %s bSuccess: %d", true, 0, Fortnite_Version >= 19).Get();

View File

@@ -495,6 +495,7 @@ static inline uint64 FindGetMaxTickRate() // UEngine::getmaxtickrate
// return FindBytes(stringRef, Fortnite_Version <= 4.1 ? std::vector<uint8_t>{ 0x40, 0x53 } : std::vector<uint8_t>{ 0x48, 0x89, 0x5C }, 1000, 0, true);
}
uint64 FindStartAircraftPhase();
uint64 FindGetSessionInterface();
uint64 FindGetPlayerViewpoint();
uint64 ApplyGameSessionPatch();

View File

@@ -104,7 +104,7 @@ static inline LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
static inline void SetIsLategame(bool Value)
{
Globals::bLateGame.store(Value);
StartingShield = 100;
StartingShield = Value ? 100 : 0;
}
static inline void Restart() // todo move?
@@ -528,7 +528,7 @@ static inline DWORD WINAPI LateGameThread(LPVOID)
return Aircrafts;
};
UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"startaircraft", nullptr);
GameMode->StartAircraftPhase();
while (GetAircrafts().size() <= 0)
{
@@ -795,7 +795,7 @@ static inline void MainUI()
}
else
{
UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"startaircraft", nullptr);
GameMode->StartAircraftPhase();
}
}
}
@@ -1086,9 +1086,10 @@ static inline void MainUI()
{
auto CurrentBuildingSMActor = (ABuildingSMActor*)AllBuildingSMActors.at(i);
if (!CurrentBuildingSMActor->IsPlayerPlaced()) continue;
if (CurrentBuildingSMActor->IsDestroyed() || CurrentBuildingSMActor->IsActorBeingDestroyed() || !CurrentBuildingSMActor->IsPlayerPlaced()) continue;
CurrentBuildingSMActor->K2_DestroyActor();
CurrentBuildingSMActor->SilentDie();
// CurrentBuildingSMActor->K2_DestroyActor();
}
AllBuildingSMActors.Free();
@@ -1137,9 +1138,12 @@ static inline void MainUI()
static auto DefaultGliderRedeployCanRedeployOffset = FindOffsetStruct("/Script/FortniteGame.FortGameStateAthena", "DefaultGliderRedeployCanRedeploy", false);
static auto DefaultParachuteDeployTraceForGroundDistanceOffset = GameState->GetOffset("DefaultParachuteDeployTraceForGroundDistance", false);
if (DefaultParachuteDeployTraceForGroundDistanceOffset != -1)
if (Globals::bStartedListening) // it resets accordingly to ProHenis b4 this
{
ImGui::InputFloat("Automatic Parachute Pullout Distance", GameState->GetPtr<float>(DefaultParachuteDeployTraceForGroundDistanceOffset));
if (DefaultParachuteDeployTraceForGroundDistanceOffset != -1)
{
ImGui::InputFloat("Automatic Parachute Pullout Distance", GameState->GetPtr<float>(DefaultParachuteDeployTraceForGroundDistanceOffset));
}
}
if (DefaultGliderRedeployCanRedeployOffset != -1)

View File

@@ -20,7 +20,7 @@ extern inline int Engine_Version = 0; // For example, 420, 421, etc. // Prevent
extern inline double Fortnite_Version = 0; // For example, 4.1, 6.21, etc. // Prevent using this when possible.
extern inline int Fortnite_CL = 0;
#define PROD // this doesnt do anything besides remove processeventhook and some assert stuff
// #define PROD // this doesnt do anything besides remove processeventhook and some assert stuff
struct PlaceholderBitfield
{