more accurate harvesting rates

This commit is contained in:
Milxnor
2023-06-17 17:21:06 -04:00
parent e79445d22e
commit b944b40b36
8 changed files with 101 additions and 29 deletions

View File

@@ -19,10 +19,34 @@ void ABuildingActor::OnDamageServerHook(ABuildingActor* BuildingActor, float Dam
auto BuildingSMActor = Cast<ABuildingSMActor>(BuildingActor); auto BuildingSMActor = Cast<ABuildingSMActor>(BuildingActor);
auto PlayerController = Cast<AFortPlayerControllerAthena>(InstigatedBy); auto PlayerController = Cast<AFortPlayerControllerAthena>(InstigatedBy);
auto Pawn = PlayerController ? PlayerController->GetMyFortPawn() : nullptr; // auto Pawn = PlayerController ? PlayerController->GetMyFortPawn() : nullptr;
auto Weapon = Cast<AFortWeapon>(DamageCauser); auto Weapon = Cast<AFortWeapon>(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<float>(LastDamageAmountOffset);
const float PreviousLastDamageHit = BuildingSMActor->Get<float>(LastDamageHitOffset);
const float CurrentBuildingHealth = BuildingActor->GetHealth();
BuildingSMActor->Get<float>(LastDamageAmountOffset) = Damage;
BuildingSMActor->Get<float>(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); return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
auto WeaponData = Cast<UFortWeaponMeleeItemDefinition>(Weapon->GetWeaponData()); auto WeaponData = Cast<UFortWeaponMeleeItemDefinition>(Weapon->GetWeaponData());
@@ -30,15 +54,16 @@ void ABuildingActor::OnDamageServerHook(ABuildingActor* BuildingActor, float Dam
if (!WeaponData) if (!WeaponData)
return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext); 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()); 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"); static auto BuildingResourceAmountOverrideOffset = BuildingSMActor->GetOffset("BuildingResourceAmountOverride");
auto& BuildingResourceAmountOverride = BuildingSMActor->Get<FCurveTableRowHandle>(BuildingResourceAmountOverrideOffset); auto& BuildingResourceAmountOverride = BuildingSMActor->Get<FCurveTableRowHandle>(BuildingResourceAmountOverrideOffset);
int ResourceCount = 0;
if (BuildingResourceAmountOverride.RowName.IsValid()) if (BuildingResourceAmountOverride.RowName.IsValid())
{ {
// auto AssetManager = Cast<UFortAssetManager>(GEngine->AssetManager); // auto AssetManager = Cast<UFortAssetManager>(GEngine->AssetManager);
@@ -48,7 +73,7 @@ void ABuildingActor::OnDamageServerHook(ABuildingActor* BuildingActor, float Dam
// LOG_INFO(LogDev, "Before1"); // LOG_INFO(LogDev, "Before1");
if (!CurveTable) if (!CurveTable)
CurveTable = FindObject<UCurveTable>("/Game/Athena/Balance/DataTables/AthenaResourceRates.AthenaResourceRates"); CurveTable = FindObject<UCurveTable>(L"/Game/Athena/Balance/DataTables/AthenaResourceRates.AthenaResourceRates");
{ {
// auto curveMap = ((UDataTable*)CurveTable)->GetRowMap(); // auto curveMap = ((UDataTable*)CurveTable)->GetRowMap();
@@ -59,31 +84,27 @@ void ABuildingActor::OnDamageServerHook(ABuildingActor* BuildingActor, float Dam
// LOG_INFO(LogDev, "Out: {}", Out); // 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 OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
// return OnDamageServer(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
} }
bool bIsWeakspot = Damage == 100.0f; bool bIsWeakspot = Damage == 100.0f;
PlayerController->ClientReportDamagedResourceBuilding(BuildingSMActor, BuildingSMActor->GetResourceType(), ResourceCount, false, bIsWeakspot); PlayerController->ClientReportDamagedResourceBuilding(BuildingSMActor, BuildingSMActor->GetResourceType(), ResourceCount, false, bIsWeakspot);
if (ResourceCount > 0) bool bShouldUpdate = false;
{ WorldInventory->AddItem(ItemDef, &bShouldUpdate, ResourceCount);
bool bShouldUpdate = false;
PlayerController->GetWorldInventory()->AddItem(ItemDef, &bShouldUpdate, ResourceCount);
if (bShouldUpdate) if (bShouldUpdate)
PlayerController->GetWorldInventory()->Update(); WorldInventory->Update();
}
return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext); return OnDamageServerOriginal(BuildingActor, Damage, DamageTags, Momentum, HitInfo, InstigatedBy, DamageCauser, EffectContext);
} }

View File

@@ -31,7 +31,7 @@ public:
void SilentDie() void SilentDie()
{ {
static auto SilentDieFn = FindObject<UFunction>("/Script/FortniteGame.BuildingActor.SilentDie"); static auto SilentDieFn = FindObject<UFunction>(L"/Script/FortniteGame.BuildingActor.SilentDie");
bool bPropagateSilentDeath = false; // idfk bool bPropagateSilentDeath = false; // idfk
this->ProcessEvent(SilentDieFn, &bPropagateSilentDeath); this->ProcessEvent(SilentDieFn, &bPropagateSilentDeath);
} }
@@ -39,7 +39,7 @@ public:
float GetMaxHealth() float GetMaxHealth()
{ {
float MaxHealth = 0; float MaxHealth = 0;
static auto fn = FindObject<UFunction>("/Script/FortniteGame.BuildingActor.GetMaxHealth"); static auto fn = FindObject<UFunction>(L"/Script/FortniteGame.BuildingActor.GetMaxHealth");
this->ProcessEvent(fn, &MaxHealth); this->ProcessEvent(fn, &MaxHealth);
return MaxHealth; return MaxHealth;
} }
@@ -47,14 +47,22 @@ public:
float GetHealthPercent() // aka GetHealth() / GetMaxHealth() float GetHealthPercent() // aka GetHealth() / GetMaxHealth()
{ {
float HealthPercent = 0; float HealthPercent = 0;
static auto fn = FindObject<UFunction>("/Script/FortniteGame.BuildingActor.GetHealthPercent"); static auto fn = FindObject<UFunction>(L"/Script/FortniteGame.BuildingActor.GetHealthPercent");
this->ProcessEvent(fn, &HealthPercent); this->ProcessEvent(fn, &HealthPercent);
return HealthPercent; return HealthPercent;
} }
float GetHealth()
{
float Health = 0;
static auto fn = FindObject<UFunction>("/Script/FortniteGame.BuildingActor.GetHealth");
this->ProcessEvent(fn, &Health);
return Health;
}
void SetTeam(unsigned char InTeam) void SetTeam(unsigned char InTeam)
{ {
static auto fn = nullptr; // FindObject<UFunction>("/Script/FortniteGame.BuildingActor.SetTeam"); static auto fn = nullptr; // FindObject<UFunction>(L"/Script/FortniteGame.BuildingActor.SetTeam");
if (!fn) if (!fn)
{ {

View File

@@ -8,6 +8,12 @@ void UCheatManager::Teleport()
this->ProcessEvent(TeleportFn); this->ProcessEvent(TeleportFn);
} }
void UCheatManager::DestroyTarget()
{
static auto DestroyTargetFn = FindObject<UFunction>("/Script/Engine.CheatManager.DestroyTarget");
this->ProcessEvent(DestroyTargetFn);
}
UClass* UCheatManager::StaticClass() UClass* UCheatManager::StaticClass()
{ {
static auto Class = FindObject<UClass>(L"/Script/Engine.CheatManager"); static auto Class = FindObject<UClass>(L"/Script/Engine.CheatManager");

View File

@@ -6,6 +6,7 @@ class UCheatManager : public UObject
{ {
public: public:
void Teleport(); void Teleport();
void DestroyTarget();
static UClass* StaticClass(); static UClass* StaticClass();
}; };

View File

@@ -12,6 +12,12 @@ struct UField : UObject
// void* pad; void* pad2; // void* pad; void* pad2;
}; };
struct UFieldPadding : UObject
{
UField* Next;
void* pad; void* pad2;
};
template <typename PropertyType = void> template <typename PropertyType = void>
static inline PropertyType* GetNext(void* Field) static inline PropertyType* GetNext(void* Field)
{ {
@@ -57,7 +63,7 @@ class UEnum : public UField
public: public:
int64 GetValue(const std::string& EnumMemberName) int64 GetValue(const std::string& EnumMemberName)
{ {
auto Names = (TArray<TPair<FName, __int64>>*)(__int64(this) + sizeof(UField) + sizeof(FString)); auto Names = (TArray<TPair<FName, int64>>*)(__int64(this) + sizeof(UField) + sizeof(FString));
for (int i = 0; i < Names->Num(); ++i) for (int i = 0; i < Names->Num(); ++i)
{ {
@@ -65,8 +71,13 @@ public:
auto& Name = Pair.Key(); auto& Name = Pair.Key();
auto Value = Pair.Value(); auto Value = Pair.Value();
if (Name.ComparisonIndex.Value && Name.ToString().contains(EnumMemberName)) if (Name.ComparisonIndex.Value)
return Value; {
auto nameStr = Name.ToString();
if (nameStr.contains(EnumMemberName))
return Value;
}
} }
return -1; return -1;

View File

@@ -47,7 +47,7 @@ namespace EFortPickupSpawnSource
{ {
static inline UEnum* GetEnum() static inline UEnum* GetEnum()
{ {
static auto Enum = FindObject<UEnum>("/Script/FortniteGame.EFortPickupSpawnSource"); static auto Enum = FindObject<UEnum>(L"/Script/FortniteGame.EFortPickupSpawnSource");
return Enum; return Enum;
} }

View File

@@ -994,7 +994,17 @@ void AFortPlayerController::ServerAttemptInventoryDropHook(AFortPlayerController
if (!ItemDefinition->ShouldIgnoreRespawningOnDrop() && (DropBehaviorOffset != -1 ? ItemDefinition->GetDropBehavior() != EWorldItemDropBehavior::DestroyOnDrop : true)) 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) if (!Pickup)
return; return;

View File

@@ -537,7 +537,7 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg)
return; return;
} }
static auto LaunchCharacterFn = FindObject<UFunction>("/Script/Engine.Character.LaunchCharacter"); static auto LaunchCharacterFn = FindObject<UFunction>(L"/Script/Engine.Character.LaunchCharacter");
struct struct
{ {
@@ -817,6 +817,20 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg)
CheatManager = nullptr; CheatManager = nullptr;
SendMessageToConsole(PlayerController, L"Teleported!"); 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") else if (Command == "bugitgo")
{ {
if (Arguments.size() <= 3) if (Arguments.size() <= 3)
@@ -865,6 +879,7 @@ cheat spawnpickup <ShortWID> - Spawns a pickup at specified player.
cheat teleport - Teleports to what the player is looking at. cheat teleport - Teleports to what the player is looking at.
cheat spawnbot <Amount=1> - Spawns a bot at the player (experimental). cheat spawnbot <Amount=1> - Spawns a bot at the player (experimental).
cheat setpickaxe <PickaxeID> - Set player's pickaxe. cheat setpickaxe <PickaxeID> - 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 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
)"; )";