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) void AFortGameModeAthena::PauseSafeZone(bool bPaused)
{ {
auto GameState = GetGameStateAthena(); auto GameState = GetGameStateAthena();

View File

@@ -263,6 +263,7 @@ public:
UClass* GetVehicleClassOverride(UClass* DefaultClass); UClass* GetVehicleClassOverride(UClass* DefaultClass);
void SkipAircraft(); void SkipAircraft();
void PauseSafeZone(bool bPaused = true); void PauseSafeZone(bool bPaused = true);
void StartAircraftPhase();
static void HandleSpawnRateForActorClass(UClass* ActorClass, float SpawnPercentage); // idk where to put 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; 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) if (bShouldUpdate)
*bShouldUpdate = false; *bShouldUpdate = false;
@@ -280,7 +280,7 @@ bool AFortInventory::RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int
bool bOverrideChangeStackSize = false; bool bOverrideChangeStackSize = false;
if (ItemDefinition->ShouldPersistWhenFinalStackEmpty()) if (!bIgnoreVariables && ItemDefinition->ShouldPersistWhenFinalStackEmpty())
{ {
bool bIsFinalStack = true; 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(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, bool bIgnoreVariables = false);
void SwapItem(const FGuid& ItemGuid, FFortItemEntry* NewItemEntry, int OverrideNewCount = -1, std::pair<FFortItemEntry*, FFortItemEntry*>* outEntries = nullptr); 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);

View File

@@ -121,11 +121,11 @@ float GetAmountOfLootPackagesToDrop(FFortLootTierData* LootTierData, int Origina
{ {
// HONESTLY IDEK WHAT FORTNITE DOES HERE // 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 v35 = (int)(float)((float)((float)((float)SumLootPackageCategoryWeightArray * v29)
+ (float)((float)SumLootPackageCategoryWeightArray * v29)) + (float)((float)SumLootPackageCategoryWeightArray * v29))
+ 0.5) >> 1; + 0.5f) >> 1;
// OutLootTierInfo->Hello++; // OutLootTierInfo->Hello++;
MinimumLootDrops++; 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. 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 LootTier = ForcedLootTier;
float IdkForcedWeightorsomething = -1;
if (LootTier == -1) if (LootTier == -1)
{ {
// IdkForcedWeightorsomething = weightofAlltherowsithink // we don't ened to do this since the pickweightedeleent already does that // LootTier = ??
} }
else 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; // 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; LOOTING_MAP_TYPE<FName, FFortLootTierData*> TierGroupLTDs;
CollectDataTablesRows<FFortLootTierData>(LTDTables, &TierGroupLTDs, [&](FName RowName, FFortLootTierData* TierData) -> bool { CollectDataTablesRows<FFortLootTierData>(LTDTables, &TierGroupLTDs, [&](FName RowName, FFortLootTierData* TierData) -> bool {
if (LootTierGroup == TierData->GetTierGroup()) 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; return true;
} }
@@ -186,20 +189,18 @@ FFortLootTierData* PickLootTierData(const std::vector<UDataTable*>& LTDTables, F
FFortLootTierData* ChosenRowLootTierData = PickWeightedElement<FName, FFortLootTierData*>(TierGroupLTDs, FFortLootTierData* ChosenRowLootTierData = PickWeightedElement<FName, FFortLootTierData*>(TierGroupLTDs,
[](FFortLootTierData* LootTierData) -> float { return LootTierData->GetWeight(); }, RandomFloatForLoot, -1, [](FFortLootTierData* LootTierData) -> float { return LootTierData->GetWeight(); }, RandomFloatForLoot, -1,
true, 1, OutRowName, false, false, IdkForcedWeightorsomething); true, Multiplier, OutRowName);
return ChosenRowLootTierData; 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) if (!OutEntries)
return; return;
LOOTING_MAP_TYPE<FName, FFortLootPackageData*> LootPackageIDMap; LOOTING_MAP_TYPE<FName, FFortLootPackageData*> LootPackageIDMap;
float TotalWeight = 0;
CollectDataTablesRows<FFortLootPackageData>(LPTables, &LootPackageIDMap, [&](FName RowName, FFortLootPackageData* LootPackage) -> bool { CollectDataTablesRows<FFortLootPackageData>(LPTables, &LootPackageIDMap, [&](FName RowName, FFortLootPackageData* LootPackage) -> bool {
if (LootPackage->GetLootPackageID() != LootPackageName) if (LootPackage->GetLootPackageID() != LootPackageName)
{ {
@@ -214,18 +215,16 @@ void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, FNam
if (WorldLevel >= 0) if (WorldLevel >= 0)
{ {
if (LootPackage->GetMaxWorldLevel() >= 0 && WorldLevel > LootPackage->GetMaxWorldLevel()) if (LootPackage->GetMaxWorldLevel() >= 0 && WorldLevel > LootPackage->GetMaxWorldLevel())
return false; return 0;
if (LootPackage->GetMinWorldLevel() >= 0 && WorldLevel < LootPackage->GetMinWorldLevel()) if (LootPackage->GetMinWorldLevel() >= 0 && WorldLevel < LootPackage->GetMinWorldLevel())
return false; return 0;
} }
TotalWeight += LootPackage->GetWeight();
return true; return true;
}); });
if (TotalWeight == 0) if (LootPackageIDMap.size() == 0)
{ {
// std::cout << std::format("Loot Package {} has no valid weights.\n", LootPackageName.ToString()); // std::cout << std::format("Loot Package {} has no valid weights.\n", LootPackageName.ToString());
return; return;
@@ -233,7 +232,8 @@ void PickLootDropsFromLootPackage(const std::vector<UDataTable*>& LPTables, FNam
FName PickedPackageRowName; FName PickedPackageRowName;
FFortLootPackageData* PickedPackage = PickWeightedElement<FName, FFortLootPackageData*>(LootPackageIDMap, 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) if (!PickedPackage)
return; 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> PickLootDrops(FName TierGroupName, int WorldLevel, int ForcedLootTier, bool bPrint, int recursive, bool bCombineDrops)
{ {
std::vector<LootDrop> LootDrops; std::vector<LootDrop> LootDrops;
@@ -509,6 +511,23 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, int WorldLevel, int For
if (ptr) 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); 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); 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); auto ParentTable = ParentTables->At(z);
@@ -685,11 +704,11 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, int WorldLevel, int For
} }
else else
{ {
NumberLootDrops = (int)(float)((float)(NumLootPackageDrops + NumLootPackageDrops) - 0.5) >> 1; NumberLootDrops = (int)(float)((float)(NumLootPackageDrops + NumLootPackageDrops) - 0.5f) >> 1;
float v20 = NumLootPackageDrops - NumberLootDrops; 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, FORCEINLINE static ValueType PickWeightedElement(const std::map<KeyType, ValueType>& Elements,
std::function<float(ValueType)> GetWeightFn, std::function<float(ValueType)> GetWeightFn,
std::function<float(float)> RandomFloatGenerator = RandomFloatForLoot, 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; 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) if (bPrint)
{ {

View File

@@ -37,7 +37,9 @@ void AFortPlayerController::ClientReportDamagedResourceBuilding(ABuildingSMActor
void AFortPlayerController::ClientEquipItem(const FGuid& ItemGuid, bool bForceExecution) 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) if (ClientEquipItemFn)
{ {
@@ -920,7 +922,9 @@ AActor* AFortPlayerController::SpawnToyInstanceHook(UObject* Context, FFrame* St
if (!ToyClass) if (!ToyClass)
return nullptr; 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"); static auto ActiveToyInstancesOffset = PlayerController->GetOffset("ActiveToyInstances");
auto& ActiveToyInstances = PlayerController->Get<TArray<AActor*>>(ActiveToyInstancesOffset); auto& ActiveToyInstances = PlayerController->Get<TArray<AActor*>>(ActiveToyInstancesOffset);
@@ -993,7 +997,9 @@ void AFortPlayerController::ServerAttemptInventoryDropHook(AFortPlayerController
static auto DropBehaviorOffset = ItemDefinition->GetOffset("DropBehavior", false); 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; PickupCreateData CreateData;
CreateData.ItemEntry = ReplicatedEntry; CreateData.ItemEntry = ReplicatedEntry;
@@ -1013,7 +1019,7 @@ void AFortPlayerController::ServerAttemptInventoryDropHook(AFortPlayerController
bool bShouldUpdate = false; bool bShouldUpdate = false;
if (!WorldInventory->RemoveItem(ItemGuid, &bShouldUpdate, Count, true)) if (!WorldInventory->RemoveItem(ItemGuid, &bShouldUpdate, Count, true, DropBehavior == EWorldItemDropBehavior::DropAsPickupDestroyOnEmpty))
return; return;
if (bShouldUpdate) if (bShouldUpdate)
@@ -1171,28 +1177,23 @@ uint8 ToDeathCause(const FGameplayTagContainer& TagContainer, bool bWasDBNO = fa
return sub_7FF7AB499410(TagContainer, bWasDBNO); return sub_7FF7AB499410(TagContainer, bWasDBNO);
} }
std::vector<APlayerController*> PlayerControllersDead; // make atomic? DWORD WINAPI SpectateThread(LPVOID PC)
// std::array<std::atomic<APlayerController*>, 100> PlayerControllersDead;
std::atomic<int> numValidElements(0);
DWORD WINAPI SpectateThread(LPVOID)
{ {
while (1) auto PlayerController = (UObject*)PC;
{
for (auto PC : PlayerControllersDead)
// for (int i = 0; i < PlayerControllersDead.size(); ++i)
{
// auto PC = PlayerControllersDead.at(i).load();
static auto SpectateOnDeathFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerZone.SpectateOnDeath") ? if (!PlayerController->IsValidLowLevel())
FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerZone.SpectateOnDeath") : return 0;
FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerAthena.SpectateOnDeath");
PC->ProcessEvent(SpectateOnDeathFn); auto SpectatingPC = Cast<AFortPlayerControllerAthena>(PlayerController);
}
Sleep(4000); if (!SpectatingPC)
} return 0;
Sleep(3000);
LOG_INFO(LogDev, "bugha!");
SpectatingPC->SpectateOnDeath();
return 0; return 0;
} }
@@ -1434,7 +1435,9 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
LOG_INFO(LogDev, "PlayersLeft: {} IsDBNO: {}", GameState->GetPlayersLeft(), DeadPawn->IsDBNO()); LOG_INFO(LogDev, "PlayersLeft: {} IsDBNO: {}", GameState->GetPlayersLeft(), DeadPawn->IsDBNO());
if (bHandleDeath && !DeadPawn->IsDBNO()) if (!DeadPawn->IsDBNO())
{
if (bHandleDeath)
{ {
if (Fortnite_Version > 1.8 || Fortnite_Version == 1.11) if (Fortnite_Version > 1.8 || Fortnite_Version == 1.11)
{ {
@@ -1452,7 +1455,7 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
if (DamageCauser->IsA(FortProjectileBaseClass)) if (DamageCauser->IsA(FortProjectileBaseClass))
{ {
auto Owner = Cast<AFortWeapon>(DamageCauser->GetOwner()); auto Owner = Cast<AFortWeapon>(DamageCauser->GetOwner());
KillerWeaponDef = Owner->IsValidLowLevel() ? Owner->GetWeaponData() : nullptr; // I just added the IsValidLowLevel check because what if the weapon destroys? 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)) if (auto Weapon = Cast<AFortWeapon>(DamageCauser))
{ {
@@ -1501,12 +1504,16 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
*/ */
LOG_INFO(LogDev, "Removed!"); LOG_INFO(LogDev, "Removed!");
}
if (Fortnite_Version < 6) // Spectating // 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"); static auto bAllowSpectateAfterDeathOffset = GameMode->GetOffset("bAllowSpectateAfterDeath");
bool bAllowSpectate = false; // GameMode->Get<bool>(bAllowSpectateAfterDeathOffset); bool bAllowSpectate = GameMode->Get<bool>(bAllowSpectateAfterDeathOffset);
LOG_INFO(LogDev, "bAllowSpectate: {}", bAllowSpectate); LOG_INFO(LogDev, "bAllowSpectate: {}", bAllowSpectate);
@@ -1517,28 +1524,10 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
static auto PlayerToSpectateOnDeathOffset = PlayerController->GetOffset("PlayerToSpectateOnDeath"); static auto PlayerToSpectateOnDeathOffset = PlayerController->GetOffset("PlayerToSpectateOnDeath");
PlayerController->Get<APawn*>(PlayerToSpectateOnDeathOffset) = KillerPawn; PlayerController->Get<APawn*>(PlayerToSpectateOnDeathOffset) = KillerPawn;
PlayerControllersDead.push_back(PlayerController); CreateThread(0, 0, SpectateThread, (LPVOID)PlayerController, 0, 0);
/* 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);
} }
} }
} }
}
// LOG_INFO(LogDev, "KillerPlayerState->Place: {}", KillerPlayerState ? KillerPlayerState->GetPlace() : -1);
}
if (IsRestartingSupported() && Globals::bAutoRestart && !bIsInAutoRestart) 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 (*StartGhostModeOriginal)(UObject* Context, FFrame* Stack, void* Ret);
static inline void (*EndGhostModeOriginal)(AFortPlayerControllerAthena* PlayerController); 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() class UAthenaResurrectionComponent*& GetResurrectionComponent()
{ {
static auto ResurrectionComponentOffset = GetOffset("ResurrectionComponent"); static auto ResurrectionComponentOffset = GetOffset("ResurrectionComponent");

View File

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

View File

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

View File

@@ -3,6 +3,47 @@
#include "reboot.h" #include "reboot.h"
#include "FortPlayerControllerAthena.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() uint64 FindGetSessionInterface()
{ {
auto strRef = Memcury::Scanner::FindStringRef(L"OnDestroyReservedSessionComplete %s bSuccess: %d", true, 0, Fortnite_Version >= 19).Get(); 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); // 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 FindGetSessionInterface();
uint64 FindGetPlayerViewpoint(); uint64 FindGetPlayerViewpoint();
uint64 ApplyGameSessionPatch(); 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) static inline void SetIsLategame(bool Value)
{ {
Globals::bLateGame.store(Value); Globals::bLateGame.store(Value);
StartingShield = 100; StartingShield = Value ? 100 : 0;
} }
static inline void Restart() // todo move? static inline void Restart() // todo move?
@@ -528,7 +528,7 @@ static inline DWORD WINAPI LateGameThread(LPVOID)
return Aircrafts; return Aircrafts;
}; };
UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"startaircraft", nullptr); GameMode->StartAircraftPhase();
while (GetAircrafts().size() <= 0) while (GetAircrafts().size() <= 0)
{ {
@@ -795,7 +795,7 @@ static inline void MainUI()
} }
else else
{ {
UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"startaircraft", nullptr); GameMode->StartAircraftPhase();
} }
} }
} }
@@ -1086,9 +1086,10 @@ static inline void MainUI()
{ {
auto CurrentBuildingSMActor = (ABuildingSMActor*)AllBuildingSMActors.at(i); 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(); AllBuildingSMActors.Free();
@@ -1137,10 +1138,13 @@ static inline void MainUI()
static auto DefaultGliderRedeployCanRedeployOffset = FindOffsetStruct("/Script/FortniteGame.FortGameStateAthena", "DefaultGliderRedeployCanRedeploy", false); static auto DefaultGliderRedeployCanRedeployOffset = FindOffsetStruct("/Script/FortniteGame.FortGameStateAthena", "DefaultGliderRedeployCanRedeploy", false);
static auto DefaultParachuteDeployTraceForGroundDistanceOffset = GameState->GetOffset("DefaultParachuteDeployTraceForGroundDistance", false); static auto DefaultParachuteDeployTraceForGroundDistanceOffset = GameState->GetOffset("DefaultParachuteDeployTraceForGroundDistance", false);
if (Globals::bStartedListening) // it resets accordingly to ProHenis b4 this
{
if (DefaultParachuteDeployTraceForGroundDistanceOffset != -1) if (DefaultParachuteDeployTraceForGroundDistanceOffset != -1)
{ {
ImGui::InputFloat("Automatic Parachute Pullout Distance", GameState->GetPtr<float>(DefaultParachuteDeployTraceForGroundDistanceOffset)); ImGui::InputFloat("Automatic Parachute Pullout Distance", GameState->GetPtr<float>(DefaultParachuteDeployTraceForGroundDistanceOffset));
} }
}
if (DefaultGliderRedeployCanRedeployOffset != -1) 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 double Fortnite_Version = 0; // For example, 4.1, 6.21, etc. // Prevent using this when possible.
extern inline int Fortnite_CL = 0; 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 struct PlaceholderBitfield
{ {