diff --git a/Project Reboot 3.0/AbilitySystemComponent.h b/Project Reboot 3.0/AbilitySystemComponent.h index 53f723f..532f74f 100644 --- a/Project Reboot 3.0/AbilitySystemComponent.h +++ b/Project Reboot 3.0/AbilitySystemComponent.h @@ -4,10 +4,11 @@ #include "GameplayAbilitySpec.h" struct PadHex18 { char Pad[0x18]; }; +struct PadHexA8 { char Pad[0xA8]; }; struct PadHexB0 { char Pad[0xB0]; }; -using FPredictionKey = PadHex18; -using FGameplayEventData = PadHexB0; +using FPredictionKey = PadHex18; // PadHex18; +using FGameplayEventData = PadHexA8; // PadHexB0; class UAbilitySystemComponent : public UObject { diff --git a/Project Reboot 3.0/AbilitySystemComponent_Abilities.cpp b/Project Reboot 3.0/AbilitySystemComponent_Abilities.cpp index be6e6fb..f477703 100644 --- a/Project Reboot 3.0/AbilitySystemComponent_Abilities.cpp +++ b/Project Reboot 3.0/AbilitySystemComponent_Abilities.cpp @@ -6,7 +6,7 @@ void LoopSpecs(UAbilitySystemComponent* AbilitySystemComponent, std::functionGetOffset("ActivatableAbilities"); auto ActivatableAbilities = AbilitySystemComponent->GetPtr(ActivatableAbilitiesOffset); - static auto ItemsOffset = 0x0108; + static auto ItemsOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpecContainer", "Items"); auto Items = (TArray<__int64>*)(__int64(ActivatableAbilities) + ItemsOffset); static auto SpecSize = FGameplayAbilitySpec::GetStructSize(); @@ -28,7 +28,7 @@ void InternalServerTryActivateAbility(UAbilitySystemComponent* AbilitySystemComp auto Spec = AbilitySystemComponent->FindAbilitySpecFromHandle(Handle); - static auto CurrentOffset = 0x0000; + static auto CurrentOffset = FindOffsetStruct("/Script/GameplayAbilities.PredictionKey", "Current"); if (!Spec) { diff --git a/Project Reboot 3.0/Actor.cpp b/Project Reboot 3.0/Actor.cpp index f154557..16ebe55 100644 --- a/Project Reboot 3.0/Actor.cpp +++ b/Project Reboot 3.0/Actor.cpp @@ -27,4 +27,13 @@ void AActor::K2_DestroyActor() static auto DestroyActorFn = FindObject("/Script/Engine.Actor.K2_DestroyActor"); this->ProcessEvent(DestroyActorFn); +} + +FVector AActor::GetActorLocation() +{ + static auto K2_GetActorLocationFn = FindObject("/Script/Engine.Actor.K2_GetActorLocation"); + FVector ret; + this->ProcessEvent(K2_GetActorLocationFn, &ret); + + return ret; } \ No newline at end of file diff --git a/Project Reboot 3.0/Actor.h b/Project Reboot 3.0/Actor.h index 118f520..44f5c5f 100644 --- a/Project Reboot 3.0/Actor.h +++ b/Project Reboot 3.0/Actor.h @@ -8,6 +8,6 @@ public: struct FTransform GetTransform(); AActor* GetOwner(); - + struct FVector GetActorLocation(); void K2_DestroyActor(); }; \ No newline at end of file diff --git a/Project Reboot 3.0/Array.h b/Project Reboot 3.0/Array.h index f903570..332f5f9 100644 --- a/Project Reboot 3.0/Array.h +++ b/Project Reboot 3.0/Array.h @@ -23,8 +23,8 @@ public: public: - inline InElementType At(int i, int Size = sizeof(InElementType)) const { return *(InElementType*)(__int64(Data) + (static_cast(Size) * i)); } - inline InElementType at(int i, int Size = sizeof(InElementType)) const { return *(InElementType*)(__int64(Data) + (static_cast(Size) * i)); } + inline InElementType& At(int i, int Size = sizeof(InElementType)) const { return *(InElementType*)(__int64(Data) + (static_cast(Size) * i)); } + inline InElementType& at(int i, int Size = sizeof(InElementType)) const { return *(InElementType*)(__int64(Data) + (static_cast(Size) * i)); } inline InElementType* AtPtr(int i, int Size = sizeof(InElementType)) const { return (InElementType*)(__int64(Data) + (static_cast(Size) * i)); } inline int Num() const { return ArrayNum; } @@ -37,18 +37,18 @@ public: void Reserve(int Number, int Size = sizeof(InElementType)) { - LOG_INFO(LogDev, "ArrayNum {}", ArrayNum); + // LOG_INFO(LogDev, "ArrayNum {}", ArrayNum); // Data = (InElementType*)FMemory::Realloc(Data, (ArrayMax = ArrayNum + Number) * Size, 0); Data = /* (ArrayMax - ArrayNum) >= ArrayNum ? Data : */ (InElementType*)FMemory::Realloc(Data, (ArrayMax = Number + ArrayNum) * Size, 0); } FORCENOINLINE void ResizeGrow(int32 OldNum, int Size = sizeof(InElementType)) { - LOG_INFO(LogMemory, "FMemory::Realloc: {}", __int64(FMemory::Realloc)); + // LOG_INFO(LogMemory, "FMemory::Realloc: {}", __int64(FMemory::Realloc)); ArrayMax = ArrayNum; // CalculateSlackGrow(/* ArrayNum */ OldNum, ArrayMax, Size); // AllocatorInstance.ResizeAllocation(OldNum, ArrayMax, sizeof(ElementType)); - LOG_INFO(LogMemory, "ArrayMax: {} Size: {}", ArrayMax, Size); + // LOG_INFO(LogMemory, "ArrayMax: {} Size: {}", ArrayMax, Size); Data = (InElementType*)FMemory::Realloc(Data, ArrayMax * Size, 0); } @@ -84,7 +84,7 @@ public: int Add(const InElementType& New, int Size = sizeof(InElementType)) { - LOG_INFO(LogDev, "ArrayMax: {}", ArrayMax); + // LOG_INFO(LogDev, "ArrayMax: {}", ArrayMax); if ((ArrayNum + 1) > ArrayMax) { diff --git a/Project Reboot 3.0/BuildingActor.cpp b/Project Reboot 3.0/BuildingActor.cpp index 4cfb53f..1640fe8 100644 --- a/Project Reboot 3.0/BuildingActor.cpp +++ b/Project Reboot 3.0/BuildingActor.cpp @@ -15,7 +15,7 @@ void ABuildingActor::OnDamageServerHook(ABuildingActor* BuildingActor, float Dam FVector Momentum, /* FHitResult */ __int64 HitInfo, APlayerController* InstigatedBy, AActor* DamageCauser, /* FGameplayEffectContextHandle */ __int64 EffectContext) { - LOG_INFO(LogDev, "Befor3e"); + // LOG_INFO(LogDev, "Befor3e"); auto BuildingSMActor = Cast(BuildingActor); auto PlayerController = Cast(InstigatedBy); @@ -42,7 +42,7 @@ void ABuildingActor::OnDamageServerHook(ABuildingActor* BuildingActor, float Dam // auto GameState = Cast(GetWorld()->GetGGetGameStateAthena); UCurveTable* CurveTable = nullptr; // GameState->CurrentPlaylistInfo.BasePlaylist ? GameState->CurrentPlaylistInfo.BasePlaylist->ResourceRates.Get() : nullptr; - LOG_INFO(LogDev, "Before1"); + // LOG_INFO(LogDev, "Before1"); if (!CurveTable) CurveTable = FindObject("/Game/Athena/Balance/DataTables/AthenaResourceRates.AthenaResourceRates"); @@ -50,13 +50,14 @@ void ABuildingActor::OnDamageServerHook(ABuildingActor* BuildingActor, float Dam { // auto curveMap = ((UDataTable*)CurveTable)->GetRowMap(); - LOG_INFO(LogDev, "Before {}", __int64(CurveTable)); + // LOG_INFO(LogDev, "Before {}", __int64(CurveTable)); float Out; FString ContextString; - UDataTableFunctionLibrary::EvaluateCurveTableRow(CurveTable, BuildingResourceAmountOverride.RowName, 0, ContextString, nullptr, &Out); + EEvaluateCurveTableResult result; + UDataTableFunctionLibrary::EvaluateCurveTableRow(CurveTable, BuildingResourceAmountOverride.RowName, 0.f, ContextString, &result, &Out); - LOG_INFO(LogDev, "Out: {}", Out); + // LOG_INFO(LogDev, "Out: {}", Out); auto DamageThatWillAffect = Damage; diff --git a/Project Reboot 3.0/BuildingContainer.h b/Project Reboot 3.0/BuildingContainer.h new file mode 100644 index 0000000..135acb7 --- /dev/null +++ b/Project Reboot 3.0/BuildingContainer.h @@ -0,0 +1,8 @@ +#pragma once + +#include "BuildingSMActor.h" + +class ABuildingContainer : public ABuildingSMActor +{ +public: +}; \ No newline at end of file diff --git a/Project Reboot 3.0/Class.cpp b/Project Reboot 3.0/Class.cpp index 5b7161c..a58a83f 100644 --- a/Project Reboot 3.0/Class.cpp +++ b/Project Reboot 3.0/Class.cpp @@ -36,7 +36,7 @@ UObject* UClass::CreateDefaultObject() return DefaultObject; } -int UClass::GetPropertiesSize() +int UStruct::GetPropertiesSize() { return *(int*)(__int64(this) + Offsets::PropertiesSize); } \ No newline at end of file diff --git a/Project Reboot 3.0/Class.h b/Project Reboot 3.0/Class.h index 4221843..99fef22 100644 --- a/Project Reboot 3.0/Class.h +++ b/Project Reboot 3.0/Class.h @@ -12,14 +12,14 @@ struct UField : UObject class UStruct : public UField { - +public: + int GetPropertiesSize(); }; class UClass : public UStruct { public: UObject* CreateDefaultObject(); - int GetPropertiesSize(); }; class UFunction : public UStruct diff --git a/Project Reboot 3.0/DataTable.h b/Project Reboot 3.0/DataTable.h index b70aeec..c402695 100644 --- a/Project Reboot 3.0/DataTable.h +++ b/Project Reboot 3.0/DataTable.h @@ -8,7 +8,7 @@ class UDataTable : public UObject { public: template - TMap GetRowMap() + TMap& GetRowMap() { static auto RowStructOffset = FindOffsetStruct("/Script/Engine.DataTable", "RowStruct"); diff --git a/Project Reboot 3.0/DataTableFunctionLibrary.cpp b/Project Reboot 3.0/DataTableFunctionLibrary.cpp index 5c328e9..b16e599 100644 --- a/Project Reboot 3.0/DataTableFunctionLibrary.cpp +++ b/Project Reboot 3.0/DataTableFunctionLibrary.cpp @@ -3,7 +3,7 @@ #include "reboot.h" void UDataTableFunctionLibrary::EvaluateCurveTableRow(UCurveTable* CurveTable, FName RowName, float InXY, - FString ContextString, EEvaluateCurveTableResult* OutResult, float* OutXY) + const FString& ContextString, EEvaluateCurveTableResult* OutResult, float* OutXY) { static auto fn = FindObject("/Script/Engine.DataTableFunctionLibrary.EvaluateCurveTableRow"); @@ -17,10 +17,10 @@ void UDataTableFunctionLibrary::EvaluateCurveTableRow(UCurveTable* CurveTable, F DefaultClass->ProcessEvent(fn, &UDataTableFunctionLibrary_EvaluateCurveTableRow_Params); if (OutResult) - *OutResult = wtf1; + *OutResult = UDataTableFunctionLibrary_EvaluateCurveTableRow_Params.OutResult; if (OutXY) - *OutXY = wtf; + *OutXY = UDataTableFunctionLibrary_EvaluateCurveTableRow_Params.OutXY; } UClass* UDataTableFunctionLibrary::StaticClass() diff --git a/Project Reboot 3.0/DataTableFunctionLibrary.h b/Project Reboot 3.0/DataTableFunctionLibrary.h index e218ecd..ee61a21 100644 --- a/Project Reboot 3.0/DataTableFunctionLibrary.h +++ b/Project Reboot 3.0/DataTableFunctionLibrary.h @@ -15,7 +15,7 @@ class UDataTableFunctionLibrary : public UObject { public: static void EvaluateCurveTableRow(UCurveTable* CurveTable, FName RowName, float InXY, - FString ContextString, EEvaluateCurveTableResult* OutResult, float* OutXY); + const FString& ContextString, EEvaluateCurveTableResult* OutResult, float* OutXY); 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 f77b4bf..7291cab 100644 --- a/Project Reboot 3.0/FortGameModeAthena.cpp +++ b/Project Reboot 3.0/FortGameModeAthena.cpp @@ -4,9 +4,96 @@ #include "NetSerialization.h" #include "FortPlayerControllerAthena.h" #include "GameplayStatics.h" +#include "KismetStringLibrary.h" +#include "SoftObjectPtr.h" +#include "FortPickup.h" +#include "FortLootPackage.h" +#include "BuildingContainer.h" static bool bFirstPlayerJoined = false; +enum class EDynamicFoundationEnabledState : uint8_t +{ + Unknown = 0, + Enabled = 1, + Disabled = 2, + EDynamicFoundationEnabledState_MAX = 3 +}; + + +// Enum FortniteGame.EDynamicFoundationType +enum class EDynamicFoundationType : uint8_t +{ + Static = 0, + StartEnabled_Stationary = 1, + StartEnabled_Dynamic = 2, + StartDisabled = 3, + EDynamicFoundationType_MAX = 4 +}; + +void ShowFoundation(AActor* BuildingFoundation) +{ + SetBitfield(BuildingFoundation->GetPtr("bServerStreamedInLevel"), 2, true); + + static auto OnRep_ServerStreamedInLevelFn = FindObject("/Script/FortniteGame.BuildingFoundation.OnRep_ServerStreamedInLevel"); + BuildingFoundation->ProcessEvent(OnRep_ServerStreamedInLevelFn); + + static auto DynamicFoundationRepDataOffset = BuildingFoundation->GetOffset("DynamicFoundationRepData", false); + + if (DynamicFoundationRepDataOffset != 0) + { + 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"); + 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); + + 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); +} + +UObject* GetPlaylistToUse() +{ + auto Playlist = FindObject("/Game/Athena/Playlists/Playlist_DefaultSolo.Playlist_DefaultSolo"); + + if (Globals::bCreative) + Playlist = FindObject("/Game/Athena/Playlists/Creative/Playlist_PlaygroundV2.Playlist_PlaygroundV2"); + + return Playlist; +} + bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* GameMode) { auto GameState = GameMode->GetGameStateAthena(); @@ -18,9 +105,10 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game static auto PlaylistReplicationKeyOffset = FindOffsetStruct("/Script/FortniteGame.PlaylistPropertyArray", "PlaylistReplicationKey"); static auto BasePlaylistOffset = FindOffsetStruct("/Script/FortniteGame.PlaylistPropertyArray", "BasePlaylist"); + static auto OverridePlaylistOffset = FindOffsetStruct("/Script/FortniteGame.PlaylistPropertyArray", "OverridePlaylist"); *(UObject**)(__int64(CurrentPlaylistInfo) + BasePlaylistOffset) = Playlist; - // CurrentPlaylistInfo.OverridePlaylist = Playlist; + *(UObject**)(__int64(CurrentPlaylistInfo) + OverridePlaylistOffset) = Playlist; (*(int*)(__int64(CurrentPlaylistInfo) + PlaylistReplicationKeyOffset))++; CurrentPlaylistInfo->MarkArrayDirty(); @@ -30,7 +118,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game else { GameState->Get("CurrentPlaylistData") = Playlist; - GameState->OnRep_CurrentPlaylistInfo(); + GameState->OnRep_CurrentPlaylistInfo(); // calls OnRep_CurrentPlaylistData } }; @@ -47,12 +135,22 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game { LastNum2 = AmountOfRestarts; - auto Playlist = FindObject("/Game/Athena/Playlists/Playlist_DefaultSolo.Playlist_DefaultSolo"); - // SetPlaylist(Playlist); + GameMode->Get("WarmupRequiredPlayerCount") = 1; + + auto PlaylistToUse = GetPlaylistToUse(); - GameMode->Get("WarmupRequiredPlayerCount") = 1; + if (PlaylistToUse) + { + static auto AdditionalLevelsOffset = PlaylistToUse->GetOffset("AdditionalLevels"); + auto& AdditionalLevels = PlaylistToUse->Get>>(AdditionalLevelsOffset); - // LOG_INFO(LogLoading, "Set playlist!"); + for (int i = 0; i < AdditionalLevels.Num(); i++) + { + // auto World = Cast(Playlist->AdditionalLevels[i].Get()); + // StreamLevel(UKismetSystemLibrary::GetPathName(World->PersistentLevel).ToString()); + StreamLevel(AdditionalLevels.at(i).SoftObjectPtr.ObjectID.AssetPathName.ToString()); + } + } } /* static auto FortPlayerStartWarmupClass = FindObject("/Script/FortniteGame.FortPlayerStartWarmup"); @@ -122,9 +220,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game GameState->OnRep_GamePhase(); } - auto Playlist = FindObject("/Game/Athena/Playlists/Playlist_DefaultSolo.Playlist_DefaultSolo"); - // FindObject("/Game/Athena/Playlists/Playground/Playlist_Playground.Playlist_Playground"); - SetPlaylist(Playlist); + SetPlaylist(GetPlaylistToUse()); GameState->Get("WarmupCountdownEndTime") = TimeSeconds + Duration; GameMode->Get("WarmupCountdownDuration") = Duration; @@ -151,8 +247,87 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint return ++NextTeamIndex; } +enum class EFortCustomPartType : uint8_t // todo move +{ + Head = 0, + Body = 1, + Hat = 2, + Backpack = 3, + Charm = 4, + Face = 5, + NumTypes = 6, + EFortCustomPartType_MAX = 7 +}; + void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena* GameMode, AActor* NewPlayerActor) { + auto SpawnIsland_FloorLoot = FindObject("/Game/Athena/Environments/Blueprints/Tiered_Athena_FloorLoot_Warmup.Tiered_Athena_FloorLoot_Warmup_C"); + auto BRIsland_FloorLoot = FindObject("/Game/Athena/Environments/Blueprints/Tiered_Athena_FloorLoot_01.Tiered_Athena_FloorLoot_01_C"); + + TArray SpawnIsland_FloorLoot_Actors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), SpawnIsland_FloorLoot); + + TArray BRIsland_FloorLoot_Actors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), BRIsland_FloorLoot); + + auto SpawnIslandTierGroup = UKismetStringLibrary::Conv_StringToName(L"Loot_AthenaFloorLoot_Warmup"); + auto BRIslandTierGroup = UKismetStringLibrary::Conv_StringToName(L"Loot_AthenaFloorLoot"); + + float UpZ = 50; + + EFortPickupSourceTypeFlag SpawnFlag = EFortPickupSourceTypeFlag::Container; + + bool bPrintWarmup = false; + + for (int i = 0; i < SpawnIsland_FloorLoot_Actors.Num(); i++) + { + ABuildingContainer* CurrentActor = (ABuildingContainer*)SpawnIsland_FloorLoot_Actors.at(i); + + // CurrentActor->K2_DestroyActor(); + // continue; + + auto Location = CurrentActor->GetActorLocation(); + Location.Z += UpZ; + + std::vector> LootDrops = PickLootDrops(SpawnIslandTierGroup, bPrintWarmup); + + if (bPrintWarmup) + { + std::cout << "\n\n"; + } + + if (LootDrops.size()) + { + for (auto& LootDrop : LootDrops) + AFortPickup::SpawnPickup(LootDrop.first, Location, LootDrop.second, SpawnFlag); + } + } + + bool bPrint = false; + + int spawned = 0; + + for (int i = 0; i < BRIsland_FloorLoot_Actors.Num(); i++) + { + ABuildingContainer* CurrentActor = (ABuildingContainer*)BRIsland_FloorLoot_Actors.at(i); + + // CurrentActor->K2_DestroyActor(); + spawned++; + // continue; + + auto Location = CurrentActor->GetActorLocation(); + Location.Z += UpZ; + + std::vector> LootDrops = PickLootDrops(BRIslandTierGroup, bPrint); + + if (bPrint) + std::cout << "\n"; + + if (LootDrops.size()) + { + for (auto& LootDrop : LootDrops) + AFortPickup::SpawnPickup(LootDrop.first, Location, LootDrop.second, SpawnFlag); + } + } + auto GameState = GameMode->GetGameStateAthena(); auto NewPlayer = (AFortPlayerControllerAthena*)NewPlayerActor; @@ -179,6 +354,25 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena auto PlayerStateAthena = NewPlayer->GetPlayerStateAthena(); + static auto CharacterPartsOffset = PlayerStateAthena->GetOffset("CharacterParts", false); + + if (CharacterPartsOffset != 0) + { + auto CharacterParts = PlayerStateAthena->GetPtr<__int64>("CharacterParts"); + + static auto PartsOffset = FindOffsetStruct("/Script/FortniteGame.CustomCharacterParts", "Parts"); + auto Parts = (UObject**)(__int64(CharacterParts) + PartsOffset); // UCustomCharacterPart* Parts[0x6] + + static auto headPart = LoadObject("/Game/Characters/CharacterParts/Female/Medium/Heads/F_Med_Head1.F_Med_Head1"); + static auto bodyPart = LoadObject("/Game/Characters/CharacterParts/Female/Medium/Bodies/F_Med_Soldier_01.F_Med_Soldier_01"); + + Parts[(int)EFortCustomPartType::Head] = headPart; + Parts[(int)EFortCustomPartType::Body] = bodyPart; + + static auto OnRep_CharacterPartsFn = FindObject("/Script/FortniteGame.FortPlayerState.OnRep_CharacterParts"); + PlayerStateAthena->ProcessEvent(OnRep_CharacterPartsFn); + } + PlayerStateAthena->GetSquadId() = PlayerStateAthena->GetTeamIndex() - 2; // if (false) @@ -200,9 +394,11 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena if (false) { - static auto GameplayAbilitySet = FindObject("/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_AthenaPlayer.GAS_AthenaPlayer") ? - FindObject("/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_AthenaPlayer.GAS_AthenaPlayer") : - FindObject("/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_DefaultPlayer.GAS_DefaultPlayer"); + static auto GameplayAbilitySet = LoadObject(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_AthenaPlayer.GAS_AthenaPlayer") ? + LoadObject(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_AthenaPlayer.GAS_AthenaPlayer") : + LoadObject(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_DefaultPlayer.GAS_DefaultPlayer"); + + // LOG_INFO(LogDev, "GameplayAbilitySet {}", __int64(GameplayAbilitySet)); if (GameplayAbilitySet) { @@ -213,7 +409,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena { UClass* AbilityClass = GameplayAbilities->At(i); - LOG_INFO(LogDev, "AbilityClass {}", __int64(AbilityClass)); + // LOG_INFO(LogDev, "AbilityClass {}", __int64(AbilityClass)); if (!AbilityClass) continue; diff --git a/Project Reboot 3.0/FortInventory.cpp b/Project Reboot 3.0/FortInventory.cpp index 616f871..349ce4a 100644 --- a/Project Reboot 3.0/FortInventory.cpp +++ b/Project Reboot 3.0/FortInventory.cpp @@ -33,7 +33,7 @@ std::pair, std::vector> AFortInventory::AddI static auto FortItemEntrySize = *(int*)(__int64(FortItemEntryStruct) + Offsets::PropertiesSize); // LOG_INFO(LogDev, "FortItemEntryStruct {}", __int64(FortItemEntryStruct)); - LOG_INFO(LogDev, "FortItemEntrySize {}", __int64(FortItemEntrySize)); + // LOG_INFO(LogDev, "FortItemEntrySize {}", __int64(FortItemEntrySize)); GetItemList().GetItemInstances().Add(NewItemInstance); GetItemList().GetReplicatedEntries().Add(*NewItemInstance->GetItemEntry(), FortItemEntrySize); diff --git a/Project Reboot 3.0/FortItem.h b/Project Reboot 3.0/FortItem.h index 1b570c7..2acdf6a 100644 --- a/Project Reboot 3.0/FortItem.h +++ b/Project Reboot 3.0/FortItem.h @@ -18,6 +18,18 @@ struct FFortItemEntry : FFastArraySerializerItem static auto ItemDefinitionOffset = FindOffsetStruct("/Script/FortniteGame.FortItemEntry", "ItemDefinition"); return *(UObject**)(__int64(this) + ItemDefinitionOffset); } + + int& GetCount() + { + static auto CountOffset = FindOffsetStruct("/Script/FortniteGame.FortItemEntry", "Count"); + return *(int*)(__int64(this) + CountOffset); + } + + int& GetLoadedAmmo() + { + static auto LoadedAmmoOffset = FindOffsetStruct("/Script/FortniteGame.FortItemEntry", "LoadedAmmo"); + return *(int*)(__int64(this) + LoadedAmmoOffset); + } }; class UFortItem : public UObject diff --git a/Project Reboot 3.0/FortItemDefinition.cpp b/Project Reboot 3.0/FortItemDefinition.cpp index 838e7ac..09f005f 100644 --- a/Project Reboot 3.0/FortItemDefinition.cpp +++ b/Project Reboot 3.0/FortItemDefinition.cpp @@ -8,4 +8,16 @@ UFortItem* UFortItemDefinition::CreateTemporaryItemInstanceBP(int Count, int Lev ProcessEvent(CreateTemporaryItemInstanceBPFunction, &CreateTemporaryItemInstanceBP_Params); return CreateTemporaryItemInstanceBP_Params.ReturnValue; +} + +float UFortItemDefinition::GetMaxStackSize() +{ + static auto MaxStackSizeOffset = this->GetOffset("MaxStackSize"); + + bool bIsScalableFloat = false; + + if (!bIsScalableFloat) + return Get(MaxStackSizeOffset); + + return 0; } \ No newline at end of file diff --git a/Project Reboot 3.0/FortItemDefinition.h b/Project Reboot 3.0/FortItemDefinition.h index 9d01846..21fb8a9 100644 --- a/Project Reboot 3.0/FortItemDefinition.h +++ b/Project Reboot 3.0/FortItemDefinition.h @@ -10,4 +10,5 @@ class UFortItemDefinition : public UObject { public: UFortItem* CreateTemporaryItemInstanceBP(int Count, int Level = 1); + float GetMaxStackSize(); }; \ No newline at end of file diff --git a/Project Reboot 3.0/FortLootPackage.cpp b/Project Reboot 3.0/FortLootPackage.cpp index e69de29..03de19f 100644 --- a/Project Reboot 3.0/FortLootPackage.cpp +++ b/Project Reboot 3.0/FortLootPackage.cpp @@ -0,0 +1,330 @@ +#include "FortLootPackage.h" + +#include "DataTable.h" +#include "KismetMathLibrary.h" + +static FFortLootTierData* GetLootTierData(std::vector& LootTierData, bool bPrint) +{ + float TotalWeight = 0; + + for (auto Item : LootTierData) + { + TotalWeight += Item->GetWeight(); + } + + float RandomNumber = UKismetMathLibrary::RandomFloatInRange(0, TotalWeight); // is -1 needed? + + FFortLootTierData* SelectedItem = nullptr; + + if (bPrint) + { + std::cout << std::format("TotalWeight: {}\n", TotalWeight); + } + + for (auto Item : LootTierData) + { + if (bPrint) + { + std::cout << std::format("Rand: {} Weight: {}\n", RandomNumber, Item->GetWeight()); + } + + if (RandomNumber <= Item->GetWeight()) + { + SelectedItem = Item; + break; + } + + RandomNumber -= Item->GetWeight(); + } + + if (!SelectedItem) + return GetLootTierData(LootTierData, bPrint); + + return SelectedItem; +} + +static FFortLootPackageData* GetLootPackage(std::vector& LootPackages) +{ + float TotalWeight = 0; + + for (auto Item : LootPackages) + { + TotalWeight += Item->GetWeight(); + } + + float RandomNumber = UKismetMathLibrary::RandomFloatInRange(0, TotalWeight); // is -1 needed? + + FFortLootPackageData* SelectedItem = nullptr; + + for (auto Item : LootPackages) + { + if (RandomNumber <= Item->GetWeight()) + { + SelectedItem = Item; + break; + } + + RandomNumber -= Item->GetWeight(); + } + + if (!SelectedItem) + return GetLootPackage(LootPackages); + + return SelectedItem; +} + +std::vector> PickLootDrops(FName TierGroupName, bool bPrint, int recursive) +{ + std::vector> LootDrops; + + static std::vector LTDTables; + static std::vector LPTables; + + static bool bHasFoundTables = false; + + if (!bHasFoundTables) + { + bHasFoundTables = true; + + LTDTables.push_back(FindObject(L"/Game/Items/Datatables/AthenaLootTierData_Client.AthenaLootTierData_Client")); + LPTables.push_back(FindObject(L"/Game/Items/Datatables/AthenaLootPackages_Client.AthenaLootPackages_Client")); + } + + std::vector TierGroupLTDs; + + for (int p = 0; p < LTDTables.size(); p++) + { + auto LTD = LTDTables[p]; + auto& LTDRowMap = LTD->GetRowMap(); + + auto LTDRowMapNum = LTDRowMap.Pairs.Elements.Num(); + + // auto TierGroupNameStr = TierGroupName.ToString(); + + for (int i = 0; i < LTDRowMapNum; i++) + { + auto& CurrentLTD = LTDRowMap.Pairs.Elements[i].ElementData.Value; + auto TierData = (FFortLootTierData*)CurrentLTD.Value(); + + // auto TierDataGroupStr = TierData->TierGroup.ToString(); + + // std::cout << "TierData->TierGroup.ToString(): " << TierDataGroupStr << '\n'; + + if (TierGroupName == TierData->GetTierGroup() /* TierDataGroupStr == TierGroupNameStr */ && TierData->GetWeight() != 0) + { + TierGroupLTDs.push_back(TierData); + } + } + } + + if (TierGroupLTDs.size() == 0) + { + // std::cout << "Failed to find LTD!\n"; + std::cout << "Failed to find any LTD for: " << TierGroupName.ToString() << '\n'; + return LootDrops; + } + + if (bPrint) + { + std::cout << "TierGroupLTDs.size(): " << TierGroupLTDs.size() << '\n'; + } + + FFortLootTierData* ChosenRowLootTierData = GetLootTierData(TierGroupLTDs, bPrint); + + if (!ChosenRowLootTierData) // Should NEVER happen + return LootDrops; + + if (ChosenRowLootTierData->GetNumLootPackageDrops() <= 0) + return PickLootDrops(TierGroupName, bPrint, ++recursive); // hm + + auto& LootPackageCategoryMinArray = ChosenRowLootTierData->GetLootPackageCategoryMinArray(); + auto& LootPackageCategoryWeightArray = ChosenRowLootTierData->GetLootPackageCategoryWeightArray(); + auto& LootPackageCategoryMaxArray = ChosenRowLootTierData->GetLootPackageCategoryMaxArray(); + + if (LootPackageCategoryMinArray.ArrayNum != LootPackageCategoryWeightArray.ArrayNum || + LootPackageCategoryMinArray.ArrayNum != LootPackageCategoryMaxArray.ArrayNum) + return PickLootDrops(TierGroupName, bPrint, ++recursive); // hm + + int MinimumLootDrops = 0; + float NumLootPackageDrops = std::floor(ChosenRowLootTierData->GetNumLootPackageDrops()); + + if (LootPackageCategoryMinArray.ArrayNum) + { + for (int i = 0; i < LootPackageCategoryMinArray.ArrayNum; i++) + { + if (LootPackageCategoryMinArray.at(i) > 0) + { + MinimumLootDrops += LootPackageCategoryMinArray.at(i); + } + } + } + + if (MinimumLootDrops > NumLootPackageDrops) + { + + } + + int SumLootPackageCategoryWeightArray = 0; + + for (int i = 0; i < LootPackageCategoryWeightArray.Num(); i++) + { + auto CategoryWeight = LootPackageCategoryWeightArray.at(i); + + if (CategoryWeight > 0) + { + auto CategoryMaxArray = LootPackageCategoryMaxArray.at(i); + + if (CategoryMaxArray < 0) + { + SumLootPackageCategoryWeightArray += CategoryWeight; + } + } + } + + int SumLootPackageCategoryMinArray = 0; + + for (int i = 0; i < LootPackageCategoryMinArray.Num(); i++) + { + auto CategoryWeight = LootPackageCategoryMinArray.at(i); + + if (CategoryWeight > 0) + { + auto CategoryMaxArray = LootPackageCategoryMaxArray.at(i); + + if (CategoryMaxArray < 0) + { + SumLootPackageCategoryMinArray += CategoryWeight; + } + } + } + + if (SumLootPackageCategoryWeightArray > SumLootPackageCategoryMinArray) + return PickLootDrops(TierGroupName, bPrint, ++recursive); // hm + + std::vector TierGroupLPs; + + for (int p = 0; p < LPTables.size(); p++) + { + auto LP = LPTables[p]; + auto& LPRowMap = LP->GetRowMap(); + + for (int i = 0; i < LPRowMap.Pairs.Elements.Num(); i++) + { + auto& CurrentLP = LPRowMap.Pairs.Elements[i].ElementData.Value; + auto LootPackage = (FFortLootPackageData*)CurrentLP.Value(); + + if (!LootPackage) + continue; + + if (LootPackage->GetLootPackageID() == ChosenRowLootTierData->GetLootPackage() && LootPackage->GetWeight() != 0) + { + TierGroupLPs.push_back(LootPackage); + } + } + } + + auto ChosenLootPackageName = ChosenRowLootTierData->GetLootPackage().ToString(); + + if (ChosenLootPackageName.contains(".Empty")) + { + return PickLootDrops(TierGroupName, bPrint); + // return LootDrops; + } + + bool bIsWorldList = ChosenLootPackageName.contains("WorldList"); + + if (bPrint) + { + std::cout << "NumLootPackageDrops Floored: " << NumLootPackageDrops << '\n'; + std::cout << "NumLootPackageDrops Original: " << ChosenRowLootTierData->GetNumLootPackageDrops() << '\n'; + std::cout << "TierGroupLPs.size(): " << TierGroupLPs.size() << '\n'; + std::cout << "ChosenLootPackageName: " << ChosenLootPackageName << '\n'; + + /* float t = ChosenRowLootTierData->NumLootPackageDrops; + + int b = (int)((t + t) - 0.5) >> 1; + auto c = ChosenRowLootTierData->NumLootPackageDrops - b; + + b += c >= (rand() * 0.000030518509); + + std::cout << "b: " << b << '\n'; */ + } + + LootDrops.reserve(NumLootPackageDrops); + + for (float i = 0; i < NumLootPackageDrops; i++) + { + if (i >= TierGroupLPs.size()) + break; + + auto TierGroupLP = TierGroupLPs.at(i); + auto TierGroupLPStr = TierGroupLP->GetLootPackageCall().ToString(); + + if (TierGroupLPStr.contains(".Empty")) + { + NumLootPackageDrops++; + continue; + } + + std::vector lootPackageCalls; + + if (bIsWorldList) + { + for (int j = 0; j < TierGroupLPs.size(); j++) + { + auto& CurrentLP = TierGroupLPs.at(j); + + if (CurrentLP->GetWeight() != 0) + lootPackageCalls.push_back(CurrentLP); + } + } + else + { + for (int p = 0; p < LPTables.size(); p++) + { + auto LPRowMap = LPTables[p]->GetRowMap(); + + for (int j = 0; j < LPRowMap.Pairs.Elements.Num(); j++) + { + auto& CurrentLP = LPRowMap.Pairs.Elements[j].ElementData.Value; + + auto LootPackage = (FFortLootPackageData*)CurrentLP.Value(); + + if (LootPackage->GetLootPackageID().ToString() == TierGroupLPStr && LootPackage->GetWeight() != 0) + { + lootPackageCalls.push_back(LootPackage); + } + } + } + } + + if (lootPackageCalls.size() == 0) + { + // std::cout << "lootPackageCalls.size() == 0!\n"; + NumLootPackageDrops++; // ?? + continue; + } + + FFortLootPackageData* LootPackageCall = GetLootPackage(lootPackageCalls); + + if (!LootPackageCall) // Should NEVER happen + continue; + + auto ItemDef = LootPackageCall->GetItemDefinition().Get(); + + if (!ItemDef) + { + NumLootPackageDrops++; // ?? + continue; + } + + if (bPrint) + { + std::cout << std::format("[{}] {} {} {}\n", i, lootPackageCalls.size(), TierGroupLPStr, ItemDef->GetName()); + } + + LootDrops.push_back({ ItemDef, LootPackageCall->GetCount() }); + } + + return LootDrops; +} \ No newline at end of file diff --git a/Project Reboot 3.0/FortLootPackage.h b/Project Reboot 3.0/FortLootPackage.h index e69de29..abbc8a7 100644 --- a/Project Reboot 3.0/FortLootPackage.h +++ b/Project Reboot 3.0/FortLootPackage.h @@ -0,0 +1,89 @@ +#pragma once + +#include + +#include "Array.h" +#include "FortItemDefinition.h" +#include "SoftObjectPtr.h" + +struct FFortLootPackageData +{ +public: + FName& GetLootPackageID() + { + static auto LootPackageIDOffset = FindOffsetStruct("/Script/FortniteGame.FortLootPackageData", "LootPackageID"); + return *(FName*)(__int64(this) + LootPackageIDOffset); + } + + float& GetWeight() + { + static auto WeightOffset = FindOffsetStruct("/Script/FortniteGame.FortLootPackageData", "Weight"); + return *(float*)(__int64(this) + WeightOffset); + } + + FString& GetLootPackageCall() + { + static auto LootPackageCallOffset = FindOffsetStruct("/Script/FortniteGame.FortLootPackageData", "LootPackageCall"); + return *(FString*)(__int64(this) + LootPackageCallOffset); + } + + TSoftObjectPtr& GetItemDefinition() + { + static auto ItemDefinitionOffset = FindOffsetStruct("/Script/FortniteGame.FortLootPackageData", "ItemDefinition"); + return *(TSoftObjectPtr*)(__int64(this) + ItemDefinitionOffset); + } + + int& GetCount() + { + static auto CountOffset = FindOffsetStruct("/Script/FortniteGame.FortLootPackageData", "Count"); + return *(int*)(__int64(this) + CountOffset); + } +}; + +struct FFortLootTierData +{ +public: + float& GetNumLootPackageDrops() + { + static auto NumLootPackageDropsOffset = FindOffsetStruct("/Script/FortniteGame.FortLootTierData", "NumLootPackageDrops"); + return *(float*)(__int64(this) + NumLootPackageDropsOffset); + } + + FName& GetTierGroup() + { + static auto TierGroupOffset = FindOffsetStruct("/Script/FortniteGame.FortLootTierData", "TierGroup"); + return *(FName*)(__int64(this) + TierGroupOffset); + } + + float& GetWeight() + { + static auto WeightOffset = FindOffsetStruct("/Script/FortniteGame.FortLootTierData", "Weight"); + return *(float*)(__int64(this) + WeightOffset); + } + + FName& GetLootPackage() + { + static auto LootPackageOffset = FindOffsetStruct("/Script/FortniteGame.FortLootTierData", "LootPackage"); + return *(FName*)(__int64(this) + LootPackageOffset); + } + + TArray& GetLootPackageCategoryWeightArray() + { + static auto LootPackageCategoryWeightArrayOffset = FindOffsetStruct("/Script/FortniteGame.FortLootTierData", "LootPackageCategoryWeightArray"); + return *(TArray*)(__int64(this) + LootPackageCategoryWeightArrayOffset); + } + + TArray& GetLootPackageCategoryMinArray() + { + static auto LootPackageCategoryMinArrayOffset = FindOffsetStruct("/Script/FortniteGame.FortLootTierData", "LootPackageCategoryMinArray"); + return *(TArray*)(__int64(this) + LootPackageCategoryMinArrayOffset); + } + + TArray& GetLootPackageCategoryMaxArray() + { + static auto LootPackageCategoryMaxArrayOffset = FindOffsetStruct("/Script/FortniteGame.FortLootTierData", "LootPackageCategoryMaxArray"); + return *(TArray*)(__int64(this) + LootPackageCategoryMaxArrayOffset); + } +}; + +std::vector> PickLootDrops(FName TierGroupName, bool bPrint = false, int recursive = 0); \ No newline at end of file diff --git a/Project Reboot 3.0/FortPickup.cpp b/Project Reboot 3.0/FortPickup.cpp new file mode 100644 index 0000000..592840e --- /dev/null +++ b/Project Reboot 3.0/FortPickup.cpp @@ -0,0 +1,58 @@ +#include "FortPickup.h" + +#include "FortPawn.h" +#include "FortItemDefinition.h" +#include "FortPlayerState.h" + +void AFortPickup::TossPickup(FVector FinalLocation, AFortPawn* ItemOwner, int OverrideMaxStackCount, bool bToss, EFortPickupSourceTypeFlag InPickupSourceTypeFlags, EFortPickupSpawnSource InPickupSpawnSource) +{ + static auto fn = FindObject(L"/Script/FortniteGame.FortPickup.TossPickup"); + + struct { FVector FinalLocation; AFortPawn* ItemOwner; int OverrideMaxStackCount; bool bToss; + EFortPickupSourceTypeFlag InPickupSourceTypeFlags; EFortPickupSpawnSource InPickupSpawnSource; } + AFortPickup_TossPickup_Params{FinalLocation, ItemOwner, OverrideMaxStackCount, bToss, InPickupSourceTypeFlags, InPickupSpawnSource}; + + this->ProcessEvent(fn, &AFortPickup_TossPickup_Params); +} + +AFortPickup* AFortPickup::SpawnPickup(UFortItemDefinition* ItemDef, FVector Location, int Count, EFortPickupSourceTypeFlag PickupSource, EFortPickupSpawnSource SpawnSource, int LoadedAmmo, AFortPawn* Pawn) +{ + static auto FortPickupClass = FindObject(L"/Script/FortniteGame.FortPickup"); + // auto PlayerState = Pawn ? Cast(Pawn->GetPlayerState) : nullptr; + + if (auto Pickup = GetWorld()->SpawnActor(FortPickupClass, Location)) + { + static auto PawnWhoDroppedPickupOffset = Pickup->GetOffset("PawnWhoDroppedPickup"); + static auto PrimaryPickupItemEntryOffset = Pickup->GetOffset("PrimaryPickupItemEntry"); + + auto PrimaryPickupItemEntry = Pickup->GetPtr(PrimaryPickupItemEntryOffset); + + PrimaryPickupItemEntry->GetCount() = Count; + PrimaryPickupItemEntry->GetItemDefinition() = ItemDef; + PrimaryPickupItemEntry->GetLoadedAmmo() = LoadedAmmo; + + // Pickup->OptionalOwnerID = Pawn ? PlayerState->WorldPlayerId : -1; + Pickup->Get(PawnWhoDroppedPickupOffset) = Pawn; + // Pickup->bCombinePickupsWhenTossCompletes = true; + + bool bToss = true; + + if (bToss) + { + PickupSource |= EFortPickupSourceTypeFlag::Tossed; + } + + Pickup->TossPickup(Location, Pawn, 0, bToss, PickupSource, SpawnSource); + + if (PickupSource == EFortPickupSourceTypeFlag::Container) + { + static auto bTossedFromContainerOffset = Pickup->GetOffset("bTossedFromContainer"); + Pickup->Get(bTossedFromContainerOffset) = true; + // Pickup->OnRep_TossedFromContainer(); + } // crashes if we do this then tosspickup + + return Pickup; + } + + return nullptr; +} \ No newline at end of file diff --git a/Project Reboot 3.0/FortPickup.h b/Project Reboot 3.0/FortPickup.h new file mode 100644 index 0000000..17d35e4 --- /dev/null +++ b/Project Reboot 3.0/FortPickup.h @@ -0,0 +1,39 @@ +#pragma once + +#include "Actor.h" + +enum class EFortPickupSourceTypeFlag : uint8_t +{ + Other = 0, + Player = 1, + Destruction = 2, + Container = 3, + AI = 4, + Tossed = 5, + FloorLoot = 6, + EFortPickupSourceTypeFlag_MAX = 7 +}; + +enum class EFortPickupSpawnSource : uint8_t +{ + Unset = 0, + PlayerElimination = 1, + Chest = 2, + SupplyDrop = 3, + AmmoBox = 4, + Drone = 5, + ItemSpawner = 6, + EFortPickupSpawnSource_MAX = 7 +}; + +ENUM_CLASS_FLAGS(EFortPickupSourceTypeFlag) + +class AFortPickup : public AActor +{ +public: + void TossPickup(FVector FinalLocation, class AFortPawn* ItemOwner, int OverrideMaxStackCount, bool bToss, EFortPickupSourceTypeFlag InPickupSourceTypeFlags, EFortPickupSpawnSource InPickupSpawnSource); + + static AFortPickup* SpawnPickup(class UFortItemDefinition* ItemDef, FVector Location, int Count, + EFortPickupSourceTypeFlag PickupSource = EFortPickupSourceTypeFlag::Other, EFortPickupSpawnSource SpawnSource = EFortPickupSpawnSource::Unset, + int LoadedAmmo = -1, class AFortPawn* Pawn = nullptr); +}; \ No newline at end of file diff --git a/Project Reboot 3.0/FortPlayerController.h b/Project Reboot 3.0/FortPlayerController.h index bf5833c..4f3fb92 100644 --- a/Project Reboot 3.0/FortPlayerController.h +++ b/Project Reboot 3.0/FortPlayerController.h @@ -26,7 +26,6 @@ public: return Get(MyFortPawnOffset); } - static UClass* StaticClass() { static auto Class = FindObject("/Script/FortniteGame.FortPlayerController"); diff --git a/Project Reboot 3.0/GameplayAbilitySpec.h b/Project Reboot 3.0/GameplayAbilitySpec.h index 154c431..7df04d5 100644 --- a/Project Reboot 3.0/GameplayAbilitySpec.h +++ b/Project Reboot 3.0/GameplayAbilitySpec.h @@ -20,19 +20,21 @@ struct FGameplayAbilitySpec : FFastArraySerializerItem { static int GetStructSize() { - static auto StructSize = 0x00C8; + static auto GameplayAbilitySpecStruct = FindObject("/Script/GameplayAbilities.GameplayAbilitySpec"); + static auto StructSize = GameplayAbilitySpecStruct->GetPropertiesSize(); + // *(int*)(__int64(GameplayAbilitySpecStruct) + Offsets::PropertiesSize); return StructSize; } UObject*& GetAbility() { - static auto AbilityOffset = 0x0010; + static auto AbilityOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpec", "Ability"); return *(UObject**)(__int64(this) + AbilityOffset); } FGameplayAbilitySpecHandle& GetHandle() { - static auto HandleOffset = 0xC; + static auto HandleOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpec", "Handle"); return *(FGameplayAbilitySpecHandle*)(__int64(this) + HandleOffset); } }; @@ -44,11 +46,9 @@ static FGameplayAbilitySpec* MakeNewSpec(UClass* GameplayAbilityClass, UObject* if (!NewSpec) return nullptr; - static auto HandleOffset = 0xC; - static auto AbilityOffset = 0x0010; - static auto LevelOffset = 0x0018; - static auto InputIDOffset = 0x001C; - static auto SourceObjectOffset = 0x0020; + static auto LevelOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpec", "Level"); + static auto SourceObjectOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpec", "SourceObject"); + static auto InputIDOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpec", "InputID"); ((FFastArraySerializerItem*)NewSpec)->MostRecentArrayReplicationKey = -1; ((FFastArraySerializerItem*)NewSpec)->ReplicationID = -1; diff --git a/Project Reboot 3.0/GameplayStatics.cpp b/Project Reboot 3.0/GameplayStatics.cpp index 6ab5df8..9b53096 100644 --- a/Project Reboot 3.0/GameplayStatics.cpp +++ b/Project Reboot 3.0/GameplayStatics.cpp @@ -6,15 +6,13 @@ TArray UGameplayStatics::GetAllActorsOfClass(const UObject* WorldContex { static auto fn = FindObject(L"/Script/Engine.GameplayStatics.GetAllActorsOfClass"); - TArray ahh; - struct { const UObject* WorldContextObject; UClass* ActorClass; TArray OutActors; } - UGameplayStatics_GetAllActorsOfClass_Params{ WorldContextObject, ActorClass, ahh }; + UGameplayStatics_GetAllActorsOfClass_Params{ WorldContextObject, ActorClass }; static auto defaultObj = StaticClass(); defaultObj->ProcessEvent(fn, &UGameplayStatics_GetAllActorsOfClass_Params); - return ahh; + return UGameplayStatics_GetAllActorsOfClass_Params.OutActors; } float UGameplayStatics::GetTimeSeconds(const UObject* WorldContextObject) diff --git a/Project Reboot 3.0/KismetMathLibrary.cpp b/Project Reboot 3.0/KismetMathLibrary.cpp new file mode 100644 index 0000000..029c977 --- /dev/null +++ b/Project Reboot 3.0/KismetMathLibrary.cpp @@ -0,0 +1,21 @@ +#include "KismetMathLibrary.h" + +#include "reboot.h" + +float UKismetMathLibrary::RandomFloatInRange(float min, float max) +{ + static auto fn = FindObject("/Script/Engine.KismetMathLibrary.RandomFloatInRange"); + + struct { float min; float max; float ret; } params{min, max}; + + static auto DefaultObject = StaticClass(); + DefaultObject->ProcessEvent(fn, ¶ms); + + return params.ret; +} + +UClass* UKismetMathLibrary::StaticClass() +{ + static auto Class = FindObject("/Script/Engine.KismetMathLibrary"); + return Class; +} \ No newline at end of file diff --git a/Project Reboot 3.0/KismetMathLibrary.h b/Project Reboot 3.0/KismetMathLibrary.h new file mode 100644 index 0000000..0b99c3a --- /dev/null +++ b/Project Reboot 3.0/KismetMathLibrary.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Object.h" + +class UKismetMathLibrary : public UObject +{ +public: + static float RandomFloatInRange(float min, float max); + + static UClass* StaticClass(); +}; \ No newline at end of file diff --git a/Project Reboot 3.0/Map.h b/Project Reboot 3.0/Map.h index ce4fc98..e719d33 100644 --- a/Project Reboot 3.0/Map.h +++ b/Project Reboot 3.0/Map.h @@ -11,6 +11,23 @@ class TPair public: KeyType First; ValueType Second; + + FORCEINLINE KeyType& Key() + { + return First; + } + FORCEINLINE const KeyType& Key() const + { + return First; + } + FORCEINLINE ValueType& Value() + { + return Second; + } + FORCEINLINE const ValueType& Value() const + { + return Second; + } }; template //, typename SetAllocator, typename KeyFuncs> diff --git a/Project Reboot 3.0/NameTypes.h b/Project Reboot 3.0/NameTypes.h index 1619816..aa71946 100644 --- a/Project Reboot 3.0/NameTypes.h +++ b/Project Reboot 3.0/NameTypes.h @@ -15,4 +15,9 @@ struct FName std::string ToString(); bool IsValid() { return ComparisonIndex.Value > 0; } + + bool operator==(FName other) + { + return ComparisonIndex.Value == other.ComparisonIndex.Value; + } }; \ No newline at end of file diff --git a/Project Reboot 3.0/Object.cpp b/Project Reboot 3.0/Object.cpp index a540e85..43a982b 100644 --- a/Project Reboot 3.0/Object.cpp +++ b/Project Reboot 3.0/Object.cpp @@ -72,3 +72,9 @@ bool UObject::IsA(UClass* otherClass) return false; } + +class UClass* UObject::StaticClass() +{ + static auto Class = FindObject("/Script/CoreUObject.Object"); + return Class; +} \ No newline at end of file diff --git a/Project Reboot 3.0/Object.h b/Project Reboot 3.0/Object.h index 742a970..a265b32 100644 --- a/Project Reboot 3.0/Object.h +++ b/Project Reboot 3.0/Object.h @@ -80,4 +80,6 @@ public: template T* GetPtr(const std::string& ChildName) { return GetPtr(GetOffset(ChildName)); } + + static class UClass* StaticClass(); }; \ No newline at end of file diff --git a/Project Reboot 3.0/PersistentObjectPtr.h b/Project Reboot 3.0/PersistentObjectPtr.h new file mode 100644 index 0000000..f37e406 --- /dev/null +++ b/Project Reboot 3.0/PersistentObjectPtr.h @@ -0,0 +1,15 @@ +#pragma once + +#include "WeakObjectPtr.h" + +template +struct TPersistentObjectPtr +{ +public: + /** Once the object has been noticed to be loaded, this is set to the object weak pointer **/ + mutable FWeakObjectPtr WeakPtr; + /** Compared to CurrentAnnotationTag and if they are not equal, a guid search will be performed **/ + mutable int TagAtLastTest; + /** Guid for the object this pointer points to or will point to. **/ + TObjectID ObjectID; +}; \ 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 149b8f7..68572f8 100644 --- a/Project Reboot 3.0/Project Reboot 3.0.vcxproj +++ b/Project Reboot 3.0/Project Reboot 3.0.vcxproj @@ -184,10 +184,12 @@ + + @@ -207,6 +209,7 @@ + @@ -227,6 +230,7 @@ + @@ -246,6 +250,7 @@ + @@ -257,6 +262,7 @@ + @@ -264,6 +270,8 @@ + + @@ -272,6 +280,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 20772ba..8d06048 100644 --- a/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters +++ b/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters @@ -101,6 +101,12 @@ Engine\Source\Runtime\Engine\Private + + Engine\Source\Runtime\Engine\Private + + + FortniteGame\Source\FortniteGame\Private\Items + @@ -314,6 +320,27 @@ Engine\Source\Runtime\Engine\Classes\Kismet + + Engine\Source\Runtime\CoreUObject\Public\UObject + + + Engine\Source\Runtime\CoreUObject\Public\UObject + + + Engine\Source\Runtime\CoreUObject\Public\UObject + + + Engine\Source\Runtime\CoreUObject\Public\UObject + + + Engine\Source\Runtime\Engine\Classes\Kismet + + + FortniteGame\Source\FortniteGame\Public\Items + + + FortniteGame\Source\FortniteGame\Public\Building + @@ -412,9 +439,6 @@ {4f177a72-585d-4b79-a258-26bb6d2c225c} - - {bcb0d983-0b85-4ca6-9fac-6567c7d79921} - {826a509f-03f4-4a18-a9bf-d67b69fe3b93} @@ -466,6 +490,9 @@ {31a7f342-8b7c-4594-a24d-c4dd5c9d230d} + + {bcb0d983-0b85-4ca6-9fac-6567c7d79921} + diff --git a/Project Reboot 3.0/Set.h b/Project Reboot 3.0/Set.h index e90d216..e51807a 100644 --- a/Project Reboot 3.0/Set.h +++ b/Project Reboot 3.0/Set.h @@ -35,6 +35,7 @@ public: template //, typename KeyFuncs, typename Allocator> class TSet { +public: typedef TSetElement ElementType; typedef TSparseArrayElementOrListLink ArrayElementType; diff --git a/Project Reboot 3.0/SoftObjectPath.h b/Project Reboot 3.0/SoftObjectPath.h new file mode 100644 index 0000000..276317e --- /dev/null +++ b/Project Reboot 3.0/SoftObjectPath.h @@ -0,0 +1,14 @@ +#pragma once + +#include "NameTypes.h" +#include "UnrealString.h" + +struct FSoftObjectPath +{ +public: + /** Asset path, patch to a top level object in a package. This is /package/path.assetname */ + FName AssetPathName; + + /** Optional FString for subobject within an asset. This is the sub path after the : */ + FString SubPathString; +}; \ No newline at end of file diff --git a/Project Reboot 3.0/SoftObjectPtr.h b/Project Reboot 3.0/SoftObjectPtr.h new file mode 100644 index 0000000..9b4a9b9 --- /dev/null +++ b/Project Reboot 3.0/SoftObjectPtr.h @@ -0,0 +1,25 @@ +#pragma once + +#include "Object.h" + +#include "PersistentObjectPtr.h" +#include "SoftObjectPath.h" + +#include "reboot.h" + +struct FSoftObjectPtr : public TPersistentObjectPtr +{ +public: +}; + +template +struct TSoftObjectPtr +{ +public: + FSoftObjectPtr SoftObjectPtr; + + T* Get() + { + return FindObject(SoftObjectPtr.ObjectID.AssetPathName.ToString()); + } +}; \ No newline at end of file diff --git a/Project Reboot 3.0/SparseArray.h b/Project Reboot 3.0/SparseArray.h index 4d6497e..5f52d3d 100644 --- a/Project Reboot 3.0/SparseArray.h +++ b/Project Reboot 3.0/SparseArray.h @@ -49,4 +49,18 @@ public: TBitArray AllocationFlags; int32 FirstFreeIndex; int32 NumFreeIndices; + + FORCEINLINE FSparseArrayElement& operator[](uint32 Index) + { + return *(FSparseArrayElement*)&Data.at(Index).ElementData; + } + FORCEINLINE const FSparseArrayElement& operator[](uint32 Index) const + { + return *(const FSparseArrayElement*)&Data.at(Index).ElementData; + } + + FORCEINLINE int32 Num() const + { + return Data.Num() - NumFreeIndices; + } }; \ No newline at end of file diff --git a/Project Reboot 3.0/UObjectGlobals.h b/Project Reboot 3.0/UObjectGlobals.h index 482a1c7..442a533 100644 --- a/Project Reboot 3.0/UObjectGlobals.h +++ b/Project Reboot 3.0/UObjectGlobals.h @@ -2,9 +2,11 @@ #include "Object.h" +#define ANY_PACKAGE (UObject*)-1 + extern inline UObject* (*StaticFindObjectOriginal)(UClass* Class, UObject* InOuter, const TCHAR* Name, bool ExactClass) = nullptr; -template +template static inline T* StaticFindObject(UClass* Class, UObject* InOuter, const TCHAR* Name, bool ExactClass = false) { // LOG_INFO(LogDev, "StaticFindObjectOriginal: {}", __int64(StaticFindObjectOriginal)); diff --git a/Project Reboot 3.0/WeakObjectPtr.h b/Project Reboot 3.0/WeakObjectPtr.h new file mode 100644 index 0000000..c4123b8 --- /dev/null +++ b/Project Reboot 3.0/WeakObjectPtr.h @@ -0,0 +1,8 @@ +#pragma once + +struct FWeakObjectPtr +{ +public: + int ObjectIndex; + int ObjectSerialNumber; +}; \ No newline at end of file diff --git a/Project Reboot 3.0/World.h b/Project Reboot 3.0/World.h index 2e0884c..47854ed 100644 --- a/Project Reboot 3.0/World.h +++ b/Project Reboot 3.0/World.h @@ -3,6 +3,7 @@ #include "EngineTypes.h" #include "Transform.h" #include "Object.h" +#include "Rotator.h" struct FNetworkNotify { @@ -45,5 +46,15 @@ public: return (ActorType*)SpawnActorOriginal(this, Class, &UserTransformPtr, SpawnParameters); } + template + ActorType* SpawnActor(UClass* Class, FVector Location, FQuat Rotation = FQuat(), FVector Scale3D = FVector(1, 1, 1), const FActorSpawnParameters& SpawnParameters = FActorSpawnParameters()) + { + FTransform UserTransformPtr{}; + UserTransformPtr.Translation = Location; + UserTransformPtr.Rotation = Rotation; + UserTransformPtr.Scale3D = Scale3D; + return SpawnActor(Class, UserTransformPtr, SpawnParameters); + } + void Listen(); }; \ No newline at end of file diff --git a/Project Reboot 3.0/addresses.cpp b/Project Reboot 3.0/addresses.cpp index 5385011..4e7099b 100644 --- a/Project Reboot 3.0/addresses.cpp +++ b/Project Reboot 3.0/addresses.cpp @@ -130,6 +130,7 @@ void Addresses::FindAll() Addresses::ReplaceBuildingActor = FindReplaceBuildingActor(); Addresses::GiveAbilityAndActivateOnce = FindGiveAbilityAndActivateOnce(); Addresses::OnDamageServer = FindOnDamageServer(); + Addresses::StaticLoadObject = FindStaticLoadObject(); } void Addresses::Print() @@ -159,6 +160,7 @@ void Addresses::Print() LOG_INFO(LogDev, "ReplaceBuildingActor: 0x{:x}", ReplaceBuildingActor - Base); LOG_INFO(LogDev, "GiveAbilityAndActivateOnce: 0x{:x}", GiveAbilityAndActivateOnce - Base); LOG_INFO(LogDev, "OnDamageServer: 0x{:x}", OnDamageServer - Base); + LOG_INFO(LogDev, "StaticLoadObject: 0x{:x}", StaticLoadObject - Base); } void Offsets::FindAll() @@ -222,6 +224,7 @@ void Addresses::Init() UAbilitySystemComponent::GiveAbilityOriginal = decltype(UAbilitySystemComponent::GiveAbilityOriginal)(GiveAbility); UAbilitySystemComponent::InternalTryActivateAbilityOriginal = decltype(UAbilitySystemComponent::InternalTryActivateAbilityOriginal)(InternalTryActivateAbility); ABuildingActor::OnDamageServerOriginal = decltype(ABuildingActor::OnDamageServerOriginal)(OnDamageServer); + StaticLoadObjectOriginal = decltype(StaticLoadObjectOriginal)(StaticLoadObject); // if (Engine_Version >= 421) ChunkedObjects = decltype(ChunkedObjects)(ObjectArray); // else UnchunkedObjects = decltype(UnchunkedObjects)(ObjectArray); diff --git a/Project Reboot 3.0/addresses.h b/Project Reboot 3.0/addresses.h index 22e9cda..27b3063 100644 --- a/Project Reboot 3.0/addresses.h +++ b/Project Reboot 3.0/addresses.h @@ -52,4 +52,14 @@ namespace Offsets void FindAll(); void Print(); -} \ No newline at end of file +} + +#define ENUM_CLASS_FLAGS(Enum) \ + inline Enum& operator|=(Enum& Lhs, Enum Rhs) { return Lhs = (Enum)((__underlying_type(Enum))Lhs | (__underlying_type(Enum))Rhs); } \ + inline Enum& operator&=(Enum& Lhs, Enum Rhs) { return Lhs = (Enum)((__underlying_type(Enum))Lhs & (__underlying_type(Enum))Rhs); } \ + inline Enum& operator^=(Enum& Lhs, Enum Rhs) { return Lhs = (Enum)((__underlying_type(Enum))Lhs ^ (__underlying_type(Enum))Rhs); } \ + inline constexpr Enum operator| (Enum Lhs, Enum Rhs) { return (Enum)((__underlying_type(Enum))Lhs | (__underlying_type(Enum))Rhs); } \ + inline constexpr Enum operator& (Enum Lhs, Enum Rhs) { return (Enum)((__underlying_type(Enum))Lhs & (__underlying_type(Enum))Rhs); } \ + inline constexpr Enum operator^ (Enum Lhs, Enum Rhs) { return (Enum)((__underlying_type(Enum))Lhs ^ (__underlying_type(Enum))Rhs); } \ + inline constexpr bool operator! (Enum E) { return !(__underlying_type(Enum))E; } \ + inline constexpr Enum operator~ (Enum E) { return (Enum)~(__underlying_type(Enum))E; } \ No newline at end of file diff --git a/Project Reboot 3.0/dllmain.cpp b/Project Reboot 3.0/dllmain.cpp index fb46ab3..1816042 100644 --- a/Project Reboot 3.0/dllmain.cpp +++ b/Project Reboot 3.0/dllmain.cpp @@ -56,7 +56,12 @@ DWORD WINAPI Main(LPVOID) static auto FortAbilitySystemComponentAthenaDefault = FindObject(L"/Script/FortniteGame.Default__FortAbilitySystemComponentAthena"); static auto SwitchLevel = FindObject(L"/Script/Engine.PlayerController.SwitchLevel"); - FString Level = Engine_Version < 424 ? L"Athena_Terrain" : Engine_Version >= 500 ? Engine_Version >= 501 ? L"Asteria_Terrain" : L"Artemis_Terrain" : L"Apollo_Terrain"; + FString Level = Engine_Version < 424 + ? L"Athena_Terrain" : Engine_Version >= 500 ? Engine_Version >= 501 + ? L"Asteria_Terrain" + : L"Artemis_Terrain" + : Globals::bCreative ? L"Creative_NoApollo_Terrain" + : L"Apollo_Terrain"; if (Hooking::MinHook::Hook((PVOID)Addresses::NoMCP, (PVOID)NoMCPHook, nullptr)) { @@ -109,8 +114,8 @@ DWORD WINAPI Main(LPVOID) UAbilitySystemComponent::ServerTryActivateAbilityHook, nullptr, false); Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerTryActivateAbilityWithEventData"), UAbilitySystemComponent::ServerTryActivateAbilityWithEventDataHook, nullptr, false); - Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerAbilityRPCBatch"), - UAbilitySystemComponent::ServerAbilityRPCBatchHook, nullptr, false); + // Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerAbilityRPCBatch"), + // UAbilitySystemComponent::ServerAbilityRPCBatchHook, nullptr, false); if (Engine_Version >= 424) { diff --git a/Project Reboot 3.0/finder.h b/Project Reboot 3.0/finder.h index 995e7a1..2a59207 100644 --- a/Project Reboot 3.0/finder.h +++ b/Project Reboot 3.0/finder.h @@ -72,6 +72,11 @@ static inline uint64 FindCreateNetDriver() static inline uint64 FindKickPlayer() { + if (Engine_Version >= 423 || Engine_Version <= 425) + return Memcury::Scanner::FindPattern("48 89 5C 24 08 48 89 74 24 10 57 48 83 EC ? 49 8B F0 48 8B DA 48 85 D2").Get(); + + // return 0; + // return Memcury::Scanner::FindPattern("48 89 5C 24 08 48 89 74 24 10 57 48 83 EC ? 49 8B F0 48 8B DA 48 85 D2").Get(); // 12.41 uint64 Ret = 0; @@ -133,13 +138,29 @@ static inline uint64 FindSpawnActor() static inline uint64 FindSetWorld() { - return Memcury::Scanner::FindStringRef(L"AOnlineBeaconHost::InitHost failed") - .ScanFor({ 0x48, 0x8B, 0xD0, 0xE8 }, false) - .RelativeOffset(4) - .Get(); // THANKS ENDER + if (Engine_Version < 426) + return Memcury::Scanner::FindStringRef(L"AOnlineBeaconHost::InitHost failed") + .ScanFor({ 0x48, 0x8B, 0xD0, 0xE8 }, false) + .RelativeOffset(4) + .Get(); // THANKS ENDER - // return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 55 57 41 56 48 8B EC 48 83 EC 30 48 8B 99").Get(); // s12 i think - return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 48 8B 99 ? ? ? ? 48 8B F2 48 8B F9 48 85 DB 0F 84 ? ? ? ? 48 8B 97").Get(); + int SetWorldIndex = 0; + + int Fortnite_Season = std::floor(Fortnite_Version); + + if (Fortnite_Season == 13) + SetWorldIndex = 0x70; + else if (Fortnite_Season == 14 || Fortnite_Version <= 15.2) + SetWorldIndex = 0x71; + else if (Fortnite_Version >= 15.3 && Fortnite_Season < 18) // i havent tested 15.2 + SetWorldIndex = 0x72; + else if (Fortnite_Season == 18) + SetWorldIndex = 0x73; + else if (Fortnite_Season >= 19 && Fortnite_Season < 21) + SetWorldIndex = 0x7A; + + static auto DefaultNetDriver = FindObject("/Script/Engine.Default__NetDriver"); + return __int64(DefaultNetDriver->VFTable[SetWorldIndex]); } static inline uint64 FindInitListen() @@ -154,6 +175,12 @@ static inline uint64 FindOnDamageServer() return Addr; } +static inline uint64 FindStaticLoadObject() +{ + auto Addr = Memcury::Scanner::FindStringRef(L"STAT_LoadObject").ScanFor({ 0x4C, 0x89, 0x4C }, false); + return Addr.Get(); +} + static inline uint64 FindNoMCP() { if (Fortnite_Version == 4) diff --git a/Project Reboot 3.0/reboot.h b/Project Reboot 3.0/reboot.h index d7ef530..5c2278e 100644 --- a/Project Reboot 3.0/reboot.h +++ b/Project Reboot 3.0/reboot.h @@ -11,16 +11,37 @@ FAILED_STRINGREF = 1, FAILED_CREATE_NETDRIVER = 2, FAILED_LISTEN = 3 -}; */ +}; */ + +namespace Globals +{ + extern inline bool bCreative = false; +} + +extern inline UObject* (*StaticLoadObjectOriginal)(UClass*, UObject*, const wchar_t* InName, const wchar_t* Filename, uint32_t LoadFlags, UObject* Sandbox, bool bAllowObjectReconciliation) = nullptr; template -static inline T* FindObject(const TCHAR* Name, UClass* Class = nullptr) +static inline T* LoadObject(const TCHAR* Name, UClass* Class = nullptr, UObject* Outer = nullptr) { - return StaticFindObject(Class, nullptr, Name); + return (T*)StaticLoadObjectOriginal(Class, Outer, Name, nullptr, 0, nullptr, false); } template -static inline T* FindObject(const std::string& NameStr, UClass* Class = nullptr) +static inline T* LoadObject(const std::string& NameStr, UClass* Class = nullptr, UObject* Outer = nullptr) +{ + auto NameCWSTR = std::wstring(NameStr.begin(), NameStr.end()).c_str(); + return (T*)StaticLoadObjectOriginal(Class, Outer, NameCWSTR, nullptr, 0, nullptr, false); +} + +template +static inline T* FindObject(const TCHAR* Name, UClass* Class = nullptr, UObject* Outer = nullptr) +{ + auto res = (T*)StaticFindObject/**/(Class, Outer, Name); + return res; +} + +template +static inline T* FindObject(const std::string& NameStr, UClass* Class = nullptr, UObject* Outer = nullptr) { auto NameCWSTR = std::wstring(NameStr.begin(), NameStr.end()).c_str(); return StaticFindObject(Class, nullptr, NameCWSTR);