Files
DarkflameServer/dGame/dComponents/Physics/PhysicsComponent.h
Aaron Kimbrell 9a464ac35f refactor(component): group the component files by the client's families
Physics/, Activity/ (activity, scripted activity, shooting gallery,
quickbuild, minigame control, racing control base, racing control, gate rush),
Vendor/, Character/ (what the client makes with a character, plus ghost,
minifig and mission), Sound/ and Property/; the rest stays where it was.
File moves only; DLU_COMPONENT_INCLUDE_DIRS gives every target the folders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 15:37:45 -05:00

95 lines
3.6 KiB
C++

#ifndef __PHYSICSCOMPONENT__H__
#define __PHYSICSCOMPONENT__H__
#include "Component.h"
#include "NiPoint3.h"
#include "NiQuaternion.h"
#include "dCommonVars.h"
struct LwoNameValue;
namespace GameMessages {
struct GetObjectReportInfo;
struct GetPosition;
};
namespace Raknet {
class BitStream;
};
enum class eReplicaComponentType : uint32_t;
class dpEntity;
class PhysicsComponent : public Component {
public:
PhysicsComponent(Entity* parent, const int32_t componentID);
void LoadDataFromTemplate() override;
void LoadConfigData() override;
virtual ~PhysicsComponent();
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
const NiPoint3& GetPosition() const noexcept { return m_Position; }
virtual void SetPosition(const NiPoint3& pos) { if (m_Position == pos) return; m_Position = pos; m_DirtyPosition = true; }
const NiQuaternion& GetRotation() const { return m_Rotation; }
virtual void SetRotation(const NiQuaternion& rot) { if (m_Rotation == rot) return; m_Rotation = rot; m_DirtyPosition = true; }
int32_t GetCollisionGroup() const noexcept { return m_CollisionGroup; }
void SetCollisionGroup(int32_t group) noexcept { m_CollisionGroup = group; }
/**
* Whether a level object is carver_only, which the client never loads (LWOResMgr2Interface::Run skips its load
* when its config has carver_only set; LWOBasePhysComponent::LoadConfigData 0x00c495c9 reads it next to
* navmesh_carver). Live never sent one.
*/
[[nodiscard]] static bool IsCarverOnly(const LwoNameValue& settings);
/**
* For a level object the server doesn't spawn (carver_only): adds its shape to the world's movement blockers, the
* way its physics component would have (RegisterMovementBlocker), owned by the world.
* @return whether it blocks movement (its data makes it a wall and the server knows its shape)
*/
static bool AddLevelMovementBlocker(LWOOBJID id, LOT lot, const LwoNameValue& settings, const NiPoint3& position, const NiQuaternion& rotation, float scale);
protected:
bool OnGetObjectReportInfo(GameMessages::GetObjectReportInfo& msg);
// isFallback, when given, says whether the asset had no known shape and got a stand in cube
dpEntity* CreatePhysicsEntity(eReplicaComponentType type, bool* isFallback = nullptr);
/**
* The shape of the physics asset of a LOT's physics component of the given type, for an object placed with this
* scale and rotation, or nullptr when it has none. Some shapes move position (in and out) to line up with the
* client's. isFallback, when given, says whether the asset had no known shape and got a stand in cube.
*/
static dpEntity* CreateAssetShape(LWOOBJID id, LOT lot, eReplicaComponentType type, int32_t collisionGroup, float scale, const NiQuaternion& rotation, NiPoint3& position, bool* isFallback = nullptr);
/**
* Makes this object a wall the server's movers can't walk through when its data says it is one
* (dpMovementBlockers::BlockingFilter: a navmesh carver, or a solid object only enemies collide with). Only
* shapes the server knows are used; a stand in cube would be a guess.
*/
void RegisterMovementBlocker(eReplicaComponentType type, bool solid, float scale);
dpEntity* CreatePhysicsLnv(const float scale, const eReplicaComponentType type) const;
void SpawnVertices(dpEntity* entity) const;
bool OnGetPosition(GameMessages::GetPosition& msg);
NiPoint3 m_Position;
NiQuaternion m_Rotation = QuatUtils::IDENTITY;
bool m_DirtyPosition;
int32_t m_CollisionGroup{};
// This object's shape as a movement blocker, owned here and not stepped with the physics world
dpEntity* m_MovementBlocker{};
};
#endif //!__PHYSICSCOMPONENT__H__