chore: Small movementAiComponent cleanup (#1145)

* rename and cleanup file

* more

* fix broken function

* Further naming fixes

t

Revert "Further naming fixes"

This reverts commit 057189982ba56788d48f9265d815e6c562ba6328.

* next step

* undo all testing changes

* minor tweaks
This commit is contained in:
David Markowitz 2023-08-03 19:38:04 -07:00 committed by GitHub
parent 208ed02158
commit d8a5fd49a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 131 additions and 295 deletions

View File

@ -318,7 +318,7 @@ void BaseCombatAIComponent::CalculateCombat(const float deltaTime) {
// Speed towards start position // Speed towards start position
if (m_MovementAI != nullptr) { if (m_MovementAI != nullptr) {
m_MovementAI->SetHaltDistance(0); m_MovementAI->SetHaltDistance(0);
m_MovementAI->SetSpeed(m_PursuitSpeed); m_MovementAI->SetMaxSpeed(m_PursuitSpeed);
m_MovementAI->SetDestination(m_StartPosition); m_MovementAI->SetDestination(m_StartPosition);
} }
@ -382,8 +382,6 @@ void BaseCombatAIComponent::CalculateCombat(const float deltaTime) {
} }
LWOOBJID BaseCombatAIComponent::FindTarget() { LWOOBJID BaseCombatAIComponent::FindTarget() {
//const auto reference = m_MovementAI == nullptr ? m_StartPosition : m_MovementAI->ApproximateLocation();
NiPoint3 reference = m_StartPosition; NiPoint3 reference = m_StartPosition;
if (m_MovementAI) reference = m_MovementAI->ApproximateLocation(); if (m_MovementAI) reference = m_MovementAI->ApproximateLocation();
@ -660,17 +658,17 @@ void BaseCombatAIComponent::Wander() {
destination.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(destination); destination.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(destination);
} }
if (Vector3::DistanceSquared(destination, m_MovementAI->GetCurrentPosition()) < 2 * 2) { if (Vector3::DistanceSquared(destination, m_MovementAI->GetParent()->GetPosition()) < 2 * 2) {
m_MovementAI->Stop(); m_MovementAI->Stop();
return; return;
} }
m_MovementAI->SetSpeed(m_TetherSpeed); m_MovementAI->SetMaxSpeed(m_TetherSpeed);
m_MovementAI->SetDestination(destination); m_MovementAI->SetDestination(destination);
m_Timer += (m_MovementAI->GetCurrentPosition().x - destination.x) / m_TetherSpeed; m_Timer += (m_MovementAI->GetParent()->GetPosition().x - destination.x) / m_TetherSpeed;
} }
void BaseCombatAIComponent::OnAggro() { void BaseCombatAIComponent::OnAggro() {
@ -685,21 +683,21 @@ void BaseCombatAIComponent::OnAggro() {
m_MovementAI->SetHaltDistance(m_AttackRadius); m_MovementAI->SetHaltDistance(m_AttackRadius);
NiPoint3 targetPos = target->GetPosition(); NiPoint3 targetPos = target->GetPosition();
NiPoint3 currentPos = m_MovementAI->GetCurrentPosition(); NiPoint3 currentPos = m_MovementAI->GetParent()->GetPosition();
// If the player's position is within range, attack // If the player's position is within range, attack
if (Vector3::DistanceSquared(currentPos, targetPos) <= m_AttackRadius * m_AttackRadius) { if (Vector3::DistanceSquared(currentPos, targetPos) <= m_AttackRadius * m_AttackRadius) {
m_MovementAI->Stop(); m_MovementAI->Stop();
} else if (Vector3::DistanceSquared(m_StartPosition, targetPos) > m_HardTetherRadius * m_HardTetherRadius) //Return to spawn if we're too far } else if (Vector3::DistanceSquared(m_StartPosition, targetPos) > m_HardTetherRadius * m_HardTetherRadius) //Return to spawn if we're too far
{ {
m_MovementAI->SetSpeed(m_PursuitSpeed); m_MovementAI->SetMaxSpeed(m_PursuitSpeed);
m_MovementAI->SetDestination(m_StartPosition); m_MovementAI->SetDestination(m_StartPosition);
} else //Chase the player's new position } else //Chase the player's new position
{ {
if (IsMech() && Vector3::DistanceSquared(targetPos, currentPos) > m_AttackRadius * m_AttackRadius * 3 * 3) return; if (IsMech() && Vector3::DistanceSquared(targetPos, currentPos) > m_AttackRadius * m_AttackRadius * 3 * 3) return;
m_MovementAI->SetSpeed(m_PursuitSpeed); m_MovementAI->SetMaxSpeed(m_PursuitSpeed);
m_MovementAI->SetDestination(targetPos); m_MovementAI->SetDestination(targetPos);
@ -725,7 +723,7 @@ void BaseCombatAIComponent::OnTether() {
m_MovementAI->Stop(); m_MovementAI->Stop();
} else if (Vector3::DistanceSquared(m_StartPosition, targetPos) > m_HardTetherRadius * m_HardTetherRadius) //Return to spawn if we're too far } else if (Vector3::DistanceSquared(m_StartPosition, targetPos) > m_HardTetherRadius * m_HardTetherRadius) //Return to spawn if we're too far
{ {
m_MovementAI->SetSpeed(m_PursuitSpeed); m_MovementAI->SetMaxSpeed(m_PursuitSpeed);
m_MovementAI->SetDestination(m_StartPosition); m_MovementAI->SetDestination(m_StartPosition);
@ -733,7 +731,7 @@ void BaseCombatAIComponent::OnTether() {
} else { } else {
if (IsMech() && Vector3::DistanceSquared(targetPos, currentPos) > m_AttackRadius * m_AttackRadius * 3 * 3) return; if (IsMech() && Vector3::DistanceSquared(targetPos, currentPos) > m_AttackRadius * m_AttackRadius * 3 * 3) return;
m_MovementAI->SetSpeed(m_PursuitSpeed); m_MovementAI->SetMaxSpeed(m_PursuitSpeed);
m_MovementAI->SetDestination(targetPos); m_MovementAI->SetDestination(targetPos);
} }

View File

@ -10,85 +10,77 @@
#include "EntityManager.h" #include "EntityManager.h"
#include "SimplePhysicsComponent.h" #include "SimplePhysicsComponent.h"
#include "CDClientManager.h" #include "CDClientManager.h"
#include "Game.h"
#include "dZoneManager.h"
#include "CDComponentsRegistryTable.h" #include "CDComponentsRegistryTable.h"
#include "CDPhysicsComponentTable.h" #include "CDPhysicsComponentTable.h"
std::map<LOT, float> MovementAIComponent::m_PhysicsSpeedCache = {}; namespace {
/**
* Cache of all lots and their respective speeds
*/
std::map<LOT, float> m_PhysicsSpeedCache;
}
MovementAIComponent::MovementAIComponent(Entity* parent, MovementAIInfo info) : Component(parent) { MovementAIComponent::MovementAIComponent(Entity* parent, MovementAIInfo info) : Component(parent) {
m_Info = std::move(info); m_Info = info;
m_Done = true; m_AtFinalWaypoint = true;
m_BaseCombatAI = nullptr; m_BaseCombatAI = nullptr;
m_BaseCombatAI = reinterpret_cast<BaseCombatAIComponent*>(m_Parent->GetComponent(eReplicaComponentType::BASE_COMBAT_AI)); m_BaseCombatAI = m_Parent->GetComponent<BaseCombatAIComponent>();
//Try and fix the insane values: //Try and fix the insane values:
if (m_Info.wanderRadius > 5.0f) m_Info.wanderRadius = m_Info.wanderRadius * 0.5f; if (m_Info.wanderRadius > 5.0f) m_Info.wanderRadius *= 0.5f;
if (m_Info.wanderRadius > 8.0f) m_Info.wanderRadius = 8.0f; if (m_Info.wanderRadius > 8.0f) m_Info.wanderRadius = 8.0f;
if (m_Info.wanderSpeed > 0.5f) m_Info.wanderSpeed = m_Info.wanderSpeed * 0.5f; if (m_Info.wanderSpeed > 0.5f) m_Info.wanderSpeed *= 0.5f;
m_BaseSpeed = GetBaseSpeed(m_Parent->GetLOT()); m_BaseSpeed = GetBaseSpeed(m_Parent->GetLOT());
m_NextWaypoint = GetCurrentPosition(); m_NextWaypoint = m_Parent->GetPosition();
m_Acceleration = 0.4f; m_Acceleration = 0.4f;
m_Interrupted = false; m_PullingToPoint = false;
m_PullPoint = {}; m_PullPoint = NiPoint3::ZERO;
m_HaltDistance = 0; m_HaltDistance = 0;
m_Timer = 0; m_TimeToTravel = 0;
m_TimeTravelled = 0;
m_CurrentSpeed = 0; m_CurrentSpeed = 0;
m_Speed = 0; m_MaxSpeed = 0;
m_TotalTime = 0;
m_LockRotation = false; m_LockRotation = false;
} }
MovementAIComponent::~MovementAIComponent() = default;
void MovementAIComponent::Update(const float deltaTime) { void MovementAIComponent::Update(const float deltaTime) {
if (m_Interrupted) { if (m_PullingToPoint) {
const auto source = GetCurrentWaypoint(); const auto source = GetCurrentWaypoint();
const auto speed = deltaTime * 2.5f; const auto speed = deltaTime * 2.5f;
NiPoint3 velocity; NiPoint3 velocity = (m_PullPoint - source) * speed;
velocity.x = (m_PullPoint.x - source.x) * speed;
velocity.y = (m_PullPoint.y - source.y) * speed;
velocity.z = (m_PullPoint.z - source.z) * speed;
SetPosition(source + velocity); SetPosition(source + velocity);
if (Vector3::DistanceSquared(GetCurrentPosition(), m_PullPoint) < 2 * 2) { if (Vector3::DistanceSquared(m_Parent->GetPosition(), m_PullPoint) < std::pow(2, 2)) {
m_Interrupted = false; m_PullingToPoint = false;
} }
return; return;
} }
if (AtFinalWaypoint()) // Are we done? // Are we done?
{ if (AtFinalWaypoint()) return;
return;
}
if (m_HaltDistance > 0) { if (m_HaltDistance > 0) {
if (Vector3::DistanceSquared(ApproximateLocation(), GetDestination()) < m_HaltDistance * m_HaltDistance) // Prevent us from hugging the target // Prevent us from hugging the target
{ if (Vector3::DistanceSquared(ApproximateLocation(), GetDestination()) < std::pow(m_HaltDistance, 2)) {
Stop(); Stop();
return; return;
} }
} }
if (m_Timer > 0) { m_TimeTravelled += deltaTime;
m_Timer -= deltaTime; if (m_TimeTravelled < m_TimeToTravel) return;
m_TimeTravelled = 0.0f;
if (m_Timer > 0) {
return;
}
m_Timer = 0;
}
const auto source = GetCurrentWaypoint(); const auto source = GetCurrentWaypoint();
@ -101,48 +93,44 @@ void MovementAIComponent::Update(const float deltaTime) {
m_NextWaypoint = GetCurrentWaypoint(); m_NextWaypoint = GetCurrentWaypoint();
if (m_NextWaypoint == source) { if (m_NextWaypoint == source) {
m_Timer = 0; m_TimeToTravel = 0.0f;
goto nextAction; goto nextAction;
} }
if (m_CurrentSpeed < m_Speed) { if (m_CurrentSpeed < m_MaxSpeed) {
m_CurrentSpeed += m_Acceleration; m_CurrentSpeed += m_Acceleration;
} }
if (m_CurrentSpeed > m_Speed) { if (m_CurrentSpeed > m_MaxSpeed) {
m_CurrentSpeed = m_Speed; m_CurrentSpeed = m_MaxSpeed;
} }
const auto speed = m_CurrentSpeed * m_BaseSpeed; const auto speed = m_CurrentSpeed * m_BaseSpeed; // scale speed based on base speed
const auto delta = m_NextWaypoint - source; const auto delta = m_NextWaypoint - source;
// Normalize the vector // Normalize the vector
const auto length = sqrtf(delta.x * delta.x + delta.y * delta.y + delta.z * delta.z); const auto length = delta.Length();
if (length > 0) { if (length > 0) {
velocity.x = (delta.x / length) * speed; velocity = (delta / length) * speed;
velocity.y = (delta.y / length) * speed;
velocity.z = (delta.z / length) * speed;
} }
// Calclute the time it will take to reach the next waypoint with the current speed // Calclute the time it will take to reach the next waypoint with the current speed
m_TotalTime = m_Timer = length / speed; m_TimeTravelled = 0.0f;
m_TimeToTravel = length / speed;
SetRotation(NiQuaternion::LookAt(source, m_NextWaypoint)); SetRotation(NiQuaternion::LookAt(source, m_NextWaypoint));
} else { } else {
// Check if there are more waypoints in the queue, if so set our next destination to the next waypoint // Check if there are more waypoints in the queue, if so set our next destination to the next waypoint
if (!m_Queue.empty()) { if (m_CurrentPath.empty()) {
SetDestination(m_Queue.top());
m_Queue.pop();
} else {
// We have reached our final waypoint
Stop(); Stop();
return; return;
} }
SetDestination(m_CurrentPath.top());
m_CurrentPath.pop();
} }
nextAction: nextAction:
@ -157,7 +145,7 @@ const MovementAIInfo& MovementAIComponent::GetInfo() const {
} }
bool MovementAIComponent::AdvanceWaypointIndex() { bool MovementAIComponent::AdvanceWaypointIndex() {
if (m_PathIndex >= m_CurrentPath.size()) { if (m_PathIndex >= m_InterpolatedWaypoints.size()) {
return false; return false;
} }
@ -167,37 +155,19 @@ bool MovementAIComponent::AdvanceWaypointIndex() {
} }
NiPoint3 MovementAIComponent::GetCurrentWaypoint() const { NiPoint3 MovementAIComponent::GetCurrentWaypoint() const {
if (m_PathIndex >= m_CurrentPath.size()) { return m_PathIndex >= m_InterpolatedWaypoints.size() ? m_Parent->GetPosition() : m_InterpolatedWaypoints[m_PathIndex];
return GetCurrentPosition();
}
return m_CurrentPath[m_PathIndex];
}
NiPoint3 MovementAIComponent::GetNextWaypoint() const {
return m_NextWaypoint;
}
NiPoint3 MovementAIComponent::GetCurrentPosition() const {
return m_Parent->GetPosition();
} }
NiPoint3 MovementAIComponent::ApproximateLocation() const { NiPoint3 MovementAIComponent::ApproximateLocation() const {
auto source = GetCurrentPosition(); auto source = m_Parent->GetPosition();
if (m_Done) { if (AtFinalWaypoint()) return source;
return source;
}
auto destination = m_NextWaypoint; auto destination = m_NextWaypoint;
auto factor = m_TotalTime > 0 ? (m_TotalTime - m_Timer) / m_TotalTime : 0; auto percentageToWaypoint = m_TimeToTravel > 0 ? m_TimeTravelled / m_TimeToTravel : 0;
auto x = source.x + factor * (destination.x - source.x); auto approximation = source + ((destination - source) * percentageToWaypoint);
auto y = source.y + factor * (destination.y - source.y);
auto z = source.z + factor * (destination.z - source.z);
NiPoint3 approximation = NiPoint3(x, y, z);
if (dpWorld::Instance().IsLoaded()) { if (dpWorld::Instance().IsLoaded()) {
approximation.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(approximation); approximation.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(approximation);
@ -226,28 +196,20 @@ bool MovementAIComponent::Warp(const NiPoint3& point) {
return true; return true;
} }
float MovementAIComponent::GetTimer() const {
return m_Timer;
}
bool MovementAIComponent::AtFinalWaypoint() const {
return m_Done;
}
void MovementAIComponent::Stop() { void MovementAIComponent::Stop() {
if (m_Done) { if (AtFinalWaypoint()) return;
return;
}
SetPosition(ApproximateLocation()); SetPosition(ApproximateLocation());
SetVelocity(NiPoint3::ZERO); SetVelocity(NiPoint3::ZERO);
m_TotalTime = m_Timer = 0; m_TimeToTravel = 0;
m_TimeTravelled = 0;
m_Done = true; m_AtFinalWaypoint = true;
m_CurrentPath = {}; m_InterpolatedWaypoints.clear();
while (!m_CurrentPath.empty()) m_CurrentPath.pop();
m_PathIndex = 0; m_PathIndex = 0;
@ -259,20 +221,17 @@ void MovementAIComponent::Stop() {
void MovementAIComponent::PullToPoint(const NiPoint3& point) { void MovementAIComponent::PullToPoint(const NiPoint3& point) {
Stop(); Stop();
m_Interrupted = true; m_PullingToPoint = true;
m_PullPoint = point; m_PullPoint = point;
} }
void MovementAIComponent::SetPath(std::vector<NiPoint3> path) { void MovementAIComponent::SetPath(std::vector<NiPoint3> path) {
std::reverse(path.begin(), path.end()); if (path.empty()) return;
std::for_each(path.rbegin(), path.rend() - 1, [this](const NiPoint3& point) {
this->m_CurrentPath.push(point);
});
for (const auto& point : path) { SetDestination(path.front());
m_Queue.push(point);
}
SetDestination(m_Queue.top());
m_Queue.pop();
} }
float MovementAIComponent::GetBaseSpeed(LOT lot) { float MovementAIComponent::GetBaseSpeed(LOT lot) {
@ -291,26 +250,14 @@ float MovementAIComponent::GetBaseSpeed(LOT lot) {
componentID = componentRegistryTable->GetByIDAndType(lot, eReplicaComponentType::CONTROLLABLE_PHYSICS, -1); componentID = componentRegistryTable->GetByIDAndType(lot, eReplicaComponentType::CONTROLLABLE_PHYSICS, -1);
if (componentID != -1) { if (componentID == -1) {
physicsComponent = physicsComponentTable->GetByID(componentID); componentID = componentRegistryTable->GetByIDAndType(lot, eReplicaComponentType::SIMPLE_PHYSICS, -1);
goto foundComponent;
} }
componentID = componentRegistryTable->GetByIDAndType(lot, eReplicaComponentType::SIMPLE_PHYSICS, -1); physicsComponent = physicsComponentTable->GetByID(componentID);
if (componentID != -1) {
physicsComponent = physicsComponentTable->GetByID(componentID);
goto foundComponent;
}
foundComponent:
// Client defaults speed to 10 and if the speed is also null in the table, it defaults to 10. // Client defaults speed to 10 and if the speed is also null in the table, it defaults to 10.
float speed = 10.0f; float speed = physicsComponent != nullptr ? physicsComponent->speed : 10.0f;
if (physicsComponent) speed = physicsComponent->speed;
float delta = fabs(speed) - 1.0f; float delta = fabs(speed) - 1.0f;
@ -322,39 +269,11 @@ foundComponent:
} }
void MovementAIComponent::SetPosition(const NiPoint3& value) { void MovementAIComponent::SetPosition(const NiPoint3& value) {
auto* controllablePhysicsComponent = m_Parent->GetComponent<ControllablePhysicsComponent>(); m_Parent->SetPosition(value);
if (controllablePhysicsComponent != nullptr) {
controllablePhysicsComponent->SetPosition(value);
return;
}
auto* simplePhysicsComponent = m_Parent->GetComponent<SimplePhysicsComponent>();
if (simplePhysicsComponent != nullptr) {
simplePhysicsComponent->SetPosition(value);
}
} }
void MovementAIComponent::SetRotation(const NiQuaternion& value) { void MovementAIComponent::SetRotation(const NiQuaternion& value) {
if (m_LockRotation) { if (!m_LockRotation) m_Parent->SetRotation(value);
return;
}
auto* controllablePhysicsComponent = m_Parent->GetComponent<ControllablePhysicsComponent>();
if (controllablePhysicsComponent != nullptr) {
controllablePhysicsComponent->SetRotation(value);
return;
}
auto* simplePhysicsComponent = m_Parent->GetComponent<SimplePhysicsComponent>();
if (simplePhysicsComponent != nullptr) {
simplePhysicsComponent->SetRotation(value);
}
} }
void MovementAIComponent::SetVelocity(const NiPoint3& value) { void MovementAIComponent::SetVelocity(const NiPoint3& value) {
@ -373,15 +292,8 @@ void MovementAIComponent::SetVelocity(const NiPoint3& value) {
} }
} }
void MovementAIComponent::SetDestination(const NiPoint3& value) { void MovementAIComponent::SetDestination(const NiPoint3& destination) {
if (m_Interrupted) { if (m_PullingToPoint) return;
return;
}
/*if (Vector3::DistanceSquared(value, GetDestination()) < 2 * 2)
{
return;
}*/
const auto location = ApproximateLocation(); const auto location = ApproximateLocation();
@ -390,97 +302,53 @@ void MovementAIComponent::SetDestination(const NiPoint3& value) {
} }
std::vector<NiPoint3> computedPath; std::vector<NiPoint3> computedPath;
if (dpWorld::Instance().IsLoaded()) { if (dpWorld::Instance().IsLoaded()) {
computedPath = dpWorld::Instance().GetNavMesh()->GetPath(GetCurrentPosition(), value, m_Info.wanderSpeed); computedPath = dpWorld::Instance().GetNavMesh()->GetPath(m_Parent->GetPosition(), destination, m_Info.wanderSpeed);
} else { }
// Somehow failed
if (computedPath.empty()) {
// Than take 10 points between the current position and the destination and make that the path // Than take 10 points between the current position and the destination and make that the path
auto point = location; auto start = location;
auto delta = value - point; auto delta = destination - start;
auto step = delta / 10; auto step = delta / 10.0f;
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
point = point + step; // TODO: Replace this with += when the NiPoint3::operator+= is fixed
start = start + step;
computedPath.push_back(point); computedPath.push_back(start);
} }
} }
if (computedPath.empty()) // Somehow failed m_InterpolatedWaypoints.clear();
{
return;
}
m_CurrentPath.clear();
m_CurrentPath.push_back(location);
// Simply path // Simply path
for (auto point : computedPath) { for (auto& point : computedPath) {
if (dpWorld::Instance().IsLoaded()) { if (dpWorld::Instance().IsLoaded()) {
point.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(point); point.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(point);
} }
m_CurrentPath.push_back(point); m_InterpolatedWaypoints.push_back(point);
} }
m_CurrentPath.push_back(computedPath[computedPath.size() - 1]);
m_PathIndex = 0; m_PathIndex = 0;
m_TotalTime = m_Timer = 0; m_TimeTravelled = 0;
m_TimeToTravel = 0;
m_Done = false; m_AtFinalWaypoint = false;
} }
NiPoint3 MovementAIComponent::GetDestination() const { NiPoint3 MovementAIComponent::GetDestination() const {
if (m_CurrentPath.empty()) { return m_InterpolatedWaypoints.empty() ? m_Parent->GetPosition() : m_InterpolatedWaypoints.back();
return GetCurrentPosition();
}
return m_CurrentPath[m_CurrentPath.size() - 1];
} }
void MovementAIComponent::SetSpeed(const float value) { void MovementAIComponent::SetMaxSpeed(const float value) {
m_Speed = value; if (value == m_MaxSpeed) return;
m_MaxSpeed = value;
m_Acceleration = value / 5; m_Acceleration = value / 5;
} }
float MovementAIComponent::GetSpeed() const {
return m_Speed;
}
void MovementAIComponent::SetAcceleration(const float value) {
m_Acceleration = value;
}
float MovementAIComponent::GetAcceleration() const {
return m_Acceleration;
}
void MovementAIComponent::SetHaltDistance(const float value) {
m_HaltDistance = value;
}
float MovementAIComponent::GetHaltDistance() const {
return m_HaltDistance;
}
void MovementAIComponent::SetCurrentSpeed(float value) {
m_CurrentSpeed = value;
}
float MovementAIComponent::GetCurrentSpeed() const {
return m_CurrentSpeed;
}
void MovementAIComponent::SetLockRotation(bool value) {
m_LockRotation = value;
}
bool MovementAIComponent::GetLockRotation() const {
return m_LockRotation;
}

View File

@ -1,6 +1,6 @@
/* /*
* Darkflame Universe * Darkflame Universe
* Copyright 2018 * Copyright 2023
*/ */
#ifndef MOVEMENTAICOMPONENT_H #ifndef MOVEMENTAICOMPONENT_H
@ -60,7 +60,6 @@ public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::MOVEMENT_AI; static const eReplicaComponentType ComponentType = eReplicaComponentType::MOVEMENT_AI;
MovementAIComponent(Entity* parentEntity, MovementAIInfo info); MovementAIComponent(Entity* parentEntity, MovementAIInfo info);
~MovementAIComponent() override;
void Update(float deltaTime) override; void Update(float deltaTime) override;
@ -86,61 +85,55 @@ public:
* Sets the max speed at which this entity may run * Sets the max speed at which this entity may run
* @param value the speed value to set * @param value the speed value to set
*/ */
void SetSpeed(float value); void SetMaxSpeed(float value);
/**
* Returns the max speed at which this entity may run
* @return the max speed at which this entity may run
*/
float GetSpeed() const;
/** /**
* Sets how fast the entity will accelerate when not running at full speed * Sets how fast the entity will accelerate when not running at full speed
* @param value the acceleration to set * @param value the acceleration to set
*/ */
void SetAcceleration(float value); void SetAcceleration(float value) { m_Acceleration = value; };
/** /**
* Returns the current speed at which this entity accelerates when not running at full speed * Returns the current speed at which this entity accelerates when not running at full speed
* @return the current speed at which this entity accelerates when not running at full speed * @return the current speed at which this entity accelerates when not running at full speed
*/ */
float GetAcceleration() const; float GetAcceleration() const { return m_Acceleration; };
/** /**
* Sets the halting distance (the distance at which we consider the target to be reached) * Sets the halting distance (the distance at which we consider the target to be reached)
* @param value the halting distance to set * @param value the halting distance to set
*/ */
void SetHaltDistance(float value); void SetHaltDistance(float value) { m_HaltDistance = value; }
/** /**
* Returns the current halting distance (the distance at which we consider the target to be reached) * Returns the current halting distance (the distance at which we consider the target to be reached)
* @return the current halting distance * @return the current halting distance
*/ */
float GetHaltDistance() const; float GetHaltDistance() const { return m_HaltDistance; }
/** /**
* Sets the speed the entity is currently running at * Sets the speed the entity is currently running at
* @param value the speed value to set * @param value the speed value to set
*/ */
void SetCurrentSpeed(float value); void SetCurrentSpeed(float value) { m_CurrentSpeed = value; }
/** /**
* Returns the speed the entity is currently running at * Returns the speed the entity is currently running at
* @return the speed the entity is currently running at * @return the speed the entity is currently running at
*/ */
float GetCurrentSpeed() const; float GetCurrentSpeed() const { return m_CurrentSpeed; }
/** /**
* Locks the rotation of this entity in place, depending on the argument * Locks the rotation of this entity in place, depending on the argument
* @param value if true, the entity will be rotationally locked * @param value if true, the entity will be rotationally locked
*/ */
void SetLockRotation(bool value); void SetLockRotation(bool value) { m_LockRotation = value; }
/** /**
* Returns whether this entity is currently rotationally locked * Returns whether this entity is currently rotationally locked
* @return true if the entity is rotationally locked, false otherwise * @return true if the entity is rotationally locked, false otherwise
*/ */
bool GetLockRotation() const; bool GetLockRotation() const { return m_LockRotation; };
/** /**
* Attempts to update the waypoint index, making the entity move to the next waypoint * Attempts to update the waypoint index, making the entity move to the next waypoint
@ -158,13 +151,7 @@ public:
* Returns the waypoint this entity is supposed to move towards next * Returns the waypoint this entity is supposed to move towards next
* @return the waypoint this entity is supposed to move towards next * @return the waypoint this entity is supposed to move towards next
*/ */
NiPoint3 GetNextWaypoint() const; NiPoint3 GetNextWaypoint() const { return m_NextWaypoint; }
/**
* Returns the current position of this entity
* @return the current position of this entity
*/
NiPoint3 GetCurrentPosition() const;
/** /**
* Returns the approximate current location of the entity, including y coordinates * Returns the approximate current location of the entity, including y coordinates
@ -180,17 +167,11 @@ public:
*/ */
bool Warp(const NiPoint3& point); bool Warp(const NiPoint3& point);
/**
* Returns the time it will take to reach the final waypoint according to the current speed
* @return the time it will take to reach the final waypoint according to the current speed
*/
float GetTimer() const;
/** /**
* Returns if the entity is at its final waypoint * Returns if the entity is at its final waypoint
* @return if the entity is at its final waypoint * @return if the entity is at its final waypoint
*/ */
bool AtFinalWaypoint() const; bool AtFinalWaypoint() const { return m_AtFinalWaypoint; }
/** /**
* Renders the entity stationary * Renders the entity stationary
@ -250,17 +231,12 @@ private:
/** /**
* The max speed this entity may move at * The max speed this entity may move at
*/ */
float m_Speed; float m_MaxSpeed;
/** /**
* The time it will take to reach the next waypoint using the current speed * The time it will take to reach the next waypoint using the current speed
*/ */
float m_Timer; float m_TimeTravelled;
/**
* The total time it will take to reach the waypoint form its starting point
*/
float m_TotalTime;
/** /**
* The path this entity is currently traversing * The path this entity is currently traversing
@ -270,7 +246,7 @@ private:
/** /**
* If the entity has reached it last waypoint * If the entity has reached it last waypoint
*/ */
bool m_Done; bool m_AtFinalWaypoint;
/** /**
* The speed the entity is currently moving at * The speed the entity is currently moving at
@ -287,6 +263,11 @@ private:
*/ */
float m_HaltDistance; float m_HaltDistance;
/**
* The total time it will take to reach the waypoint form its starting point
*/
float m_TimeToTravel;
/** /**
* The base speed this entity has * The base speed this entity has
*/ */
@ -295,7 +276,7 @@ private:
/** /**
* If the AI is currently turned of (e.g. when teleporting to some location) * If the AI is currently turned of (e.g. when teleporting to some location)
*/ */
bool m_Interrupted; bool m_PullingToPoint;
/** /**
* A position that the entity is currently moving towards while being interrupted * A position that the entity is currently moving towards while being interrupted
@ -315,17 +296,12 @@ private:
/** /**
* The path the entity is currently following * The path the entity is currently following
*/ */
std::vector<NiPoint3> m_CurrentPath; std::vector<NiPoint3> m_InterpolatedWaypoints;
/** /**
* Queue of positions to traverse * The path from the current position to the destination.
*/ */
std::stack<NiPoint3> m_Queue; std::stack<NiPoint3> m_CurrentPath;
/**
* Cache of all lots and their respective speeds
*/
static std::map<LOT, float> m_PhysicsSpeedCache;
}; };
#endif // MOVEMENTAICOMPONENT_H #endif // MOVEMENTAICOMPONENT_H

View File

@ -395,7 +395,7 @@ void PetComponent::Update(float deltaTime) {
} }
auto destination = owner->GetPosition(); auto destination = owner->GetPosition();
NiPoint3 position = m_MovementAI->GetCurrentPosition(); NiPoint3 position = m_MovementAI->GetParent()->GetPosition();
float distanceToOwner = Vector3::DistanceSquared(position, destination); float distanceToOwner = Vector3::DistanceSquared(position, destination);
@ -466,7 +466,7 @@ skipTresure:
m_MovementAI->SetHaltDistance(haltDistance); m_MovementAI->SetHaltDistance(haltDistance);
m_MovementAI->SetSpeed(2.5f); m_MovementAI->SetMaxSpeed(2.5f);
m_MovementAI->SetDestination(destination); m_MovementAI->SetDestination(destination);
@ -822,17 +822,17 @@ void PetComponent::Wander() {
destination.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(destination); destination.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(destination);
} }
if (Vector3::DistanceSquared(destination, m_MovementAI->GetCurrentPosition()) < 2 * 2) { if (Vector3::DistanceSquared(destination, m_MovementAI->GetParent()->GetPosition()) < 2 * 2) {
m_MovementAI->Stop(); m_MovementAI->Stop();
return; return;
} }
m_MovementAI->SetSpeed(info.wanderSpeed); m_MovementAI->SetMaxSpeed(info.wanderSpeed);
m_MovementAI->SetDestination(destination); m_MovementAI->SetDestination(destination);
m_Timer += (m_MovementAI->GetCurrentPosition().x - destination.x) / info.wanderSpeed; m_Timer += (m_MovementAI->GetParent()->GetPosition().x - destination.x) / info.wanderSpeed;
} }
void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) { void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) {

View File

@ -136,7 +136,7 @@ void AmShieldGenerator::EnemyEnteredShield(Entity* self, Entity* intruder) {
// TODO: Figure out how todo knockback, I'll stun them for now // TODO: Figure out how todo knockback, I'll stun them for now
if (NiPoint3::DistanceSquared(self->GetPosition(), movementAIComponent->GetCurrentPosition()) < 20 * 20) { if (NiPoint3::DistanceSquared(self->GetPosition(), intruder->GetPosition()) < 20 * 20) {
baseCombatAIComponent->Stun(2.0f); baseCombatAIComponent->Stun(2.0f);
movementAIComponent->SetDestination(baseCombatAIComponent->GetStartPosition()); movementAIComponent->SetDestination(baseCombatAIComponent->GetStartPosition());
} }

View File

@ -194,7 +194,7 @@ void AmShieldGeneratorQuickbuild::EnemyEnteredShield(Entity* self, Entity* intru
// TODO: Figure out how todo knockback, I'll stun them for now // TODO: Figure out how todo knockback, I'll stun them for now
if (NiPoint3::DistanceSquared(self->GetPosition(), movementAIComponent->GetCurrentPosition()) < 20 * 20) { if (NiPoint3::DistanceSquared(self->GetPosition(), intruder->GetPosition()) < 20 * 20) {
baseCombatAIComponent->Stun(2.0f); baseCombatAIComponent->Stun(2.0f);
movementAIComponent->SetDestination(baseCombatAIComponent->GetStartPosition()); movementAIComponent->SetDestination(baseCombatAIComponent->GetStartPosition());
} }

View File

@ -52,12 +52,6 @@ void EnemySpiderSpawner::OnTimerDone(Entity* self, std::string timerName) {
if (newEntity) { if (newEntity) {
Game::entityManager->ConstructEntity(newEntity); Game::entityManager->ConstructEntity(newEntity);
newEntity->GetGroups().push_back("BabySpider"); newEntity->GetGroups().push_back("BabySpider");
/*
auto* movementAi = newEntity->GetComponent<MovementAIComponent>();
movementAi->SetDestination(newEntity->GetPosition());
*/
} }
self->ScheduleKillAfterUpdate(); self->ScheduleKillAfterUpdate();

View File

@ -291,7 +291,7 @@ void SGCannon::OnActivityTimerDone(Entity* self, const std::string& name) {
enemy->AddComponent(eReplicaComponentType::MOVEMENT_AI, movementAI); enemy->AddComponent(eReplicaComponentType::MOVEMENT_AI, movementAI);
movementAI->SetSpeed(toSpawn.initialSpeed); movementAI->SetMaxSpeed(toSpawn.initialSpeed);
movementAI->SetCurrentSpeed(toSpawn.initialSpeed); movementAI->SetCurrentSpeed(toSpawn.initialSpeed);
movementAI->SetHaltDistance(0.0f); movementAI->SetHaltDistance(0.0f);