2023-08-08 01:40:06 +00:00
|
|
|
#ifndef MOVEMENTAICOMPONENT_H
|
|
|
|
#include "MovementAIComponent.h"
|
|
|
|
#endif
|
2023-08-10 02:37:36 +00:00
|
|
|
#include "eWaypointCommandType.h"
|
2023-08-12 05:40:48 +00:00
|
|
|
#include "RenderComponent.h"
|
|
|
|
#include "SkillComponent.h"
|
2023-08-08 01:40:06 +00:00
|
|
|
|
|
|
|
void MovementAIComponent::HandleWaypointArrived() {
|
2023-08-10 08:55:35 +00:00
|
|
|
if (!m_Path) return;
|
2023-08-10 02:37:36 +00:00
|
|
|
if (m_Path->pathWaypoints[m_CurrentPathWaypointIndex].commands.empty()) return;
|
|
|
|
for(auto [command, data] : m_Path->pathWaypoints[m_CurrentPathWaypointIndex].commands){
|
|
|
|
switch(command){
|
|
|
|
case eWaypointCommandType::STOP:
|
2023-08-12 05:40:48 +00:00
|
|
|
Stop();
|
2023-08-10 02:37:36 +00:00
|
|
|
break;
|
|
|
|
case eWaypointCommandType::GROUP_EMOTE:
|
2023-08-12 05:40:48 +00:00
|
|
|
HandleWaypointCommandGroupEmote(data);
|
2023-08-10 02:37:36 +00:00
|
|
|
break;
|
|
|
|
case eWaypointCommandType::SET_VARIABLE:
|
2023-08-12 05:40:48 +00:00
|
|
|
HandleWaypointCommandSetVariable(data);
|
2023-08-10 02:37:36 +00:00
|
|
|
break;
|
|
|
|
case eWaypointCommandType::CAST_SKILL:
|
2023-08-12 05:40:48 +00:00
|
|
|
HandleWaypointCommandCastSkill(data);
|
2023-08-10 02:37:36 +00:00
|
|
|
break;
|
|
|
|
case eWaypointCommandType::EQUIP_INVENTORY:
|
2023-08-12 05:40:48 +00:00
|
|
|
HandleWaypointCommandEquipInventory(data);
|
2023-08-10 02:37:36 +00:00
|
|
|
break;
|
|
|
|
case eWaypointCommandType::UNEQUIP_INVENTORY:
|
2023-08-12 05:40:48 +00:00
|
|
|
HandleWaypointCommandUnequipInventory(data);
|
2023-08-10 02:37:36 +00:00
|
|
|
break;
|
|
|
|
case eWaypointCommandType::DELAY:
|
2023-08-12 05:40:48 +00:00
|
|
|
HandleWaypointCommandDelay(data);
|
2023-08-10 02:37:36 +00:00
|
|
|
break;
|
|
|
|
case eWaypointCommandType::EMOTE:
|
2023-08-12 05:40:48 +00:00
|
|
|
HandleWaypointCommandEmote(data);
|
2023-08-10 02:37:36 +00:00
|
|
|
break;
|
|
|
|
case eWaypointCommandType::TELEPORT:
|
2023-08-12 05:40:48 +00:00
|
|
|
HandleWaypointCommandTeleport(data);
|
2023-08-10 02:37:36 +00:00
|
|
|
break;
|
|
|
|
case eWaypointCommandType::PATH_SPEED:
|
2023-08-12 05:40:48 +00:00
|
|
|
HandleWaypointCommandPathSpeed(data);
|
2023-08-10 02:37:36 +00:00
|
|
|
break;
|
|
|
|
case eWaypointCommandType::REMOVE_NPC:
|
2023-08-12 05:40:48 +00:00
|
|
|
HandleWaypointCommandRemoveNPC(data);
|
2023-08-10 02:37:36 +00:00
|
|
|
break;
|
|
|
|
case eWaypointCommandType::CHANGE_WAYPOINT:
|
2023-08-12 05:40:48 +00:00
|
|
|
HandleWaypointCommandChangeWaypoint(data);
|
2023-08-10 02:37:36 +00:00
|
|
|
break;
|
|
|
|
case eWaypointCommandType::KILL_SELF:
|
2023-08-12 05:40:48 +00:00
|
|
|
m_Parent->Smash(LWOOBJID_EMPTY, eKillType::SILENT);
|
2023-08-10 02:37:36 +00:00
|
|
|
break;
|
2023-08-10 04:29:04 +00:00
|
|
|
case eWaypointCommandType::DELETE_SELF:
|
2023-08-12 05:40:48 +00:00
|
|
|
m_Parent->Kill();
|
2023-08-10 02:37:36 +00:00
|
|
|
break;
|
|
|
|
case eWaypointCommandType::SPAWN_OBJECT:
|
2023-08-12 05:40:48 +00:00
|
|
|
HandleWaypointCommandSpawnObject(data);
|
2023-08-10 02:37:36 +00:00
|
|
|
break;
|
|
|
|
case eWaypointCommandType::PLAY_SOUND:
|
2023-08-12 05:40:48 +00:00
|
|
|
GameMessages::SendPlayNDAudioEmitter(m_Parent, UNASSIGNED_SYSTEM_ADDRESS, data);
|
2023-08-10 04:29:04 +00:00
|
|
|
break;
|
|
|
|
case eWaypointCommandType::BOUNCE:
|
2023-08-12 05:40:48 +00:00
|
|
|
Game::logger->LogDebug("MovementAIComponent", "Unusable Command %i", command);
|
2023-08-10 02:37:36 +00:00
|
|
|
break;
|
|
|
|
case eWaypointCommandType::INVALID:
|
2023-08-10 08:55:35 +00:00
|
|
|
default:
|
2023-08-12 05:40:48 +00:00
|
|
|
Game::logger->LogDebug("MovementAIComponent", "Got invalid waypoint command %i", command);
|
2023-08-10 04:29:04 +00:00
|
|
|
break;
|
2023-08-10 02:37:36 +00:00
|
|
|
}
|
|
|
|
}
|
2023-08-08 01:40:06 +00:00
|
|
|
}
|
2023-08-12 05:40:48 +00:00
|
|
|
|
|
|
|
void MovementAIComponent::HandleWaypointCommandGroupEmote(std::string data) {
|
|
|
|
const auto& split = GeneralUtils::SplitString(data, ';');
|
|
|
|
if (split.size() != 2) return;
|
|
|
|
const auto& entities = Game::entityManager->GetEntitiesInGroup(split[0]);
|
|
|
|
for (auto& entity: entities){
|
|
|
|
RenderComponent::PlayAnimation(entity, split[1]);
|
|
|
|
}
|
|
|
|
// delay for animation time
|
|
|
|
}
|
|
|
|
void MovementAIComponent::HandleWaypointCommandSetVariable(std::string data) {
|
|
|
|
const auto& split = GeneralUtils::SplitString(data, '=');
|
|
|
|
m_Parent->SetNetworkVar(GeneralUtils::ASCIIToUTF16(split[0]), split[1]);
|
|
|
|
}
|
|
|
|
void MovementAIComponent::HandleWaypointCommandCastSkill(std::string data) {
|
|
|
|
if (data.empty()) return;
|
|
|
|
auto* skillComponent = m_Parent->GetComponent<SkillComponent>();
|
|
|
|
if (!skillComponent) {
|
|
|
|
Game::logger->LogDebug("MovementAIComponent::HandleWaypointArrived", "Skill component not found!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
uint32_t skillId = 0;
|
|
|
|
GeneralUtils::TryParse<uint32_t>(data, skillId);
|
|
|
|
if (skillId != 0) skillComponent->CastSkill(skillId);
|
|
|
|
// add some delay??
|
|
|
|
}
|
|
|
|
void MovementAIComponent::HandleWaypointCommandEquipInventory(std::string data) {
|
|
|
|
// equip item via ID (not lot???)
|
|
|
|
}
|
|
|
|
void MovementAIComponent::HandleWaypointCommandUnequipInventory(std::string data) {
|
|
|
|
// unequip item via ID (not lot??)
|
|
|
|
}
|
|
|
|
void MovementAIComponent::HandleWaypointCommandDelay(std::string data) {
|
|
|
|
Pause();
|
|
|
|
std::remove_if(data.begin(), data.end(), isspace);
|
|
|
|
// delay for time
|
|
|
|
}
|
|
|
|
void MovementAIComponent::HandleWaypointCommandEmote(std::string data) {
|
|
|
|
// pause fore animation time
|
|
|
|
auto delay = RenderComponent::PlayAnimation(m_Parent, data);
|
|
|
|
}
|
|
|
|
void MovementAIComponent::HandleWaypointCommandTeleport(std::string data) {
|
|
|
|
auto posString = GeneralUtils::SplitString(data, ',');
|
|
|
|
if (posString.size() == 0) return;
|
|
|
|
auto newPos = NiPoint3();
|
|
|
|
if (posString.size() == 1) GeneralUtils::TryParse<float>(posString[0], newPos.x);
|
|
|
|
if (posString.size() == 2) GeneralUtils::TryParse<float>(posString[1], newPos.y);
|
|
|
|
if (posString.size() == 3) GeneralUtils::TryParse<float>(posString[2], newPos.z);
|
|
|
|
GameMessages::SendTeleport(m_Parent->GetObjectID(), newPos, NiQuaternion::IDENTITY, UNASSIGNED_SYSTEM_ADDRESS);
|
|
|
|
}
|
|
|
|
void MovementAIComponent::HandleWaypointCommandPathSpeed(std::string data) {
|
|
|
|
float speed = 0.0;
|
|
|
|
GeneralUtils::TryParse<float>(data, speed);
|
|
|
|
SetMaxSpeed(speed);
|
|
|
|
}
|
|
|
|
void MovementAIComponent::HandleWaypointCommandRemoveNPC(std::string data) {
|
|
|
|
// get objects in proximity
|
|
|
|
// KillOBJS ???
|
|
|
|
}
|
|
|
|
void MovementAIComponent::HandleWaypointCommandChangeWaypoint(std::string data) {
|
|
|
|
std::string path_string = "";
|
|
|
|
int32_t index = 0;
|
|
|
|
// sometimes there's a path and what waypoint to start, which are comma separated
|
|
|
|
if (data.find(",") != std::string::npos){
|
|
|
|
auto datas = GeneralUtils::SplitString(data, ',');
|
|
|
|
path_string = datas[0];
|
|
|
|
index = stoi(datas[1]);
|
|
|
|
} else path_string = data;
|
|
|
|
|
|
|
|
if (path_string != "") {
|
|
|
|
SetupPath(path_string);
|
|
|
|
SetCurrentPathWaypointIndex(index);
|
|
|
|
SetNextPathWaypointIndex(index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void MovementAIComponent::HandleWaypointCommandSpawnObject(std::string data) {
|
|
|
|
// just do it
|
|
|
|
}
|