cool update

add option for auto restart, fix some bugs with auto restart, fix a crash with having no playlist set, fix double pleasant and hlod buildings on 7.30, fix 6.21 hlod buildings, performance
This commit is contained in:
Milxnor
2023-05-01 23:52:41 -04:00
parent f4c12fd7f5
commit 3b0f0ad4e1
7 changed files with 140 additions and 80 deletions

View File

@@ -33,6 +33,8 @@
static UFortPlaylist* GetPlaylistToUse()
{
// LOG_DEBUG(LogDev, "PlaylistName: {}", PlaylistName);
auto Playlist = FindObject<UFortPlaylist>(PlaylistName);
if (Globals::bGoingToPlayEvent)
@@ -202,7 +204,8 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
LOG_INFO(LogDev, "Presetup!");
GameMode->Get<int>("WarmupRequiredPlayerCount") = 1;
static auto WarmupRequiredPlayerCountOffset = GameMode->GetOffset("WarmupRequiredPlayerCount");
GameMode->Get<int>(WarmupRequiredPlayerCountOffset) = 1;
static auto CurrentPlaylistDataOffset = GameState->GetOffset("CurrentPlaylistData", false);
@@ -238,22 +241,6 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
{
if (Fortnite_Season == 7)
{
if (Fortnite_Version == 7.30)
{
// should be automatic..
if (true)
{
auto PleasantParkIdk = FindObject<AActor>(("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.PleasentParkFestivus"));
ShowFoundation(PleasantParkIdk);
}
else
{
auto PleasantParkGround = FindObject<AActor>("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.PleasentParkDefault");
ShowFoundation(PleasantParkGround);
}
}
ShowFoundation(FindObject<AActor>("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.LF_Athena_POI_25x36")); // Polar Peak
ShowFoundation(FindObject<AActor>("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.ShopsNew")); // Tilted Tower Shops, is this 7.40 specific?
}
@@ -353,11 +340,16 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
if (Fortnite_Version == 7.30)
{
auto PleasantParkIdk = FindObject<AActor>(("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.PleasentParkFestivus"));
ShowFoundation(PleasantParkIdk);
auto PleasantParkGround = FindObject<AActor>("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.PleasentParkDefault");
ShowFoundation(PleasantParkGround);
if (true) // idfk if the stage only showed on marshmello playlist
{
auto PleasantParkIdk = FindObject<AActor>(("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.PleasentParkFestivus"));
ShowFoundation(PleasantParkIdk);
}
else
{
auto PleasantParkGround = FindObject<AActor>("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.PleasentParkDefault");
ShowFoundation(PleasantParkGround);
}
}
if (Fortnite_Season == 6)
@@ -368,7 +360,6 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
auto Lake2 = FindObject<AActor>("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.LF_Lake2");
Fortnite_Version <= 6.21 ? ShowFoundation(Lake) : ShowFoundation(Lake2);
// ^ This shows the lake after or before the event i dont know if this is needed.
}
else
{
@@ -424,7 +415,8 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
}
}
SetBitfield(GameMode->GetPtr<PlaceholderBitfield>("bWorldIsReady"), 1, true); // idk when we actually set this
static auto bWorldIsReadyOffset = GameMode->GetOffset("bWorldIsReady");
SetBitfield(GameMode->GetPtr<PlaceholderBitfield>(bWorldIsReadyOffset), 1, true); // idk when we actually set this
// Calendar::SetSnow(1000);
@@ -465,8 +457,9 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
// if (!Globals::bCreative)
{
static auto FortPlayerStartWarmupClass = Globals::bCreative ? FindObject<UClass>("/Script/FortniteGame.FortPlayerStartCreative") : FindObject<UClass>("/Script/FortniteGame.FortPlayerStartWarmup");
TArray<AActor*> Actors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), FortPlayerStartWarmupClass);
static auto FortPlayerStartCreativeClass = FindObject<UClass>("/Script/FortniteGame.FortPlayerStartCreative");
static auto FortPlayerStartWarmupClass = FindObject<UClass>("/Script/FortniteGame.FortPlayerStartWarmup");
TArray<AActor*> Actors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), Globals::bCreative ? FortPlayerStartCreativeClass : FortPlayerStartWarmupClass);
int ActorsNum = Actors.Num();
@@ -499,11 +492,16 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
LOG_INFO(LogDev, "GameMode 0x{:x}", __int64(GameMode));
GameState->Get<float>("WarmupCountdownEndTime") = TimeSeconds + Duration;
GameMode->Get<float>("WarmupCountdownDuration") = Duration;
static auto WarmupCountdownEndTimeOffset = GameState->GetOffset("WarmupCountdownEndTime");
static auto WarmupCountdownStartTimeOffset = GameState->GetOffset("WarmupCountdownStartTime");
static auto WarmupCountdownDurationOffset = GameMode->GetOffset("WarmupCountdownDuration");
static auto WarmupEarlyCountdownDurationOffset = GameMode->GetOffset("WarmupEarlyCountdownDuration");
GameState->Get<float>("WarmupCountdownStartTime") = TimeSeconds;
GameMode->Get<float>("WarmupEarlyCountdownDuration") = EarlyDuration;
GameState->Get<float>(WarmupCountdownEndTimeOffset) = TimeSeconds + Duration;
GameMode->Get<float>(WarmupCountdownDurationOffset) = Duration;
GameState->Get<float>(WarmupCountdownStartTimeOffset) = TimeSeconds;
GameMode->Get<float>(WarmupEarlyCountdownDurationOffset) = EarlyDuration;
static auto GameSessionOffset = GameMode->GetOffset("GameSession");
auto GameSession = GameMode->Get<AActor*>(GameSessionOffset);
@@ -583,6 +581,50 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
}
}
std::vector<std::string> WorldNamesToStreamAllFoundationsIn; // wtf
if (Fortnite_Version == 6.21)
{
WorldNamesToStreamAllFoundationsIn.push_back("/Temp/Game/Athena/Maps/POI/Athena_POI_Lake_002_5d9a86c8.Athena_POI_Lake_002:PersistentLevel.");
}
if (Fortnite_Version == 7.30)
{
// idk what one we actually need
WorldNamesToStreamAllFoundationsIn.push_back("/Temp/Game/Athena/Maps/POI/Athena_POI_CommunityPark_003_77acf920");
WorldNamesToStreamAllFoundationsIn.push_back("/Temp/Game/Athena/Maps/POI/Athena_POI_CommunityPark_003_M_5c711338");
}
if (WorldNamesToStreamAllFoundationsIn.size() > 0)
{
auto ObjectNum = ChunkedObjects ? ChunkedObjects->Num() : UnchunkedObjects ? UnchunkedObjects->Num() : 0;
for (int i = 0; i < ObjectNum; i++)
{
auto CurrentObject = GetObjectByIndex(i);
if (!CurrentObject)
continue;
static auto BuildingFoundationClass = FindObject<UClass>("/Script/FortniteGame.BuildingFoundation");
if (!CurrentObject->IsA(BuildingFoundationClass))
continue;
auto CurrentObjectFullName = CurrentObject->GetFullName(); // We can do GetPathName() and starts with but eh.
for (int z = 0; z < WorldNamesToStreamAllFoundationsIn.size(); z++)
{
if (CurrentObject->GetFullName().contains(WorldNamesToStreamAllFoundationsIn.at(z)))
{
// I think we only have to set bServerStreamedInLevel.
ShowFoundation((AActor*)CurrentObject);
continue;
}
}
}
}
Globals::bStartedListening = true;
}

View File

@@ -583,7 +583,7 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recurs
if (bPrint)
{
LOG_INFO(LogDev, "Adding LootPackage: {}", CurrentLP->GetAnnotation().ToString());
// LOG_INFO(LogDev, "Adding LootPackage: {}", CurrentLP->GetAnnotation().ToString());
}
}
}

View File

@@ -1235,50 +1235,51 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
{
auto WorldInventory = PlayerController->GetWorldInventory();
if (!WorldInventory)
return ClientOnPawnDiedOriginal(PlayerController, DeathReport);
auto& ItemInstances = WorldInventory->GetItemList().GetItemInstances();
std::vector<std::pair<FGuid, int>> GuidAndCountsToRemove;
for (int i = 0; i < ItemInstances.Num(); i++)
if (WorldInventory)
{
auto ItemInstance = ItemInstances.at(i);
// LOG_INFO(LogDev, "[{}/{}] CurrentItemInstance {}", i, ItemInstances.Num(), __int64(ItemInstance));
auto& ItemInstances = WorldInventory->GetItemList().GetItemInstances();
if (!ItemInstance)
continue;
std::vector<std::pair<FGuid, int>> GuidAndCountsToRemove;
auto ItemEntry = ItemInstance->GetItemEntry();
auto WorldItemDefinition = Cast<UFortWorldItemDefinition>(ItemEntry->GetItemDefinition());
for (int i = 0; i < ItemInstances.Num(); i++)
{
auto ItemInstance = ItemInstances.at(i);
// LOG_INFO(LogDev, "[{}/{}] WorldItemDefinition {}", i, ItemInstances.Num(), WorldItemDefinition ? WorldItemDefinition->GetFullName() : "InvalidObject");
// LOG_INFO(LogDev, "[{}/{}] CurrentItemInstance {}", i, ItemInstances.Num(), __int64(ItemInstance));
if (!WorldItemDefinition)
continue;
if (!ItemInstance)
continue;
auto ShouldBeDropped = WorldItemDefinition->CanBeDropped(); // WorldItemDefinition->ShouldDropOnDeath();
auto ItemEntry = ItemInstance->GetItemEntry();
auto WorldItemDefinition = Cast<UFortWorldItemDefinition>(ItemEntry->GetItemDefinition());
// LOG_INFO(LogDev, "[{}/{}] ShouldBeDropped {}", i, ItemInstances.Num(), ShouldBeDropped);
// LOG_INFO(LogDev, "[{}/{}] WorldItemDefinition {}", i, ItemInstances.Num(), WorldItemDefinition ? WorldItemDefinition->GetFullName() : "InvalidObject");
if (!ShouldBeDropped)
continue;
if (!WorldItemDefinition)
continue;
AFortPickup::SpawnPickup(WorldItemDefinition, DeathLocation, ItemEntry->GetCount(), EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::PlayerElimination,
ItemEntry->GetLoadedAmmo());
auto ShouldBeDropped = WorldItemDefinition->CanBeDropped(); // WorldItemDefinition->ShouldDropOnDeath();
GuidAndCountsToRemove.push_back({ ItemEntry->GetItemGuid(), ItemEntry->GetCount() });
// WorldInventory->RemoveItem(ItemEntry->GetItemGuid(), nullptr, ItemEntry->GetCount());
// LOG_INFO(LogDev, "[{}/{}] ShouldBeDropped {}", i, ItemInstances.Num(), ShouldBeDropped);
if (!ShouldBeDropped)
continue;
AFortPickup::SpawnPickup(WorldItemDefinition, DeathLocation, ItemEntry->GetCount(), EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::PlayerElimination,
ItemEntry->GetLoadedAmmo());
GuidAndCountsToRemove.push_back({ ItemEntry->GetItemGuid(), ItemEntry->GetCount() });
// WorldInventory->RemoveItem(ItemEntry->GetItemGuid(), nullptr, ItemEntry->GetCount());
}
for (auto& Pair : GuidAndCountsToRemove)
{
WorldInventory->RemoveItem(Pair.first, nullptr, Pair.second, true);
}
WorldInventory->Update();
}
for (auto& Pair : GuidAndCountsToRemove)
{
WorldInventory->RemoveItem(Pair.first, nullptr, Pair.second, true);
}
WorldInventory->Update();
}
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
@@ -1354,13 +1355,16 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
}
// LOG_INFO(LogDev, "KillerPlayerState->Place: {}", KillerPlayerState ? KillerPlayerState->GetPlace() : -1);
}
bool bDidSomeoneWin = false;
if (IsRestartingSupported() && Globals::bAutoRestart && !bIsInAutoRestart)
{
// wtf
auto AllPlayerStates = UGameplayStatics::GetAllActorsOfClass(GetWorld(), AFortPlayerStateAthena::StaticClass());
bool bDidSomeoneWin = AllPlayerStates.Num() == 0;
for (int i = 0; i < AllPlayerStates.Num(); i++)
{
if (((AFortPlayerStateAthena*)AllPlayerStates.at(i))->GetPlace() <= 1)

View File

@@ -37,12 +37,14 @@ void UWorld::Listen()
static bool (*InitHost)(UObject* Beacon) = decltype(InitHost)(Addresses::InitHost);
static void (*PauseBeaconRequests)(UObject* Beacon, bool bPause) = decltype(PauseBeaconRequests)(Addresses::PauseBeaconRequests);
NewBeacon->Get<int>("ListenPort") = Engine_Version < 426 ? Port - 1 : Port;
static auto ListenPortOffset = NewBeacon->GetOffset("ListenPort");
NewBeacon->Get<int>(ListenPortOffset) = Engine_Version < 426 ? Port - 1 : Port;
InitHost(NewBeacon);
PauseBeaconRequests(NewBeacon, false);
NewNetDriver = NewBeacon->Get<UNetDriver*>("NetDriver");
static auto Beacon_NetDriverOffset = NewBeacon->GetOffset("NetDriver");
NewNetDriver = NewBeacon->Get<UNetDriver*>(Beacon_NetDriverOffset);
}
else
{
@@ -55,8 +57,11 @@ void UWorld::Listen()
return;
}
NewNetDriver->Get<FName>("NetDriverName") = GameNetDriverName;
GetWorld()->Get("NetDriver") = NewNetDriver;
static auto NetDriverNameOffset = NewNetDriver->GetOffset("NetDriverName");
NewNetDriver->Get<FName>(NetDriverNameOffset) = GameNetDriverName;
static auto World_NetDriverOffset = GetWorld()->GetOffset("NetDriver");
GetWorld()->Get(World_NetDriverOffset) = NewNetDriver;
FURL URL = FURL();
URL.Port = Port - (Engine_Version >= 426);
@@ -73,8 +78,9 @@ void UWorld::Listen()
// LEVEL COLLECTIONS
auto& LevelCollections = GetWorld()->Get<TArray<__int64>>("LevelCollections");
int LevelCollectionSize = FindObject<UStruct>("/Script/Engine.LevelCollection")->GetPropertiesSize();
static auto LevelCollectionsOffset = GetWorld()->GetOffset("LevelCollections");
auto& LevelCollections = GetWorld()->Get<TArray<__int64>>(LevelCollectionsOffset);
static int LevelCollectionSize = FindObject<UStruct>("/Script/Engine.LevelCollection")->GetPropertiesSize();
*(UNetDriver**)(__int64(LevelCollections.AtPtr(0, LevelCollectionSize)) + 0x10) = NewNetDriver;
*(UNetDriver**)(__int64(LevelCollections.AtPtr(1, LevelCollectionSize)) + 0x10) = NewNetDriver;
@@ -87,6 +93,7 @@ AWorldSettings* UWorld::GetWorldSettings(const bool bCheckStreamingPersistent, c
// checkSlow(!IsInActualRenderingThread());
AWorldSettings* WorldSettings = nullptr;
static auto PersistentLevelOffset = GetOffset("PersistentLevel");
if (Get(PersistentLevelOffset))
{
WorldSettings = Get<ULevel*>(PersistentLevelOffset)->GetWorldSettings(bChecked);

View File

@@ -8,7 +8,7 @@ namespace Globals
{
extern inline bool bCreative = false;
extern inline bool bGoingToPlayEvent = false;
extern inline bool bEnableAGIDs = false;
extern inline bool bEnableAGIDs = true;
extern inline bool bNoMCP = true;
extern inline bool bLogProcessEvent = false;
// extern inline bool bLateGame = false;

View File

@@ -58,7 +58,7 @@
static inline int SecondsUntilTravel = 5;
static inline bool bSwitchedInitialLevel = false;
static inline bool bIsInAutoRestart = false;
extern inline bool bIsInAutoRestart = false;
// THE BASE CODE IS FROM IMGUI GITHUB
@@ -72,7 +72,7 @@ static inline void CleanupDeviceD3D();
static inline void ResetDevice();
static inline LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
static inline bool bStartedBus = false;
extern inline bool bStartedBus = false;
static inline void Restart() // todo move?
{
@@ -263,7 +263,7 @@ static inline void StaticUI()
{
if (IsRestartingSupported())
{
// ImGui::Checkbox("Auto Restart", &Globals::bAutoRestart);
ImGui::Checkbox("Auto Restart", &Globals::bAutoRestart);
}
#ifndef PROD

View File

@@ -63,11 +63,15 @@ static inline void FillItemCollector(ABuildingItemCollectorActor* ItemCollector,
static auto ItemCollectionsOffset = ItemCollector->GetOffset("ItemCollections");
auto& ItemCollections = ItemCollector->Get<TArray<FCollectorUnitInfo>>(ItemCollectionsOffset);
auto CurrentPlaylist = GameState->GetCurrentPlaylist();
UCurveTable* FortGameData = nullptr;
static auto GameDataOffset = CurrentPlaylist->GetOffset("GameData");
FortGameData = CurrentPlaylist ? CurrentPlaylist->Get<TSoftObjectPtr<UCurveTable>>(GameDataOffset).Get() : nullptr;
auto CurrentPlaylist = GameState->GetCurrentPlaylist();
if (CurrentPlaylist)
{
static auto GameDataOffset = CurrentPlaylist->GetOffset("GameData");
FortGameData = CurrentPlaylist ? CurrentPlaylist->GetPtr<TSoftObjectPtr<UCurveTable>>(GameDataOffset)->Get() : nullptr;
}
if (!FortGameData)
FortGameData = FindObject<UCurveTable>("/Game/Athena/Balance/AthenaGameData.AthenaGameData"); // uhm so theres one without athena and on newer versions that has it so idk
@@ -187,8 +191,11 @@ static inline void FillItemCollector(ABuildingItemCollectorActor* ItemCollector,
}
// The reason I set the curve to 0 is because it will force it to return value, probably not how we are supposed to do it but whatever.
ItemCollection->GetInputCount()->GetCurve().CurveTable = Fortnite_Version < 5 ? nullptr : FortGameData; // scuffed idc
ItemCollection->GetInputCount()->GetCurve().RowName = Fortnite_Version < 5 ? FName(0) : WoodName; // Scuffed idc
bool bShouldBeNullTable = true; // Fortnite_Version < 5
ItemCollection->GetInputCount()->GetCurve().CurveTable = bShouldBeNullTable ? nullptr : FortGameData; // scuffed idc
ItemCollection->GetInputCount()->GetCurve().RowName = bShouldBeNullTable ? FName(0) : WoodName; // Scuffed idc
ItemCollection->GetInputCount()->GetValue() = RarityToUse == 0 ? CommonPrice
: RarityToUse == 1 ? UncommonPrice
: RarityToUse == 2 ? RarePrice