diff --git a/Project Reboot 3.0/Actor.cpp b/Project Reboot 3.0/Actor.cpp index 73088e1..933a3b6 100644 --- a/Project Reboot 3.0/Actor.cpp +++ b/Project Reboot 3.0/Actor.cpp @@ -87,6 +87,19 @@ void AActor::FlushNetDormancy() this->ProcessEvent(fn); } +bool AActor::TeleportTo(const FVector& DestLocation, const FRotator& DestRotation) +{ + static auto fn = FindObject("/Script/Engine.Actor.K2_TeleportTo"); + struct + { + struct FVector DestLocation; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + struct FRotator DestRotation; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, NativeAccessSpecifierPublic) + bool ReturnValue; // (Parm, OutParm, ZeroConstructor, ReturnParm, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + } AActor_K2_TeleportTo_Params{DestLocation, DestRotation}; + this->ProcessEvent(fn, &AActor_K2_TeleportTo_Params); + return AActor_K2_TeleportTo_Params.ReturnValue; +} + UClass* AActor::StaticClass() { static auto Class = FindObject(L"/Script/Engine.Actor"); diff --git a/Project Reboot 3.0/Actor.h b/Project Reboot 3.0/Actor.h index 71ea66e..47a62fb 100644 --- a/Project Reboot 3.0/Actor.h +++ b/Project Reboot 3.0/Actor.h @@ -15,6 +15,7 @@ public: float GetDistanceTo(AActor* OtherActor); struct FRotator GetActorRotation(); void FlushNetDormancy(); + bool TeleportTo(const FVector& DestLocation, const FRotator& DestRotation); static class UClass* StaticClass(); }; \ No newline at end of file diff --git a/Project Reboot 3.0/CurveTable.h b/Project Reboot 3.0/CurveTable.h index c264c4a..e21150a 100644 --- a/Project Reboot 3.0/CurveTable.h +++ b/Project Reboot 3.0/CurveTable.h @@ -3,6 +3,8 @@ #include "Object.h" #include "NameTypes.h" +#include "reboot.h" + class UCurveTable : public UObject { public: @@ -12,4 +14,28 @@ struct FCurveTableRowHandle { UCurveTable* CurveTable; FName RowName; +}; + +struct FSimpleCurveKey +{ + float Time; // 0x0000(0x0004) (Edit, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + float Value; // 0x0004(0x0004) (Edit, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) +}; + +struct FIndexedCurve +{ + +}; + +struct FRealCurve : public FIndexedCurve +{ +}; + +struct FSimpleCurve : public FRealCurve +{ + TArray& GetKeys() + { + static auto KeysOffset = FindOffsetStruct("/Script/Engine.SimpleCurve", "Keys"); + return *(TArray*)(__int64(this) + KeysOffset); + } }; \ No newline at end of file diff --git a/Project Reboot 3.0/FortGameModeAthena.cpp b/Project Reboot 3.0/FortGameModeAthena.cpp index ff18cfd..479f355 100644 --- a/Project Reboot 3.0/FortGameModeAthena.cpp +++ b/Project Reboot 3.0/FortGameModeAthena.cpp @@ -698,9 +698,11 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena 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"); + static auto backpackPart = LoadObject("/Game/Characters/CharacterParts/Backpacks/NoBackpack.NoBackpack"); Parts[(int)EFortCustomPartType::Head] = headPart; Parts[(int)EFortCustomPartType::Body] = bodyPart; + Parts[(int)EFortCustomPartType::Backpack] = backpackPart; static auto OnRep_CharacterPartsFn = FindObject("/Script/FortniteGame.FortPlayerState.OnRep_CharacterParts"); PlayerStateAthena->ProcessEvent(OnRep_CharacterPartsFn); @@ -726,9 +728,9 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena PlayerStateAthena->ProcessEvent(OnRep_bHasStartedPlayingFn); } - // static int CurrentPlayerId = 1; - static auto PlayerIdOffset = PlayerStateAthena->GetOffset("PlayerId"); - PlayerStateAthena->GetWorldPlayerId() = PlayerStateAthena->Get(PlayerIdOffset); // ++CurrentPlayerId; + static int CurrentPlayerId = 1; + // static auto PlayerIdOffset = PlayerStateAthena->GetOffset("PlayerId"); // Unable to find tf + PlayerStateAthena->GetWorldPlayerId() = ++CurrentPlayerId; // PlayerStateAthena->Get(PlayerIdOffset); // if (Globals::bAbilitiesEnabled) { diff --git a/Project Reboot 3.0/FortInventory.cpp b/Project Reboot 3.0/FortInventory.cpp index a628aaa..7b2dba6 100644 --- a/Project Reboot 3.0/FortInventory.cpp +++ b/Project Reboot 3.0/FortInventory.cpp @@ -1,5 +1,6 @@ #include "FortInventory.h" #include "FortPlayerController.h" +#include "FortPickup.h" UFortItem* CreateItemInstance(AFortPlayerController* PlayerController, UFortItemDefinition* ItemDefinition, int Count) { @@ -24,11 +25,90 @@ std::pair, std::vector> AFortInventory::AddI LoadedAmmo = 0; } + auto& ItemInstances = GetItemList().GetItemInstances(); + + auto MaxStackSize = ItemDefinition->GetMaxStackSize(); + + bool bAllowMultipleStacks = true; + int OverStack = 0; + std::vector NewItemInstances; std::vector ModifiedItemInstances; + if (MaxStackSize > 1) + { + for (int i = 0; i < ItemInstances.Num(); i++) + { + auto CurrentItemInstance = ItemInstances.at(i); + auto CurrentEntry = CurrentItemInstance->GetItemEntry(); + + if (CurrentEntry->GetItemDefinition() == ItemDefinition) + { + if (CurrentEntry->GetCount() < MaxStackSize || !bAllowMultipleStacks) + { + OverStack = CurrentEntry->GetCount() + Count - MaxStackSize; + + if (!bAllowMultipleStacks && !(CurrentEntry->GetCount() < MaxStackSize)) + { + break; + } + + int AmountToStack = OverStack > 0 ? Count - OverStack : Count; + + auto ReplicatedEntry = FindReplicatedEntry(CurrentEntry->GetItemGuid()); + + CurrentEntry->GetCount() += AmountToStack; + ReplicatedEntry->GetCount() += AmountToStack; + + // std::cout << std::format("{} : {} : {}\n", CurrentEntry.Count, ReplicatedEntry->Count, OverStack); + + /* if (bAddToStateValues) + { + FFortItemEntryStateValue StateValue; + StateValue.IntValue = 1; + StateValue.StateType = EFortItemEntryState::ShouldShowItemToast; + + CurrentEntry.StateValues.Add(StateValue); + ReplicatedEntry->StateValues.Add(StateValue); + } + else + { + // CurrentEntry.StateValues.FreeBAD(); + // ReplicatedEntry->StateValues.FreeBAD(); + } */ + + ModifiedItemInstances.push_back(CurrentItemInstance); + + GetItemList().MarkItemDirty(CurrentEntry); + GetItemList().MarkItemDirty(ReplicatedEntry); + + if (OverStack <= 0) + return std::make_pair(NewItemInstances, ModifiedItemInstances); + + // break; + } + } + } + } + + Count = OverStack > 0 ? OverStack : Count; + auto PlayerController = Cast(GetOwner()); + if (!PlayerController) + return std::make_pair(NewItemInstances, ModifiedItemInstances); + + if (OverStack > 0 && !bAllowMultipleStacks) + { + auto Pawn = PlayerController->GetMyFortPawn(); + + if (!Pawn) + return std::make_pair(NewItemInstances, ModifiedItemInstances); + + AFortPickup::SpawnPickup(ItemDefinition, Pawn->GetActorLocation(), Count, EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset, -1, Pawn); + return std::make_pair(NewItemInstances, ModifiedItemInstances); + } + UFortItem* NewItemInstance = CreateItemInstance(PlayerController, ItemDefinition, Count); if (NewItemInstance) @@ -46,7 +126,7 @@ std::pair, std::vector> AFortInventory::AddI // LOG_INFO(LogDev, "FortItemEntryStruct {}", __int64(FortItemEntryStruct)); // LOG_INFO(LogDev, "FortItemEntrySize {}", __int64(FortItemEntrySize)); - GetItemList().GetItemInstances().Add(NewItemInstance); + ItemInstances.Add(NewItemInstance); GetItemList().GetReplicatedEntries().Add(*NewItemInstance->GetItemEntry(), FortItemEntrySize); if (bShouldUpdate) diff --git a/Project Reboot 3.0/FortItemDefinition.cpp b/Project Reboot 3.0/FortItemDefinition.cpp index 09f005f..4933874 100644 --- a/Project Reboot 3.0/FortItemDefinition.cpp +++ b/Project Reboot 3.0/FortItemDefinition.cpp @@ -1,4 +1,6 @@ #include "FortItemDefinition.h" +#include "CurveTable.h" +#include "DataTable.h" UFortItem* UFortItemDefinition::CreateTemporaryItemInstanceBP(int Count, int Level) { @@ -14,10 +16,42 @@ float UFortItemDefinition::GetMaxStackSize() { static auto MaxStackSizeOffset = this->GetOffset("MaxStackSize"); - bool bIsScalableFloat = false; + bool bIsScalableFloat = Engine_Version >= 424; // idk if (!bIsScalableFloat) return Get(MaxStackSizeOffset); - return 0; + struct FScalableFloat + { + public: + float Value; // 0x0(0x4)(Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + uint8 Pad_3BF0[0x4]; // Fixing Size After Last Property [ Dumper-7 ] + FCurveTableRowHandle Curve; // 0x8(0x10)(Edit, BlueprintVisible, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + }; + + static auto AthenaGameData = FindObject("/Game/Athena/Balance/DataTables/AthenaGameData.AthenaGameData"); + + auto& ScalableFloat = Get(MaxStackSizeOffset); + auto& RowMap = AthenaGameData->GetRowMap(); + + if (ScalableFloat.Curve.RowName.ComparisonIndex.Value == 0) + return ScalableFloat.Value; + + FSimpleCurve* Curve = nullptr; + + for (int i = 0; i < RowMap.Pairs.Elements.Data.Num(); i++) + { + auto& Pair = RowMap.Pairs.Elements.Data.at(i).ElementData.Value; + + if (Pair.Key() == ScalableFloat.Curve.RowName) + { + Curve = (FSimpleCurve*)Pair.Value(); + break; + } + } + + if (!Curve) + return 1; + + return Curve->GetKeys().at(0).Value; } \ No newline at end of file diff --git a/Project Reboot 3.0/FortKismetLibrary.cpp b/Project Reboot 3.0/FortKismetLibrary.cpp index 7b10734..354271e 100644 --- a/Project Reboot 3.0/FortKismetLibrary.cpp +++ b/Project Reboot 3.0/FortKismetLibrary.cpp @@ -1,5 +1,6 @@ #include "FortKismetLibrary.h" #include "ScriptInterface.h" +#include "FortPickup.h" UFortResourceItemDefinition* UFortKismetLibrary::K2_GetResourceItemDefinition(EFortResourceType ResourceType) { @@ -74,71 +75,80 @@ void UFortKismetLibrary::GiveItemToInventoryOwnerHook(UObject* Context, FFrame& static auto ItemLevelOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.GiveItemToInventoryOwner", "ItemLevel"); static auto PickupInstigatorHandleOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.GiveItemToInventoryOwner", "PickupInstigatorHandle"); - LOG_INFO(LogDev, "wtf: {}", __int64(Stack.Code)); - - return; + // return GiveItemToInventoryOwnerOriginal(Context, Stack, Ret); TScriptInterface InventoryOwner; // = *(TScriptInterface*)(__int64(Params) + InventoryOwnerOffset); - UFortWorldItemDefinition* ItemDefinition; // *(UFortWorldItemDefinition**)(__int64(Params) + ItemDefinitionOffset); + UFortWorldItemDefinition* ItemDefinition = nullptr; // *(UFortWorldItemDefinition**)(__int64(Params) + ItemDefinitionOffset); int NumberToGive; // = *(int*)(__int64(Params) + NumberToGiveOffset); bool bNotifyPlayer; // = *(bool*)(__int64(Params) + bNotifyPlayerOffset); int ItemLevel; // = *(int*)(__int64(Params) + ItemLevelOffset); int PickupInstigatorHandle; // = *(int*)(__int64(Params) + PickupInstigatorHandleOffset); - Stack.Step(Context, &InventoryOwner); - Stack.Step(Context, &ItemDefinition); - Stack.Step(Context, &NumberToGive); - Stack.Step(Context, &bNotifyPlayer); - Stack.Step(Context, &ItemLevel); - Stack.Step(Context, &PickupInstigatorHandle); + Stack.Step(Stack.Object, &InventoryOwner); + Stack.Step(Stack.Object, &ItemDefinition); + Stack.Step(Stack.Object, &NumberToGive); + Stack.Step(Stack.Object, &bNotifyPlayer); + Stack.Step(Stack.Object, &ItemLevel); + Stack.Step(Stack.Object, &PickupInstigatorHandle); + + if (!ItemDefinition) + return GiveItemToInventoryOwnerOriginal(Context, Stack, Ret); auto InterfacePointer = InventoryOwner.InterfacePointer; LOG_INFO(LogDev, "InterfacePointer: {}", __int64(InterfacePointer)); if (!InterfacePointer) - return; + return GiveItemToInventoryOwnerOriginal(Context, Stack, Ret); auto ObjectPointer = InventoryOwner.ObjectPointer; - if (!ObjectPointer) - return; + LOG_INFO(LogDev, "ObjectPointer: {}", __int64(ObjectPointer)); - // LOG_INFO(LogDev, "ObjectPointer Name: {}", ObjectPointer->GetFullName()); + if (!ObjectPointer) + return GiveItemToInventoryOwnerOriginal(Context, Stack, Ret); + + LOG_INFO(LogDev, "ObjectPointer Name: {}", ObjectPointer->GetFullName()); + + auto PlayerController = Cast(ObjectPointer); + + if (!PlayerController) + return GiveItemToInventoryOwnerOriginal(Context, Stack, Ret); + + bool bShouldUpdate = false; + LOG_INFO(LogDev, "ItemDefinition: {}", __int64(ItemDefinition)); + LOG_INFO(LogDev, "ItemDefinition Name: {}", ItemDefinition->GetFullName()); + PlayerController->GetWorldInventory()->AddItem(ItemDefinition, &bShouldUpdate, NumberToGive, -1, bNotifyPlayer); + + if (bShouldUpdate) + PlayerController->GetWorldInventory()->Update(); return GiveItemToInventoryOwnerOriginal(Context, Stack, Ret); } void UFortKismetLibrary::K2_RemoveItemFromPlayerHook(UObject* Context, FFrame& Stack, void* Ret) { - struct UFortKismetLibrary_K2_RemoveItemFromPlayer_Params - { - AFortPlayerController* PlayerController; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) - UFortWorldItemDefinition* ItemDefinition; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) - int AmountToRemove; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) - bool bForceRemoval; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) - int ReturnValue; // (Parm, OutParm, ZeroConstructor, ReturnParm, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) - }; - - auto Params = /*(UFortKismetLibrary_K2_RemoveItemFromPlayer_Params*)*/Stack.Locals; - static auto PlayerControllerOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.K2_RemoveItemFromPlayer", "PlayerController"); static auto ItemDefinitionOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.K2_RemoveItemFromPlayer", "ItemDefinition"); static auto AmountToRemoveOffset = FindOffsetStruct("/Script/FortniteGame.FortKismetLibrary.K2_RemoveItemFromPlayer", "AmountToRemove"); - auto PlayerController = *(AFortPlayerController**)(__int64(Params) + PlayerControllerOffset); - auto ItemDefinition = *(UFortWorldItemDefinition**)(__int64(Params) + ItemDefinitionOffset); - auto AmountToRemove = *(int*)(__int64(Params) + AmountToRemoveOffset); + AFortPlayerController* PlayerController = nullptr; + UFortWorldItemDefinition* ItemDefinition = nullptr; + int AmountToRemove; + + Stack.Step(Stack.Object, &PlayerController); + Stack.Step(Stack.Object, &ItemDefinition); + Stack.Step(Stack.Object, &AmountToRemove); auto WorldInventory = PlayerController->GetWorldInventory(); if (!WorldInventory) - return; + return K2_RemoveItemFromPlayerOriginal(Context, Stack, Ret); auto ItemInstance = WorldInventory->FindItemInstance(ItemDefinition); if (!ItemInstance) - return; + return K2_RemoveItemFromPlayerOriginal(Context, Stack, Ret); bool bShouldUpdate = false; WorldInventory->RemoveItem(ItemInstance->GetItemEntry()->GetItemGuid(), &bShouldUpdate, AmountToRemove); @@ -149,22 +159,51 @@ void UFortKismetLibrary::K2_RemoveItemFromPlayerHook(UObject* Context, FFrame& S return K2_RemoveItemFromPlayerOriginal(Context, Stack, Ret); } +void UFortKismetLibrary::K2_RemoveItemFromPlayerByGuidHook(UObject* Context, FFrame& Stack, void* Ret) +{ + AFortPlayerController* PlayerController = nullptr; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + FGuid ItemGuid; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + int AmountToRemove; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + bool bForceRemoval; + + Stack.Step(Stack.Object, &PlayerController); + Stack.Step(Stack.Object, &ItemGuid); + Stack.Step(Stack.Object, &AmountToRemove); + Stack.Step(Stack.Object, &bForceRemoval); + + if (!PlayerController) + return; + + auto WorldInventory = PlayerController->GetWorldInventory(); + + if (!WorldInventory) + return K2_RemoveItemFromPlayerByGuidOriginal(Context, Stack, Ret); + + bool bShouldUpdate = false; + WorldInventory->RemoveItem(ItemGuid, &bShouldUpdate, AmountToRemove); + + if (bShouldUpdate) + WorldInventory->Update(); + + return K2_RemoveItemFromPlayerByGuidOriginal(Context, Stack, Ret); +} + void UFortKismetLibrary::K2_GiveItemToPlayerHook(UObject* Context, FFrame& Stack, void* Ret) { - struct UFortKismetLibrary_K2_GiveItemToPlayer_Params - { - AFortPlayerController* PlayerController; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) - UFortWorldItemDefinition* ItemDefinition; // (ConstParm, Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) - int NumberToGive; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) - bool bNotifyPlayer; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) - }; + auto Params = Stack.Locals; - auto Params = (UFortKismetLibrary_K2_GiveItemToPlayer_Params*)Stack.Locals; + AFortPlayerController* PlayerController = nullptr; + UFortWorldItemDefinition* ItemDefinition = nullptr; + int NumberToGive; + bool bNotifyPlayer; - auto PlayerController = Params->PlayerController; - auto ItemDefinition = Params->ItemDefinition; - auto NumberToGive = Params->NumberToGive; - auto bNotifyPlayer = Params->bNotifyPlayer; + Stack.Step(Stack.Object, &PlayerController); + Stack.Step(Stack.Object, &ItemDefinition); + Stack.Step(Stack.Object, &NumberToGive); + Stack.Step(Stack.Object, &bNotifyPlayer); + + if (!PlayerController || !ItemDefinition) + return K2_GiveItemToPlayerOriginal(Context, Stack, Ret); bool bShouldUpdate = false; PlayerController->GetWorldInventory()->AddItem(ItemDefinition, &bShouldUpdate, NumberToGive, -1, bNotifyPlayer); @@ -175,6 +214,75 @@ void UFortKismetLibrary::K2_GiveItemToPlayerHook(UObject* Context, FFrame& Stack return K2_GiveItemToPlayerOriginal(Context, Stack, Ret); } +void UFortKismetLibrary::K2_RemoveFortItemFromPlayerHook(UObject* Context, FFrame& Stack, void* Ret) +{ + AFortPlayerController* PlayerController = nullptr; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + UFortItem* Item = nullptr; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + int AmountToRemove; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + bool bForceRemoval; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + + Stack.Step(Stack.Object, &PlayerController); + Stack.Step(Stack.Object, &Item); + Stack.Step(Stack.Object, &AmountToRemove); + Stack.Step(Stack.Object, &bForceRemoval); + + if (!PlayerController) + return; + + auto WorldInventory = PlayerController->GetWorldInventory(); + + if (!WorldInventory) + return K2_RemoveFortItemFromPlayerOriginal(Context, Stack, Ret); + + bool bShouldUpdate = false; + WorldInventory->RemoveItem(Item->GetItemEntry()->GetItemGuid(), &bShouldUpdate, AmountToRemove); + + if (bShouldUpdate) + WorldInventory->Update(); + + return K2_RemoveFortItemFromPlayerOriginal(Context, Stack, Ret); +} + +AFortPickup* UFortKismetLibrary::K2_SpawnPickupInWorldHook(UObject* Context, FFrame& Stack, AFortPickup** Ret) +{ + UObject* WorldContextObject; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + UFortWorldItemDefinition* ItemDefinition; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + int NumberToSpawn; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + FVector Position; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + FVector Direction; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + int OverrideMaxStackCount; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + bool bToss; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + bool bRandomRotation; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + bool bBlockedFromAutoPickup; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + int PickupInstigatorHandle; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + EFortPickupSourceTypeFlag SourceType; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + EFortPickupSpawnSource Source; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + AFortPlayerController* OptionalOwnerPC; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + bool bPickupOnlyRelevantToOwner; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + + Stack.Step(Stack.Object, &WorldContextObject); + Stack.Step(Stack.Object, &ItemDefinition); + Stack.Step(Stack.Object, &NumberToSpawn); + Stack.Step(Stack.Object, &Position); + Stack.Step(Stack.Object, &Direction); + Stack.Step(Stack.Object, &OverrideMaxStackCount); + Stack.Step(Stack.Object, &bToss); + Stack.Step(Stack.Object, &bRandomRotation); + Stack.Step(Stack.Object, &bBlockedFromAutoPickup); + Stack.Step(Stack.Object, &PickupInstigatorHandle); + Stack.Step(Stack.Object, &SourceType); + Stack.Step(Stack.Object, &Source); + Stack.Step(Stack.Object, &OptionalOwnerPC); + Stack.Step(Stack.Object, &bPickupOnlyRelevantToOwner); + + auto aa = AFortPickup::SpawnPickup(ItemDefinition, Position, NumberToSpawn, SourceType, Source); + + K2_SpawnPickupInWorldOriginal(Context, Stack, Ret); + + *Ret = aa; + return *Ret; +} + UClass* UFortKismetLibrary::StaticClass() { static auto ptr = FindObject(L"/Script/FortniteGame.FortKismetLibrary"); diff --git a/Project Reboot 3.0/FortKismetLibrary.h b/Project Reboot 3.0/FortKismetLibrary.h index 9d16468..7129c43 100644 --- a/Project Reboot 3.0/FortKismetLibrary.h +++ b/Project Reboot 3.0/FortKismetLibrary.h @@ -5,6 +5,7 @@ #include "FortResourceItemDefinition.h" #include "FortPlayerController.h" #include "BuildingSMActor.h" +#include "FortPickup.h" class UFortKismetLibrary : public UObject { @@ -13,14 +14,20 @@ public: static inline void (*K2_GiveItemToPlayerOriginal)(UObject* Context, FFrame& Stack, void* Ret); static inline void (*K2_RemoveItemFromPlayerOriginal)(UObject* Context, FFrame& Stack, void* Ret); + static inline void (*K2_RemoveItemFromPlayerByGuidOriginal)(UObject* Context, FFrame& Stack, void* Ret); static inline void (*GiveItemToInventoryOwnerOriginal)(UObject* Context, FFrame& Stack, void* Ret); + static inline void (*K2_RemoveFortItemFromPlayerOriginal)(UObject* Context, FFrame& Stack, void* Ret); + static inline AFortPickup* (*K2_SpawnPickupInWorldOriginal)(UObject* Context, FFrame& Stack, AFortPickup** Ret); static UFortResourceItemDefinition* K2_GetResourceItemDefinition(EFortResourceType ResourceType); static void ApplyCharacterCosmetics(UObject* WorldContextObject, const TArray& CharacterParts, UObject* PlayerState, bool* bSuccess); static void GiveItemToInventoryOwnerHook(UObject* Context, FFrame& Stack, void* Ret); static void K2_RemoveItemFromPlayerHook(UObject* Context, FFrame& Stack, void* Ret); + static void K2_RemoveItemFromPlayerByGuidHook(UObject* Context, FFrame& Stack, void* Ret); static void K2_GiveItemToPlayerHook(UObject* Context, FFrame& Stack, void* Ret); + static void K2_RemoveFortItemFromPlayerHook(UObject* Context, FFrame& Stack, void* Ret); + static AFortPickup* K2_SpawnPickupInWorldHook(UObject* Context, FFrame& Stack, AFortPickup** Ret); static UClass* StaticClass(); }; \ No newline at end of file diff --git a/Project Reboot 3.0/FortPickup.cpp b/Project Reboot 3.0/FortPickup.cpp index 340ec0a..31c6944 100644 --- a/Project Reboot 3.0/FortPickup.cpp +++ b/Project Reboot 3.0/FortPickup.cpp @@ -32,9 +32,9 @@ AFortPickup* AFortPickup::SpawnPickup(UFortItemDefinition* ItemDef, FVector Loca PrimaryPickupItemEntry->GetItemDefinition() = ItemDef; PrimaryPickupItemEntry->GetLoadedAmmo() = LoadedAmmo; - static auto OptionalOwnerIDOffset = Pickup->GetOffset("OptionalOwnerID"); - Pickup->Get(OptionalOwnerIDOffset) = PlayerState ? PlayerState->GetWorldPlayerId() : -1; - // Pickup->OptionalOwnerID = Pawn ? PlayerState->WorldPlayerId : -1; + // static auto OptionalOwnerIDOffset = Pickup->GetOffset("OptionalOwnerID"); + // Pickup->Get(OptionalOwnerIDOffset) = PlayerState ? PlayerState->GetWorldPlayerId() : -1; + Pickup->Get(PawnWhoDroppedPickupOffset) = Pawn; bool bToss = true; diff --git a/Project Reboot 3.0/FortPlayerControllerAthena.cpp b/Project Reboot 3.0/FortPlayerControllerAthena.cpp index 74b8697..8b9fe2c 100644 --- a/Project Reboot 3.0/FortPlayerControllerAthena.cpp +++ b/Project Reboot 3.0/FortPlayerControllerAthena.cpp @@ -3,6 +3,7 @@ #include "FortKismetLibrary.h" #include "SoftObjectPtr.h" +#include "globals.h" void ApplyCID(AFortPlayerPawn* Pawn, UObject* CID) { @@ -55,6 +56,9 @@ void AFortPlayerControllerAthena::ServerAcknowledgePossessionHook(APlayerControl static auto AcknowledgedPawnOffset = Controller->GetOffset("AcknowledgedPawn"); Controller->Get(AcknowledgedPawnOffset) = Pawn; + if (Globals::bNoMCP) + return; + auto ControllerAsFort = Cast(Controller); auto PawnAsFort = Cast(Pawn); auto PlayerStateAsFort = Cast(Pawn->GetPlayerState()); diff --git a/Project Reboot 3.0/GameModeBase.cpp b/Project Reboot 3.0/GameModeBase.cpp index 4c33821..f46239a 100644 --- a/Project Reboot 3.0/GameModeBase.cpp +++ b/Project Reboot 3.0/GameModeBase.cpp @@ -51,6 +51,7 @@ APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AControll WorldInventory->AddItem(WoodItemData, nullptr, 100); WorldInventory->AddItem(DamageTrap, nullptr); // WorldInventory->AddItem(FindObject(L"/ParallelGameplay/Items/WestSausage/WID_WestSausage_Parallel.WID_WestSausage_Parallel"), nullptr, 1, 1000); + WorldInventory->AddItem(FindObject(L"/Game/Athena/Items/Consumables/HappyGhost/WID_Athena_HappyGhost.WID_Athena_HappyGhost"), nullptr); WorldInventory->Update(true); } diff --git a/Project Reboot 3.0/NetSerialization.h b/Project Reboot 3.0/NetSerialization.h index 6aac683..cc1fbea 100644 --- a/Project Reboot 3.0/NetSerialization.h +++ b/Project Reboot 3.0/NetSerialization.h @@ -110,8 +110,8 @@ struct FFastArraySerializer void MarkArrayDirty() { - // ((FFastArraySerializer2*)this)->MarkArrayDirty(); - // return; + ((FFastArraySerializer2*)this)->MarkArrayDirty(); + return; // ItemMap.Reset(); // This allows to clients to add predictive elements to arrays without affecting replication. GetArrayReplicationKey()++; diff --git a/Project Reboot 3.0/Stack.h b/Project Reboot 3.0/Stack.h index d3a13c9..032a8a0 100644 --- a/Project Reboot 3.0/Stack.h +++ b/Project Reboot 3.0/Stack.h @@ -20,8 +20,8 @@ public: void Step(UObject* Context, RESULT_DECL) { - static void (*StepOriginal)(UObject* Context, RESULT_DECL) = decltype(StepOriginal)(Addresses::FrameStep); - StepOriginal(Context, RESULT_PARAM); + static void (*StepOriginal)(__int64 frame, UObject* Context, RESULT_DECL) = decltype(StepOriginal)(Addresses::FrameStep); + StepOriginal(__int64(this), Context, RESULT_PARAM); // int32 B = *Code++; // (GNatives[B])(Context, *this, RESULT_PARAM); diff --git a/Project Reboot 3.0/commands.h b/Project Reboot 3.0/commands.h index eb220e0..1f389c3 100644 --- a/Project Reboot 3.0/commands.h +++ b/Project Reboot 3.0/commands.h @@ -164,7 +164,7 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg) { } - LOG_INFO(LogDev, "weaponName: {}", weaponName); + // LOG_INFO(LogDev, "weaponName: {}", weaponName); auto WID = Cast(FindObject(weaponName, nullptr, ANY_PACKAGE)); @@ -182,5 +182,32 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg) SendMessageToConsole(PlayerController, L"Granted item!"); } + else if (Command == "bugitgo") + { + if (Arguments.size() <= 3) + { + SendMessageToConsole(PlayerController, L"Please provide X, Y, and Z!\n"); + return; + } + + float X{}, Y{}, Z{}; + + try { X = std::stof(Arguments[1]); } + catch (...) {} + try { Y = std::stof(Arguments[2]); } + catch (...) {} + try { Z = std::stof(Arguments[3]); } + catch (...) {} + + auto Pawn = Cast(ReceivingController->GetPawn()); + + if (!Pawn) + { + SendMessageToConsole(PlayerController, L"No pawn to teleport!"); + return; + } + + Pawn->TeleportTo(FVector(X, Y, Z), Pawn->GetActorRotation()); + } } } \ No newline at end of file diff --git a/Project Reboot 3.0/dllmain.cpp b/Project Reboot 3.0/dllmain.cpp index 41d40b4..7416340 100644 --- a/Project Reboot 3.0/dllmain.cpp +++ b/Project Reboot 3.0/dllmain.cpp @@ -199,13 +199,20 @@ DWORD WINAPI Main(LPVOID) AFortPlayerPawn::ServerSendZiplineStateHook, nullptr, false); // if (false) + if (Addresses::FrameStep) { - // Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject(L"Script/FortniteGame.FortKismetLibrary.K2_GiveItemToPlayer"), - // UFortKismetLibrary::K2_GiveItemToPlayerHook, (PVOID*)&UFortKismetLibrary::K2_GiveItemToPlayerOriginal, false, true); + Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject(L"Script/FortniteGame.FortKismetLibrary.K2_GiveItemToPlayer"), + UFortKismetLibrary::K2_GiveItemToPlayerHook, (PVOID*)&UFortKismetLibrary::K2_GiveItemToPlayerOriginal, false, true); Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject(L"/Script/FortniteGame.FortKismetLibrary.GiveItemToInventoryOwner"), UFortKismetLibrary::GiveItemToInventoryOwnerHook, (PVOID*)&UFortKismetLibrary::GiveItemToInventoryOwnerOriginal, false, true); - // Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject(L"/Script/FortniteGame.FortKismetLibrary.K2_RemoveItemFromPlayer"), - // UFortKismetLibrary::K2_RemoveItemFromPlayerHook, (PVOID*)&UFortKismetLibrary::K2_RemoveItemFromPlayerOriginal, false, true); + Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject(L"/Script/FortniteGame.FortKismetLibrary.K2_RemoveItemFromPlayerByGuid"), + UFortKismetLibrary::K2_RemoveItemFromPlayerByGuidHook, (PVOID*)&UFortKismetLibrary::K2_RemoveItemFromPlayerByGuidOriginal, false, true); + Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject(L"/Script/FortniteGame.FortKismetLibrary.K2_RemoveItemFromPlayer"), + UFortKismetLibrary::K2_RemoveItemFromPlayerHook, (PVOID*)&UFortKismetLibrary::K2_RemoveItemFromPlayerOriginal, false, true); + Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject(L"/Script/FortniteGame.FortKismetLibrary.K2_RemoveFortItemFromPlayer"), + UFortKismetLibrary::K2_RemoveFortItemFromPlayerHook, (PVOID*)&UFortKismetLibrary::K2_RemoveFortItemFromPlayerOriginal, false, true); + Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject(L"/Script/FortniteGame.FortKismetLibrary.K2_SpawnPickupInWorld"), + UFortKismetLibrary::K2_SpawnPickupInWorldHook, (PVOID*)&UFortKismetLibrary::K2_SpawnPickupInWorldOriginal, false, true); } static auto ServerHandlePickupInfoFn = FindObject("/Script/FortniteGame.FortPlayerPawn.ServerHandlePickupInfo"); @@ -254,7 +261,10 @@ DWORD WINAPI Main(LPVOID) Hooking::MinHook::Hook((PVOID)Addresses::GetPlayerViewpoint, (PVOID)AFortPlayerControllerAthena::GetPlayerViewPointHook, (PVOID*)&AFortPlayerControllerAthena::GetPlayerViewPointOriginal); Hooking::MinHook::Hook((PVOID)Addresses::TickFlush, (PVOID)UNetDriver::TickFlushHook, (PVOID*)&UNetDriver::TickFlushOriginal); - // Hooking::MinHook::Hook((PVOID)Addresses::OnDamageServer, (PVOID)ABuildingActor::OnDamageServerHook, (PVOID*)&ABuildingActor::OnDamageServerOriginal); + + if (Engine_Version < 427) + Hooking::MinHook::Hook((PVOID)Addresses::OnDamageServer, (PVOID)ABuildingActor::OnDamageServerHook, (PVOID*)&ABuildingActor::OnDamageServerOriginal); + // Hooking::MinHook::Hook((PVOID)Addresses::CollectGarbage, (PVOID)CollectGarbageHook, nullptr); Hooking::MinHook::Hook((PVOID)Addresses::PickTeam, (PVOID)AFortGameModeAthena::Athena_PickTeamHook); // Hooking::MinHook::Hook((PVOID)Addresses::SetZoneToIndex, (PVOID)AFortGameModeAthena::SetZoneToIndexHook, (PVOID*)&AFortGameModeAthena::SetZoneToIndexOriginal); diff --git a/Project Reboot 3.0/finder.h b/Project Reboot 3.0/finder.h index 6bebd6c..aa5d54b 100644 --- a/Project Reboot 3.0/finder.h +++ b/Project Reboot 3.0/finder.h @@ -734,5 +734,5 @@ static inline uint64 FindReplaceBuildingActor() return 0; } - return FindBytes(StringRef, (Engine_Version == 420 ? std::vector{ 0x48, 0x8B, 0xC4 } : std::vector{ 0x4C, 0x8B }), 1000, 0, true); + return FindBytes(StringRef, (Engine_Version == 420 || Engine_Version == 421 ? std::vector{ 0x48, 0x8B, 0xC4 } : std::vector{ 0x4C, 0x8B }), 1000, 0, true); } \ No newline at end of file