i hope maxs pr works

sidegrading and upgrading on upgradebenches
This commit is contained in:
Gray
2024-01-14 17:43:15 -05:00
committed by GitHub
2 changed files with 221 additions and 73 deletions

View File

@@ -429,6 +429,9 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame*
static auto ReceivingActorOffset = FindOffsetStruct(StructName, "ReceivingActor"); static auto ReceivingActorOffset = FindOffsetStruct(StructName, "ReceivingActor");
auto ReceivingActor = *(AActor**)(__int64(Params) + ReceivingActorOffset); auto ReceivingActor = *(AActor**)(__int64(Params) + ReceivingActorOffset);
static auto InteractionBeingAttemptedOffset = FindOffsetStruct(StructName, "InteractionBeingAttempted");
auto InteractionBeingAttempted = *(EInteractionBeingAttempted*)(__int64(Params) + InteractionBeingAttemptedOffset);
// LOG_INFO(LogInteraction, "ReceivingActor: {}", __int64(ReceivingActor)); // LOG_INFO(LogInteraction, "ReceivingActor: {}", __int64(ReceivingActor));
if (!ReceivingActor) if (!ReceivingActor)
@@ -549,83 +552,179 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame*
} }
else if (ReceivingActor->IsA(BuildingItemCollectorActorClass)) else if (ReceivingActor->IsA(BuildingItemCollectorActorClass))
{ {
auto WorldInventory = PlayerController->GetWorldInventory(); if (Engine_Version >= 424 && Fortnite_Version < 15 && ReceivingActor->GetFullName().contains("Wumba"))
if (!WorldInventory)
return ServerAttemptInteractOriginal(Context, Stack, Ret);
auto ItemCollector = ReceivingActor;
static auto ActiveInputItemOffset = ItemCollector->GetOffset("ActiveInputItem");
auto CurrentMaterial = ItemCollector->Get<UFortWorldItemDefinition*>(ActiveInputItemOffset); // InteractType->OptionalObjectData
if (!CurrentMaterial)
return ServerAttemptInteractOriginal(Context, Stack, Ret);
int Index = 0;
// this is a weird way of getting the current item collection we are on.
static auto StoneItemData = FindObject<UFortResourceItemDefinition>(L"/Game/Items/ResourcePickups/StoneItemData.StoneItemData");
static auto MetalItemData = FindObject<UFortResourceItemDefinition>(L"/Game/Items/ResourcePickups/MetalItemData.MetalItemData");
if (CurrentMaterial == StoneItemData)
Index = 1;
else if (CurrentMaterial == MetalItemData)
Index = 2;
static auto ItemCollectionsOffset = ItemCollector->GetOffset("ItemCollections");
auto& ItemCollections = ItemCollector->Get<TArray<FCollectorUnitInfo>>(ItemCollectionsOffset);
auto ItemCollection = ItemCollections.AtPtr(Index, FCollectorUnitInfo::GetPropertiesSize());
if (Fortnite_Version < 8.10)
{ {
auto Cost = ItemCollection->GetInputCount()->GetValue(); bool bIsSidegrading = InteractionBeingAttempted == EInteractionBeingAttempted::SecondInteraction ? true : false;
if (!CurrentMaterial) LOG_INFO(LogDev, "bIsSidegrading: {}", (bool)bIsSidegrading);
return ServerAttemptInteractOriginal(Context, Stack, Ret);
struct FWeaponUpgradeItemRow
auto MatInstance = WorldInventory->FindItemInstance(CurrentMaterial); {
void* FTableRowBaseInheritance;
if (!MatInstance) UFortWeaponItemDefinition* CurrentWeaponDef; // 0x8(0x8)(Edit, ZeroConstructor, DisableEditOnInstance, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
return ServerAttemptInteractOriginal(Context, Stack, Ret); UFortWeaponItemDefinition* UpgradedWeaponDef; // 0x10(0x8)(Edit, ZeroConstructor, DisableEditOnInstance, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
EFortWeaponUpgradeCosts WoodCost; // 0x18(0x1)(Edit, ZeroConstructor, DisableEditOnInstance, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
EFortWeaponUpgradeCosts MetalCost; // 0x19(0x1)(Edit, ZeroConstructor, DisableEditOnInstance, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
EFortWeaponUpgradeCosts BrickCost; // 0x1A(0x1)(Edit, ZeroConstructor, DisableEditOnInstance, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
EFortWeaponUpgradeDirection Direction;
};
static auto WumbaDataTable = FindObject<UDataTable>("/Game/Items/Datatables/AthenaWumbaData.AthenaWumbaData");
static auto LootPackagesRowMap = WumbaDataTable->GetRowMap();
auto Pawn = Cast<AFortPawn>(PlayerController->GetPawn());
auto CurrentHeldWeapon = Pawn->GetCurrentWeapon();
auto CurrentHeldWeaponDef = CurrentHeldWeapon->GetWeaponData();
auto Direction = bIsSidegrading ? EFortWeaponUpgradeDirection::Horizontal : EFortWeaponUpgradeDirection::Vertical;
LOG_INFO(LogDev, "Direction: {}", (int)Direction);
FWeaponUpgradeItemRow* FoundRow = nullptr;
for (int i = 0; i < LootPackagesRowMap.Pairs.Elements.Data.Num(); i++)
{
auto& Pair = LootPackagesRowMap.Pairs.Elements.Data.at(i).ElementData.Value;
auto First = Pair.First;
auto Row = (FWeaponUpgradeItemRow*)Pair.Second;
if (Row->CurrentWeaponDef == CurrentHeldWeaponDef && Row->Direction == Direction)
{
FoundRow = Row;
break;
}
}
if (!FoundRow)
{
LOG_WARN(LogGame, "Failed to find row!");
return;
}
auto NewDefinition = FoundRow->UpgradedWeaponDef;
LOG_INFO(LogDev, "UpgradedWeaponDef: {}", NewDefinition->GetFullName());
int WoodCost = (int)FoundRow->WoodCost * 50;
int StoneCost = (int)FoundRow->BrickCost * 50 - 400;
int MetalCost = (int)FoundRow->MetalCost * 50 - 200;
if (bIsSidegrading)
{
WoodCost = 20;
StoneCost = 20;
MetalCost = 20;
}
static auto WoodItemData = FindObject<UFortItemDefinition>("/Game/Items/ResourcePickups/WoodItemData.WoodItemData");
static auto StoneItemData = FindObject<UFortItemDefinition>("/Game/Items/ResourcePickups/StoneItemData.StoneItemData");
static auto MetalItemData = FindObject<UFortItemDefinition>("/Game/Items/ResourcePickups/MetalItemData.MetalItemData");
auto WorldInventory = PlayerController->GetWorldInventory();
auto WoodInstance = WorldInventory->FindItemInstance(WoodItemData);
auto WoodCount = WoodInstance->GetItemEntry()->GetCount();
auto StoneInstance = WorldInventory->FindItemInstance(StoneItemData);
auto StoneCount = StoneInstance->GetItemEntry()->GetCount();
auto MetalInstance = WorldInventory->FindItemInstance(MetalItemData);
auto MetalCount = MetalInstance->GetItemEntry()->GetCount();
bool bShouldUpdate = false; bool bShouldUpdate = false;
if (!WorldInventory->RemoveItem(MatInstance->GetItemEntry()->GetItemGuid(), &bShouldUpdate, Cost, true)) WorldInventory->RemoveItem(WoodInstance->GetItemEntry()->GetItemGuid(), &bShouldUpdate, WoodCost);
return ServerAttemptInteractOriginal(Context, Stack, Ret); WorldInventory->RemoveItem(StoneInstance->GetItemEntry()->GetItemGuid(), &bShouldUpdate, StoneCost);
WorldInventory->RemoveItem(MetalInstance->GetItemEntry()->GetItemGuid(), &bShouldUpdate, MetalCost);
WorldInventory->RemoveItem(CurrentHeldWeapon->GetItemEntryGuid(), &bShouldUpdate, 1, true);
WorldInventory->AddItem(NewDefinition, &bShouldUpdate);
if (bShouldUpdate) if (bShouldUpdate)
WorldInventory->Update(); WorldInventory->Update();
} }
else
for (int z = 0; z < ItemCollection->GetOutputItemEntry()->Num(); z++)
{ {
auto Entry = ItemCollection->GetOutputItemEntry()->AtPtr(z, FFortItemEntry::GetStructSize()); auto WorldInventory = PlayerController->GetWorldInventory();
PickupCreateData CreateData; if (!WorldInventory)
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(Entry->GetItemDefinition(), Entry->GetCount(), Entry->GetLoadedAmmo(), MAX_DURABILITY, Entry->GetLevel()); return ServerAttemptInteractOriginal(Context, Stack, Ret);
CreateData.SpawnLocation = LocationToSpawnLoot;
CreateData.PawnOwner = PlayerController->GetMyFortPawn(); // hmm auto ItemCollector = ReceivingActor;
CreateData.bShouldFreeItemEntryWhenDeconstructed = true; static auto ActiveInputItemOffset = ItemCollector->GetOffset("ActiveInputItem");
auto CurrentMaterial = ItemCollector->Get<UFortWorldItemDefinition*>(ActiveInputItemOffset); // InteractType->OptionalObjectData
AFortPickup::SpawnPickup(CreateData);
} if (!CurrentMaterial)
return ServerAttemptInteractOriginal(Context, Stack, Ret);
static auto bCurrentInteractionSuccessOffset = ItemCollector->GetOffset("bCurrentInteractionSuccess", false);
int Index = 0;
if (bCurrentInteractionSuccessOffset != -1)
{ // this is a weird way of getting the current item collection we are on.
static auto bCurrentInteractionSuccessFieldMask = GetFieldMask(ItemCollector->GetProperty("bCurrentInteractionSuccess"));
ItemCollector->SetBitfieldValue(bCurrentInteractionSuccessOffset, bCurrentInteractionSuccessFieldMask, true); // idek if this is needed static auto StoneItemData = FindObject<UFortResourceItemDefinition>(L"/Game/Items/ResourcePickups/StoneItemData.StoneItemData");
} static auto MetalItemData = FindObject<UFortResourceItemDefinition>(L"/Game/Items/ResourcePickups/MetalItemData.MetalItemData");
static auto DoVendDeath = FindObject<UFunction>(L"/Game/Athena/Items/Gameplay/VendingMachine/B_Athena_VendingMachine.B_Athena_VendingMachine_C.DoVendDeath"); if (CurrentMaterial == StoneItemData)
Index = 1;
if (DoVendDeath) else if (CurrentMaterial == MetalItemData)
{ Index = 2;
ItemCollector->ProcessEvent(DoVendDeath);
ItemCollector->K2_DestroyActor(); static auto ItemCollectionsOffset = ItemCollector->GetOffset("ItemCollections");
auto& ItemCollections = ItemCollector->Get<TArray<FCollectorUnitInfo>>(ItemCollectionsOffset);
auto ItemCollection = ItemCollections.AtPtr(Index, FCollectorUnitInfo::GetPropertiesSize());
if (Fortnite_Version < 8.10)
{
auto Cost = ItemCollection->GetInputCount()->GetValue();
if (!CurrentMaterial)
return ServerAttemptInteractOriginal(Context, Stack, Ret);
auto MatInstance = WorldInventory->FindItemInstance(CurrentMaterial);
if (!MatInstance)
return ServerAttemptInteractOriginal(Context, Stack, Ret);
bool bShouldUpdate = false;
if (!WorldInventory->RemoveItem(MatInstance->GetItemEntry()->GetItemGuid(), &bShouldUpdate, Cost, true))
return ServerAttemptInteractOriginal(Context, Stack, Ret);
if (bShouldUpdate)
WorldInventory->Update();
}
for (int z = 0; z < ItemCollection->GetOutputItemEntry()->Num(); z++)
{
auto Entry = ItemCollection->GetOutputItemEntry()->AtPtr(z, FFortItemEntry::GetStructSize());
PickupCreateData CreateData;
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(Entry->GetItemDefinition(), Entry->GetCount(), Entry->GetLoadedAmmo(), MAX_DURABILITY, Entry->GetLevel());
CreateData.SpawnLocation = LocationToSpawnLoot;
CreateData.PawnOwner = PlayerController->GetMyFortPawn(); // hmm
CreateData.bShouldFreeItemEntryWhenDeconstructed = true;
AFortPickup::SpawnPickup(CreateData);
}
static auto bCurrentInteractionSuccessOffset = ItemCollector->GetOffset("bCurrentInteractionSuccess", false);
if (bCurrentInteractionSuccessOffset != -1)
{
static auto bCurrentInteractionSuccessFieldMask = GetFieldMask(ItemCollector->GetProperty("bCurrentInteractionSuccess"));
ItemCollector->SetBitfieldValue(bCurrentInteractionSuccessOffset, bCurrentInteractionSuccessFieldMask, true); // idek if this is needed
}
static auto DoVendDeath = FindObject<UFunction>(L"/Game/Athena/Items/Gameplay/VendingMachine/B_Athena_VendingMachine.B_Athena_VendingMachine_C.DoVendDeath");
if (DoVendDeath)
{
ItemCollector->ProcessEvent(DoVendDeath);
ItemCollector->K2_DestroyActor();
}
} }
} }
@@ -1692,4 +1791,4 @@ void AFortPlayerController::ServerEndEditingBuildingActorHook(AFortPlayerControl
EditTool->GetEditActor() = nullptr; EditTool->GetEditActor() = nullptr;
EditTool->OnRep_EditActor(); EditTool->OnRep_EditActor();
} }
} }

View File

@@ -40,6 +40,55 @@ struct FFortAthenaLoadout
} }
}; };
enum class EFortWeaponUpgradeCosts : uint8_t
{
NotSet = 0,
WoodUncommon = 1,
WoodRare = 2,
WoodVeryRare = 3,
WoodSuperRare = 4,
MetalUncommon = 5,
MetalRare = 6,
MetalVeryRare = 7,
MetalSuperRare = 8,
BrickUncommon = 9,
BrickRare = 10,
BrickVeryRare = 11,
BrickSuperRare = 12,
HorizontalWoodCommon = 13,
HorizontalWoodUncommon = 14,
HorizontalWoodRare = 15,
HorizontalWoodVeryRare = 16,
HorizontalWoodSuperRare = 17,
HorizontalMetalCommon = 18,
HorizontalMetalUncommon = 19,
HorizontalMetalRare = 20,
HorizontalMetalVeryRare = 21,
HorizontalMetalSuperRare = 22,
HorizontalBrickCommon = 23,
HorizontalBrickUncommon = 24,
HorizontalBrickRare = 25,
HorizontalBrickVeryRare = 26,
HorizontalBrickSuperRare = 27,
EFortWeaponUpgradeCosts_MAX = 28,
};
enum class EFortWeaponUpgradeDirection : uint8
{
NotSet = 0,
Vertical = 1,
Horizontal = 2,
EFortWeaponUpgradeDirection_MAX = 3,
};
enum class EInteractionBeingAttempted : uint8
{
FirstInteraction = 0,
SecondInteraction = 1,
AllInteraction = 2,
EInteractionBeingAttempted_MAX = 3,
};
class AFortPlayerController : public APlayerController class AFortPlayerController : public APlayerController
{ {
public: public:
@@ -169,4 +218,4 @@ public:
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortPlayerController"); static auto Class = FindObject<UClass>("/Script/FortniteGame.FortPlayerController");
return Class; return Class;
} }
}; };