From 6daab8d5a2eab76a004c682170e93889e19471a7 Mon Sep 17 00:00:00 2001 From: Milxnor Date: Mon, 17 Apr 2023 21:05:08 -0400 Subject: [PATCH] a bit fix restarting, add cheat teleport and help, build free and infinite ammo, fix restarting on c1, fix some gui issues. --- Project Reboot 3.0/CheatManager.cpp | 15 +++ Project Reboot 3.0/CheatManager.h | 11 ++ Project Reboot 3.0/FortGameModeAthena.cpp | 97 ---------------- Project Reboot 3.0/FortGameModeAthena.h | 98 +++++++++++++++++ Project Reboot 3.0/FortInventory.cpp | 7 +- Project Reboot 3.0/FortInventoryInterface.cpp | 13 ++- Project Reboot 3.0/FortLootPackage.cpp | 27 ++++- Project Reboot 3.0/FortPlayerController.cpp | 16 +-- Project Reboot 3.0/FortPlayerController.h | 1 - .../FortPlayerControllerAthena.h | 1 + Project Reboot 3.0/FortPlayerPawn.cpp | 2 +- .../FortPlaysetItemDefinition.cpp | 20 ++++ .../FortPlaysetItemDefinition.h | 4 +- Project Reboot 3.0/FortVolume.h | 6 + Project Reboot 3.0/FortVolumeManager.cpp | 14 +++ Project Reboot 3.0/FortVolumeManager.h | 13 +++ Project Reboot 3.0/GameplayStatics.h | 9 ++ Project Reboot 3.0/PlayerController.cpp | 7 ++ Project Reboot 3.0/PlayerController.h | 8 ++ .../PlaysetLevelStreamComponent.cpp | 13 +++ .../PlaysetLevelStreamComponent.h | 13 +++ Project Reboot 3.0/Project Reboot 3.0.vcxproj | 4 +- .../Project Reboot 3.0.vcxproj.filters | 24 ++-- Project Reboot 3.0/commands.h | 104 ++++++------------ Project Reboot 3.0/die.h | 6 +- Project Reboot 3.0/dllmain.cpp | 13 ++- Project Reboot 3.0/globals.h | 6 +- Project Reboot 3.0/gui.h | 8 +- 28 files changed, 352 insertions(+), 208 deletions(-) create mode 100644 Project Reboot 3.0/CheatManager.cpp create mode 100644 Project Reboot 3.0/CheatManager.h create mode 100644 Project Reboot 3.0/FortVolumeManager.cpp create mode 100644 Project Reboot 3.0/FortVolumeManager.h create mode 100644 Project Reboot 3.0/PlaysetLevelStreamComponent.cpp create mode 100644 Project Reboot 3.0/PlaysetLevelStreamComponent.h diff --git a/Project Reboot 3.0/CheatManager.cpp b/Project Reboot 3.0/CheatManager.cpp new file mode 100644 index 0000000..744b7b2 --- /dev/null +++ b/Project Reboot 3.0/CheatManager.cpp @@ -0,0 +1,15 @@ +#include "CheatManager.h" + +#include "reboot.h" + +void UCheatManager::Teleport() +{ + static auto TeleportFn = FindObject("/Script/Engine.CheatManager.Teleport"); + this->ProcessEvent(TeleportFn); +} + +UClass* UCheatManager::StaticClass() +{ + static auto Class = FindObject("/Script/Engine.CheatManager"); + return Class; +} \ No newline at end of file diff --git a/Project Reboot 3.0/CheatManager.h b/Project Reboot 3.0/CheatManager.h new file mode 100644 index 0000000..6ef989d --- /dev/null +++ b/Project Reboot 3.0/CheatManager.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Object.h" + +class UCheatManager : public UObject +{ +public: + void Teleport(); + + static UClass* StaticClass(); +}; \ No newline at end of file diff --git a/Project Reboot 3.0/FortGameModeAthena.cpp b/Project Reboot 3.0/FortGameModeAthena.cpp index 78f71de..8d8df64 100644 --- a/Project Reboot 3.0/FortGameModeAthena.cpp +++ b/Project Reboot 3.0/FortGameModeAthena.cpp @@ -25,23 +25,6 @@ #include "BGA.h" #include "vendingmachine.h" -enum class EDynamicFoundationEnabledState : uint8_t -{ - Unknown = 0, - Enabled = 1, - Disabled = 2, - EDynamicFoundationEnabledState_MAX = 3 -}; - -enum class EDynamicFoundationType : uint8_t -{ - Static = 0, - StartEnabled_Stationary = 1, - StartEnabled_Dynamic = 2, - StartDisabled = 3, - EDynamicFoundationType_MAX = 4 -}; - static UFortPlaylist* GetPlaylistToUse() { auto Playlist = FindObject(PlaylistName); @@ -87,86 +70,6 @@ EFortAthenaPlaylist GetPlaylistForOldVersion() ? EFortAthenaPlaylist::AthenaSquad : EFortAthenaPlaylist::AthenaSolo; } -void ShowFoundation(UObject* BuildingFoundation) -{ - if (!BuildingFoundation) - { - LOG_WARN(LogGame, "Attempting to show invalid building foundation."); - return; - } - - static auto bServerStreamedInLevelFieldMask = GetFieldMask(BuildingFoundation->GetProperty("bServerStreamedInLevel")); - static auto bServerStreamedInLevelOffset = BuildingFoundation->GetOffset("bServerStreamedInLevel"); - BuildingFoundation->SetBitfieldValue(bServerStreamedInLevelOffset, bServerStreamedInLevelFieldMask, true); - - static auto DynamicFoundationTypeOffset = BuildingFoundation->GetOffset("DynamicFoundationType"); - BuildingFoundation->Get(DynamicFoundationTypeOffset) = true ? 0 : 3; - - static auto bShowHLODWhenDisabledOffset = BuildingFoundation->GetOffset("bShowHLODWhenDisabled", false); - - if (bShowHLODWhenDisabledOffset != -1) - { - static auto bShowHLODWhenDisabledFieldMask = GetFieldMask(BuildingFoundation->GetProperty("bShowHLODWhenDisabled")); - BuildingFoundation->SetBitfieldValue(bShowHLODWhenDisabledOffset, bShowHLODWhenDisabledFieldMask, true); - } - - static auto OnRep_ServerStreamedInLevelFn = FindObject("/Script/FortniteGame.BuildingFoundation.OnRep_ServerStreamedInLevel"); - BuildingFoundation->ProcessEvent(OnRep_ServerStreamedInLevelFn); - - static auto DynamicFoundationRepDataOffset = BuildingFoundation->GetOffset("DynamicFoundationRepData", false); - - if (DynamicFoundationRepDataOffset != -1) - { - auto DynamicFoundationRepData = BuildingFoundation->GetPtr(DynamicFoundationRepDataOffset); - - static auto EnabledStateOffset = FindOffsetStruct("/Script/FortniteGame.DynamicBuildingFoundationRepData", "EnabledState"); - - *(EDynamicFoundationEnabledState*)(__int64(DynamicFoundationRepData) + EnabledStateOffset) = EDynamicFoundationEnabledState::Enabled; - - static auto OnRep_DynamicFoundationRepDataFn = FindObject("/Script/FortniteGame.BuildingFoundation.OnRep_DynamicFoundationRepData"); - BuildingFoundation->ProcessEvent(OnRep_DynamicFoundationRepDataFn); - } - - static auto FoundationEnabledStateOffset = BuildingFoundation->GetOffset("FoundationEnabledState", false); - - if (FoundationEnabledStateOffset != -1) - BuildingFoundation->Get(FoundationEnabledStateOffset) = EDynamicFoundationEnabledState::Enabled; -} - -static void StreamLevel(std::string LevelName, FVector Location = {}) -{ - static auto BuildingFoundation3x3Class = FindObject("/Script/FortniteGame.BuildingFoundation3x3"); - FTransform Transform{}; - Transform.Scale3D = { 1, 1, 1 }; - Transform.Translation = Location; - auto BuildingFoundation = (GetWorld()->SpawnActor(BuildingFoundation3x3Class, Transform)); - - if (!BuildingFoundation) - { - LOG_ERROR(LogGame, "Failed to spawn BuildingFoundation for streaming!"); - return; - } - - // BuildingFoundation->InitializeBuildingActor(BuildingFoundation, nullptr, false); - - static auto FoundationNameOffset = FindOffsetStruct("/Script/FortniteGame.BuildingFoundationStreamingData", "FoundationName"); - static auto FoundationLocationOffset = FindOffsetStruct("/Script/FortniteGame.BuildingFoundationStreamingData", "FoundationLocation"); - static auto StreamingDataOffset = BuildingFoundation->GetOffset("StreamingData"); - static auto LevelToStreamOffset = BuildingFoundation->GetOffset("LevelToStream"); - - auto StreamingData = BuildingFoundation->GetPtr<__int64>(StreamingDataOffset); - - *(FName*)(__int64(StreamingData) + FoundationNameOffset) = UKismetStringLibrary::Conv_StringToName(std::wstring(LevelName.begin(), LevelName.end()).c_str()); - *(FVector*)(__int64(StreamingData) + FoundationLocationOffset) = Location; - - *(FName*)(__int64(BuildingFoundation) + LevelToStreamOffset) = UKismetStringLibrary::Conv_StringToName(std::wstring(LevelName.begin(), LevelName.end()).c_str()); - - static auto OnRep_LevelToStreamFn = FindObject("/Script/FortniteGame.BuildingFoundation.OnRep_LevelToStream"); - BuildingFoundation->ProcessEvent(OnRep_LevelToStreamFn); - - ShowFoundation(BuildingFoundation); -} - FName AFortGameModeAthena::RedirectLootTier(const FName& LootTier) { static auto RedirectAthenaLootTierGroupsOffset = this->GetOffset("RedirectAthenaLootTierGroups", false); diff --git a/Project Reboot 3.0/FortGameModeAthena.h b/Project Reboot 3.0/FortGameModeAthena.h index c83632e..18a5ef8 100644 --- a/Project Reboot 3.0/FortGameModeAthena.h +++ b/Project Reboot 3.0/FortGameModeAthena.h @@ -3,6 +3,104 @@ #include "FortGameModePvPBase.h" // #include "FortPlayerControllerAthena.h" #include "FortGameStateAthena.h" +#include "KismetStringLibrary.h" +#include "reboot.h" +#include "BuildingSMActor.h" + +enum class EDynamicFoundationEnabledState : uint8_t +{ + Unknown = 0, + Enabled = 1, + Disabled = 2, + EDynamicFoundationEnabledState_MAX = 3 +}; + +enum class EDynamicFoundationType : uint8_t +{ + Static = 0, + StartEnabled_Stationary = 1, + StartEnabled_Dynamic = 2, + StartDisabled = 3, + EDynamicFoundationType_MAX = 4 +}; + +static void ShowFoundation(UObject* BuildingFoundation) +{ + if (!BuildingFoundation) + { + LOG_WARN(LogGame, "Attempting to show invalid building foundation."); + return; + } + + static auto bServerStreamedInLevelFieldMask = GetFieldMask(BuildingFoundation->GetProperty("bServerStreamedInLevel")); + static auto bServerStreamedInLevelOffset = BuildingFoundation->GetOffset("bServerStreamedInLevel"); + BuildingFoundation->SetBitfieldValue(bServerStreamedInLevelOffset, bServerStreamedInLevelFieldMask, true); + + static auto DynamicFoundationTypeOffset = BuildingFoundation->GetOffset("DynamicFoundationType"); + BuildingFoundation->Get(DynamicFoundationTypeOffset) = true ? 0 : 3; + + static auto bShowHLODWhenDisabledOffset = BuildingFoundation->GetOffset("bShowHLODWhenDisabled", false); + + if (bShowHLODWhenDisabledOffset != -1) + { + static auto bShowHLODWhenDisabledFieldMask = GetFieldMask(BuildingFoundation->GetProperty("bShowHLODWhenDisabled")); + BuildingFoundation->SetBitfieldValue(bShowHLODWhenDisabledOffset, bShowHLODWhenDisabledFieldMask, true); + } + + static auto OnRep_ServerStreamedInLevelFn = FindObject("/Script/FortniteGame.BuildingFoundation.OnRep_ServerStreamedInLevel"); + BuildingFoundation->ProcessEvent(OnRep_ServerStreamedInLevelFn); + + static auto DynamicFoundationRepDataOffset = BuildingFoundation->GetOffset("DynamicFoundationRepData", false); + + if (DynamicFoundationRepDataOffset != -1) + { + auto DynamicFoundationRepData = BuildingFoundation->GetPtr(DynamicFoundationRepDataOffset); + + static auto EnabledStateOffset = FindOffsetStruct("/Script/FortniteGame.DynamicBuildingFoundationRepData", "EnabledState"); + + *(EDynamicFoundationEnabledState*)(__int64(DynamicFoundationRepData) + EnabledStateOffset) = EDynamicFoundationEnabledState::Enabled; + + static auto OnRep_DynamicFoundationRepDataFn = FindObject("/Script/FortniteGame.BuildingFoundation.OnRep_DynamicFoundationRepData"); + BuildingFoundation->ProcessEvent(OnRep_DynamicFoundationRepDataFn); + } + + static auto FoundationEnabledStateOffset = BuildingFoundation->GetOffset("FoundationEnabledState", false); + + if (FoundationEnabledStateOffset != -1) + BuildingFoundation->Get(FoundationEnabledStateOffset) = EDynamicFoundationEnabledState::Enabled; +} + +static void StreamLevel(const std::string& LevelName, FVector Location = {}) +{ + static auto BuildingFoundation3x3Class = FindObject("/Script/FortniteGame.BuildingFoundation3x3"); + FTransform Transform{}; + Transform.Scale3D = { 1, 1, 1 }; + Transform.Translation = Location; + auto BuildingFoundation = GetWorld()->SpawnActor(BuildingFoundation3x3Class, Transform); + + if (!BuildingFoundation) + { + LOG_ERROR(LogGame, "Failed to spawn BuildingFoundation for streaming!"); + return; + } + + static auto FoundationNameOffset = FindOffsetStruct("/Script/FortniteGame.BuildingFoundationStreamingData", "FoundationName"); + static auto FoundationLocationOffset = FindOffsetStruct("/Script/FortniteGame.BuildingFoundationStreamingData", "FoundationLocation"); + static auto StreamingDataOffset = BuildingFoundation->GetOffset("StreamingData"); + static auto LevelToStreamOffset = BuildingFoundation->GetOffset("LevelToStream"); + + auto StreamingData = BuildingFoundation->GetPtr<__int64>(StreamingDataOffset); + + *(FName*)(__int64(StreamingData) + FoundationNameOffset) = UKismetStringLibrary::Conv_StringToName(std::wstring(LevelName.begin(), LevelName.end()).c_str()); + *(FVector*)(__int64(StreamingData) + FoundationLocationOffset) = Location; + + *(FName*)(__int64(BuildingFoundation) + LevelToStreamOffset) = UKismetStringLibrary::Conv_StringToName(std::wstring(LevelName.begin(), LevelName.end()).c_str()); + + static auto OnRep_LevelToStreamFn = FindObject("/Script/FortniteGame.BuildingFoundation.OnRep_LevelToStream"); + BuildingFoundation->ProcessEvent(OnRep_LevelToStreamFn); + + ShowFoundation(BuildingFoundation); +} class AFortGameModeAthena : public AFortGameModePvPBase { diff --git a/Project Reboot 3.0/FortInventory.cpp b/Project Reboot 3.0/FortInventory.cpp index d766ce6..e022637 100644 --- a/Project Reboot 3.0/FortInventory.cpp +++ b/Project Reboot 3.0/FortInventory.cpp @@ -180,10 +180,15 @@ std::pair, std::vector> AFortInventory::AddI bool (*ApplyGadgetData)(UFortGadgetItemDefinition * a1, __int64 a2, UFortItem* a3, unsigned __int8 a4) = decltype(ApplyGadgetData)(Addresses::ApplyGadgetData); static auto FortInventoryOwnerInterfaceClass = FindObject("/Script/FortniteGame.FortInventoryOwnerInterface"); - LOG_INFO(LogDev, "Res: {}", ApplyGadgetData(GadgetItemDefinition, __int64(PlayerController->GetInterfaceAddress(FortInventoryOwnerInterfaceClass)), NewItemInstance, true)); + auto Interface = __int64(PlayerController->GetInterfaceAddress(FortInventoryOwnerInterfaceClass)); + LOG_INFO(LogDev, "Res: {}", ApplyGadgetData(GadgetItemDefinition, Interface, NewItemInstance, true)); } } } + else + { + LOG_INFO(LogDev, "Not Valid!"); + } if (FortPlayerController && Engine_Version < 420) { diff --git a/Project Reboot 3.0/FortInventoryInterface.cpp b/Project Reboot 3.0/FortInventoryInterface.cpp index 43c4e19..e2840a9 100644 --- a/Project Reboot 3.0/FortInventoryInterface.cpp +++ b/Project Reboot 3.0/FortInventoryInterface.cpp @@ -30,13 +30,16 @@ char UFortInventoryInterface::RemoveInventoryItemHook(__int64 a1, FGuid a2, int if (!WorldInventory) return false; - bool bShouldUpdate = false; - WorldInventory->RemoveItem(a2, &bShouldUpdate, Count, bForceRemoval); + if (!Globals::bInfiniteAmmo) + { + bool bShouldUpdate = false; + WorldInventory->RemoveItem(a2, &bShouldUpdate, Count, bForceRemoval); - if (bShouldUpdate) - WorldInventory->Update(); + if (bShouldUpdate) + WorldInventory->Update(); + } - if (Engine_Version < 424) + if (Engine_Version < 424) // doesnt work on c2+ idk why { auto Pawn = PlayerController->GetMyFortPawn(); diff --git a/Project Reboot 3.0/FortLootPackage.cpp b/Project Reboot 3.0/FortLootPackage.cpp index 0207b67..7de1353 100644 --- a/Project Reboot 3.0/FortLootPackage.cpp +++ b/Project Reboot 3.0/FortLootPackage.cpp @@ -103,6 +103,9 @@ std::vector PickLootDrops(FName TierGroupName, bool bPrint, int recurs { LastNum1 = AmountOfRestarts; + LTDTables.clear(); + LPTables.clear(); + bool bFoundPlaylistTable = false; if (CurrentPlaylist) @@ -285,15 +288,29 @@ std::vector PickLootDrops(FName TierGroupName, bool bPrint, int recurs for (int i = 0; i < LTDTables.size(); i++) { - LTDTables.at(i)->AddToRoot(); - LOG_INFO(LogDev, "[{}] LTD {}", i, LTDTables.at(i)->GetFullName()); + auto& Table = LTDTables.at(i); + + if (!Table->IsValidLowLevel()) + { + continue; + } + + Table->AddToRoot(); + LOG_INFO(LogDev, "[{}] LTD {}", i, Table->GetFullName()); } for (int i = 0; i < LPTables.size(); i++) { - LPTables.at(i)->AddToRoot(); - LOG_INFO(LogDev, "[{}] LP {}", i, LPTables.at(i)->GetFullName()); - } + auto& Table = LPTables.at(i); + + if (!Table->IsValidLowLevel()) + { + continue; + } + + Table->AddToRoot(); + LOG_INFO(LogDev, "[{}] LP {}", i, Table->GetFullName()); + } } if (Fortnite_Version <= 6) // ahhh diff --git a/Project Reboot 3.0/FortPlayerController.cpp b/Project Reboot 3.0/FortPlayerController.cpp index 3707a5b..2db2eb0 100644 --- a/Project Reboot 3.0/FortPlayerController.cpp +++ b/Project Reboot 3.0/FortPlayerController.cpp @@ -33,6 +33,9 @@ void AFortPlayerController::ClientReportDamagedResourceBuilding(ABuildingSMActor bool AFortPlayerController::DoesBuildFree() { + if (Globals::bInfiniteMaterials) + return true; + static auto bBuildFreeOffset = GetOffset("bBuildFree"); static auto bBuildFreeFieldMask = GetFieldMask(GetProperty("bBuildFree")); return ReadBitfieldValue(bBuildFreeOffset, bBuildFreeFieldMask); @@ -175,11 +178,6 @@ void AFortPlayerController::ApplyCosmeticLoadout() UFortKismetLibrary::StaticClass()->ProcessEvent(UpdatePlayerCustomCharacterPartsVisualizationFn, &PlayerStateAsFort); } -void AFortPlayerController::ServerSetInventoryStateValueHook(AFortPlayerController* PlayerController, FGuid a2, __int64 StateValue) -{ - LOG_INFO(LogDev, "ServerSetInventoryStateValueHook! Please tell Milxnor if this gets logged."); -} - void AFortPlayerController::ServerLoadingScreenDroppedHook(UObject* Context, FFrame* Stack, void* Ret) { auto PlayerController = (AFortPlayerController*)Context; @@ -709,9 +707,11 @@ void AFortPlayerController::ServerCreateBuildingActorHook(UObject* Context, FFra auto MatInstance = WorldInventory->FindItemInstance(MatDefinition); - bool bShouldDestroy = MatInstance && MatInstance->GetItemEntry() ? (PlayerController->DoesBuildFree() ? false : MatInstance->GetItemEntry()->GetCount() < 10) : true; + bool bBuildFree = PlayerController->DoesBuildFree(); - if (bShouldDestroy) + bool bShouldDestroy = MatInstance && MatInstance->GetItemEntry() ? MatInstance->GetItemEntry()->GetCount() < 10 : true; + + if (bShouldDestroy && !bBuildFree) { BuildingActor->SilentDie(); return ServerCreateBuildingActorOriginal(Context, Stack, Ret); @@ -721,7 +721,7 @@ void AFortPlayerController::ServerCreateBuildingActorHook(UObject* Context, FFra BuildingActor->InitializeBuildingActor(PlayerController, BuildingActor, true); BuildingActor->SetTeam(PlayerStateAthena->GetTeamIndex()); // required? - if (!PlayerController->DoesBuildFree()) + if (!bBuildFree) { bool bShouldUpdate = false; WorldInventory->RemoveItem(MatInstance->GetItemEntry()->GetItemGuid(), &bShouldUpdate, 10); diff --git a/Project Reboot 3.0/FortPlayerController.h b/Project Reboot 3.0/FortPlayerController.h index 47f9d53..f4d4f87 100644 --- a/Project Reboot 3.0/FortPlayerController.h +++ b/Project Reboot 3.0/FortPlayerController.h @@ -84,7 +84,6 @@ public: void DropAllItems(const std::vector& IgnoreItemDefs, bool bIgnoreSecondaryQuickbar = false, bool bRemoveIfNotDroppable = false); void ApplyCosmeticLoadout(); - static void ServerSetInventoryStateValueHook(AFortPlayerController* PlayerController, FGuid a2, __int64 StateValue); static void ServerLoadingScreenDroppedHook(UObject* Context, FFrame* Stack, void* Ret); static void ServerRepairBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToRepair); static void ServerExecuteInventoryItemHook(AFortPlayerController* PlayerController, FGuid ItemGuid); diff --git a/Project Reboot 3.0/FortPlayerControllerAthena.h b/Project Reboot 3.0/FortPlayerControllerAthena.h index 1c62921..ce112d6 100644 --- a/Project Reboot 3.0/FortPlayerControllerAthena.h +++ b/Project Reboot 3.0/FortPlayerControllerAthena.h @@ -6,6 +6,7 @@ #include "SoftObjectPtr.h" #include "FortKismetLibrary.h" #include "AthenaMarkerComponent.h" +#include "FortVolume.h" static void ApplyCID(AFortPlayerPawn* Pawn, UObject* CID, bool bUseServerChoosePart = false) { diff --git a/Project Reboot 3.0/FortPlayerPawn.cpp b/Project Reboot 3.0/FortPlayerPawn.cpp index fd2be1b..597af0f 100644 --- a/Project Reboot 3.0/FortPlayerPawn.cpp +++ b/Project Reboot 3.0/FortPlayerPawn.cpp @@ -197,7 +197,7 @@ void AFortPlayerPawn::ServerHandlePickupHook(AFortPlayerPawn* Pawn, AFortPickup* static auto OnRep_bPickedUpFn = FindObject(L"/Script/FortniteGame.FortPickup.OnRep_bPickedUp"); Pickup->ProcessEvent(OnRep_bPickedUpFn); -} + } void AFortPlayerPawn::ServerHandlePickupInfoHook(AFortPlayerPawn* Pawn, AFortPickup* Pickup, __int64 Params) { diff --git a/Project Reboot 3.0/FortPlaysetItemDefinition.cpp b/Project Reboot 3.0/FortPlaysetItemDefinition.cpp index a3b1c8d..93a457b 100644 --- a/Project Reboot 3.0/FortPlaysetItemDefinition.cpp +++ b/Project Reboot 3.0/FortPlaysetItemDefinition.cpp @@ -1,7 +1,27 @@ #include "FortPlaysetItemDefinition.h" +#include "PlaysetLevelStreamComponent.h" + void UFortPlaysetItemDefinition::ShowPlayset(UFortPlaysetItemDefinition* PlaysetItemDef, AFortVolume* Volume) { + /* This doesn't stream it to the client. + + static auto SpawnPlaysetFn = FindObject("/Script/FortniteGame.FortPlaysetItemDefinition.SpawnPlayset"); + + struct + { + UObject* WorldContextObject; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + UFortPlaysetItemDefinition* Playset; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + FVector Location; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + FRotator Rotation; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, NativeAccessSpecifierPublic) + char pad[0x100]; // idk out param stuff + } UFortPlaysetItemDefinition_SpawnPlayset_Params{GetWorld(), PlaysetItemDef, Volume->GetActorLocation(), FRotator()}; + + static auto defaultObj = FindObject("/Script/FortniteGame.Default__FortPlaysetItemDefinition"); + defaultObj->ProcessEvent(SpawnPlaysetFn, &UFortPlaysetItemDefinition_SpawnPlayset_Params); + + return; */ + auto VolumeToUse = Volume; static auto PlaysetLevelStreamComponentClass = FindObject("/Script/FortniteGame.PlaysetLevelStreamComponent"); diff --git a/Project Reboot 3.0/FortPlaysetItemDefinition.h b/Project Reboot 3.0/FortPlaysetItemDefinition.h index 77e8429..5be8ce2 100644 --- a/Project Reboot 3.0/FortPlaysetItemDefinition.h +++ b/Project Reboot 3.0/FortPlaysetItemDefinition.h @@ -3,9 +3,7 @@ #include "FortItemDefinition.h" #include "FortVolume.h" -using UPlaysetLevelStreamComponent = UObject; - -extern inline __int64 (*LoadPlaysetOriginal)(UPlaysetLevelStreamComponent* a1) = nullptr; +extern inline __int64 (*LoadPlaysetOriginal)(class UPlaysetLevelStreamComponent* a1) = nullptr; class UFortPlaysetItemDefinition : public UFortItemDefinition // UFortAccountItemDefinition { diff --git a/Project Reboot 3.0/FortVolume.h b/Project Reboot 3.0/FortVolume.h index 2d4b275..48909b6 100644 --- a/Project Reboot 3.0/FortVolume.h +++ b/Project Reboot 3.0/FortVolume.h @@ -20,6 +20,12 @@ public: return Get(VolumeStateOffset); } + void SetCurrentPlayset(class UFortPlaysetItemDefinition* NewPlayset) + { + static auto SetCurrentPlaysetFn = FindObject("/Script/FortniteGame.FortVolume.SetCurrentPlayset"); + this->ProcessEvent(SetCurrentPlaysetFn, &NewPlayset); + } + void UpdateSize(const FVector& Scale) { static auto UpdateSizeFn = FindObject("/Script/FortniteGame.FortVolume.UpdateSize"); diff --git a/Project Reboot 3.0/FortVolumeManager.cpp b/Project Reboot 3.0/FortVolumeManager.cpp new file mode 100644 index 0000000..da31e27 --- /dev/null +++ b/Project Reboot 3.0/FortVolumeManager.cpp @@ -0,0 +1,14 @@ +#include "FortVolumeManager.h" + +AFortVolume* AFortVolumeManager::SpawnVolumeHook(AFortVolumeManager* VolumeManager, UClass* VolumeActor, UFortPlaysetItemDefinition* Playset, FVector Location, FRotator Rotation) +{ + // They inlined SetPlayset idk why + + static auto VolumeObjectsOffset = VolumeManager->GetOffset("VolumeObjects"); + auto& VolumeObjects = VolumeManager->Get>(VolumeObjectsOffset); + + LOG_INFO(LogDev, "SpawnVolumeHook!"); + auto ret = SpawnVolumeOriginal(VolumeManager, VolumeActor, Playset, Location, Rotation); + + return ret; +} \ No newline at end of file diff --git a/Project Reboot 3.0/FortVolumeManager.h b/Project Reboot 3.0/FortVolumeManager.h new file mode 100644 index 0000000..4f31cab --- /dev/null +++ b/Project Reboot 3.0/FortVolumeManager.h @@ -0,0 +1,13 @@ +#pragma once + +#include "FortVolume.h" + +#include "FortPlaysetItemDefinition.h" + +class AFortVolumeManager : public AActor +{ +public: + static inline AFortVolume* (*SpawnVolumeOriginal)(AFortVolumeManager* VolumeManager, UClass* VolumeActor, UFortPlaysetItemDefinition* Playset, FVector Location, FRotator Rotation); + + static AFortVolume* SpawnVolumeHook(AFortVolumeManager* VolumeManager, UClass* VolumeActor, UFortPlaysetItemDefinition* Playset, FVector Location, FRotator Rotation); +}; \ No newline at end of file diff --git a/Project Reboot 3.0/GameplayStatics.h b/Project Reboot 3.0/GameplayStatics.h index bbd4fa3..591ca5c 100644 --- a/Project Reboot 3.0/GameplayStatics.h +++ b/Project Reboot 3.0/GameplayStatics.h @@ -9,7 +9,16 @@ class UGameplayStatics : public UObject public: static TArray GetAllActorsOfClass(const UObject* WorldContextObject, UClass* ActorClass); static float GetTimeSeconds(UObject* WorldContextObject); + static UObject* SpawnObject(UClass* ObjectClass, UObject* Outer); + + template + static ObjectType* SpawnObject(UClass* ObjectClass, UObject* Outer, bool bCheckType) + { + auto Object = SpawnObject(ObjectClass, Outer); + return bCheckType ? Cast(Object) : (ObjectType*)Object; + } + // static void OpenLevel(UObject* WorldContextObject, FName LevelName, bool bAbsolute, const FString& Options); static void RemovePlayer(class APlayerController* Player, bool bDestroyPawn); diff --git a/Project Reboot 3.0/PlayerController.cpp b/Project Reboot 3.0/PlayerController.cpp index 92e84c4..c96854a 100644 --- a/Project Reboot 3.0/PlayerController.cpp +++ b/Project Reboot 3.0/PlayerController.cpp @@ -1,7 +1,14 @@ #include "PlayerController.h" +#include "GameplayStatics.h" #include "reboot.h" +UCheatManager*& APlayerController::SpawnCheatManager(UClass* CheatManagerClass) +{ + GetCheatManager() = UGameplayStatics::SpawnObject(CheatManagerClass, this, true); + return GetCheatManager(); +} + FRotator APlayerController::GetControlRotation() { static auto fn = FindObject(L"/Script/Engine.Controller.GetControlRotation"); diff --git a/Project Reboot 3.0/PlayerController.h b/Project Reboot 3.0/PlayerController.h index c6937b5..547d041 100644 --- a/Project Reboot 3.0/PlayerController.h +++ b/Project Reboot 3.0/PlayerController.h @@ -2,6 +2,7 @@ #include "Class.h" #include "Controller.h" +#include "CheatManager.h" #include "Rotator.h" @@ -32,6 +33,13 @@ public: return this->Get(PawnOffset); } + UCheatManager*& GetCheatManager() + { + static auto CheatManagerOffset = this->GetOffset("CheatManager"); + return this->Get(CheatManagerOffset); + } + + UCheatManager*& SpawnCheatManager(UClass* CheatManagerClass); FRotator GetControlRotation(); void Possess(class APawn* Pawn); void ServerRestartPlayer(); diff --git a/Project Reboot 3.0/PlaysetLevelStreamComponent.cpp b/Project Reboot 3.0/PlaysetLevelStreamComponent.cpp new file mode 100644 index 0000000..ef1527c --- /dev/null +++ b/Project Reboot 3.0/PlaysetLevelStreamComponent.cpp @@ -0,0 +1,13 @@ +#include "PlaysetLevelStreamComponent.h" + +void UPlaysetLevelStreamComponent::SetPlaysetHook(UPlaysetLevelStreamComponent* Component, UFortPlaysetItemDefinition* NewPlayset) +{ + SetPlaysetOriginal(Component, NewPlayset); + + auto Volume = Cast(Component->GetOwner()); + + LOG_INFO(LogDev, "Volume: {}", __int64(Volume)); + + if (!Volume || !Volume->HasAuthority()) + return; +} \ No newline at end of file diff --git a/Project Reboot 3.0/PlaysetLevelStreamComponent.h b/Project Reboot 3.0/PlaysetLevelStreamComponent.h new file mode 100644 index 0000000..04d3601 --- /dev/null +++ b/Project Reboot 3.0/PlaysetLevelStreamComponent.h @@ -0,0 +1,13 @@ +#pragma once + +#include "ActorComponent.h" + +#include "FortPlaysetItemDefinition.h" + +class UPlaysetLevelStreamComponent : public UActorComponent +{ +public: + static inline void (*SetPlaysetOriginal)(UPlaysetLevelStreamComponent* Component, UFortPlaysetItemDefinition* NewPlayset); + + static void SetPlaysetHook(UPlaysetLevelStreamComponent* Component, UFortPlaysetItemDefinition* NewPlayset); +}; \ No newline at end of file diff --git a/Project Reboot 3.0/Project Reboot 3.0.vcxproj b/Project Reboot 3.0/Project Reboot 3.0.vcxproj index ade4410..b7f2570 100644 --- a/Project Reboot 3.0/Project Reboot 3.0.vcxproj +++ b/Project Reboot 3.0/Project Reboot 3.0.vcxproj @@ -1,4 +1,4 @@ - + @@ -182,6 +182,7 @@ + @@ -266,6 +267,7 @@ + diff --git a/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters b/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters index 2edc58a..366a032 100644 --- a/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters +++ b/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -108,7 +108,7 @@ FortniteGame\Source\FortniteGame\Private\Pawns - Reboot\Private\Gameplay + FortniteGame\Source\FortniteGame\Public\Private\Gameplay FortniteGame\Source\FortniteGame\Private\Player @@ -141,7 +141,7 @@ Engine\Source\Runtime\Engine\Private - Reboot\Private + FortniteGame\Source\FortniteGame\Public\Private Engine\Source\Runtime\Engine\Classes\Engine @@ -227,6 +227,9 @@ FortniteGame\Source\FortniteGame\Private\Vehicles + + Engine\Source\Runtime\Engine\Private + @@ -704,6 +707,9 @@ Engine\Source\Runtime\Core\Public\Templates + + Engine\Source\Runtime\Engine\Classes\GameFramework + @@ -853,15 +859,9 @@ {bcb0d983-0b85-4ca6-9fac-6567c7d79921} - - {563ca89b-be74-42a6-a995-f87ac7a532e4} - {ad1c6299-9a6d-4eba-a1f8-66642a8afd21} - - {52d438db-beaf-44be-bddd-9aeb07c2459f} - {9923af6f-0a65-43f7-ad58-8a66e83814ba} @@ -925,6 +925,12 @@ {2eee3380-ea4b-4137-b058-b57a7b66005e} + + {563ca89b-be74-42a6-a995-f87ac7a532e4} + + + {52d438db-beaf-44be-bddd-9aeb07c2459f} + diff --git a/Project Reboot 3.0/commands.h b/Project Reboot 3.0/commands.h index eb0ae47..307f502 100644 --- a/Project Reboot 3.0/commands.h +++ b/Project Reboot 3.0/commands.h @@ -143,6 +143,8 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg) // std::cout << "NumArgs: " << NumArgs << '\n'; + bool bSendHelpMessage = false; + if (Arguments.size() >= 1) { auto& Command = Arguments[0]; @@ -194,60 +196,6 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg) SendMessageToConsole(PlayerController, L"Granted item!"); } - /* else if (Command == "giveprefab") - { - if (NumArgs < 1) - { - SendMessageToConsole(PlayerController, L"Please provide a WID!"); - return; - } - - auto WorldInventory = ReceivingController->GetWorldInventory(); - - if (!WorldInventory) - { - SendMessageToConsole(PlayerController, L"No world inventory!"); - return; - } - - auto& weaponName = Arguments[1]; - int count = 1; - - try - { - if (NumArgs >= 2) - count = std::stoi(Arguments[2]); - } - catch (...) - { - } - - // LOG_INFO(LogDev, "weaponName: {}", weaponName); - - auto WID = Cast(FindObject(weaponName, nullptr, ANY_PACKAGE)); - - if (!WID) - { - SendMessageToConsole(PlayerController, L"Invalid WID!"); - return; - } - - bool bShouldUpdate = false; - auto NewAndModifiedInstances = WorldInventory->AddItem(WID, &bShouldUpdate, count); - - auto NewPrefabInstance = NewAndModifiedInstances.first[0]; - - if (!NewPrefabInstance) - { - SendMessageToConsole(PlayerController, L"Failed to give item!"); - return; - } - - if (bShouldUpdate) - WorldInventory->Update(); - - SendMessageToConsole(PlayerController, L"Granted item!"); - } */ else if (Command == "spawnpickup") { if (NumArgs < 1) @@ -256,7 +204,7 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg) return; } - auto Pawn = PlayerController->GetMyFortPawn(); + auto Pawn = ReceivingController->GetMyFortPawn(); if (!Pawn) { @@ -344,6 +292,7 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg) bool bZOverride; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) } ACharacter_LaunchCharacter_Params{ FVector(X, Y, Z), false, false}; Pawn->ProcessEvent(LaunchCharacterFn, &ACharacter_LaunchCharacter_Params); + SendMessageToConsole(PlayerController, L"Launched character!"); } else if (Command == "setshield") @@ -486,28 +435,18 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg) { UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"pausesafezone", nullptr); } - else if (Command == "testspawn") + else if (Command == "teleport") { - auto Pawn = Cast(ReceivingController->GetPawn()); + auto CheatManager = ReceivingController->SpawnCheatManager(UCheatManager::StaticClass()); - if (!Pawn) + if (!CheatManager) { - SendMessageToConsole(PlayerController, L"No pawn to teleport!"); + SendMessageToConsole(PlayerController, L"Failed to spawn player's cheat manager!"); return; } - auto Class = FindObject("/Game/Athena/Items/Gameplay/MinigameSettingsControl/MinigameSettingsMachine.MinigameSettingsMachine_C"); - - if (!Class) - { - SendMessageToConsole(PlayerController, L"Failed to find Class!"); - return; - } - - auto PawnLocation = Pawn->GetActorLocation(); - PawnLocation.Z += 250; - GetWorld()->SpawnActor(Class, PawnLocation); - SendMessageToConsole(PlayerController, L"Spawned!"); + CheatManager->Teleport(); + CheatManager = nullptr; } else if (Command == "bugitgo") { @@ -537,5 +476,28 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg) Pawn->TeleportTo(FVector(X, Y, Z), Pawn->GetActorRotation()); SendMessageToConsole(PlayerController, L"Teleported!"); } + else { bSendHelpMessage = true; }; + } + else { bSendHelpMessage = true; }; + + if (bSendHelpMessage) + { + FString HelpMessage = LR"( +cheat giveitem - Gives a weapon to the executing player, if inventory is full drops a pickup on the player. +cheat summon - Summons the specified blueprint class at the executing player's location. Note: There is a limit on the count. +cheat bugitgo - Teleport to a location. +cheat launch - Launches a player. +cheat listplayers - Gives you all players names. +cheat pausesafezone - Pauses the zone. +cheat sethealth - Sets executing player's health. +cheat setshield - Sets executing player's shield. +cheat applycid - Sets a player's character. +cheat spawnpickup - Spawns a pickup at specified player. +cheat teleport - Teleports to what the player is looking at. + +If you want to execute a command on a certain player, surround their name (case sensitive) with \, and put the param anywhere. Example: cheat sethealth \Milxnor\ 100 +)"; + + SendMessageToConsole(PlayerController, HelpMessage); } } \ No newline at end of file diff --git a/Project Reboot 3.0/die.h b/Project Reboot 3.0/die.h index 5b00208..eac9365 100644 --- a/Project Reboot 3.0/die.h +++ b/Project Reboot 3.0/die.h @@ -4,8 +4,9 @@ #include "FortGameModeAthena.h" #include "GameplayStatics.h" #include "CurveTable.h" -#include "KismetStringLibrary.h"s +#include "KismetStringLibrary.h" #include "DataTableFunctionLibrary.h" +#include "FortPlaysetItemDefinition.h" static inline void (*SetZoneToIndexOriginal)(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK); @@ -259,7 +260,8 @@ void ProcessEventHook(UObject* Object, UFunction* Function, void* Parameters) !strstr(ObjectName.c_str(), "FlopperSpawn") && !strstr(FunctionFullName.c_str(), "GCNL_EnvCampFire_Fire_C") && !strstr(FunctionName.c_str(), "BlueprintGetAllHighlightableComponents") && - !strstr(FunctionFullName.c_str(), "Primitive_Structure_AmbAudioComponent")) + !strstr(FunctionFullName.c_str(), "Primitive_Structure_AmbAudioComponent") && + !strstr(FunctionName.c_str(), "ServerTriggerCombatEvent")) { LOG_INFO(LogDev, "Function called: {} with {}", FunctionFullName, ObjectName); } diff --git a/Project Reboot 3.0/dllmain.cpp b/Project Reboot 3.0/dllmain.cpp index 019c027..9acb005 100644 --- a/Project Reboot 3.0/dllmain.cpp +++ b/Project Reboot 3.0/dllmain.cpp @@ -34,6 +34,9 @@ #include "FortGameplayAbilityAthena_PeriodicItemGrant.h" #include "vendingmachine.h" #include "FortOctopusVehicle.h" +#include "FortVolumeManager.h" + +#include "PlaysetLevelStreamComponent.h" enum ENetMode { @@ -142,6 +145,8 @@ DWORD WINAPI Main(LPVOID) Sleep(1000); } + bSwitchedInitialLevel = true; + static auto GameModeDefault = FindObject(L"/Script/FortniteGame.Default__FortGameModeAthena"); static auto FortPlayerControllerZoneDefault = FindObject(L"/Script/FortniteGame.Default__FortPlayerControllerZone"); static auto FortPlayerControllerAthenaDefault = FindObject(L"/Script/FortniteGame.Default__FortPlayerControllerAthena"); // FindObject(L"/Game/Athena/Athena_PlayerController.Default__Athena_PlayerController_C"); @@ -157,6 +162,7 @@ DWORD WINAPI Main(LPVOID) // UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogNetTraffic VeryVerbose", nullptr); // UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogNet VeryVerbose", nullptr); UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogBuilding VeryVerbose", nullptr); + // UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogFortQuest VeryVerbose", nullptr); // UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogFortUIDirector NoLogging", nullptr); UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogAbilitySystem VeryVerbose", nullptr); UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogDataTable VeryVerbose", nullptr); @@ -415,10 +421,13 @@ DWORD WINAPI Main(LPVOID) LOG_INFO(LogDev, "OnPlayImpactFX: 0x{:x}", OnPlayImpactFXAddr - __int64(GetModuleHandleW(0))); Hooking::MinHook::Hook((PVOID)OnPlayImpactFXAddr, AFortWeapon::OnPlayImpactFXHook, (PVOID*)&AFortWeapon::OnPlayImpactFXOriginal); + /* Hooking::MinHook::Hook(FindObject("/Script/FortniteGame.Default__FortVolumeManager"), FindObject(L"/Script/FortniteGame.FortVolumeManager.SpawnVolume"), + AFortVolumeManager::SpawnVolumeHook, (PVOID*)&AFortVolumeManager::SpawnVolumeOriginal, false); + Hooking::MinHook::Hook((PVOID)GetFunctionIdxOrPtr(FindObject("/Script/FortniteGame.PlaysetLevelStreamComponent.SetPlayset"), true), + UPlaysetLevelStreamComponent::SetPlaysetHook, (PVOID*)&UPlaysetLevelStreamComponent::SetPlaysetOriginal); */ + Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject(L"/Script/FortniteGame.FortPlayerController.ServerDropAllItems"), AFortPlayerController::ServerDropAllItemsHook, nullptr, false); - Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject(L"/Script/FortniteGame.FortPlayerController.ServerSetInventoryStateValue"), - AFortPlayerController::ServerSetInventoryStateValueHook, nullptr, false); Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject("/Script/FortniteGame.FortPlayerController.ServerSpawnInventoryDrop") ? FindObject("/Script/FortniteGame.FortPlayerController.ServerSpawnInventoryDrop") : FindObject(L"/Script/FortniteGame.FortPlayerController.ServerAttemptInventoryDrop"), diff --git a/Project Reboot 3.0/globals.h b/Project Reboot 3.0/globals.h index 4cff373..5085950 100644 --- a/Project Reboot 3.0/globals.h +++ b/Project Reboot 3.0/globals.h @@ -11,6 +11,9 @@ namespace Globals extern inline bool bLogProcessEvent = false; extern inline bool bLateGame = false; + extern inline bool bInfiniteMaterials = false; + extern inline bool bInfiniteAmmo = false; + extern inline bool bHitReadyToStartMatch = false; extern inline bool bInitializedPlaylist = false; extern inline bool bStartedListening = false; @@ -24,4 +27,5 @@ extern inline std::string PlaylistName = // "/Game/Athena/Playlists/Carmine/Playlist_Carmine.Playlist_Carmine"; // "/Game/Athena/Playlists/Fill/Playlist_Fill_Solo.Playlist_Fill_Solo"; // "/Game/Athena/Playlists/Low/Playlist_Low_Solo.Playlist_Low_Solo"; -// "/Game/Athena/Playlists/Bling/Playlist_Bling_Solo.Playlist_Bling_Solo"; \ No newline at end of file +// "/Game/Athena/Playlists/Bling/Playlist_Bling_Solo.Playlist_Bling_Solo"; +// "/Game/Athena/Playlists/Creative/Playlist_PlaygroundV2.Playlist_PlaygroundV2"; \ No newline at end of file diff --git a/Project Reboot 3.0/gui.h b/Project Reboot 3.0/gui.h index bf19e8d..57d6a61 100644 --- a/Project Reboot 3.0/gui.h +++ b/Project Reboot 3.0/gui.h @@ -54,6 +54,7 @@ #define FUN_PLAYERTAB 5 static inline int SecondsUntilTravel = 5; +static bool bSwitchedInitialLevel = false; // THE BASE CODE IS FROM IMGUI GITHUB @@ -215,6 +216,9 @@ static int playerTabTab = MAIN_PLAYERTAB; void StaticUI() { + ImGui::Checkbox("Infinite Ammo", &Globals::bInfiniteAmmo); + ImGui::Checkbox("Infinite Materials", &Globals::bInfiniteMaterials); + ImGui::Checkbox("No MCP (Don't change unless you know what this is)", &Globals::bNoMCP); if (Addresses::ApplyGadgetData && Addresses::RemoveGadgetData) @@ -634,7 +638,9 @@ void PregameUI() ImGui::Checkbox("Play Event", &Globals::bGoingToPlayEvent); } - ImGui::SliderInt("Seconds until load into map", &SecondsUntilTravel, 1, 100); + if (!bSwitchedInitialLevel) + ImGui::SliderInt("Seconds until load into map", &SecondsUntilTravel, 1, 100); + ImGui::InputText("Playlist", &PlaylistName); }