diff --git a/Project Reboot 3.0/BuildingContainer.cpp b/Project Reboot 3.0/BuildingContainer.cpp index e228c97..8752374 100644 --- a/Project Reboot 3.0/BuildingContainer.cpp +++ b/Project Reboot 3.0/BuildingContainer.cpp @@ -4,22 +4,60 @@ #include "FortGameModeAthena.h" #include "gui.h" +void ABuildingContainer::BuildingContainer_SetMeshSet(FMeshSet* MeshSet) +{ + BuildingSMActor_SetMeshSet(MeshSet); + + // if (!NewSearchedMesh && !BuildingContainer->ShouldDestroyOnSearch()) error + + this->GetSearchedMesh() = MeshSet->GetSearchedMesh(); + + if (!IsAlreadySearched()) + { + // todo clear StaticMeshComponent->OverrideMaterials + + // todo reapply StaticMaterials + } + + static auto SearchSpeedOffset = GetOffset("SearchSpeed"); + Get(SearchSpeedOffset) = MeshSet->GetSearchSpeed(); + + if (MeshSet->GetLootNoiseLoudness() < 0) + { + this->GetLootNoiseRange() = MeshSet->GetLootNoiseRange(); + } + else + { + this->GetLootNoiseRange() = MeshSet->GetLootNoiseLoudness() * 1000; + // MeshSet->GetLootNoiseLoudness() = // IDKK; + } + + this->GetLootSpawnLocation() = MeshSet->GetLootSpawnLocation(); +} + +__m128 ToM128(const FVector& Vec) +{ + std::array Arr = { Vec.X, Vec.Y, Vec.Z, 0.0f }; + return _mm_loadu_ps(Arr.data()); +} + bool ABuildingContainer::SpawnLoot(AFortPawn* Pawn) { + if (!Pawn) + return false; + + this->ForceNetUpdate(); + auto GameMode = Cast(GetWorld()->GetGameMode()); auto GameState = Cast(GetWorld()->GetGameState()); - FVector LocationToSpawnLoot = this->GetActorLocation() + this->GetActorRightVector() * 70.f + FVector{ 0, 0, 50 }; + FVector LocationToSpawnLoot = this->GetActorLocation() + this->GetActorRightVector() * 70.f + FVector{ 0, 0, 50 }; // proper? static auto SearchLootTierGroupOffset = this->GetOffset("SearchLootTierGroup"); auto RedirectedLootTier = GameMode->RedirectLootTier(this->Get(SearchLootTierGroupOffset)); - // LOG_INFO(LogInteraction, "RedirectedLootTier: {}", RedirectedLootTier.ToString()); - auto LootDrops = PickLootDrops(RedirectedLootTier, GameState->GetWorldLevel(), -1, bDebugPrintLooting); - // LOG_INFO(LogInteraction, "LootDrops.size(): {}", LootDrops.size()); - for (auto& LootDrop : LootDrops) { PickupCreateData CreateData{}; @@ -34,17 +72,66 @@ bool ABuildingContainer::SpawnLoot(AFortPawn* Pawn) auto NewPickup = AFortPickup::SpawnPickup(CreateData); } + if (this->GetLootNoiseRange() > 0) + { + + } + + if (!this->IsDestroyed()) + { + this->ForceNetUpdate(); + // a buncha other stuff + } + static auto SearchAnimationCountOffset = FindOffsetStruct("/Script/FortniteGame.FortSearchBounceData", "SearchAnimationCount"); + static auto BounceNormalOffset = FindOffsetStruct("/Script/FortniteGame.FortSearchBounceData", "BounceNormal"); static auto SearchBounceDataOffset = this->GetOffset("SearchBounceData"); auto SearchBounceData = this->GetPtr(SearchBounceDataOffset); + + auto PawnLocation = Pawn->GetActorLocation(); + + // thanks openai + + __m128 v149 = ToM128(PawnLocation); + FVector BuildingContainerLocation = this->GetActorLocation(); + __m128 v150 = ToM128(BuildingContainerLocation); + + // Calculate v150 and v149 as before + v150.m128_f32[0] = PawnLocation.X - BuildingContainerLocation.X; + v149.m128_f32[0] = PawnLocation.Y - BuildingContainerLocation.Y; + + // Use the unpacklo_ps intrinsic to interleave the two __m128 vectors + __m128 result = _mm_unpacklo_ps(v150, v149); + + // Convert the result to a uint64_t using a union + union { + __m128i m128i; + uint64_t u64; + } data{}; + data.m128i = _mm_castps_si128(result); + + *(uint64*)(__int64(SearchBounceData) + BounceNormalOffset) = data.u64; // this will set x and y + (*(FVector*)(__int64(SearchBounceData) + BounceNormalOffset)).Z = 0; + + auto BounceNormalSquared = (*(FVector*)(__int64(SearchBounceData) + BounceNormalOffset)).SizeSquared(); + + if (BounceNormalSquared > 0.0000000099999999) + { + float v155 = FMath::InvSqrt(BounceNormalSquared); + float v156 = v155 + (float)(v155 * (float)(0.5 - (float)((float)(BounceNormalSquared * 0.5) * (float)(v155 * v155)))); + float idk = v156 + (float)(v156 * (float)(0.5 - (float)((float)(BounceNormalSquared * 0.5) * (float)(v156 * v156)))); + float v157 = (*(FVector*)(__int64(SearchBounceData) + BounceNormalOffset)).Y * idk; + float v158 = (*(FVector*)(__int64(SearchBounceData) + BounceNormalOffset)).Z * idk; + (*(FVector*)(__int64(SearchBounceData) + BounceNormalOffset)).X = (*(FVector*)(__int64(SearchBounceData) + BounceNormalOffset)).X * idk; + (*(FVector*)(__int64(SearchBounceData) + BounceNormalOffset)).Y = v157; + (*(FVector*)(__int64(SearchBounceData) + BounceNormalOffset)).Z = v158; + } (*(int*)(__int64(SearchBounceData) + SearchAnimationCountOffset))++; - static auto OnRep_bAlreadySearchedFn = FindObject(L"/Script/FortniteGame.BuildingContainer.OnRep_bAlreadySearched"); - this->ProcessEvent(OnRep_bAlreadySearchedFn); - - // Now there is some function called here but idk what it is, it calls OnLoot though. + static auto BounceContainerFn = FindObject("/Script/FortniteGame.BuildingContainer.BounceContainer"); + this->ProcessEvent(BounceContainerFn); return true; } \ No newline at end of file diff --git a/Project Reboot 3.0/BuildingContainer.h b/Project Reboot 3.0/BuildingContainer.h index 444c95b..3b6ffb4 100644 --- a/Project Reboot 3.0/BuildingContainer.h +++ b/Project Reboot 3.0/BuildingContainer.h @@ -13,6 +13,52 @@ public: return this->ReadBitfieldValue(bDestroyContainerOnSearchOffset, bDestroyContainerOnSearchFieldMask); } + UStaticMesh*& GetSearchedMesh() + { + static auto SearchedMeshOffset = GetOffset("SearchedMesh"); + return Get(SearchedMeshOffset); + } + + UStaticMesh*& GetStaticMesh() + { + static auto StaticMeshOffset = GetOffset("StaticMesh"); + return Get(StaticMeshOffset); + } + + void BuildingContainer_SetMeshSet(FMeshSet* MeshSet); + + bool IsAlreadySearched() + { + static auto bAlreadySearchedOffset = this->GetOffset("bAlreadySearched"); + static auto bAlreadySearchedFieldMask = GetFieldMask(this->GetProperty("bAlreadySearched")); + return this->ReadBitfieldValue(bAlreadySearchedOffset, bAlreadySearchedFieldMask); + } + + void SetAlreadySearched(bool bNewValue, bool bOnRep = true) + { + static auto bAlreadySearchedOffset = this->GetOffset("bAlreadySearched"); + static auto bAlreadySearchedFieldMask = GetFieldMask(this->GetProperty("bAlreadySearched")); + this->SetBitfieldValue(bAlreadySearchedOffset, bAlreadySearchedFieldMask, bNewValue); + + if (bOnRep) + { + static auto OnRep_bAlreadySearchedFn = FindObject(L"/Script/FortniteGame.BuildingContainer.OnRep_bAlreadySearched"); + this->ProcessEvent(OnRep_bAlreadySearchedFn); + } + } + + FVector& GetLootSpawnLocation() + { + static auto LootSpawnLocationOffset = GetOffset("LootSpawnLocation"); + return Get(LootSpawnLocationOffset); + } + + float& GetLootNoiseRange() + { + static auto LootNoiseRangeOffset = GetOffset("LootNoiseRange"); + return Get(LootNoiseRangeOffset); + } + bool SpawnLoot(AFortPawn* Pawn); static UClass* StaticClass() diff --git a/Project Reboot 3.0/BuildingSMActor.cpp b/Project Reboot 3.0/BuildingSMActor.cpp index b2f45c9..4ff5e03 100644 --- a/Project Reboot 3.0/BuildingSMActor.cpp +++ b/Project Reboot 3.0/BuildingSMActor.cpp @@ -1,5 +1,14 @@ #include "BuildingSMActor.h" +void ABuildingSMActor::BuildingSMActor_SetMeshSet(FMeshSet* MeshSet) +{ + static auto BreakEffectOffset = GetOffset("BreakEffect"); + Get(BreakEffectOffset) = MeshSet->GetBreakEffect(); + + static auto ConstructedEffectOffset = GetOffset("ConstructedEffect"); + Get(ConstructedEffectOffset) = MeshSet->GetConstructedEffect(); +} + UClass* ABuildingSMActor::StaticClass() { static auto Class = FindObject(L"/Script/FortniteGame.BuildingSMActor"); diff --git a/Project Reboot 3.0/BuildingSMActor.h b/Project Reboot 3.0/BuildingSMActor.h index bcff2be..4b10308 100644 --- a/Project Reboot 3.0/BuildingSMActor.h +++ b/Project Reboot 3.0/BuildingSMActor.h @@ -2,6 +2,7 @@ #include "BuildingActor.h" #include "PlayerState.h" +#include "CurveTable.h" enum class EFortResourceType : uint8_t { @@ -13,6 +14,90 @@ enum class EFortResourceType : uint8_t EFortResourceType_MAX = 5 }; +using UStaticMesh = UObject; +using UStaticMeshComponent = UObject; +using UParticleSystem = UObject; + +struct FMeshSet +{ + static UStruct* GetStruct() + { + static auto Struct = FindObject(L"/Script/FortniteGame.MeshSet"); + return Struct; + } + + static int GetPropertiesSize() { return GetStruct()->GetPropertiesSize(); } + + UStaticMesh* GetBaseMesh() + { + static auto BaseMeshOffset = FindOffsetStruct("/Script/FortniteGame.MeshSet", "BaseMesh"); + return *(UStaticMesh**)(__int64(this) + BaseMeshOffset); + } + + UStaticMesh* GetSearchedMesh() + { + static auto SearchedMeshOffset = FindOffsetStruct("/Script/FortniteGame.MeshSet", "SearchedMesh"); + return *(UStaticMesh**)(__int64(this) + SearchedMeshOffset); + } + + EFortResourceType& GetResourceType() + { + static auto ResourceTypeOffset = FindOffsetStruct("/Script/FortniteGame.MeshSet", "ResourceType"); + return *(EFortResourceType*)(__int64(this) + ResourceTypeOffset); + } + + float& GetLootNoiseRange() + { + static auto LootNoiseRangeOffset = FindOffsetStruct("/Script/FortniteGame.MeshSet", "LootNoiseRange"); + return *(float*)(__int64(this) + LootNoiseRangeOffset); + } + + FVector& GetLootSpawnLocation() + { + static auto LootSpawnLocationOffset = FindOffsetStruct("/Script/FortniteGame.MeshSet", "LootSpawnLocation"); + return *(FVector*)(__int64(this) + LootSpawnLocationOffset); + } + + float& GetLootNoiseLoudness() + { + static auto LootNoiseLoudnessOffset = FindOffsetStruct("/Script/FortniteGame.MeshSet", "LootNoiseLoudness"); + return *(float*)(__int64(this) + LootNoiseLoudnessOffset); + } + + FCurveTableRowHandle& GetSearchSpeed() + { + static auto SearchSpeedOffset = FindOffsetStruct("/Script/FortniteGame.MeshSet", "SearchSpeed"); + return *(FCurveTableRowHandle*)(__int64(this) + SearchSpeedOffset); + } + + UParticleSystem*& GetConstructedEffect() + { + static auto ConstructedEffectOffset = FindOffsetStruct("/Script/FortniteGame.MeshSet", "ConstructedEffect"); + return *(UParticleSystem**)(__int64(this) + ConstructedEffectOffset); + } + + UParticleSystem*& GetBreakEffect() + { + static auto BreakEffectOffset = FindOffsetStruct("/Script/FortniteGame.MeshSet", "BreakEffect"); + return *(UParticleSystem**)(__int64(this) + BreakEffectOffset); + } +}; + +struct FTierMeshSets +{ + int32& GetTier() + { + static auto TierOffset = FindOffsetStruct("/Script/FortniteGame.TierMeshSets", "Tier"); + return *(int32*)(__int64(this) + TierOffset); + } + + TArray& GetMeshSets() + { + static auto MeshSetsOffset = FindOffsetStruct("/Script/FortniteGame.TierMeshSets", "MeshSets"); + return *(TArray*)(__int64(this) + MeshSetsOffset); + } +}; + class ABuildingSMActor : public ABuildingActor { public: @@ -23,6 +108,20 @@ public: return ReadBitfieldValue(bPlayerPlacedOffset, bPlayerPlacedFieldMask); } + TArray& GetAlternateMeshes() + { + static auto AlternateMeshesOffset = GetOffset("AlternateMeshes"); + return Get>(AlternateMeshesOffset); + } + + int32& GetAltMeshIdx() + { + static auto AltMeshIdxOffset = GetOffset("AltMeshIdx"); + return Get(AltMeshIdxOffset); + } + + void BuildingSMActor_SetMeshSet(FMeshSet* MeshSet); + void SetPlayerPlaced(bool NewValue) { static auto bPlayerPlacedOffset = GetOffset("bPlayerPlaced"); @@ -42,6 +141,12 @@ public: return Get(CurrentBuildingLevelOffset); } + UStaticMeshComponent*& GetStaticMeshComponent() + { + static auto StaticMeshComponentOffset = GetOffset("StaticMeshComponent"); + return Get(StaticMeshComponentOffset); + } + EFortResourceType& GetResourceType() { static auto ResourceTypeOffset = GetOffset("ResourceType"); diff --git a/Project Reboot 3.0/FortAthenaMutator_InventoryOverride.h b/Project Reboot 3.0/FortAthenaMutator_InventoryOverride.h index 324bfcb..a5c3244 100644 --- a/Project Reboot 3.0/FortAthenaMutator_InventoryOverride.h +++ b/Project Reboot 3.0/FortAthenaMutator_InventoryOverride.h @@ -98,7 +98,7 @@ public: if (LoadoutTeam.TeamIndex == TeamIndex) { if (LoadoutTeam.UpdateOverrideType != EAthenaInventorySpawnOverride::NoOverride) - return LoadoutTeam.UpdateOverrideType; + return LoadoutTeam.UpdateOverrideType; // this is temporary! } } @@ -115,7 +115,7 @@ public: if (LoadoutTeam.TeamIndex == TeamIndex) { if (LoadoutTeam.DropAllItemsOverride != EAthenaLootDropOverride::NoOverride) - return LoadoutTeam.DropAllItemsOverride; + return LoadoutTeam.DropAllItemsOverride; // this is temporary! } } diff --git a/Project Reboot 3.0/FortGameModeAthena.cpp b/Project Reboot 3.0/FortGameModeAthena.cpp index d3e11b8..7d2aa6d 100644 --- a/Project Reboot 3.0/FortGameModeAthena.cpp +++ b/Project Reboot 3.0/FortGameModeAthena.cpp @@ -31,6 +31,7 @@ #include "calendar.h" #include "gui.h" #include +#include "die.h" static UFortPlaylist* GetPlaylistToUse() { @@ -165,8 +166,8 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game if (currentBasePlaylist) { - GameMode->SetCurrentPlaylistName(currentBasePlaylist); - GameState->SetPlaylistId(currentBasePlaylist); + // GameMode->SetCurrentPlaylistName(currentBasePlaylist); + // GameState->SetPlaylistId(currentBasePlaylist); } } else @@ -179,8 +180,8 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game if (GameState->Get(CurrentPlaylistDataOffset)) { - GameMode->SetCurrentPlaylistName(GameState->Get(CurrentPlaylistDataOffset)); - GameState->SetPlaylistId(GameState->Get(CurrentPlaylistDataOffset)); + // GameMode->SetCurrentPlaylistName(GameState->Get(CurrentPlaylistDataOffset)); + // GameState->SetPlaylistId(GameState->Get(CurrentPlaylistDataOffset)); } } } @@ -416,7 +417,8 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game } static auto bWorldIsReadyOffset = GameMode->GetOffset("bWorldIsReady"); - SetBitfield(GameMode->GetPtr(bWorldIsReadyOffset), 1, true); // idk when we actually set this + static auto bWorldIsReadyFieldMask = GetFieldMask(GameMode->GetProperty("bWorldIsReady")); + GameMode->SetBitfieldValue(bWorldIsReadyOffset, bWorldIsReadyFieldMask, true); // idk when we actually set this // Calendar::SetSnow(1000); @@ -553,10 +555,15 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game GetWorld()->Listen(); + FixBuildingContainers(); + LOG_INFO(LogDev, "WorldLevel: {}", GameState->GetWorldLevel()); - SetupAIDirector(); - SetupServerBotManager(); + if (false) + { + SetupAIDirector(); + SetupServerBotManager(); + } bool bPrintCommonObjectPaths = true; @@ -635,7 +642,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game { if (CurrentObject->GetFullName().contains(WorldNamesToStreamAllFoundationsIn.at(z))) { - // I think we only have to set bServerStreamedInLevel. + // I think we only have to set bServerStreamedInLevel but whatever. ShowFoundation((AActor*)CurrentObject); continue; } @@ -644,6 +651,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game } Globals::bStartedListening = true; + // LOG_INFO(LogDev, "Finished listening!"); } bool Ret = false; diff --git a/Project Reboot 3.0/FortLootPackage.cpp b/Project Reboot 3.0/FortLootPackage.cpp index b526a68..aef94c3 100644 --- a/Project Reboot 3.0/FortLootPackage.cpp +++ b/Project Reboot 3.0/FortLootPackage.cpp @@ -406,7 +406,7 @@ std::vector PickLootDrops(FName TierGroupName, int WorldLevel, int For // LTDTables.push_back(LoadObject(L"/Game/Athena/Playlists/Playground/AthenaLootTierData_Client.AthenaLootTierData_Client")); // LPTables.push_back(LoadObject(L"/Game/Athena/Playlists/Playground/AthenaLootPackages_Client.AthenaLootPackages_Client")); - static auto FortGameFeatureDataClass = FindObject("/Script/FortniteGame.FortGameFeatureData"); + static auto FortGameFeatureDataClass = FindObject(L"/Script/FortniteGame.FortGameFeatureData"); if (FortGameFeatureDataClass) { diff --git a/Project Reboot 3.0/FortPlayerController.cpp b/Project Reboot 3.0/FortPlayerController.cpp index 14d7d06..688f18a 100644 --- a/Project Reboot 3.0/FortPlayerController.cpp +++ b/Project Reboot 3.0/FortPlayerController.cpp @@ -433,18 +433,13 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame* if (auto BuildingContainer = Cast(ReceivingActor)) { - static auto bAlreadySearchedOffset = BuildingContainer->GetOffset("bAlreadySearched"); - static auto bAlreadySearchedFieldMask = GetFieldMask(BuildingContainer->GetProperty("bAlreadySearched")); - - if (BuildingContainer->ReadBitfieldValue(bAlreadySearchedOffset, bAlreadySearchedFieldMask)) + if (BuildingContainer->IsAlreadySearched()) return; - // LOG_INFO(LogInteraction, "bAlreadySearchedFieldMask: {}", bAlreadySearchedFieldMask); - - BuildingContainer->SetBitfieldValue(bAlreadySearchedOffset, bAlreadySearchedFieldMask, true); - BuildingContainer->SpawnLoot(PlayerController->GetMyFortPawn()); + BuildingContainer->SetAlreadySearched(true); + // if (BuildingContainer->ShouldDestroyOnSearch()) // BuildingContainer->K2_DestroyActor(); } @@ -1474,6 +1469,7 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo } return ClientOnPawnDiedOriginal(PlayerController, DeathReport); + return ClientOnPawnDiedOriginal(PlayerController, DeathReport); } bool IsBuildingOkForEditing(ABuildingSMActor* BuildingActorToEdit) diff --git a/Project Reboot 3.0/GenericPlatformMath.h b/Project Reboot 3.0/GenericPlatformMath.h index 95439f0..a4f9bc6 100644 --- a/Project Reboot 3.0/GenericPlatformMath.h +++ b/Project Reboot 3.0/GenericPlatformMath.h @@ -21,6 +21,11 @@ public: return (A <= B) ? A : B; } + static FORCEINLINE float InvSqrt(float F) + { + return 1.0f / sqrtf(F); + } + static FORCENOINLINE float Fmod(float X, float Y); static FORCEINLINE int32 FloorToInt(float F) diff --git a/Project Reboot 3.0/Project Reboot 3.0.vcxproj b/Project Reboot 3.0/Project Reboot 3.0.vcxproj index 97bc21f..f87d2d9 100644 --- a/Project Reboot 3.0/Project Reboot 3.0.vcxproj +++ b/Project Reboot 3.0/Project Reboot 3.0.vcxproj @@ -250,6 +250,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 fdd245a..1df2168 100644 --- a/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters +++ b/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters @@ -274,6 +274,9 @@ FortniteGame\Source\FortniteGame\Private\Items + + Reboot\Private + diff --git a/Project Reboot 3.0/SoftObjectPtr.h b/Project Reboot 3.0/SoftObjectPtr.h index 43ad475..18dca1b 100644 --- a/Project Reboot 3.0/SoftObjectPtr.h +++ b/Project Reboot 3.0/SoftObjectPtr.h @@ -32,6 +32,14 @@ public: } } + T* GetByWeakObject() + { + if (SoftObjectPtr.ObjectID.AssetPathName.ComparisonIndex.Value <= 0) + return nullptr; + + return GetObjectByIndex(SoftObjectPtr.WeakPtr.ObjectIndex); + } + T* Get(UClass* ClassToLoad = nullptr, bool bTryToLoad = false) { if (Engine_Version <= 416) diff --git a/Project Reboot 3.0/Vector.h b/Project Reboot 3.0/Vector.h index f00e925..d847488 100644 --- a/Project Reboot 3.0/Vector.h +++ b/Project Reboot 3.0/Vector.h @@ -20,6 +20,9 @@ public: return FVector{ this->X - A.X, this->Y - A.Y, this->Z - A.Z }; } + + FORCEINLINE FVector operator*(float Scale) const; + FORCEINLINE float SizeSquared() const { return X * X + Y * Y + Z * Z; @@ -49,4 +52,9 @@ public: { *this = *this - A; } -}; \ No newline at end of file +}; + +FORCEINLINE FVector FVector::operator*(float Scale) const +{ + return FVector(X * Scale, Y * Scale, Z * Scale); +} \ No newline at end of file diff --git a/Project Reboot 3.0/addresses.cpp b/Project Reboot 3.0/addresses.cpp index c1c6669..794f29f 100644 --- a/Project Reboot 3.0/addresses.cpp +++ b/Project Reboot 3.0/addresses.cpp @@ -291,6 +291,9 @@ void Addresses::FindAll() LOG_INFO(LogDev, "Finding PickSupplyDropLocation"); Addresses::PickSupplyDropLocation = FindPickSupplyDropLocation(); + LOG_INFO(LogDev, "Finding LoadAsset"); + Addresses::LoadAsset = FindLoadAsset(); + LOG_INFO(LogDev, "Finished finding!"); } @@ -359,6 +362,7 @@ void Addresses::Print() LOG_INFO(LogDev, "CombinePickupLea: 0x{:x}", CombinePickupLea - Base); LOG_INFO(LogDev, "CreateBuildingActorCallForDeco: 0x{:x}", CreateBuildingActorCallForDeco - Base); LOG_INFO(LogDev, "PickSupplyDropLocation: 0x{:x}", PickSupplyDropLocation - Base); + LOG_INFO(LogDev, "LoadAsset: 0x{:x}", LoadAsset - Base); } void Offsets::FindAll() diff --git a/Project Reboot 3.0/addresses.h b/Project Reboot 3.0/addresses.h index 85a2e24..e49a8b3 100644 --- a/Project Reboot 3.0/addresses.h +++ b/Project Reboot 3.0/addresses.h @@ -69,6 +69,7 @@ namespace Addresses extern inline uint64 CombinePickupLea = 0; extern inline uint64 CreateBuildingActorCallForDeco = 0; extern inline uint64 PickSupplyDropLocation = 0; + extern inline uint64 LoadAsset = 0; void SetupVersion(); // Finds Engine Version void FindAll(); diff --git a/Project Reboot 3.0/ai.h b/Project Reboot 3.0/ai.h index a8ec7a3..1ab3730 100644 --- a/Project Reboot 3.0/ai.h +++ b/Project Reboot 3.0/ai.h @@ -76,7 +76,7 @@ static void SetupServerBotManager() auto GameState = Cast(GetWorld()->GetGameState()); auto GameMode = Cast(GetWorld()->GetGameMode()); - static auto FortServerBotManagerClass = FindObject("/Script/FortniteGame.FortServerBotManagerAthena"); // Is there a BP for this? // GameMode->ServerBotManagerClass + static auto FortServerBotManagerClass = FindObject(L"/Script/FortniteGame.FortServerBotManagerAthena"); // Is there a BP for this? // GameMode->ServerBotManagerClass if (!FortServerBotManagerClass) return; @@ -92,11 +92,13 @@ static void SetupServerBotManager() static auto CachedGameModeOffset = ServerBotManager->GetOffset("CachedGameMode"); ServerBotManager->Get(CachedGameModeOffset) = GameMode; - static auto CachedGameStateOffset = ServerBotManager->GetOffset("CachedGameState"); - ServerBotManager->Get(CachedGameStateOffset) = GameState; + static auto CachedGameStateOffset = ServerBotManager->GetOffset("CachedGameState", false); + + if (CachedGameStateOffset != -1) + ServerBotManager->Get(CachedGameStateOffset) = GameState; static auto CachedBotMutatorOffset = ServerBotManager->GetOffset("CachedBotMutator"); - ServerBotManager->Get(CachedBotMutatorOffset) = FindFirstMutator(FindObject("/Script/FortniteGame.FortAthenaMutator_Bots")); + ServerBotManager->Get(CachedBotMutatorOffset) = FindFirstMutator(FindObject(L"/Script/FortniteGame.FortAthenaMutator_Bots")); } } @@ -105,7 +107,7 @@ static void SetupAIDirector() auto GameState = Cast(GetWorld()->GetGameState()); auto GameMode = Cast(GetWorld()->GetGameMode()); - static auto AIDirectorClass = FindObject("/Script/FortniteGame.AthenaAIDirector"); // Probably wrong class + static auto AIDirectorClass = FindObject(L"/Script/FortniteGame.AthenaAIDirector"); // Probably wrong class if (!AIDirectorClass) return; diff --git a/Project Reboot 3.0/die.h b/Project Reboot 3.0/die.h index eaa1753..52bee3a 100644 --- a/Project Reboot 3.0/die.h +++ b/Project Reboot 3.0/die.h @@ -174,7 +174,7 @@ static void SetZoneToIndexHook(AFortGameModeAthena* GameModeAthena, int Override SafeZoneIndicator->Get(SafeZoneFinishShrinkTimeOffset) = SafeZoneIndicator->Get(SafeZoneStartShrinkTimeOffset) + ZoneDuration; } -void ProcessEventHook(UObject* Object, UFunction* Function, void* Parameters) +static inline void ProcessEventHook(UObject* Object, UFunction* Function, void* Parameters) { if (!Object || !Function) return; @@ -330,4 +330,23 @@ void ProcessEventHook(UObject* Object, UFunction* Function, void* Parameters) } return Object->ProcessEvent(Function, Parameters); +} + +static inline void FixBuildingContainers() +{ + if (Fortnite_Version > 2) + return; + + auto AllBuildingContainers = UGameplayStatics::GetAllActorsOfClass(GetWorld(), ABuildingContainer::StaticClass()); + + for (int i = 0; i < AllBuildingContainers.size(); i++) + { + auto BuildingContainer = (ABuildingContainer*)AllBuildingContainers.at(i); + + // TODO Figure it out proper (i think its something like this) + + // BuildingContainer->GetAltMeshIdx() = BuildingContainer->GetAlternateMeshes().Num() > 0 ? BuildingContainer->GetAlternateMeshes().Num() - 1 : 0; + } + + AllBuildingContainers.Free(); } \ No newline at end of file diff --git a/Project Reboot 3.0/dllmain.cpp b/Project Reboot 3.0/dllmain.cpp index b8901e9..fe6e963 100644 --- a/Project Reboot 3.0/dllmain.cpp +++ b/Project Reboot 3.0/dllmain.cpp @@ -403,7 +403,7 @@ DWORD WINAPI Main(LPVOID) } Hooking::MinHook::Hook(GameModeDefault, FindObject(L"/Script/Engine.GameMode.ReadyToStartMatch"), AFortGameModeAthena::Athena_ReadyToStartMatchHook, - (PVOID*)&AFortGameModeAthena::Athena_ReadyToStartMatchOriginal, false, false, true); + (PVOID*)&AFortGameModeAthena::Athena_ReadyToStartMatchOriginal, false, false, true); Hooking::MinHook::Hook(GameModeDefault, FindObject(L"/Script/Engine.GameModeBase.SpawnDefaultPawnFor"), AGameModeBase::SpawnDefaultPawnForHook, nullptr, false); @@ -442,8 +442,11 @@ DWORD WINAPI Main(LPVOID) // Hooking::MinHook::Hook(FortPlayerControllerZoneDefault->VFTable[0xD0 / 8], CanCreateInCurrentContextHook, (PVOID*)&CanCreateInCurrentContextOriginal); - HookInstruction(Addresses::UpdateTrackedAttributesLea, (PVOID)UFortGadgetItemDefinition::UpdateTrackedAttributesHook, "/Script/FortniteGame.FortPlayerController.Suicide", ERelativeOffsets::LEA, FortPlayerControllerAthenaDefault); - HookInstruction(Addresses::CombinePickupLea, (PVOID)AFortPickup::CombinePickupHook, "/Script/Engine.PlayerController.SetVirtualJoystickVisibility", ERelativeOffsets::LEA, FortPlayerControllerAthenaDefault); + if (false) + { + HookInstruction(Addresses::UpdateTrackedAttributesLea, (PVOID)UFortGadgetItemDefinition::UpdateTrackedAttributesHook, "/Script/FortniteGame.FortPlayerController.Suicide", ERelativeOffsets::LEA, FortPlayerControllerAthenaDefault); + HookInstruction(Addresses::CombinePickupLea, (PVOID)AFortPickup::CombinePickupHook, "/Script/Engine.PlayerController.SetVirtualJoystickVisibility", ERelativeOffsets::LEA, FortPlayerControllerAthenaDefault); + } Hooking::MinHook::Hook(FortWeaponDefault, FindObject(L"/Script/FortniteGame.FortWeapon.ServerReleaseWeaponAbility"), AFortWeapon::ServerReleaseWeaponAbilityHook, (PVOID*)&AFortWeapon::ServerReleaseWeaponAbilityOriginal, false, true); diff --git a/Project Reboot 3.0/finder.h b/Project Reboot 3.0/finder.h index 624ae19..a54d709 100644 --- a/Project Reboot 3.0/finder.h +++ b/Project Reboot 3.0/finder.h @@ -165,6 +165,22 @@ static inline uint64 FindPickupInitialize() return 0; } +static inline uint64 FindLoadAsset() +{ + auto Addrr = Memcury::Scanner::FindStringRef(L"Loaded delay-load asset %s").Get(); + + for (int i = 0; i < 2000; i++) + { + if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x48 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x89 && + (*(uint8_t*)(uint8_t*)(Addrr - i + 2) == 0x74 || *(uint8_t*)(uint8_t*)(Addrr - i + 2) == 0x6C)) + { + return Addrr - i; + } + } + + return 0; +} + static inline uint64 FindCreateNetDriver() { return 0; diff --git a/Project Reboot 3.0/reboot.cpp b/Project Reboot 3.0/reboot.cpp new file mode 100644 index 0000000..87126cb --- /dev/null +++ b/Project Reboot 3.0/reboot.cpp @@ -0,0 +1,29 @@ +#include "reboot.h" + +#include "SoftObjectPtr.h" + +#include "KismetStringLibrary.h" + +inline UObject* Assets::LoadAsset(FName Name, bool ShowDelayTimes) +{ + static UObject* (*LoadAssetOriginal)(FName a1, bool a2); + + return LoadAssetOriginal(Name, ShowDelayTimes); +} + +inline UObject* Assets::LoadSoftObject(void* SoftObjectPtr) +{ + if (Engine_Version == 416) + { + auto tAssetPtr = (TAssetPtr*)SoftObjectPtr; + // return LoadAsset(tAssetPtr->AssetPtr.ObjectID.AssetLongPathname.); + return nullptr; // later + } + + auto tSoftObjectPtr = (TSoftObjectPtr*)SoftObjectPtr; + + // if (auto WeakObject = tSoftObjectPtr->GetByWeakObject()) + // return WeakObject; + + return LoadAsset(tSoftObjectPtr->SoftObjectPtr.ObjectID.AssetPathName); +} \ No newline at end of file diff --git a/Project Reboot 3.0/reboot.h b/Project Reboot 3.0/reboot.h index 18c5d27..60bc596 100644 --- a/Project Reboot 3.0/reboot.h +++ b/Project Reboot 3.0/reboot.h @@ -384,6 +384,12 @@ static void CopyStruct(void* Dest, void* Src, size_t Size, UStruct* Struct = nul } } +class Assets +{ + static inline UObject* LoadAsset(FName Name, bool ShowDelayTimes = false); + static inline UObject* LoadSoftObject(void* SoftObjectPtr); +}; + template static T* Alloc(size_t Size = sizeof(T), bool bUseFMemoryRealloc = false) {