Further work on subcomponents

serialization is improved, next is re-implementing the actual functionality.
This commit is contained in:
David Markowitz
2023-08-01 01:19:07 -07:00
parent ba409b6ee2
commit 43657324e9
7 changed files with 268 additions and 63 deletions

View File

@@ -12,10 +12,15 @@
#include "GameMessages.h"
#include "CppScripts.h"
#include "SimplePhysicsComponent.h"
#include "CDClientManager.h"
#include "CDMovingPlatformComponentTable.h"
#include "Zone.h"
PlatformSubComponent::PlatformSubComponent() {
//------------- PlatformSubComponent begin --------------
PlatformSubComponent::PlatformSubComponent(MovingPlatformComponent* parentComponent) {
m_Position = NiPoint3::ZERO;
m_ParentComponent = parentComponent;
m_State = eMovementPlatformState::Stopped | eMovementPlatformState::ReachedDesiredWaypoint;
m_DesiredWaypointIndex = 0;
@@ -31,8 +36,8 @@ PlatformSubComponent::PlatformSubComponent() {
}
void PlatformSubComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
outBitStream->Write(m_IsDirty);
if (!m_IsDirty) return;
outBitStream->Write(bIsInitialUpdate || m_IsDirty);
if (!(bIsInitialUpdate || m_IsDirty)) return;
outBitStream->Write(m_State);
outBitStream->Write(m_DesiredWaypointIndex);
outBitStream->Write(m_ShouldStopAtDesiredWaypoint);
@@ -48,22 +53,105 @@ void PlatformSubComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn
if (!bIsInitialUpdate) m_IsDirty = false;
}
//------------- MovingPlatformComponent below --------------
//------------- PlatformSubComponent end --------------
//------------- MoverPlatformSubComponent begin --------------
MoverPlatformSubComponent::MoverPlatformSubComponent(MovingPlatformComponent* parentComponent) : PlatformSubComponent(parentComponent) {
}
//------------- MoverPlatformSubComponent end --------------
//------------- RotatorPlatformSubComponent begin --------------
RotatorPlatformSubComponent::RotatorPlatformSubComponent(MovingPlatformComponent* parentComponent) : PlatformSubComponent(parentComponent) {
}
//------------- RotatorPlatformSubComponent end --------------
//------------- SimpleMoverPlatformSubComponent begin --------------
void SimpleMoverPlatformSubComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
outBitStream->Write(bIsInitialUpdate || m_DirtyStartingPoint);
if (bIsInitialUpdate || m_DirtyStartingPoint) {
outBitStream->Write(m_HasStartingPoint);
if (m_HasStartingPoint) {
outBitStream->Write(m_StartingPoint.x);
outBitStream->Write(m_StartingPoint.y);
outBitStream->Write(m_StartingPoint.z);
outBitStream->Write(m_StartingRotation.w);
outBitStream->Write(m_StartingRotation.x);
outBitStream->Write(m_StartingRotation.y);
outBitStream->Write(m_StartingRotation.z);
}
if (!bIsInitialUpdate) m_DirtyStartingPoint = false;
}
outBitStream->Write(bIsInitialUpdate || m_IsDirty);
if (bIsInitialUpdate || m_IsDirty) {
outBitStream->Write(m_State);
outBitStream->Write(m_CurrentWaypointIndex);
outBitStream->Write(m_InReverse);
if (!bIsInitialUpdate) m_IsDirty = false;
}
}
void SimpleMoverPlatformSubComponent::LoadConfigData() {
if (m_ParentComponent->GetParent()->GetVar<bool>(u"dbonly")) return;
NiPoint3 platformMove(
m_ParentComponent->GetParent()->GetVar<float>(u"platformMoveX"),
m_ParentComponent->GetParent()->GetVar<float>(u"platformMoveY"),
m_ParentComponent->GetParent()->GetVar<float>(u"platformMoveZ")
);
m_PlatformMove = platformMove;
m_MoveTime = m_ParentComponent->GetParent()->GetVar<float>(u"platformMoveTime");
// idk either. client does it!
m_StartAtEnd = m_ParentComponent->GetParent()->GetVar<uint32_t>(u"attached_path_start") != 0;
m_StartAtEnd = m_ParentComponent->GetParent()->GetVar<bool>(u"platformStartAtEnd");
}
void SimpleMoverPlatformSubComponent::LoadDataFromTemplate() {
if (!m_ParentComponent->GetParent()->GetVar<bool>(u"dbonly")) return;
auto* movingPlatformTable = CDClientManager::Instance().GetTable<CDMovingPlatformComponentTable>();
if (movingPlatformTable == nullptr) return;
const auto& platformEntry = movingPlatformTable->GetPlatformEntry(m_ParentComponent->GetComponentId());
if (!platformEntry || !platformEntry->platformIsSimpleMover) return;
NiPoint3 platformMove = platformEntry->platformMove;
float moveTime = platformEntry->moveTime;
}
SimpleMoverPlatformSubComponent::SimpleMoverPlatformSubComponent(MovingPlatformComponent* parentComponent, const NiPoint3& platformMove, const bool startsInReverse) : PlatformSubComponent(parentComponent) {
m_PlatformMove = platformMove;
m_InReverse = startsInReverse;
m_HasStartingPoint = true;
m_DirtyStartingPoint = true;
m_IsDirty = true;
m_StartingPoint = m_ParentComponent->GetParent()->GetPosition();
m_StartingRotation = m_ParentComponent->GetParent()->GetRotation();
}
//------------- SimpleMoverPlatformSubComponent end --------------
//------------- MovingPlatformComponent begin --------------
MovingPlatformComponent::MovingPlatformComponent(Entity* parent, const std::string& pathName) : Component(parent) {
if (Game::zoneManager == nullptr) return;
auto path = Game::zoneManager->GetZone()->GetPath(pathName);
if (!path) return;
Game::logger->Log("MovingPlatformComponent", "Path found: %s", pathName.c_str());
}
void MovingPlatformComponent::LoadConfigData() {
if (m_Parent->GetVar<bool>(u"platformIsSimpleMover")) {
m_Platforms.push_back(std::make_unique<SimpleMoverPlatformSubComponent>());
AddMovingPlatform<SimpleMoverPlatformSubComponent>(NiPoint3::ZERO, false);
}
if (m_Parent->GetVar<bool>(u"platformIsMover")) {
m_Platforms.push_back(std::make_unique<MoverPlatformSubComponent>());
AddMovingPlatform<MoverPlatformSubComponent>();
}
if (m_Parent->GetVar<bool>(u"platformIsRotater")) {
m_Platforms.push_back(std::make_unique<RotatorPlatformSubComponent>());
AddMovingPlatform<RotatorPlatformSubComponent>();
}
m_DirtyPathInfo = true;
}
@@ -80,11 +168,12 @@ void MovingPlatformComponent::Serialize(RakNet::BitStream* outBitStream, bool bI
for (const auto& c : m_PathName) {
outBitStream->Write(static_cast<uint16_t>(c));
}
outBitStream->Write<uint32_t>(1); // Starting waypoint
outBitStream->Write1(); // is in reverse
outBitStream->Write(m_StartingWaypointIndex);
outBitStream->Write(m_StartsIsInReverse);
}
if (!bIsInitialUpdate) m_DirtyPathInfo = false;
}
if (m_Platforms.empty()) return;
for (const auto& platform : m_Platforms) {
outBitStream->Write1(); // Has platform to write
@@ -325,3 +414,5 @@ size_t MovingPlatformComponent::GetLastWaypointIndex() const {
return 0;
// return m_Path->pathWaypoints.size() - 1;
}
//------------- MovingPlatformComponent end --------------

View File

@@ -28,9 +28,11 @@ enum class eMoverSubComponentType : uint32_t {
Rotator = 6
};
class MovingPlatformComponent;
class PlatformSubComponent {
public:
PlatformSubComponent();
PlatformSubComponent(MovingPlatformComponent* parentComponent);
virtual ~PlatformSubComponent() = default;
virtual void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate);
virtual eMoverSubComponentType GetPlatformType() { return eMoverSubComponentType::None; };
@@ -40,6 +42,7 @@ protected:
#ifdef _MOVING_PLATFORM_TEST
public:
#endif
MovingPlatformComponent* m_ParentComponent = nullptr;
/**
* The state the platform is currently in
*/
@@ -60,27 +63,38 @@ public:
class MoverPlatformSubComponent : public PlatformSubComponent {
public:
MoverPlatformSubComponent() : PlatformSubComponent() {};
inline static const eMoverSubComponentType SubComponentType = eMoverSubComponentType::Mover;
MoverPlatformSubComponent(MovingPlatformComponent* parentComponent);
~MoverPlatformSubComponent() override = default;
eMoverSubComponentType GetPlatformType() override { return eMoverSubComponentType::Mover; }
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override { PlatformSubComponent::Serialize(outBitStream, bIsInitialUpdate); };
};
class RotatorPlatformSubComponent : public PlatformSubComponent {
public:
RotatorPlatformSubComponent() : PlatformSubComponent() {};
inline static const eMoverSubComponentType SubComponentType = eMoverSubComponentType::Rotator;
RotatorPlatformSubComponent(MovingPlatformComponent* parentComponent);
~RotatorPlatformSubComponent() override = default;
eMoverSubComponentType GetPlatformType() override { return eMoverSubComponentType::Rotator; }
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override { PlatformSubComponent::Serialize(outBitStream, bIsInitialUpdate); };
};
// Only moves. Has NO path.
// Only moves. Has NO path. This moving platform gets its initial position and rotation from the server on serialization.
class SimpleMoverPlatformSubComponent : public PlatformSubComponent {
public:
SimpleMoverPlatformSubComponent() : PlatformSubComponent() {};
inline static const eMoverSubComponentType SubComponentType = eMoverSubComponentType::SimpleMover;
SimpleMoverPlatformSubComponent(MovingPlatformComponent* parentComponent, const NiPoint3& platformMove, const bool startAtEnd);
~SimpleMoverPlatformSubComponent() override = default;
eMoverSubComponentType GetPlatformType() override { return eMoverSubComponentType::SimpleMover; }
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override { PlatformSubComponent::Serialize(outBitStream, bIsInitialUpdate); };
void LoadConfigData();
void LoadDataFromTemplate();
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
bool m_HasStartingPoint = false;
bool m_DirtyStartingPoint = false;
NiPoint3 m_StartingPoint;
NiQuaternion m_StartingRotation;
NiPoint3 m_PlatformMove;
float m_MoveTime;
bool m_StartAtEnd;
};
/**
@@ -96,6 +110,8 @@ public:
MovingPlatformComponent(Entity* parent, const std::string& pathName);
void LoadConfigData();
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags);
/**
@@ -166,6 +182,19 @@ public:
*/
size_t GetLastWaypointIndex() const;
template<typename MovingPlatform, typename ...ConstructorValues>
void AddMovingPlatform(ConstructorValues... arguments) {
static_assert(std::is_base_of<PlatformSubComponent, MovingPlatform>::value, "MovingPlatform must derive from PlatformSubComponent");
auto hasPlatform = std::find_if(m_Platforms.begin(), m_Platforms.end(), [](const std::unique_ptr<PlatformSubComponent>& platform) {
return platform->GetPlatformType() == MovingPlatform::SubComponentType;
}) != m_Platforms.end();
if (!hasPlatform) {
m_Platforms.push_back(std::make_unique<MovingPlatform>(this, std::forward<ConstructorValues>(arguments)...));
}
}
int32_t GetComponentId() const { return componentId; }
#ifdef _MOVING_PLATFORM_TEST
/**
* Only used for testing. Do not call in production code. Let the constructor take care of this.
@@ -192,6 +221,12 @@ private:
*/
bool m_PathingStopped = false;
uint32_t m_StartingWaypointIndex = 0;
bool m_StartsIsInReverse = false;
int32_t componentId = -1;;
/**
* The mover sub component that belongs to this platform
*/