From 3cf460cc5233d6201202a8a9c17d082c103a6b7c Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Mon, 31 Jul 2023 02:13:19 -0700 Subject: [PATCH 01/17] throw away the old impl --- dCommon/dEnums/eMovementPlatformState.h | 14 +- dGame/dComponents/MovingPlatformComponent.cpp | 420 ++++++++---------- dGame/dComponents/MovingPlatformComponent.h | 155 +++---- dGame/dGameMessages/GameMessages.cpp | 2 +- dGame/dGameMessages/GameMessages.h | 2 +- .../Map/General/PropertyPlatform.cpp | 13 +- dScripts/ai/AG/AgQbElevator.cpp | 6 +- .../dComponentsTests/CMakeLists.txt | 1 + .../MovingPlatformComponentTests.cpp | 158 +++++++ 9 files changed, 443 insertions(+), 328 deletions(-) create mode 100644 tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp diff --git a/dCommon/dEnums/eMovementPlatformState.h b/dCommon/dEnums/eMovementPlatformState.h index 1df437d85..dc7a85cd2 100644 --- a/dCommon/dEnums/eMovementPlatformState.h +++ b/dCommon/dEnums/eMovementPlatformState.h @@ -4,13 +4,19 @@ #include /** - * The different types of platform movement state, supposedly a bitmap + * The different types of platform movement state */ enum class eMovementPlatformState : uint32_t { - Moving = 0b00010, - Stationary = 0b11001, - Stopped = 0b01100 + Waiting = 1 << 0U, + Travelling = 1 << 1U, + Stopped = 1 << 2U, + ReachedDesiredWaypoint = 1 << 3U, + ReachedFinalWaypoint = 1 << 4U, +}; + +inline constexpr eMovementPlatformState operator|(eMovementPlatformState a, eMovementPlatformState b) { + return static_cast(static_cast(a) | static_cast(b)); }; #endif //!__EMOVEMENTPLATFORMSTATE__H__ diff --git a/dGame/dComponents/MovingPlatformComponent.cpp b/dGame/dComponents/MovingPlatformComponent.cpp index f4dcdbe98..758170564 100644 --- a/dGame/dComponents/MovingPlatformComponent.cpp +++ b/dGame/dComponents/MovingPlatformComponent.cpp @@ -14,107 +14,84 @@ #include "SimplePhysicsComponent.h" #include "Zone.h" -MoverSubComponent::MoverSubComponent(const NiPoint3& startPos) { - mPosition = {}; +PlatformSubComponent::PlatformSubComponent() { + m_Position = NiPoint3::ZERO; - mState = eMovementPlatformState::Stopped; - mDesiredWaypointIndex = 0; // -1; - mInReverse = false; - mShouldStopAtDesiredWaypoint = false; + m_State = eMovementPlatformState::Stopped | eMovementPlatformState::ReachedDesiredWaypoint; + m_DesiredWaypointIndex = 0; + m_InReverse = false; + m_ShouldStopAtDesiredWaypoint = false; - mPercentBetweenPoints = 0.0f; + m_PercentBetweenPoints = 0.0f; - mCurrentWaypointIndex = 0; - mNextWaypointIndex = 0; //mCurrentWaypointIndex + 1; + m_CurrentWaypointIndex = 0; + m_NextWaypointIndex = 0; - mIdleTimeElapsed = 0.0f; + m_IdleTimeElapsed = 0.0f; } -MoverSubComponent::~MoverSubComponent() = default; - -void MoverSubComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) const { - outBitStream->Write(true); - - outBitStream->Write(static_cast(mState)); - outBitStream->Write(mDesiredWaypointIndex); - outBitStream->Write(mShouldStopAtDesiredWaypoint); - outBitStream->Write(mInReverse); - - outBitStream->Write(mPercentBetweenPoints); - - outBitStream->Write(mPosition.x); - outBitStream->Write(mPosition.y); - outBitStream->Write(mPosition.z); - - outBitStream->Write(mCurrentWaypointIndex); - outBitStream->Write(mNextWaypointIndex); - - outBitStream->Write(mIdleTimeElapsed); - outBitStream->Write(0.0f); // Move time elapsed +void PlatformSubComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { + outBitStream->Write(m_IsDirty); + if (!m_IsDirty) return; + outBitStream->Write(m_State); + outBitStream->Write(m_DesiredWaypointIndex); + outBitStream->Write(m_ShouldStopAtDesiredWaypoint); + outBitStream->Write(m_InReverse); + outBitStream->Write(m_PercentBetweenPoints); + outBitStream->Write(m_Position.x); + outBitStream->Write(m_Position.y); + outBitStream->Write(m_Position.z); + outBitStream->Write(m_CurrentWaypointIndex); + outBitStream->Write(m_NextWaypointIndex); + outBitStream->Write(m_IdleTimeElapsed); + outBitStream->Write(m_MoveTimeElapsed); + if (!bIsInitialUpdate) m_IsDirty = false; } //------------- MovingPlatformComponent below -------------- MovingPlatformComponent::MovingPlatformComponent(Entity* parent, const std::string& pathName) : Component(parent) { - m_MoverSubComponentType = eMoverSubComponentType::mover; - m_MoverSubComponent = new MoverSubComponent(m_Parent->GetDefaultPosition()); - m_PathName = GeneralUtils::ASCIIToUTF16(pathName); - m_Path = Game::zoneManager->GetZone()->GetPath(pathName); - m_NoAutoStart = false; - - if (m_Path == nullptr) { - Game::logger->Log("MovingPlatformComponent", "Path not found: %s", pathName.c_str()); - } -} + 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()); -MovingPlatformComponent::~MovingPlatformComponent() { - delete static_cast(m_MoverSubComponent); + if (m_Parent->GetVar(u"platformIsSimpleMover")) { + m_Platforms.push_back(std::make_unique()); + } + if (m_Parent->GetVar(u"platformIsMover")) { + m_Platforms.push_back(std::make_unique()); + } + if (m_Parent->GetVar(u"platformIsRotater")) { + m_Platforms.push_back(std::make_unique()); + } + m_DirtyPathInfo = true; } void MovingPlatformComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { - // Here we don't serialize the moving platform to let the client simulate the movement - - if (!m_Serialize) { - outBitStream->Write(false); - outBitStream->Write(false); - - return; - } - - outBitStream->Write(true); - - auto hasPath = !m_PathingStopped && !m_PathName.empty(); - outBitStream->Write(hasPath); - - if (hasPath) { - // Is on rail - outBitStream->Write1(); - - outBitStream->Write(static_cast(m_PathName.size())); - for (const auto& c : m_PathName) { - outBitStream->Write(static_cast(c)); + // For some reason we need to write this here instead of later on. + outBitStream->Write(!m_Platforms.empty()); + + outBitStream->Write(bIsInitialUpdate || m_DirtyPathInfo); + if (bIsInitialUpdate || m_DirtyPathInfo) { + outBitStream->Write(!m_PathName.empty()); + if (!m_PathName.empty()) { + outBitStream->Write(static_cast(m_PathName.size())); + for (const auto& c : m_PathName) { + outBitStream->Write(static_cast(c)); + } + outBitStream->Write(1); // Starting waypoint + outBitStream->Write1(); // is in reverse } - - // Starting point - outBitStream->Write(0); - - // Reverse - outBitStream->Write(false); + if (!bIsInitialUpdate) m_DirtyPathInfo = false; } - const auto hasPlatform = m_MoverSubComponent != nullptr; - outBitStream->Write(hasPlatform); - - if (hasPlatform) { - auto* mover = static_cast(m_MoverSubComponent); - outBitStream->Write(static_cast(m_MoverSubComponentType)); - - if (m_MoverSubComponentType == eMoverSubComponentType::simpleMover) { - // TODO - } else { - mover->Serialize(outBitStream, bIsInitialUpdate, flags); - } + for (const auto& platform : m_Platforms) { + outBitStream->Write1(); // Has platform to write + outBitStream->Write(platform->GetPlatformType()); + platform->Serialize(outBitStream, bIsInitialUpdate); } + outBitStream->Write0(); // No more platforms to write } void MovingPlatformComponent::OnRebuildInitilized() { @@ -122,232 +99,229 @@ void MovingPlatformComponent::OnRebuildInitilized() { } void MovingPlatformComponent::OnCompleteRebuild() { - if (m_NoAutoStart) - return; + if (m_NoAutoStart) return; StartPathing(); } void MovingPlatformComponent::SetMovementState(eMovementPlatformState value) { - auto* subComponent = static_cast(m_MoverSubComponent); + // auto* subComponent = static_cast(m_MoverSubComponent); - subComponent->mState = value; + // subComponent->mState = value; - Game::entityManager->SerializeEntity(m_Parent); + // Game::entityManager->SerializeEntity(m_Parent); } void MovingPlatformComponent::GotoWaypoint(uint32_t index, bool stopAtWaypoint) { - auto* subComponent = static_cast(m_MoverSubComponent); + // auto* subComponent = static_cast(m_MoverSubComponent); - subComponent->mDesiredWaypointIndex = index; - subComponent->mNextWaypointIndex = index; - subComponent->mShouldStopAtDesiredWaypoint = stopAtWaypoint; + // subComponent->mDesiredWaypointIndex = index; + // subComponent->mNextWaypointIndex = index; + // subComponent->mShouldStopAtDesiredWaypoint = stopAtWaypoint; - StartPathing(); + // StartPathing(); } void MovingPlatformComponent::StartPathing() { - //GameMessages::SendStartPathing(m_Parent); - m_PathingStopped = false; + // //GameMessages::SendStartPathing(m_Parent); + // m_PathingStopped = false; - auto* subComponent = static_cast(m_MoverSubComponent); + // auto* subComponent = static_cast(m_MoverSubComponent); - subComponent->mShouldStopAtDesiredWaypoint = true; - subComponent->mState = eMovementPlatformState::Stationary; + // subComponent->mShouldStopAtDesiredWaypoint = true; + // subComponent->mState = eMovementPlatformState::Stationary; - NiPoint3 targetPosition; + // NiPoint3 targetPosition; - if (m_Path != nullptr) { - const auto& currentWaypoint = m_Path->pathWaypoints[subComponent->mCurrentWaypointIndex]; - const auto& nextWaypoint = m_Path->pathWaypoints[subComponent->mNextWaypointIndex]; + // if (m_Path != nullptr) { + // const auto& currentWaypoint = m_Path->pathWaypoints[subComponent->mCurrentWaypointIndex]; + // const auto& nextWaypoint = m_Path->pathWaypoints[subComponent->mNextWaypointIndex]; - subComponent->mPosition = currentWaypoint.position; - subComponent->mSpeed = currentWaypoint.movingPlatform.speed; - subComponent->mWaitTime = currentWaypoint.movingPlatform.wait; + // subComponent->mPosition = currentWaypoint.position; + // subComponent->mSpeed = currentWaypoint.movingPlatform.speed; + // subComponent->mWaitTime = currentWaypoint.movingPlatform.wait; - targetPosition = nextWaypoint.position; - } else { - subComponent->mPosition = m_Parent->GetPosition(); - subComponent->mSpeed = 1.0f; - subComponent->mWaitTime = 2.0f; + // targetPosition = nextWaypoint.position; + // } else { + // subComponent->mPosition = m_Parent->GetPosition(); + // subComponent->mSpeed = 1.0f; + // subComponent->mWaitTime = 2.0f; - targetPosition = m_Parent->GetPosition() + NiPoint3(0.0f, 10.0f, 0.0f); - } + // targetPosition = m_Parent->GetPosition() + NiPoint3(0.0f, 10.0f, 0.0f); + // } - m_Parent->AddCallbackTimer(subComponent->mWaitTime, [this] { - SetMovementState(eMovementPlatformState::Moving); - }); + // m_Parent->AddCallbackTimer(subComponent->mWaitTime, [this] { + // SetMovementState(eMovementPlatformState::Moving); + // }); - const auto travelTime = Vector3::Distance(targetPosition, subComponent->mPosition) / subComponent->mSpeed + 1.5f; + // const auto travelTime = Vector3::Distance(targetPosition, subComponent->mPosition) / subComponent->mSpeed + 1.5f; - const auto travelNext = subComponent->mWaitTime + travelTime; + // const auto travelNext = subComponent->mWaitTime + travelTime; - m_Parent->AddCallbackTimer(travelTime, [subComponent, this] { - for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) { - script->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex); - } - }); + // m_Parent->AddCallbackTimer(travelTime, [subComponent, this] { + // for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) { + // script->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex); + // } + // }); - m_Parent->AddCallbackTimer(travelNext, [this] { - ContinuePathing(); - }); + // m_Parent->AddCallbackTimer(travelNext, [this] { + // ContinuePathing(); + // }); - //GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS); + // //GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS); - Game::entityManager->SerializeEntity(m_Parent); + // Game::entityManager->SerializeEntity(m_Parent); } void MovingPlatformComponent::ContinuePathing() { - auto* subComponent = static_cast(m_MoverSubComponent); + // auto* subComponent = static_cast(m_MoverSubComponent); - subComponent->mState = eMovementPlatformState::Stationary; + // subComponent->mState = eMovementPlatformState::Stationary; - subComponent->mCurrentWaypointIndex = subComponent->mNextWaypointIndex; + // subComponent->mCurrentWaypointIndex = subComponent->mNextWaypointIndex; - NiPoint3 targetPosition; - uint32_t pathSize; - PathBehavior behavior; + // NiPoint3 targetPosition; + // uint32_t pathSize; + // PathBehavior behavior; - if (m_Path != nullptr) { - const auto& currentWaypoint = m_Path->pathWaypoints[subComponent->mCurrentWaypointIndex]; - const auto& nextWaypoint = m_Path->pathWaypoints[subComponent->mNextWaypointIndex]; + // if (m_Path != nullptr) { + // const auto& currentWaypoint = m_Path->pathWaypoints[subComponent->mCurrentWaypointIndex]; + // const auto& nextWaypoint = m_Path->pathWaypoints[subComponent->mNextWaypointIndex]; - subComponent->mPosition = currentWaypoint.position; - subComponent->mSpeed = currentWaypoint.movingPlatform.speed; - subComponent->mWaitTime = currentWaypoint.movingPlatform.wait; // + 2; + // subComponent->mPosition = currentWaypoint.position; + // subComponent->mSpeed = currentWaypoint.movingPlatform.speed; + // subComponent->mWaitTime = currentWaypoint.movingPlatform.wait; // + 2; - pathSize = m_Path->pathWaypoints.size() - 1; + // pathSize = m_Path->pathWaypoints.size() - 1; - behavior = static_cast(m_Path->pathBehavior); + // behavior = static_cast(m_Path->pathBehavior); - targetPosition = nextWaypoint.position; - } else { - subComponent->mPosition = m_Parent->GetPosition(); - subComponent->mSpeed = 1.0f; - subComponent->mWaitTime = 2.0f; + // targetPosition = nextWaypoint.position; + // } else { + // subComponent->mPosition = m_Parent->GetPosition(); + // subComponent->mSpeed = 1.0f; + // subComponent->mWaitTime = 2.0f; - targetPosition = m_Parent->GetPosition() + NiPoint3(0.0f, 10.0f, 0.0f); + // targetPosition = m_Parent->GetPosition() + NiPoint3(0.0f, 10.0f, 0.0f); - pathSize = 1; - behavior = PathBehavior::Loop; - } + // pathSize = 1; + // behavior = PathBehavior::Loop; + // } - if (m_Parent->GetLOT() == 9483) { - behavior = PathBehavior::Bounce; - } else { - return; - } + // if (m_Parent->GetLOT() == 9483) { + // behavior = PathBehavior::Bounce; + // } else { + // return; + // } - if (subComponent->mCurrentWaypointIndex >= pathSize) { - subComponent->mCurrentWaypointIndex = pathSize; - switch (behavior) { - case PathBehavior::Once: - Game::entityManager->SerializeEntity(m_Parent); - return; + // if (subComponent->mCurrentWaypointIndex >= pathSize) { + // subComponent->mCurrentWaypointIndex = pathSize; + // switch (behavior) { + // case PathBehavior::Once: + // Game::entityManager->SerializeEntity(m_Parent); + // return; - case PathBehavior::Bounce: - subComponent->mInReverse = true; - break; + // case PathBehavior::Bounce: + // subComponent->mInReverse = true; + // break; - case PathBehavior::Loop: - subComponent->mNextWaypointIndex = 0; - break; + // case PathBehavior::Loop: + // subComponent->mNextWaypointIndex = 0; + // break; - default: - break; - } - } else if (subComponent->mCurrentWaypointIndex == 0) { - subComponent->mInReverse = false; - } + // default: + // break; + // } + // } else if (subComponent->mCurrentWaypointIndex == 0) { + // subComponent->mInReverse = false; + // } - if (subComponent->mInReverse) { - subComponent->mNextWaypointIndex = subComponent->mCurrentWaypointIndex - 1; - } else { - subComponent->mNextWaypointIndex = subComponent->mCurrentWaypointIndex + 1; - } + // if (subComponent->mInReverse) { + // subComponent->mNextWaypointIndex = subComponent->mCurrentWaypointIndex - 1; + // } else { + // subComponent->mNextWaypointIndex = subComponent->mCurrentWaypointIndex + 1; + // } - /* - subComponent->mNextWaypointIndex = 0; - subComponent->mCurrentWaypointIndex = 1; - */ + // /* + // subComponent->mNextWaypointIndex = 0; + // subComponent->mCurrentWaypointIndex = 1; + // */ - //GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS); + // //GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS); - if (subComponent->mCurrentWaypointIndex == subComponent->mDesiredWaypointIndex) { - // TODO: Send event? - StopPathing(); + // if (subComponent->mCurrentWaypointIndex == subComponent->mDesiredWaypointIndex) { + // // TODO: Send event? + // StopPathing(); - return; - } + // return; + // } - m_Parent->CancelCallbackTimers(); + // m_Parent->CancelCallbackTimers(); - m_Parent->AddCallbackTimer(subComponent->mWaitTime, [this] { - SetMovementState(eMovementPlatformState::Moving); - }); + // m_Parent->AddCallbackTimer(subComponent->mWaitTime, [this] { + // SetMovementState(eMovementPlatformState::Moving); + // }); - auto travelTime = Vector3::Distance(targetPosition, subComponent->mPosition) / subComponent->mSpeed + 1.5; + // auto travelTime = Vector3::Distance(targetPosition, subComponent->mPosition) / subComponent->mSpeed + 1.5; - if (m_Parent->GetLOT() == 9483) { - travelTime += 20; - } + // if (m_Parent->GetLOT() == 9483) { + // travelTime += 20; + // } - const auto travelNext = subComponent->mWaitTime + travelTime; + // const auto travelNext = subComponent->mWaitTime + travelTime; - m_Parent->AddCallbackTimer(travelTime, [subComponent, this] { - for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) { - script->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex); - } - }); + // m_Parent->AddCallbackTimer(travelTime, [subComponent, this] { + // for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) { + // script->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex); + // } + // }); - m_Parent->AddCallbackTimer(travelNext, [this] { - ContinuePathing(); - }); + // m_Parent->AddCallbackTimer(travelNext, [this] { + // ContinuePathing(); + // }); - Game::entityManager->SerializeEntity(m_Parent); + // Game::entityManager->SerializeEntity(m_Parent); } void MovingPlatformComponent::StopPathing() { //m_Parent->CancelCallbackTimers(); - auto* subComponent = static_cast(m_MoverSubComponent); + // auto* subComponent = static_cast(m_MoverSubComponent); - m_PathingStopped = true; + // m_PathingStopped = true; - subComponent->mState = eMovementPlatformState::Stopped; - subComponent->mDesiredWaypointIndex = -1; - subComponent->mShouldStopAtDesiredWaypoint = false; + // subComponent->mState = eMovementPlatformState::Stopped; + // subComponent->mDesiredWaypointIndex = -1; + // subComponent->mShouldStopAtDesiredWaypoint = false; - Game::entityManager->SerializeEntity(m_Parent); + // Game::entityManager->SerializeEntity(m_Parent); //GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS); } void MovingPlatformComponent::SetSerialized(bool value) { - m_Serialize = value; + // m_Serialize = value; } bool MovingPlatformComponent::GetNoAutoStart() const { - return m_NoAutoStart; + return false; + // return m_NoAutoStart; } void MovingPlatformComponent::SetNoAutoStart(const bool value) { - m_NoAutoStart = value; + // m_NoAutoStart = value; } void MovingPlatformComponent::WarpToWaypoint(size_t index) { - const auto& waypoint = m_Path->pathWaypoints[index]; + // const auto& waypoint = m_Path->pathWaypoints[index]; - m_Parent->SetPosition(waypoint.position); - m_Parent->SetRotation(waypoint.rotation); + // m_Parent->SetPosition(waypoint.position); + // m_Parent->SetRotation(waypoint.rotation); - Game::entityManager->SerializeEntity(m_Parent); + // Game::entityManager->SerializeEntity(m_Parent); } size_t MovingPlatformComponent::GetLastWaypointIndex() const { - return m_Path->pathWaypoints.size() - 1; -} - -MoverSubComponent* MovingPlatformComponent::GetMoverSubComponent() const { - return static_cast(m_MoverSubComponent); + return 0; + // return m_Path->pathWaypoints.size() - 1; } diff --git a/dGame/dComponents/MovingPlatformComponent.h b/dGame/dComponents/MovingPlatformComponent.h index 9e4c1ecfe..06957fbc0 100644 --- a/dGame/dComponents/MovingPlatformComponent.h +++ b/dGame/dComponents/MovingPlatformComponent.h @@ -6,96 +6,82 @@ #ifndef MOVINGPLATFORMCOMPONENT_H #define MOVINGPLATFORMCOMPONENT_H -#include "RakNetTypes.h" #include "NiPoint3.h" +#include #include +#include #include "dCommonVars.h" -#include "EntityManager.h" #include "Component.h" #include "eMovementPlatformState.h" #include "eReplicaComponentType.h" class Path; - /** - * Different types of available platforms - */ +/** + * Different types of available platforms + */ enum class eMoverSubComponentType : uint32_t { - mover = 4, - - /** - * Used in NJ - */ - simpleMover = 5, + None = 0, + Mover = 4, + SimpleMover = 5, + Rotator = 6 }; -/** - * Sub component for moving platforms that determine the actual current movement state - */ -class MoverSubComponent { +class PlatformSubComponent { public: - MoverSubComponent(const NiPoint3& startPos); - ~MoverSubComponent(); - - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) const; - + PlatformSubComponent(); + virtual ~PlatformSubComponent() = default; + virtual void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate); + virtual eMoverSubComponentType GetPlatformType() { return eMoverSubComponentType::None; }; + bool GetIsDirty() const { return m_IsDirty; } +protected: + +#ifdef _MOVING_PLATFORM_TEST +public: +#endif /** * The state the platform is currently in */ - eMovementPlatformState mState = eMovementPlatformState::Stationary; - - /** - * The waypoint this platform currently wants to traverse to - */ - int32_t mDesiredWaypointIndex = 0; - - /** - * Whether the platform is currently reversing away from the desired waypoint - */ - bool mInReverse = false; - - /** - * Whether the platform should stop moving when reaching the desired waypoint - */ - bool mShouldStopAtDesiredWaypoint = false; - - /** - * The percentage of the way between the last point and the desired point - */ - float mPercentBetweenPoints = 0; - - /** - * The current position of the platofrm - */ - NiPoint3 mPosition{}; - - /** - * The waypoint the platform is (was) at - */ - uint32_t mCurrentWaypointIndex; - - /** - * The waypoint the platform is attempting to go to - */ - uint32_t mNextWaypointIndex; - - /** - * The timer that handles the time before stopping idling and continue platform movement - */ - float mIdleTimeElapsed = 0; + eMovementPlatformState m_State = eMovementPlatformState::Stopped | eMovementPlatformState::ReachedDesiredWaypoint; + int32_t m_DesiredWaypointIndex = 0; + float m_PercentBetweenPoints = 0; + NiPoint3 m_Position; + uint32_t m_CurrentWaypointIndex; + uint32_t m_NextWaypointIndex; + float m_IdleTimeElapsed = 0; + float m_Speed = 0; + float m_WaitTime = 0; + float m_MoveTimeElapsed = 0; + bool m_IsDirty = false; + bool m_InReverse = false; + bool m_ShouldStopAtDesiredWaypoint = false; +}; - /** - * The speed the platform is currently moving at - */ - float mSpeed = 0; +class MoverPlatformSubComponent : public PlatformSubComponent { +public: + MoverPlatformSubComponent() : PlatformSubComponent() {}; + ~MoverPlatformSubComponent() override = default; + eMoverSubComponentType GetPlatformType() override { return eMoverSubComponentType::Mover; } + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override { PlatformSubComponent::Serialize(outBitStream, bIsInitialUpdate); }; +}; - /** - * The time to wait before continuing movement - */ - float mWaitTime = 0; +class RotatorPlatformSubComponent : public PlatformSubComponent { +public: + RotatorPlatformSubComponent() : PlatformSubComponent() {}; + ~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. +class SimpleMoverPlatformSubComponent : public PlatformSubComponent { +public: + SimpleMoverPlatformSubComponent() : PlatformSubComponent() {}; + ~SimpleMoverPlatformSubComponent() override = default; + eMoverSubComponentType GetPlatformType() override { return eMoverSubComponentType::SimpleMover; } + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override { PlatformSubComponent::Serialize(outBitStream, bIsInitialUpdate); }; +}; /** * Represents entities that may be moving platforms, indicating how they should move through the world. @@ -109,7 +95,6 @@ class MovingPlatformComponent : public Component { static const eReplicaComponentType ComponentType = eReplicaComponentType::MOVING_PLATFORM; MovingPlatformComponent(Entity* parent, const std::string& pathName); - ~MovingPlatformComponent() override; void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); @@ -181,19 +166,22 @@ class MovingPlatformComponent : public Component { */ size_t GetLastWaypointIndex() const; +#ifdef _MOVING_PLATFORM_TEST /** - * Returns the sub component that actually defines how the platform moves around (speeds, etc). - * @return the sub component that actually defines how the platform moves around + * Only used for testing. Do not call in production code. Let the constructor take care of this. + * + * @param platformSubComponent */ - MoverSubComponent* GetMoverSubComponent() const; + void _AddPlatformSubComponent(std::unique_ptr platformSubComponent) { + m_Platforms.push_back(std::move(platformSubComponent)); + } + void _SetPath(const std::u16string& path) { + m_PathName = path; + m_DirtyPathInfo = true; + } +#endif private: - - /** - * The path this platform is currently on - */ - const Path* m_Path = nullptr; - /** * The name of the path this platform is currently on */ @@ -204,15 +192,10 @@ class MovingPlatformComponent : public Component { */ bool m_PathingStopped = false; - /** - * The type of the subcomponent - */ - eMoverSubComponentType m_MoverSubComponentType; - /** * The mover sub component that belongs to this platform */ - void* m_MoverSubComponent; + std::vector> m_Platforms; /** * Whether the platform shouldn't auto start @@ -223,6 +206,8 @@ class MovingPlatformComponent : public Component { * Whether to serialize the entity on the next update */ bool m_Serialize = false; + + bool m_DirtyPathInfo = false; }; #endif // MOVINGPLATFORMCOMPONENT_H diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 8d8085a9e..ef9bea483 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -362,7 +362,7 @@ void GameMessages::SendPlatformResync(Entity* entity, const SystemAddress& sysAd iIndex = 0; nextIndex = 0; bStopAtDesiredWaypoint = true; - movementState = eMovementPlatformState::Stationary; + movementState = eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint; } bitStream.Write(entity->GetObjectID()); diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index bd1224d3b..695d82097 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -71,7 +71,7 @@ namespace GameMessages { void SendStartPathing(Entity* entity); void SendPlatformResync(Entity* entity, const SystemAddress& sysAddr, bool bStopAtDesiredWaypoint = false, int iIndex = 0, int iDesiredWaypointIndex = 1, int nextIndex = 1, - eMovementPlatformState movementState = eMovementPlatformState::Moving); + eMovementPlatformState movementState = eMovementPlatformState::Travelling); void SendRestoreToPostLoadStats(Entity* entity, const SystemAddress& sysAddr); void SendServerDoneLoadingAllObjects(Entity* entity, const SystemAddress& sysAddr); diff --git a/dScripts/02_server/Map/General/PropertyPlatform.cpp b/dScripts/02_server/Map/General/PropertyPlatform.cpp index 7016db94c..b831bf489 100644 --- a/dScripts/02_server/Map/General/PropertyPlatform.cpp +++ b/dScripts/02_server/Map/General/PropertyPlatform.cpp @@ -4,24 +4,15 @@ #include "MovingPlatformComponent.h" void PropertyPlatform::OnRebuildComplete(Entity* self, Entity* target) { - // auto* movingPlatform = self->GetComponent(); - // if (movingPlatform != nullptr) { - // movingPlatform->StopPathing(); - // movingPlatform->SetNoAutoStart(true); - // } GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0, - 0, 0, eMovementPlatformState::Stationary); + 0, 0, eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint); } void PropertyPlatform::OnUse(Entity* self, Entity* user) { auto* rebuildComponent = self->GetComponent(); if (rebuildComponent != nullptr && rebuildComponent->GetState() == eRebuildState::COMPLETED) { - // auto* movingPlatform = self->GetComponent(); - // if (movingPlatform != nullptr) { - // movingPlatform->GotoWaypoint(1); - // } GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0, - 1, 1, eMovementPlatformState::Moving); + 1, 1, eMovementPlatformState::Travelling); self->AddCallbackTimer(movementDelay + effectDelay, [self, this]() { self->SetNetworkVar(u"startEffect", dieDelay); diff --git a/dScripts/ai/AG/AgQbElevator.cpp b/dScripts/ai/AG/AgQbElevator.cpp index 5a5353475..b39d31984 100644 --- a/dScripts/ai/AG/AgQbElevator.cpp +++ b/dScripts/ai/AG/AgQbElevator.cpp @@ -15,7 +15,7 @@ void AgQbElevator::OnRebuildComplete(Entity* self, Entity* target) { if (delayTime < 1) delayTime = 1; GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0, - 0, 0, eMovementPlatformState::Stationary); + 0, 0, eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint); //add a timer that will kill the QB if no players get on in the killTime self->AddTimer("startKillTimer", killTime); @@ -33,7 +33,7 @@ void AgQbElevator::OnProximityUpdate(Entity* self, Entity* entering, std::string self->CancelTimer("StartElevator"); GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0, - 1, 1, eMovementPlatformState::Moving); + 1, 1, eMovementPlatformState::Travelling); } else if (!self->GetBoolean(u"StartTimer")) { self->SetBoolean(u"StartTimer", true); self->AddTimer("StartElevator", startTime); @@ -45,7 +45,7 @@ void AgQbElevator::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "StartElevator") { GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0, - 1, 1, eMovementPlatformState::Moving); + 1, 1, eMovementPlatformState::Travelling); } else if (timerName == "startKillTimer") { killTimerStartup(self); } else if (timerName == "KillTimer") { diff --git a/tests/dGameTests/dComponentsTests/CMakeLists.txt b/tests/dGameTests/dComponentsTests/CMakeLists.txt index 17e69a2f7..9441c8cba 100644 --- a/tests/dGameTests/dComponentsTests/CMakeLists.txt +++ b/tests/dGameTests/dComponentsTests/CMakeLists.txt @@ -1,5 +1,6 @@ set(DCOMPONENTS_TESTS "DestroyableComponentTests.cpp" + "MovingPlatformComponentTests.cpp" ) # Get the folder name and prepend it to the files above diff --git a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp new file mode 100644 index 000000000..d055e88ad --- /dev/null +++ b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp @@ -0,0 +1,158 @@ +#include "GameDependencies.h" +#include + +#include "BitStream.h" +#include "Entity.h" + +#define _MOVING_PLATFORM_TEST +#include "MovingPlatformComponent.h" +#undef _MOVING_PLATFORM_TEST +#include "eReplicaComponentType.h" + +class MovingPlatformComponentTests : public GameDependenciesTest { +protected: + std::unique_ptr baseEntity; + CBITSTREAM; + uint32_t flags = 0; + void SetUp() override { + SetUpDependencies(); + baseEntity = std::make_unique(15, GameDependenciesTest::info); + auto* movingPlatformComponent = new MovingPlatformComponent(baseEntity.get(), ""); + baseEntity->AddComponent(eReplicaComponentType::MOVING_PLATFORM, movingPlatformComponent); + auto moverPlatformSubComponent = std::make_unique(); + moverPlatformSubComponent->m_State = eMovementPlatformState::Stopped | eMovementPlatformState::ReachedDesiredWaypoint; + moverPlatformSubComponent->m_DesiredWaypointIndex = 1; + moverPlatformSubComponent->m_PercentBetweenPoints = 2; + moverPlatformSubComponent->m_Position = NiPoint3(3, 4, 5); + moverPlatformSubComponent->m_CurrentWaypointIndex = 6; + moverPlatformSubComponent->m_NextWaypointIndex = 7; + moverPlatformSubComponent->m_IdleTimeElapsed = 8; + moverPlatformSubComponent->m_MoveTimeElapsed = 11; + moverPlatformSubComponent->m_IsDirty = true; + moverPlatformSubComponent->m_InReverse = true; + moverPlatformSubComponent->m_ShouldStopAtDesiredWaypoint = true; + + auto rotatorPlatformSubComponent = std::make_unique(); + rotatorPlatformSubComponent->m_State = eMovementPlatformState::Travelling; + rotatorPlatformSubComponent->m_DesiredWaypointIndex = 12; + rotatorPlatformSubComponent->m_PercentBetweenPoints = 13; + rotatorPlatformSubComponent->m_Position = NiPoint3(14, 15, 16); + rotatorPlatformSubComponent->m_CurrentWaypointIndex = 17; + rotatorPlatformSubComponent->m_NextWaypointIndex = 18; + rotatorPlatformSubComponent->m_IdleTimeElapsed = 19; + rotatorPlatformSubComponent->m_MoveTimeElapsed = 22; + rotatorPlatformSubComponent->m_IsDirty = true; + rotatorPlatformSubComponent->m_InReverse = true; + rotatorPlatformSubComponent->m_ShouldStopAtDesiredWaypoint = true; + + auto simpleMoverPlatformSubComponent = std::make_unique(); + simpleMoverPlatformSubComponent->m_State = eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint; + simpleMoverPlatformSubComponent->m_DesiredWaypointIndex = 23; + simpleMoverPlatformSubComponent->m_PercentBetweenPoints = 24; + simpleMoverPlatformSubComponent->m_Position = NiPoint3(25, 26, 27); + simpleMoverPlatformSubComponent->m_CurrentWaypointIndex = 28; + simpleMoverPlatformSubComponent->m_NextWaypointIndex = 29; + simpleMoverPlatformSubComponent->m_IdleTimeElapsed = 30; + simpleMoverPlatformSubComponent->m_MoveTimeElapsed = 33; + simpleMoverPlatformSubComponent->m_IsDirty = true; + simpleMoverPlatformSubComponent->m_InReverse = true; + simpleMoverPlatformSubComponent->m_ShouldStopAtDesiredWaypoint = true; + + movingPlatformComponent->_AddPlatformSubComponent(std::move(moverPlatformSubComponent)); + movingPlatformComponent->_AddPlatformSubComponent(std::move(rotatorPlatformSubComponent)); + movingPlatformComponent->_AddPlatformSubComponent(std::move(simpleMoverPlatformSubComponent)); + movingPlatformComponent->_SetPath(u"ExamplePath"); + } + + void TearDown() override { + TearDownDependencies(); + } +}; + +TEST_F(MovingPlatformComponentTests, MovingPlatformConstructionTest) { + auto* movingPlatformComponent = baseEntity->GetComponent(); + ASSERT_NE(movingPlatformComponent, nullptr); + uint32_t flags = 0; + movingPlatformComponent->Serialize(&bitStream, true, flags); + // read in the full BitStream and check the values match what they were set to above + bool hasPlatformSubComponents = false; + bitStream.Read(hasPlatformSubComponents); + ASSERT_TRUE(hasPlatformSubComponents); + + bool dirtyPathInfo; + bitStream.Read(dirtyPathInfo); + ASSERT_TRUE(dirtyPathInfo); + + bool hasPath; + bitStream.Read(hasPath); + ASSERT_TRUE(hasPath); + + std::u16string pathName; + uint16_t pathNameLength; + bitStream.Read(pathNameLength); + pathName.resize(pathNameLength); + bitStream.ReadBits(reinterpret_cast(pathName.data()), BYTES_TO_BITS(pathNameLength) * 2); + ASSERT_EQ(pathName, u"ExamplePath"); + + uint32_t pathStartIndex; + bitStream.Read(pathStartIndex); + ASSERT_EQ(pathStartIndex, 1); + + bool isInReverse; + bitStream.Read(isInReverse); + ASSERT_TRUE(isInReverse); + + bool hasPlatformData; + bitStream.Read(hasPlatformData); + ASSERT_TRUE(hasPlatformData); + + eMoverSubComponentType platformType; + bitStream.Read(platformType); + ASSERT_EQ(platformType, eMoverSubComponentType::Mover); + + bool isDirty; + bitStream.Read(isDirty); + ASSERT_TRUE(isDirty); + + eMovementPlatformState state; + bitStream.Read(state); + ASSERT_EQ(state, eMovementPlatformState::Stopped | eMovementPlatformState::ReachedDesiredWaypoint); + + int32_t desiredWaypointIndex; + bitStream.Read(desiredWaypointIndex); + ASSERT_EQ(desiredWaypointIndex, 1); + + bool shouldStopAtDesiredWaypoint; + bitStream.Read(shouldStopAtDesiredWaypoint); + ASSERT_TRUE(shouldStopAtDesiredWaypoint); + + bool isInReverse2; + bitStream.Read(isInReverse2); + ASSERT_TRUE(isInReverse2); + + float percentBetweenPoints; + bitStream.Read(percentBetweenPoints); + ASSERT_EQ(percentBetweenPoints, 2); + + NiPoint3 position; + bitStream.Read(position.x); + bitStream.Read(position.y); + bitStream.Read(position.z); + ASSERT_EQ(position, NiPoint3(3, 4, 5)); + + uint32_t currentWaypointIndex; + bitStream.Read(currentWaypointIndex); + ASSERT_EQ(currentWaypointIndex, 6); + + uint32_t nextWaypointIndex; + bitStream.Read(nextWaypointIndex); + ASSERT_EQ(nextWaypointIndex, 7); + + float idleTimeElapsed; + bitStream.Read(idleTimeElapsed); + ASSERT_EQ(idleTimeElapsed, 8); + + float moveTimeElapsed; + bitStream.Read(moveTimeElapsed); + ASSERT_EQ(moveTimeElapsed, 11); +} From a7eb28279e239ef57e09e3a90fb584bfb7e92c9a Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Mon, 31 Jul 2023 18:36:14 -0700 Subject: [PATCH 02/17] finish construction serialization test --- .../MovingPlatformComponentTests.cpp | 114 +++++++++++++++++- 1 file changed, 113 insertions(+), 1 deletion(-) diff --git a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp index d055e88ad..0d8290c69 100644 --- a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp @@ -154,5 +154,117 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformConstructionTest) { float moveTimeElapsed; bitStream.Read(moveTimeElapsed); - ASSERT_EQ(moveTimeElapsed, 11); + ASSERT_EQ(moveTimeElapsed, 11); + + bool hasPlatformData2; + bitStream.Read(hasPlatformData2); + ASSERT_TRUE(hasPlatformData2); + + eMoverSubComponentType platformType2; + bitStream.Read(platformType2); + ASSERT_EQ(platformType2, eMoverSubComponentType::Rotator); + + bool isDirty2; + bitStream.Read(isDirty2); + ASSERT_TRUE(isDirty2); + + eMovementPlatformState state2; + bitStream.Read(state2); + ASSERT_EQ(state2, eMovementPlatformState::Travelling); + + int32_t desiredWaypointIndex2; + bitStream.Read(desiredWaypointIndex2); + ASSERT_EQ(desiredWaypointIndex2, 12); + + bool shouldStopAtDesiredWaypoint2; + bitStream.Read(shouldStopAtDesiredWaypoint2); + ASSERT_TRUE(shouldStopAtDesiredWaypoint2); + + bool isInReverse3; + bitStream.Read(isInReverse3); + ASSERT_TRUE(isInReverse3); + + float percentBetweenPoints2; + bitStream.Read(percentBetweenPoints2); + ASSERT_EQ(percentBetweenPoints2, 13); + + NiPoint3 position2; + bitStream.Read(position2.x); + bitStream.Read(position2.y); + bitStream.Read(position2.z); + ASSERT_EQ(position2, NiPoint3(14, 15, 16)); + + uint32_t currentWaypointIndex2; + bitStream.Read(currentWaypointIndex2); + ASSERT_EQ(currentWaypointIndex2, 17); + + uint32_t nextWaypointIndex2; + bitStream.Read(nextWaypointIndex2); + ASSERT_EQ(nextWaypointIndex2, 18); + + float idleTimeElapsed2; + bitStream.Read(idleTimeElapsed2); + ASSERT_EQ(idleTimeElapsed2, 19); + + float moveTimeElapsed2; + bitStream.Read(moveTimeElapsed2); + ASSERT_EQ(moveTimeElapsed2, 22); + + bool hasPlatformData3; + bitStream.Read(hasPlatformData3); + ASSERT_TRUE(hasPlatformData3); + + eMoverSubComponentType platformType3; + bitStream.Read(platformType3); + ASSERT_EQ(platformType3, eMoverSubComponentType::SimpleMover); + + bool isDirty3; + bitStream.Read(isDirty3); + ASSERT_TRUE(isDirty3); + + eMovementPlatformState state3; + bitStream.Read(state3); + ASSERT_EQ(state3, eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint); + + int32_t desiredWaypointIndex3; + bitStream.Read(desiredWaypointIndex3); + ASSERT_EQ(desiredWaypointIndex3, 23); + + bool shouldStopAtDesiredWaypoint3; + bitStream.Read(shouldStopAtDesiredWaypoint3); + ASSERT_TRUE(shouldStopAtDesiredWaypoint3); + + bool isInReverse4; + bitStream.Read(isInReverse4); + ASSERT_TRUE(isInReverse4); + + float percentBetweenPoints3; + bitStream.Read(percentBetweenPoints3); + ASSERT_EQ(percentBetweenPoints3, 24); + + NiPoint3 position3; + bitStream.Read(position3.x); + bitStream.Read(position3.y); + bitStream.Read(position3.z); + ASSERT_EQ(position3, NiPoint3(25, 26, 27)); + + uint32_t currentWaypointIndex3; + bitStream.Read(currentWaypointIndex3); + ASSERT_EQ(currentWaypointIndex3, 28); + + uint32_t nextWaypointIndex3; + bitStream.Read(nextWaypointIndex3); + ASSERT_EQ(nextWaypointIndex3, 29); + + float idleTimeElapsed3; + bitStream.Read(idleTimeElapsed3); + ASSERT_EQ(idleTimeElapsed3, 30); + + float moveTimeElapsed3; + bitStream.Read(moveTimeElapsed3); + ASSERT_EQ(moveTimeElapsed3, 33); + + bool hasPlatformSubComponents2; + bitStream.Read(hasPlatformSubComponents2); + ASSERT_FALSE(hasPlatformSubComponents2); } From ba409b6ee2fdd2204ae19c7a660fa49b91d0f8b0 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Mon, 31 Jul 2023 18:38:26 -0700 Subject: [PATCH 03/17] add serialization test --- .../MovingPlatformComponentTests.cpp | 406 +++++++++--------- 1 file changed, 207 insertions(+), 199 deletions(-) diff --git a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp index 0d8290c69..35e2f55b3 100644 --- a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp @@ -31,7 +31,7 @@ class MovingPlatformComponentTests : public GameDependenciesTest { moverPlatformSubComponent->m_IsDirty = true; moverPlatformSubComponent->m_InReverse = true; moverPlatformSubComponent->m_ShouldStopAtDesiredWaypoint = true; - + auto rotatorPlatformSubComponent = std::make_unique(); rotatorPlatformSubComponent->m_State = eMovementPlatformState::Travelling; rotatorPlatformSubComponent->m_DesiredWaypointIndex = 12; @@ -44,7 +44,7 @@ class MovingPlatformComponentTests : public GameDependenciesTest { rotatorPlatformSubComponent->m_IsDirty = true; rotatorPlatformSubComponent->m_InReverse = true; rotatorPlatformSubComponent->m_ShouldStopAtDesiredWaypoint = true; - + auto simpleMoverPlatformSubComponent = std::make_unique(); simpleMoverPlatformSubComponent->m_State = eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint; simpleMoverPlatformSubComponent->m_DesiredWaypointIndex = 23; @@ -67,204 +67,212 @@ class MovingPlatformComponentTests : public GameDependenciesTest { void TearDown() override { TearDownDependencies(); } + + void TestSerialization() { + auto* movingPlatformComponent = baseEntity->GetComponent(); + ASSERT_NE(movingPlatformComponent, nullptr); + uint32_t flags = 0; + movingPlatformComponent->Serialize(&bitStream, true, flags); + // read in the full BitStream and check the values match what they were set to above + bool hasPlatformSubComponents = false; + bitStream.Read(hasPlatformSubComponents); + ASSERT_TRUE(hasPlatformSubComponents); + + bool dirtyPathInfo; + bitStream.Read(dirtyPathInfo); + ASSERT_TRUE(dirtyPathInfo); + + bool hasPath; + bitStream.Read(hasPath); + ASSERT_TRUE(hasPath); + + std::u16string pathName; + uint16_t pathNameLength; + bitStream.Read(pathNameLength); + pathName.resize(pathNameLength); + bitStream.ReadBits(reinterpret_cast(pathName.data()), BYTES_TO_BITS(pathNameLength) * 2); + ASSERT_EQ(pathName, u"ExamplePath"); + + uint32_t pathStartIndex; + bitStream.Read(pathStartIndex); + ASSERT_EQ(pathStartIndex, 1); + + bool isInReverse; + bitStream.Read(isInReverse); + ASSERT_TRUE(isInReverse); + + bool hasPlatformData; + bitStream.Read(hasPlatformData); + ASSERT_TRUE(hasPlatformData); + + eMoverSubComponentType platformType; + bitStream.Read(platformType); + ASSERT_EQ(platformType, eMoverSubComponentType::Mover); + + bool isDirty; + bitStream.Read(isDirty); + ASSERT_TRUE(isDirty); + + eMovementPlatformState state; + bitStream.Read(state); + ASSERT_EQ(state, eMovementPlatformState::Stopped | eMovementPlatformState::ReachedDesiredWaypoint); + + int32_t desiredWaypointIndex; + bitStream.Read(desiredWaypointIndex); + ASSERT_EQ(desiredWaypointIndex, 1); + + bool shouldStopAtDesiredWaypoint; + bitStream.Read(shouldStopAtDesiredWaypoint); + ASSERT_TRUE(shouldStopAtDesiredWaypoint); + + bool isInReverse2; + bitStream.Read(isInReverse2); + ASSERT_TRUE(isInReverse2); + + float percentBetweenPoints; + bitStream.Read(percentBetweenPoints); + ASSERT_EQ(percentBetweenPoints, 2); + + NiPoint3 position; + bitStream.Read(position.x); + bitStream.Read(position.y); + bitStream.Read(position.z); + ASSERT_EQ(position, NiPoint3(3, 4, 5)); + + uint32_t currentWaypointIndex; + bitStream.Read(currentWaypointIndex); + ASSERT_EQ(currentWaypointIndex, 6); + + uint32_t nextWaypointIndex; + bitStream.Read(nextWaypointIndex); + ASSERT_EQ(nextWaypointIndex, 7); + + float idleTimeElapsed; + bitStream.Read(idleTimeElapsed); + ASSERT_EQ(idleTimeElapsed, 8); + + float moveTimeElapsed; + bitStream.Read(moveTimeElapsed); + ASSERT_EQ(moveTimeElapsed, 11); + + bool hasPlatformData2; + bitStream.Read(hasPlatformData2); + ASSERT_TRUE(hasPlatformData2); + + eMoverSubComponentType platformType2; + bitStream.Read(platformType2); + ASSERT_EQ(platformType2, eMoverSubComponentType::Rotator); + + bool isDirty2; + bitStream.Read(isDirty2); + ASSERT_TRUE(isDirty2); + + eMovementPlatformState state2; + bitStream.Read(state2); + ASSERT_EQ(state2, eMovementPlatformState::Travelling); + + int32_t desiredWaypointIndex2; + bitStream.Read(desiredWaypointIndex2); + ASSERT_EQ(desiredWaypointIndex2, 12); + + bool shouldStopAtDesiredWaypoint2; + bitStream.Read(shouldStopAtDesiredWaypoint2); + ASSERT_TRUE(shouldStopAtDesiredWaypoint2); + + bool isInReverse3; + bitStream.Read(isInReverse3); + ASSERT_TRUE(isInReverse3); + + float percentBetweenPoints2; + bitStream.Read(percentBetweenPoints2); + ASSERT_EQ(percentBetweenPoints2, 13); + + NiPoint3 position2; + bitStream.Read(position2.x); + bitStream.Read(position2.y); + bitStream.Read(position2.z); + ASSERT_EQ(position2, NiPoint3(14, 15, 16)); + + uint32_t currentWaypointIndex2; + bitStream.Read(currentWaypointIndex2); + ASSERT_EQ(currentWaypointIndex2, 17); + + uint32_t nextWaypointIndex2; + bitStream.Read(nextWaypointIndex2); + ASSERT_EQ(nextWaypointIndex2, 18); + + float idleTimeElapsed2; + bitStream.Read(idleTimeElapsed2); + ASSERT_EQ(idleTimeElapsed2, 19); + + float moveTimeElapsed2; + bitStream.Read(moveTimeElapsed2); + ASSERT_EQ(moveTimeElapsed2, 22); + + bool hasPlatformData3; + bitStream.Read(hasPlatformData3); + ASSERT_TRUE(hasPlatformData3); + + eMoverSubComponentType platformType3; + bitStream.Read(platformType3); + ASSERT_EQ(platformType3, eMoverSubComponentType::SimpleMover); + + bool isDirty3; + bitStream.Read(isDirty3); + ASSERT_TRUE(isDirty3); + + eMovementPlatformState state3; + bitStream.Read(state3); + ASSERT_EQ(state3, eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint); + + int32_t desiredWaypointIndex3; + bitStream.Read(desiredWaypointIndex3); + ASSERT_EQ(desiredWaypointIndex3, 23); + + bool shouldStopAtDesiredWaypoint3; + bitStream.Read(shouldStopAtDesiredWaypoint3); + ASSERT_TRUE(shouldStopAtDesiredWaypoint3); + + bool isInReverse4; + bitStream.Read(isInReverse4); + ASSERT_TRUE(isInReverse4); + + float percentBetweenPoints3; + bitStream.Read(percentBetweenPoints3); + ASSERT_EQ(percentBetweenPoints3, 24); + + NiPoint3 position3; + bitStream.Read(position3.x); + bitStream.Read(position3.y); + bitStream.Read(position3.z); + ASSERT_EQ(position3, NiPoint3(25, 26, 27)); + + uint32_t currentWaypointIndex3; + bitStream.Read(currentWaypointIndex3); + ASSERT_EQ(currentWaypointIndex3, 28); + + uint32_t nextWaypointIndex3; + bitStream.Read(nextWaypointIndex3); + ASSERT_EQ(nextWaypointIndex3, 29); + + float idleTimeElapsed3; + bitStream.Read(idleTimeElapsed3); + ASSERT_EQ(idleTimeElapsed3, 30); + + float moveTimeElapsed3; + bitStream.Read(moveTimeElapsed3); + ASSERT_EQ(moveTimeElapsed3, 33); + + bool hasPlatformSubComponents2; + bitStream.Read(hasPlatformSubComponents2); + ASSERT_FALSE(hasPlatformSubComponents2); + } }; TEST_F(MovingPlatformComponentTests, MovingPlatformConstructionTest) { - auto* movingPlatformComponent = baseEntity->GetComponent(); - ASSERT_NE(movingPlatformComponent, nullptr); - uint32_t flags = 0; - movingPlatformComponent->Serialize(&bitStream, true, flags); - // read in the full BitStream and check the values match what they were set to above - bool hasPlatformSubComponents = false; - bitStream.Read(hasPlatformSubComponents); - ASSERT_TRUE(hasPlatformSubComponents); - - bool dirtyPathInfo; - bitStream.Read(dirtyPathInfo); - ASSERT_TRUE(dirtyPathInfo); - - bool hasPath; - bitStream.Read(hasPath); - ASSERT_TRUE(hasPath); - - std::u16string pathName; - uint16_t pathNameLength; - bitStream.Read(pathNameLength); - pathName.resize(pathNameLength); - bitStream.ReadBits(reinterpret_cast(pathName.data()), BYTES_TO_BITS(pathNameLength) * 2); - ASSERT_EQ(pathName, u"ExamplePath"); - - uint32_t pathStartIndex; - bitStream.Read(pathStartIndex); - ASSERT_EQ(pathStartIndex, 1); - - bool isInReverse; - bitStream.Read(isInReverse); - ASSERT_TRUE(isInReverse); - - bool hasPlatformData; - bitStream.Read(hasPlatformData); - ASSERT_TRUE(hasPlatformData); - - eMoverSubComponentType platformType; - bitStream.Read(platformType); - ASSERT_EQ(platformType, eMoverSubComponentType::Mover); - - bool isDirty; - bitStream.Read(isDirty); - ASSERT_TRUE(isDirty); - - eMovementPlatformState state; - bitStream.Read(state); - ASSERT_EQ(state, eMovementPlatformState::Stopped | eMovementPlatformState::ReachedDesiredWaypoint); - - int32_t desiredWaypointIndex; - bitStream.Read(desiredWaypointIndex); - ASSERT_EQ(desiredWaypointIndex, 1); - - bool shouldStopAtDesiredWaypoint; - bitStream.Read(shouldStopAtDesiredWaypoint); - ASSERT_TRUE(shouldStopAtDesiredWaypoint); - - bool isInReverse2; - bitStream.Read(isInReverse2); - ASSERT_TRUE(isInReverse2); - - float percentBetweenPoints; - bitStream.Read(percentBetweenPoints); - ASSERT_EQ(percentBetweenPoints, 2); - - NiPoint3 position; - bitStream.Read(position.x); - bitStream.Read(position.y); - bitStream.Read(position.z); - ASSERT_EQ(position, NiPoint3(3, 4, 5)); - - uint32_t currentWaypointIndex; - bitStream.Read(currentWaypointIndex); - ASSERT_EQ(currentWaypointIndex, 6); - - uint32_t nextWaypointIndex; - bitStream.Read(nextWaypointIndex); - ASSERT_EQ(nextWaypointIndex, 7); - - float idleTimeElapsed; - bitStream.Read(idleTimeElapsed); - ASSERT_EQ(idleTimeElapsed, 8); - - float moveTimeElapsed; - bitStream.Read(moveTimeElapsed); - ASSERT_EQ(moveTimeElapsed, 11); - - bool hasPlatformData2; - bitStream.Read(hasPlatformData2); - ASSERT_TRUE(hasPlatformData2); - - eMoverSubComponentType platformType2; - bitStream.Read(platformType2); - ASSERT_EQ(platformType2, eMoverSubComponentType::Rotator); - - bool isDirty2; - bitStream.Read(isDirty2); - ASSERT_TRUE(isDirty2); - - eMovementPlatformState state2; - bitStream.Read(state2); - ASSERT_EQ(state2, eMovementPlatformState::Travelling); - - int32_t desiredWaypointIndex2; - bitStream.Read(desiredWaypointIndex2); - ASSERT_EQ(desiredWaypointIndex2, 12); - - bool shouldStopAtDesiredWaypoint2; - bitStream.Read(shouldStopAtDesiredWaypoint2); - ASSERT_TRUE(shouldStopAtDesiredWaypoint2); - - bool isInReverse3; - bitStream.Read(isInReverse3); - ASSERT_TRUE(isInReverse3); - - float percentBetweenPoints2; - bitStream.Read(percentBetweenPoints2); - ASSERT_EQ(percentBetweenPoints2, 13); - - NiPoint3 position2; - bitStream.Read(position2.x); - bitStream.Read(position2.y); - bitStream.Read(position2.z); - ASSERT_EQ(position2, NiPoint3(14, 15, 16)); - - uint32_t currentWaypointIndex2; - bitStream.Read(currentWaypointIndex2); - ASSERT_EQ(currentWaypointIndex2, 17); - - uint32_t nextWaypointIndex2; - bitStream.Read(nextWaypointIndex2); - ASSERT_EQ(nextWaypointIndex2, 18); - - float idleTimeElapsed2; - bitStream.Read(idleTimeElapsed2); - ASSERT_EQ(idleTimeElapsed2, 19); - - float moveTimeElapsed2; - bitStream.Read(moveTimeElapsed2); - ASSERT_EQ(moveTimeElapsed2, 22); - - bool hasPlatformData3; - bitStream.Read(hasPlatformData3); - ASSERT_TRUE(hasPlatformData3); - - eMoverSubComponentType platformType3; - bitStream.Read(platformType3); - ASSERT_EQ(platformType3, eMoverSubComponentType::SimpleMover); - - bool isDirty3; - bitStream.Read(isDirty3); - ASSERT_TRUE(isDirty3); - - eMovementPlatformState state3; - bitStream.Read(state3); - ASSERT_EQ(state3, eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint); - - int32_t desiredWaypointIndex3; - bitStream.Read(desiredWaypointIndex3); - ASSERT_EQ(desiredWaypointIndex3, 23); - - bool shouldStopAtDesiredWaypoint3; - bitStream.Read(shouldStopAtDesiredWaypoint3); - ASSERT_TRUE(shouldStopAtDesiredWaypoint3); - - bool isInReverse4; - bitStream.Read(isInReverse4); - ASSERT_TRUE(isInReverse4); - - float percentBetweenPoints3; - bitStream.Read(percentBetweenPoints3); - ASSERT_EQ(percentBetweenPoints3, 24); - - NiPoint3 position3; - bitStream.Read(position3.x); - bitStream.Read(position3.y); - bitStream.Read(position3.z); - ASSERT_EQ(position3, NiPoint3(25, 26, 27)); - - uint32_t currentWaypointIndex3; - bitStream.Read(currentWaypointIndex3); - ASSERT_EQ(currentWaypointIndex3, 28); - - uint32_t nextWaypointIndex3; - bitStream.Read(nextWaypointIndex3); - ASSERT_EQ(nextWaypointIndex3, 29); - - float idleTimeElapsed3; - bitStream.Read(idleTimeElapsed3); - ASSERT_EQ(idleTimeElapsed3, 30); - - float moveTimeElapsed3; - bitStream.Read(moveTimeElapsed3); - ASSERT_EQ(moveTimeElapsed3, 33); - - bool hasPlatformSubComponents2; - bitStream.Read(hasPlatformSubComponents2); - ASSERT_FALSE(hasPlatformSubComponents2); + TestSerialization(); +} + +TEST_F(MovingPlatformComponentTests, MovingPlatformSerializationTest) { + TestSerialization(); } From 43657324e9324ca3f53e949da6065a1efb5fe4f8 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Tue, 1 Aug 2023 01:19:07 -0700 Subject: [PATCH 04/17] Further work on subcomponents serialization is improved, next is re-implementing the actual functionality. --- dCommon/dEnums/eMovementPlatformState.h | 4 +- .../Tables/CDMovingPlatformComponentTable.cpp | 45 +++++++ .../Tables/CDMovingPlatformComponentTable.h | 27 ++++ dDatabase/Tables/CMakeLists.txt | 1 + dGame/dComponents/MovingPlatformComponent.cpp | 117 ++++++++++++++++-- dGame/dComponents/MovingPlatformComponent.h | 49 ++++++-- .../MovingPlatformComponentTests.cpp | 88 ++++++------- 7 files changed, 268 insertions(+), 63 deletions(-) create mode 100644 dDatabase/Tables/CDMovingPlatformComponentTable.cpp create mode 100644 dDatabase/Tables/CDMovingPlatformComponentTable.h diff --git a/dCommon/dEnums/eMovementPlatformState.h b/dCommon/dEnums/eMovementPlatformState.h index dc7a85cd2..f4e839384 100644 --- a/dCommon/dEnums/eMovementPlatformState.h +++ b/dCommon/dEnums/eMovementPlatformState.h @@ -16,7 +16,9 @@ enum class eMovementPlatformState : uint32_t }; inline constexpr eMovementPlatformState operator|(eMovementPlatformState a, eMovementPlatformState b) { - return static_cast(static_cast(a) | static_cast(b)); + return static_cast( + static_cast::type>(a) | + static_cast::type>(b)); }; #endif //!__EMOVEMENTPLATFORMSTATE__H__ diff --git a/dDatabase/Tables/CDMovingPlatformComponentTable.cpp b/dDatabase/Tables/CDMovingPlatformComponentTable.cpp new file mode 100644 index 000000000..af1aaa7a7 --- /dev/null +++ b/dDatabase/Tables/CDMovingPlatformComponentTable.cpp @@ -0,0 +1,45 @@ +#include "CDMovingPlatformComponentTable.h" + +CDMovingPlatformComponentTable::CDMovingPlatformComponentTable() { + auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MovementAIComponent"); + while (!tableData.eof()) { + CDMovingPlatformTableEntry entry; + entry.platformIsSimpleMover = tableData.getIntField("platformIsSimpleMover", 0) == 1; + entry.platformStartAtEnd = tableData.getIntField("platformStartAtEnd", 0) == 1; + entry.platformMove.x = tableData.getFloatField("platformMoveX", 0.0f); + entry.platformMove.y = tableData.getFloatField("platformMoveY", 0.0f); + entry.platformMove.z = tableData.getFloatField("platformMoveZ", 0.0f); + entry.moveTime = tableData.getFloatField("platformMoveTime", -1.0f); + + DluAssert(m_Platforms.insert(std::make_pair(tableData.getIntField("id", -1), entry)).second); + tableData.nextRow(); + } +} + +void CDMovingPlatformComponentTable::CachePlatformEntry(ComponentID id) { + auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM MovementAIComponent WHERE id = ?;"); + query.bind(1, static_cast(id)); + + auto tableData = query.execQuery(); + while (!tableData.eof()) { + CDMovingPlatformTableEntry entry; + entry.platformIsSimpleMover = tableData.getIntField("platformIsSimpleMover", 0) == 1; + entry.platformStartAtEnd = tableData.getIntField("platformStartAtEnd", 0) == 1; + entry.platformMove.x = tableData.getFloatField("platformMoveX", 0.0f); + entry.platformMove.y = tableData.getFloatField("platformMoveY", 0.0f); + entry.platformMove.z = tableData.getFloatField("platformMoveZ", 0.0f); + entry.moveTime = tableData.getFloatField("platformMoveTime", -1.0f); + + DluAssert(m_Platforms.insert(std::make_pair(tableData.getIntField("id", -1), entry)).second); + tableData.nextRow(); + } +} + +const std::optional CDMovingPlatformComponentTable::GetPlatformEntry(ComponentID id) { + auto itr = m_Platforms.find(id); + if (itr == m_Platforms.end()) { + CachePlatformEntry(id); + itr = m_Platforms.find(id); + } + return itr != m_Platforms.end() ? std::make_optional(itr->second) : std::nullopt; +} diff --git a/dDatabase/Tables/CDMovingPlatformComponentTable.h b/dDatabase/Tables/CDMovingPlatformComponentTable.h new file mode 100644 index 000000000..bcb1d12b1 --- /dev/null +++ b/dDatabase/Tables/CDMovingPlatformComponentTable.h @@ -0,0 +1,27 @@ +#ifndef __CDMOVINGPLATFORMCOMPONENTTABLE__H__ +#define __CDMOVINGPLATFORMCOMPONENTTABLE__H__ + +#include "CDTable.h" +#include "NiPoint3.h" + +#include + +typedef uint32_t ComponentID; + +struct CDMovingPlatformTableEntry { + NiPoint3 platformMove; + float moveTime; + bool platformIsSimpleMover; + bool platformStartAtEnd; +}; + +class CDMovingPlatformComponentTable : public CDTable { +public: + CDMovingPlatformComponentTable(); + + void CachePlatformEntry(ComponentID id); + const std::optional GetPlatformEntry(ComponentID id); +private: + std::map m_Platforms; +}; +#endif //!__CDMOVINGPLATFORMCOMPONENTTABLE__H__ diff --git a/dDatabase/Tables/CMakeLists.txt b/dDatabase/Tables/CMakeLists.txt index b6a02b02d..fafe8d582 100644 --- a/dDatabase/Tables/CMakeLists.txt +++ b/dDatabase/Tables/CMakeLists.txt @@ -16,6 +16,7 @@ set(DDATABASE_TABLES_SOURCES "CDActivitiesTable.cpp" "CDLevelProgressionLookupTable.cpp" "CDLootMatrixTable.cpp" "CDLootTableTable.cpp" + "CDMovingPlatformComponentTable.cpp" "CDMissionEmailTable.cpp" "CDMissionNPCComponentTable.cpp" "CDMissionsTable.cpp" diff --git a/dGame/dComponents/MovingPlatformComponent.cpp b/dGame/dComponents/MovingPlatformComponent.cpp index 758170564..e34f4d40f 100644 --- a/dGame/dComponents/MovingPlatformComponent.cpp +++ b/dGame/dComponents/MovingPlatformComponent.cpp @@ -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(u"dbonly")) return; + NiPoint3 platformMove( + m_ParentComponent->GetParent()->GetVar(u"platformMoveX"), + m_ParentComponent->GetParent()->GetVar(u"platformMoveY"), + m_ParentComponent->GetParent()->GetVar(u"platformMoveZ") + ); + m_PlatformMove = platformMove; + m_MoveTime = m_ParentComponent->GetParent()->GetVar(u"platformMoveTime"); + // idk either. client does it! + m_StartAtEnd = m_ParentComponent->GetParent()->GetVar(u"attached_path_start") != 0; + m_StartAtEnd = m_ParentComponent->GetParent()->GetVar(u"platformStartAtEnd"); +} + +void SimpleMoverPlatformSubComponent::LoadDataFromTemplate() { + if (!m_ParentComponent->GetParent()->GetVar(u"dbonly")) return; + + auto* movingPlatformTable = CDClientManager::Instance().GetTable(); + 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(u"platformIsSimpleMover")) { - m_Platforms.push_back(std::make_unique()); + AddMovingPlatform(NiPoint3::ZERO, false); } if (m_Parent->GetVar(u"platformIsMover")) { - m_Platforms.push_back(std::make_unique()); + AddMovingPlatform(); } if (m_Parent->GetVar(u"platformIsRotater")) { - m_Platforms.push_back(std::make_unique()); + AddMovingPlatform(); } 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(c)); } - outBitStream->Write(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 -------------- diff --git a/dGame/dComponents/MovingPlatformComponent.h b/dGame/dComponents/MovingPlatformComponent.h index 06957fbc0..343cae3b5 100644 --- a/dGame/dComponents/MovingPlatformComponent.h +++ b/dGame/dComponents/MovingPlatformComponent.h @@ -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 @@ class PlatformSubComponent { #ifdef _MOVING_PLATFORM_TEST public: #endif + MovingPlatformComponent* m_ParentComponent = nullptr; /** * The state the platform is currently in */ @@ -60,27 +63,38 @@ class PlatformSubComponent { 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 @@ class MovingPlatformComponent : public Component { MovingPlatformComponent(Entity* parent, const std::string& pathName); + void LoadConfigData(); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); /** @@ -166,6 +182,19 @@ class MovingPlatformComponent : public Component { */ size_t GetLastWaypointIndex() const; + template + void AddMovingPlatform(ConstructorValues... arguments) { + static_assert(std::is_base_of::value, "MovingPlatform must derive from PlatformSubComponent"); + auto hasPlatform = std::find_if(m_Platforms.begin(), m_Platforms.end(), [](const std::unique_ptr& platform) { + return platform->GetPlatformType() == MovingPlatform::SubComponentType; + }) != m_Platforms.end(); + if (!hasPlatform) { + m_Platforms.push_back(std::make_unique(this, std::forward(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 @@ class MovingPlatformComponent : public Component { */ 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 */ diff --git a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp index 35e2f55b3..d215a134c 100644 --- a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp @@ -7,6 +7,7 @@ #define _MOVING_PLATFORM_TEST #include "MovingPlatformComponent.h" #undef _MOVING_PLATFORM_TEST +#include "SimplePhysicsComponent.h" #include "eReplicaComponentType.h" class MovingPlatformComponentTests : public GameDependenciesTest { @@ -17,9 +18,19 @@ class MovingPlatformComponentTests : public GameDependenciesTest { void SetUp() override { SetUpDependencies(); baseEntity = std::make_unique(15, GameDependenciesTest::info); + baseEntity->SetVar(u"dbonly", false); + baseEntity->SetVar(u"platformMoveX", 23); + baseEntity->SetVar(u"platformMoveY", 453); + baseEntity->SetVar(u"platformMoveZ", 523); + baseEntity->SetVar(u"platformMoveTime", 5724); + baseEntity->SetVar(u"platformStartAtEnd", true); auto* movingPlatformComponent = new MovingPlatformComponent(baseEntity.get(), ""); + auto* simplePhysicsComponent = new SimplePhysicsComponent(1, baseEntity.get()); baseEntity->AddComponent(eReplicaComponentType::MOVING_PLATFORM, movingPlatformComponent); - auto moverPlatformSubComponent = std::make_unique(); + baseEntity->AddComponent(eReplicaComponentType::SIMPLE_PHYSICS, simplePhysicsComponent); + baseEntity->SetPosition(NiPoint3(25, 26, 27)); + baseEntity->SetRotation(NiQuaternion(28, 29, 30, 31)); + auto moverPlatformSubComponent = std::make_unique(movingPlatformComponent); moverPlatformSubComponent->m_State = eMovementPlatformState::Stopped | eMovementPlatformState::ReachedDesiredWaypoint; moverPlatformSubComponent->m_DesiredWaypointIndex = 1; moverPlatformSubComponent->m_PercentBetweenPoints = 2; @@ -32,7 +43,7 @@ class MovingPlatformComponentTests : public GameDependenciesTest { moverPlatformSubComponent->m_InReverse = true; moverPlatformSubComponent->m_ShouldStopAtDesiredWaypoint = true; - auto rotatorPlatformSubComponent = std::make_unique(); + auto rotatorPlatformSubComponent = std::make_unique(movingPlatformComponent); rotatorPlatformSubComponent->m_State = eMovementPlatformState::Travelling; rotatorPlatformSubComponent->m_DesiredWaypointIndex = 12; rotatorPlatformSubComponent->m_PercentBetweenPoints = 13; @@ -45,18 +56,20 @@ class MovingPlatformComponentTests : public GameDependenciesTest { rotatorPlatformSubComponent->m_InReverse = true; rotatorPlatformSubComponent->m_ShouldStopAtDesiredWaypoint = true; - auto simpleMoverPlatformSubComponent = std::make_unique(); + auto simpleMoverPlatformSubComponent = std::make_unique(movingPlatformComponent, NiPoint3(), true); simpleMoverPlatformSubComponent->m_State = eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint; simpleMoverPlatformSubComponent->m_DesiredWaypointIndex = 23; simpleMoverPlatformSubComponent->m_PercentBetweenPoints = 24; - simpleMoverPlatformSubComponent->m_Position = NiPoint3(25, 26, 27); simpleMoverPlatformSubComponent->m_CurrentWaypointIndex = 28; simpleMoverPlatformSubComponent->m_NextWaypointIndex = 29; simpleMoverPlatformSubComponent->m_IdleTimeElapsed = 30; simpleMoverPlatformSubComponent->m_MoveTimeElapsed = 33; simpleMoverPlatformSubComponent->m_IsDirty = true; simpleMoverPlatformSubComponent->m_InReverse = true; + simpleMoverPlatformSubComponent->m_DirtyStartingPoint = true; + simpleMoverPlatformSubComponent->m_HasStartingPoint = true; simpleMoverPlatformSubComponent->m_ShouldStopAtDesiredWaypoint = true; + simpleMoverPlatformSubComponent->LoadConfigData(); movingPlatformComponent->_AddPlatformSubComponent(std::move(moverPlatformSubComponent)); movingPlatformComponent->_AddPlatformSubComponent(std::move(rotatorPlatformSubComponent)); @@ -95,11 +108,11 @@ class MovingPlatformComponentTests : public GameDependenciesTest { uint32_t pathStartIndex; bitStream.Read(pathStartIndex); - ASSERT_EQ(pathStartIndex, 1); + ASSERT_EQ(pathStartIndex, 0); bool isInReverse; bitStream.Read(isInReverse); - ASSERT_TRUE(isInReverse); + ASSERT_FALSE(isInReverse); bool hasPlatformData; bitStream.Read(hasPlatformData); @@ -217,51 +230,42 @@ class MovingPlatformComponentTests : public GameDependenciesTest { bitStream.Read(platformType3); ASSERT_EQ(platformType3, eMoverSubComponentType::SimpleMover); - bool isDirty3; - bitStream.Read(isDirty3); - ASSERT_TRUE(isDirty3); + bool dirtyStartingPoint; + bitStream.Read(dirtyStartingPoint); + ASSERT_TRUE(dirtyStartingPoint); - eMovementPlatformState state3; - bitStream.Read(state3); - ASSERT_EQ(state3, eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint); - - int32_t desiredWaypointIndex3; - bitStream.Read(desiredWaypointIndex3); - ASSERT_EQ(desiredWaypointIndex3, 23); + bool hasStartingPoint; + bitStream.Read(hasStartingPoint); + ASSERT_TRUE(hasStartingPoint); - bool shouldStopAtDesiredWaypoint3; - bitStream.Read(shouldStopAtDesiredWaypoint3); - ASSERT_TRUE(shouldStopAtDesiredWaypoint3); + NiPoint3 startingPoint; + bitStream.Read(startingPoint.x); + bitStream.Read(startingPoint.y); + bitStream.Read(startingPoint.z); + ASSERT_EQ(startingPoint, NiPoint3(25, 26, 27)); - bool isInReverse4; - bitStream.Read(isInReverse4); - ASSERT_TRUE(isInReverse4); + NiQuaternion startingRotation; + bitStream.Read(startingRotation.w); + bitStream.Read(startingRotation.x); + bitStream.Read(startingRotation.y); + bitStream.Read(startingRotation.z); + ASSERT_EQ(startingRotation, NiQuaternion(28, 29, 30, 31)); - float percentBetweenPoints3; - bitStream.Read(percentBetweenPoints3); - ASSERT_EQ(percentBetweenPoints3, 24); + bool isDirty4; + bitStream.Read(isDirty4); + ASSERT_TRUE(isDirty4); - NiPoint3 position3; - bitStream.Read(position3.x); - bitStream.Read(position3.y); - bitStream.Read(position3.z); - ASSERT_EQ(position3, NiPoint3(25, 26, 27)); + eMovementPlatformState state3; + bitStream.Read(state3); + ASSERT_EQ(state3, eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint); - uint32_t currentWaypointIndex3; + int32_t currentWaypointIndex3; bitStream.Read(currentWaypointIndex3); ASSERT_EQ(currentWaypointIndex3, 28); - uint32_t nextWaypointIndex3; - bitStream.Read(nextWaypointIndex3); - ASSERT_EQ(nextWaypointIndex3, 29); - - float idleTimeElapsed3; - bitStream.Read(idleTimeElapsed3); - ASSERT_EQ(idleTimeElapsed3, 30); - - float moveTimeElapsed3; - bitStream.Read(moveTimeElapsed3); - ASSERT_EQ(moveTimeElapsed3, 33); + bool isInReverse4; + bitStream.Read(isInReverse4); + ASSERT_TRUE(isInReverse4); bool hasPlatformSubComponents2; bitStream.Read(hasPlatformSubComponents2); From 4336cb7f506c70f4479f3e9bedb47ea360131828 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Tue, 1 Aug 2023 01:36:24 -0700 Subject: [PATCH 05/17] quick notes --- dGame/dComponents/MovingPlatformComponent.cpp | 13 +++++++++---- dGame/dComponents/MovingPlatformComponent.h | 7 +++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/dGame/dComponents/MovingPlatformComponent.cpp b/dGame/dComponents/MovingPlatformComponent.cpp index e34f4d40f..c33c073c9 100644 --- a/dGame/dComponents/MovingPlatformComponent.cpp +++ b/dGame/dComponents/MovingPlatformComponent.cpp @@ -123,6 +123,8 @@ void SimpleMoverPlatformSubComponent::LoadDataFromTemplate() { NiPoint3 platformMove = platformEntry->platformMove; float moveTime = platformEntry->moveTime; + m_PlatformMove = platformMove; + m_MoveTime = moveTime; } SimpleMoverPlatformSubComponent::SimpleMoverPlatformSubComponent(MovingPlatformComponent* parentComponent, const NiPoint3& platformMove, const bool startsInReverse) : PlatformSubComponent(parentComponent) { @@ -143,6 +145,10 @@ MovingPlatformComponent::MovingPlatformComponent(Entity* parent, const std::stri } +void MovingPlatformComponent::LoadDataFromTemplate() { + std::for_each(m_Platforms.begin(), m_Platforms.end(), [](const std::unique_ptr& platform) { platform->LoadDataFromTemplate(); }); +} + void MovingPlatformComponent::LoadConfigData() { if (m_Parent->GetVar(u"platformIsSimpleMover")) { AddMovingPlatform(NiPoint3::ZERO, false); @@ -212,6 +218,7 @@ void MovingPlatformComponent::GotoWaypoint(uint32_t index, bool stopAtWaypoint) } void MovingPlatformComponent::StartPathing() { + // state == Travelling // //GameMessages::SendStartPathing(m_Parent); // m_PathingStopped = false; @@ -263,6 +270,7 @@ void MovingPlatformComponent::StartPathing() { } void MovingPlatformComponent::ContinuePathing() { + // state == Travelling // auto* subComponent = static_cast(m_MoverSubComponent); // subComponent->mState = eMovementPlatformState::Stationary; @@ -373,6 +381,7 @@ void MovingPlatformComponent::ContinuePathing() { } void MovingPlatformComponent::StopPathing() { + // state == Stopped //m_Parent->CancelCallbackTimers(); // auto* subComponent = static_cast(m_MoverSubComponent); @@ -388,10 +397,6 @@ void MovingPlatformComponent::StopPathing() { //GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS); } -void MovingPlatformComponent::SetSerialized(bool value) { - // m_Serialize = value; -} - bool MovingPlatformComponent::GetNoAutoStart() const { return false; // return m_NoAutoStart; diff --git a/dGame/dComponents/MovingPlatformComponent.h b/dGame/dComponents/MovingPlatformComponent.h index 343cae3b5..94514e518 100644 --- a/dGame/dComponents/MovingPlatformComponent.h +++ b/dGame/dComponents/MovingPlatformComponent.h @@ -37,6 +37,8 @@ class PlatformSubComponent { virtual void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate); virtual eMoverSubComponentType GetPlatformType() { return eMoverSubComponentType::None; }; bool GetIsDirty() const { return m_IsDirty; } + virtual void LoadDataFromTemplate() {}; + virtual void LoadConfigData() {}; protected: #ifdef _MOVING_PLATFORM_TEST @@ -85,8 +87,8 @@ class SimpleMoverPlatformSubComponent : public PlatformSubComponent { SimpleMoverPlatformSubComponent(MovingPlatformComponent* parentComponent, const NiPoint3& platformMove, const bool startAtEnd); ~SimpleMoverPlatformSubComponent() override = default; eMoverSubComponentType GetPlatformType() override { return eMoverSubComponentType::SimpleMover; } - void LoadConfigData(); - void LoadDataFromTemplate(); + void LoadConfigData() override; + void LoadDataFromTemplate() override; void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; bool m_HasStartingPoint = false; bool m_DirtyStartingPoint = false; @@ -110,6 +112,7 @@ class MovingPlatformComponent : public Component { MovingPlatformComponent(Entity* parent, const std::string& pathName); + void LoadDataFromTemplate(); void LoadConfigData(); void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); From c293b7a9d722b29739b7905299e18c22017a1c76 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 2 Aug 2023 00:02:02 -0700 Subject: [PATCH 06/17] moving platform work --- dCommon/dEnums/eMovementPlatformState.h | 24 ----------- dGame/dComponents/MovingPlatformComponent.cpp | 41 +++++++++++++++++++ dGame/dComponents/MovingPlatformComponent.h | 25 +++++++++-- dGame/dGameMessages/GameMessages.cpp | 12 +++--- dGame/dGameMessages/GameMessages.h | 8 ++-- .../Map/General/PropertyPlatform.cpp | 9 ++-- dScripts/ai/AG/AgBusDoor.cpp | 5 ++- dScripts/ai/AG/AgQbElevator.cpp | 14 ++++--- .../ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 3 +- dZoneManager/Zone.cpp | 3 +- 10 files changed, 93 insertions(+), 51 deletions(-) delete mode 100644 dCommon/dEnums/eMovementPlatformState.h diff --git a/dCommon/dEnums/eMovementPlatformState.h b/dCommon/dEnums/eMovementPlatformState.h deleted file mode 100644 index f4e839384..000000000 --- a/dCommon/dEnums/eMovementPlatformState.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __EMOVEMENTPLATFORMSTATE__H__ -#define __EMOVEMENTPLATFORMSTATE__H__ - -#include - -/** - * The different types of platform movement state - */ -enum class eMovementPlatformState : uint32_t -{ - Waiting = 1 << 0U, - Travelling = 1 << 1U, - Stopped = 1 << 2U, - ReachedDesiredWaypoint = 1 << 3U, - ReachedFinalWaypoint = 1 << 4U, -}; - -inline constexpr eMovementPlatformState operator|(eMovementPlatformState a, eMovementPlatformState b) { - return static_cast( - static_cast::type>(a) | - static_cast::type>(b)); -}; - -#endif //!__EMOVEMENTPLATFORMSTATE__H__ diff --git a/dGame/dComponents/MovingPlatformComponent.cpp b/dGame/dComponents/MovingPlatformComponent.cpp index c33c073c9..5c06d3554 100644 --- a/dGame/dComponents/MovingPlatformComponent.cpp +++ b/dGame/dComponents/MovingPlatformComponent.cpp @@ -53,6 +53,44 @@ void PlatformSubComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn if (!bIsInitialUpdate) m_IsDirty = false; } +void PlatformSubComponent::StartPathing() { + m_State |= eMovementPlatformState::Travelling; + m_State &= ~eMovementPlatformState::Stopped; + m_State &= ~eMovementPlatformState::Waiting; +} + +void PlatformSubComponent::ResumePathing() { + if (m_State & eMovementPlatformState::Stopped && (m_State & eMovementPlatformState::ReachedDesiredWaypoint) == 0) { + StartPathing(); + } + if (m_State & eMovementPlatformState::Travelling == 0) { + m_State |= eMovementPlatformState::Waiting; + m_State &= ~eMovementPlatformState::Stopped; + m_State &= ~eMovementPlatformState::Travelling; + } else { + m_State &= eMovementPlatformState::Waiting; + m_State &= eMovementPlatformState::Travelling; + m_State &= eMovementPlatformState::Stopped; + // Set the velocities + } +} + +void PlatformSubComponent::StopPathing() { + m_State |= eMovementPlatformState::Stopped; + m_State &= ~eMovementPlatformState::Travelling; + m_State &= ~eMovementPlatformState::Waiting; + m_LinearVelocity = NiPoint3::ZERO; + m_AngularVelocity = NiPoint3::ZERO; +} + +void PlatformSubComponent::Update(float deltaTime) { + if (m_TimeBasedMovement && m_State & eMovementPlatformState::Travelling) { + m_MoveTimeElapsed += deltaTime; + } + if (m_State == 0) return; + +} + //------------- PlatformSubComponent end -------------- //------------- MoverPlatformSubComponent begin -------------- @@ -218,6 +256,9 @@ void MovingPlatformComponent::GotoWaypoint(uint32_t index, bool stopAtWaypoint) } void MovingPlatformComponent::StartPathing() { + std::for_each(m_Platforms.begin(), m_Platforms.end(), [](const std::unique_ptr& platform) { + platform->StartPathing(); + }); // state == Travelling // //GameMessages::SendStartPathing(m_Parent); // m_PathingStopped = false; diff --git a/dGame/dComponents/MovingPlatformComponent.h b/dGame/dComponents/MovingPlatformComponent.h index 94514e518..05f98d4f4 100644 --- a/dGame/dComponents/MovingPlatformComponent.h +++ b/dGame/dComponents/MovingPlatformComponent.h @@ -13,11 +13,22 @@ #include "dCommonVars.h" #include "Component.h" -#include "eMovementPlatformState.h" #include "eReplicaComponentType.h" class Path; +/** + * The different types of platform movement state + */ +enum eMovementPlatformState : uint32_t +{ + Waiting = 1 << 0U, + Travelling = 1 << 1U, + Stopped = 1 << 2U, + ReachedDesiredWaypoint = 1 << 3U, + ReachedFinalWaypoint = 1 << 4U, +}; + /** * Different types of available platforms */ @@ -39,16 +50,21 @@ class PlatformSubComponent { bool GetIsDirty() const { return m_IsDirty; } virtual void LoadDataFromTemplate() {}; virtual void LoadConfigData() {}; + virtual void StartPathing(); + virtual void ResumePathing(); + virtual void StopPathing(); + virtual void Update(float deltaTime); protected: #ifdef _MOVING_PLATFORM_TEST public: #endif MovingPlatformComponent* m_ParentComponent = nullptr; + /** * The state the platform is currently in */ - eMovementPlatformState m_State = eMovementPlatformState::Stopped | eMovementPlatformState::ReachedDesiredWaypoint; + uint32_t m_State = eMovementPlatformState::Stopped | eMovementPlatformState::ReachedDesiredWaypoint; int32_t m_DesiredWaypointIndex = 0; float m_PercentBetweenPoints = 0; NiPoint3 m_Position; @@ -61,6 +77,9 @@ class PlatformSubComponent { bool m_IsDirty = false; bool m_InReverse = false; bool m_ShouldStopAtDesiredWaypoint = false; + NiPoint3 m_LinearVelocity; + NiPoint3 m_AngularVelocity; + bool m_TimeBasedMovement = false; }; class MoverPlatformSubComponent : public PlatformSubComponent { @@ -159,7 +178,7 @@ class MovingPlatformComponent : public Component { * Determines if the entity should be serialized on the next update * @param value whether to serialize the entity or not */ - void SetSerialized(bool value); + void SetSerialized(bool value) {}; /** * Returns if this platform will start automatically after spawn diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index ef9bea483..caa096e5f 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -26,7 +26,6 @@ #include "ChatPackets.h" #include "RocketLaunchLupComponent.h" #include "eUnequippableActiveType.h" -#include "eMovementPlatformState.h" #include "LeaderboardManager.h" #include "Amf3.h" #include "Loot.h" @@ -349,9 +348,9 @@ void GameMessages::SendStartPathing(Entity* entity) { SEND_PACKET_BROADCAST; } -void GameMessages::SendPlatformResync(Entity* entity, const SystemAddress& sysAddr, bool bStopAtDesiredWaypoint, - int iIndex, int iDesiredWaypointIndex, int nextIndex, - eMovementPlatformState movementState) { +void GameMessages::SendPlatformResync(Entity* entity, const SystemAddress& sysAddr, + eMovementPlatformState movementState, bool bStopAtDesiredWaypoint, + int iIndex, int iDesiredWaypointIndex, int nextIndex) { CBITSTREAM; CMSGHEADER; @@ -362,7 +361,8 @@ void GameMessages::SendPlatformResync(Entity* entity, const SystemAddress& sysAd iIndex = 0; nextIndex = 0; bStopAtDesiredWaypoint = true; - movementState = eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint; + movementState = static_cast( + eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint); } bitStream.Write(entity->GetObjectID()); @@ -5005,7 +5005,7 @@ void GameMessages::HandleFireEventServerSide(RakNet::BitStream* inStream, Entity void GameMessages::HandleRequestPlatformResync(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { if (entity->GetLOT() == 6267 || entity->GetLOT() == 16141) return; - GameMessages::SendPlatformResync(entity, sysAddr); + GameMessages::SendPlatformResync(entity, sysAddr, eMovementPlatformState::Travelling); } void GameMessages::HandleRebuildCancel(RakNet::BitStream* inStream, Entity* entity) { diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 695d82097..8a0deb678 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -5,7 +5,6 @@ #include #include #include -#include "eMovementPlatformState.h" #include "NiPoint3.h" #include "eEndBehavior.h" #include "eCyclingMode.h" @@ -21,6 +20,7 @@ class Leaderboard; class PropertySelectQueryProperty; class TradeItem; +enum eMovementPlatformState : uint32_t; enum class eAnimationFlags : uint32_t; enum class eUnequippableActiveType; @@ -69,9 +69,9 @@ namespace GameMessages { void SendPlayNDAudioEmitter(Entity* entity, const SystemAddress& sysAddr, std::string audioGUID); void SendStartPathing(Entity* entity); - void SendPlatformResync(Entity* entity, const SystemAddress& sysAddr, bool bStopAtDesiredWaypoint = false, - int iIndex = 0, int iDesiredWaypointIndex = 1, int nextIndex = 1, - eMovementPlatformState movementState = eMovementPlatformState::Travelling); + void SendPlatformResync(Entity* entity, const SystemAddress& sysAddr, + eMovementPlatformState movementState, bool bStopAtDesiredWaypoint = false, + int iIndex = 0, int iDesiredWaypointIndex = 1, int nextIndex = 1); void SendRestoreToPostLoadStats(Entity* entity, const SystemAddress& sysAddr); void SendServerDoneLoadingAllObjects(Entity* entity, const SystemAddress& sysAddr); diff --git a/dScripts/02_server/Map/General/PropertyPlatform.cpp b/dScripts/02_server/Map/General/PropertyPlatform.cpp index b831bf489..2e6f68edf 100644 --- a/dScripts/02_server/Map/General/PropertyPlatform.cpp +++ b/dScripts/02_server/Map/General/PropertyPlatform.cpp @@ -4,15 +4,16 @@ #include "MovingPlatformComponent.h" void PropertyPlatform::OnRebuildComplete(Entity* self, Entity* target) { - GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0, - 0, 0, eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint); + GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS + , static_cast(eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint), + true, 0, 0, 0); } void PropertyPlatform::OnUse(Entity* self, Entity* user) { auto* rebuildComponent = self->GetComponent(); if (rebuildComponent != nullptr && rebuildComponent->GetState() == eRebuildState::COMPLETED) { - GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0, - 1, 1, eMovementPlatformState::Travelling); + GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, eMovementPlatformState::Travelling, true, 0, + 1, 1); self->AddCallbackTimer(movementDelay + effectDelay, [self, this]() { self->SetNetworkVar(u"startEffect", dieDelay); diff --git a/dScripts/ai/AG/AgBusDoor.cpp b/dScripts/ai/AG/AgBusDoor.cpp index fd6c272ed..880d73c44 100644 --- a/dScripts/ai/AG/AgBusDoor.cpp +++ b/dScripts/ai/AG/AgBusDoor.cpp @@ -2,6 +2,7 @@ #include "Entity.h" #include "GameMessages.h" #include "ProximityMonitorComponent.h" +#include "MovingPlatformComponent.h" void AgBusDoor::OnStartup(Entity* self) { m_Counter = 0; @@ -48,9 +49,9 @@ void AgBusDoor::OnProximityUpdate(Entity* self, Entity* entering, std::string na void AgBusDoor::MoveDoor(Entity* self, bool bOpen) { if (bOpen) { - GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 1, 0); + GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, eMovementPlatformState::Travelling, true, 1, 0); } else { - GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0, 1); + GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, eMovementPlatformState::Travelling, true, 0, 1); self->AddTimer("dustTimer", 2.0f); } diff --git a/dScripts/ai/AG/AgQbElevator.cpp b/dScripts/ai/AG/AgQbElevator.cpp index b39d31984..4f4d94f46 100644 --- a/dScripts/ai/AG/AgQbElevator.cpp +++ b/dScripts/ai/AG/AgQbElevator.cpp @@ -1,6 +1,7 @@ #include "AgQbElevator.h" #include "EntityManager.h" #include "GameMessages.h" +#include "MovingPlatformComponent.h" void AgQbElevator::OnStartup(Entity* self) { @@ -14,8 +15,9 @@ void AgQbElevator::OnRebuildComplete(Entity* self, Entity* target) { float delayTime = killTime - endTime; if (delayTime < 1) delayTime = 1; - GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0, - 0, 0, eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint); + GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, + static_cast(eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint) + , true, 0, 0, 0); //add a timer that will kill the QB if no players get on in the killTime self->AddTimer("startKillTimer", killTime); @@ -32,8 +34,8 @@ void AgQbElevator::OnProximityUpdate(Entity* self, Entity* entering, std::string self->SetBoolean(u"qbPlayerRdy", true); self->CancelTimer("StartElevator"); - GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0, - 1, 1, eMovementPlatformState::Travelling); + GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, eMovementPlatformState::Travelling, true, 0, + 1, 1); } else if (!self->GetBoolean(u"StartTimer")) { self->SetBoolean(u"StartTimer", true); self->AddTimer("StartElevator", startTime); @@ -44,8 +46,8 @@ void AgQbElevator::OnProximityUpdate(Entity* self, Entity* entering, std::string void AgQbElevator::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "StartElevator") { - GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0, - 1, 1, eMovementPlatformState::Travelling); + GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, eMovementPlatformState::Travelling, true, 0, + 1, 1); } else if (timerName == "startKillTimer") { killTimerStartup(self); } else if (timerName == "KillTimer") { diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index 4aa8d0c94..21de5a6ec 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -17,6 +17,7 @@ #include "eReplicaComponentType.h" #include "RenderComponent.h" #include "eGameActivity.h" +#include "MovingPlatformComponent.h" void SGCannon::OnStartup(Entity* self) { Game::logger->Log("SGCannon", "OnStartup"); @@ -314,7 +315,7 @@ void SGCannon::OnActivityTimerDone(Entity* self, const std::string& name) { // Save the enemy and tell it to start pathing if (enemy != nullptr) { const_cast&>(self->GetVar>(SpawnedObjects)).push_back(enemy->GetObjectID()); - GameMessages::SendPlatformResync(enemy, UNASSIGNED_SYSTEM_ADDRESS); + GameMessages::SendPlatformResync(enemy, UNASSIGNED_SYSTEM_ADDRESS, eMovementPlatformState::Travelling); } } } else if (name == EndGameBufferTimer) { diff --git a/dZoneManager/Zone.cpp b/dZoneManager/Zone.cpp index 6b1537063..e2cdbf909 100644 --- a/dZoneManager/Zone.cpp +++ b/dZoneManager/Zone.cpp @@ -381,7 +381,7 @@ void Zone::LoadPath(std::istream& file) { BinaryIO::BinaryRead(file, character); path.pathName.push_back(character); } - + Game::logger->Log("Zone", "pathname: %s", path.pathName.c_str()); BinaryIO::BinaryRead(file, path.pathType); BinaryIO::BinaryRead(file, path.flags); BinaryIO::BinaryRead(file, path.pathBehavior); @@ -479,6 +479,7 @@ void Zone::LoadPath(std::istream& file) { if (path.pathType == PathType::MovingPlatform) { BinaryIO::BinaryRead(file, waypoint.movingPlatform.lockPlayer); BinaryIO::BinaryRead(file, waypoint.movingPlatform.speed); + Game::logger->Log("Zone", "speed: %f", waypoint.movingPlatform.speed); BinaryIO::BinaryRead(file, waypoint.movingPlatform.wait); if (path.pathVersion >= 13) { uint8_t count1; From 2252088e1b2ed02c6d40b5de7e6256d853d900e4 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Thu, 3 Aug 2023 01:50:34 -0700 Subject: [PATCH 07/17] TDD --- dGame/dComponents/MovingPlatformComponent.cpp | 82 ++++++++++++++++- dGame/dComponents/MovingPlatformComponent.h | 32 ++++--- .../MovingPlatformComponentTests.cpp | 87 ++++++++++++++++++- 3 files changed, 184 insertions(+), 17 deletions(-) diff --git a/dGame/dComponents/MovingPlatformComponent.cpp b/dGame/dComponents/MovingPlatformComponent.cpp index 5c06d3554..11294c2aa 100644 --- a/dGame/dComponents/MovingPlatformComponent.cpp +++ b/dGame/dComponents/MovingPlatformComponent.cpp @@ -27,7 +27,7 @@ PlatformSubComponent::PlatformSubComponent(MovingPlatformComponent* parentCompon m_InReverse = false; m_ShouldStopAtDesiredWaypoint = false; - m_PercentBetweenPoints = 0.0f; + m_PercentUntilNextWaypoint = 0.0f; m_CurrentWaypointIndex = 0; m_NextWaypointIndex = 0; @@ -35,6 +35,80 @@ PlatformSubComponent::PlatformSubComponent(MovingPlatformComponent* parentCompon m_IdleTimeElapsed = 0.0f; } +void PlatformSubComponent::AdvanceToNextWaypoint() { + uint32_t numWaypoints = m_Path->pathWaypoints.size(); + m_CurrentWaypointIndex = m_NextWaypointIndex; + uint32_t nextWaypointIndex = m_CurrentWaypointIndex; + if (numWaypoints <= nextWaypointIndex) { + PathBehavior behavior = m_Path->pathBehavior; + if (behavior == PathBehavior::Once) { + nextWaypointIndex = m_Path->pathWaypoints.size() - 1; + } else if (behavior == PathBehavior::Bounce) { + nextWaypointIndex = m_Path->pathWaypoints.size() - 2; + m_InReverse = true; + } else { + m_NextWaypointIndex = 0; + } + } + m_NextWaypointIndex = nextWaypointIndex; +} + +void PlatformSubComponent::AdvanceToNextReverseWaypoint() { + uint32_t numWaypoints = m_Path->pathWaypoints.size(); + m_CurrentWaypointIndex = m_NextWaypointIndex; + int32_t nextWaypointIndex = m_CurrentWaypointIndex; + if (nextWaypointIndex < 0) { + PathBehavior behavior = m_Path->pathBehavior; + if (behavior == PathBehavior::Once) { + nextWaypointIndex = 0; + } else if (behavior == PathBehavior::Bounce) { + nextWaypointIndex = 1; + m_InReverse = false; + } else { + nextWaypointIndex = m_Path->pathWaypoints.size() - 1; + } + } + m_NextWaypointIndex = nextWaypointIndex; +} + +void PlatformSubComponent::SetupPath(const std::string& pathName, uint32_t startingWaypointIndex, bool startsInReverse) { + m_Path = Game::zoneManager->GetZone()->GetPath(pathName); + if (!m_Path) { + Game::logger->Log("MovingPlatformComponent", "Failed to find path (%s)", pathName.c_str()); + return; + } + m_InReverse = startsInReverse; + m_CurrentWaypointIndex = startingWaypointIndex; + m_TimeBasedMovement = m_Path->movingPlatform.timeBasedMovement; +} + +const PathWaypoint PlatformSubComponent::GetNextWaypoint() const { + DluAssert(m_Path != nullptr); + if (m_NextWaypointIndex >= m_Path->pathWaypoints.size()) return PathWaypoint(); + return m_Path->pathWaypoints.at(m_NextWaypointIndex); +} + +const PathWaypoint PlatformSubComponent::GetCurrentWaypoint() const { + DluAssert(m_Path != nullptr); + if (m_CurrentWaypointIndex >= m_Path->pathWaypoints.size()) return PathWaypoint(); + return m_Path->pathWaypoints.at(m_CurrentWaypointIndex); +} + +float PlatformSubComponent::CalculateSpeed() const { + float speed; + if (m_TimeBasedMovement) { + float unitizedDirection = 1.0f / (GetNextWaypoint().position - GetCurrentWaypoint().position).Length(); + speed = unitizedDirection / GetCurrentWaypoint().movingPlatform.speed; + } else { + speed = (GetNextWaypoint().movingPlatform.speed - GetCurrentWaypoint().movingPlatform.speed) * m_PercentUntilNextWaypoint + GetCurrentWaypoint().movingPlatform.speed; + } + return speed; +} + +NiPoint3 PlatformSubComponent::CalculateLinearVelocity() { + return (GetNextWaypoint().position - GetCurrentWaypoint().position).Unitize() * CalculateSpeed(); +} + void PlatformSubComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { outBitStream->Write(bIsInitialUpdate || m_IsDirty); if (!(bIsInitialUpdate || m_IsDirty)) return; @@ -42,7 +116,7 @@ void PlatformSubComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn outBitStream->Write(m_DesiredWaypointIndex); outBitStream->Write(m_ShouldStopAtDesiredWaypoint); outBitStream->Write(m_InReverse); - outBitStream->Write(m_PercentBetweenPoints); + outBitStream->Write(m_PercentUntilNextWaypoint); outBitStream->Write(m_Position.x); outBitStream->Write(m_Position.y); outBitStream->Write(m_Position.z); @@ -145,8 +219,6 @@ void SimpleMoverPlatformSubComponent::LoadConfigData() { ); m_PlatformMove = platformMove; m_MoveTime = m_ParentComponent->GetParent()->GetVar(u"platformMoveTime"); - // idk either. client does it! - m_StartAtEnd = m_ParentComponent->GetParent()->GetVar(u"attached_path_start") != 0; m_StartAtEnd = m_ParentComponent->GetParent()->GetVar(u"platformStartAtEnd"); } @@ -197,6 +269,8 @@ void MovingPlatformComponent::LoadConfigData() { if (m_Parent->GetVar(u"platformIsRotater")) { AddMovingPlatform(); } + m_StartingWaypointIndex = m_Parent->GetVar(u"attached_path_start"); + m_StartsIsInReverse = false; m_DirtyPathInfo = true; } diff --git a/dGame/dComponents/MovingPlatformComponent.h b/dGame/dComponents/MovingPlatformComponent.h index 05f98d4f4..94157c331 100644 --- a/dGame/dComponents/MovingPlatformComponent.h +++ b/dGame/dComponents/MovingPlatformComponent.h @@ -15,6 +15,7 @@ #include "Component.h" #include "eReplicaComponentType.h" +class PathWaypoint; class Path; /** @@ -54,10 +55,20 @@ class PlatformSubComponent { virtual void ResumePathing(); virtual void StopPathing(); virtual void Update(float deltaTime); + float CalculateSpeed() const; + const PathWaypoint GetNextWaypoint() const; + const PathWaypoint GetCurrentWaypoint() const; + void SetupPath(const std::string& pathName, uint32_t startingWaypointIndex, bool startsInReverse); + void AdvanceToNextWaypoint(); + void AdvanceToNextReverseWaypoint(); + NiPoint3 CalculateLinearVelocity(); protected: #ifdef _MOVING_PLATFORM_TEST public: + void _SetPath(const Path* path) { + m_Path = path; + } #endif MovingPlatformComponent* m_ParentComponent = nullptr; @@ -66,10 +77,10 @@ class PlatformSubComponent { */ uint32_t m_State = eMovementPlatformState::Stopped | eMovementPlatformState::ReachedDesiredWaypoint; int32_t m_DesiredWaypointIndex = 0; - float m_PercentBetweenPoints = 0; + float m_PercentUntilNextWaypoint = 0; NiPoint3 m_Position; - uint32_t m_CurrentWaypointIndex; - uint32_t m_NextWaypointIndex; + int32_t m_CurrentWaypointIndex; + int32_t m_NextWaypointIndex; float m_IdleTimeElapsed = 0; float m_Speed = 0; float m_WaitTime = 0; @@ -80,6 +91,7 @@ class PlatformSubComponent { NiPoint3 m_LinearVelocity; NiPoint3 m_AngularVelocity; bool m_TimeBasedMovement = false; + const Path* m_Path = nullptr; }; class MoverPlatformSubComponent : public PlatformSubComponent { @@ -209,10 +221,10 @@ class MovingPlatformComponent : public Component { static_assert(std::is_base_of::value, "MovingPlatform must derive from PlatformSubComponent"); auto hasPlatform = std::find_if(m_Platforms.begin(), m_Platforms.end(), [](const std::unique_ptr& platform) { return platform->GetPlatformType() == MovingPlatform::SubComponentType; - }) != m_Platforms.end(); - if (!hasPlatform) { - m_Platforms.push_back(std::make_unique(this, std::forward(arguments)...)); - } + }) != m_Platforms.end(); + if (!hasPlatform) { + m_Platforms.push_back(std::make_unique(this, std::forward(arguments)...)); + } } int32_t GetComponentId() const { return componentId; } @@ -220,8 +232,8 @@ class MovingPlatformComponent : public Component { #ifdef _MOVING_PLATFORM_TEST /** * Only used for testing. Do not call in production code. Let the constructor take care of this. - * - * @param platformSubComponent + * + * @param platformSubComponent */ void _AddPlatformSubComponent(std::unique_ptr platformSubComponent) { m_Platforms.push_back(std::move(platformSubComponent)); @@ -230,7 +242,7 @@ class MovingPlatformComponent : public Component { void _SetPath(const std::u16string& path) { m_PathName = path; m_DirtyPathInfo = true; - } +} #endif private: /** diff --git a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp index d215a134c..79f370be0 100644 --- a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp @@ -7,6 +7,7 @@ #define _MOVING_PLATFORM_TEST #include "MovingPlatformComponent.h" #undef _MOVING_PLATFORM_TEST +#include "Zone.h" #include "SimplePhysicsComponent.h" #include "eReplicaComponentType.h" @@ -15,8 +16,22 @@ class MovingPlatformComponentTests : public GameDependenciesTest { std::unique_ptr baseEntity; CBITSTREAM; uint32_t flags = 0; + Path path; void SetUp() override { SetUpDependencies(); + path.movingPlatform.timeBasedMovement = false; + path.pathBehavior = PathBehavior::Once; + PathWaypoint waypointStart; + waypointStart.position = NiPoint3(1, 2, 3); + waypointStart.rotation = NiQuaternion(4, 5, 6, 7); + + PathWaypoint waypointEnd; + waypointEnd.position = NiPoint3(4, 5, 6); + waypointEnd.rotation = NiQuaternion(7, 8, 9, 10); + + path.pathWaypoints.push_back(waypointStart); + path.pathWaypoints.push_back(waypointEnd); + baseEntity = std::make_unique(15, GameDependenciesTest::info); baseEntity->SetVar(u"dbonly", false); baseEntity->SetVar(u"platformMoveX", 23); @@ -33,7 +48,7 @@ class MovingPlatformComponentTests : public GameDependenciesTest { auto moverPlatformSubComponent = std::make_unique(movingPlatformComponent); moverPlatformSubComponent->m_State = eMovementPlatformState::Stopped | eMovementPlatformState::ReachedDesiredWaypoint; moverPlatformSubComponent->m_DesiredWaypointIndex = 1; - moverPlatformSubComponent->m_PercentBetweenPoints = 2; + moverPlatformSubComponent->m_PercentUntilNextWaypoint = 2; moverPlatformSubComponent->m_Position = NiPoint3(3, 4, 5); moverPlatformSubComponent->m_CurrentWaypointIndex = 6; moverPlatformSubComponent->m_NextWaypointIndex = 7; @@ -46,7 +61,7 @@ class MovingPlatformComponentTests : public GameDependenciesTest { auto rotatorPlatformSubComponent = std::make_unique(movingPlatformComponent); rotatorPlatformSubComponent->m_State = eMovementPlatformState::Travelling; rotatorPlatformSubComponent->m_DesiredWaypointIndex = 12; - rotatorPlatformSubComponent->m_PercentBetweenPoints = 13; + rotatorPlatformSubComponent->m_PercentUntilNextWaypoint = 13; rotatorPlatformSubComponent->m_Position = NiPoint3(14, 15, 16); rotatorPlatformSubComponent->m_CurrentWaypointIndex = 17; rotatorPlatformSubComponent->m_NextWaypointIndex = 18; @@ -59,7 +74,7 @@ class MovingPlatformComponentTests : public GameDependenciesTest { auto simpleMoverPlatformSubComponent = std::make_unique(movingPlatformComponent, NiPoint3(), true); simpleMoverPlatformSubComponent->m_State = eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint; simpleMoverPlatformSubComponent->m_DesiredWaypointIndex = 23; - simpleMoverPlatformSubComponent->m_PercentBetweenPoints = 24; + simpleMoverPlatformSubComponent->m_PercentUntilNextWaypoint = 24; simpleMoverPlatformSubComponent->m_CurrentWaypointIndex = 28; simpleMoverPlatformSubComponent->m_NextWaypointIndex = 29; simpleMoverPlatformSubComponent->m_IdleTimeElapsed = 30; @@ -280,3 +295,69 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformConstructionTest) { TEST_F(MovingPlatformComponentTests, MovingPlatformSerializationTest) { TestSerialization(); } + +TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceForwardTest) { + MoverPlatformSubComponent moverPlatformSubComponent(nullptr); + moverPlatformSubComponent._SetPath(&path); + moverPlatformSubComponent.m_CurrentWaypointIndex = 0; + moverPlatformSubComponent.m_NextWaypointIndex = 1; + moverPlatformSubComponent.m_InReverse = false; + moverPlatformSubComponent.AdvanceToNextWaypoint(); + ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 1); + ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 0); + ASSERT_FALSE(moverPlatformSubComponent.m_InReverse); + moverPlatformSubComponent.AdvanceToNextWaypoint(); + ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 1); + ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 0); + ASSERT_FALSE(moverPlatformSubComponent.m_InReverse); + path.pathBehavior = PathBehavior::Bounce; + moverPlatformSubComponent.AdvanceToNextWaypoint(); + ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 0); + ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 1); + ASSERT_TRUE(moverPlatformSubComponent.m_InReverse); +} + +TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceReverseTest) { + MoverPlatformSubComponent moverPlatformSubComponent(nullptr); + moverPlatformSubComponent._SetPath(&path); + moverPlatformSubComponent.m_CurrentWaypointIndex = 1; + moverPlatformSubComponent.m_NextWaypointIndex = 0; + moverPlatformSubComponent.m_InReverse = true; + moverPlatformSubComponent.AdvanceToNextReverseWaypoint(); + ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 0); + ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 0); + ASSERT_TRUE(moverPlatformSubComponent.m_InReverse); + path.pathBehavior = PathBehavior::Bounce; + moverPlatformSubComponent.m_CurrentWaypointIndex = 1; + moverPlatformSubComponent.m_NextWaypointIndex = 0; + moverPlatformSubComponent.AdvanceToNextReverseWaypoint(); + ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 0); + ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 1); + ASSERT_TRUE(moverPlatformSubComponent.m_InReverse); + moverPlatformSubComponent.AdvanceToNextReverseWaypoint(); + ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 1); + ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 0); + ASSERT_FALSE(moverPlatformSubComponent.m_InReverse); +} + +TEST_F(MovingPlatformComponentTests, MovingPlatformMoverSpeedCalculationTest) { + MoverPlatformSubComponent moverPlatformSubComponent(nullptr); + path.pathWaypoints.at(0).position = NiPoint3(99.296440, 419.293335, 207.219498); + path.pathWaypoints.at(0).movingPlatform.speed = 16.0f; + + path.pathWaypoints.at(1).position = NiPoint3(141.680099, 419.990051, 208.680450); + path.pathWaypoints.at(1).movingPlatform.speed = 16.0f; + path.pathBehavior = PathBehavior::Bounce; + moverPlatformSubComponent._SetPath(&path); + moverPlatformSubComponent.m_Speed = 16.0f; + moverPlatformSubComponent.m_TimeBasedMovement = false; + moverPlatformSubComponent.m_InReverse = false; + moverPlatformSubComponent.m_CurrentWaypointIndex = 0; + moverPlatformSubComponent.m_NextWaypointIndex = 1; + ASSERT_EQ(moverPlatformSubComponent.CalculateSpeed(), 16.0f); + NiPoint3 r = moverPlatformSubComponent.CalculateLinearVelocity(); + ASSERT_FLOAT_EQ(r.x, 15.988346099854); + ASSERT_FLOAT_EQ(r.y, 0.26282161474228); + ASSERT_FLOAT_EQ(r.z, 0.5511137843132); + moverPlatformSubComponent.AdvanceToNextWaypoint(); +} From e6fe2edfaeb23b619c3c6cd06dfabf56cb457d96 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Thu, 3 Aug 2023 21:37:08 -0700 Subject: [PATCH 08/17] better tests for advancing waypoint --- dGame/dComponents/MovingPlatformComponent.cpp | 4 +- .../MovingPlatformComponentTests.cpp | 51 +++++++++++++++---- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/dGame/dComponents/MovingPlatformComponent.cpp b/dGame/dComponents/MovingPlatformComponent.cpp index 11294c2aa..caac434e3 100644 --- a/dGame/dComponents/MovingPlatformComponent.cpp +++ b/dGame/dComponents/MovingPlatformComponent.cpp @@ -38,7 +38,7 @@ PlatformSubComponent::PlatformSubComponent(MovingPlatformComponent* parentCompon void PlatformSubComponent::AdvanceToNextWaypoint() { uint32_t numWaypoints = m_Path->pathWaypoints.size(); m_CurrentWaypointIndex = m_NextWaypointIndex; - uint32_t nextWaypointIndex = m_CurrentWaypointIndex; + uint32_t nextWaypointIndex = m_CurrentWaypointIndex + 1; if (numWaypoints <= nextWaypointIndex) { PathBehavior behavior = m_Path->pathBehavior; if (behavior == PathBehavior::Once) { @@ -56,7 +56,7 @@ void PlatformSubComponent::AdvanceToNextWaypoint() { void PlatformSubComponent::AdvanceToNextReverseWaypoint() { uint32_t numWaypoints = m_Path->pathWaypoints.size(); m_CurrentWaypointIndex = m_NextWaypointIndex; - int32_t nextWaypointIndex = m_CurrentWaypointIndex; + int32_t nextWaypointIndex = m_CurrentWaypointIndex - 1; if (nextWaypointIndex < 0) { PathBehavior behavior = m_Path->pathBehavior; if (behavior == PathBehavior::Once) { diff --git a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp index 79f370be0..8c70c0ee8 100644 --- a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp @@ -25,11 +25,16 @@ class MovingPlatformComponentTests : public GameDependenciesTest { waypointStart.position = NiPoint3(1, 2, 3); waypointStart.rotation = NiQuaternion(4, 5, 6, 7); + PathWaypoint waypointMiddle; + waypointMiddle.position = NiPoint3(4, 5, 6); + waypointMiddle.rotation = NiQuaternion(7, 8, 9, 10); + PathWaypoint waypointEnd; waypointEnd.position = NiPoint3(4, 5, 6); waypointEnd.rotation = NiQuaternion(7, 8, 9, 10); path.pathWaypoints.push_back(waypointStart); + path.pathWaypoints.push_back(waypointMiddle); path.pathWaypoints.push_back(waypointEnd); baseEntity = std::make_unique(15, GameDependenciesTest::info); @@ -304,15 +309,14 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceForwar moverPlatformSubComponent.m_InReverse = false; moverPlatformSubComponent.AdvanceToNextWaypoint(); ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 1); - ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 0); - ASSERT_FALSE(moverPlatformSubComponent.m_InReverse); + ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 2); moverPlatformSubComponent.AdvanceToNextWaypoint(); - ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 1); - ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 0); + ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 2); + ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 2); ASSERT_FALSE(moverPlatformSubComponent.m_InReverse); path.pathBehavior = PathBehavior::Bounce; moverPlatformSubComponent.AdvanceToNextWaypoint(); - ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 0); + ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 2); ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 1); ASSERT_TRUE(moverPlatformSubComponent.m_InReverse); } @@ -320,23 +324,50 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceForwar TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceReverseTest) { MoverPlatformSubComponent moverPlatformSubComponent(nullptr); moverPlatformSubComponent._SetPath(&path); - moverPlatformSubComponent.m_CurrentWaypointIndex = 1; - moverPlatformSubComponent.m_NextWaypointIndex = 0; + moverPlatformSubComponent.m_CurrentWaypointIndex = 2; + moverPlatformSubComponent.m_NextWaypointIndex = 1; moverPlatformSubComponent.m_InReverse = true; moverPlatformSubComponent.AdvanceToNextReverseWaypoint(); + ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 1); + ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 0); + ASSERT_TRUE(moverPlatformSubComponent.m_InReverse); + moverPlatformSubComponent.AdvanceToNextReverseWaypoint(); ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 0); ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 0); ASSERT_TRUE(moverPlatformSubComponent.m_InReverse); path.pathBehavior = PathBehavior::Bounce; - moverPlatformSubComponent.m_CurrentWaypointIndex = 1; - moverPlatformSubComponent.m_NextWaypointIndex = 0; - moverPlatformSubComponent.AdvanceToNextReverseWaypoint(); + moverPlatformSubComponent.AdvanceToNextWaypoint(); ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 0); ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 1); ASSERT_TRUE(moverPlatformSubComponent.m_InReverse); +} + +TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceTest) { + MoverPlatformSubComponent moverPlatformSubComponent(nullptr); + moverPlatformSubComponent._SetPath(&path); + path.pathBehavior = PathBehavior::Bounce; + moverPlatformSubComponent.m_CurrentWaypointIndex = 0; + moverPlatformSubComponent.m_NextWaypointIndex = 1; + moverPlatformSubComponent.m_InReverse = false; + moverPlatformSubComponent.AdvanceToNextWaypoint(); + ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 1); + ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 2); + ASSERT_FALSE(moverPlatformSubComponent.m_InReverse); + moverPlatformSubComponent.AdvanceToNextWaypoint(); + ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 2); + ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 1); + ASSERT_TRUE(moverPlatformSubComponent.m_InReverse); moverPlatformSubComponent.AdvanceToNextReverseWaypoint(); ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 1); ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 0); + ASSERT_TRUE(moverPlatformSubComponent.m_InReverse); + moverPlatformSubComponent.AdvanceToNextReverseWaypoint(); + ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 0); + ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 1); + ASSERT_FALSE(moverPlatformSubComponent.m_InReverse); + moverPlatformSubComponent.AdvanceToNextWaypoint(); + ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 1); + ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 2); ASSERT_FALSE(moverPlatformSubComponent.m_InReverse); } From 42de987e2595c931520fd7bb75646d6d8366b329 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Fri, 4 Aug 2023 00:54:48 -0700 Subject: [PATCH 09/17] Keep updating --- dGame/dComponents/MovingPlatformComponent.cpp | 30 +++++++++++---- dGame/dComponents/MovingPlatformComponent.h | 1 + .../MovingPlatformComponentTests.cpp | 38 ++++++++++++++++++- 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/dGame/dComponents/MovingPlatformComponent.cpp b/dGame/dComponents/MovingPlatformComponent.cpp index caac434e3..1ef7d935d 100644 --- a/dGame/dComponents/MovingPlatformComponent.cpp +++ b/dGame/dComponents/MovingPlatformComponent.cpp @@ -35,6 +35,26 @@ PlatformSubComponent::PlatformSubComponent(MovingPlatformComponent* parentCompon m_IdleTimeElapsed = 0.0f; } +void PlatformSubComponent::Update(float deltaTime) { + if (m_State == 0) return; + if (m_State & eMovementPlatformState::Travelling) { + m_MoveTimeElapsed += deltaTime; + + // Only need to recalculate the linear velocity if the speed is changing between waypoints + // Unfortunately for the poor client, they chose to, instead of change the speed once at the start of the waypoint, + // the speed is changed over the course of the waypoint. This means we have to recalculate the linear velocity every frame. + // yay. + if (GetCurrentWaypoint().movingPlatform.speed != GetNextWaypoint().movingPlatform.speed) { + UpdateLinearVelocity(); + } + m_Position += m_LinearVelocity * deltaTime; + } +} + +void PlatformSubComponent::UpdateLinearVelocity() { + m_LinearVelocity = CalculateLinearVelocity(); +} + void PlatformSubComponent::AdvanceToNextWaypoint() { uint32_t numWaypoints = m_Path->pathWaypoints.size(); m_CurrentWaypointIndex = m_NextWaypointIndex; @@ -51,6 +71,7 @@ void PlatformSubComponent::AdvanceToNextWaypoint() { } } m_NextWaypointIndex = nextWaypointIndex; + UpdateLinearVelocity(); } void PlatformSubComponent::AdvanceToNextReverseWaypoint() { @@ -69,6 +90,7 @@ void PlatformSubComponent::AdvanceToNextReverseWaypoint() { } } m_NextWaypointIndex = nextWaypointIndex; + UpdateLinearVelocity(); } void PlatformSubComponent::SetupPath(const std::string& pathName, uint32_t startingWaypointIndex, bool startsInReverse) { @@ -157,14 +179,6 @@ void PlatformSubComponent::StopPathing() { m_AngularVelocity = NiPoint3::ZERO; } -void PlatformSubComponent::Update(float deltaTime) { - if (m_TimeBasedMovement && m_State & eMovementPlatformState::Travelling) { - m_MoveTimeElapsed += deltaTime; - } - if (m_State == 0) return; - -} - //------------- PlatformSubComponent end -------------- //------------- MoverPlatformSubComponent begin -------------- diff --git a/dGame/dComponents/MovingPlatformComponent.h b/dGame/dComponents/MovingPlatformComponent.h index 94157c331..02904925e 100644 --- a/dGame/dComponents/MovingPlatformComponent.h +++ b/dGame/dComponents/MovingPlatformComponent.h @@ -62,6 +62,7 @@ class PlatformSubComponent { void AdvanceToNextWaypoint(); void AdvanceToNextReverseWaypoint(); NiPoint3 CalculateLinearVelocity(); + void UpdateLinearVelocity(); protected: #ifdef _MOVING_PLATFORM_TEST diff --git a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp index 8c70c0ee8..00a7608c0 100644 --- a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp @@ -30,7 +30,7 @@ class MovingPlatformComponentTests : public GameDependenciesTest { waypointMiddle.rotation = NiQuaternion(7, 8, 9, 10); PathWaypoint waypointEnd; - waypointEnd.position = NiPoint3(4, 5, 6); + waypointEnd.position = NiPoint3(4, 5, 7); waypointEnd.rotation = NiQuaternion(7, 8, 9, 10); path.pathWaypoints.push_back(waypointStart); @@ -375,7 +375,7 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformMoverSpeedCalculationTest) { MoverPlatformSubComponent moverPlatformSubComponent(nullptr); path.pathWaypoints.at(0).position = NiPoint3(99.296440, 419.293335, 207.219498); path.pathWaypoints.at(0).movingPlatform.speed = 16.0f; - + path.pathWaypoints.at(1).position = NiPoint3(141.680099, 419.990051, 208.680450); path.pathWaypoints.at(1).movingPlatform.speed = 16.0f; path.pathBehavior = PathBehavior::Bounce; @@ -392,3 +392,37 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformMoverSpeedCalculationTest) { ASSERT_FLOAT_EQ(r.z, 0.5511137843132); moverPlatformSubComponent.AdvanceToNextWaypoint(); } + +TEST_F(MovingPlatformComponentTests, MovingPlatformNextAndCurrentWaypointAccess) { + MoverPlatformSubComponent moverPlatformSubComponent(nullptr); + moverPlatformSubComponent._SetPath(&path); + moverPlatformSubComponent.m_CurrentWaypointIndex = 0; + moverPlatformSubComponent.m_NextWaypointIndex = 1; + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypoint().position, NiPoint3(1, 2, 3)); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypoint().position, NiPoint3(4, 5, 6)); + moverPlatformSubComponent.AdvanceToNextWaypoint(); + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypoint().position, NiPoint3(4, 5, 6)); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypoint().position, NiPoint3(4, 5, 7)); +} + +TEST_F(MovingPlatformComponentTests, MovingPlatformRunTest) { + MoverPlatformSubComponent moverPlatformSubComponent(nullptr); + moverPlatformSubComponent._SetPath(&path); + path.pathWaypoints.at(0).position = NiPoint3(99.296440f, 419.293335f, 207.219498f); + path.pathWaypoints.at(0).movingPlatform.speed = 16.0f; + path.pathWaypoints.at(1).position = NiPoint3(141.680099f, 419.990051f, 208.680450f); + path.pathWaypoints.at(1).movingPlatform.speed = 16.0f; + moverPlatformSubComponent.m_State = 0; + moverPlatformSubComponent.m_TimeBasedMovement = false; + moverPlatformSubComponent.m_State = eMovementPlatformState::Travelling; + moverPlatformSubComponent.m_CurrentWaypointIndex = 0; + moverPlatformSubComponent.m_NextWaypointIndex = 1; + moverPlatformSubComponent.m_Speed = 16.0f; + moverPlatformSubComponent.m_Position = path.pathWaypoints.at(0).position; + moverPlatformSubComponent.Update(2.65f); + + // just check that its close enough + EXPECT_LT(141.680099f - moverPlatformSubComponent.m_Position.x, 0.1f); + EXPECT_LT(419.990051f - moverPlatformSubComponent.m_Position.y, 0.1f); + EXPECT_LT(208.680450f - moverPlatformSubComponent.m_Position.z, 0.1f); +} From af8bc2c4581635ffb9b521d0017d697fa181720f Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sat, 5 Aug 2023 01:21:59 -0700 Subject: [PATCH 10/17] refactor to class style and not c style --- .../Tables/CDMovingPlatformComponentTable.cpp | 4 +- dGame/EntityManager.cpp | 2 +- dGame/dComponents/MovingPlatformComponent.cpp | 279 +++-------- dGame/dComponents/MovingPlatformComponent.h | 110 +++-- dGame/dGameMessages/GameMessages.cpp | 66 +-- .../02_server/Map/njhub/CavePrisonCage.cpp | 5 +- dZoneManager/Zone.h | 1 + tests/dGameTests/GameDependencies.cpp | 25 + tests/dGameTests/GameDependencies.h | 25 +- .../MovingPlatformComponentTests.cpp | 455 +++++++----------- 10 files changed, 386 insertions(+), 586 deletions(-) diff --git a/dDatabase/Tables/CDMovingPlatformComponentTable.cpp b/dDatabase/Tables/CDMovingPlatformComponentTable.cpp index af1aaa7a7..f4331eb29 100644 --- a/dDatabase/Tables/CDMovingPlatformComponentTable.cpp +++ b/dDatabase/Tables/CDMovingPlatformComponentTable.cpp @@ -1,7 +1,7 @@ #include "CDMovingPlatformComponentTable.h" CDMovingPlatformComponentTable::CDMovingPlatformComponentTable() { - auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MovementAIComponent"); + auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MovingPlatforms"); while (!tableData.eof()) { CDMovingPlatformTableEntry entry; entry.platformIsSimpleMover = tableData.getIntField("platformIsSimpleMover", 0) == 1; @@ -17,7 +17,7 @@ CDMovingPlatformComponentTable::CDMovingPlatformComponentTable() { } void CDMovingPlatformComponentTable::CachePlatformEntry(ComponentID id) { - auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM MovementAIComponent WHERE id = ?;"); + auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM MovingPlatforms WHERE id = ?;"); query.bind(1, static_cast(id)); auto tableData = query.execQuery(); diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index 28b5f5268..4f1b7373d 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -313,7 +313,7 @@ Entity* EntityManager::GetSpawnPointEntity(const std::string& spawnName) const { // Check if the spawn point entity is valid just in case return GetEntity(spawnPoint->second); } - +#include const std::unordered_map& EntityManager::GetSpawnPointEntities() const { return m_SpawnPoints; } diff --git a/dGame/dComponents/MovingPlatformComponent.cpp b/dGame/dComponents/MovingPlatformComponent.cpp index 1ef7d935d..01680bef3 100644 --- a/dGame/dComponents/MovingPlatformComponent.cpp +++ b/dGame/dComponents/MovingPlatformComponent.cpp @@ -19,24 +19,31 @@ //------------- PlatformSubComponent begin -------------- PlatformSubComponent::PlatformSubComponent(MovingPlatformComponent* parentComponent) { - m_Position = NiPoint3::ZERO; + DluAssert(parentComponent != nullptr); m_ParentComponent = parentComponent; + m_Position = parentComponent->GetParent()->GetPosition(); + m_Rotation = parentComponent->GetParent()->GetRotation(); m_State = eMovementPlatformState::Stopped | eMovementPlatformState::ReachedDesiredWaypoint; - m_DesiredWaypointIndex = 0; - m_InReverse = false; - m_ShouldStopAtDesiredWaypoint = false; - + m_DesiredWaypointIndex = -1; m_PercentUntilNextWaypoint = 0.0f; - m_CurrentWaypointIndex = 0; - m_NextWaypointIndex = 0; - + m_NextWaypointIndex = -1; m_IdleTimeElapsed = 0.0f; + m_Speed = 0.0f; + m_WaitTime = 0.0f; + m_MoveTimeElapsed = 0.0f; + m_IsDirty = false; + m_InReverse = false; + m_ShouldStopAtDesiredWaypoint = false; + m_LinearVelocity = NiPoint3::ZERO; + m_AngularVelocity = NiPoint3::ZERO; + m_TimeBasedMovement = false; + m_Path = nullptr; } void PlatformSubComponent::Update(float deltaTime) { - if (m_State == 0) return; + if (m_State == 0 || !m_Path) return; if (m_State & eMovementPlatformState::Travelling) { m_MoveTimeElapsed += deltaTime; @@ -44,13 +51,34 @@ void PlatformSubComponent::Update(float deltaTime) { // Unfortunately for the poor client, they chose to, instead of change the speed once at the start of the waypoint, // the speed is changed over the course of the waypoint. This means we have to recalculate the linear velocity every frame. // yay. - if (GetCurrentWaypoint().movingPlatform.speed != GetNextWaypoint().movingPlatform.speed) { + if (m_Speed == 0.0f || (GetCurrentWaypoint().movingPlatform.speed != GetNextWaypoint().movingPlatform.speed)) { UpdateLinearVelocity(); + m_IsDirty = true; } m_Position += m_LinearVelocity * deltaTime; + if (CalculatePercentToNextWaypoint() > 0.99) { + m_MoveTimeElapsed = 0; + m_ParentComponent->GetParent()->SetPosition(m_Position); + m_InReverse ? AdvanceToNextReverseWaypoint() : AdvanceToNextWaypoint(); + m_IsDirty = true; + Game::entityManager->SerializeEntity(m_ParentComponent->GetParent()); + } } } +float PlatformSubComponent::CalculatePercentToNextWaypoint() { + if (m_TimeBasedMovement) return 0; + float distanceToNextWaypoint = (GetNextWaypoint().position - GetCurrentWaypoint().position).Length(); + if (distanceToNextWaypoint == 0.0f) return 0; + float distanceToCurrentWaypoint = (m_Position - GetCurrentWaypoint().position).Length(); + return distanceToCurrentWaypoint / distanceToNextWaypoint; +} + +void PlatformSubComponent::UpdateAngularVelocity() { + // Update the angular velocity + // This one is sure to be fun... +} + void PlatformSubComponent::UpdateLinearVelocity() { m_LinearVelocity = CalculateLinearVelocity(); } @@ -58,6 +86,8 @@ void PlatformSubComponent::UpdateLinearVelocity() { void PlatformSubComponent::AdvanceToNextWaypoint() { uint32_t numWaypoints = m_Path->pathWaypoints.size(); m_CurrentWaypointIndex = m_NextWaypointIndex; + m_ParentComponent->GetParent()->SetPosition(GetCurrentWaypoint().position); + m_ParentComponent->GetParent()->SetRotation(GetCurrentWaypoint().rotation); uint32_t nextWaypointIndex = m_CurrentWaypointIndex + 1; if (numWaypoints <= nextWaypointIndex) { PathBehavior behavior = m_Path->pathBehavior; @@ -71,11 +101,16 @@ void PlatformSubComponent::AdvanceToNextWaypoint() { } } m_NextWaypointIndex = nextWaypointIndex; + m_DesiredWaypointIndex = nextWaypointIndex; UpdateLinearVelocity(); + UpdateAngularVelocity(); + m_IsDirty = true; } void PlatformSubComponent::AdvanceToNextReverseWaypoint() { uint32_t numWaypoints = m_Path->pathWaypoints.size(); + m_ParentComponent->GetParent()->SetPosition(GetCurrentWaypoint().position); + m_ParentComponent->GetParent()->SetRotation(GetCurrentWaypoint().rotation); m_CurrentWaypointIndex = m_NextWaypointIndex; int32_t nextWaypointIndex = m_CurrentWaypointIndex - 1; if (nextWaypointIndex < 0) { @@ -90,11 +125,15 @@ void PlatformSubComponent::AdvanceToNextReverseWaypoint() { } } m_NextWaypointIndex = nextWaypointIndex; + m_DesiredWaypointIndex = nextWaypointIndex; UpdateLinearVelocity(); + UpdateAngularVelocity(); + m_IsDirty = true; } void PlatformSubComponent::SetupPath(const std::string& pathName, uint32_t startingWaypointIndex, bool startsInReverse) { m_Path = Game::zoneManager->GetZone()->GetPath(pathName); + Game::logger->Log("MovingPlatformComponent", "setting up path %s", pathName.c_str()); if (!m_Path) { Game::logger->Log("MovingPlatformComponent", "Failed to find path (%s)", pathName.c_str()); return; @@ -104,15 +143,13 @@ void PlatformSubComponent::SetupPath(const std::string& pathName, uint32_t start m_TimeBasedMovement = m_Path->movingPlatform.timeBasedMovement; } -const PathWaypoint PlatformSubComponent::GetNextWaypoint() const { +const PathWaypoint& PlatformSubComponent::GetNextWaypoint() const { DluAssert(m_Path != nullptr); - if (m_NextWaypointIndex >= m_Path->pathWaypoints.size()) return PathWaypoint(); return m_Path->pathWaypoints.at(m_NextWaypointIndex); } -const PathWaypoint PlatformSubComponent::GetCurrentWaypoint() const { +const PathWaypoint& PlatformSubComponent::GetCurrentWaypoint() const { DluAssert(m_Path != nullptr); - if (m_CurrentWaypointIndex >= m_Path->pathWaypoints.size()) return PathWaypoint(); return m_Path->pathWaypoints.at(m_CurrentWaypointIndex); } @@ -146,6 +183,7 @@ void PlatformSubComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn outBitStream->Write(m_NextWaypointIndex); outBitStream->Write(m_IdleTimeElapsed); outBitStream->Write(m_MoveTimeElapsed); + if (!bIsInitialUpdate) m_IsDirty = false; } @@ -153,6 +191,11 @@ void PlatformSubComponent::StartPathing() { m_State |= eMovementPlatformState::Travelling; m_State &= ~eMovementPlatformState::Stopped; m_State &= ~eMovementPlatformState::Waiting; + m_IsDirty = true; + m_CurrentWaypointIndex = m_ParentComponent->GetStartingWaypointIndex(); + m_InReverse = m_ParentComponent->GetStartsIsInReverse(); + m_NextWaypointIndex = m_InReverse ? m_CurrentWaypointIndex - 1 : m_CurrentWaypointIndex + 1; + Game::entityManager->SerializeEntity(m_ParentComponent->GetParent()); } void PlatformSubComponent::ResumePathing() { @@ -163,11 +206,14 @@ void PlatformSubComponent::ResumePathing() { m_State |= eMovementPlatformState::Waiting; m_State &= ~eMovementPlatformState::Stopped; m_State &= ~eMovementPlatformState::Travelling; + m_IsDirty = true; } else { m_State &= eMovementPlatformState::Waiting; m_State &= eMovementPlatformState::Travelling; m_State &= eMovementPlatformState::Stopped; - // Set the velocities + m_IsDirty = true; + UpdateLinearVelocity(); + UpdateAngularVelocity(); } } @@ -266,7 +312,7 @@ SimpleMoverPlatformSubComponent::SimpleMoverPlatformSubComponent(MovingPlatformC //------------- MovingPlatformComponent begin -------------- MovingPlatformComponent::MovingPlatformComponent(Entity* parent, const std::string& pathName) : Component(parent) { - + m_PathName = GeneralUtils::ASCIIToUTF16(pathName); } void MovingPlatformComponent::LoadDataFromTemplate() { @@ -274,18 +320,23 @@ void MovingPlatformComponent::LoadDataFromTemplate() { } void MovingPlatformComponent::LoadConfigData() { - if (m_Parent->GetVar(u"platformIsSimpleMover")) { - AddMovingPlatform(NiPoint3::ZERO, false); - } if (m_Parent->GetVar(u"platformIsMover")) { AddMovingPlatform(); } + if (m_Parent->GetVar(u"platformIsSimpleMover")) { + AddMovingPlatform(NiPoint3::ZERO, false); + } if (m_Parent->GetVar(u"platformIsRotater")) { AddMovingPlatform(); } m_StartingWaypointIndex = m_Parent->GetVar(u"attached_path_start"); m_StartsIsInReverse = false; m_DirtyPathInfo = true; + m_StartOnload = m_Parent->GetVar(u"startPathingOnLoad"); +} + +void MovingPlatformComponent::Update(float deltaTime) { + std::for_each(m_Platforms.begin(), m_Platforms.end(), [deltaTime](const std::unique_ptr& platform) { platform->Update(deltaTime); }); } void MovingPlatformComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { @@ -326,227 +377,39 @@ void MovingPlatformComponent::OnCompleteRebuild() { } void MovingPlatformComponent::SetMovementState(eMovementPlatformState value) { - // auto* subComponent = static_cast(m_MoverSubComponent); - - // subComponent->mState = value; - - // Game::entityManager->SerializeEntity(m_Parent); } void MovingPlatformComponent::GotoWaypoint(uint32_t index, bool stopAtWaypoint) { - // auto* subComponent = static_cast(m_MoverSubComponent); - - // subComponent->mDesiredWaypointIndex = index; - // subComponent->mNextWaypointIndex = index; - // subComponent->mShouldStopAtDesiredWaypoint = stopAtWaypoint; - - // StartPathing(); } void MovingPlatformComponent::StartPathing() { std::for_each(m_Platforms.begin(), m_Platforms.end(), [](const std::unique_ptr& platform) { platform->StartPathing(); }); - // state == Travelling - // //GameMessages::SendStartPathing(m_Parent); - // m_PathingStopped = false; - - // auto* subComponent = static_cast(m_MoverSubComponent); - - // subComponent->mShouldStopAtDesiredWaypoint = true; - // subComponent->mState = eMovementPlatformState::Stationary; - - // NiPoint3 targetPosition; - - // if (m_Path != nullptr) { - // const auto& currentWaypoint = m_Path->pathWaypoints[subComponent->mCurrentWaypointIndex]; - // const auto& nextWaypoint = m_Path->pathWaypoints[subComponent->mNextWaypointIndex]; - - // subComponent->mPosition = currentWaypoint.position; - // subComponent->mSpeed = currentWaypoint.movingPlatform.speed; - // subComponent->mWaitTime = currentWaypoint.movingPlatform.wait; - - // targetPosition = nextWaypoint.position; - // } else { - // subComponent->mPosition = m_Parent->GetPosition(); - // subComponent->mSpeed = 1.0f; - // subComponent->mWaitTime = 2.0f; - - // targetPosition = m_Parent->GetPosition() + NiPoint3(0.0f, 10.0f, 0.0f); - // } - - // m_Parent->AddCallbackTimer(subComponent->mWaitTime, [this] { - // SetMovementState(eMovementPlatformState::Moving); - // }); - - // const auto travelTime = Vector3::Distance(targetPosition, subComponent->mPosition) / subComponent->mSpeed + 1.5f; - - // const auto travelNext = subComponent->mWaitTime + travelTime; - - // m_Parent->AddCallbackTimer(travelTime, [subComponent, this] { - // for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) { - // script->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex); - // } - // }); - - // m_Parent->AddCallbackTimer(travelNext, [this] { - // ContinuePathing(); - // }); - - // //GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS); - - // Game::entityManager->SerializeEntity(m_Parent); } void MovingPlatformComponent::ContinuePathing() { - // state == Travelling - // auto* subComponent = static_cast(m_MoverSubComponent); - - // subComponent->mState = eMovementPlatformState::Stationary; - - // subComponent->mCurrentWaypointIndex = subComponent->mNextWaypointIndex; - - // NiPoint3 targetPosition; - // uint32_t pathSize; - // PathBehavior behavior; - - // if (m_Path != nullptr) { - // const auto& currentWaypoint = m_Path->pathWaypoints[subComponent->mCurrentWaypointIndex]; - // const auto& nextWaypoint = m_Path->pathWaypoints[subComponent->mNextWaypointIndex]; - - // subComponent->mPosition = currentWaypoint.position; - // subComponent->mSpeed = currentWaypoint.movingPlatform.speed; - // subComponent->mWaitTime = currentWaypoint.movingPlatform.wait; // + 2; - - // pathSize = m_Path->pathWaypoints.size() - 1; - - // behavior = static_cast(m_Path->pathBehavior); - - // targetPosition = nextWaypoint.position; - // } else { - // subComponent->mPosition = m_Parent->GetPosition(); - // subComponent->mSpeed = 1.0f; - // subComponent->mWaitTime = 2.0f; - - // targetPosition = m_Parent->GetPosition() + NiPoint3(0.0f, 10.0f, 0.0f); - - // pathSize = 1; - // behavior = PathBehavior::Loop; - // } - - // if (m_Parent->GetLOT() == 9483) { - // behavior = PathBehavior::Bounce; - // } else { - // return; - // } - - // if (subComponent->mCurrentWaypointIndex >= pathSize) { - // subComponent->mCurrentWaypointIndex = pathSize; - // switch (behavior) { - // case PathBehavior::Once: - // Game::entityManager->SerializeEntity(m_Parent); - // return; - - // case PathBehavior::Bounce: - // subComponent->mInReverse = true; - // break; - - // case PathBehavior::Loop: - // subComponent->mNextWaypointIndex = 0; - // break; - // default: - // break; - // } - // } else if (subComponent->mCurrentWaypointIndex == 0) { - // subComponent->mInReverse = false; - // } - - // if (subComponent->mInReverse) { - // subComponent->mNextWaypointIndex = subComponent->mCurrentWaypointIndex - 1; - // } else { - // subComponent->mNextWaypointIndex = subComponent->mCurrentWaypointIndex + 1; - // } - - // /* - // subComponent->mNextWaypointIndex = 0; - // subComponent->mCurrentWaypointIndex = 1; - // */ - - // //GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS); - - // if (subComponent->mCurrentWaypointIndex == subComponent->mDesiredWaypointIndex) { - // // TODO: Send event? - // StopPathing(); - - // return; - // } - - // m_Parent->CancelCallbackTimers(); - - // m_Parent->AddCallbackTimer(subComponent->mWaitTime, [this] { - // SetMovementState(eMovementPlatformState::Moving); - // }); - - // auto travelTime = Vector3::Distance(targetPosition, subComponent->mPosition) / subComponent->mSpeed + 1.5; - - // if (m_Parent->GetLOT() == 9483) { - // travelTime += 20; - // } - - // const auto travelNext = subComponent->mWaitTime + travelTime; - - // m_Parent->AddCallbackTimer(travelTime, [subComponent, this] { - // for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) { - // script->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex); - // } - // }); - - // m_Parent->AddCallbackTimer(travelNext, [this] { - // ContinuePathing(); - // }); - - // Game::entityManager->SerializeEntity(m_Parent); } void MovingPlatformComponent::StopPathing() { - // state == Stopped - //m_Parent->CancelCallbackTimers(); - - // auto* subComponent = static_cast(m_MoverSubComponent); - - // m_PathingStopped = true; - // subComponent->mState = eMovementPlatformState::Stopped; - // subComponent->mDesiredWaypointIndex = -1; - // subComponent->mShouldStopAtDesiredWaypoint = false; - - // Game::entityManager->SerializeEntity(m_Parent); - - //GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS); } bool MovingPlatformComponent::GetNoAutoStart() const { return false; - // return m_NoAutoStart; } void MovingPlatformComponent::SetNoAutoStart(const bool value) { - // m_NoAutoStart = value; + } void MovingPlatformComponent::WarpToWaypoint(size_t index) { - // const auto& waypoint = m_Path->pathWaypoints[index]; - - // m_Parent->SetPosition(waypoint.position); - // m_Parent->SetRotation(waypoint.rotation); - // Game::entityManager->SerializeEntity(m_Parent); } size_t MovingPlatformComponent::GetLastWaypointIndex() const { return 0; - // return m_Path->pathWaypoints.size() - 1; } //------------- MovingPlatformComponent end -------------- diff --git a/dGame/dComponents/MovingPlatformComponent.h b/dGame/dComponents/MovingPlatformComponent.h index 02904925e..fb0756222 100644 --- a/dGame/dComponents/MovingPlatformComponent.h +++ b/dGame/dComponents/MovingPlatformComponent.h @@ -42,6 +42,8 @@ enum class eMoverSubComponentType : uint32_t { class MovingPlatformComponent; +// In the context of a platform that is TimeBasedMovement, +// the speed member from the Path is used as the time to go between waypoints. class PlatformSubComponent { public: PlatformSubComponent(MovingPlatformComponent* parentComponent); @@ -56,43 +58,61 @@ class PlatformSubComponent { virtual void StopPathing(); virtual void Update(float deltaTime); float CalculateSpeed() const; - const PathWaypoint GetNextWaypoint() const; - const PathWaypoint GetCurrentWaypoint() const; + const PathWaypoint& GetNextWaypoint() const; + const PathWaypoint& GetCurrentWaypoint() const; void SetupPath(const std::string& pathName, uint32_t startingWaypointIndex, bool startsInReverse); void AdvanceToNextWaypoint(); void AdvanceToNextReverseWaypoint(); NiPoint3 CalculateLinearVelocity(); void UpdateLinearVelocity(); -protected: + void UpdateAngularVelocity(); + float CalculatePercentToNextWaypoint(); + + // Write all the getters for the below members + bool GetTimeBasedMovement() const { return m_TimeBasedMovement; } + const Path* GetPath() const { return m_Path; } + float GetSpeed() const { return m_Speed; } + float GetWaitTime() const { return m_WaitTime; } + float GetMoveTimeElapsed() const { return m_MoveTimeElapsed; } + float GetPercentUntilNextWaypoint() const { return m_PercentUntilNextWaypoint; } + int32_t GetCurrentWaypointIndex() const { return m_CurrentWaypointIndex; } + int32_t GetNextWaypointIndex() const { return m_NextWaypointIndex; } + bool GetInReverse() const { return m_InReverse; } + bool GetShouldStopAtDesiredWaypoint() const { return m_ShouldStopAtDesiredWaypoint; } + int32_t GetDesiredWaypointIndex() const { return m_DesiredWaypointIndex; } + uint32_t GetState() const { return m_State; } + const NiPoint3& GetPosition() const { return m_Position; } + const NiQuaternion& GetRotation() const { return m_Rotation; } + const NiPoint3& GetLinearVelocity() const { return m_LinearVelocity; } + const NiPoint3& GetAngularVelocity() const { return m_AngularVelocity; } + const MovingPlatformComponent* GetParentComponent() const { return m_ParentComponent; } + const float GetIdleTimeElapsed() const { return m_IdleTimeElapsed; } -#ifdef _MOVING_PLATFORM_TEST -public: - void _SetPath(const Path* path) { - m_Path = path; - } -#endif - MovingPlatformComponent* m_ParentComponent = nullptr; + +protected: + MovingPlatformComponent* m_ParentComponent; /** * The state the platform is currently in */ - uint32_t m_State = eMovementPlatformState::Stopped | eMovementPlatformState::ReachedDesiredWaypoint; - int32_t m_DesiredWaypointIndex = 0; - float m_PercentUntilNextWaypoint = 0; + uint32_t m_State; + int32_t m_DesiredWaypointIndex; + float m_PercentUntilNextWaypoint; NiPoint3 m_Position; int32_t m_CurrentWaypointIndex; int32_t m_NextWaypointIndex; - float m_IdleTimeElapsed = 0; - float m_Speed = 0; - float m_WaitTime = 0; - float m_MoveTimeElapsed = 0; - bool m_IsDirty = false; - bool m_InReverse = false; - bool m_ShouldStopAtDesiredWaypoint = false; + float m_IdleTimeElapsed; + float m_Speed; + float m_WaitTime; + float m_MoveTimeElapsed; + bool m_IsDirty; + bool m_InReverse; + bool m_ShouldStopAtDesiredWaypoint; NiPoint3 m_LinearVelocity; NiPoint3 m_AngularVelocity; - bool m_TimeBasedMovement = false; - const Path* m_Path = nullptr; + bool m_TimeBasedMovement; + const Path* m_Path; + NiQuaternion m_Rotation; }; class MoverPlatformSubComponent : public PlatformSubComponent { @@ -146,6 +166,7 @@ class MovingPlatformComponent : public Component { void LoadDataFromTemplate(); void LoadConfigData(); + void Update(float deltaTime) override; void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); @@ -228,23 +249,32 @@ class MovingPlatformComponent : public Component { } } - int32_t GetComponentId() const { return componentId; } + bool HasPlatform() { return !m_Platforms.empty(); } -#ifdef _MOVING_PLATFORM_TEST - /** - * Only used for testing. Do not call in production code. Let the constructor take care of this. - * - * @param platformSubComponent - */ - void _AddPlatformSubComponent(std::unique_ptr platformSubComponent) { - m_Platforms.push_back(std::move(platformSubComponent)); + const PlatformSubComponent& GetPlatform() const { + return *m_Platforms.at(0); } - void _SetPath(const std::u16string& path) { - m_PathName = path; - m_DirtyPathInfo = true; -} -#endif + int32_t GetComponentId() const { return componentId; } + + // Make + const std::u16string& GetPathName() const { return m_PathName; } + void SetPathName(const std::u16string& pathName) { m_PathName = pathName; } + + bool GetPathingStopped() const { return m_PathingStopped; } + void SetPathingStopped(bool value) { m_PathingStopped = value; } + + uint32_t GetStartingWaypointIndex() const { return m_StartingWaypointIndex; } + void SetStartingWaypointIndex(uint32_t value) { m_StartingWaypointIndex = value; } + + bool GetStartsIsInReverse() const { return m_StartsIsInReverse; } + void SetStartsIsInReverse(bool value) { m_StartsIsInReverse = value; } + + bool GetStartOnload() const { return m_StartOnload; } + void SetStartOnload(bool value) { m_StartOnload = value; } + + bool GetDirtyPathInfo() const { return m_DirtyPathInfo; } + private: /** * The name of the path this platform is currently on @@ -260,7 +290,7 @@ class MovingPlatformComponent : public Component { bool m_StartsIsInReverse = false; - int32_t componentId = -1;; + int32_t componentId = -1; /** * The mover sub component that belongs to this platform @@ -272,12 +302,8 @@ class MovingPlatformComponent : public Component { */ bool m_NoAutoStart; - /** - * Whether to serialize the entity on the next update - */ - bool m_Serialize = false; - bool m_DirtyPathInfo = false; + bool m_StartOnload = false; }; #endif // MOVINGPLATFORMCOMPONENT_H diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index ee21006eb..195570199 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -357,48 +357,35 @@ void GameMessages::SendPlatformResync(Entity* entity, const SystemAddress& sysAd const auto lot = entity->GetLOT(); - if (lot == 12341 || lot == 5027 || lot == 5028 || lot == 14335 || lot == 14447 || lot == 14449) { - iDesiredWaypointIndex = 0; - iIndex = 0; - nextIndex = 0; - bStopAtDesiredWaypoint = true; - movementState = static_cast( - eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint); - } - bitStream.Write(entity->GetObjectID()); bitStream.Write((uint16_t)eGameMessageType::PLATFORM_RESYNC); - bool bReverse = false; - int eCommand = 0; - int eUnexpectedCommand = 0; - float fIdleTimeElapsed = 0.0f; - float fMoveTimeElapsed = 0.0f; - float fPercentBetweenPoints = 0.0f; - NiPoint3 ptUnexpectedLocation = NiPoint3::ZERO; - NiQuaternion qUnexpectedRotation = NiQuaternion::IDENTITY; - - bitStream.Write(bReverse); - bitStream.Write(bStopAtDesiredWaypoint); - bitStream.Write(eCommand); - bitStream.Write(static_cast(movementState)); - bitStream.Write(eUnexpectedCommand); - bitStream.Write(fIdleTimeElapsed); - bitStream.Write(fMoveTimeElapsed); - bitStream.Write(fPercentBetweenPoints); - bitStream.Write(iDesiredWaypointIndex); - bitStream.Write(iIndex); - bitStream.Write(nextIndex); - bitStream.Write(ptUnexpectedLocation.x); - bitStream.Write(ptUnexpectedLocation.y); - bitStream.Write(ptUnexpectedLocation.z); - - bitStream.Write(qUnexpectedRotation != NiQuaternion::IDENTITY); - if (qUnexpectedRotation != NiQuaternion::IDENTITY) { - bitStream.Write(qUnexpectedRotation.x); - bitStream.Write(qUnexpectedRotation.y); - bitStream.Write(qUnexpectedRotation.z); - bitStream.Write(qUnexpectedRotation.w); + auto* movingPlatformComponent = entity->GetComponent(); + if (!movingPlatformComponent) return; + if (!movingPlatformComponent->HasPlatform()) return; + auto& subComponent = movingPlatformComponent->GetPlatform(); + + bitStream.Write(subComponent.GetInReverse()); + bitStream.Write(subComponent.GetShouldStopAtDesiredWaypoint()); + bitStream.Write(0); + bitStream.Write(subComponent.GetState()); + bitStream.Write(0); + bitStream.Write(subComponent.GetIdleTimeElapsed()); + bitStream.Write(subComponent.GetMoveTimeElapsed()); + bitStream.Write(subComponent.GetPercentUntilNextWaypoint()); + bitStream.Write(subComponent.GetDesiredWaypointIndex()); + bitStream.Write(subComponent.GetCurrentWaypointIndex()); + bitStream.Write(subComponent.GetNextWaypointIndex()); + bitStream.Write(subComponent.GetPosition().x); + bitStream.Write(subComponent.GetPosition().y); + bitStream.Write(subComponent.GetPosition().z); + + bitStream.Write(subComponent.GetRotation() != NiQuaternion::IDENTITY); + if (subComponent.GetRotation() != NiQuaternion::IDENTITY) { + bitStream.Write(subComponent.GetRotation().x); + bitStream.Write(subComponent.GetRotation().y); + bitStream.Write(subComponent.GetRotation().z); + bitStream.Write(subComponent.GetRotation().w); } SEND_PACKET_BROADCAST; @@ -5006,7 +4993,6 @@ void GameMessages::HandleFireEventServerSide(RakNet::BitStream* inStream, Entity } void GameMessages::HandleRequestPlatformResync(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { - if (entity->GetLOT() == 6267 || entity->GetLOT() == 16141) return; GameMessages::SendPlatformResync(entity, sysAddr, eMovementPlatformState::Travelling); } diff --git a/dScripts/02_server/Map/njhub/CavePrisonCage.cpp b/dScripts/02_server/Map/njhub/CavePrisonCage.cpp index 9bd890679..0f8cdd3f1 100644 --- a/dScripts/02_server/Map/njhub/CavePrisonCage.cpp +++ b/dScripts/02_server/Map/njhub/CavePrisonCage.cpp @@ -5,6 +5,7 @@ #include "Character.h" #include "dZoneManager.h" #include "RenderComponent.h" +#include "MovingPlatformComponent.h" void CavePrisonCage::OnStartup(Entity* self) { const auto& myNum = self->GetVar(u"myNumber"); @@ -83,8 +84,8 @@ void CavePrisonCage::SpawnCounterweight(Entity* self, Spawner* spawner) { return; } - // Move the counterweight down 2 units - counterweight->SetPosition(counterweight->GetPosition() + NiPoint3(0, -2, 0)); + auto* mpc = counterweight->GetComponent(); + if (mpc) mpc->StartPathing(); // Serialize the counterweight Game::entityManager->SerializeEntity(counterweight); diff --git a/dZoneManager/Zone.h b/dZoneManager/Zone.h index b3e720366..798cab65f 100644 --- a/dZoneManager/Zone.h +++ b/dZoneManager/Zone.h @@ -203,6 +203,7 @@ class Zone { const void PrintAllGameObjects(); LUTriggers::Trigger* GetTrigger(uint32_t sceneID, uint32_t triggerID); const Path* GetPath(std::string name) const; + void AddPath(const Path& path) { m_Paths.push_back(path); }; uint32_t GetWorldID() const { return m_WorldID; } [[nodiscard]] std::string GetZoneName() const { return m_ZoneName; } diff --git a/tests/dGameTests/GameDependencies.cpp b/tests/dGameTests/GameDependencies.cpp index 1765bd9b9..11b341988 100644 --- a/tests/dGameTests/GameDependencies.cpp +++ b/tests/dGameTests/GameDependencies.cpp @@ -12,3 +12,28 @@ namespace Game { SystemAddress chatSysAddr; EntityManager* entityManager = nullptr; } + +void GameDependenciesTest::SetUpDependencies() { + info.pos = NiPoint3::ZERO; + info.rot = NiQuaternion::IDENTITY; + info.scale = 1.0f; + info.spawner = nullptr; + info.lot = 999; + Game::logger = new dLogger("./testing.log", true, true); + Game::server = new dServerMock(); + Game::config = new dConfig("worldconfig.ini"); + Game::entityManager = new EntityManager(); + Game::zoneManager = new dZoneManager(); + Game::zoneManager->LoadZone(LWOZONEID(0, 0, 0)); +} + +void GameDependenciesTest::TearDownDependencies() { + if (Game::server) delete Game::server; + if (Game::entityManager) delete Game::entityManager; + if (Game::config) delete Game::config; + if (Game::zoneManager) delete Game::zoneManager; + if (Game::logger) { + Game::logger->Flush(); + delete Game::logger; + } +} diff --git a/tests/dGameTests/GameDependencies.h b/tests/dGameTests/GameDependencies.h index 95ef2f9f2..205b8f742 100644 --- a/tests/dGameTests/GameDependencies.h +++ b/tests/dGameTests/GameDependencies.h @@ -6,6 +6,7 @@ #include "dServer.h" #include "EntityInfo.h" #include "EntityManager.h" +#include "dZoneManager.h" #include "dConfig.h" #include @@ -23,29 +24,11 @@ class dServerMock : public dServer { class GameDependenciesTest : public ::testing::Test { protected: - void SetUpDependencies() { - info.pos = NiPoint3::ZERO; - info.rot = NiQuaternion::IDENTITY; - info.scale = 1.0f; - info.spawner = nullptr; - info.lot = 999; - Game::logger = new dLogger("./testing.log", true, true); - Game::server = new dServerMock(); - Game::config = new dConfig("worldconfig.ini"); - Game::entityManager = new EntityManager(); - } + void SetUpDependencies(); - void TearDownDependencies() { - if (Game::server) delete Game::server; - if (Game::entityManager) delete Game::entityManager; - if (Game::logger) { - Game::logger->Flush(); - delete Game::logger; - } - if (Game::config) delete Game::config; - } + void TearDownDependencies(); - EntityInfo info{}; + EntityInfo info; }; #endif //!__GAMEDEPENDENCIES__H__ diff --git a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp index 00a7608c0..1ce8c6874 100644 --- a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp @@ -21,6 +21,7 @@ class MovingPlatformComponentTests : public GameDependenciesTest { SetUpDependencies(); path.movingPlatform.timeBasedMovement = false; path.pathBehavior = PathBehavior::Once; + path.pathName = "ExamplePath"; PathWaypoint waypointStart; waypointStart.position = NiPoint3(1, 2, 3); waypointStart.rotation = NiQuaternion(4, 5, 6, 7); @@ -37,259 +38,186 @@ class MovingPlatformComponentTests : public GameDependenciesTest { path.pathWaypoints.push_back(waypointMiddle); path.pathWaypoints.push_back(waypointEnd); + Game::zoneManager->GetZone()->AddPath(path); + + // Set our starting position + info.pos = NiPoint3(25, 26, 27); + info.rot = NiQuaternion(28, 29, 30, 31); + + // Simple mover data + info.settings.push_back(new LDFData(u"platformMoveX", 23)); + info.settings.push_back(new LDFData(u"platformMoveY", 453)); + info.settings.push_back(new LDFData(u"platformMoveZ", 523)); + info.settings.push_back(new LDFData(u"platformMoveTime", 5724)); + info.settings.push_back(new LDFData(u"platformStartAtEnd", true)); + info.settings.push_back(new LDFData(u"dbonly", false)); + info.settings.push_back(new LDFData(u"platformIsMover", true)); + info.settings.push_back(new LDFData(u"platformIsSimpleMover", true)); + info.settings.push_back(new LDFData(u"platformIsRotater", true)); + baseEntity = std::make_unique(15, GameDependenciesTest::info); - baseEntity->SetVar(u"dbonly", false); - baseEntity->SetVar(u"platformMoveX", 23); - baseEntity->SetVar(u"platformMoveY", 453); - baseEntity->SetVar(u"platformMoveZ", 523); - baseEntity->SetVar(u"platformMoveTime", 5724); - baseEntity->SetVar(u"platformStartAtEnd", true); - auto* movingPlatformComponent = new MovingPlatformComponent(baseEntity.get(), ""); + auto* simplePhysicsComponent = new SimplePhysicsComponent(1, baseEntity.get()); - baseEntity->AddComponent(eReplicaComponentType::MOVING_PLATFORM, movingPlatformComponent); - baseEntity->AddComponent(eReplicaComponentType::SIMPLE_PHYSICS, simplePhysicsComponent); - baseEntity->SetPosition(NiPoint3(25, 26, 27)); - baseEntity->SetRotation(NiQuaternion(28, 29, 30, 31)); - auto moverPlatformSubComponent = std::make_unique(movingPlatformComponent); - moverPlatformSubComponent->m_State = eMovementPlatformState::Stopped | eMovementPlatformState::ReachedDesiredWaypoint; - moverPlatformSubComponent->m_DesiredWaypointIndex = 1; - moverPlatformSubComponent->m_PercentUntilNextWaypoint = 2; - moverPlatformSubComponent->m_Position = NiPoint3(3, 4, 5); - moverPlatformSubComponent->m_CurrentWaypointIndex = 6; - moverPlatformSubComponent->m_NextWaypointIndex = 7; - moverPlatformSubComponent->m_IdleTimeElapsed = 8; - moverPlatformSubComponent->m_MoveTimeElapsed = 11; - moverPlatformSubComponent->m_IsDirty = true; - moverPlatformSubComponent->m_InReverse = true; - moverPlatformSubComponent->m_ShouldStopAtDesiredWaypoint = true; - - auto rotatorPlatformSubComponent = std::make_unique(movingPlatformComponent); - rotatorPlatformSubComponent->m_State = eMovementPlatformState::Travelling; - rotatorPlatformSubComponent->m_DesiredWaypointIndex = 12; - rotatorPlatformSubComponent->m_PercentUntilNextWaypoint = 13; - rotatorPlatformSubComponent->m_Position = NiPoint3(14, 15, 16); - rotatorPlatformSubComponent->m_CurrentWaypointIndex = 17; - rotatorPlatformSubComponent->m_NextWaypointIndex = 18; - rotatorPlatformSubComponent->m_IdleTimeElapsed = 19; - rotatorPlatformSubComponent->m_MoveTimeElapsed = 22; - rotatorPlatformSubComponent->m_IsDirty = true; - rotatorPlatformSubComponent->m_InReverse = true; - rotatorPlatformSubComponent->m_ShouldStopAtDesiredWaypoint = true; - - auto simpleMoverPlatformSubComponent = std::make_unique(movingPlatformComponent, NiPoint3(), true); - simpleMoverPlatformSubComponent->m_State = eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint; - simpleMoverPlatformSubComponent->m_DesiredWaypointIndex = 23; - simpleMoverPlatformSubComponent->m_PercentUntilNextWaypoint = 24; - simpleMoverPlatformSubComponent->m_CurrentWaypointIndex = 28; - simpleMoverPlatformSubComponent->m_NextWaypointIndex = 29; - simpleMoverPlatformSubComponent->m_IdleTimeElapsed = 30; - simpleMoverPlatformSubComponent->m_MoveTimeElapsed = 33; - simpleMoverPlatformSubComponent->m_IsDirty = true; - simpleMoverPlatformSubComponent->m_InReverse = true; - simpleMoverPlatformSubComponent->m_DirtyStartingPoint = true; - simpleMoverPlatformSubComponent->m_HasStartingPoint = true; - simpleMoverPlatformSubComponent->m_ShouldStopAtDesiredWaypoint = true; - simpleMoverPlatformSubComponent->LoadConfigData(); - - movingPlatformComponent->_AddPlatformSubComponent(std::move(moverPlatformSubComponent)); - movingPlatformComponent->_AddPlatformSubComponent(std::move(rotatorPlatformSubComponent)); - movingPlatformComponent->_AddPlatformSubComponent(std::move(simpleMoverPlatformSubComponent)); - movingPlatformComponent->_SetPath(u"ExamplePath"); + baseEntity->AddComponent(SimplePhysicsComponent::ComponentType, simplePhysicsComponent); + auto* movingPlatformComponent = new MovingPlatformComponent(baseEntity.get(), path.pathName); + movingPlatformComponent->LoadConfigData(); + movingPlatformComponent->LoadDataFromTemplate(); + baseEntity->AddComponent(MovingPlatformComponent::ComponentType, movingPlatformComponent); } void TearDown() override { TearDownDependencies(); } - void TestSerialization() { - auto* movingPlatformComponent = baseEntity->GetComponent(); - ASSERT_NE(movingPlatformComponent, nullptr); - uint32_t flags = 0; - movingPlatformComponent->Serialize(&bitStream, true, flags); - // read in the full BitStream and check the values match what they were set to above - bool hasPlatformSubComponents = false; - bitStream.Read(hasPlatformSubComponents); - ASSERT_TRUE(hasPlatformSubComponents); + void DeserializeSimpleMoverPlatformSubComponent() { + bool dirtyStartingPoint; + bitStream.Read(dirtyStartingPoint); + ASSERT_TRUE(dirtyStartingPoint); - bool dirtyPathInfo; - bitStream.Read(dirtyPathInfo); - ASSERT_TRUE(dirtyPathInfo); + bool hasStartingPoint; + bitStream.Read(hasStartingPoint); + ASSERT_TRUE(hasStartingPoint); - bool hasPath; - bitStream.Read(hasPath); - ASSERT_TRUE(hasPath); + NiPoint3 startingPoint; + bitStream.Read(startingPoint.x); + bitStream.Read(startingPoint.y); + bitStream.Read(startingPoint.z); + ASSERT_EQ(startingPoint, NiPoint3(25, 26, 27)); - std::u16string pathName; - uint16_t pathNameLength; - bitStream.Read(pathNameLength); - pathName.resize(pathNameLength); - bitStream.ReadBits(reinterpret_cast(pathName.data()), BYTES_TO_BITS(pathNameLength) * 2); - ASSERT_EQ(pathName, u"ExamplePath"); + NiQuaternion startingRotation; + bitStream.Read(startingRotation.w); + bitStream.Read(startingRotation.x); + bitStream.Read(startingRotation.y); + bitStream.Read(startingRotation.z); + ASSERT_EQ(startingRotation, NiQuaternion(28, 29, 30, 31)); - uint32_t pathStartIndex; - bitStream.Read(pathStartIndex); - ASSERT_EQ(pathStartIndex, 0); + bool isDirty; + bitStream.Read(isDirty); + ASSERT_TRUE(isDirty); + + eMovementPlatformState state; + bitStream.Read(state); + ASSERT_EQ(state, eMovementPlatformState::Stopped | eMovementPlatformState::ReachedDesiredWaypoint); + + int32_t currentWaypointIndex; + bitStream.Read(currentWaypointIndex); + ASSERT_EQ(currentWaypointIndex, 0); bool isInReverse; bitStream.Read(isInReverse); ASSERT_FALSE(isInReverse); + } - bool hasPlatformData; - bitStream.Read(hasPlatformData); - ASSERT_TRUE(hasPlatformData); - - eMoverSubComponentType platformType; - bitStream.Read(platformType); - ASSERT_EQ(platformType, eMoverSubComponentType::Mover); - + void DeserializeMovingPlatformSubComponent() { bool isDirty; - bitStream.Read(isDirty); + ASSERT_TRUE(bitStream.Read(isDirty)); ASSERT_TRUE(isDirty); eMovementPlatformState state; - bitStream.Read(state); + ASSERT_TRUE(bitStream.Read(state)); ASSERT_EQ(state, eMovementPlatformState::Stopped | eMovementPlatformState::ReachedDesiredWaypoint); int32_t desiredWaypointIndex; - bitStream.Read(desiredWaypointIndex); - ASSERT_EQ(desiredWaypointIndex, 1); + ASSERT_TRUE(bitStream.Read(desiredWaypointIndex)); + ASSERT_EQ(desiredWaypointIndex, -1); bool shouldStopAtDesiredWaypoint; - bitStream.Read(shouldStopAtDesiredWaypoint); - ASSERT_TRUE(shouldStopAtDesiredWaypoint); + ASSERT_TRUE(bitStream.Read(shouldStopAtDesiredWaypoint)); + ASSERT_FALSE(shouldStopAtDesiredWaypoint); bool isInReverse2; - bitStream.Read(isInReverse2); - ASSERT_TRUE(isInReverse2); + ASSERT_TRUE(bitStream.Read(isInReverse2)); + ASSERT_FALSE(isInReverse2); float percentBetweenPoints; - bitStream.Read(percentBetweenPoints); - ASSERT_EQ(percentBetweenPoints, 2); + ASSERT_TRUE(bitStream.Read(percentBetweenPoints)); + ASSERT_EQ(percentBetweenPoints, 0); NiPoint3 position; - bitStream.Read(position.x); - bitStream.Read(position.y); - bitStream.Read(position.z); - ASSERT_EQ(position, NiPoint3(3, 4, 5)); + ASSERT_TRUE(bitStream.Read(position.x)); + ASSERT_TRUE(bitStream.Read(position.y)); + ASSERT_TRUE(bitStream.Read(position.z)); + ASSERT_EQ(position, NiPoint3(25, 26, 27)); uint32_t currentWaypointIndex; - bitStream.Read(currentWaypointIndex); - ASSERT_EQ(currentWaypointIndex, 6); + ASSERT_TRUE(bitStream.Read(currentWaypointIndex)); + ASSERT_EQ(currentWaypointIndex, 0); uint32_t nextWaypointIndex; - bitStream.Read(nextWaypointIndex); - ASSERT_EQ(nextWaypointIndex, 7); + ASSERT_TRUE(bitStream.Read(nextWaypointIndex)); + ASSERT_EQ(nextWaypointIndex, -1); float idleTimeElapsed; - bitStream.Read(idleTimeElapsed); - ASSERT_EQ(idleTimeElapsed, 8); + ASSERT_TRUE(bitStream.Read(idleTimeElapsed)); + ASSERT_FLOAT_EQ(idleTimeElapsed, 0.0f); float moveTimeElapsed; - bitStream.Read(moveTimeElapsed); - ASSERT_EQ(moveTimeElapsed, 11); - - bool hasPlatformData2; - bitStream.Read(hasPlatformData2); - ASSERT_TRUE(hasPlatformData2); - - eMoverSubComponentType platformType2; - bitStream.Read(platformType2); - ASSERT_EQ(platformType2, eMoverSubComponentType::Rotator); - - bool isDirty2; - bitStream.Read(isDirty2); - ASSERT_TRUE(isDirty2); - - eMovementPlatformState state2; - bitStream.Read(state2); - ASSERT_EQ(state2, eMovementPlatformState::Travelling); - - int32_t desiredWaypointIndex2; - bitStream.Read(desiredWaypointIndex2); - ASSERT_EQ(desiredWaypointIndex2, 12); - - bool shouldStopAtDesiredWaypoint2; - bitStream.Read(shouldStopAtDesiredWaypoint2); - ASSERT_TRUE(shouldStopAtDesiredWaypoint2); - - bool isInReverse3; - bitStream.Read(isInReverse3); - ASSERT_TRUE(isInReverse3); - - float percentBetweenPoints2; - bitStream.Read(percentBetweenPoints2); - ASSERT_EQ(percentBetweenPoints2, 13); - - NiPoint3 position2; - bitStream.Read(position2.x); - bitStream.Read(position2.y); - bitStream.Read(position2.z); - ASSERT_EQ(position2, NiPoint3(14, 15, 16)); - - uint32_t currentWaypointIndex2; - bitStream.Read(currentWaypointIndex2); - ASSERT_EQ(currentWaypointIndex2, 17); + ASSERT_TRUE(bitStream.Read(moveTimeElapsed)); + ASSERT_FLOAT_EQ(moveTimeElapsed, 0.0f); + } - uint32_t nextWaypointIndex2; - bitStream.Read(nextWaypointIndex2); - ASSERT_EQ(nextWaypointIndex2, 18); + void DeserializeMovingPlatformComponent() { + // read in the full BitStream and check the values match what they were set to above + bool hasPlatformSubComponents = false; + ASSERT_TRUE(bitStream.Read(hasPlatformSubComponents)); + ASSERT_TRUE(hasPlatformSubComponents); - float idleTimeElapsed2; - bitStream.Read(idleTimeElapsed2); - ASSERT_EQ(idleTimeElapsed2, 19); + bool dirtyPathInfo; + ASSERT_TRUE(bitStream.Read(dirtyPathInfo)); + ASSERT_TRUE(dirtyPathInfo); - float moveTimeElapsed2; - bitStream.Read(moveTimeElapsed2); - ASSERT_EQ(moveTimeElapsed2, 22); + bool hasPath; + ASSERT_TRUE(bitStream.Read(hasPath)); + ASSERT_TRUE(hasPath); - bool hasPlatformData3; - bitStream.Read(hasPlatformData3); - ASSERT_TRUE(hasPlatformData3); + std::u16string pathName; + uint16_t pathNameLength; + ASSERT_TRUE(bitStream.Read(pathNameLength)); + pathName.resize(pathNameLength); + ASSERT_TRUE(bitStream.ReadBits(reinterpret_cast(pathName.data()), BYTES_TO_BITS(pathNameLength) * 2)); + ASSERT_EQ(pathName, u"ExamplePath"); - eMoverSubComponentType platformType3; - bitStream.Read(platformType3); - ASSERT_EQ(platformType3, eMoverSubComponentType::SimpleMover); + uint32_t pathStartIndex; + ASSERT_TRUE(bitStream.Read(pathStartIndex)); + ASSERT_EQ(pathStartIndex, 0); - bool dirtyStartingPoint; - bitStream.Read(dirtyStartingPoint); - ASSERT_TRUE(dirtyStartingPoint); + bool isInReverse; + ASSERT_TRUE(bitStream.Read(isInReverse)); + ASSERT_FALSE(isInReverse); - bool hasStartingPoint; - bitStream.Read(hasStartingPoint); - ASSERT_TRUE(hasStartingPoint); + bool hasPlatformData; + ASSERT_TRUE(bitStream.Read(hasPlatformData)); + ASSERT_TRUE(hasPlatformData); - NiPoint3 startingPoint; - bitStream.Read(startingPoint.x); - bitStream.Read(startingPoint.y); - bitStream.Read(startingPoint.z); - ASSERT_EQ(startingPoint, NiPoint3(25, 26, 27)); + eMoverSubComponentType platformType; + ASSERT_TRUE(bitStream.Read(platformType)); + ASSERT_EQ(platformType, eMoverSubComponentType::Mover); + DeserializeMovingPlatformSubComponent(); - NiQuaternion startingRotation; - bitStream.Read(startingRotation.w); - bitStream.Read(startingRotation.x); - bitStream.Read(startingRotation.y); - bitStream.Read(startingRotation.z); - ASSERT_EQ(startingRotation, NiQuaternion(28, 29, 30, 31)); + ASSERT_TRUE(bitStream.Read(hasPlatformData)); + ASSERT_TRUE(hasPlatformData); - bool isDirty4; - bitStream.Read(isDirty4); - ASSERT_TRUE(isDirty4); + ASSERT_TRUE(bitStream.Read(platformType)); + ASSERT_EQ(platformType, eMoverSubComponentType::SimpleMover); + DeserializeSimpleMoverPlatformSubComponent(); - eMovementPlatformState state3; - bitStream.Read(state3); - ASSERT_EQ(state3, eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint); + ASSERT_TRUE(bitStream.Read(hasPlatformData)); + ASSERT_TRUE(hasPlatformData); - int32_t currentWaypointIndex3; - bitStream.Read(currentWaypointIndex3); - ASSERT_EQ(currentWaypointIndex3, 28); + ASSERT_TRUE(bitStream.Read(platformType)); + ASSERT_EQ(platformType, eMoverSubComponentType::Rotator); + DeserializeMovingPlatformSubComponent(); - bool isInReverse4; - bitStream.Read(isInReverse4); - ASSERT_TRUE(isInReverse4); + ASSERT_TRUE(bitStream.Read(hasPlatformData)); + ASSERT_FALSE(hasPlatformData); + } - bool hasPlatformSubComponents2; - bitStream.Read(hasPlatformSubComponents2); - ASSERT_FALSE(hasPlatformSubComponents2); + void TestSerialization() { + auto* movingPlatformComponent = baseEntity->GetComponent(); + ASSERT_NE(movingPlatformComponent, nullptr); + uint32_t flags = 0; + movingPlatformComponent->Serialize(&bitStream, true, flags); + DeserializeMovingPlatformComponent(); } }; @@ -302,89 +230,70 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformSerializationTest) { } TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceForwardTest) { - MoverPlatformSubComponent moverPlatformSubComponent(nullptr); - moverPlatformSubComponent._SetPath(&path); - moverPlatformSubComponent.m_CurrentWaypointIndex = 0; - moverPlatformSubComponent.m_NextWaypointIndex = 1; - moverPlatformSubComponent.m_InReverse = false; + MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); moverPlatformSubComponent.AdvanceToNextWaypoint(); - ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 1); - ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 2); + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 1); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 2); moverPlatformSubComponent.AdvanceToNextWaypoint(); - ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 2); - ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 2); - ASSERT_FALSE(moverPlatformSubComponent.m_InReverse); + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 2); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 2); + ASSERT_FALSE(moverPlatformSubComponent.GetInReverse()); path.pathBehavior = PathBehavior::Bounce; moverPlatformSubComponent.AdvanceToNextWaypoint(); - ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 2); - ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 1); - ASSERT_TRUE(moverPlatformSubComponent.m_InReverse); + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 2); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1); + ASSERT_TRUE(moverPlatformSubComponent.GetInReverse()); } TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceReverseTest) { - MoverPlatformSubComponent moverPlatformSubComponent(nullptr); - moverPlatformSubComponent._SetPath(&path); - moverPlatformSubComponent.m_CurrentWaypointIndex = 2; - moverPlatformSubComponent.m_NextWaypointIndex = 1; - moverPlatformSubComponent.m_InReverse = true; + MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); moverPlatformSubComponent.AdvanceToNextReverseWaypoint(); - ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 1); - ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 0); - ASSERT_TRUE(moverPlatformSubComponent.m_InReverse); + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 1); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 0); + ASSERT_TRUE(moverPlatformSubComponent.GetInReverse()); moverPlatformSubComponent.AdvanceToNextReverseWaypoint(); - ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 0); - ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 0); - ASSERT_TRUE(moverPlatformSubComponent.m_InReverse); + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 0); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 0); + ASSERT_TRUE(moverPlatformSubComponent.GetInReverse()); path.pathBehavior = PathBehavior::Bounce; moverPlatformSubComponent.AdvanceToNextWaypoint(); - ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 0); - ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 1); - ASSERT_TRUE(moverPlatformSubComponent.m_InReverse); + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 0); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1); + ASSERT_TRUE(moverPlatformSubComponent.GetInReverse()); } TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceTest) { - MoverPlatformSubComponent moverPlatformSubComponent(nullptr); - moverPlatformSubComponent._SetPath(&path); - path.pathBehavior = PathBehavior::Bounce; - moverPlatformSubComponent.m_CurrentWaypointIndex = 0; - moverPlatformSubComponent.m_NextWaypointIndex = 1; - moverPlatformSubComponent.m_InReverse = false; + MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); moverPlatformSubComponent.AdvanceToNextWaypoint(); - ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 1); - ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 2); - ASSERT_FALSE(moverPlatformSubComponent.m_InReverse); + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 1); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 2); + ASSERT_FALSE(moverPlatformSubComponent.GetInReverse()); moverPlatformSubComponent.AdvanceToNextWaypoint(); - ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 2); - ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 1); - ASSERT_TRUE(moverPlatformSubComponent.m_InReverse); + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 2); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1); + ASSERT_TRUE(moverPlatformSubComponent.GetInReverse()); moverPlatformSubComponent.AdvanceToNextReverseWaypoint(); - ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 1); - ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 0); - ASSERT_TRUE(moverPlatformSubComponent.m_InReverse); + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 1); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 0); + ASSERT_TRUE(moverPlatformSubComponent.GetInReverse()); moverPlatformSubComponent.AdvanceToNextReverseWaypoint(); - ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 0); - ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 1); - ASSERT_FALSE(moverPlatformSubComponent.m_InReverse); + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 0); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1); + ASSERT_FALSE(moverPlatformSubComponent.GetInReverse()); moverPlatformSubComponent.AdvanceToNextWaypoint(); - ASSERT_EQ(moverPlatformSubComponent.m_CurrentWaypointIndex, 1); - ASSERT_EQ(moverPlatformSubComponent.m_NextWaypointIndex, 2); - ASSERT_FALSE(moverPlatformSubComponent.m_InReverse); + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 1); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 2); + ASSERT_FALSE(moverPlatformSubComponent.GetInReverse()); } TEST_F(MovingPlatformComponentTests, MovingPlatformMoverSpeedCalculationTest) { - MoverPlatformSubComponent moverPlatformSubComponent(nullptr); + MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); path.pathWaypoints.at(0).position = NiPoint3(99.296440, 419.293335, 207.219498); path.pathWaypoints.at(0).movingPlatform.speed = 16.0f; path.pathWaypoints.at(1).position = NiPoint3(141.680099, 419.990051, 208.680450); path.pathWaypoints.at(1).movingPlatform.speed = 16.0f; path.pathBehavior = PathBehavior::Bounce; - moverPlatformSubComponent._SetPath(&path); - moverPlatformSubComponent.m_Speed = 16.0f; - moverPlatformSubComponent.m_TimeBasedMovement = false; - moverPlatformSubComponent.m_InReverse = false; - moverPlatformSubComponent.m_CurrentWaypointIndex = 0; - moverPlatformSubComponent.m_NextWaypointIndex = 1; ASSERT_EQ(moverPlatformSubComponent.CalculateSpeed(), 16.0f); NiPoint3 r = moverPlatformSubComponent.CalculateLinearVelocity(); ASSERT_FLOAT_EQ(r.x, 15.988346099854); @@ -394,10 +303,7 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformMoverSpeedCalculationTest) { } TEST_F(MovingPlatformComponentTests, MovingPlatformNextAndCurrentWaypointAccess) { - MoverPlatformSubComponent moverPlatformSubComponent(nullptr); - moverPlatformSubComponent._SetPath(&path); - moverPlatformSubComponent.m_CurrentWaypointIndex = 0; - moverPlatformSubComponent.m_NextWaypointIndex = 1; + MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypoint().position, NiPoint3(1, 2, 3)); ASSERT_EQ(moverPlatformSubComponent.GetNextWaypoint().position, NiPoint3(4, 5, 6)); moverPlatformSubComponent.AdvanceToNextWaypoint(); @@ -406,23 +312,32 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformNextAndCurrentWaypointAccess) } TEST_F(MovingPlatformComponentTests, MovingPlatformRunTest) { - MoverPlatformSubComponent moverPlatformSubComponent(nullptr); - moverPlatformSubComponent._SetPath(&path); + MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); path.pathWaypoints.at(0).position = NiPoint3(99.296440f, 419.293335f, 207.219498f); path.pathWaypoints.at(0).movingPlatform.speed = 16.0f; + path.pathWaypoints.at(1).position = NiPoint3(141.680099f, 419.990051f, 208.680450f); path.pathWaypoints.at(1).movingPlatform.speed = 16.0f; - moverPlatformSubComponent.m_State = 0; - moverPlatformSubComponent.m_TimeBasedMovement = false; - moverPlatformSubComponent.m_State = eMovementPlatformState::Travelling; - moverPlatformSubComponent.m_CurrentWaypointIndex = 0; - moverPlatformSubComponent.m_NextWaypointIndex = 1; - moverPlatformSubComponent.m_Speed = 16.0f; - moverPlatformSubComponent.m_Position = path.pathWaypoints.at(0).position; + + moverPlatformSubComponent.UpdateLinearVelocity(); moverPlatformSubComponent.Update(2.65f); // just check that its close enough - EXPECT_LT(141.680099f - moverPlatformSubComponent.m_Position.x, 0.1f); - EXPECT_LT(419.990051f - moverPlatformSubComponent.m_Position.y, 0.1f); - EXPECT_LT(208.680450f - moverPlatformSubComponent.m_Position.z, 0.1f); + EXPECT_LT(141.680099f - moverPlatformSubComponent.GetPosition().x, 0.1f); + EXPECT_LT(419.990051f - moverPlatformSubComponent.GetPosition().y, 0.1f); + EXPECT_LT(208.680450f - moverPlatformSubComponent.GetPosition().z, 0.1f); +} + +TEST_F(MovingPlatformComponentTests, MovingPlatformPercentBetweenPointsTest) { + MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); + path.pathWaypoints.at(0).position = NiPoint3(0, 0, 1); + path.pathWaypoints.at(1).position = NiPoint3(0, 0, 3); + // moverPlatformSubComponent.m_Position = NiPoint3(0, 0, 1); + ASSERT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 0.0f); + // moverPlatformSubComponent.m_Position = NiPoint3(0, 0, 2); + ASSERT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 0.5f); + // moverPlatformSubComponent.m_Position = NiPoint3(0, 0, 3); + ASSERT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 1.0f); + // moverPlatformSubComponent.m_TimeBasedMovement = true; + ASSERT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 0.0f); } From 944d3e1bac6376719f43202ef163bbd382a8181e Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sat, 10 Feb 2024 19:23:35 -0800 Subject: [PATCH 11/17] branch back to working state --- dDatabase/CDClientDatabase/CDClientManager.cpp | 2 ++ .../CDMovingPlatformComponentTable.cpp | 15 +++++++++------ .../CDMovingPlatformComponentTable.h | 4 +--- dGame/dComponents/MovingPlatformComponent.cpp | 16 ++++++++-------- dGame/dGameMessages/GameMessages.cpp | 4 ++-- .../02_server/Map/General/PropertyPlatform.cpp | 6 +++--- dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 8 ++++---- tests/dGameTests/GameDependencies.cpp | 6 +++--- .../MovingPlatformComponentTests.cpp | 10 ++++------ 9 files changed, 36 insertions(+), 35 deletions(-) diff --git a/dDatabase/CDClientDatabase/CDClientManager.cpp b/dDatabase/CDClientDatabase/CDClientManager.cpp index 0e05c0b83..e1548db79 100644 --- a/dDatabase/CDClientDatabase/CDClientManager.cpp +++ b/dDatabase/CDClientDatabase/CDClientManager.cpp @@ -40,6 +40,7 @@ #include "CDRailActivatorComponent.h" #include "CDRewardCodesTable.h" #include "CDPetComponentTable.h" +#include "CDMovingPlatformComponentTable.h" #include @@ -110,6 +111,7 @@ DEFINE_TABLE_STORAGE(CDScriptComponentTable); DEFINE_TABLE_STORAGE(CDSkillBehaviorTable); DEFINE_TABLE_STORAGE(CDVendorComponentTable); DEFINE_TABLE_STORAGE(CDZoneTableTable); +DEFINE_TABLE_STORAGE(CDMovingPlatformComponentTable); void CDClientManager::LoadValuesFromDatabase() { if (!CDClientDatabase::isConnected) throw CDClientConnectionException(); diff --git a/dDatabase/CDClientDatabase/CDClientTables/CDMovingPlatformComponentTable.cpp b/dDatabase/CDClientDatabase/CDClientTables/CDMovingPlatformComponentTable.cpp index f4331eb29..e6029e67e 100644 --- a/dDatabase/CDClientDatabase/CDClientTables/CDMovingPlatformComponentTable.cpp +++ b/dDatabase/CDClientDatabase/CDClientTables/CDMovingPlatformComponentTable.cpp @@ -1,6 +1,7 @@ #include "CDMovingPlatformComponentTable.h" CDMovingPlatformComponentTable::CDMovingPlatformComponentTable() { + auto& entries = GetEntriesMutable(); auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MovingPlatforms"); while (!tableData.eof()) { CDMovingPlatformTableEntry entry; @@ -11,12 +12,13 @@ CDMovingPlatformComponentTable::CDMovingPlatformComponentTable() { entry.platformMove.z = tableData.getFloatField("platformMoveZ", 0.0f); entry.moveTime = tableData.getFloatField("platformMoveTime", -1.0f); - DluAssert(m_Platforms.insert(std::make_pair(tableData.getIntField("id", -1), entry)).second); + DluAssert(entries.insert(std::make_pair(tableData.getIntField("id", -1), entry)).second); tableData.nextRow(); } } void CDMovingPlatformComponentTable::CachePlatformEntry(ComponentID id) { + auto& entries = GetEntriesMutable(); auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM MovingPlatforms WHERE id = ?;"); query.bind(1, static_cast(id)); @@ -30,16 +32,17 @@ void CDMovingPlatformComponentTable::CachePlatformEntry(ComponentID id) { entry.platformMove.z = tableData.getFloatField("platformMoveZ", 0.0f); entry.moveTime = tableData.getFloatField("platformMoveTime", -1.0f); - DluAssert(m_Platforms.insert(std::make_pair(tableData.getIntField("id", -1), entry)).second); + DluAssert(entries.insert(std::make_pair(tableData.getIntField("id", -1), entry)).second); tableData.nextRow(); } } const std::optional CDMovingPlatformComponentTable::GetPlatformEntry(ComponentID id) { - auto itr = m_Platforms.find(id); - if (itr == m_Platforms.end()) { + auto& entries = GetEntriesMutable(); + auto itr = entries.find(id); + if (itr == entries.end()) { CachePlatformEntry(id); - itr = m_Platforms.find(id); + itr = entries.find(id); } - return itr != m_Platforms.end() ? std::make_optional(itr->second) : std::nullopt; + return itr != entries.end() ? std::make_optional(itr->second) : std::nullopt; } diff --git a/dDatabase/CDClientDatabase/CDClientTables/CDMovingPlatformComponentTable.h b/dDatabase/CDClientDatabase/CDClientTables/CDMovingPlatformComponentTable.h index bcb1d12b1..dccac16c5 100644 --- a/dDatabase/CDClientDatabase/CDClientTables/CDMovingPlatformComponentTable.h +++ b/dDatabase/CDClientDatabase/CDClientTables/CDMovingPlatformComponentTable.h @@ -15,13 +15,11 @@ struct CDMovingPlatformTableEntry { bool platformStartAtEnd; }; -class CDMovingPlatformComponentTable : public CDTable { +class CDMovingPlatformComponentTable : public CDTable> { public: CDMovingPlatformComponentTable(); void CachePlatformEntry(ComponentID id); const std::optional GetPlatformEntry(ComponentID id); -private: - std::map m_Platforms; }; #endif //!__CDMOVINGPLATFORMCOMPONENTTABLE__H__ diff --git a/dGame/dComponents/MovingPlatformComponent.cpp b/dGame/dComponents/MovingPlatformComponent.cpp index ae0e616ca..ab865d953 100644 --- a/dGame/dComponents/MovingPlatformComponent.cpp +++ b/dGame/dComponents/MovingPlatformComponent.cpp @@ -36,8 +36,8 @@ PlatformSubComponent::PlatformSubComponent(MovingPlatformComponent* parentCompon m_IsDirty = false; m_InReverse = false; m_ShouldStopAtDesiredWaypoint = false; - m_LinearVelocity = NiPoint3::ZERO; - m_AngularVelocity = NiPoint3::ZERO; + m_LinearVelocity = NiPoint3Constant::ZERO; + m_AngularVelocity = NiPoint3Constant::ZERO; m_TimeBasedMovement = false; m_Path = nullptr; } @@ -221,8 +221,8 @@ void PlatformSubComponent::StopPathing() { m_State |= eMovementPlatformState::Stopped; m_State &= ~eMovementPlatformState::Travelling; m_State &= ~eMovementPlatformState::Waiting; - m_LinearVelocity = NiPoint3::ZERO; - m_AngularVelocity = NiPoint3::ZERO; + m_LinearVelocity = NiPoint3Constant::ZERO; + m_AngularVelocity = NiPoint3Constant::ZERO; } //------------- PlatformSubComponent end -------------- @@ -285,7 +285,7 @@ void SimpleMoverPlatformSubComponent::LoadConfigData() { void SimpleMoverPlatformSubComponent::LoadDataFromTemplate() { if (!m_ParentComponent->GetParent()->GetVar(u"dbonly")) return; - auto* movingPlatformTable = CDClientManager::Instance().GetTable(); + auto* movingPlatformTable = CDClientManager::GetTable(); if (movingPlatformTable == nullptr) return; const auto& platformEntry = movingPlatformTable->GetPlatformEntry(m_ParentComponent->GetComponentId()); @@ -324,7 +324,7 @@ void MovingPlatformComponent::LoadConfigData() { AddMovingPlatform(); } if (m_Parent->GetVar(u"platformIsSimpleMover")) { - AddMovingPlatform(NiPoint3::ZERO, false); + AddMovingPlatform(NiPoint3Constant::ZERO, false); } if (m_Parent->GetVar(u"platformIsRotater")) { AddMovingPlatform(); @@ -339,7 +339,7 @@ void MovingPlatformComponent::Update(float deltaTime) { std::for_each(m_Platforms.begin(), m_Platforms.end(), [deltaTime](const std::unique_ptr& platform) { platform->Update(deltaTime); }); } -void MovingPlatformComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void MovingPlatformComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { // For some reason we need to write this here instead of later on. outBitStream->Write(!m_Platforms.empty()); @@ -370,7 +370,7 @@ void MovingPlatformComponent::OnQuickBuildInitilized() { StopPathing(); } -void MovingPlatformComponent::OnCompleteRebuild() { +void MovingPlatformComponent::OnCompleteQuickBuild() { if (m_NoAutoStart) return; StartPathing(); diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index d0a7dfa2d..4cd195732 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -389,8 +389,8 @@ void GameMessages::SendPlatformResync(Entity* entity, const SystemAddress& sysAd bitStream.Write(subComponent.GetPosition().y); bitStream.Write(subComponent.GetPosition().z); - bitStream.Write(subComponent.GetRotation() != NiQuaternion::IDENTITY); - if (subComponent.GetRotation() != NiQuaternion::IDENTITY) { + bitStream.Write(subComponent.GetRotation() != NiQuaternionConstant::IDENTITY); + if (subComponent.GetRotation() != NiQuaternionConstant::IDENTITY) { bitStream.Write(subComponent.GetRotation().x); bitStream.Write(subComponent.GetRotation().y); bitStream.Write(subComponent.GetRotation().z); diff --git a/dScripts/02_server/Map/General/PropertyPlatform.cpp b/dScripts/02_server/Map/General/PropertyPlatform.cpp index de06db0ca..eee2a6c2e 100644 --- a/dScripts/02_server/Map/General/PropertyPlatform.cpp +++ b/dScripts/02_server/Map/General/PropertyPlatform.cpp @@ -3,15 +3,15 @@ #include "GameMessages.h" #include "MovingPlatformComponent.h" -void PropertyPlatform::OnRebuildComplete(Entity* self, Entity* target) { +void PropertyPlatform::OnQuickBuildComplete(Entity* self, Entity* target) { GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS , static_cast(eMovementPlatformState::Waiting | eMovementPlatformState::ReachedDesiredWaypoint | eMovementPlatformState::ReachedFinalWaypoint), true, 0, 0, 0); } void PropertyPlatform::OnUse(Entity* self, Entity* user) { - auto* rebuildComponent = self->GetComponent(); - if (rebuildComponent != nullptr && rebuildComponent->GetState() == eRebuildState::COMPLETED) { + auto* rebuildComponent = self->GetComponent(); + if (rebuildComponent != nullptr && rebuildComponent->GetState() == eQuickBuildState::COMPLETED) { GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, eMovementPlatformState::Travelling, true, 0, 1, 1); diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index 44788a641..1efaeb7a1 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -327,11 +327,13 @@ void SGCannon::DoSpawnTimerFunc(Entity* self, const std::string& name) { // Save the enemy and tell it to start pathing if (enemy != nullptr) { const_cast&>(self->GetVar>(SpawnedObjects)).push_back(enemy->GetObjectID()); - GameMessages::SendPlatformResync(enemy, UNASSIGNED_SYSTEM_ADDRESS); + GameMessages::SendPlatformResync(enemy, UNASSIGNED_SYSTEM_ADDRESS, eMovementPlatformState::Travelling); } } } +#pragma warning("TODO: FIX THE ABOVE GM CALL") + void SGCannon::EndGameBufferTimerFunc(Entity* self) { RecordPlayerScore(self); StopGame(self, false); @@ -381,9 +383,7 @@ void SGCannon::OnActivityTimerDone(Entity* self, const std::string& name) { auto* enemy = Game::entityManager->CreateEntity(info, nullptr, self); Game::entityManager->ConstructEntity(enemy); - auto* movementAI = new MovementAIComponent(enemy, {}); - - enemy->AddComponent(eReplicaComponentType::MOVEMENT_AI, movementAI); + auto* movementAI = enemy->AddComponent({}); movementAI->SetMaxSpeed(toSpawn.initialSpeed); movementAI->SetCurrentSpeed(toSpawn.initialSpeed); diff --git a/tests/dGameTests/GameDependencies.cpp b/tests/dGameTests/GameDependencies.cpp index da92ade73..1b3d0d6ef 100644 --- a/tests/dGameTests/GameDependencies.cpp +++ b/tests/dGameTests/GameDependencies.cpp @@ -15,12 +15,12 @@ namespace Game { } void GameDependenciesTest::SetUpDependencies() { - info.pos = NiPoint3::ZERO; - info.rot = NiQuaternion::IDENTITY; + info.pos = NiPoint3Constant::ZERO; + info.rot = NiQuaternionConstant::IDENTITY; info.scale = 1.0f; info.spawner = nullptr; info.lot = 999; - Game::logger = new dLogger("./testing.log", true, true); + Game::logger = new Logger("./testing.log", true, true); Game::server = new dServerMock(); Game::config = new dConfig("worldconfig.ini"); Game::entityManager = new EntityManager(); diff --git a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp index 1ce8c6874..e809cc84b 100644 --- a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp @@ -57,12 +57,11 @@ class MovingPlatformComponentTests : public GameDependenciesTest { baseEntity = std::make_unique(15, GameDependenciesTest::info); - auto* simplePhysicsComponent = new SimplePhysicsComponent(1, baseEntity.get()); - baseEntity->AddComponent(SimplePhysicsComponent::ComponentType, simplePhysicsComponent); - auto* movingPlatformComponent = new MovingPlatformComponent(baseEntity.get(), path.pathName); + auto* simplePhysicsComponent = baseEntity->AddComponent(1); + auto* movingPlatformComponent = baseEntity->AddComponent("ExamplePath"); + new MovingPlatformComponent(baseEntity.get(), path.pathName); movingPlatformComponent->LoadConfigData(); movingPlatformComponent->LoadDataFromTemplate(); - baseEntity->AddComponent(MovingPlatformComponent::ComponentType, movingPlatformComponent); } void TearDown() override { @@ -215,8 +214,7 @@ class MovingPlatformComponentTests : public GameDependenciesTest { void TestSerialization() { auto* movingPlatformComponent = baseEntity->GetComponent(); ASSERT_NE(movingPlatformComponent, nullptr); - uint32_t flags = 0; - movingPlatformComponent->Serialize(&bitStream, true, flags); + movingPlatformComponent->Serialize(&bitStream, true); DeserializeMovingPlatformComponent(); } }; From 1ae57dc6e80058aee67aa7462c49c26e24e80d21 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sat, 10 Feb 2024 19:53:20 -0800 Subject: [PATCH 12/17] Fix one failing test --- dCommon/DluAssert.h | 1 + dCommon/Logger.h | 2 +- dGame/dComponents/MovingPlatformComponent.cpp | 3 +++ .../MovingPlatformComponentTests.cpp | 17 ++++++++--------- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/dCommon/DluAssert.h b/dCommon/DluAssert.h index c54dd54e1..d112f011d 100644 --- a/dCommon/DluAssert.h +++ b/dCommon/DluAssert.h @@ -2,6 +2,7 @@ #define __DLUASSERT__H__ #include +#define _DEBUG #ifdef _DEBUG # define DluAssert(expression) assert(expression) diff --git a/dCommon/Logger.h b/dCommon/Logger.h index 5754d9acc..fc0d118fc 100644 --- a/dCommon/Logger.h +++ b/dCommon/Logger.h @@ -29,7 +29,7 @@ constexpr const char* GetFileNameFromAbsolutePath(const char* path) { // they will not be valid constexpr and will be evaluated at runtime instead of compile time! // The full string is still stored in the binary, however the offset of the filename in the absolute paths // is used in the instruction instead of the start of the absolute path. -#define LOG(message, ...) do { auto str = FILENAME_AND_LINE; Game::logger->Log(str, message, ##__VA_ARGS__); } while(0) +#define LOG(message, ...) do { auto str = FILENAME_AND_LINE; Game::logger->Log(str, message, ##__VA_ARGS__); Game::logger->Flush(); } while(0) #define LOG_DEBUG(message, ...) do { auto str = FILENAME_AND_LINE; Game::logger->LogDebug(str, message, ##__VA_ARGS__); } while(0) // Writer class for writing data to files. diff --git a/dGame/dComponents/MovingPlatformComponent.cpp b/dGame/dComponents/MovingPlatformComponent.cpp index ab865d953..ece25685e 100644 --- a/dGame/dComponents/MovingPlatformComponent.cpp +++ b/dGame/dComponents/MovingPlatformComponent.cpp @@ -141,6 +141,7 @@ void PlatformSubComponent::SetupPath(const std::string& pathName, uint32_t start m_InReverse = startsInReverse; m_CurrentWaypointIndex = startingWaypointIndex; m_TimeBasedMovement = m_Path->movingPlatform.timeBasedMovement; + m_NextWaypointIndex = m_InReverse ? m_CurrentWaypointIndex - 1 : m_CurrentWaypointIndex + 1; } const PathWaypoint& PlatformSubComponent::GetNextWaypoint() const { @@ -159,6 +160,8 @@ float PlatformSubComponent::CalculateSpeed() const { float unitizedDirection = 1.0f / (GetNextWaypoint().position - GetCurrentWaypoint().position).Length(); speed = unitizedDirection / GetCurrentWaypoint().movingPlatform.speed; } else { + LOG("%i %i", m_CurrentWaypointIndex, m_NextWaypointIndex); + Game::logger->Flush(); speed = (GetNextWaypoint().movingPlatform.speed - GetCurrentWaypoint().movingPlatform.speed) * m_PercentUntilNextWaypoint + GetCurrentWaypoint().movingPlatform.speed; } return speed; diff --git a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp index e809cc84b..41dc6cd84 100644 --- a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp @@ -25,14 +25,17 @@ class MovingPlatformComponentTests : public GameDependenciesTest { PathWaypoint waypointStart; waypointStart.position = NiPoint3(1, 2, 3); waypointStart.rotation = NiQuaternion(4, 5, 6, 7); + waypointStart.movingPlatform.speed = 16.0f; PathWaypoint waypointMiddle; waypointMiddle.position = NiPoint3(4, 5, 6); waypointMiddle.rotation = NiQuaternion(7, 8, 9, 10); + waypointStart.movingPlatform.speed = 16.0f; PathWaypoint waypointEnd; waypointEnd.position = NiPoint3(4, 5, 7); waypointEnd.rotation = NiQuaternion(7, 8, 9, 10); + waypointStart.movingPlatform.speed = 16.0f; path.pathWaypoints.push_back(waypointStart); path.pathWaypoints.push_back(waypointMiddle); @@ -59,7 +62,6 @@ class MovingPlatformComponentTests : public GameDependenciesTest { auto* simplePhysicsComponent = baseEntity->AddComponent(1); auto* movingPlatformComponent = baseEntity->AddComponent("ExamplePath"); - new MovingPlatformComponent(baseEntity.get(), path.pathName); movingPlatformComponent->LoadConfigData(); movingPlatformComponent->LoadDataFromTemplate(); } @@ -286,17 +288,14 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceTest) TEST_F(MovingPlatformComponentTests, MovingPlatformMoverSpeedCalculationTest) { MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); - path.pathWaypoints.at(0).position = NiPoint3(99.296440, 419.293335, 207.219498); - path.pathWaypoints.at(0).movingPlatform.speed = 16.0f; - path.pathWaypoints.at(1).position = NiPoint3(141.680099, 419.990051, 208.680450); - path.pathWaypoints.at(1).movingPlatform.speed = 16.0f; - path.pathBehavior = PathBehavior::Bounce; + moverPlatformSubComponent.SetupPath("ExamplePath", 0, false); + ASSERT_EQ(moverPlatformSubComponent.CalculateSpeed(), 16.0f); NiPoint3 r = moverPlatformSubComponent.CalculateLinearVelocity(); - ASSERT_FLOAT_EQ(r.x, 15.988346099854); - ASSERT_FLOAT_EQ(r.y, 0.26282161474228); - ASSERT_FLOAT_EQ(r.z, 0.5511137843132); + ASSERT_FLOAT_EQ(r.x, 9.2376051); + ASSERT_FLOAT_EQ(r.y, 9.2376051); + ASSERT_FLOAT_EQ(r.z, 9.2376051); moverPlatformSubComponent.AdvanceToNextWaypoint(); } From c35ab1f9e377ad659fb4f4483dab09b2c0d7eb11 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Mon, 12 Feb 2024 10:43:58 -0600 Subject: [PATCH 13/17] Add test logs, fix seg faults in tests --- dCommon/Logger.h | 3 ++- .../MovingPlatformComponentTests.cpp | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/dCommon/Logger.h b/dCommon/Logger.h index fc0d118fc..5b329f191 100644 --- a/dCommon/Logger.h +++ b/dCommon/Logger.h @@ -29,8 +29,9 @@ constexpr const char* GetFileNameFromAbsolutePath(const char* path) { // they will not be valid constexpr and will be evaluated at runtime instead of compile time! // The full string is still stored in the binary, however the offset of the filename in the absolute paths // is used in the instruction instead of the start of the absolute path. -#define LOG(message, ...) do { auto str = FILENAME_AND_LINE; Game::logger->Log(str, message, ##__VA_ARGS__); Game::logger->Flush(); } while(0) +#define LOG(message, ...) do { auto str = FILENAME_AND_LINE; Game::logger->Log(str, message, ##__VA_ARGS__); } while(0) #define LOG_DEBUG(message, ...) do { auto str = FILENAME_AND_LINE; Game::logger->LogDebug(str, message, ##__VA_ARGS__); } while(0) +#define LOG_TEST(message, ...) do { auto str = FILENAME_AND_LINE; Game::logger->LogDebug(str, message, ##__VA_ARGS__); Game::logger->Flush();} while(0) // Writer class for writing data to files. class Writer { diff --git a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp index 41dc6cd84..bcaf139f0 100644 --- a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp @@ -71,11 +71,11 @@ class MovingPlatformComponentTests : public GameDependenciesTest { } void DeserializeSimpleMoverPlatformSubComponent() { - bool dirtyStartingPoint; + bool dirtyStartingPoint = false; bitStream.Read(dirtyStartingPoint); ASSERT_TRUE(dirtyStartingPoint); - bool hasStartingPoint; + bool hasStartingPoint = false; bitStream.Read(hasStartingPoint); ASSERT_TRUE(hasStartingPoint); @@ -231,6 +231,8 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformSerializationTest) { TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceForwardTest) { MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); + moverPlatformSubComponent.SetupPath("ExamplePath", 0, false); + moverPlatformSubComponent.AdvanceToNextWaypoint(); ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 1); ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 2); @@ -247,6 +249,8 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceForwar TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceReverseTest) { MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); + moverPlatformSubComponent.SetupPath("ExamplePath", 0, true); + moverPlatformSubComponent.AdvanceToNextReverseWaypoint(); ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 1); ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 0); @@ -264,6 +268,8 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceRevers TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceTest) { MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); + moverPlatformSubComponent.SetupPath("ExamplePath", 0, false); + moverPlatformSubComponent.AdvanceToNextWaypoint(); ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 1); ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 2); @@ -301,6 +307,8 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformMoverSpeedCalculationTest) { TEST_F(MovingPlatformComponentTests, MovingPlatformNextAndCurrentWaypointAccess) { MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); + moverPlatformSubComponent.SetupPath("ExamplePath", 0, false); + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypoint().position, NiPoint3(1, 2, 3)); ASSERT_EQ(moverPlatformSubComponent.GetNextWaypoint().position, NiPoint3(4, 5, 6)); moverPlatformSubComponent.AdvanceToNextWaypoint(); @@ -310,6 +318,8 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformNextAndCurrentWaypointAccess) TEST_F(MovingPlatformComponentTests, MovingPlatformRunTest) { MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); + moverPlatformSubComponent.SetupPath("ExamplePath", 0, false); + path.pathWaypoints.at(0).position = NiPoint3(99.296440f, 419.293335f, 207.219498f); path.pathWaypoints.at(0).movingPlatform.speed = 16.0f; @@ -327,6 +337,8 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformRunTest) { TEST_F(MovingPlatformComponentTests, MovingPlatformPercentBetweenPointsTest) { MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); + moverPlatformSubComponent.SetupPath("ExamplePath", 0, false); + path.pathWaypoints.at(0).position = NiPoint3(0, 0, 1); path.pathWaypoints.at(1).position = NiPoint3(0, 0, 3); // moverPlatformSubComponent.m_Position = NiPoint3(0, 0, 1); From 92696606e121b61609a4b767e66fc3e13711782e Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Sat, 17 Feb 2024 02:14:36 -0600 Subject: [PATCH 14/17] Expand tests to cover path types and edge cases --- dGame/dComponents/MovingPlatformComponent.cpp | 67 ++++---- dGame/dComponents/MovingPlatformComponent.h | 2 + .../MovingPlatformComponentTests.cpp | 148 ++++++++++++------ 3 files changed, 140 insertions(+), 77 deletions(-) diff --git a/dGame/dComponents/MovingPlatformComponent.cpp b/dGame/dComponents/MovingPlatformComponent.cpp index ece25685e..ac79c0d1d 100644 --- a/dGame/dComponents/MovingPlatformComponent.cpp +++ b/dGame/dComponents/MovingPlatformComponent.cpp @@ -15,6 +15,7 @@ #include "CDClientManager.h" #include "CDMovingPlatformComponentTable.h" #include "Zone.h" +#include "StringifiedEnum.h" //------------- PlatformSubComponent begin -------------- @@ -84,22 +85,10 @@ void PlatformSubComponent::UpdateLinearVelocity() { } void PlatformSubComponent::AdvanceToNextWaypoint() { - uint32_t numWaypoints = m_Path->pathWaypoints.size(); m_CurrentWaypointIndex = m_NextWaypointIndex; m_ParentComponent->GetParent()->SetPosition(GetCurrentWaypoint().position); m_ParentComponent->GetParent()->SetRotation(GetCurrentWaypoint().rotation); - uint32_t nextWaypointIndex = m_CurrentWaypointIndex + 1; - if (numWaypoints <= nextWaypointIndex) { - PathBehavior behavior = m_Path->pathBehavior; - if (behavior == PathBehavior::Once) { - nextWaypointIndex = m_Path->pathWaypoints.size() - 1; - } else if (behavior == PathBehavior::Bounce) { - nextWaypointIndex = m_Path->pathWaypoints.size() - 2; - m_InReverse = true; - } else { - m_NextWaypointIndex = 0; - } - } + int32_t nextWaypointIndex = FindNextWaypointIndex(); m_NextWaypointIndex = nextWaypointIndex; m_DesiredWaypointIndex = nextWaypointIndex; UpdateLinearVelocity(); @@ -108,22 +97,10 @@ void PlatformSubComponent::AdvanceToNextWaypoint() { } void PlatformSubComponent::AdvanceToNextReverseWaypoint() { - uint32_t numWaypoints = m_Path->pathWaypoints.size(); m_ParentComponent->GetParent()->SetPosition(GetCurrentWaypoint().position); m_ParentComponent->GetParent()->SetRotation(GetCurrentWaypoint().rotation); m_CurrentWaypointIndex = m_NextWaypointIndex; - int32_t nextWaypointIndex = m_CurrentWaypointIndex - 1; - if (nextWaypointIndex < 0) { - PathBehavior behavior = m_Path->pathBehavior; - if (behavior == PathBehavior::Once) { - nextWaypointIndex = 0; - } else if (behavior == PathBehavior::Bounce) { - nextWaypointIndex = 1; - m_InReverse = false; - } else { - nextWaypointIndex = m_Path->pathWaypoints.size() - 1; - } - } + int32_t nextWaypointIndex = FindNextReversedWaypointIndex(); m_NextWaypointIndex = nextWaypointIndex; m_DesiredWaypointIndex = nextWaypointIndex; UpdateLinearVelocity(); @@ -141,13 +118,49 @@ void PlatformSubComponent::SetupPath(const std::string& pathName, uint32_t start m_InReverse = startsInReverse; m_CurrentWaypointIndex = startingWaypointIndex; m_TimeBasedMovement = m_Path->movingPlatform.timeBasedMovement; - m_NextWaypointIndex = m_InReverse ? m_CurrentWaypointIndex - 1 : m_CurrentWaypointIndex + 1; + m_NextWaypointIndex = m_InReverse ? FindNextReversedWaypointIndex() : FindNextWaypointIndex(); } const PathWaypoint& PlatformSubComponent::GetNextWaypoint() const { DluAssert(m_Path != nullptr); return m_Path->pathWaypoints.at(m_NextWaypointIndex); } +const int32_t PlatformSubComponent::FindNextWaypointIndex() { + DluAssert(m_Path != nullptr); + uint32_t numWaypoints = m_Path->pathWaypoints.size(); + uint32_t nextWaypointIndex = m_CurrentWaypointIndex + 1; + if (numWaypoints <= nextWaypointIndex) { + PathBehavior behavior = m_Path->pathBehavior; + if (behavior == PathBehavior::Once) { + nextWaypointIndex = m_Path->pathWaypoints.size() - 1; + } else if (behavior == PathBehavior::Bounce) { + nextWaypointIndex = m_Path->pathWaypoints.size() - 2; + m_InReverse = true; + } else { + nextWaypointIndex = 0; + } + } + return nextWaypointIndex; +} + +const int32_t PlatformSubComponent::FindNextReversedWaypointIndex() { + DluAssert(m_Path != nullptr); + uint32_t numWaypoints = m_Path->pathWaypoints.size(); + int32_t nextWaypointIndex = m_CurrentWaypointIndex - 1; + if (nextWaypointIndex < 0) { + PathBehavior behavior = m_Path->pathBehavior; + if (behavior == PathBehavior::Once) { + nextWaypointIndex = 0; + } else if (behavior == PathBehavior::Bounce) { + nextWaypointIndex = 1; + m_InReverse = false; + } else { + nextWaypointIndex = m_Path->pathWaypoints.size() - 1; + } + } + return nextWaypointIndex; +} + const PathWaypoint& PlatformSubComponent::GetCurrentWaypoint() const { DluAssert(m_Path != nullptr); diff --git a/dGame/dComponents/MovingPlatformComponent.h b/dGame/dComponents/MovingPlatformComponent.h index 5a5b7b7e5..fc2b9f3fa 100644 --- a/dGame/dComponents/MovingPlatformComponent.h +++ b/dGame/dComponents/MovingPlatformComponent.h @@ -60,6 +60,8 @@ class PlatformSubComponent { float CalculateSpeed() const; const PathWaypoint& GetNextWaypoint() const; const PathWaypoint& GetCurrentWaypoint() const; + const int32_t FindNextWaypointIndex(); + const int32_t FindNextReversedWaypointIndex(); void SetupPath(const std::string& pathName, uint32_t startingWaypointIndex, bool startsInReverse); void AdvanceToNextWaypoint(); void AdvanceToNextReverseWaypoint(); diff --git a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp index bcaf139f0..a5db068a8 100644 --- a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp @@ -16,12 +16,11 @@ class MovingPlatformComponentTests : public GameDependenciesTest { std::unique_ptr baseEntity; CBITSTREAM; uint32_t flags = 0; - Path path; + Path pathOnce; + Path pathBounce; + Path pathLoop; void SetUp() override { SetUpDependencies(); - path.movingPlatform.timeBasedMovement = false; - path.pathBehavior = PathBehavior::Once; - path.pathName = "ExamplePath"; PathWaypoint waypointStart; waypointStart.position = NiPoint3(1, 2, 3); waypointStart.rotation = NiQuaternion(4, 5, 6, 7); @@ -36,13 +35,40 @@ class MovingPlatformComponentTests : public GameDependenciesTest { waypointEnd.position = NiPoint3(4, 5, 7); waypointEnd.rotation = NiQuaternion(7, 8, 9, 10); waypointStart.movingPlatform.speed = 16.0f; - - path.pathWaypoints.push_back(waypointStart); - path.pathWaypoints.push_back(waypointMiddle); - path.pathWaypoints.push_back(waypointEnd); - - Game::zoneManager->GetZone()->AddPath(path); - + { + pathOnce.movingPlatform.timeBasedMovement = false; + pathOnce.pathBehavior = PathBehavior::Once; + pathOnce.pathName = "ExampleOncePath"; + + pathOnce.pathWaypoints.push_back(waypointStart); + pathOnce.pathWaypoints.push_back(waypointMiddle); + pathOnce.pathWaypoints.push_back(waypointEnd); + + Game::zoneManager->GetZone()->AddPath(pathOnce); + } + { + pathBounce.movingPlatform.timeBasedMovement = false; + pathBounce.pathBehavior = PathBehavior::Bounce; + pathBounce.pathName = "ExampleBouncePath"; + + pathBounce.pathWaypoints.push_back(waypointStart); + pathBounce.pathWaypoints.push_back(waypointMiddle); + pathBounce.pathWaypoints.push_back(waypointEnd); + + Game::zoneManager->GetZone()->AddPath(pathBounce); + } + { + pathLoop.movingPlatform.timeBasedMovement = false; + pathLoop.pathBehavior = PathBehavior::Loop; + pathLoop.pathName = "ExampleLoopPath"; + + + pathLoop.pathWaypoints.push_back(waypointStart); + pathLoop.pathWaypoints.push_back(waypointMiddle); + pathLoop.pathWaypoints.push_back(waypointEnd); + + Game::zoneManager->GetZone()->AddPath(pathLoop); + } // Set our starting position info.pos = NiPoint3(25, 26, 27); info.rot = NiQuaternion(28, 29, 30, 31); @@ -61,7 +87,7 @@ class MovingPlatformComponentTests : public GameDependenciesTest { baseEntity = std::make_unique(15, GameDependenciesTest::info); auto* simplePhysicsComponent = baseEntity->AddComponent(1); - auto* movingPlatformComponent = baseEntity->AddComponent("ExamplePath"); + auto* movingPlatformComponent = baseEntity->AddComponent("ExampleOncePath"); movingPlatformComponent->LoadConfigData(); movingPlatformComponent->LoadDataFromTemplate(); } @@ -176,7 +202,7 @@ class MovingPlatformComponentTests : public GameDependenciesTest { ASSERT_TRUE(bitStream.Read(pathNameLength)); pathName.resize(pathNameLength); ASSERT_TRUE(bitStream.ReadBits(reinterpret_cast(pathName.data()), BYTES_TO_BITS(pathNameLength) * 2)); - ASSERT_EQ(pathName, u"ExamplePath"); + ASSERT_EQ(pathName, u"ExampleOncePath"); uint32_t pathStartIndex; ASSERT_TRUE(bitStream.Read(pathStartIndex)); @@ -229,10 +255,12 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformSerializationTest) { TestSerialization(); } -TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceForwardTest) { +TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathOnceAdvanceTest) { MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); - moverPlatformSubComponent.SetupPath("ExamplePath", 0, false); - + moverPlatformSubComponent.SetupPath("ExampleOncePath", 0, false); + + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 0); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1); moverPlatformSubComponent.AdvanceToNextWaypoint(); ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 1); ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 2); @@ -240,41 +268,63 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceForwar ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 2); ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 2); ASSERT_FALSE(moverPlatformSubComponent.GetInReverse()); - path.pathBehavior = PathBehavior::Bounce; moverPlatformSubComponent.AdvanceToNextWaypoint(); ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 2); - ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1); - ASSERT_TRUE(moverPlatformSubComponent.GetInReverse()); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 2); + ASSERT_FALSE(moverPlatformSubComponent.GetInReverse()); } -TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceReverseTest) { +TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathBounceAdvanceTest) { MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); - moverPlatformSubComponent.SetupPath("ExamplePath", 0, true); - - moverPlatformSubComponent.AdvanceToNextReverseWaypoint(); + moverPlatformSubComponent.SetupPath("ExampleBouncePath", 0, false); + + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 0); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1); + moverPlatformSubComponent.AdvanceToNextWaypoint(); ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 1); - ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 0); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 2); + ASSERT_FALSE(moverPlatformSubComponent.GetInReverse()); + moverPlatformSubComponent.AdvanceToNextWaypoint(); + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 2); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1); ASSERT_TRUE(moverPlatformSubComponent.GetInReverse()); moverPlatformSubComponent.AdvanceToNextReverseWaypoint(); - ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 0); + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 1); ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 0); ASSERT_TRUE(moverPlatformSubComponent.GetInReverse()); - path.pathBehavior = PathBehavior::Bounce; - moverPlatformSubComponent.AdvanceToNextWaypoint(); + moverPlatformSubComponent.AdvanceToNextReverseWaypoint(); ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 0); ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1); - ASSERT_TRUE(moverPlatformSubComponent.GetInReverse()); + ASSERT_FALSE(moverPlatformSubComponent.GetInReverse()); } -TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceTest) { +TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentLoopAdvanceTest) { MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); - moverPlatformSubComponent.SetupPath("ExamplePath", 0, false); - + moverPlatformSubComponent.SetupPath("ExampleLoopPath", 0, false); + + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 0); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1); moverPlatformSubComponent.AdvanceToNextWaypoint(); ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 1); ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 2); + moverPlatformSubComponent.AdvanceToNextWaypoint(); + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 2); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 0); ASSERT_FALSE(moverPlatformSubComponent.GetInReverse()); moverPlatformSubComponent.AdvanceToNextWaypoint(); + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 0); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1); + ASSERT_FALSE(moverPlatformSubComponent.GetInReverse()); +} + +TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentLoopAdvanceReverseTest) { + MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); + moverPlatformSubComponent.SetupPath("ExampleLoopPath", 0, true); + + ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 0); + ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 2); + ASSERT_TRUE(moverPlatformSubComponent.GetInReverse()); + moverPlatformSubComponent.AdvanceToNextReverseWaypoint(); ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 2); ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1); ASSERT_TRUE(moverPlatformSubComponent.GetInReverse()); @@ -284,18 +334,15 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformSubComponentPathAdvanceTest) ASSERT_TRUE(moverPlatformSubComponent.GetInReverse()); moverPlatformSubComponent.AdvanceToNextReverseWaypoint(); ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 0); - ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 1); - ASSERT_FALSE(moverPlatformSubComponent.GetInReverse()); - moverPlatformSubComponent.AdvanceToNextWaypoint(); - ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypointIndex(), 1); ASSERT_EQ(moverPlatformSubComponent.GetNextWaypointIndex(), 2); - ASSERT_FALSE(moverPlatformSubComponent.GetInReverse()); + ASSERT_TRUE(moverPlatformSubComponent.GetInReverse()); } + TEST_F(MovingPlatformComponentTests, MovingPlatformMoverSpeedCalculationTest) { MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); - moverPlatformSubComponent.SetupPath("ExamplePath", 0, false); + moverPlatformSubComponent.SetupPath("ExampleOncePath", 0, false); ASSERT_EQ(moverPlatformSubComponent.CalculateSpeed(), 16.0f); NiPoint3 r = moverPlatformSubComponent.CalculateLinearVelocity(); @@ -307,7 +354,7 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformMoverSpeedCalculationTest) { TEST_F(MovingPlatformComponentTests, MovingPlatformNextAndCurrentWaypointAccess) { MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); - moverPlatformSubComponent.SetupPath("ExamplePath", 0, false); + moverPlatformSubComponent.SetupPath("ExampleOncePath", 0, false); ASSERT_EQ(moverPlatformSubComponent.GetCurrentWaypoint().position, NiPoint3(1, 2, 3)); ASSERT_EQ(moverPlatformSubComponent.GetNextWaypoint().position, NiPoint3(4, 5, 6)); @@ -318,29 +365,30 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformNextAndCurrentWaypointAccess) TEST_F(MovingPlatformComponentTests, MovingPlatformRunTest) { MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); - moverPlatformSubComponent.SetupPath("ExamplePath", 0, false); + moverPlatformSubComponent.SetupPath("ExampleOncePath", 0, false); - path.pathWaypoints.at(0).position = NiPoint3(99.296440f, 419.293335f, 207.219498f); - path.pathWaypoints.at(0).movingPlatform.speed = 16.0f; + pathOnce.pathWaypoints.at(1).position = NiPoint3(99.296440f, 419.293335f, 207.219498f); + pathOnce.pathWaypoints.at(1).movingPlatform.speed = 16.0f; - path.pathWaypoints.at(1).position = NiPoint3(141.680099f, 419.990051f, 208.680450f); - path.pathWaypoints.at(1).movingPlatform.speed = 16.0f; + pathOnce.pathWaypoints.at(2).position = NiPoint3(141.680099f, 419.990051f, 208.680450f); + pathOnce.pathWaypoints.at(2).movingPlatform.speed = 16.0f; moverPlatformSubComponent.UpdateLinearVelocity(); moverPlatformSubComponent.Update(2.65f); - + auto [x,y,z] = moverPlatformSubComponent.GetPosition(); + LOG_TEST("x: %f, y: %f, z: %f", x, y, z); // just check that its close enough - EXPECT_LT(141.680099f - moverPlatformSubComponent.GetPosition().x, 0.1f); - EXPECT_LT(419.990051f - moverPlatformSubComponent.GetPosition().y, 0.1f); - EXPECT_LT(208.680450f - moverPlatformSubComponent.GetPosition().z, 0.1f); + EXPECT_LT(141.680099f - x, 0.1f); + EXPECT_LT(419.990051f - y, 0.1f); + EXPECT_LT(208.680450f - z, 0.1f); } TEST_F(MovingPlatformComponentTests, MovingPlatformPercentBetweenPointsTest) { MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); - moverPlatformSubComponent.SetupPath("ExamplePath", 0, false); + moverPlatformSubComponent.SetupPath("ExampleOncePath", 0, false); - path.pathWaypoints.at(0).position = NiPoint3(0, 0, 1); - path.pathWaypoints.at(1).position = NiPoint3(0, 0, 3); + pathOnce.pathWaypoints.at(0).position = NiPoint3(0, 0, 1); + pathOnce.pathWaypoints.at(1).position = NiPoint3(0, 0, 3); // moverPlatformSubComponent.m_Position = NiPoint3(0, 0, 1); ASSERT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 0.0f); // moverPlatformSubComponent.m_Position = NiPoint3(0, 0, 2); From 52228ece16de486629014d6c7df714fc6913dbf5 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Sat, 17 Feb 2024 02:41:17 -0600 Subject: [PATCH 15/17] Make the test have the capability of passing if the code is correct Before the platform was not moving and the positions werent; getting updated --- .../MovingPlatformComponentTests.cpp | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp index a5db068a8..84d9b80f5 100644 --- a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp @@ -364,19 +364,21 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformNextAndCurrentWaypointAccess) } TEST_F(MovingPlatformComponentTests, MovingPlatformRunTest) { + baseEntity->SetPosition(NiPoint3(99.296440f, 419.293335f, 207.219498f)); MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); moverPlatformSubComponent.SetupPath("ExampleOncePath", 0, false); - pathOnce.pathWaypoints.at(1).position = NiPoint3(99.296440f, 419.293335f, 207.219498f); - pathOnce.pathWaypoints.at(1).movingPlatform.speed = 16.0f; + pathOnce.pathWaypoints.at(0).position = NiPoint3(99.296440f, 419.293335f, 207.219498f); + pathOnce.pathWaypoints.at(0).movingPlatform.speed = 16.0f; - pathOnce.pathWaypoints.at(2).position = NiPoint3(141.680099f, 419.990051f, 208.680450f); - pathOnce.pathWaypoints.at(2).movingPlatform.speed = 16.0f; + pathOnce.pathWaypoints.at(1).position = NiPoint3(141.680099f, 419.990051f, 208.680450f); + pathOnce.pathWaypoints.at(1).movingPlatform.speed = 16.0f; moverPlatformSubComponent.UpdateLinearVelocity(); + moverPlatformSubComponent.StartPathing(); moverPlatformSubComponent.Update(2.65f); + auto [x,y,z] = moverPlatformSubComponent.GetPosition(); - LOG_TEST("x: %f, y: %f, z: %f", x, y, z); // just check that its close enough EXPECT_LT(141.680099f - x, 0.1f); EXPECT_LT(419.990051f - y, 0.1f); @@ -384,17 +386,26 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformRunTest) { } TEST_F(MovingPlatformComponentTests, MovingPlatformPercentBetweenPointsTest) { - MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); - moverPlatformSubComponent.SetupPath("ExampleOncePath", 0, false); - - pathOnce.pathWaypoints.at(0).position = NiPoint3(0, 0, 1); - pathOnce.pathWaypoints.at(1).position = NiPoint3(0, 0, 3); - // moverPlatformSubComponent.m_Position = NiPoint3(0, 0, 1); - ASSERT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 0.0f); - // moverPlatformSubComponent.m_Position = NiPoint3(0, 0, 2); - ASSERT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 0.5f); - // moverPlatformSubComponent.m_Position = NiPoint3(0, 0, 3); - ASSERT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 1.0f); + pathOnce.pathWaypoints.at(0).position = NiPoint3(1, 0, 0); + pathOnce.pathWaypoints.at(1).position = NiPoint3(3, 0, 0); + { + baseEntity->SetPosition(NiPoint3(1, 0, 0)); + MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); + moverPlatformSubComponent.SetupPath("ExampleOncePath", 0, false); + ASSERT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 0.0f); + } + { + baseEntity->SetPosition(NiPoint3(2, 0, 0)); + MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); + moverPlatformSubComponent.SetupPath("ExampleOncePath", 0, false); + ASSERT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 0.5f); + } + { + baseEntity->SetPosition(NiPoint3(3, 0, 0)); + MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); + moverPlatformSubComponent.SetupPath("ExampleOncePath", 0, false); + ASSERT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 1.0f); + } // moverPlatformSubComponent.m_TimeBasedMovement = true; - ASSERT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 0.0f); + // ASSERT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 0.0f); } From d4ca011466c1a9d97d79331ab173b80c95483edb Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Sat, 17 Feb 2024 03:21:41 -0600 Subject: [PATCH 16/17] fix tests --- .../MovingPlatformComponentTests.cpp | 74 ++++++++++++++----- 1 file changed, 57 insertions(+), 17 deletions(-) diff --git a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp index 84d9b80f5..9d8e31f26 100644 --- a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp @@ -365,14 +365,28 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformNextAndCurrentWaypointAccess) TEST_F(MovingPlatformComponentTests, MovingPlatformRunTest) { baseEntity->SetPosition(NiPoint3(99.296440f, 419.293335f, 207.219498f)); - MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); - moverPlatformSubComponent.SetupPath("ExampleOncePath", 0, false); + Path path; + + PathWaypoint waypointStart; + waypointStart.position = NiPoint3(99.296440f, 419.293335f, 207.219498f); + waypointStart.rotation = NiQuaternion(0, 0, 0, 0); + waypointStart.movingPlatform.speed = 16.0f; - pathOnce.pathWaypoints.at(0).position = NiPoint3(99.296440f, 419.293335f, 207.219498f); - pathOnce.pathWaypoints.at(0).movingPlatform.speed = 16.0f; + PathWaypoint waypointEnd; + waypointEnd.position = NiPoint3(141.680099f, 419.990051f, 208.680450f); + waypointEnd.rotation = NiQuaternion(0, 0, 0, 0); - pathOnce.pathWaypoints.at(1).position = NiPoint3(141.680099f, 419.990051f, 208.680450f); - pathOnce.pathWaypoints.at(1).movingPlatform.speed = 16.0f; + waypointStart.movingPlatform.speed = 16.0f; + path.movingPlatform.timeBasedMovement = false; + path.pathBehavior = PathBehavior::Once; + path.pathName = "ExamplePath"; + + path.pathWaypoints.push_back(waypointStart); + path.pathWaypoints.push_back(waypointEnd); + + Game::zoneManager->GetZone()->AddPath(path); + MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); + moverPlatformSubComponent.SetupPath("ExamplePath", 0, false); moverPlatformSubComponent.UpdateLinearVelocity(); moverPlatformSubComponent.StartPathing(); @@ -386,26 +400,52 @@ TEST_F(MovingPlatformComponentTests, MovingPlatformRunTest) { } TEST_F(MovingPlatformComponentTests, MovingPlatformPercentBetweenPointsTest) { - pathOnce.pathWaypoints.at(0).position = NiPoint3(1, 0, 0); - pathOnce.pathWaypoints.at(1).position = NiPoint3(3, 0, 0); + + Path path; + + PathWaypoint waypointStart; + waypointStart.position = NiPoint3(0, 0, 0); + waypointStart.rotation = NiQuaternion(0, 0, 0, 0); + waypointStart.movingPlatform.speed = 16.0f; + + PathWaypoint waypointEnd; + waypointEnd.position = NiPoint3(2, 0, 0); + waypointEnd.rotation = NiQuaternion(0, 0, 0, 0); + + waypointStart.movingPlatform.speed = 16.0f; + path.movingPlatform.timeBasedMovement = false; + path.pathBehavior = PathBehavior::Once; + path.pathName = "ExamplePath"; + + path.pathWaypoints.push_back(waypointStart); + path.pathWaypoints.push_back(waypointEnd); + + Game::zoneManager->GetZone()->AddPath(path); + { + baseEntity->SetPosition(NiPoint3(0, 0, 0)); + MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); + moverPlatformSubComponent.SetupPath("ExamplePath", 0, false); + EXPECT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 0.0f); + } { baseEntity->SetPosition(NiPoint3(1, 0, 0)); MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); - moverPlatformSubComponent.SetupPath("ExampleOncePath", 0, false); - ASSERT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 0.0f); + moverPlatformSubComponent.SetupPath("ExamplePath", 0, false); + EXPECT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 0.5f); } { baseEntity->SetPosition(NiPoint3(2, 0, 0)); MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); - moverPlatformSubComponent.SetupPath("ExampleOncePath", 0, false); - ASSERT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 0.5f); + moverPlatformSubComponent.SetupPath("ExamplePath", 0, false); + EXPECT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 1.0f); } { - baseEntity->SetPosition(NiPoint3(3, 0, 0)); + path.movingPlatform.timeBasedMovement = true; + path.pathName = "ExamplePath2"; + Game::zoneManager->GetZone()->AddPath(path); + baseEntity->SetPosition(NiPoint3(1, 0, 0)); MoverPlatformSubComponent moverPlatformSubComponent(baseEntity->GetComponent()); - moverPlatformSubComponent.SetupPath("ExampleOncePath", 0, false); - ASSERT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 1.0f); + moverPlatformSubComponent.SetupPath("ExamplePath2", 0, false); + ASSERT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 0.0f); } - // moverPlatformSubComponent.m_TimeBasedMovement = true; - // ASSERT_FLOAT_EQ(moverPlatformSubComponent.CalculatePercentToNextWaypoint(), 0.0f); } From bb8d4f2eb79e072f2700bced64cc8b22f73ee27c Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Sun, 18 Feb 2024 00:55:20 -0600 Subject: [PATCH 17/17] impl mover and rotator loadconfigdata --- dGame/dComponents/MovingPlatformComponent.cpp | 28 +++++++++++++++++++ dGame/dComponents/MovingPlatformComponent.h | 14 ++++++++++ 2 files changed, 42 insertions(+) diff --git a/dGame/dComponents/MovingPlatformComponent.cpp b/dGame/dComponents/MovingPlatformComponent.cpp index ac79c0d1d..38ead3412 100644 --- a/dGame/dComponents/MovingPlatformComponent.cpp +++ b/dGame/dComponents/MovingPlatformComponent.cpp @@ -249,12 +249,40 @@ MoverPlatformSubComponent::MoverPlatformSubComponent(MovingPlatformComponent* pa } +void MoverPlatformSubComponent::LoadConfigData() { + m_AllowPositionSnapping = m_ParentComponent->GetParent()->GetVar(u"allowPosSnap"); + if(m_ParentComponent->GetParent()->HasVar(u"maxLerpDist")){ + m_MaxLerpDistnace = m_ParentComponent->GetParent()->GetVar(u"maxLerpDist"); + m_MaxLerpDistnace = m_MaxLerpDistnace * m_MaxLerpDistnace; + } + +} //------------- MoverPlatformSubComponent end -------------- //------------- RotatorPlatformSubComponent begin -------------- RotatorPlatformSubComponent::RotatorPlatformSubComponent(MovingPlatformComponent* parentComponent) : PlatformSubComponent(parentComponent) { +} +void RotatorPlatformSubComponent::LoadConfigData() { + if(m_ParentComponent->GetParent()->HasVar(u"rotX")){ + m_Rotation.x = m_ParentComponent->GetParent()->GetVar(u"rotX") * M_PI; + } + if(m_ParentComponent->GetParent()->HasVar(u"rotY")){ + m_Rotation.y = m_ParentComponent->GetParent()->GetVar(u"rotY") * M_PI; + } + if(m_ParentComponent->GetParent()->HasVar(u"rotZ")){ + m_Rotation.z = m_ParentComponent->GetParent()->GetVar(u"rotZ") * M_PI; + } + if(m_ParentComponent->GetParent()->HasVar(u"allowRotSnap")){ + m_AllowRotationSnapping = m_ParentComponent->GetParent()->GetVar(u"allowRotSnap"); + } + if(m_AllowRotationSnapping) { + if(m_ParentComponent->GetParent()->HasVar(u"maxLerpAngle")){ + m_MaxLerpAngle = (m_ParentComponent->GetParent()->GetVar(u"maxLerpAngle") * M_PI) / 180; + } + } + } //------------- RotatorPlatformSubComponent end -------------- diff --git a/dGame/dComponents/MovingPlatformComponent.h b/dGame/dComponents/MovingPlatformComponent.h index fc2b9f3fa..270dc0cc9 100644 --- a/dGame/dComponents/MovingPlatformComponent.h +++ b/dGame/dComponents/MovingPlatformComponent.h @@ -123,6 +123,11 @@ class MoverPlatformSubComponent : public PlatformSubComponent { MoverPlatformSubComponent(MovingPlatformComponent* parentComponent); ~MoverPlatformSubComponent() override = default; eMoverSubComponentType GetPlatformType() override { return eMoverSubComponentType::Mover; } + void LoadConfigData() override; + +private: + bool m_AllowPositionSnapping = true; + float m_MaxLerpDistnace = 16.0f; }; class RotatorPlatformSubComponent : public PlatformSubComponent { @@ -131,7 +136,16 @@ class RotatorPlatformSubComponent : public PlatformSubComponent { RotatorPlatformSubComponent(MovingPlatformComponent* parentComponent); ~RotatorPlatformSubComponent() override = default; eMoverSubComponentType GetPlatformType() override { return eMoverSubComponentType::Rotator; } + void LoadConfigData() override; void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override { PlatformSubComponent::Serialize(outBitStream, bIsInitialUpdate); }; +private: + NiPoint3 m_Rotation = NiPoint3Constant::ZERO; + float m_Rate = 0.0f; + NiPoint3 m_AngularVelocity = NiPoint3Constant::ZERO; + bool m_AllowRotationSnapping = true; + float m_MaxLerpAngle = 0.1396263; + bool m_DirtyAngularVelocity = false; + float m_UnknownFloat = 0.0f; }; // Only moves. Has NO path. This moving platform gets its initial position and rotation from the server on serialization.