feat: Destroyable component debug info (#1849)

tested that the ui now shows server and client info together if configured to do so
This commit is contained in:
David Markowitz
2025-07-23 02:08:39 -07:00
committed by GitHub
parent ba964932b7
commit 24f4c9d413
5 changed files with 74 additions and 5 deletions

View File

@@ -2243,7 +2243,7 @@ bool Entity::MsgRequestServerObjectInfo(GameMessages::GameMsg& msg) {
} }
HandleMsg(info); HandleMsg(info);
auto* targetForReport = Game::entityManager->GetEntity(requestInfo.targetForReport); auto* client = Game::entityManager->GetEntity(requestInfo.clientId);
if (targetForReport) GameMessages::SendUIMessageServerToSingleClient("ToggleObjectDebugger", response, targetForReport->GetSystemAddress()); if (client) GameMessages::SendUIMessageServerToSingleClient("ToggleObjectDebugger", response, client->GetSystemAddress());
return true; return true;
} }

View File

@@ -56,10 +56,16 @@ public:
protected: protected:
void RegisterMsg(const MessageType::Game msgId, auto* self, const auto handler) { inline void RegisterMsg(const MessageType::Game msgId, auto* self, const auto handler) {
m_Parent->RegisterMsg(msgId, std::bind(handler, self, std::placeholders::_1)); m_Parent->RegisterMsg(msgId, std::bind(handler, self, std::placeholders::_1));
} }
template<typename T>
inline void RegisterMsg(auto* self, const auto handler) {
T msg;
RegisterMsg(msg.msgId, self, handler);
}
/** /**
* The entity that owns this component * The entity that owns this component
*/ */

View File

@@ -21,6 +21,7 @@
#include "BuffComponent.h" #include "BuffComponent.h"
#include "SkillComponent.h" #include "SkillComponent.h"
#include "Item.h" #include "Item.h"
#include "Amf3.h"
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
@@ -42,6 +43,7 @@ Implementation<bool, const Entity*> DestroyableComponent::IsEnemyImplentation;
Implementation<bool, const Entity*> DestroyableComponent::IsFriendImplentation; Implementation<bool, const Entity*> DestroyableComponent::IsFriendImplentation;
DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) { DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) {
using namespace GameMessages;
m_iArmor = 0; m_iArmor = 0;
m_fMaxArmor = 0.0f; m_fMaxArmor = 0.0f;
m_iImagination = 0; m_iImagination = 0;
@@ -78,6 +80,8 @@ DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) {
m_DeathBehavior = -1; m_DeathBehavior = -1;
m_DamageCooldownTimer = 0.0f; m_DamageCooldownTimer = 0.0f;
RegisterMsg<GetObjectReportInfo>(this, &DestroyableComponent::OnGetObjectReportInfo);
} }
DestroyableComponent::~DestroyableComponent() { DestroyableComponent::~DestroyableComponent() {
@@ -1031,3 +1035,55 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source) {
} }
} }
} }
bool DestroyableComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
auto& destroyableInfo = reportInfo.info->PushDebug("Destroyable");
destroyableInfo.PushDebug<AMFIntValue>("Health") = m_iHealth;
destroyableInfo.PushDebug<AMFDoubleValue>("Max Health") = m_fMaxHealth;
destroyableInfo.PushDebug<AMFIntValue>("Armor") = m_iArmor;
destroyableInfo.PushDebug<AMFDoubleValue>("Max Armor") = m_fMaxArmor;
destroyableInfo.PushDebug<AMFIntValue>("Imagination") = m_iImagination;
destroyableInfo.PushDebug<AMFDoubleValue>("Max Imagination") = m_fMaxImagination;
destroyableInfo.PushDebug<AMFIntValue>("Damage To Absorb") = m_DamageToAbsorb;
destroyableInfo.PushDebug<AMFBoolValue>("Is GM Immune") = m_IsGMImmune;
destroyableInfo.PushDebug<AMFBoolValue>("Is Shielded") = m_IsShielded;
destroyableInfo.PushDebug<AMFIntValue>("Attacks To Block") = m_AttacksToBlock;
destroyableInfo.PushDebug<AMFIntValue>("Damage Reduction") = m_DamageReduction;
auto& factions = destroyableInfo.PushDebug("Factions");
for (const auto factionID : m_FactionIDs) {
factions.PushDebug<AMFStringValue>(std::to_string(factionID)) = "";
}
auto& enemyFactions = destroyableInfo.PushDebug("Enemy Factions");
for (const auto enemyFactionID : m_EnemyFactionIDs) {
enemyFactions.PushDebug<AMFStringValue>(std::to_string(enemyFactionID)) = "";
}
destroyableInfo.PushDebug<AMFBoolValue>("Is Smashable") = m_IsSmashable;
destroyableInfo.PushDebug<AMFBoolValue>("Is Dead") = m_IsDead;
destroyableInfo.PushDebug<AMFBoolValue>("Is Smashed") = m_IsSmashed;
destroyableInfo.PushDebug<AMFBoolValue>("Is Module Assembly") = m_IsModuleAssembly;
destroyableInfo.PushDebug<AMFDoubleValue>("Explode Factor") = m_ExplodeFactor;
destroyableInfo.PushDebug<AMFBoolValue>("Has Threats") = m_HasThreats;
destroyableInfo.PushDebug<AMFIntValue>("Loot Matrix ID") = m_LootMatrixID;
destroyableInfo.PushDebug<AMFIntValue>("Min Coins") = m_MinCoins;
destroyableInfo.PushDebug<AMFIntValue>("Max Coins") = m_MaxCoins;
destroyableInfo.PushDebug<AMFStringValue>("Killer ID") = std::to_string(m_KillerID);
// "Scripts"; idk what to do about scripts yet
auto& immuneCounts = destroyableInfo.PushDebug("Immune Counts");
immuneCounts.PushDebug<AMFIntValue>("Basic Attack") = m_ImmuneToBasicAttackCount;
immuneCounts.PushDebug<AMFIntValue>("Damage Over Time") = m_ImmuneToDamageOverTimeCount;
immuneCounts.PushDebug<AMFIntValue>("Knockback") = m_ImmuneToKnockbackCount;
immuneCounts.PushDebug<AMFIntValue>("Interrupt") = m_ImmuneToInterruptCount;
immuneCounts.PushDebug<AMFIntValue>("Speed") = m_ImmuneToSpeedCount;
immuneCounts.PushDebug<AMFIntValue>("Imagination Gain") = m_ImmuneToImaginationGainCount;
immuneCounts.PushDebug<AMFIntValue>("Imagination Loss") = m_ImmuneToImaginationLossCount;
immuneCounts.PushDebug<AMFIntValue>("Quickbuild Interrupt") = m_ImmuneToQuickbuildInterruptCount;
immuneCounts.PushDebug<AMFIntValue>("Pull To Point") = m_ImmuneToPullToPointCount;
destroyableInfo.PushDebug<AMFIntValue>("Death Behavior") = m_DeathBehavior;
destroyableInfo.PushDebug<AMFDoubleValue>("Damage Cooldown Timer") = m_DamageCooldownTimer;
return true;
}

View File

@@ -9,6 +9,10 @@
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
#include "Implementation.h" #include "Implementation.h"
namespace GameMessages {
struct GetObjectReportInfo;
};
namespace CppScripts { namespace CppScripts {
class Script; class Script;
}; //! namespace CppScripts }; //! namespace CppScripts
@@ -464,6 +468,8 @@ public:
// handle hardcode mode drops // handle hardcode mode drops
void DoHardcoreModeDrops(const LWOOBJID source); void DoHardcoreModeDrops(const LWOOBJID source);
bool OnGetObjectReportInfo(GameMessages::GameMsg& msg);
static Implementation<bool, const Entity*> IsEnemyImplentation; static Implementation<bool, const Entity*> IsEnemyImplentation;
static Implementation<bool, const Entity*> IsFriendImplentation; static Implementation<bool, const Entity*> IsFriendImplentation;
@@ -591,7 +597,7 @@ private:
/** /**
* The ID of the entity that smashed this entity, if any * The ID of the entity that smashed this entity, if any
*/ */
LWOOBJID m_KillerID; LWOOBJID m_KillerID{};
/** /**
* The list of callbacks that will be called when this entity gets hit * The list of callbacks that will be called when this entity gets hit

View File

@@ -1524,7 +1524,8 @@ namespace DEVGMCommands {
GameMessages::RequestServerObjectInfo objectInfo; GameMessages::RequestServerObjectInfo objectInfo;
objectInfo.bVerbose = true; objectInfo.bVerbose = true;
objectInfo.target = closest->GetObjectID(); objectInfo.target = closest->GetObjectID();
objectInfo.targetForReport = entity->GetObjectID(); objectInfo.targetForReport = closest->GetObjectID();
objectInfo.clientId = entity->GetObjectID();
closest->HandleMsg(objectInfo); closest->HandleMsg(objectInfo);
Game::entityManager->SerializeEntity(closest); Game::entityManager->SerializeEntity(closest);