mirror of
https://github.com/Milxnor/Project-Reboot-3.0.git
synced 2026-01-13 02:42:22 +01:00
fixed looting
This commit is contained in:
@@ -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();
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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,110 +1435,98 @@ 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 (Fortnite_Version > 1.8 || Fortnite_Version == 1.11)
|
if (bHandleDeath)
|
||||||
{
|
{
|
||||||
static void (*RemoveFromAlivePlayers)(AFortGameModeAthena * GameMode, AFortPlayerController * PlayerController, APlayerState * PlayerState, APawn * FinisherPawn,
|
if (Fortnite_Version > 1.8 || Fortnite_Version == 1.11)
|
||||||
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 (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());
|
if (DamageCauser->IsA(FortProjectileBaseClass))
|
||||||
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())
|
|
||||||
{
|
{
|
||||||
PlayerControllersDead[numValidElements].store(PlayerController);
|
auto Owner = Cast<AFortWeapon>(DamageCauser->GetOwner());
|
||||||
numValidElements.fetch_add(1);
|
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))
|
||||||
static bool bCreatedThread = false;
|
|
||||||
|
|
||||||
if (!bCreatedThread)
|
|
||||||
{
|
{
|
||||||
bCreatedThread = true;
|
KillerWeaponDef = Weapon->GetWeaponData();
|
||||||
|
|
||||||
CreateThread(0, 0, SpectateThread, 0, 0, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
if (IsRestartingSupported() && Globals::bAutoRestart && !bIsInAutoRestart)
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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,9 +1138,12 @@ 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 (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)
|
if (DefaultGliderRedeployCanRedeployOffset != -1)
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user