This commit is contained in:
David Markowitz
2025-10-27 02:22:25 -07:00
parent 929e16bd40
commit 4de67b57fa
23 changed files with 81 additions and 88 deletions

View File

@@ -68,7 +68,7 @@ set(RECASTNAVIGATION_EXAMPLES OFF CACHE BOOL "" FORCE)
# Disabled unknown pragmas because Linux doesn't understand Windows pragmas.
if(UNIX)
add_link_options("-Wl,-rpath,$ORIGIN/")
add_compile_options("-fPIC")
add_compile_options("-fPIC" "-O2")
add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0 _GLIBCXX_USE_CXX17_ABI=0)
# For all except Clang and Apple Clang

View File

@@ -194,10 +194,10 @@ Entity::~Entity() {
}
void Entity::Initialize() {
RegisterMsg<GameMessages::RequestServerObjectInfo>(this, &Entity::MsgRequestServerObjectInfo);
RegisterMsg<GameMessages::DropClientLoot>(this, &Entity::MsgDropClientLoot);
RegisterMsg<GameMessages::GetFactionTokenType>(this, &Entity::MsgGetFactionTokenType);
RegisterMsg<GameMessages::PickupItem>(this, &Entity::MsgPickupItem);
RegisterMsg(this, &Entity::MsgRequestServerObjectInfo);
RegisterMsg(this, &Entity::MsgDropClientLoot);
RegisterMsg(this, &Entity::MsgGetFactionTokenType);
RegisterMsg(this, &Entity::MsgPickupItem);
/**
* Setup trigger
*/
@@ -2275,8 +2275,7 @@ void Entity::RegisterMsg(const MessageType::Game msgId, std::function<bool(GameM
m_MsgHandlers.emplace(msgId, handler);
}
bool Entity::MsgRequestServerObjectInfo(GameMessages::GameMsg& msg) {
auto& requestInfo = static_cast<GameMessages::RequestServerObjectInfo&>(msg);
bool Entity::MsgRequestServerObjectInfo(GameMessages::RequestServerObjectInfo& requestInfo) {
AMFArrayValue response;
response.Insert("visible", true);
response.Insert("objectID", std::to_string(m_ObjectID));
@@ -2312,9 +2311,7 @@ bool Entity::MsgRequestServerObjectInfo(GameMessages::GameMsg& msg) {
return true;
}
bool Entity::MsgDropClientLoot(GameMessages::GameMsg& msg) {
auto& dropLootMsg = static_cast<GameMessages::DropClientLoot&>(msg);
bool Entity::MsgDropClientLoot(GameMessages::DropClientLoot& dropLootMsg) {
if (dropLootMsg.item != LOT_NULL && dropLootMsg.item != 0) {
Loot::Info info{
.id = dropLootMsg.lootID,
@@ -2331,13 +2328,11 @@ bool Entity::MsgDropClientLoot(GameMessages::GameMsg& msg) {
return true;
}
bool Entity::MsgGetFlag(GameMessages::GameMsg& msg) {
auto& flagMsg = static_cast<GameMessages::GetFlag&>(msg);
bool Entity::MsgGetFlag(GameMessages::GetFlag& flagMsg) {
if (m_Character) flagMsg.flag = m_Character->GetPlayerFlag(flagMsg.flagID);
return true;
}
bool Entity::MsgGetFactionTokenType(GameMessages::GameMsg& msg) {
auto& tokenMsg = static_cast<GameMessages::GetFactionTokenType&>(msg);
bool Entity::MsgGetFactionTokenType(GameMessages::GetFactionTokenType& tokenMsg) {
GameMessages::GetFlag getFlagMsg{};
getFlagMsg.flagID = ePlayerFlag::ASSEMBLY_FACTION;
@@ -2360,8 +2355,7 @@ bool Entity::MsgGetFactionTokenType(GameMessages::GameMsg& msg) {
return tokenMsg.tokenType != LOT_NULL;
}
bool Entity::MsgPickupItem(GameMessages::GameMsg& msg) {
auto& pickupItemMsg = static_cast<GameMessages::PickupItem&>(msg);
bool Entity::MsgPickupItem(GameMessages::PickupItem& pickupItemMsg) {
if (GetObjectID() == pickupItemMsg.lootOwnerID) {
PickupItem(pickupItemMsg.lootID);
} else {

View File

@@ -20,6 +20,11 @@ namespace GameMessages {
struct ShootingGalleryFire;
struct ChildLoaded;
struct PlayerResurrectionFinished;
struct RequestServerObjectInfo;
struct DropClientLoot;
struct GetFlag;
struct GetFactionTokenType;
struct PickupItem;
};
namespace MessageType {
@@ -177,11 +182,11 @@ public:
void AddComponent(eReplicaComponentType componentId, Component* component);
bool MsgRequestServerObjectInfo(GameMessages::GameMsg& msg);
bool MsgDropClientLoot(GameMessages::GameMsg& msg);
bool MsgGetFlag(GameMessages::GameMsg& msg);
bool MsgGetFactionTokenType(GameMessages::GameMsg& msg);
bool MsgPickupItem(GameMessages::GameMsg& msg);
bool MsgRequestServerObjectInfo(GameMessages::RequestServerObjectInfo& msg);
bool MsgDropClientLoot(GameMessages::DropClientLoot& msg);
bool MsgGetFlag(GameMessages::GetFlag& msg);
bool MsgGetFactionTokenType(GameMessages::GetFactionTokenType& msg);
bool MsgPickupItem(GameMessages::PickupItem& msg);
// This is expceted to never return nullptr, an assert checks this.
CppScripts::Script* const GetScript() const;
@@ -346,13 +351,17 @@ public:
bool HandleMsg(GameMessages::GameMsg& msg) const;
void RegisterMsg(const MessageType::Game msgId, auto* self, const auto handler) {
RegisterMsg(msgId, std::bind(handler, self, std::placeholders::_1));
RegisterMsg(msgId, handler);
}
template<typename T>
inline void RegisterMsg(auto* self, const auto handler) {
T msg;
RegisterMsg(msg.msgId, self, handler);
template<typename DerivedGameMsg>
inline void RegisterMsg(auto* self, bool (Entity::* handler)(DerivedGameMsg&)) {
const auto boundFunction = std::bind(handler, self, std::placeholders::_1);
const auto castWrapper = [boundFunction](GameMessages::GameMsg& msg) {
return boundFunction(static_cast<DerivedGameMsg&>(msg));
};
DerivedGameMsg msg;
RegisterMsg(msg.msgId, self, castWrapper);
}
/**

View File

@@ -31,8 +31,7 @@
#include "Amf3.h"
ActivityComponent::ActivityComponent(Entity* parent, int32_t componentID) : Component(parent, componentID) {
using namespace GameMessages;
RegisterMsg<GetObjectReportInfo>(this, &ActivityComponent::OnGetObjectReportInfo);
RegisterMsg(this, &ActivityComponent::OnGetObjectReportInfo);
/*
* This is precisely what the client does functionally
* Use the component id as the default activity id and load its data from the database
@@ -591,9 +590,7 @@ Entity* LobbyPlayer::GetEntity() const {
return Game::entityManager->GetEntity(entityID);
}
bool ActivityComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
bool ActivityComponent::OnGetObjectReportInfo(GameMessages::GetObjectReportInfo& reportInfo) {
auto& activityInfo = reportInfo.info->PushDebug("Activity");
auto& instances = activityInfo.PushDebug("Instances: " + std::to_string(m_Instances.size()));

View File

@@ -347,7 +347,7 @@ public:
private:
bool OnGetObjectReportInfo(GameMessages::GameMsg& msg);
bool OnGetObjectReportInfo(GameMessages::GetObjectReportInfo& msg);
/**
* The database information for this activity
*/

View File

@@ -30,10 +30,7 @@
#include "Amf3.h"
BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const int32_t componentID) : Component(parent, componentID) {
{
using namespace GameMessages;
RegisterMsg<GetObjectReportInfo>(this, &BaseCombatAIComponent::MsgGetObjectReportInfo);
}
RegisterMsg(this, &BaseCombatAIComponent::MsgGetObjectReportInfo);
m_Target = LWOOBJID_EMPTY;
m_DirtyStateOrTarget = true;
m_State = AiState::spawn;
@@ -874,12 +871,12 @@ bool BaseCombatAIComponent::MsgGetObjectReportInfo(GameMessages::GameMsg& msg) {
// roundInfo.PushDebug<AMFDoubleValue>("Combat Start Delay") = m_CombatStartDelay;
std::string curState;
switch (m_State) {
case idle: curState = "Idling"; break;
case aggro: curState = "Aggroed"; break;
case tether: curState = "Returning to Tether"; break;
case spawn: curState = "Spawn"; break;
case dead: curState = "Dead"; break;
default: curState = "Unknown or Undefined"; break;
case idle: curState = "Idling"; break;
case aggro: curState = "Aggroed"; break;
case tether: curState = "Returning to Tether"; break;
case spawn: curState = "Spawn"; break;
case dead: curState = "Dead"; break;
default: curState = "Unknown or Undefined"; break;
}
cmptType.PushDebug<AMFStringValue>("Current Combat State") = curState;

View File

@@ -31,10 +31,7 @@ BouncerComponent::BouncerComponent(Entity* parent, const int32_t componentID) :
LookupPetSwitch();
}
{
using namespace GameMessages;
RegisterMsg<GetObjectReportInfo>(this, &BouncerComponent::MsgGetObjectReportInfo);
}
RegisterMsg(this, &BouncerComponent::MsgGetObjectReportInfo);
}
BouncerComponent::~BouncerComponent() {

View File

@@ -49,7 +49,7 @@ CharacterComponent::CharacterComponent(Entity* parent, const int32_t componentID
m_LastUpdateTimestamp = std::time(nullptr);
m_SystemAddress = systemAddress;
RegisterMsg(MessageType::Game::GET_OBJECT_REPORT_INFO, this, &CharacterComponent::OnGetObjectReportInfo);
RegisterMsg(this, &CharacterComponent::OnGetObjectReportInfo);
}
bool CharacterComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {

View File

@@ -6,8 +6,7 @@
CollectibleComponent::CollectibleComponent(Entity* parentEntity, const int32_t componentID, const int32_t collectibleId) :
Component(parentEntity, componentID), m_CollectibleId(collectibleId) {
using namespace GameMessages;
RegisterMsg<GetObjectReportInfo>(this, &CollectibleComponent::MsgGetObjectReportInfo);
RegisterMsg(this, &CollectibleComponent::MsgGetObjectReportInfo);
}
void CollectibleComponent::Serialize(RakNet::BitStream& outBitStream, bool isConstruction) {

View File

@@ -55,17 +55,21 @@ public:
virtual void LoadFromXml(const tinyxml2::XMLDocument& doc) {}
virtual void Serialize(RakNet::BitStream& outBitStream, bool isConstruction) {}
protected:
private:
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, handler);
}
template<typename T>
inline void RegisterMsg(auto* self, const auto handler) {
T msg;
RegisterMsg(msg.msgId, self, handler);
protected:
template<typename GameObjClass, typename DerivedMsg>
inline void RegisterMsg(auto* self, bool (GameObjClass::*handler)(DerivedMsg&)) {
const auto handlerBound = std::bind(handler, self, std::placeholders::_1);
const auto castWrapper = [handlerBound](GameMessages::GameMsg& msg) {
return handlerBound(static_cast<DerivedMsg&>(msg));
};
DerivedMsg msg;
RegisterMsg(msg.msgId, self, castWrapper);
}
/**

View File

@@ -21,7 +21,7 @@
#include "Amf3.h"
ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity, const int32_t componentID) : PhysicsComponent(entity, componentID) {
RegisterMsg(MessageType::Game::GET_OBJECT_REPORT_INFO, this, &ControllablePhysicsComponent::OnGetObjectReportInfo);
RegisterMsg(this, &ControllablePhysicsComponent::OnGetObjectReportInfo);
m_Velocity = {};
m_AngularVelocity = {};
@@ -374,8 +374,8 @@ void ControllablePhysicsComponent::SetStunImmunity(
}
bool ControllablePhysicsComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
PhysicsComponent::OnGetObjectReportInfo(msg);
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
PhysicsComponent::OnGetObjectReportInfo(reportInfo);
auto& info = reportInfo.subCategory->PushDebug("Controllable Info");
auto& vel = info.PushDebug("Velocity");

View File

@@ -48,7 +48,6 @@ Implementation<bool, const Entity*> DestroyableComponent::IsEnemyImplentation;
Implementation<bool, const Entity*> DestroyableComponent::IsFriendImplentation;
DestroyableComponent::DestroyableComponent(Entity* parent, const int32_t componentID) : Component(parent, componentID) {
using namespace GameMessages;
m_iArmor = 0;
m_fMaxArmor = 0.0f;
m_iImagination = 0;
@@ -86,9 +85,9 @@ DestroyableComponent::DestroyableComponent(Entity* parent, const int32_t compone
m_DamageCooldownTimer = 0.0f;
RegisterMsg<GetObjectReportInfo>(this, &DestroyableComponent::OnGetObjectReportInfo);
RegisterMsg<GameMessages::SetFaction>(this, &DestroyableComponent::OnSetFaction);
RegisterMsg<GameMessages::IsDead>(this, &DestroyableComponent::OnIsDead);
RegisterMsg(this, &DestroyableComponent::OnGetObjectReportInfo);
RegisterMsg(this, &DestroyableComponent::OnSetFaction);
RegisterMsg(this, &DestroyableComponent::OnIsDead);
}
DestroyableComponent::~DestroyableComponent() {

View File

@@ -8,7 +8,7 @@ GhostComponent::GhostComponent(Entity* parent, const int32_t componentID) : Comp
m_GhostOverridePoint = NiPoint3Constant::ZERO;
m_GhostOverride = false;
RegisterMsg<GameMessages::GetObjectReportInfo>(this, &GhostComponent::MsgGetObjectReportInfo);
RegisterMsg(this, &GhostComponent::MsgGetObjectReportInfo);
}
GhostComponent::~GhostComponent() {

View File

@@ -3,7 +3,7 @@
#include "Amf3.h"
HavokVehiclePhysicsComponent::HavokVehiclePhysicsComponent(Entity* parent, const int32_t componentID) : PhysicsComponent(parent, componentID) {
RegisterMsg(MessageType::Game::GET_OBJECT_REPORT_INFO, this, &HavokVehiclePhysicsComponent::OnGetObjectReportInfo);
RegisterMsg(this, &HavokVehiclePhysicsComponent::OnGetObjectReportInfo);
m_Velocity = NiPoint3Constant::ZERO;
m_AngularVelocity = NiPoint3Constant::ZERO;
@@ -103,8 +103,8 @@ void HavokVehiclePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bo
}
bool HavokVehiclePhysicsComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
PhysicsComponent::OnGetObjectReportInfo(msg);
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
PhysicsComponent::OnGetObjectReportInfo(reportInfo);
if (!reportInfo.subCategory) {
return false;
}

View File

@@ -44,8 +44,7 @@
#include <ranges>
InventoryComponent::InventoryComponent(Entity* parent, const int32_t componentID) : Component(parent, componentID) {
using namespace GameMessages;
RegisterMsg<GetObjectReportInfo>(this, &InventoryComponent::OnGetObjectReportInfo);
RegisterMsg(this, &InventoryComponent::OnGetObjectReportInfo);
this->m_Dirty = true;
this->m_Equipped = {};
this->m_Pushed = {};

View File

@@ -22,9 +22,9 @@ ModelComponent::ModelComponent(Entity* parent, const int32_t componentID) : Comp
m_NumListeningInteract = 0;
m_userModelID = m_Parent->GetVarAs<LWOOBJID>(u"userModelID");
RegisterMsg<RequestUse>(this, &ModelComponent::OnRequestUse);
RegisterMsg<ResetModelToDefaults>(this, &ModelComponent::OnResetModelToDefaults);
RegisterMsg<GetObjectReportInfo>(this, &ModelComponent::OnGetObjectReportInfo);
RegisterMsg(this, &ModelComponent::OnRequestUse);
RegisterMsg(this, &ModelComponent::OnResetModelToDefaults);
RegisterMsg(this, &ModelComponent::OnGetObjectReportInfo);
}
bool ModelComponent::OnResetModelToDefaults(GameMessages::GameMsg& msg) {

View File

@@ -62,7 +62,7 @@ MovementAIComponent::MovementAIComponent(Entity* parent, const int32_t component
m_SavedVelocity = NiPoint3Constant::ZERO;
m_IsBounced = false;
RegisterMsg<GameMessages::GetObjectReportInfo>(this, &MovementAIComponent::OnGetObjectReportInfo);
RegisterMsg(this, &MovementAIComponent::OnGetObjectReportInfo);
if (!m_Parent->GetComponent<BaseCombatAIComponent>()) SetPath(m_Parent->GetVarAsString(u"attached_path"));
}

View File

@@ -29,7 +29,7 @@
#include "dpShapeSphere.h"
PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent, const int32_t componentID) : PhysicsComponent(parent, componentID) {
RegisterMsg(MessageType::Game::GET_OBJECT_REPORT_INFO, this, &PhantomPhysicsComponent::OnGetObjectReportInfo);
RegisterMsg(this, &PhantomPhysicsComponent::OnGetObjectReportInfo);
m_Position = m_Parent->GetDefaultPosition();
m_Rotation = m_Parent->GetDefaultRotation();
@@ -243,8 +243,8 @@ void PhantomPhysicsComponent::SetRotation(const NiQuaternion& rot) {
}
bool PhantomPhysicsComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
PhysicsComponent::OnGetObjectReportInfo(msg);
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
PhysicsComponent::OnGetObjectReportInfo(reportInfo);
if (!reportInfo.subCategory) {
return false;
}

View File

@@ -31,11 +31,11 @@ PhysicsComponent::PhysicsComponent(Entity* parent, const int32_t componentID) :
if (m_Parent->HasVar(u"CollisionGroupID")) m_CollisionGroup = m_Parent->GetVar<int32_t>(u"CollisionGroupID");
RegisterMsg(MessageType::Game::GET_POSITION, this, &PhysicsComponent::OnGetPosition);
RegisterMsg(this, &PhysicsComponent::OnGetPosition);
}
bool PhysicsComponent::OnGetPosition(GameMessages::GameMsg& msg) {
static_cast<GameMessages::GetPosition&>(msg).pos = GetPosition();
bool PhysicsComponent::OnGetPosition(GameMessages::GetPosition& msg) {
msg.pos = GetPosition();
return true;
}
@@ -245,8 +245,7 @@ void PhysicsComponent::SpawnVertices(dpEntity* entity) const {
}
}
bool PhysicsComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
bool PhysicsComponent::OnGetObjectReportInfo(GameMessages::GetObjectReportInfo& reportInfo) {
auto& info = reportInfo.info->PushDebug("Physics");
reportInfo.subCategory = &info;

View File

@@ -7,6 +7,7 @@
namespace GameMessages {
struct GetObjectReportInfo;
struct GetPosition;
};
namespace Raknet {
@@ -33,7 +34,8 @@ public:
int32_t GetCollisionGroup() const noexcept { return m_CollisionGroup; }
void SetCollisionGroup(int32_t group) noexcept { m_CollisionGroup = group; }
protected:
bool OnGetObjectReportInfo(GameMessages::GameMsg& msg);
bool OnGetObjectReportInfo(GameMessages::GetObjectReportInfo& reportInfo);
bool OnGetPosition(GameMessages::GetPosition& msg);
dpEntity* CreatePhysicsEntity(eReplicaComponentType type);
@@ -41,8 +43,6 @@ protected:
void SpawnVertices(dpEntity* entity) const;
bool OnGetPosition(GameMessages::GameMsg& msg);
NiPoint3 m_Position;
NiQuaternion m_Rotation = QuatUtils::IDENTITY;

View File

@@ -14,7 +14,7 @@
#include "Amf3.h"
RigidbodyPhantomPhysicsComponent::RigidbodyPhantomPhysicsComponent(Entity* parent, const int32_t componentID) : PhysicsComponent(parent, componentID) {
RegisterMsg(MessageType::Game::GET_OBJECT_REPORT_INFO, this, &RigidbodyPhantomPhysicsComponent::OnGetObjectReportInfo);
RegisterMsg(this, &RigidbodyPhantomPhysicsComponent::OnGetObjectReportInfo);
m_Position = m_Parent->GetDefaultPosition();
m_Rotation = m_Parent->GetDefaultRotation();
@@ -60,8 +60,8 @@ void RigidbodyPhantomPhysicsComponent::SpawnVertices() const {
}
bool RigidbodyPhantomPhysicsComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
PhysicsComponent::OnGetObjectReportInfo(msg);
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
PhysicsComponent::OnGetObjectReportInfo(reportInfo);
auto& info = reportInfo.subCategory->PushDebug("Rigidbody Phantom Info");
info.PushDebug<AMFDoubleValue>("Scale") = m_Scale;
return true;

View File

@@ -9,13 +9,12 @@
#include "Amf3.h"
ScriptComponent::ScriptComponent(Entity* parent, const int32_t componentID, const std::string& scriptName, bool serialized, bool client) : Component(parent, componentID) {
using namespace GameMessages;
m_Serialized = serialized;
m_Client = client;
m_ScriptName = scriptName;
SetScript(scriptName);
RegisterMsg<GetObjectReportInfo>(this, &ScriptComponent::OnGetObjectReportInfo);
RegisterMsg(this, &ScriptComponent::OnGetObjectReportInfo);
}
void ScriptComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {

View File

@@ -16,7 +16,7 @@
#include "Amf3.h"
SimplePhysicsComponent::SimplePhysicsComponent(Entity* parent, const int32_t componentID) : PhysicsComponent(parent, componentID) {
RegisterMsg(MessageType::Game::GET_OBJECT_REPORT_INFO, this, &SimplePhysicsComponent::OnGetObjectReportInfo);
RegisterMsg(this, &SimplePhysicsComponent::OnGetObjectReportInfo);
m_Position = m_Parent->GetDefaultPosition();
m_Rotation = m_Parent->GetDefaultRotation();
@@ -82,8 +82,8 @@ void SimplePhysicsComponent::SetPhysicsMotionState(uint32_t value) {
}
bool SimplePhysicsComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
PhysicsComponent::OnGetObjectReportInfo(msg);
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
PhysicsComponent::OnGetObjectReportInfo(reportInfo);
auto& info = reportInfo.subCategory->PushDebug("Simple Physics Info");
auto& velocity = info.PushDebug("Velocity");
velocity.PushDebug<AMFDoubleValue>("x") = m_Velocity.x;