mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-11-15 04:38:21 +00:00
Add waypoint command handling
This commit is contained in:
parent
1b54387677
commit
a63d7df0d2
@ -15,6 +15,7 @@ set(DGAME_DCOMPONENTS_SOURCES "BaseCombatAIComponent.cpp"
|
|||||||
"ModelComponent.cpp"
|
"ModelComponent.cpp"
|
||||||
"ModuleAssemblyComponent.cpp"
|
"ModuleAssemblyComponent.cpp"
|
||||||
"MovementAIComponent.cpp"
|
"MovementAIComponent.cpp"
|
||||||
|
"MovementAIComponentAronwk.cpp"
|
||||||
"MovingPlatformComponent.cpp"
|
"MovingPlatformComponent.cpp"
|
||||||
"PetComponent.cpp"
|
"PetComponent.cpp"
|
||||||
"PhantomPhysicsComponent.cpp"
|
"PhantomPhysicsComponent.cpp"
|
||||||
|
@ -310,6 +310,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
const std::vector<int32_t>& GetFactionIDs() const { return m_FactionIDs; }
|
const std::vector<int32_t>& GetFactionIDs() const { return m_FactionIDs; }
|
||||||
|
|
||||||
|
const bool BelongsToFaction(int32_t factionID) const {return std::find(m_FactionIDs.begin(), m_FactionIDs.end(), factionID) != m_FactionIDs.end(); }
|
||||||
/**
|
/**
|
||||||
* Returns all the faction IDs that this entity considers an enemy
|
* Returns all the faction IDs that this entity considers an enemy
|
||||||
* @return all the faction IDs that this entity considers an enemy
|
* @return all the faction IDs that this entity considers an enemy
|
||||||
|
@ -155,7 +155,7 @@ void MovementAIComponent::Update(const float deltaTime) {
|
|||||||
} 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
|
||||||
// All checks for how to progress when you arrive at a waypoint will be handled in this else block.
|
// All checks for how to progress when you arrive at a waypoint will be handled in this else block.
|
||||||
HandleWaypointArrived();
|
HandleWaypointArrived(0);
|
||||||
if (!AdvancePathWaypointIndex()) {
|
if (!AdvancePathWaypointIndex()) {
|
||||||
if (m_Path) {
|
if (m_Path) {
|
||||||
if (m_Path->pathBehavior == PathBehavior::Bounce) {
|
if (m_Path->pathBehavior == PathBehavior::Bounce) {
|
||||||
|
@ -194,7 +194,7 @@ public:
|
|||||||
|
|
||||||
void ReversePath();
|
void ReversePath();
|
||||||
|
|
||||||
void HandleWaypointArrived();
|
void HandleWaypointArrived(uint32_t commandIndex);
|
||||||
|
|
||||||
void SetupPath(const std::string& pathname);
|
void SetupPath(const std::string& pathname);
|
||||||
|
|
||||||
@ -228,18 +228,17 @@ private:
|
|||||||
// TODO: Advance properly
|
// TODO: Advance properly
|
||||||
void SetCurrentPathWaypointIndex(uint32_t value) { };
|
void SetCurrentPathWaypointIndex(uint32_t value) { };
|
||||||
void SetNextPathWaypointIndex(uint32_t value) { };
|
void SetNextPathWaypointIndex(uint32_t value) { };
|
||||||
void HandleWaypointCommandGroupEmote(std::string data);
|
float HandleWaypointCommandGroupEmote(const std::string& data);
|
||||||
void HandleWaypointCommandSetVariable(std::string data);
|
void HandleWaypointCommandSetVariable(const std::string& data);
|
||||||
void HandleWaypointCommandCastSkill(std::string data);
|
void HandleWaypointCommandCastSkill(const std::string& data);
|
||||||
void HandleWaypointCommandEquipInventory(std::string data);
|
void HandleWaypointCommandEquipInventory(const std::string& data);
|
||||||
void HandleWaypointCommandUnequipInventory(std::string data);
|
void HandleWaypointCommandUnequipInventory(const std::string& data);
|
||||||
void HandleWaypointCommandDelay(std::string data);
|
float HandleWaypointCommandDelay(const std::string& data);
|
||||||
void HandleWaypointCommandEmote(std::string data);
|
void HandleWaypointCommandTeleport(const std::string& data);
|
||||||
void HandleWaypointCommandTeleport(std::string data);
|
void HandleWaypointCommandPathSpeed(const std::string& data);
|
||||||
void HandleWaypointCommandPathSpeed(std::string data);
|
void HandleWaypointCommandRemoveNPC(const std::string& data);
|
||||||
void HandleWaypointCommandRemoveNPC(std::string data);
|
void HandleWaypointCommandChangeWaypoint(const std::string& data);
|
||||||
void HandleWaypointCommandChangeWaypoint(std::string data);
|
void HandleWaypointCommandSpawnObject(const std::string& data);
|
||||||
void HandleWaypointCommandSpawnObject(std::string data);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the current position of the entity
|
* Sets the current position of the entity
|
||||||
|
@ -4,17 +4,32 @@
|
|||||||
#include "eWaypointCommandType.h"
|
#include "eWaypointCommandType.h"
|
||||||
#include "RenderComponent.h"
|
#include "RenderComponent.h"
|
||||||
#include "SkillComponent.h"
|
#include "SkillComponent.h"
|
||||||
|
#include "InventoryComponent.h"
|
||||||
|
#include "Zone.h"
|
||||||
|
#include "EntityInfo.h"
|
||||||
|
#include "ProximityMonitorComponent.h"
|
||||||
|
#include "DestroyableComponent.h"
|
||||||
|
|
||||||
void MovementAIComponent::HandleWaypointArrived() {
|
void MovementAIComponent::HandleWaypointArrived(uint32_t commandIndex) {
|
||||||
if (!m_Path) return;
|
Pause();
|
||||||
if (m_Path->pathWaypoints.at(m_CurrentPathWaypointIndex).commands.empty()) return;
|
if (!m_Path){
|
||||||
for(auto [command, data] : m_Path->pathWaypoints.at(m_CurrentPathWaypointIndex).commands){
|
Resume();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (commandIndex >= m_Path->pathWaypoints.at(m_CurrentPathWaypointIndex).commands.size()){
|
||||||
|
Resume();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& data = m_Path->pathWaypoints.at(m_CurrentPathWaypointIndex).commands.at(commandIndex).data;
|
||||||
|
const auto& command = m_Path->pathWaypoints.at(m_CurrentPathWaypointIndex).commands.at(commandIndex).command;
|
||||||
|
float delay = 0.0f;
|
||||||
switch(command){
|
switch(command){
|
||||||
case eWaypointCommandType::STOP:
|
case eWaypointCommandType::STOP:
|
||||||
Stop();
|
Stop();
|
||||||
break;
|
break;
|
||||||
case eWaypointCommandType::GROUP_EMOTE:
|
case eWaypointCommandType::GROUP_EMOTE:
|
||||||
HandleWaypointCommandGroupEmote(data);
|
delay = HandleWaypointCommandGroupEmote(data);
|
||||||
break;
|
break;
|
||||||
case eWaypointCommandType::SET_VARIABLE:
|
case eWaypointCommandType::SET_VARIABLE:
|
||||||
HandleWaypointCommandSetVariable(data);
|
HandleWaypointCommandSetVariable(data);
|
||||||
@ -29,10 +44,10 @@ void MovementAIComponent::HandleWaypointArrived() {
|
|||||||
HandleWaypointCommandUnequipInventory(data);
|
HandleWaypointCommandUnequipInventory(data);
|
||||||
break;
|
break;
|
||||||
case eWaypointCommandType::DELAY:
|
case eWaypointCommandType::DELAY:
|
||||||
HandleWaypointCommandDelay(data);
|
delay = HandleWaypointCommandDelay(data);
|
||||||
break;
|
break;
|
||||||
case eWaypointCommandType::EMOTE:
|
case eWaypointCommandType::EMOTE:
|
||||||
HandleWaypointCommandEmote(data);
|
delay = RenderComponent::PlayAnimation(m_Parent, data);
|
||||||
break;
|
break;
|
||||||
case eWaypointCommandType::TELEPORT:
|
case eWaypointCommandType::TELEPORT:
|
||||||
HandleWaypointCommandTeleport(data);
|
HandleWaypointCommandTeleport(data);
|
||||||
@ -59,90 +74,152 @@ void MovementAIComponent::HandleWaypointArrived() {
|
|||||||
GameMessages::SendPlayNDAudioEmitter(m_Parent, UNASSIGNED_SYSTEM_ADDRESS, data);
|
GameMessages::SendPlayNDAudioEmitter(m_Parent, UNASSIGNED_SYSTEM_ADDRESS, data);
|
||||||
break;
|
break;
|
||||||
case eWaypointCommandType::BOUNCE:
|
case eWaypointCommandType::BOUNCE:
|
||||||
Game::logger->LogDebug("MovementAIComponent", "Unusable Command %i", command);
|
Game::logger->LogDebug("MovementAIComponent", "Unable to process bounce waypoint command server side");
|
||||||
break;
|
break;
|
||||||
case eWaypointCommandType::INVALID:
|
case eWaypointCommandType::INVALID:
|
||||||
default:
|
default:
|
||||||
Game::logger->LogDebug("MovementAIComponent", "Got invalid waypoint command %i", command);
|
Game::logger->LogDebug("MovementAIComponent", "Got invalid waypoint command %i", command);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_Parent->AddCallbackTimer(delay, [this, commandIndex](){
|
||||||
|
auto newCommandIndex = commandIndex + 1;
|
||||||
|
this->HandleWaypointArrived(newCommandIndex);
|
||||||
}
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MovementAIComponent::HandleWaypointCommandGroupEmote(std::string data) {
|
float MovementAIComponent::HandleWaypointCommandGroupEmote(const std::string& data) {
|
||||||
const auto& split = GeneralUtils::SplitString(data, ';');
|
const auto& split = GeneralUtils::SplitString(data, ';');
|
||||||
if (split.size() != 2) return;
|
if (split.size() != 2) return 0.0f;
|
||||||
const auto& entities = Game::entityManager->GetEntitiesInGroup(split[0]);
|
const auto& entities = Game::entityManager->GetEntitiesInGroup(split.at(0));
|
||||||
|
float delay = 0.0f;
|
||||||
for (auto& entity: entities){
|
for (auto& entity: entities){
|
||||||
RenderComponent::PlayAnimation(entity, split[1]);
|
delay = RenderComponent::PlayAnimation(entity, split.at(1));
|
||||||
}
|
}
|
||||||
// delay for animation time
|
return delay;
|
||||||
}
|
}
|
||||||
void MovementAIComponent::HandleWaypointCommandSetVariable(std::string data) {
|
|
||||||
const auto& split = GeneralUtils::SplitString(data, '=');
|
void MovementAIComponent::HandleWaypointCommandSetVariable(const std::string& data) {
|
||||||
m_Parent->SetNetworkVar(GeneralUtils::ASCIIToUTF16(split[0]), split[1]);
|
const auto& split = GeneralUtils::SplitString(data, ',');
|
||||||
|
m_Parent->SetNetworkVar(GeneralUtils::ASCIIToUTF16(split.at(0)), split.at(1));
|
||||||
}
|
}
|
||||||
void MovementAIComponent::HandleWaypointCommandCastSkill(std::string data) {
|
|
||||||
|
void MovementAIComponent::HandleWaypointCommandCastSkill(const std::string& data) {
|
||||||
if (data.empty()) return;
|
if (data.empty()) return;
|
||||||
auto* skillComponent = m_Parent->GetComponent<SkillComponent>();
|
auto* skillComponent = m_Parent->GetComponent<SkillComponent>();
|
||||||
if (!skillComponent) {
|
if (!skillComponent) {
|
||||||
Game::logger->LogDebug("MovementAIComponent::HandleWaypointArrived", "Skill component not found!");
|
Game::logger->LogDebug("MovementAIComponent::HandleWaypointCommandCastSkill", "Skill component not found!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint32_t skillId = 0;
|
uint32_t skillId = 0;
|
||||||
GeneralUtils::TryParse<uint32_t>(data, skillId);
|
GeneralUtils::TryParse<uint32_t>(data, skillId);
|
||||||
if (skillId != 0) skillComponent->CastSkill(skillId);
|
if (skillId != 0) skillComponent->CastSkill(skillId);
|
||||||
// add some delay??
|
return;
|
||||||
}
|
}
|
||||||
void MovementAIComponent::HandleWaypointCommandEquipInventory(std::string data) {
|
|
||||||
// equip item via ID (not lot???)
|
void MovementAIComponent::HandleWaypointCommandEquipInventory(const std::string& data) {
|
||||||
|
if (data.empty()) return;
|
||||||
|
auto* inventoryComponent = m_Parent->GetComponent<InventoryComponent>();
|
||||||
|
if (!inventoryComponent) {
|
||||||
|
Game::logger->LogDebug("MovementAIComponent::HandleWaypointCommandEquipInventory", "Inventory component not found!");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
void MovementAIComponent::HandleWaypointCommandUnequipInventory(std::string data) {
|
// the client says use slot 0 of items
|
||||||
// unequip item via ID (not lot??)
|
const auto inventory = inventoryComponent->GetInventory(eInventoryType::ITEMS);
|
||||||
|
if (!inventory) return;
|
||||||
|
const auto slots = inventory->GetSlots();
|
||||||
|
const auto item = slots.find(0);
|
||||||
|
if (item != slots.end()) inventoryComponent->EquipItem(item->second);
|
||||||
}
|
}
|
||||||
void MovementAIComponent::HandleWaypointCommandDelay(std::string data) {
|
|
||||||
Pause();
|
void MovementAIComponent::HandleWaypointCommandUnequipInventory(const std::string& data) {
|
||||||
std::remove_if(data.begin(), data.end(), ::isspace);
|
if (data.empty()) return;
|
||||||
// delay for time
|
auto* inventoryComponent = m_Parent->GetComponent<InventoryComponent>();
|
||||||
|
if (!inventoryComponent) {
|
||||||
|
Game::logger->LogDebug("MovementAIComponent::HandleWaypointCommandEquipInventory", "Inventory component not found!");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
void MovementAIComponent::HandleWaypointCommandEmote(std::string data) {
|
// the client says use slot 0 of items
|
||||||
// pause for animation time
|
const auto inventory = inventoryComponent->GetInventory(eInventoryType::ITEMS);
|
||||||
auto delay = RenderComponent::PlayAnimation(m_Parent, data);
|
if (!inventory) return;
|
||||||
|
const auto slots = inventory->GetSlots();
|
||||||
|
const auto item = slots.find(0);
|
||||||
|
if (item != slots.end()) inventoryComponent->UnEquipItem(item->second);
|
||||||
}
|
}
|
||||||
void MovementAIComponent::HandleWaypointCommandTeleport(std::string data) {
|
|
||||||
|
float MovementAIComponent::HandleWaypointCommandDelay(const std::string& data) {
|
||||||
|
float delay = 0.0f;
|
||||||
|
std::string delayString = data;
|
||||||
|
std::remove_if(delayString.begin(), delayString.end(), ::isspace);
|
||||||
|
GeneralUtils::TryParse<float>(delayString, delay);
|
||||||
|
return delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovementAIComponent::HandleWaypointCommandTeleport(const std::string& data) {
|
||||||
auto posString = GeneralUtils::SplitString(data, ',');
|
auto posString = GeneralUtils::SplitString(data, ',');
|
||||||
if (posString.size() == 0) return;
|
if (posString.size() == 0) return;
|
||||||
auto newPos = NiPoint3();
|
auto newPos = NiPoint3();
|
||||||
if (posString.size() == 1) GeneralUtils::TryParse<float>(posString.at(0), newPos.x);
|
if (posString.size() == 1 && !GeneralUtils::TryParse<float>(posString.at(0), newPos.x)) return;
|
||||||
if (posString.size() == 2) GeneralUtils::TryParse<float>(posString.at(1), newPos.y);
|
if (posString.size() == 2 && !GeneralUtils::TryParse<float>(posString.at(1), newPos.y)) return;
|
||||||
if (posString.size() == 3) GeneralUtils::TryParse<float>(posString.at(2), newPos.z);
|
if (posString.size() == 3 && !GeneralUtils::TryParse<float>(posString.at(2), newPos.z)) return;
|
||||||
GameMessages::SendTeleport(m_Parent->GetObjectID(), newPos, NiQuaternion::IDENTITY, UNASSIGNED_SYSTEM_ADDRESS);
|
GameMessages::SendTeleport(m_Parent->GetObjectID(), newPos, NiQuaternion::IDENTITY, UNASSIGNED_SYSTEM_ADDRESS);
|
||||||
}
|
}
|
||||||
void MovementAIComponent::HandleWaypointCommandPathSpeed(std::string data) {
|
|
||||||
|
void MovementAIComponent::HandleWaypointCommandPathSpeed(const std::string& data) {
|
||||||
float speed = 0.0;
|
float speed = 0.0;
|
||||||
GeneralUtils::TryParse<float>(data, speed);
|
GeneralUtils::TryParse<float>(data, speed);
|
||||||
SetMaxSpeed(speed);
|
SetCurrentSpeed(speed);
|
||||||
}
|
}
|
||||||
void MovementAIComponent::HandleWaypointCommandRemoveNPC(std::string data) {
|
|
||||||
// get objects in proximity
|
void MovementAIComponent::HandleWaypointCommandRemoveNPC(const std::string& data) {
|
||||||
// KillOBJS ???
|
if (data.empty()) return;
|
||||||
|
auto* proximityMonitorComponent = m_Parent->GetComponent<ProximityMonitorComponent>();
|
||||||
|
if (!proximityMonitorComponent) {
|
||||||
|
Game::logger->LogDebug("MovementAIComponent::HandleWaypointCommandRemoveNPC", "Proximity monitor component not found!");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
void MovementAIComponent::HandleWaypointCommandChangeWaypoint(std::string data) {
|
const auto foundObjs = proximityMonitorComponent->GetProximityObjects("KillOBJS");
|
||||||
|
for (auto& [objid, phyEntity] : foundObjs){
|
||||||
|
auto entity = Game::entityManager->GetEntity(objid);
|
||||||
|
if (!entity) return;
|
||||||
|
auto* destroyableComponent = m_Parent->GetComponent<DestroyableComponent>();
|
||||||
|
if (!destroyableComponent) {
|
||||||
|
Game::logger->LogDebug("MovementAIComponent::HandleWaypointCommandRemoveNPC", "Destroyable component not found!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint32_t factionID = -1;
|
||||||
|
GeneralUtils::TryParse<uint32_t>(data, factionID);
|
||||||
|
if (destroyableComponent->BelongsToFaction(factionID)) m_Parent->Kill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovementAIComponent::HandleWaypointCommandChangeWaypoint(const std::string& data) {
|
||||||
std::string path_string = "";
|
std::string path_string = "";
|
||||||
int32_t index = 0;
|
int32_t index = 0;
|
||||||
// sometimes there's a path and what waypoint to start, which are comma separated
|
// sometimes there's a path and what waypoint to start, which are comma separated
|
||||||
if (data.find(",") != std::string::npos){
|
if (data.find(",") != std::string::npos){
|
||||||
auto datas = GeneralUtils::SplitString(data, ',');
|
auto datas = GeneralUtils::SplitString(data, ',');
|
||||||
path_string = datas[0];
|
path_string = datas.at(0);
|
||||||
index = stoi(datas[1]);
|
GeneralUtils::TryParse(datas.at(1), index);
|
||||||
} else path_string = data;
|
} else path_string = data;
|
||||||
|
|
||||||
if (path_string != "") {
|
if (path_string != "") {
|
||||||
SetupPath(path_string);
|
SetupPath(path_string);
|
||||||
|
// TODO: do better? talk to emo
|
||||||
SetCurrentPathWaypointIndex(index);
|
SetCurrentPathWaypointIndex(index);
|
||||||
SetNextPathWaypointIndex(index);
|
SetNextPathWaypointIndex(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void MovementAIComponent::HandleWaypointCommandSpawnObject(std::string data) {
|
|
||||||
// just do it
|
void MovementAIComponent::HandleWaypointCommandSpawnObject(const std::string& data) {
|
||||||
|
LOT newObjectLOT = 0;
|
||||||
|
GeneralUtils::TryParse(data, newObjectLOT);
|
||||||
|
EntityInfo info{};
|
||||||
|
info.lot = newObjectLOT;
|
||||||
|
info.pos = m_Parent->GetPosition();
|
||||||
|
info.rot = m_Parent->GetRotation();
|
||||||
|
auto* spawnedEntity = Game::entityManager->CreateEntity(info, nullptr, m_Parent);
|
||||||
|
Game::entityManager->ConstructEntity(spawnedEntity);
|
||||||
|
m_Parent->Smash(LWOOBJID_EMPTY, eKillType::SILENT);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user