diff --git a/Project Reboot 3.0/BuildingActor.cpp b/Project Reboot 3.0/BuildingActor.cpp index 011f3c0..9cdfee3 100644 --- a/Project Reboot 3.0/BuildingActor.cpp +++ b/Project Reboot 3.0/BuildingActor.cpp @@ -19,26 +19,51 @@ void ABuildingActor::OnDamageServerHook(ABuildingActor* BuildingActor, float Dam auto BuildingSMActor = Cast(BuildingActor); auto PlayerController = Cast(InstigatedBy); - auto Pawn = PlayerController ? PlayerController->GetMyFortPawn() : nullptr; + // auto Pawn = PlayerController ? PlayerController->GetMyFortPawn() : nullptr; auto Weapon = Cast(DamageCauser); - if (!BuildingSMActor || !PlayerController || !Pawn || !Weapon) + if (!BuildingSMActor) + return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext); + + if (BuildingSMActor->IsDestroyed()) + return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext); + + static auto LastDamageAmountOffset = BuildingSMActor->GetOffset("LastDamageAmount"); + static auto LastDamageHitOffset = BuildingSMActor->GetOffset("LastDamageHit", false) != -1 ? BuildingSMActor->GetOffset("LastDamageHit") : BuildingSMActor->GetOffset("LastDamageHitImpulseDir"); // idc + + const float PreviousLastDamageAmount = BuildingSMActor->Get(LastDamageAmountOffset); + const float PreviousLastDamageHit = BuildingSMActor->Get(LastDamageHitOffset); + const float CurrentBuildingHealth = BuildingActor->GetHealth(); + + BuildingSMActor->Get(LastDamageAmountOffset) = Damage; + BuildingSMActor->Get(LastDamageHitOffset) = CurrentBuildingHealth; + + if (!PlayerController || !Weapon) + return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext); + + // if (!Pawn) + // return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext); + + auto WorldInventory = PlayerController->GetWorldInventory(); + + if (!WorldInventory) return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext); auto WeaponData = Cast(Weapon->GetWeaponData()); if (!WeaponData) return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext); - - if (BuildingSMActor->IsDestroyed()) - return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext); - auto ResourceCount = 0; UFortResourceItemDefinition* ItemDef = UFortKismetLibrary::K2_GetResourceItemDefinition(BuildingSMActor->GetResourceType()); + if (!ItemDef) + return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext); + static auto BuildingResourceAmountOverrideOffset = BuildingSMActor->GetOffset("BuildingResourceAmountOverride"); auto& BuildingResourceAmountOverride = BuildingSMActor->Get(BuildingResourceAmountOverrideOffset); + int ResourceCount = 0; + if (BuildingResourceAmountOverride.RowName.IsValid()) { // auto AssetManager = Cast(GEngine->AssetManager); @@ -48,7 +73,7 @@ void ABuildingActor::OnDamageServerHook(ABuildingActor* BuildingActor, float Dam // LOG_INFO(LogDev, "Before1"); if (!CurveTable) - CurveTable = FindObject("/Game/Athena/Balance/DataTables/AthenaResourceRates.AthenaResourceRates"); + CurveTable = FindObject(L"/Game/Athena/Balance/DataTables/AthenaResourceRates.AthenaResourceRates"); { // auto curveMap = ((UDataTable*)CurveTable)->GetRowMap(); @@ -59,31 +84,27 @@ void ABuildingActor::OnDamageServerHook(ABuildingActor* BuildingActor, float Dam // LOG_INFO(LogDev, "Out: {}", Out); - auto DamageThatWillAffect = Damage; + const float DamageThatWillAffect = PreviousLastDamageHit > 0 && Damage > PreviousLastDamageHit ? PreviousLastDamageHit : Damage; - float skid = Out / (BuildingSMActor->GetMaxHealth() / DamageThatWillAffect); + float skid = Out / (BuildingActor->GetMaxHealth() / DamageThatWillAffect); - ResourceCount = round(skid); // almost right + ResourceCount = round(skid); } } - if (!ItemDef || ResourceCount <= 0) + if (ResourceCount <= 0) { return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext); - // return OnDamageServer(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext); } bool bIsWeakspot = Damage == 100.0f; PlayerController->ClientReportDamagedResourceBuilding(BuildingSMActor, BuildingSMActor->GetResourceType(), ResourceCount, false, bIsWeakspot); - if (ResourceCount > 0) - { - bool bShouldUpdate = false; - PlayerController->GetWorldInventory()->AddItem(ItemDef, &bShouldUpdate, ResourceCount); + bool bShouldUpdate = false; + WorldInventory->AddItem(ItemDef, &bShouldUpdate, ResourceCount); - if (bShouldUpdate) - PlayerController->GetWorldInventory()->Update(); - } + if (bShouldUpdate) + WorldInventory->Update(); return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext); } diff --git a/Project Reboot 3.0/BuildingActor.h b/Project Reboot 3.0/BuildingActor.h index 9bc2a56..5d72862 100644 --- a/Project Reboot 3.0/BuildingActor.h +++ b/Project Reboot 3.0/BuildingActor.h @@ -31,7 +31,7 @@ public: void SilentDie() { - static auto SilentDieFn = FindObject("/Script/FortniteGame.BuildingActor.SilentDie"); + static auto SilentDieFn = FindObject(L"/Script/FortniteGame.BuildingActor.SilentDie"); bool bPropagateSilentDeath = false; // idfk this->ProcessEvent(SilentDieFn, &bPropagateSilentDeath); } @@ -39,7 +39,7 @@ public: float GetMaxHealth() { float MaxHealth = 0; - static auto fn = FindObject("/Script/FortniteGame.BuildingActor.GetMaxHealth"); + static auto fn = FindObject(L"/Script/FortniteGame.BuildingActor.GetMaxHealth"); this->ProcessEvent(fn, &MaxHealth); return MaxHealth; } @@ -47,14 +47,22 @@ public: float GetHealthPercent() // aka GetHealth() / GetMaxHealth() { float HealthPercent = 0; - static auto fn = FindObject("/Script/FortniteGame.BuildingActor.GetHealthPercent"); + static auto fn = FindObject(L"/Script/FortniteGame.BuildingActor.GetHealthPercent"); this->ProcessEvent(fn, &HealthPercent); return HealthPercent; } + float GetHealth() + { + float Health = 0; + static auto fn = FindObject("/Script/FortniteGame.BuildingActor.GetHealth"); + this->ProcessEvent(fn, &Health); + return Health; + } + void SetTeam(unsigned char InTeam) { - static auto fn = nullptr; // FindObject("/Script/FortniteGame.BuildingActor.SetTeam"); + static auto fn = nullptr; // FindObject(L"/Script/FortniteGame.BuildingActor.SetTeam"); if (!fn) { diff --git a/Project Reboot 3.0/CheatManager.cpp b/Project Reboot 3.0/CheatManager.cpp index f2e77ba..70d51e3 100644 --- a/Project Reboot 3.0/CheatManager.cpp +++ b/Project Reboot 3.0/CheatManager.cpp @@ -8,6 +8,12 @@ void UCheatManager::Teleport() this->ProcessEvent(TeleportFn); } +void UCheatManager::DestroyTarget() +{ + static auto DestroyTargetFn = FindObject("/Script/Engine.CheatManager.DestroyTarget"); + this->ProcessEvent(DestroyTargetFn); +} + UClass* UCheatManager::StaticClass() { static auto Class = FindObject(L"/Script/Engine.CheatManager"); diff --git a/Project Reboot 3.0/CheatManager.h b/Project Reboot 3.0/CheatManager.h index 6ef989d..f1ee34b 100644 --- a/Project Reboot 3.0/CheatManager.h +++ b/Project Reboot 3.0/CheatManager.h @@ -6,6 +6,7 @@ class UCheatManager : public UObject { public: void Teleport(); + void DestroyTarget(); static UClass* StaticClass(); }; \ No newline at end of file diff --git a/Project Reboot 3.0/Class.h b/Project Reboot 3.0/Class.h index f950bf4..2b7b4cb 100644 --- a/Project Reboot 3.0/Class.h +++ b/Project Reboot 3.0/Class.h @@ -12,6 +12,12 @@ struct UField : UObject // void* pad; void* pad2; }; +struct UFieldPadding : UObject +{ + UField* Next; + void* pad; void* pad2; +}; + template static inline PropertyType* GetNext(void* Field) { @@ -57,7 +63,7 @@ class UEnum : public UField public: int64 GetValue(const std::string& EnumMemberName) { - auto Names = (TArray>*)(__int64(this) + sizeof(UField) + sizeof(FString)); + auto Names = (TArray>*)(__int64(this) + sizeof(UField) + sizeof(FString)); for (int i = 0; i < Names->Num(); ++i) { @@ -65,8 +71,13 @@ public: auto& Name = Pair.Key(); auto Value = Pair.Value(); - if (Name.ComparisonIndex.Value && Name.ToString().contains(EnumMemberName)) - return Value; + if (Name.ComparisonIndex.Value) + { + auto nameStr = Name.ToString(); + + if (nameStr.contains(EnumMemberName)) + return Value; + } } return -1; diff --git a/Project Reboot 3.0/FortPickup.h b/Project Reboot 3.0/FortPickup.h index 39a155a..207a919 100644 --- a/Project Reboot 3.0/FortPickup.h +++ b/Project Reboot 3.0/FortPickup.h @@ -47,7 +47,7 @@ namespace EFortPickupSpawnSource { static inline UEnum* GetEnum() { - static auto Enum = FindObject("/Script/FortniteGame.EFortPickupSpawnSource"); + static auto Enum = FindObject(L"/Script/FortniteGame.EFortPickupSpawnSource"); return Enum; } diff --git a/Project Reboot 3.0/FortPlayerController.cpp b/Project Reboot 3.0/FortPlayerController.cpp index f1faa0c..200cb3f 100644 --- a/Project Reboot 3.0/FortPlayerController.cpp +++ b/Project Reboot 3.0/FortPlayerController.cpp @@ -994,7 +994,17 @@ void AFortPlayerController::ServerAttemptInventoryDropHook(AFortPlayerController if (!ItemDefinition->ShouldIgnoreRespawningOnDrop() && (DropBehaviorOffset != -1 ? ItemDefinition->GetDropBehavior() != EWorldItemDropBehavior::DestroyOnDrop : true)) { - auto Pickup = AFortPickup::SpawnPickup(ReplicatedEntry, Pawn->GetActorLocation(), EFortPickupSourceTypeFlag::GetPlayerValue(), 0, Pawn, nullptr, true, Count); + PickupCreateData CreateData; + CreateData.ItemEntry = ReplicatedEntry; + CreateData.SpawnLocation = Pawn->GetActorLocation(); + CreateData.bToss = true; + CreateData.OverrideCount = Count; + CreateData.PawnOwner = Pawn; + CreateData.bRandomRotation = true; + CreateData.SourceType = EFortPickupSourceTypeFlag::GetPlayerValue(); + CreateData.bShouldFreeItemEntryWhenDeconstructed = false; + + auto Pickup = AFortPickup::SpawnPickup(CreateData); if (!Pickup) return; diff --git a/Project Reboot 3.0/commands.h b/Project Reboot 3.0/commands.h index 1291857..6e23bd9 100644 --- a/Project Reboot 3.0/commands.h +++ b/Project Reboot 3.0/commands.h @@ -537,7 +537,7 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg) return; } - static auto LaunchCharacterFn = FindObject("/Script/Engine.Character.LaunchCharacter"); + static auto LaunchCharacterFn = FindObject(L"/Script/Engine.Character.LaunchCharacter"); struct { @@ -817,6 +817,20 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg) CheatManager = nullptr; SendMessageToConsole(PlayerController, L"Teleported!"); } + else if (Command == "destroytarget") + { + auto CheatManager = ReceivingController->SpawnCheatManager(UCheatManager::StaticClass()); + + if (!CheatManager) + { + SendMessageToConsole(PlayerController, L"Failed to spawn player's cheat manager!"); + return; + } + + CheatManager->DestroyTarget(); + CheatManager = nullptr; + SendMessageToConsole(PlayerController, L"Destroyed target!"); + } else if (Command == "bugitgo") { if (Arguments.size() <= 3) @@ -865,6 +879,7 @@ cheat spawnpickup - Spawns a pickup at specified player. cheat teleport - Teleports to what the player is looking at. cheat spawnbot - Spawns a bot at the player (experimental). cheat setpickaxe - Set player's pickaxe. +cheat destroytarget - Destroys the actor that the player is looking at. If you want to execute a command on a certain player, surround their name (case sensitive) with \, and put the param anywhere. Example: cheat sethealth \Milxnor\ 100 )";