diff --git a/dCommon/GeneralUtils.h b/dCommon/GeneralUtils.h index 69c5fc44..57806a16 100644 --- a/dCommon/GeneralUtils.h +++ b/dCommon/GeneralUtils.h @@ -300,6 +300,12 @@ namespace GeneralUtils { return T(); } + template + inline Container::value_type GetRandomElement(const Container& container) { + DluAssert(!container.empty()); + return container[GenerateRandomNumber(0, container.size() - 1)]; + } + /** * Casts the value of an enum entry to its underlying type * @param entry Enum entry to cast diff --git a/dGame/dComponents/MovementAIComponent.cpp b/dGame/dComponents/MovementAIComponent.cpp index 9463e7d6..ea62cd17 100644 --- a/dGame/dComponents/MovementAIComponent.cpp +++ b/dGame/dComponents/MovementAIComponent.cpp @@ -14,6 +14,7 @@ #include "dZoneManager.h" #include "CDComponentsRegistryTable.h" +#include "QuickBuildComponent.h" #include "CDPhysicsComponentTable.h" #include "dNavMesh.h" @@ -89,6 +90,9 @@ void MovementAIComponent::Resume() { void MovementAIComponent::Update(const float deltaTime) { if (m_Paused) return; + auto* const quickBuildComponent = m_Parent->GetComponent(); + if (quickBuildComponent && quickBuildComponent->GetState() != eQuickBuildState::COMPLETED) return; + if (m_PullingToPoint) { const auto source = GetCurrentWaypoint(); @@ -154,6 +158,7 @@ void MovementAIComponent::Update(const float deltaTime) { } } else { // Check if there are more waypoints in the queue, if so set our next destination to the next waypoint + const auto waypointNum = m_IsBounced ? m_CurrentPath.size() : m_CurrentPathWaypointCount - m_CurrentPath.size() - 1; if (m_CurrentPath.empty()) { if (m_Path) { if (m_Path->pathBehavior == PathBehavior::Loop) { @@ -161,20 +166,24 @@ void MovementAIComponent::Update(const float deltaTime) { } else if (m_Path->pathBehavior == PathBehavior::Bounce) { m_IsBounced = !m_IsBounced; std::vector waypoints = m_Path->pathWaypoints; - if (m_IsBounced) std::reverse(waypoints.begin(), waypoints.end()); + if (m_IsBounced) std::ranges::reverse(waypoints); SetPath(waypoints); } else if (m_Path->pathBehavior == PathBehavior::Once) { + m_Parent->GetScript()->OnWaypointReached(m_Parent, waypointNum); Stop(); return; } } else { + m_Parent->GetScript()->OnWaypointReached(m_Parent, waypointNum); Stop(); return; } - } - SetDestination(m_CurrentPath.top().position); + } else { + m_Parent->GetScript()->OnWaypointReached(m_Parent, waypointNum); + SetDestination(m_CurrentPath.top().position); - m_CurrentPath.pop(); + m_CurrentPath.pop(); + } } Game::entityManager->SerializeEntity(m_Parent); @@ -250,6 +259,7 @@ void MovementAIComponent::Stop() { m_InterpolatedWaypoints.clear(); while (!m_CurrentPath.empty()) m_CurrentPath.pop(); + m_CurrentPathWaypointCount = 0; m_PathIndex = 0; @@ -272,6 +282,7 @@ void MovementAIComponent::SetPath(std::vector path) { this->m_CurrentPath.push(point); }); + m_CurrentPathWaypointCount = path.size(); SetDestination(path.front().position); } diff --git a/dGame/dComponents/MovementAIComponent.h b/dGame/dComponents/MovementAIComponent.h index dbb0661c..6c612b7e 100644 --- a/dGame/dComponents/MovementAIComponent.h +++ b/dGame/dComponents/MovementAIComponent.h @@ -209,6 +209,8 @@ public: */ static float GetBaseSpeed(LOT lot); + bool IsPaused() const { return m_Paused; } + private: /** @@ -323,6 +325,9 @@ private: NiPoint3 m_SavedVelocity; bool m_IsBounced{}; + + // The number of waypoints that were on the path in the call to SetPath + uint32_t m_CurrentPathWaypointCount{ 0 }; }; #endif // MOVEMENTAICOMPONENT_H