2021-12-05 17:54:36 +00:00
|
|
|
/*
|
|
|
|
* Darkflame Universe
|
2023-08-04 02:38:04 +00:00
|
|
|
* Copyright 2023
|
2021-12-05 17:54:36 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef MOVEMENTAICOMPONENT_H
|
|
|
|
#define MOVEMENTAICOMPONENT_H
|
|
|
|
|
|
|
|
#include "BitStream.h"
|
|
|
|
#include "Entity.h"
|
|
|
|
#include "GameMessages.h"
|
|
|
|
#include "EntityManager.h"
|
|
|
|
#include "Game.h"
|
2023-10-21 23:31:55 +00:00
|
|
|
#include "Logger.h"
|
2021-12-05 17:54:36 +00:00
|
|
|
#include "Component.h"
|
2023-03-04 07:16:37 +00:00
|
|
|
#include "eReplicaComponentType.h"
|
2021-12-05 17:54:36 +00:00
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
class ControllablePhysicsComponent;
|
|
|
|
class BaseCombatAIComponent;
|
2023-08-09 07:34:39 +00:00
|
|
|
class Path;
|
2021-12-05 17:54:36 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Information that describes the different variables used to make an entity move around
|
|
|
|
*/
|
|
|
|
struct MovementAIInfo {
|
|
|
|
std::string movementType;
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* The radius that the entity can wander in
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
float wanderRadius;
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* The speed at which the entity wanders
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
float wanderSpeed;
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* This is only used for the emotes
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
float wanderChance;
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* The min amount of delay before wandering
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
float wanderDelayMin;
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* The max amount of delay before wandering
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
float wanderDelayMax;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Component that handles the movement settings of an entity. Not to be confused with the BaseCombatAI component that
|
2023-08-08 01:40:06 +00:00
|
|
|
* actually handles attacking and following enemy entities.
|
2021-12-05 17:54:36 +00:00
|
|
|
*/
|
2024-01-24 05:13:23 +00:00
|
|
|
class MovementAIComponent final : public Component {
|
2021-12-05 17:54:36 +00:00
|
|
|
public:
|
2024-01-24 05:13:23 +00:00
|
|
|
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::MOVEMENT_AI;
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
MovementAIComponent(Entity* parentEntity, MovementAIInfo info);
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2022-04-05 12:11:06 +00:00
|
|
|
void Update(float deltaTime) override;
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Returns the basic settings that this entity uses to move around
|
|
|
|
* @return the basic settings that this entity uses to move around
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
const MovementAIInfo& GetInfo() const;
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Set a destination point for the entity to move towards
|
|
|
|
* @param value the destination point to move towards
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
void SetDestination(const NiPoint3& value);
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Returns the current rotation this entity is moving towards
|
|
|
|
* @return the current rotation this entity is moving towards
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
NiPoint3 GetDestination() const;
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Sets the max speed at which this entity may run
|
|
|
|
* @param value the speed value to set
|
|
|
|
*/
|
2023-08-04 02:38:04 +00:00
|
|
|
void SetMaxSpeed(float value);
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Sets how fast the entity will accelerate when not running at full speed
|
|
|
|
* @param value the acceleration to set
|
|
|
|
*/
|
2023-08-04 02:38:04 +00:00
|
|
|
void SetAcceleration(float value) { m_Acceleration = value; };
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2023-08-04 02:38:04 +00:00
|
|
|
float GetAcceleration() const { return m_Acceleration; };
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Sets the halting distance (the distance at which we consider the target to be reached)
|
|
|
|
* @param value the halting distance to set
|
|
|
|
*/
|
2023-08-04 02:38:04 +00:00
|
|
|
void SetHaltDistance(float value) { m_HaltDistance = value; }
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Returns the current halting distance (the distance at which we consider the target to be reached)
|
|
|
|
* @return the current halting distance
|
|
|
|
*/
|
2023-08-04 02:38:04 +00:00
|
|
|
float GetHaltDistance() const { return m_HaltDistance; }
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Sets the speed the entity is currently running at
|
|
|
|
* @param value the speed value to set
|
|
|
|
*/
|
2023-08-04 02:38:04 +00:00
|
|
|
void SetCurrentSpeed(float value) { m_CurrentSpeed = value; }
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Returns the speed the entity is currently running at
|
|
|
|
* @return the speed the entity is currently running at
|
|
|
|
*/
|
2023-08-04 02:38:04 +00:00
|
|
|
float GetCurrentSpeed() const { return m_CurrentSpeed; }
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Locks the rotation of this entity in place, depending on the argument
|
|
|
|
* @param value if true, the entity will be rotationally locked
|
|
|
|
*/
|
2023-08-04 02:38:04 +00:00
|
|
|
void SetLockRotation(bool value) { m_LockRotation = value; }
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Returns whether this entity is currently rotationally locked
|
|
|
|
* @return true if the entity is rotationally locked, false otherwise
|
|
|
|
*/
|
2023-08-04 02:38:04 +00:00
|
|
|
bool GetLockRotation() const { return m_LockRotation; };
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Attempts to update the waypoint index, making the entity move to the next waypoint
|
|
|
|
* @return true if the waypoint could be increased, false if the entity is at the last waypoint already
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
bool AdvanceWaypointIndex();
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Returns the waypoint the entity is currently moving towards
|
|
|
|
* @return the waypoint the entity is currently moving towards
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
NiPoint3 GetCurrentWaypoint() const;
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Returns the waypoint this entity is supposed to move towards next
|
|
|
|
* @return the waypoint this entity is supposed to move towards next
|
|
|
|
*/
|
2023-08-04 02:38:04 +00:00
|
|
|
NiPoint3 GetNextWaypoint() const { return m_NextWaypoint; }
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2023-08-21 19:33:13 +00:00
|
|
|
NiPoint3 GetNextPathWaypoint() const {
|
|
|
|
if (m_CurrentPath.empty()) return GetNextWaypoint();
|
|
|
|
if (m_IsInReverse) {
|
|
|
|
return m_CurrentPathWaypointIndex - 1 < 0 ?
|
|
|
|
m_CurrentPath.front() :
|
|
|
|
m_CurrentPath.at(m_CurrentPathWaypointIndex - 1);
|
|
|
|
} else {
|
|
|
|
return m_CurrentPathWaypointIndex + 1 >= m_CurrentPath.size() ?
|
|
|
|
m_CurrentPath.back() :
|
|
|
|
m_CurrentPath.at(m_CurrentPathWaypointIndex + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Returns the approximate current location of the entity, including y coordinates
|
|
|
|
* @return the approximate current location of the entity
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
NiPoint3 ApproximateLocation() const;
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Teleports this entity to a position. If the distance between the provided point and the y it should have
|
|
|
|
* according to map data, this will not succeed (to avoid teleporting entities into the sky).
|
|
|
|
* @param point the point to teleport to
|
|
|
|
* @return true if the warp was successful, false otherwise
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
bool Warp(const NiPoint3& point);
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Returns if the entity is at its final waypoint
|
|
|
|
* @return if the entity is at its final waypoint
|
|
|
|
*/
|
2023-08-04 02:38:04 +00:00
|
|
|
bool AtFinalWaypoint() const { return m_AtFinalWaypoint; }
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2023-08-07 07:44:57 +00:00
|
|
|
bool IsPaused() const { return m_IsPaused; }
|
|
|
|
|
2023-08-07 08:46:03 +00:00
|
|
|
/**
|
|
|
|
* Pauses the current pathing of this entity. The current path waypoint will be saved for resuming later.
|
|
|
|
*/
|
2023-08-07 07:44:57 +00:00
|
|
|
void Pause();
|
|
|
|
|
2023-08-07 08:46:03 +00:00
|
|
|
/**
|
|
|
|
* Resumes pathing from the current position to the destination that was set
|
|
|
|
* when the entity was paused.
|
|
|
|
*/
|
2023-08-07 07:44:57 +00:00
|
|
|
void Resume();
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Renders the entity stationary
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
void Stop();
|
|
|
|
|
2023-08-07 08:46:03 +00:00
|
|
|
void ReversePath();
|
|
|
|
|
2023-08-14 14:31:10 +00:00
|
|
|
void HandleWaypointArrived(uint32_t commandIndex);
|
2023-08-12 05:40:48 +00:00
|
|
|
|
2023-08-08 01:40:06 +00:00
|
|
|
void SetupPath(const std::string& pathname);
|
2023-08-07 09:03:09 +00:00
|
|
|
|
2023-08-21 19:33:13 +00:00
|
|
|
float GetCurrentPathWaypointSpeed() const;
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Stops the current movement and moves the entity to a certain point. Will continue until it's close enough,
|
|
|
|
* after which its AI is enabled again.
|
|
|
|
* @param point the point to move towards
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
void PullToPoint(const NiPoint3& point);
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Sets a path to follow for the AI
|
|
|
|
* @param path the path to follow
|
|
|
|
*/
|
2024-02-25 07:29:41 +00:00
|
|
|
void SetPath(const std::vector<NiPoint3>& path, bool startsInReverse = false);
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2023-08-07 04:15:06 +00:00
|
|
|
// Advance the path waypoint index and return if there is a next waypoint
|
2023-08-07 03:25:22 +00:00
|
|
|
bool AdvancePathWaypointIndex();
|
|
|
|
|
2023-08-07 06:40:30 +00:00
|
|
|
const NiPoint3& GetCurrentPathWaypoint() const;
|
2023-08-07 03:25:22 +00:00
|
|
|
|
2023-08-15 03:28:27 +00:00
|
|
|
void SetPathStartingWaypointIndex(int32_t value) { m_StartingWaypointIndex = value; }
|
|
|
|
|
|
|
|
bool HasAttachedPathStart() const { return m_StartingWaypointIndex != -1; }
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Returns the base speed from the DB for a given LOT
|
|
|
|
* @param lot the lot to check for
|
|
|
|
* @return the base speed of the lot
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
static float GetBaseSpeed(LOT lot);
|
|
|
|
|
2023-08-23 19:53:02 +00:00
|
|
|
const bool GetIsInReverse(){ return m_IsInReverse; };
|
|
|
|
|
2023-08-12 07:40:18 +00:00
|
|
|
private:
|
2023-08-14 14:31:10 +00:00
|
|
|
float HandleWaypointCommandGroupEmote(const std::string& data);
|
|
|
|
void HandleWaypointCommandSetVariable(const std::string& data);
|
|
|
|
void HandleWaypointCommandCastSkill(const std::string& data);
|
|
|
|
void HandleWaypointCommandEquipInventory(const std::string& data);
|
|
|
|
void HandleWaypointCommandUnequipInventory(const std::string& data);
|
|
|
|
float HandleWaypointCommandDelay(const std::string& data);
|
|
|
|
void HandleWaypointCommandTeleport(const std::string& data);
|
|
|
|
void HandleWaypointCommandPathSpeed(const std::string& data);
|
|
|
|
void HandleWaypointCommandRemoveNPC(const std::string& data);
|
|
|
|
void HandleWaypointCommandChangeWaypoint(const std::string& data);
|
|
|
|
void HandleWaypointCommandSpawnObject(const std::string& data);
|
2023-08-12 05:40:48 +00:00
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Sets the current position of the entity
|
|
|
|
* @param value the position to set
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
void SetPosition(const NiPoint3& value);
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Sets the current rotation of the entity
|
|
|
|
* @param value the rotation to set
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
void SetRotation(const NiQuaternion& value);
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Sets the current velocity of the entityes
|
|
|
|
* @param value the velocity to set
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
void SetVelocity(const NiPoint3& value);
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Base information regarding the movement information for this entity
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
MovementAIInfo m_Info;
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* The point this entity is moving towards
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
NiPoint3 m_NextWaypoint;
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* The max speed this entity may move at
|
|
|
|
*/
|
2023-08-04 02:38:04 +00:00
|
|
|
float m_MaxSpeed;
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* The time it will take to reach the next waypoint using the current speed
|
|
|
|
*/
|
2023-08-04 02:38:04 +00:00
|
|
|
float m_TimeTravelled;
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* The path this entity is currently traversing
|
|
|
|
*/
|
2023-08-09 07:34:39 +00:00
|
|
|
int32_t m_PathIndex;
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* If the entity has reached it last waypoint
|
|
|
|
*/
|
2023-08-04 02:38:04 +00:00
|
|
|
bool m_AtFinalWaypoint;
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* The speed the entity is currently moving at
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
float m_CurrentSpeed;
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* The acceleration this entity has when not moving at its top speed yet
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
float m_Acceleration;
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* The distance between the current position and the target waypoint to consider it reached (to not ghost into it).
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
float m_HaltDistance;
|
|
|
|
|
2023-08-04 02:38:04 +00:00
|
|
|
/**
|
|
|
|
* The total time it will take to reach the waypoint form its starting point
|
|
|
|
*/
|
|
|
|
float m_TimeToTravel;
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* The base speed this entity has
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
float m_BaseSpeed;
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* If the AI is currently turned of (e.g. when teleporting to some location)
|
|
|
|
*/
|
2023-08-04 02:38:04 +00:00
|
|
|
bool m_PullingToPoint;
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* A position that the entity is currently moving towards while being interrupted
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
NiPoint3 m_PullPoint;
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* If the entity is currently rotationally locked
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
bool m_LockRotation;
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Optional direct link to the combat AI component of the parent entity
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
BaseCombatAIComponent* m_BaseCombatAI = nullptr;
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* The path the entity is currently following
|
|
|
|
*/
|
2023-08-04 02:38:04 +00:00
|
|
|
std::vector<NiPoint3> m_InterpolatedWaypoints;
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
2023-08-04 02:38:04 +00:00
|
|
|
* The path from the current position to the destination.
|
2022-07-28 13:39:57 +00:00
|
|
|
*/
|
2023-08-07 03:25:22 +00:00
|
|
|
std::vector<NiPoint3> m_CurrentPath;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The index of the current waypoint in the path
|
|
|
|
*/
|
2023-08-07 06:40:30 +00:00
|
|
|
int32_t m_CurrentPathWaypointIndex;
|
2023-08-07 04:15:06 +00:00
|
|
|
|
|
|
|
/**
|
2023-08-12 05:40:48 +00:00
|
|
|
* The index of the next waypoint in the path
|
2023-08-07 04:15:06 +00:00
|
|
|
*/
|
2023-08-07 06:40:30 +00:00
|
|
|
int32_t m_NextPathWaypointIndex;
|
2023-08-07 04:15:06 +00:00
|
|
|
|
2023-08-07 06:40:30 +00:00
|
|
|
/**
|
2023-08-12 05:40:48 +00:00
|
|
|
* Whether or not the path is being read in reverse
|
2023-08-07 06:40:30 +00:00
|
|
|
*/
|
2023-08-07 04:15:06 +00:00
|
|
|
bool m_IsInReverse;
|
2023-08-07 07:44:57 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Whether or not the current movement via pathing is paused.
|
|
|
|
*/
|
|
|
|
bool m_IsPaused;
|
2023-08-09 07:34:39 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The optional path this component will follow.
|
|
|
|
*/
|
|
|
|
const Path* m_Path = nullptr;
|
2023-08-15 03:28:27 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The starting index for the provided path
|
|
|
|
*/
|
|
|
|
int32_t m_StartingWaypointIndex = -1;
|
2021-12-05 17:54:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // MOVEMENTAICOMPONENT_H
|