mirror of
				https://github.com/DarkflameUniverse/DarkflameServer.git
				synced 2025-11-04 06:32:00 +00:00 
			
		
		
		
	Combine files
Add LUtrigger interfaces and calling
This commit is contained in:
		@@ -15,7 +15,6 @@ set(DGAME_DCOMPONENTS_SOURCES "BaseCombatAIComponent.cpp"
 | 
			
		||||
	"ModelComponent.cpp"
 | 
			
		||||
	"ModuleAssemblyComponent.cpp"
 | 
			
		||||
	"MovementAIComponent.cpp"
 | 
			
		||||
	"MovementAIComponentAronwk.cpp"
 | 
			
		||||
	"MovingPlatformComponent.cpp"
 | 
			
		||||
	"PetComponent.cpp"
 | 
			
		||||
	"PhantomPhysicsComponent.cpp"
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,13 @@
 | 
			
		||||
#include "CDClientManager.h"
 | 
			
		||||
#include "Game.h"
 | 
			
		||||
#include "dZoneManager.h"
 | 
			
		||||
#include "eTriggerEventType.h"
 | 
			
		||||
#include "eWaypointCommandType.h"
 | 
			
		||||
#include "RenderComponent.h"
 | 
			
		||||
#include "SkillComponent.h"
 | 
			
		||||
#include "InventoryComponent.h"
 | 
			
		||||
#include "ProximityMonitorComponent.h"
 | 
			
		||||
#include "DestroyableComponent.h"
 | 
			
		||||
 | 
			
		||||
#include "CDComponentsRegistryTable.h"
 | 
			
		||||
#include "CDPhysicsComponentTable.h"
 | 
			
		||||
@@ -457,4 +464,232 @@ void MovementAIComponent::SetMaxSpeed(const float value) {
 | 
			
		||||
	m_Acceleration = value / 5;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include "MovementAIComponentAronwk.cpp"
 | 
			
		||||
void MovementAIComponent::HandleWaypointArrived(uint32_t commandIndex) {
 | 
			
		||||
	m_Parent->TriggerEvent(eTriggerEventType::ARRIVED);
 | 
			
		||||
	m_Parent->TriggerEvent(eTriggerEventType::ARRIVED_AT_DESIRED_WAYPOINT);
 | 
			
		||||
	if (!m_Path || commandIndex >= m_Path->pathWaypoints.at(m_CurrentPathWaypointIndex).commands.size()) {
 | 
			
		||||
		if (!AdvancePathWaypointIndex()) {
 | 
			
		||||
			if (m_Path) {
 | 
			
		||||
				if (m_Path->pathBehavior == PathBehavior::Bounce) {
 | 
			
		||||
					ReversePath();
 | 
			
		||||
				} else if (m_Path->pathBehavior == PathBehavior::Loop) {
 | 
			
		||||
					m_CurrentPathWaypointIndex = 0;
 | 
			
		||||
					m_NextPathWaypointIndex = 0;
 | 
			
		||||
					AdvancePathWaypointIndex();
 | 
			
		||||
					SetDestination(GetCurrentPathWaypoint());
 | 
			
		||||
					SetMaxSpeed(GetCurrentPathWaypointSpeed());
 | 
			
		||||
				} else {
 | 
			
		||||
					Stop();
 | 
			
		||||
					m_Parent->TriggerEvent(eTriggerEventType::ARRIVED_AT_END_OF_PATH);
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				Stop();
 | 
			
		||||
			}
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		SetDestination(GetCurrentPathWaypoint());
 | 
			
		||||
		SetMaxSpeed(GetCurrentPathWaypointSpeed());
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (!IsPaused()) Pause();
 | 
			
		||||
	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) {
 | 
			
		||||
	case eWaypointCommandType::STOP:
 | 
			
		||||
		Stop();
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::GROUP_EMOTE:
 | 
			
		||||
		delay = HandleWaypointCommandGroupEmote(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::SET_VARIABLE:
 | 
			
		||||
		HandleWaypointCommandSetVariable(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::CAST_SKILL:
 | 
			
		||||
		HandleWaypointCommandCastSkill(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::EQUIP_INVENTORY:
 | 
			
		||||
		HandleWaypointCommandEquipInventory(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::UNEQUIP_INVENTORY:
 | 
			
		||||
		HandleWaypointCommandUnequipInventory(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::DELAY:
 | 
			
		||||
		delay = HandleWaypointCommandDelay(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::EMOTE:
 | 
			
		||||
		delay = RenderComponent::PlayAnimation(m_Parent, data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::TELEPORT:
 | 
			
		||||
		HandleWaypointCommandTeleport(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::PATH_SPEED:
 | 
			
		||||
		HandleWaypointCommandPathSpeed(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::REMOVE_NPC:
 | 
			
		||||
		HandleWaypointCommandRemoveNPC(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::CHANGE_WAYPOINT:
 | 
			
		||||
		HandleWaypointCommandChangeWaypoint(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::KILL_SELF:
 | 
			
		||||
		m_Parent->Smash(LWOOBJID_EMPTY, eKillType::SILENT);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::DELETE_SELF:
 | 
			
		||||
		m_Parent->Kill();
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::SPAWN_OBJECT:
 | 
			
		||||
		HandleWaypointCommandSpawnObject(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::PLAY_SOUND:
 | 
			
		||||
		GameMessages::SendPlayNDAudioEmitter(m_Parent, UNASSIGNED_SYSTEM_ADDRESS, data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::BOUNCE:
 | 
			
		||||
		Game::logger->LogDebug("MovementAIComponent", "Unable to process bounce waypoint command server side!");
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::INVALID:
 | 
			
		||||
	default:
 | 
			
		||||
		Game::logger->LogDebug("MovementAIComponent", "Got invalid waypoint command %i", command);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m_Parent->AddCallbackTimer(delay, [this, commandIndex]() {
 | 
			
		||||
		this->HandleWaypointArrived(commandIndex + 1);
 | 
			
		||||
		}
 | 
			
		||||
	);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float MovementAIComponent::HandleWaypointCommandGroupEmote(const std::string& data) {
 | 
			
		||||
	const auto& split = GeneralUtils::SplitString(data, ';');
 | 
			
		||||
	if (split.size() != 2) return 0.0f;
 | 
			
		||||
	const auto& entities = Game::entityManager->GetEntitiesInGroup(split.at(0));
 | 
			
		||||
	float delay = 0.0f;
 | 
			
		||||
	for (auto& entity : entities) {
 | 
			
		||||
		delay = RenderComponent::PlayAnimation(entity, split.at(1));
 | 
			
		||||
	}
 | 
			
		||||
	return delay;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MovementAIComponent::HandleWaypointCommandSetVariable(const std::string& data) {
 | 
			
		||||
	const auto& split = GeneralUtils::SplitString(data, ',');
 | 
			
		||||
	m_Parent->SetNetworkVar(GeneralUtils::ASCIIToUTF16(split.at(0)), split.at(1));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MovementAIComponent::HandleWaypointCommandCastSkill(const std::string& data) {
 | 
			
		||||
	if (data.empty()) return;
 | 
			
		||||
	auto* skillComponent = m_Parent->GetComponent<SkillComponent>();
 | 
			
		||||
	if (!skillComponent) {
 | 
			
		||||
		Game::logger->LogDebug("MovementAIComponent::HandleWaypointCommandCastSkill", "Skill component not found!");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	uint32_t skillId = 0;
 | 
			
		||||
	if (!GeneralUtils::TryParse<uint32_t>(data, skillId)) return;
 | 
			
		||||
	if (skillId != 0) skillComponent->CastSkill(skillId);
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
	}
 | 
			
		||||
	// the client says use slot 0 of items
 | 
			
		||||
	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::HandleWaypointCommandUnequipInventory(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;
 | 
			
		||||
	}
 | 
			
		||||
	// the client says use slot 0 of items
 | 
			
		||||
	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->UnEquipItem(item->second);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float MovementAIComponent::HandleWaypointCommandDelay(const std::string& data) {
 | 
			
		||||
	float delay = 0.0f;
 | 
			
		||||
	std::string delayString = data;
 | 
			
		||||
	if (!GeneralUtils::TryParse<float>(delayString, delay)) {
 | 
			
		||||
		Game::logger->LogDebug("MovementAIComponentAronwk", "Failed to parse delay %s", data.c_str());
 | 
			
		||||
	}
 | 
			
		||||
	return delay;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MovementAIComponent::HandleWaypointCommandTeleport(const std::string& data) {
 | 
			
		||||
	auto posString = GeneralUtils::SplitString(data, ',');
 | 
			
		||||
	if (posString.size() == 0) return;
 | 
			
		||||
	auto newPos = NiPoint3();
 | 
			
		||||
	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)) return;
 | 
			
		||||
	if (posString.size() == 3 && !GeneralUtils::TryParse<float>(posString.at(2), newPos.z)) return;
 | 
			
		||||
	GameMessages::SendTeleport(m_Parent->GetObjectID(), newPos, NiQuaternion::IDENTITY, UNASSIGNED_SYSTEM_ADDRESS);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MovementAIComponent::HandleWaypointCommandPathSpeed(const std::string& data) {
 | 
			
		||||
	float speed = 0.0;
 | 
			
		||||
	if (!GeneralUtils::TryParse<float>(data, speed)) return;
 | 
			
		||||
	SetMaxSpeed(speed);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MovementAIComponent::HandleWaypointCommandRemoveNPC(const std::string& data) {
 | 
			
		||||
	if (data.empty()) return;
 | 
			
		||||
	auto* proximityMonitorComponent = m_Parent->GetComponent<ProximityMonitorComponent>();
 | 
			
		||||
	if (!proximityMonitorComponent) {
 | 
			
		||||
		Game::logger->LogDebug("MovementAIComponent::HandleWaypointCommandRemoveNPC", "Proximity monitor component not found!");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	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;
 | 
			
		||||
		if (!GeneralUtils::TryParse<uint32_t>(data, factionID)) return;
 | 
			
		||||
		if (destroyableComponent->BelongsToFaction(factionID)) m_Parent->Kill();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MovementAIComponent::HandleWaypointCommandChangeWaypoint(const 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.at(0);
 | 
			
		||||
		if (!GeneralUtils::TryParse(datas.at(1), index)) return;
 | 
			
		||||
	} else path_string = data;
 | 
			
		||||
 | 
			
		||||
	if (path_string != "") {
 | 
			
		||||
		SetPathStartingWaypointIndex(index);
 | 
			
		||||
		SetupPath(path_string);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MovementAIComponent::HandleWaypointCommandSpawnObject(const std::string& data) {
 | 
			
		||||
	LOT newObjectLOT = 0;
 | 
			
		||||
	if (!GeneralUtils::TryParse(data, newObjectLOT)) return;
 | 
			
		||||
	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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -242,6 +242,8 @@ public:
 | 
			
		||||
	 */
 | 
			
		||||
	static float GetBaseSpeed(LOT lot);
 | 
			
		||||
 | 
			
		||||
	const bool GetIsInReverse(){ return m_IsInReverse; };
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	float HandleWaypointCommandGroupEmote(const std::string& data);
 | 
			
		||||
	void HandleWaypointCommandSetVariable(const std::string& data);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,237 +0,0 @@
 | 
			
		||||
#ifndef MOVEMENTAICOMPONENT_H
 | 
			
		||||
#include "MovementAIComponent.h"
 | 
			
		||||
#endif
 | 
			
		||||
#include "eWaypointCommandType.h"
 | 
			
		||||
#include "RenderComponent.h"
 | 
			
		||||
#include "SkillComponent.h"
 | 
			
		||||
#include "InventoryComponent.h"
 | 
			
		||||
#include "Zone.h"
 | 
			
		||||
#include "EntityInfo.h"
 | 
			
		||||
#include "ProximityMonitorComponent.h"
 | 
			
		||||
#include "DestroyableComponent.h"
 | 
			
		||||
 | 
			
		||||
void MovementAIComponent::HandleWaypointArrived(uint32_t commandIndex) {
 | 
			
		||||
	if (!m_Path || commandIndex >= m_Path->pathWaypoints.at(m_CurrentPathWaypointIndex).commands.size()) {
 | 
			
		||||
		if (!AdvancePathWaypointIndex()) {
 | 
			
		||||
			if (m_Path) {
 | 
			
		||||
				if (m_Path->pathBehavior == PathBehavior::Bounce) {
 | 
			
		||||
					ReversePath();
 | 
			
		||||
				} else if (m_Path->pathBehavior == PathBehavior::Loop) {
 | 
			
		||||
					m_CurrentPathWaypointIndex = 0;
 | 
			
		||||
					m_NextPathWaypointIndex = 0;
 | 
			
		||||
					AdvancePathWaypointIndex();
 | 
			
		||||
					SetDestination(GetCurrentPathWaypoint());
 | 
			
		||||
					SetMaxSpeed(GetCurrentPathWaypointSpeed());
 | 
			
		||||
				} else {
 | 
			
		||||
					Stop();
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				Stop();
 | 
			
		||||
			}
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		SetDestination(GetCurrentPathWaypoint());
 | 
			
		||||
		SetMaxSpeed(GetCurrentPathWaypointSpeed());
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (!IsPaused()) Pause();
 | 
			
		||||
	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) {
 | 
			
		||||
	case eWaypointCommandType::STOP:
 | 
			
		||||
		Stop();
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::GROUP_EMOTE:
 | 
			
		||||
		delay = HandleWaypointCommandGroupEmote(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::SET_VARIABLE:
 | 
			
		||||
		HandleWaypointCommandSetVariable(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::CAST_SKILL:
 | 
			
		||||
		HandleWaypointCommandCastSkill(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::EQUIP_INVENTORY:
 | 
			
		||||
		HandleWaypointCommandEquipInventory(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::UNEQUIP_INVENTORY:
 | 
			
		||||
		HandleWaypointCommandUnequipInventory(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::DELAY:
 | 
			
		||||
		delay = HandleWaypointCommandDelay(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::EMOTE:
 | 
			
		||||
		delay = RenderComponent::PlayAnimation(m_Parent, data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::TELEPORT:
 | 
			
		||||
		HandleWaypointCommandTeleport(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::PATH_SPEED:
 | 
			
		||||
		HandleWaypointCommandPathSpeed(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::REMOVE_NPC:
 | 
			
		||||
		HandleWaypointCommandRemoveNPC(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::CHANGE_WAYPOINT:
 | 
			
		||||
		HandleWaypointCommandChangeWaypoint(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::KILL_SELF:
 | 
			
		||||
		m_Parent->Smash(LWOOBJID_EMPTY, eKillType::SILENT);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::DELETE_SELF:
 | 
			
		||||
		m_Parent->Kill();
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::SPAWN_OBJECT:
 | 
			
		||||
		HandleWaypointCommandSpawnObject(data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::PLAY_SOUND:
 | 
			
		||||
		GameMessages::SendPlayNDAudioEmitter(m_Parent, UNASSIGNED_SYSTEM_ADDRESS, data);
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::BOUNCE:
 | 
			
		||||
		Game::logger->LogDebug("MovementAIComponent", "Unable to process bounce waypoint command server side!");
 | 
			
		||||
		break;
 | 
			
		||||
	case eWaypointCommandType::INVALID:
 | 
			
		||||
	default:
 | 
			
		||||
		Game::logger->LogDebug("MovementAIComponent", "Got invalid waypoint command %i", command);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m_Parent->AddCallbackTimer(delay, [this, commandIndex]() {
 | 
			
		||||
		this->HandleWaypointArrived(commandIndex + 1);
 | 
			
		||||
		}
 | 
			
		||||
	);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float MovementAIComponent::HandleWaypointCommandGroupEmote(const std::string& data) {
 | 
			
		||||
	const auto& split = GeneralUtils::SplitString(data, ';');
 | 
			
		||||
	if (split.size() != 2) return 0.0f;
 | 
			
		||||
	const auto& entities = Game::entityManager->GetEntitiesInGroup(split.at(0));
 | 
			
		||||
	float delay = 0.0f;
 | 
			
		||||
	for (auto& entity : entities) {
 | 
			
		||||
		delay = RenderComponent::PlayAnimation(entity, split.at(1));
 | 
			
		||||
	}
 | 
			
		||||
	return delay;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MovementAIComponent::HandleWaypointCommandSetVariable(const std::string& data) {
 | 
			
		||||
	const auto& split = GeneralUtils::SplitString(data, ',');
 | 
			
		||||
	m_Parent->SetNetworkVar(GeneralUtils::ASCIIToUTF16(split.at(0)), split.at(1));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MovementAIComponent::HandleWaypointCommandCastSkill(const std::string& data) {
 | 
			
		||||
	if (data.empty()) return;
 | 
			
		||||
	auto* skillComponent = m_Parent->GetComponent<SkillComponent>();
 | 
			
		||||
	if (!skillComponent) {
 | 
			
		||||
		Game::logger->LogDebug("MovementAIComponent::HandleWaypointCommandCastSkill", "Skill component not found!");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	uint32_t skillId = 0;
 | 
			
		||||
	if (!GeneralUtils::TryParse<uint32_t>(data, skillId)) return;
 | 
			
		||||
	if (skillId != 0) skillComponent->CastSkill(skillId);
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
	}
 | 
			
		||||
	// the client says use slot 0 of items
 | 
			
		||||
	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::HandleWaypointCommandUnequipInventory(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;
 | 
			
		||||
	}
 | 
			
		||||
	// the client says use slot 0 of items
 | 
			
		||||
	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->UnEquipItem(item->second);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float MovementAIComponent::HandleWaypointCommandDelay(const std::string& data) {
 | 
			
		||||
	float delay = 0.0f;
 | 
			
		||||
	std::string delayString = data;
 | 
			
		||||
	if (!GeneralUtils::TryParse<float>(delayString, delay)) {
 | 
			
		||||
		Game::logger->LogDebug("MovementAIComponentAronwk", "Failed to parse delay %s", data.c_str());
 | 
			
		||||
	}
 | 
			
		||||
	return delay;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MovementAIComponent::HandleWaypointCommandTeleport(const std::string& data) {
 | 
			
		||||
	auto posString = GeneralUtils::SplitString(data, ',');
 | 
			
		||||
	if (posString.size() == 0) return;
 | 
			
		||||
	auto newPos = NiPoint3();
 | 
			
		||||
	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)) return;
 | 
			
		||||
	if (posString.size() == 3 && !GeneralUtils::TryParse<float>(posString.at(2), newPos.z)) return;
 | 
			
		||||
	GameMessages::SendTeleport(m_Parent->GetObjectID(), newPos, NiQuaternion::IDENTITY, UNASSIGNED_SYSTEM_ADDRESS);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MovementAIComponent::HandleWaypointCommandPathSpeed(const std::string& data) {
 | 
			
		||||
	float speed = 0.0;
 | 
			
		||||
	if (!GeneralUtils::TryParse<float>(data, speed)) return;
 | 
			
		||||
	SetMaxSpeed(speed);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MovementAIComponent::HandleWaypointCommandRemoveNPC(const std::string& data) {
 | 
			
		||||
	if (data.empty()) return;
 | 
			
		||||
	auto* proximityMonitorComponent = m_Parent->GetComponent<ProximityMonitorComponent>();
 | 
			
		||||
	if (!proximityMonitorComponent) {
 | 
			
		||||
		Game::logger->LogDebug("MovementAIComponent::HandleWaypointCommandRemoveNPC", "Proximity monitor component not found!");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	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;
 | 
			
		||||
		if (!GeneralUtils::TryParse<uint32_t>(data, factionID)) return;
 | 
			
		||||
		if (destroyableComponent->BelongsToFaction(factionID)) m_Parent->Kill();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MovementAIComponent::HandleWaypointCommandChangeWaypoint(const 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.at(0);
 | 
			
		||||
		if (!GeneralUtils::TryParse(datas.at(1), index)) return;
 | 
			
		||||
	} else path_string = data;
 | 
			
		||||
 | 
			
		||||
	if (path_string != "") {
 | 
			
		||||
		SetPathStartingWaypointIndex(index);
 | 
			
		||||
		SetupPath(path_string);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MovementAIComponent::HandleWaypointCommandSpawnObject(const std::string& data) {
 | 
			
		||||
	LOT newObjectLOT = 0;
 | 
			
		||||
	if (!GeneralUtils::TryParse(data, newObjectLOT)) return;
 | 
			
		||||
	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);
 | 
			
		||||
}
 | 
			
		||||
@@ -12,9 +12,9 @@
 | 
			
		||||
#include "Player.h"
 | 
			
		||||
#include "RebuildComponent.h"
 | 
			
		||||
#include "SkillComponent.h"
 | 
			
		||||
#include "MovementAIComponent.h"
 | 
			
		||||
#include "eEndBehavior.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
TriggerComponent::TriggerComponent(Entity* parent, const std::string triggerInfo): Component(parent) {
 | 
			
		||||
	m_Parent = parent;
 | 
			
		||||
	m_Trigger = nullptr;
 | 
			
		||||
@@ -69,7 +69,9 @@ void TriggerComponent::HandleTriggerCommand(LUTriggers::Command* command, Entity
 | 
			
		||||
			case eTriggerCommandType::RESET_REBUILD:
 | 
			
		||||
				HandleResetRebuild(targetEntity, command->args);
 | 
			
		||||
				break;
 | 
			
		||||
			case eTriggerCommandType::SET_PATH: break;
 | 
			
		||||
			case eTriggerCommandType::SET_PATH:
 | 
			
		||||
				HandleSetPath(targetEntity, argArray);
 | 
			
		||||
				break;
 | 
			
		||||
			case eTriggerCommandType::SET_PICK_TYPE: break;
 | 
			
		||||
			case eTriggerCommandType::MOVE_OBJECT:
 | 
			
		||||
				HandleMoveObject(targetEntity, argArray);
 | 
			
		||||
@@ -100,11 +102,21 @@ void TriggerComponent::HandleTriggerCommand(LUTriggers::Command* command, Entity
 | 
			
		||||
				break;
 | 
			
		||||
			case eTriggerCommandType::SET_BOUNCER_STATE: break;
 | 
			
		||||
			case eTriggerCommandType::BOUNCE_ALL_ON_BOUNCER: break;
 | 
			
		||||
			case eTriggerCommandType::TURN_AROUND_ON_PATH: break;
 | 
			
		||||
			case eTriggerCommandType::GO_FORWARD_ON_PATH: break;
 | 
			
		||||
			case eTriggerCommandType::GO_BACKWARD_ON_PATH: break;
 | 
			
		||||
			case eTriggerCommandType::STOP_PATHING: break;
 | 
			
		||||
			case eTriggerCommandType::START_PATHING: break;
 | 
			
		||||
			case eTriggerCommandType::TURN_AROUND_ON_PATH:
 | 
			
		||||
				HandleTurnAroundOnPath(targetEntity);
 | 
			
		||||
				break;
 | 
			
		||||
			case eTriggerCommandType::GO_FORWARD_ON_PATH:
 | 
			
		||||
				HandleGoForwardOnPath(targetEntity);
 | 
			
		||||
				break;
 | 
			
		||||
			case eTriggerCommandType::GO_BACKWARD_ON_PATH:
 | 
			
		||||
				HandleGoBackwardOnPath(targetEntity);
 | 
			
		||||
				break;
 | 
			
		||||
			case eTriggerCommandType::STOP_PATHING:
 | 
			
		||||
				HandleStopPathing(targetEntity);
 | 
			
		||||
				break;
 | 
			
		||||
			case eTriggerCommandType::START_PATHING:
 | 
			
		||||
				HandleStartPathing(targetEntity);
 | 
			
		||||
				break;
 | 
			
		||||
			case eTriggerCommandType::LOCK_OR_UNLOCK_CONTROLS: break;
 | 
			
		||||
			case eTriggerCommandType::PLAY_EFFECT:
 | 
			
		||||
				HandlePlayEffect(targetEntity, argArray);
 | 
			
		||||
@@ -213,6 +225,18 @@ void TriggerComponent::HandleResetRebuild(Entity* targetEntity, std::string args
 | 
			
		||||
	rebuildComponent->ResetRebuild(args == "1");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TriggerComponent::HandleSetPath(Entity* targetEntity, std::vector<std::string> argArray){
 | 
			
		||||
	auto* movementAIComponent = targetEntity->GetComponent<MovementAIComponent>();
 | 
			
		||||
	if (!movementAIComponent) return;
 | 
			
		||||
	movementAIComponent->SetupPath(argArray.at(0));
 | 
			
		||||
	if (argArray.size() >= 2) {
 | 
			
		||||
		int32_t index = 0;
 | 
			
		||||
		if (!GeneralUtils::TryParse(argArray.at(1), index)) return;
 | 
			
		||||
		movementAIComponent->SetPathStartingWaypointIndex(index);
 | 
			
		||||
	}
 | 
			
		||||
	if (argArray.size() >= 3 && argArray.at(2) == "1") movementAIComponent->ReversePath();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TriggerComponent::HandleMoveObject(Entity* targetEntity, std::vector<std::string> argArray){
 | 
			
		||||
	if (argArray.size() <= 2) return;
 | 
			
		||||
 | 
			
		||||
@@ -342,6 +366,36 @@ void TriggerComponent::HandleUpdateMission(Entity* targetEntity, std::vector<std
 | 
			
		||||
	missionComponent->Progress(eMissionTaskType::EXPLORE, 0, 0, argArray.at(4));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TriggerComponent::HandleTurnAroundOnPath(Entity* targetEntity){
 | 
			
		||||
	auto* movementAIComponent = targetEntity->GetComponent<MovementAIComponent>();
 | 
			
		||||
	if (!movementAIComponent) return;
 | 
			
		||||
	movementAIComponent->ReversePath();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TriggerComponent::HandleGoForwardOnPath(Entity* targetEntity){
 | 
			
		||||
	auto* movementAIComponent = targetEntity->GetComponent<MovementAIComponent>();
 | 
			
		||||
	if (!movementAIComponent) return;
 | 
			
		||||
	if (movementAIComponent->GetIsInReverse()) movementAIComponent->ReversePath();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TriggerComponent::HandleGoBackwardOnPath(Entity* targetEntity){
 | 
			
		||||
	auto* movementAIComponent = targetEntity->GetComponent<MovementAIComponent>();
 | 
			
		||||
	if (!movementAIComponent) return;
 | 
			
		||||
	if (!movementAIComponent->GetIsInReverse()) movementAIComponent->ReversePath();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TriggerComponent::HandleStopPathing(Entity* targetEntity){
 | 
			
		||||
	auto* movementAIComponent = targetEntity->GetComponent<MovementAIComponent>();
 | 
			
		||||
	if (!movementAIComponent) return;
 | 
			
		||||
	movementAIComponent->Pause();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TriggerComponent::HandleStartPathing(Entity* targetEntity){
 | 
			
		||||
	auto* movementAIComponent = targetEntity->GetComponent<MovementAIComponent>();
 | 
			
		||||
	if (!movementAIComponent) return;
 | 
			
		||||
	movementAIComponent->Resume();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TriggerComponent::HandlePlayEffect(Entity* targetEntity, std::vector<std::string> argArray) {
 | 
			
		||||
	if (argArray.size() < 3) return;
 | 
			
		||||
	int32_t effectID = 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@ private:
 | 
			
		||||
	void HandleDestroyObject(Entity* targetEntity, std::string args);
 | 
			
		||||
	void HandleToggleTrigger(Entity* targetEntity, std::string args);
 | 
			
		||||
	void HandleResetRebuild(Entity* targetEntity, std::string args);
 | 
			
		||||
	void HandleSetPath(Entity* targetEntity, std::vector<std::string> argArray);
 | 
			
		||||
	void HandleMoveObject(Entity* targetEntity, std::vector<std::string> argArray);
 | 
			
		||||
	void HandleRotateObject(Entity* targetEntity, std::vector<std::string> argArray);
 | 
			
		||||
	void HandlePushObject(Entity* targetEntity, std::vector<std::string> argArray);
 | 
			
		||||
@@ -35,6 +36,11 @@ private:
 | 
			
		||||
	void HandlePlayCinematic(Entity* targetEntity, std::vector<std::string> argArray);
 | 
			
		||||
	void HandleToggleBBB(Entity* targetEntity, std::string args);
 | 
			
		||||
	void HandleUpdateMission(Entity* targetEntity, std::vector<std::string> argArray);
 | 
			
		||||
	void HandleTurnAroundOnPath(Entity* targetEntity);
 | 
			
		||||
	void HandleGoForwardOnPath(Entity* targetEntity);
 | 
			
		||||
	void HandleGoBackwardOnPath(Entity* targetEntity);
 | 
			
		||||
	void HandleStopPathing(Entity* targetEntity);
 | 
			
		||||
	void HandleStartPathing(Entity* targetEntity);
 | 
			
		||||
	void HandlePlayEffect(Entity* targetEntity, std::vector<std::string> argArray);
 | 
			
		||||
	void HandleCastSkill(Entity* targetEntity, std::string args);
 | 
			
		||||
	void HandleSetPhysicsVolumeEffect(Entity* targetEntity, std::vector<std::string> argArray);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user