Compare commits

..

2 Commits

Author SHA1 Message Date
8b0f374ab4 this does nothing 2023-01-07 03:21:42 -06:00
bb20aa7f86 wip 2023-01-07 01:15:27 -06:00
5 changed files with 63 additions and 215 deletions

View File

@@ -693,8 +693,7 @@ void Entity::Initialize() {
}
std::string pathName = GetVarAsString(u"attached_path");
Path* path = nullptr;
if (!pathName.empty()) path = const_cast<Path*>(dZoneManager::Instance()->GetZone()->GetPath(pathName));
const Path* path = dZoneManager::Instance()->GetZone()->GetPath(pathName);
//Check to see if we have an attached path and add the appropiate component to handle it:
if (path){
@@ -703,16 +702,14 @@ void Entity::Initialize() {
MovingPlatformComponent* plat = new MovingPlatformComponent(this, pathName);
m_Components.insert(std::make_pair(COMPONENT_TYPE_MOVING_PLATFORM, plat));
// else if we are a movement path
} else if (path->pathType == PathType::Movement) {
} /*else if (path->pathType == PathType::Movement) {
auto movementAIcomp = GetComponent<MovementAIComponent>();
if (movementAIcomp){
movementAIcomp->SetMovementPath(path);
// TODO: set path in existing movementAIComp
} else {
movementAIcomp = new MovementAIComponent(this, MovementAIInfo());
movementAIcomp->SetMovementPath(path);
m_Components.insert(std::make_pair(COMPONENT_TYPE_MOVEMENT_AI, movementAIcomp));
// TODO: create movementAIcomp and set path
}
}
}*/
}
int proximityMonitorID = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_PROXIMITY_MONITOR);

View File

@@ -1,6 +1,7 @@
#include "JetPackBehavior.h"
#include "BehaviorBranchContext.h"
#include "ControllablePhysicsComponent.h"
#include "GameMessages.h"
#include "Character.h"
@@ -12,11 +13,11 @@ void JetPackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_st
if (entity->IsPlayer()) {
auto* character = entity->GetCharacter();
if (character) {
character->SetIsFlying(true);
}
if (character) character->SetIsFlying(true);
}
auto controllablePhysicsComponent = entity->GetComponent<ControllablePhysicsComponent>();
if (controllablePhysicsComponent) controllablePhysicsComponent->SetJetpackFlying(true);
}
void JetPackBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) {
@@ -26,11 +27,11 @@ void JetPackBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext bra
if (entity->IsPlayer()) {
auto* character = entity->GetCharacter();
if (character) {
character->SetIsFlying(false);
}
if (character) character->SetIsFlying(false);
}
auto controllablePhysicsComponent = entity->GetComponent<ControllablePhysicsComponent>();
if (controllablePhysicsComponent) controllablePhysicsComponent->SetJetpackFlying(false);
}
void JetPackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) {

View File

@@ -127,12 +127,6 @@ public:
*/
void SetDirtyAngularVelocity(bool val);
/**
* Sets whether or not the entity is currently wearing a jetpack
* @param val whether or not the entity is currently wearing a jetpack
*/
void SetInJetpackMode(bool val) { m_InJetpackMode = val; }
/**
* Returns whether or not the entity is currently wearing a jetpack
* @return whether or not the entity is currently wearing a jetpack
@@ -143,7 +137,7 @@ public:
* Sets whether or not the entity is currently flying a jetpack
* @param val whether or not the entity is currently flying a jetpack
*/
void SetJetpackFlying(bool val) { m_JetpackFlying = val; }
void SetJetpackFlying(bool val) { m_JetpackFlying = val; m_DirtyEquippedItemInfo = true;}
/**
* Returns whether or not an entity is currently flying a jetpack

View File

@@ -9,7 +9,6 @@
#include "dpWorld.h"
#include "EntityManager.h"
#include "SimplePhysicsComponent.h"
#include "dZoneManager.h"
#include "CDClientManager.h"
std::map<LOT, float> MovementAIComponent::m_PhysicsSpeedCache = {};
@@ -17,9 +16,9 @@ std::map<LOT, float> MovementAIComponent::m_PhysicsSpeedCache = {};
MovementAIComponent::MovementAIComponent(Entity* parent, MovementAIInfo info) : Component(parent) {
m_Info = std::move(info);
m_Done = true;
m_IsPaused = false;
m_BaseCombatAI = nullptr;
m_BaseCombatAI = reinterpret_cast<BaseCombatAIComponent*>(m_Parent->GetComponent(COMPONENT_TYPE_BASE_COMBAT_AI));
//Try and fix the insane values:
@@ -37,21 +36,13 @@ MovementAIComponent::MovementAIComponent(Entity* parent, MovementAIInfo info) :
m_Timer = 0;
m_CurrentSpeed = 0;
m_Speed = 0;
m_TotalTime = 0;
m_LockRotation = false;
m_MovementPath = nullptr;
m_isReverse = false;
}
MovementAIComponent::~MovementAIComponent() = default;
void MovementAIComponent::Update(const float deltaTime) {
if (m_IsPaused) return;
if (m_Interrupted) {
const auto source = GetCurrentWaypoint();
@@ -72,64 +63,71 @@ void MovementAIComponent::Update(const float deltaTime) {
return;
}
if (AtFinalWaypoint()) return; // Are we done?
if (AtFinalWaypoint()) // Are we done?
{
return;
}
if (m_HaltDistance > 0) {
if (Vector3::DistanceSquared(ApproximateLocation(), GetDestination()) < m_HaltDistance * m_HaltDistance) { // Prevent us from hugging the target
if (Vector3::DistanceSquared(ApproximateLocation(), GetDestination()) < m_HaltDistance * m_HaltDistance) // Prevent us from hugging the target
{
Stop();
return;
}
}
// Game::logger->Log("MovementAIComponent", "timer %f", m_Timer);
if (m_Timer > 0) {
m_Timer -= deltaTime;
if (m_Timer > 0) return;
if (m_Timer > 0) {
return;
}
m_Timer = 0;
}
const auto source = GetCurrentWaypoint();
// We've arrived at a waypoint, do the things if we need to
SetPosition(source);
NiPoint3 velocity = NiPoint3::ZERO;
if (AdvanceWaypointIndex()) { // Do we have another waypoint to seek?
if (AdvanceWaypointIndex()) // Do we have another waypoint to seek?
{
m_NextWaypoint = GetCurrentWaypoint();
if (m_NextWaypoint == source) {
m_Timer = 0;
} else {
if (m_CurrentSpeed < m_Speed) {
m_CurrentSpeed += m_Acceleration;
}
if (m_CurrentSpeed > m_Speed) {
m_CurrentSpeed = m_Speed;
}
const auto speed = m_BaseSpeed;
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);
if (length > 0) {
velocity.x = (delta.x / 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
Game::logger->Log("MovementAIComponent", "length %f speed %f", length, speed);
m_TotalTime = m_Timer = length / speed;
SetRotation(NiQuaternion::LookAt(source, m_NextWaypoint));
goto nextAction;
}
if (m_CurrentSpeed < m_Speed) {
m_CurrentSpeed += m_Acceleration;
}
if (m_CurrentSpeed > m_Speed) {
m_CurrentSpeed = m_Speed;
}
const auto speed = m_CurrentSpeed * m_BaseSpeed;
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);
if (length > 0) {
velocity.x = (delta.x / 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
m_TotalTime = m_Timer = 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()) {
@@ -144,6 +142,8 @@ void MovementAIComponent::Update(const float deltaTime) {
}
}
nextAction:
SetVelocity(velocity);
EntityManager::Instance()->SerializeEntity(m_Parent);
@@ -154,106 +154,21 @@ const MovementAIInfo& MovementAIComponent::GetInfo() const {
}
bool MovementAIComponent::AdvanceWaypointIndex() {
Game::logger->Log("MovementAIComponent", "reached waypoint check");
if (m_PathIndex >= m_CurrentPath.size()) {
if (m_MovementPath){
if (m_MovementPath->pathBehavior == PathBehavior::Loop){
m_PathIndex = 0;
return true;
} else {
if (m_MovementPath->pathBehavior == PathBehavior::Bounce){
m_isReverse = true;
m_PathIndex--;
return true;
}
}
}
return false;
} else if (m_PathIndex <= 0) {
m_PathIndex = 0;
m_isReverse = false;
}
if (m_isReverse) m_PathIndex--;
else m_PathIndex++;
m_PathIndex++;
return true;
}
NiPoint3 MovementAIComponent::GetCurrentWaypoint() const {
Game::logger->Log("MovementAIComponent", "get current waypoint");
if (m_PathIndex >= m_CurrentPath.size()) {
return GetCurrentPosition();
}
auto source = GetCurrentPosition();
auto destination = m_CurrentPath.at(m_PathIndex);
if (dpWorld::Instance().IsLoaded()) {
destination.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(destination);
}
if (abs(destination.y - source.y) > 3) destination.y = source.y;
return destination;
}
void MovementAIComponent::ArrivedAtPathWaypoint(){
if(!m_MovementPath) return;
if (m_PathIndex >= m_CurrentPath.size()) return;
// TODO: Call scripts here
PathWaypoint waypoint = m_MovementPath->pathWaypoints.at(m_PathIndex);
if (waypoint.config.size() > 0) {
for (LDFBaseData* action : waypoint.config) {
if (action) {
// delay: has time as float
if (action->GetKey() == u"delay"){
m_Timer += std::stof(action->GetValueAsString());
SetVelocity(NiPoint3::ZERO);
EntityManager::Instance()->SerializeEntity(m_Parent);
// emote: has name of animation to play
} else if (action->GetKey() == u"emote"){
GameMessages::SendPlayAnimation(m_Parent, GeneralUtils::UTF8ToUTF16(action->GetValueAsString()));
// TODO Get proper animation time and add to wait
m_Timer += 1;
SetVelocity(NiPoint3::ZERO);
EntityManager::Instance()->SerializeEntity(m_Parent);
// pathspeed: has pathing speed as a float
} else if (action->GetKey() == u"pathspeed") {
m_BaseSpeed = std::stof(action->GetValueAsString());
// changeWP: <path to change to>,<waypoint to use> the command and waypoint are optional
} else if (action->GetKey() == u"changeWP") {
// use an intermediate value since it can be one or two things
auto intermed = action->GetValueAsString();
std::string path_string = "";
// sometimes there's a path and what waypoint to start, which are comma separated
if (intermed.find(",") != std::string::npos){
auto datas = GeneralUtils::SplitString(intermed, ',');
path_string = datas[0];
m_PathIndex = stoi(datas[1]) - 1;
} else {
path_string = intermed;
m_PathIndex = 0;
}
if (path_string != "") {
SetMovementPath(const_cast<Path*>(dZoneManager::Instance()->GetZone()->GetPath(path_string)));
} else m_MovementPath = nullptr;
} else {
// We don't recognize the action, let a dev know
Game::logger->LogDebug("ControllablePhysicsComponent", "Unhandled action %s", GeneralUtils::UTF16ToWTF8(action->GetKey()).c_str());
}
}
}
}
return m_CurrentPath[m_PathIndex];
}
NiPoint3 MovementAIComponent::GetNextWaypoint() const {
@@ -284,7 +199,6 @@ NiPoint3 MovementAIComponent::ApproximateLocation() const {
if (dpWorld::Instance().IsLoaded()) {
approximation.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(approximation);
}
if (abs(destination.y - source.y) > 3) destination.y = source.y;
return approximation;
}
@@ -314,12 +228,10 @@ float MovementAIComponent::GetTimer() const {
}
bool MovementAIComponent::AtFinalWaypoint() const {
return m_Done;
}
void MovementAIComponent::Stop() {
Game::logger->Log("MovementAIComponent", "stopped");
if (m_Done) {
return;
}
@@ -360,22 +272,6 @@ void MovementAIComponent::SetPath(std::vector<NiPoint3> path) {
m_Queue.pop();
}
void MovementAIComponent::SetMovementPath(Path* movementPath){
Game::logger->Log("MovementAIComponent", "setmovementpath %s", movementPath->pathName.c_str());
m_MovementPath = movementPath;
// get waypoints
std::vector<NiPoint3> pathWaypoints;
for (const auto& waypoint : movementPath->pathWaypoints) m_CurrentPath.push_back(waypoint.position);
SetSpeed(m_BaseSpeed);
m_PathIndex = m_Parent->GetVarAs<int>(u"attached_path_start");
m_TotalTime = m_Timer = 0;
m_Done = false;
};
float MovementAIComponent::GetBaseSpeed(LOT lot) {
// Check if the lot is in the cache
const auto& it = m_PhysicsSpeedCache.find(lot);
@@ -417,13 +313,11 @@ foundComponent:
}
m_PhysicsSpeedCache[lot] = speed;
Game::logger->Log("MovementAIComponent", "speed = %f", speed);
return speed;
}
void MovementAIComponent::SetPosition(const NiPoint3& value) {
Game::logger->Log("MovementAIComponent", "set position %f %f %f", value.x, value.y, value.z);
auto* controllablePhysicsComponent = m_Parent->GetComponent<ControllablePhysicsComponent>();
if (controllablePhysicsComponent != nullptr) {
@@ -460,8 +354,6 @@ void MovementAIComponent::SetRotation(const NiQuaternion& value) {
}
void MovementAIComponent::SetVelocity(const NiPoint3& value) {
Game::logger->Log("MovementAIComponent", "set velocity %f %f %f", value.x, value.y, value.z);
auto* controllablePhysicsComponent = m_Parent->GetComponent<ControllablePhysicsComponent>();
if (controllablePhysicsComponent != nullptr) {
@@ -531,7 +423,7 @@ void MovementAIComponent::SetDestination(const NiPoint3& value) {
m_CurrentPath.push_back(point);
}
m_CurrentPath.push_back(computedPath.at(computedPath.size() - 1));
m_CurrentPath.push_back(computedPath[computedPath.size() - 1]);
m_PathIndex = 0;
@@ -545,14 +437,7 @@ NiPoint3 MovementAIComponent::GetDestination() const {
return GetCurrentPosition();
}
auto destination = m_CurrentPath.at(m_CurrentPath.size() - 1);
if (dpWorld::Instance().IsLoaded()) {
destination.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(destination);
}
auto source = ApproximateLocation();
if (abs(destination.y - source.y) > 3) destination.y = source.y;
return destination;
return m_CurrentPath[m_CurrentPath.size() - 1];
}
void MovementAIComponent::SetSpeed(const float value) {

View File

@@ -209,12 +209,6 @@ public:
*/
void SetPath(std::vector<NiPoint3> path);
/**
* Set the path from a movement path for the AI to follow
* @param movementPath the Path to follow
*/
void SetMovementPath(Path* movementPath);
/**
* Returns the base speed from the DB for a given LOT
* @param lot the lot to check for
@@ -222,8 +216,6 @@ public:
*/
static float GetBaseSpeed(LOT lot);
void ArrivedAtPathWaypoint();
private:
/**
@@ -333,27 +325,6 @@ private:
* Cache of all lots and their respective speeds
*/
static std::map<LOT, float> m_PhysicsSpeedCache;
/**
* Path from luz that we the entity is following
*/
Path* m_MovementPath;
/**
* If we are reversing on a path
*/
bool m_isReverse;
/**
* If we are waiting on a delay before moving
*/
bool m_IsWaiting;
/**
* If we are paused for some reason
*/
bool m_IsPaused;
};
#endif // MOVEMENTAICOMPONENT_H