mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-08-09 20:24:16 +00:00
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:
@@ -10,85 +10,77 @@
|
||||
#include "EntityManager.h"
|
||||
#include "SimplePhysicsComponent.h"
|
||||
#include "CDClientManager.h"
|
||||
#include "Game.h"
|
||||
#include "dZoneManager.h"
|
||||
|
||||
#include "CDComponentsRegistryTable.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) {
|
||||
m_Info = std::move(info);
|
||||
m_Done = true;
|
||||
m_Info = info;
|
||||
m_AtFinalWaypoint = true;
|
||||
|
||||
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:
|
||||
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.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_NextWaypoint = GetCurrentPosition();
|
||||
m_NextWaypoint = m_Parent->GetPosition();
|
||||
m_Acceleration = 0.4f;
|
||||
m_Interrupted = false;
|
||||
m_PullPoint = {};
|
||||
m_PullingToPoint = false;
|
||||
m_PullPoint = NiPoint3::ZERO;
|
||||
m_HaltDistance = 0;
|
||||
m_Timer = 0;
|
||||
m_TimeToTravel = 0;
|
||||
m_TimeTravelled = 0;
|
||||
m_CurrentSpeed = 0;
|
||||
m_Speed = 0;
|
||||
m_TotalTime = 0;
|
||||
m_MaxSpeed = 0;
|
||||
m_LockRotation = false;
|
||||
}
|
||||
|
||||
MovementAIComponent::~MovementAIComponent() = default;
|
||||
|
||||
void MovementAIComponent::Update(const float deltaTime) {
|
||||
if (m_Interrupted) {
|
||||
if (m_PullingToPoint) {
|
||||
const auto source = GetCurrentWaypoint();
|
||||
|
||||
const auto speed = deltaTime * 2.5f;
|
||||
|
||||
NiPoint3 velocity;
|
||||
|
||||
velocity.x = (m_PullPoint.x - source.x) * speed;
|
||||
velocity.y = (m_PullPoint.y - source.y) * speed;
|
||||
velocity.z = (m_PullPoint.z - source.z) * speed;
|
||||
NiPoint3 velocity = (m_PullPoint - source) * speed;
|
||||
|
||||
SetPosition(source + velocity);
|
||||
|
||||
if (Vector3::DistanceSquared(GetCurrentPosition(), m_PullPoint) < 2 * 2) {
|
||||
m_Interrupted = false;
|
||||
if (Vector3::DistanceSquared(m_Parent->GetPosition(), m_PullPoint) < std::pow(2, 2)) {
|
||||
m_PullingToPoint = false;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (AtFinalWaypoint()) // Are we done?
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Are we done?
|
||||
if (AtFinalWaypoint()) return;
|
||||
|
||||
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();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_Timer > 0) {
|
||||
m_Timer -= deltaTime;
|
||||
|
||||
if (m_Timer > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_Timer = 0;
|
||||
}
|
||||
m_TimeTravelled += deltaTime;
|
||||
if (m_TimeTravelled < m_TimeToTravel) return;
|
||||
m_TimeTravelled = 0.0f;
|
||||
|
||||
const auto source = GetCurrentWaypoint();
|
||||
|
||||
@@ -101,48 +93,44 @@ void MovementAIComponent::Update(const float deltaTime) {
|
||||
m_NextWaypoint = GetCurrentWaypoint();
|
||||
|
||||
if (m_NextWaypoint == source) {
|
||||
m_Timer = 0;
|
||||
m_TimeToTravel = 0.0f;
|
||||
|
||||
goto nextAction;
|
||||
}
|
||||
|
||||
if (m_CurrentSpeed < m_Speed) {
|
||||
if (m_CurrentSpeed < m_MaxSpeed) {
|
||||
m_CurrentSpeed += m_Acceleration;
|
||||
}
|
||||
|
||||
if (m_CurrentSpeed > m_Speed) {
|
||||
m_CurrentSpeed = m_Speed;
|
||||
if (m_CurrentSpeed > m_MaxSpeed) {
|
||||
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;
|
||||
|
||||
// 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) {
|
||||
velocity.x = (delta.x / length) * speed;
|
||||
velocity.y = (delta.y / length) * speed;
|
||||
velocity.z = (delta.z / length) * speed;
|
||||
velocity = (delta / length) * 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));
|
||||
} else {
|
||||
// Check if there are more waypoints in the queue, if so set our next destination to the next waypoint
|
||||
if (!m_Queue.empty()) {
|
||||
SetDestination(m_Queue.top());
|
||||
|
||||
m_Queue.pop();
|
||||
} else {
|
||||
// We have reached our final waypoint
|
||||
if (m_CurrentPath.empty()) {
|
||||
Stop();
|
||||
|
||||
return;
|
||||
}
|
||||
SetDestination(m_CurrentPath.top());
|
||||
|
||||
m_CurrentPath.pop();
|
||||
}
|
||||
|
||||
nextAction:
|
||||
@@ -157,7 +145,7 @@ const MovementAIInfo& MovementAIComponent::GetInfo() const {
|
||||
}
|
||||
|
||||
bool MovementAIComponent::AdvanceWaypointIndex() {
|
||||
if (m_PathIndex >= m_CurrentPath.size()) {
|
||||
if (m_PathIndex >= m_InterpolatedWaypoints.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -167,37 +155,19 @@ bool MovementAIComponent::AdvanceWaypointIndex() {
|
||||
}
|
||||
|
||||
NiPoint3 MovementAIComponent::GetCurrentWaypoint() const {
|
||||
if (m_PathIndex >= m_CurrentPath.size()) {
|
||||
return GetCurrentPosition();
|
||||
}
|
||||
|
||||
return m_CurrentPath[m_PathIndex];
|
||||
}
|
||||
|
||||
NiPoint3 MovementAIComponent::GetNextWaypoint() const {
|
||||
return m_NextWaypoint;
|
||||
}
|
||||
|
||||
NiPoint3 MovementAIComponent::GetCurrentPosition() const {
|
||||
return m_Parent->GetPosition();
|
||||
return m_PathIndex >= m_InterpolatedWaypoints.size() ? m_Parent->GetPosition() : m_InterpolatedWaypoints[m_PathIndex];
|
||||
}
|
||||
|
||||
NiPoint3 MovementAIComponent::ApproximateLocation() const {
|
||||
auto source = GetCurrentPosition();
|
||||
auto source = m_Parent->GetPosition();
|
||||
|
||||
if (m_Done) {
|
||||
return source;
|
||||
}
|
||||
if (AtFinalWaypoint()) return source;
|
||||
|
||||
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 y = source.y + factor * (destination.y - source.y);
|
||||
auto z = source.z + factor * (destination.z - source.z);
|
||||
|
||||
NiPoint3 approximation = NiPoint3(x, y, z);
|
||||
auto approximation = source + ((destination - source) * percentageToWaypoint);
|
||||
|
||||
if (dpWorld::Instance().IsLoaded()) {
|
||||
approximation.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(approximation);
|
||||
@@ -226,28 +196,20 @@ bool MovementAIComponent::Warp(const NiPoint3& point) {
|
||||
return true;
|
||||
}
|
||||
|
||||
float MovementAIComponent::GetTimer() const {
|
||||
return m_Timer;
|
||||
}
|
||||
|
||||
bool MovementAIComponent::AtFinalWaypoint() const {
|
||||
return m_Done;
|
||||
}
|
||||
|
||||
void MovementAIComponent::Stop() {
|
||||
if (m_Done) {
|
||||
return;
|
||||
}
|
||||
if (AtFinalWaypoint()) return;
|
||||
|
||||
SetPosition(ApproximateLocation());
|
||||
|
||||
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;
|
||||
|
||||
@@ -259,20 +221,17 @@ void MovementAIComponent::Stop() {
|
||||
void MovementAIComponent::PullToPoint(const NiPoint3& point) {
|
||||
Stop();
|
||||
|
||||
m_Interrupted = true;
|
||||
m_PullingToPoint = true;
|
||||
m_PullPoint = point;
|
||||
}
|
||||
|
||||
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) {
|
||||
m_Queue.push(point);
|
||||
}
|
||||
|
||||
SetDestination(m_Queue.top());
|
||||
|
||||
m_Queue.pop();
|
||||
SetDestination(path.front());
|
||||
}
|
||||
|
||||
float MovementAIComponent::GetBaseSpeed(LOT lot) {
|
||||
@@ -291,26 +250,14 @@ float MovementAIComponent::GetBaseSpeed(LOT lot) {
|
||||
|
||||
componentID = componentRegistryTable->GetByIDAndType(lot, eReplicaComponentType::CONTROLLABLE_PHYSICS, -1);
|
||||
|
||||
if (componentID != -1) {
|
||||
physicsComponent = physicsComponentTable->GetByID(componentID);
|
||||
|
||||
goto foundComponent;
|
||||
if (componentID == -1) {
|
||||
componentID = componentRegistryTable->GetByIDAndType(lot, eReplicaComponentType::SIMPLE_PHYSICS, -1);
|
||||
}
|
||||
|
||||
componentID = componentRegistryTable->GetByIDAndType(lot, eReplicaComponentType::SIMPLE_PHYSICS, -1);
|
||||
|
||||
if (componentID != -1) {
|
||||
physicsComponent = physicsComponentTable->GetByID(componentID);
|
||||
|
||||
goto foundComponent;
|
||||
}
|
||||
|
||||
foundComponent:
|
||||
physicsComponent = physicsComponentTable->GetByID(componentID);
|
||||
|
||||
// Client defaults speed to 10 and if the speed is also null in the table, it defaults to 10.
|
||||
float speed = 10.0f;
|
||||
|
||||
if (physicsComponent) speed = physicsComponent->speed;
|
||||
float speed = physicsComponent != nullptr ? physicsComponent->speed : 10.0f;
|
||||
|
||||
float delta = fabs(speed) - 1.0f;
|
||||
|
||||
@@ -322,39 +269,11 @@ foundComponent:
|
||||
}
|
||||
|
||||
void MovementAIComponent::SetPosition(const NiPoint3& value) {
|
||||
auto* controllablePhysicsComponent = m_Parent->GetComponent<ControllablePhysicsComponent>();
|
||||
|
||||
if (controllablePhysicsComponent != nullptr) {
|
||||
controllablePhysicsComponent->SetPosition(value);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
auto* simplePhysicsComponent = m_Parent->GetComponent<SimplePhysicsComponent>();
|
||||
|
||||
if (simplePhysicsComponent != nullptr) {
|
||||
simplePhysicsComponent->SetPosition(value);
|
||||
}
|
||||
m_Parent->SetPosition(value);
|
||||
}
|
||||
|
||||
void MovementAIComponent::SetRotation(const NiQuaternion& value) {
|
||||
if (m_LockRotation) {
|
||||
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);
|
||||
}
|
||||
if (!m_LockRotation) m_Parent->SetRotation(value);
|
||||
}
|
||||
|
||||
void MovementAIComponent::SetVelocity(const NiPoint3& value) {
|
||||
@@ -373,15 +292,8 @@ void MovementAIComponent::SetVelocity(const NiPoint3& value) {
|
||||
}
|
||||
}
|
||||
|
||||
void MovementAIComponent::SetDestination(const NiPoint3& value) {
|
||||
if (m_Interrupted) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*if (Vector3::DistanceSquared(value, GetDestination()) < 2 * 2)
|
||||
{
|
||||
return;
|
||||
}*/
|
||||
void MovementAIComponent::SetDestination(const NiPoint3& destination) {
|
||||
if (m_PullingToPoint) return;
|
||||
|
||||
const auto location = ApproximateLocation();
|
||||
|
||||
@@ -390,97 +302,53 @@ void MovementAIComponent::SetDestination(const NiPoint3& value) {
|
||||
}
|
||||
|
||||
std::vector<NiPoint3> computedPath;
|
||||
|
||||
if (dpWorld::Instance().IsLoaded()) {
|
||||
computedPath = dpWorld::Instance().GetNavMesh()->GetPath(GetCurrentPosition(), value, m_Info.wanderSpeed);
|
||||
} else {
|
||||
computedPath = dpWorld::Instance().GetNavMesh()->GetPath(m_Parent->GetPosition(), destination, m_Info.wanderSpeed);
|
||||
}
|
||||
|
||||
// Somehow failed
|
||||
if (computedPath.empty()) {
|
||||
// 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++) {
|
||||
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
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_CurrentPath.clear();
|
||||
|
||||
m_CurrentPath.push_back(location);
|
||||
m_InterpolatedWaypoints.clear();
|
||||
|
||||
// Simply path
|
||||
for (auto point : computedPath) {
|
||||
for (auto& point : computedPath) {
|
||||
if (dpWorld::Instance().IsLoaded()) {
|
||||
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_TotalTime = m_Timer = 0;
|
||||
m_TimeTravelled = 0;
|
||||
m_TimeToTravel = 0;
|
||||
|
||||
m_Done = false;
|
||||
m_AtFinalWaypoint = false;
|
||||
}
|
||||
|
||||
NiPoint3 MovementAIComponent::GetDestination() const {
|
||||
if (m_CurrentPath.empty()) {
|
||||
return GetCurrentPosition();
|
||||
}
|
||||
|
||||
return m_CurrentPath[m_CurrentPath.size() - 1];
|
||||
return m_InterpolatedWaypoints.empty() ? m_Parent->GetPosition() : m_InterpolatedWaypoints.back();
|
||||
}
|
||||
|
||||
void MovementAIComponent::SetSpeed(const float value) {
|
||||
m_Speed = value;
|
||||
void MovementAIComponent::SetMaxSpeed(const float value) {
|
||||
if (value == m_MaxSpeed) return;
|
||||
m_MaxSpeed = value;
|
||||
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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user