From 8a4f50fd71f4e9d098b62046a8da55b4201b28d5 Mon Sep 17 00:00:00 2001 From: Milxnor Date: Thu, 16 Mar 2023 19:56:25 -0400 Subject: [PATCH] somecreatgive stuff --- Project Reboot 3.0/FortGameModeAthena.cpp | 34 ++++++++++-- Project Reboot 3.0/FortKismetLibrary.cpp | 14 +++-- Project Reboot 3.0/FortPlayerController.cpp | 47 +++++++++------- .../FortPlayerControllerAthena.cpp | 19 +++++++ .../FortPlayerControllerAthena.h | 1 + Project Reboot 3.0/KismetSystemLibrary.h | 14 +++++ Project Reboot 3.0/NetDriver.cpp | 18 +++++- Project Reboot 3.0/NetDriver.h | 1 + Project Reboot 3.0/Object.cpp | 2 + Project Reboot 3.0/addresses.cpp | 3 + Project Reboot 3.0/dllmain.cpp | 7 ++- Project Reboot 3.0/finder.h | 55 ++++++++++++++++--- Project Reboot 3.0/globals.h | 2 +- 13 files changed, 177 insertions(+), 40 deletions(-) diff --git a/Project Reboot 3.0/FortGameModeAthena.cpp b/Project Reboot 3.0/FortGameModeAthena.cpp index e6abc6c..3ba7d0c 100644 --- a/Project Reboot 3.0/FortGameModeAthena.cpp +++ b/Project Reboot 3.0/FortGameModeAthena.cpp @@ -458,9 +458,9 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game } } - if (!Globals::bCreative) + // if (!Globals::bCreative) { - static auto FortPlayerStartWarmupClass = FindObject("/Script/FortniteGame.FortPlayerStartWarmup"); + static auto FortPlayerStartWarmupClass = Globals::bCreative ? FindObject("/Script/FortniteGame.FortPlayerStartCreative") : FindObject("/Script/FortniteGame.FortPlayerStartWarmup"); TArray Actors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), FortPlayerStartWarmupClass); int ActorsNum = Actors.Num(); @@ -595,9 +595,16 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena if (bFirst) { bFirst = false; + + auto PlaylistToUse = GetPlaylistToUse(); - GameState->GetGamePhase() = EAthenaGamePhase::Warmup; - GameState->OnRep_GamePhase(); + // if (!PlaylistToUse || !PlaylistToUse->Get("bSkipWarmup")) + { + GameState->GetGamePhase() = EAthenaGamePhase::Warmup; + GameState->OnRep_GamePhase(); + } + + // GameState->OnRep_CurrentPlaylistInfo(); } static bool bSpawnedFloorLoot = false; @@ -886,7 +893,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena if (PlayersReadyOffset != 0) { auto& PlayersReady = Portal->Get>(PlayersReadyOffset); - PlayersReady.Add(PlayerStateUniqueId); + PlayersReady.Add(PlayerStateUniqueId); // im not even sure what this is } Portal->GetUserInitiatedLoad() = true; @@ -900,9 +907,26 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena Portal->GetLinkedVolume()->GetVolumeState() = EVolumeState::Ready; + if (auto Volume = NewPlayer->Get(CreativePlotLinkedVolumeOffset)) + { + static auto FortLevelSaveComponentClass = FindObject("/Script/FortniteGame.FortLevelSaveComponent"); + auto LevelSaveComponent = (UObject*)Volume->GetComponentByClass(FortLevelSaveComponentClass); + + if (LevelSaveComponent) + { + static auto AccountIdOfOwnerOffset = LevelSaveComponent->GetOffset("AccountIdOfOwner"); + LevelSaveComponent->Get(AccountIdOfOwnerOffset) = PlayerStateUniqueId; + + static auto bIsLoadedOffset = LevelSaveComponent->GetOffset("bIsLoaded"); + LevelSaveComponent->Get(bIsLoadedOffset) = true; + } + } + static auto IslandPlayset = FindObject("/Game/Playsets/PID_Playset_60x60_Composed.PID_Playset_60x60_Composed"); UFortPlaysetItemDefinition::ShowPlayset(IslandPlayset, Portal->GetLinkedVolume()); + + LOG_INFO(LogCreative, "Initialized player portal!"); } else { diff --git a/Project Reboot 3.0/FortKismetLibrary.cpp b/Project Reboot 3.0/FortKismetLibrary.cpp index c0cd096..836bcbd 100644 --- a/Project Reboot 3.0/FortKismetLibrary.cpp +++ b/Project Reboot 3.0/FortKismetLibrary.cpp @@ -72,8 +72,8 @@ void UFortKismetLibrary::GiveItemToInventoryOwnerHook(UObject* Context, FFrame& static auto ItemDefinitionOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.GiveItemToInventoryOwner", "ItemDefinition"); static auto NumberToGiveOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.GiveItemToInventoryOwner", "NumberToGive"); static auto bNotifyPlayerOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.GiveItemToInventoryOwner", "bNotifyPlayer"); - static auto ItemLevelOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.GiveItemToInventoryOwner", "ItemLevel"); - static auto PickupInstigatorHandleOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.GiveItemToInventoryOwner", "PickupInstigatorHandle"); + static auto ItemLevelOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.GiveItemToInventoryOwner", "ItemLevel", false); + static auto PickupInstigatorHandleOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.GiveItemToInventoryOwner", "PickupInstigatorHandle", false); // return GiveItemToInventoryOwnerOriginal(Context, Stack, Ret); @@ -88,8 +88,12 @@ void UFortKismetLibrary::GiveItemToInventoryOwnerHook(UObject* Context, FFrame& Stack.Step(Stack.Object, &ItemDefinition); Stack.Step(Stack.Object, &NumberToGive); Stack.Step(Stack.Object, &bNotifyPlayer); - Stack.Step(Stack.Object, &ItemLevel); - Stack.Step(Stack.Object, &PickupInstigatorHandle); + + if (ItemLevelOffset != 0) + Stack.Step(Stack.Object, &ItemLevel); + + if (PickupInstigatorHandleOffset != 0) + Stack.Step(Stack.Object, &PickupInstigatorHandle); if (!ItemDefinition) return GiveItemToInventoryOwnerOriginal(Context, Stack, Ret); @@ -156,6 +160,8 @@ void UFortKismetLibrary::K2_RemoveItemFromPlayerHook(UObject* Context, FFrame& S if (bShouldUpdate) WorldInventory->Update(); + LOG_INFO(LogDev, "Removed!"); + return K2_RemoveItemFromPlayerOriginal(Context, Stack, Ret); } diff --git a/Project Reboot 3.0/FortPlayerController.cpp b/Project Reboot 3.0/FortPlayerController.cpp index fc404cf..e76e06f 100644 --- a/Project Reboot 3.0/FortPlayerController.cpp +++ b/Project Reboot 3.0/FortPlayerController.cpp @@ -439,31 +439,40 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo static auto OnRep_DeathInfoFn = FindObject("/Script/FortniteGame.FortPlayerStateAthena.OnRep_DeathInfo"); DeadPlayerState->ProcessEvent(OnRep_DeathInfoFn); - auto WorldInventory = PlayerController->GetWorldInventory(); - - if (!WorldInventory) - return ClientOnPawnDiedOriginal(PlayerController, DeathReport); + bool bIsRespawningAllowed = true; - auto& ItemInstances = WorldInventory->GetItemList().GetItemInstances(); - - for (int i = 0; i < ItemInstances.Num(); i++) + if (!bIsRespawningAllowed) { - auto ItemInstance = ItemInstances.at(i); + auto WorldInventory = PlayerController->GetWorldInventory(); - if (!ItemInstance) - continue; + if (!WorldInventory) + return ClientOnPawnDiedOriginal(PlayerController, DeathReport); - auto ItemEntry = ItemInstance->GetItemEntry(); - auto WorldItemDefinition = Cast(ItemEntry->GetItemDefinition()); - - if (!WorldItemDefinition) - continue; + auto& ItemInstances = WorldInventory->GetItemList().GetItemInstances(); - if (!WorldItemDefinition->ShouldDropOnDeath()) - continue; + for (int i = 0; i < ItemInstances.Num(); i++) + { + auto ItemInstance = ItemInstances.at(i); - AFortPickup::SpawnPickup(WorldItemDefinition, DeathLocation, ItemEntry->GetCount(), EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::PlayerElimination, - ItemEntry->GetLoadedAmmo()); + if (!ItemInstance) + continue; + + auto ItemEntry = ItemInstance->GetItemEntry(); + auto WorldItemDefinition = Cast(ItemEntry->GetItemDefinition()); + + if (!WorldItemDefinition) + continue; + + // if (!WorldItemDefinition->ShouldDropOnDeath()) + // continue; + + AFortPickup::SpawnPickup(WorldItemDefinition, DeathLocation, ItemEntry->GetCount(), EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::PlayerElimination, + ItemEntry->GetLoadedAmmo()); + + WorldInventory->RemoveItem(ItemEntry->GetItemGuid(), nullptr, ItemEntry->GetCount()); + } + + WorldInventory->Update(); } return ClientOnPawnDiedOriginal(PlayerController, DeathReport); diff --git a/Project Reboot 3.0/FortPlayerControllerAthena.cpp b/Project Reboot 3.0/FortPlayerControllerAthena.cpp index 1878ea4..b9e1830 100644 --- a/Project Reboot 3.0/FortPlayerControllerAthena.cpp +++ b/Project Reboot 3.0/FortPlayerControllerAthena.cpp @@ -52,6 +52,24 @@ void ApplyCID(AFortPlayerPawn* Pawn, UObject* CID) } } +void AFortPlayerControllerAthena::ServerGiveCreativeItemHook(AFortPlayerControllerAthena* Controller, FFortItemEntry CreativeItem) +{ + // Don't worry, the validate has a check if it is a creative enabled mode or not, but we need to add a volume check. + + auto CreativeItemPtr = &CreativeItem; + auto ItemDefinition = CreativeItemPtr->GetItemDefinition(); + + if (!ItemDefinition) + return; + + bool bShouldUpdate = false; + auto LoadedAmmo = -1; // CreativeItemPtr->GetLoadedAmmo() + Controller->GetWorldInventory()->AddItem(ItemDefinition, &bShouldUpdate, CreativeItemPtr->GetCount(), LoadedAmmo, false); + + if (bShouldUpdate) + Controller->GetWorldInventory()->Update(Controller); +} + void AFortPlayerControllerAthena::ServerTeleportToPlaygroundLobbyIslandHook(AFortPlayerControllerAthena* Controller) { auto Pawn = Controller->GetMyFortPawn(); @@ -73,6 +91,7 @@ void AFortPlayerControllerAthena::ServerTeleportToPlaygroundLobbyIslandHook(AFor continue; Pawn->TeleportTo(CurrentPlayerStart->GetActorLocation(), Pawn->GetActorRotation()); + break; } AllCreativePlayerStarts.Free(); diff --git a/Project Reboot 3.0/FortPlayerControllerAthena.h b/Project Reboot 3.0/FortPlayerControllerAthena.h index 32e0617..385dda2 100644 --- a/Project Reboot 3.0/FortPlayerControllerAthena.h +++ b/Project Reboot 3.0/FortPlayerControllerAthena.h @@ -13,6 +13,7 @@ public: return (AFortPlayerStateAthena*)GetPlayerState(); } + static void ServerGiveCreativeItemHook(AFortPlayerControllerAthena* Controller, FFortItemEntry CreativeItem); static void ServerTeleportToPlaygroundLobbyIslandHook(AFortPlayerControllerAthena* Controller); static void ServerAcknowledgePossessionHook(APlayerController* Controller, APawn* Pawn); static void ServerPlaySquadQuickChatMessage(AFortPlayerControllerAthena* PlayerController, __int64 ChatEntry, __int64 SenderID); diff --git a/Project Reboot 3.0/KismetSystemLibrary.h b/Project Reboot 3.0/KismetSystemLibrary.h index 47c5d2b..7e84fa3 100644 --- a/Project Reboot 3.0/KismetSystemLibrary.h +++ b/Project Reboot 3.0/KismetSystemLibrary.h @@ -21,4 +21,18 @@ public: return Ret; } + + static void ExecuteConsoleCommand(UObject* WorldContextObject, const FString& Command, class APlayerController* SpecificPlayer) + { + static auto KismetSystemLibrary = FindObject("/Script/Engine.Default__KismetSystemLibrary"); + static auto fn = FindObject("/Script/Engine.KismetSystemLibrary.ExecuteConsoleCommand"); + + struct { + UObject* WorldContextObject; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + FString Command; // (Parm, ZeroConstructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + class APlayerController* SpecificPlayer; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + } UKismetSystemLibrary_ExecuteConsoleCommand_Params{WorldContextObject, Command, SpecificPlayer}; + + KismetSystemLibrary->ProcessEvent(fn, &UKismetSystemLibrary_ExecuteConsoleCommand_Params); + } }; \ No newline at end of file diff --git a/Project Reboot 3.0/NetDriver.cpp b/Project Reboot 3.0/NetDriver.cpp index ca7c574..e7aecc4 100644 --- a/Project Reboot 3.0/NetDriver.cpp +++ b/Project Reboot 3.0/NetDriver.cpp @@ -4,10 +4,22 @@ void UNetDriver::TickFlushHook(UNetDriver* NetDriver) { - static auto ReplicationDriverOffset = NetDriver->GetOffset("ReplicationDriver"); + static auto ReplicationDriverOffset = NetDriver->GetOffset("ReplicationDriver", false); - if (auto ReplicationDriver = NetDriver->Get(ReplicationDriverOffset)) - reinterpret_cast(ReplicationDriver->VFTable[Offsets::ServerReplicateActors])(ReplicationDriver); + if (ReplicationDriverOffset == 0) + { + NetDriver->ServerReplicateActors(); + } + else + { + if (auto ReplicationDriver = NetDriver->Get(ReplicationDriverOffset)) + reinterpret_cast(ReplicationDriver->VFTable[Offsets::ServerReplicateActors])(ReplicationDriver); + } return TickFlushOriginal(NetDriver); +} + +void UNetDriver::ServerReplicateActors() +{ + } \ No newline at end of file diff --git a/Project Reboot 3.0/NetDriver.h b/Project Reboot 3.0/NetDriver.h index 185946a..d46467c 100644 --- a/Project Reboot 3.0/NetDriver.h +++ b/Project Reboot 3.0/NetDriver.h @@ -31,4 +31,5 @@ public: bool InitListen(FNetworkNotify* InNotify, FURL& ListenURL, bool bReuseAddressAndPort, FString& Error) { return InitListenOriginal(this, InNotify, ListenURL, bReuseAddressAndPort, Error); } void SetWorld(UWorld* World) { return SetWorldOriginal(this, World); } + void ServerReplicateActors(); }; \ No newline at end of file diff --git a/Project Reboot 3.0/Object.cpp b/Project Reboot 3.0/Object.cpp index 75b3359..39f4126 100644 --- a/Project Reboot 3.0/Object.cpp +++ b/Project Reboot 3.0/Object.cpp @@ -25,6 +25,8 @@ void* UObject::GetProperty(const std::string& ChildName, bool bWarnIfNotFound) if (Property) { + // LOG_INFO(LogDev, "Reading prop name.."); + std::string PropName = getFNameOfProp(Property)->ToString(); // LOG_INFO(LogDev, "PropName: {}", PropName); diff --git a/Project Reboot 3.0/addresses.cpp b/Project Reboot 3.0/addresses.cpp index 0f73731..70037c9 100644 --- a/Project Reboot 3.0/addresses.cpp +++ b/Project Reboot 3.0/addresses.cpp @@ -112,6 +112,8 @@ void Addresses::SetupVersion() void Addresses::FindAll() { + auto Base = __int64(GetModuleHandleW(0)); + LOG_INFO(LogDev, "9241"); Addresses::ProcessEvent = FindProcessEvent(); UObject::ProcessEventOriginal = decltype(UObject::ProcessEventOriginal)(ProcessEvent); @@ -119,6 +121,7 @@ void Addresses::FindAll() Addresses::StaticFindObject = FindStaticFindObject(); StaticFindObjectOriginal = decltype(StaticFindObjectOriginal)(StaticFindObject); + LOG_INFO(LogDev, "StaticFindObject: 0x{:x}", StaticFindObject - Base); LOG_INFO(LogDev, "2151"); Addresses::GetPlayerViewpoint = FindGetPlayerViewpoint(); diff --git a/Project Reboot 3.0/dllmain.cpp b/Project Reboot 3.0/dllmain.cpp index cddaa53..7f8bf22 100644 --- a/Project Reboot 3.0/dllmain.cpp +++ b/Project Reboot 3.0/dllmain.cpp @@ -22,6 +22,7 @@ #include "commands.h" #include "FortAthenaSupplyDrop.h" #include "FortMinigame.h" +#include "KismetSystemLibrary.h" enum ENetMode { @@ -78,6 +79,8 @@ DWORD WINAPI Main(LPVOID) static auto FortAbilitySystemComponentAthenaDefault = FindObject(L"/Script/FortniteGame.Default__FortAbilitySystemComponentAthena"); static auto FortKismetLibraryDefault = FindObject(L"/Script/FortniteGame.Default__FortKismetLibrary"); + // UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogAbilitySystem VeryVerbose", nullptr); + static auto SwitchLevel = FindObject(L"/Script/Engine.PlayerController.SwitchLevel"); FString Level = Engine_Version < 424 ? L"Athena_Terrain" : Engine_Version >= 500 ? Engine_Version >= 501 @@ -195,6 +198,8 @@ DWORD WINAPI Main(LPVOID) AFortPlayerController::ServerEditBuildingActorHook, nullptr, false); Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject(L"/Script/FortniteGame.FortPlayerController.ServerEndEditingBuildingActor"), AFortPlayerController::ServerEndEditingBuildingActorHook, nullptr, false); + Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject(L"/Script/FortniteGame.FortPlayerControllerAthena.ServerGiveCreativeItem"), + AFortPlayerControllerAthena::ServerGiveCreativeItemHook, nullptr, true); Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject(L"/Script/FortniteGame.FortPlayerControllerAthena.ServerPlaySquadQuickChatMessage"), AFortPlayerControllerAthena::ServerPlaySquadQuickChatMessage, nullptr, false); Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject(L"/Script/FortniteGame.FortPlayerControllerAthena.ServerTeleportToPlaygroundLobbyIsland"), @@ -203,7 +208,7 @@ DWORD WINAPI Main(LPVOID) Hooking::MinHook::Hook(FortPlayerPawnAthenaDefault, FindObject(L"/Script/FortniteGame.FortPlayerPawn.ServerSendZiplineState"), AFortPlayerPawn::ServerSendZiplineStateHook, nullptr, false); - if (Addresses::FrameStep) // put all exec hooks in this scope + if (Addresses::FrameStep) // put all non rpc exec hooks in this scope { Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject(L"Script/FortniteGame.FortKismetLibrary.K2_GiveItemToPlayer"), UFortKismetLibrary::K2_GiveItemToPlayerHook, (PVOID*)&UFortKismetLibrary::K2_GiveItemToPlayerOriginal, false, true); diff --git a/Project Reboot 3.0/finder.h b/Project Reboot 3.0/finder.h index f394a12..04105c7 100644 --- a/Project Reboot 3.0/finder.h +++ b/Project Reboot 3.0/finder.h @@ -12,12 +12,14 @@ static inline uintptr_t FindBytes(Memcury::Scanner& Scanner, const std::vector= 427); - return FindBytes(Addr, { 0x48, 0x89, 0x5C }, 255, 0, true); // Addr.ScanFor(bytes, false).Get(); + auto Addr = Memcury::Scanner::FindStringRef(L"Illegal call to StaticFindObject() while serializing object data!", true, StringSkip, Engine_Version >= 427); + auto Final = FindBytes(Addr, { 0x48, 0x89, 0x5C }, 255, 0, true, 0, false); // Addr.ScanFor(bytes, false).Get(); + + return Final; } static inline uint64 FindProcessEvent() @@ -271,7 +275,14 @@ static inline uint64 FindSpecConstructor() return Memcury::Scanner::FindPattern("80 61 29 F8 48 8B 44 24 ?").Get(); // 11.31 if (Engine_Version == 425) - return Memcury::Scanner::FindPattern("48 8B 44 24 ? 80 61 29 F8 80 61 31 FE 48 89 41 20 33 C0 89 41").Get(); + { + auto ba = Memcury::Scanner::FindPattern("48 8B 44 24 ? 80 61 29 F8 80 61 31 FE 48 89 41 20 33 C0 89 41", false).Get(); + + if (!ba) + ba = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 56 48 83 EC 20 45 33 F6 48 C7 01 ? ? ? ? 48 C7 41").Get(); // i think this right for 12.00 ?? + + return ba; + } if (Engine_Version == 426) return Memcury::Scanner::FindPattern("80 61 31 FE 0F 57 C0 80 61 29 F0 48 8B 44 24 ? 48").Get(); @@ -410,14 +421,44 @@ static inline uint64 FindNavSystemCleanUp() return FindBytes(Addr, { 0x48, 0x89, 0x5C }, 500, 0, true); } -static inline uint64 FindLoadPlayset() +static inline uint64 FindLoadPlayset(const std::vector& Bytes = std::vector({ 0x48, 0x89, 0x5C }), int recursive = 0) { + if (recursive >= 2) + return 0; + auto StringRef = Memcury::Scanner::FindStringRef(L"UPlaysetLevelStreamComponent::LoadPlayset Error: no owner for %s", Fortnite_Version >= 7); if (!StringRef.Get()) return 0; - return FindBytes(StringRef, { 0x48, 0x89, 0x5C }, 1000, 0, true); + for (int i = 0 + 0; i < 400 + 0; i++) // we should subtract from skip if goup + { + auto CurrentByte = *(Memcury::ASM::MNEMONIC*)(true ? StringRef.Get() - i : StringRef.Get() + i); + + if (CurrentByte == Bytes[0]) + { + bool Found = true; + for (int j = 1; j < Bytes.size(); j++) + { + if (*(Memcury::ASM::MNEMONIC*)(true ? StringRef.Get() - i + j : StringRef.Get() + i + j) != Bytes[j]) + { + Found = false; + break; + } + } + if (Found) + { + return true ? StringRef.Get() - i : StringRef.Get() + i; + } + } + + if (CurrentByte == 0xC3) + return FindLoadPlayset({ 0x40, 0x55 }, ++recursive); + + // std::cout << std::format("CurrentByte: 0x{:x}\n", (uint8_t)CurrentByte); + } + + return 0; } static inline uint64 FindGIsServer() diff --git a/Project Reboot 3.0/globals.h b/Project Reboot 3.0/globals.h index 9c301c7..69901e7 100644 --- a/Project Reboot 3.0/globals.h +++ b/Project Reboot 3.0/globals.h @@ -2,7 +2,7 @@ namespace Globals { - extern inline bool bCreative = false; + extern inline bool bCreative = true; extern inline bool bGoingToPlayEvent = false; extern inline bool bNoMCP = true; extern inline bool bLateGame = false;