mirror of
https://github.com/Milxnor/Project-Reboot-3.0.git
synced 2026-01-13 02:42:22 +01:00
more accurate harvesting rates
This commit is contained in:
@@ -19,26 +19,51 @@ 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());
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ class UCheatManager : public UObject
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void Teleport();
|
void Teleport();
|
||||||
|
void DestroyTarget();
|
||||||
|
|
||||||
static UClass* StaticClass();
|
static UClass* StaticClass();
|
||||||
};
|
};
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
)";
|
)";
|
||||||
|
|||||||
Reference in New Issue
Block a user