mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 10:53:44 +00:00
The ActivatePhysics trigger command was a TODO. The client activates or deactivates the object's physics component (LWOPhysicsSystemComponent::msgActivatePhysics, 1.10.64 0x00ccf970); the server now does the same to phantom physics: switching it off takes the volume out of the physics world (dpWorld::DetachEntity, without deleting it) and makes whatever was inside leave, switching it on adds it back and whatever is inside enters on the next step. This lets trigger driven volumes like the monument lasers turn on and off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
524 lines
19 KiB
C++
524 lines
19 KiB
C++
#include "TriggerComponent.h"
|
|
#include "dZoneManager.h"
|
|
#include "TeamManager.h"
|
|
#include "eTriggerCommandType.h"
|
|
#include "eMissionTaskType.h"
|
|
#include "ePhysicsEffectType.h"
|
|
|
|
#include "CharacterComponent.h"
|
|
#include "ControllablePhysicsComponent.h"
|
|
#include "MissionComponent.h"
|
|
#include "PhantomPhysicsComponent.h"
|
|
#include "QuickBuildComponent.h"
|
|
#include "SkillComponent.h"
|
|
#include "eEndBehavior.h"
|
|
#include "PlayerManager.h"
|
|
#include "Game.h"
|
|
#include "EntityManager.h"
|
|
#include "MovementAIComponent.h"
|
|
|
|
#include <glm/gtc/quaternion.hpp>
|
|
#include "EffectsMessages.h"
|
|
|
|
TriggerComponent::TriggerComponent(Entity* parent, const int32_t componentID, const std::string triggerInfo) : Component(parent, componentID) {
|
|
m_Parent = parent;
|
|
m_Trigger = nullptr;
|
|
|
|
std::vector<std::string> tokens = GeneralUtils::SplitString(triggerInfo, ':');
|
|
|
|
const auto sceneID = GeneralUtils::TryParse<uint32_t>(tokens.at(0)).value_or(0);
|
|
const auto triggerID = GeneralUtils::TryParse<uint32_t>(tokens.at(1)).value_or(0);
|
|
|
|
m_Trigger = Game::zoneManager->GetZone()->GetTrigger(sceneID, triggerID);
|
|
|
|
if (!m_Trigger) m_Trigger = new LUTriggers::Trigger();
|
|
}
|
|
|
|
void TriggerComponent::TriggerEvent(eTriggerEventType event, Entity* optionalTarget) {
|
|
if (m_Trigger && m_Trigger->enabled) {
|
|
for (LUTriggers::Event* triggerEvent : m_Trigger->events) {
|
|
if (triggerEvent->id == event) {
|
|
for (LUTriggers::Command* command : triggerEvent->commands) {
|
|
HandleTriggerCommand(command, optionalTarget);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void TriggerComponent::HandleTriggerCommand(LUTriggers::Command* command, Entity* optionalTarget) {
|
|
auto argArray = GeneralUtils::SplitString(command->args, ',');
|
|
|
|
// determine targets
|
|
std::vector<Entity*> targetEntities = GatherTargets(command, optionalTarget);
|
|
|
|
// if we have no targets, then we are done
|
|
if (targetEntities.empty()) return;
|
|
|
|
for (Entity* targetEntity : targetEntities) {
|
|
if (!targetEntity) continue;
|
|
|
|
switch (command->id) {
|
|
case eTriggerCommandType::ZONE_PLAYER: break;
|
|
case eTriggerCommandType::FIRE_EVENT:
|
|
HandleFireEvent(targetEntity, command->args);
|
|
break;
|
|
case eTriggerCommandType::DESTROY_OBJ:
|
|
HandleDestroyObject(targetEntity, command->args);
|
|
break;
|
|
case eTriggerCommandType::TOGGLE_TRIGGER:
|
|
HandleToggleTrigger(targetEntity, command->args);
|
|
break;
|
|
case eTriggerCommandType::RESET_REBUILD:
|
|
HandleResetRebuild(targetEntity, command->args);
|
|
break;
|
|
case eTriggerCommandType::SET_PATH:
|
|
HandleSetPath(targetEntity, argArray);
|
|
break;
|
|
case eTriggerCommandType::SET_PICK_TYPE: break;
|
|
case eTriggerCommandType::MOVE_OBJECT:
|
|
HandleMoveObject(targetEntity, argArray);
|
|
break;
|
|
case eTriggerCommandType::ROTATE_OBJECT:
|
|
HandleRotateObject(targetEntity, argArray);
|
|
break;
|
|
case eTriggerCommandType::PUSH_OBJECT:
|
|
HandlePushObject(targetEntity, argArray);
|
|
break;
|
|
case eTriggerCommandType::REPEL_OBJECT:
|
|
HandleRepelObject(targetEntity, command->args);
|
|
break;
|
|
case eTriggerCommandType::SET_TIMER:
|
|
HandleSetTimer(targetEntity, argArray);
|
|
break;
|
|
case eTriggerCommandType::CANCEL_TIMER:
|
|
HandleCancelTimer(targetEntity, command->args);
|
|
break;
|
|
case eTriggerCommandType::PLAY_CINEMATIC:
|
|
HandlePlayCinematic(targetEntity, argArray);
|
|
break;
|
|
case eTriggerCommandType::TOGGLE_BBB:
|
|
HandleToggleBBB(targetEntity, command->args);
|
|
break;
|
|
case eTriggerCommandType::UPDATE_MISSION:
|
|
HandleUpdateMission(targetEntity, argArray);
|
|
break;
|
|
case eTriggerCommandType::SET_BOUNCER_STATE: break;
|
|
case eTriggerCommandType::BOUNCE_ALL_ON_BOUNCER: 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);
|
|
break;
|
|
case eTriggerCommandType::STOP_EFFECT:
|
|
GameMessages::StopFXEffect(targetEntity->GetObjectID(), true, command->args).Send(UNASSIGNED_SYSTEM_ADDRESS);
|
|
break;
|
|
case eTriggerCommandType::CAST_SKILL:
|
|
HandleCastSkill(targetEntity, command->args);
|
|
break;
|
|
case eTriggerCommandType::DISPLAY_ZONE_SUMMARY:
|
|
GameMessages::SendDisplayZoneSummary(targetEntity->GetObjectID(), targetEntity->GetSystemAddress(), false, command->args == "1", m_Parent->GetObjectID());
|
|
break;
|
|
case eTriggerCommandType::SET_PHYSICS_VOLUME_EFFECT:
|
|
HandleSetPhysicsVolumeEffect(targetEntity, argArray);
|
|
break;
|
|
case eTriggerCommandType::SET_PHYSICS_VOLUME_STATUS:
|
|
HandleSetPhysicsVolumeStatus(targetEntity, command->args);
|
|
break;
|
|
case eTriggerCommandType::SET_MODEL_TO_BUILD: break;
|
|
case eTriggerCommandType::SPAWN_MODEL_BRICKS: break;
|
|
case eTriggerCommandType::ACTIVATE_SPAWNER_NETWORK:
|
|
HandleActivateSpawnerNetwork(command->args);
|
|
break;
|
|
case eTriggerCommandType::DEACTIVATE_SPAWNER_NETWORK:
|
|
HandleDeactivateSpawnerNetwork(command->args);
|
|
break;
|
|
case eTriggerCommandType::RESET_SPAWNER_NETWORK:
|
|
HandleResetSpawnerNetwork(command->args);
|
|
break;
|
|
case eTriggerCommandType::DESTROY_SPAWNER_NETWORK_OBJECTS:
|
|
HandleDestroySpawnerNetworkObjects(command->args);
|
|
break;
|
|
case eTriggerCommandType::GO_TO_WAYPOINT: break;
|
|
case eTriggerCommandType::ACTIVATE_PHYSICS:
|
|
HandleActivatePhysics(targetEntity, command->args);
|
|
break;
|
|
// DEPRECATED BLOCK START
|
|
case eTriggerCommandType::ACTIVATE_MUSIC_CUE: break;
|
|
case eTriggerCommandType::DEACTIVATE_MUSIC_CUE: break;
|
|
case eTriggerCommandType::FLASH_MUSIC_CUE: break;
|
|
case eTriggerCommandType::SET_MUSIC_PARAMETER: break;
|
|
case eTriggerCommandType::PLAY_2D_AMBIENT_SOUND: break;
|
|
case eTriggerCommandType::STOP_2D_AMBIENT_SOUND: break;
|
|
case eTriggerCommandType::PLAY_3D_AMBIENT_SOUND: break;
|
|
case eTriggerCommandType::STOP_3D_AMBIENT_SOUND: break;
|
|
case eTriggerCommandType::ACTIVATE_MIXER_PROGRAM: break;
|
|
case eTriggerCommandType::DEACTIVATE_MIXER_PROGRAM: break;
|
|
// DEPRECATED BLOCK END
|
|
default:
|
|
LOG_DEBUG("Event %i was not handled!", command->id);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
std::vector<Entity*> TriggerComponent::GatherTargets(LUTriggers::Command* command, Entity* optionalTarget) {
|
|
std::vector<Entity*> entities = {};
|
|
|
|
if (command->target == "self") entities.push_back(m_Parent);
|
|
else if (command->target == "zone") {
|
|
// The zone itself is represented by the zone control object.
|
|
auto* const zoneControl = Game::zoneManager->GetZoneControlObject();
|
|
if (zoneControl) entities.push_back(zoneControl);
|
|
} else if (command->target == "target" && optionalTarget) {
|
|
entities.push_back(optionalTarget);
|
|
} else if (command->target == "targetTeam" && optionalTarget) {
|
|
auto* team = TeamManager::Instance()->GetTeam(optionalTarget->GetObjectID());
|
|
for (const auto memberId : team->members) {
|
|
auto* member = Game::entityManager->GetEntity(memberId);
|
|
if (member) entities.push_back(member);
|
|
}
|
|
} else if (command->target == "objGroup") {
|
|
entities = Game::entityManager->GetEntitiesInGroup(command->targetName);
|
|
} else if (command->target == "allPlayers") {
|
|
for (auto* player : PlayerManager::GetAllPlayers()) {
|
|
entities.push_back(player);
|
|
}
|
|
} else if (command->target == "allNPCs") {
|
|
/*UNUSED*/
|
|
}
|
|
|
|
return entities;
|
|
}
|
|
|
|
void TriggerComponent::HandleFireEvent(Entity* targetEntity, std::string args) {
|
|
targetEntity->GetScript()->OnFireEventServerSide(targetEntity, m_Parent, args, 0, 0, 0);
|
|
}
|
|
|
|
void TriggerComponent::HandleDestroyObject(Entity* targetEntity, std::string args) {
|
|
const eKillType killType = GeneralUtils::TryParse<eKillType>(args).value_or(eKillType::VIOLENT);
|
|
targetEntity->Smash(m_Parent->GetObjectID(), killType);
|
|
}
|
|
|
|
void TriggerComponent::HandleToggleTrigger(Entity* targetEntity, std::string args) {
|
|
auto* triggerComponent = targetEntity->GetComponent<TriggerComponent>();
|
|
if (!triggerComponent) {
|
|
LOG_DEBUG("Trigger component not found!");
|
|
return;
|
|
}
|
|
triggerComponent->SetTriggerEnabled(args == "1");
|
|
}
|
|
|
|
void TriggerComponent::HandleResetRebuild(Entity* targetEntity, std::string args) {
|
|
auto* quickBuildComponent = targetEntity->GetComponent<QuickBuildComponent>();
|
|
if (!quickBuildComponent) {
|
|
LOG_DEBUG("Rebuild component not found!");
|
|
return;
|
|
}
|
|
quickBuildComponent->ResetQuickBuild(args == "1");
|
|
}
|
|
|
|
void TriggerComponent::HandleMoveObject(Entity* targetEntity, std::vector<std::string> argArray) {
|
|
if (argArray.size() <= 2) return;
|
|
|
|
NiPoint3 position = targetEntity->GetPosition();
|
|
const NiPoint3 offset = GeneralUtils::TryParse<NiPoint3>(argArray).value_or(NiPoint3Constant::ZERO);
|
|
|
|
position += offset;
|
|
targetEntity->SetPosition(position);
|
|
}
|
|
|
|
void TriggerComponent::HandleRotateObject(Entity* targetEntity, std::vector<std::string> argArray) {
|
|
if (argArray.size() <= 2) return;
|
|
|
|
const auto vector = GeneralUtils::TryParse<glm::vec3>(argArray).value_or(glm::zero<glm::vec3>());
|
|
|
|
targetEntity->SetRotation(glm::quat(vector));
|
|
}
|
|
|
|
void TriggerComponent::HandlePushObject(Entity* targetEntity, std::vector<std::string> argArray) {
|
|
if (argArray.size() < 3) return;
|
|
|
|
auto* phantomPhysicsComponent = m_Parent->GetComponent<PhantomPhysicsComponent>();
|
|
if (!phantomPhysicsComponent) {
|
|
LOG_DEBUG("Phantom Physics component not found!");
|
|
return;
|
|
}
|
|
phantomPhysicsComponent->SetPhysicsEffectActive(true);
|
|
phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::PUSH);
|
|
phantomPhysicsComponent->SetDirectionalMultiplier(1);
|
|
const NiPoint3 direction = GeneralUtils::TryParse<NiPoint3>(argArray).value_or(NiPoint3Constant::ZERO);
|
|
phantomPhysicsComponent->SetDirection(direction);
|
|
|
|
Game::entityManager->SerializeEntity(m_Parent);
|
|
}
|
|
|
|
|
|
void TriggerComponent::HandleRepelObject(Entity* targetEntity, std::string args) {
|
|
auto* phantomPhysicsComponent = m_Parent->GetComponent<PhantomPhysicsComponent>();
|
|
if (!phantomPhysicsComponent) {
|
|
LOG_DEBUG("Phantom Physics component not found!");
|
|
return;
|
|
}
|
|
const float forceMultiplier = GeneralUtils::TryParse<float>(args).value_or(1.0f);
|
|
|
|
phantomPhysicsComponent->SetPhysicsEffectActive(true);
|
|
phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::REPULSE);
|
|
phantomPhysicsComponent->SetDirectionalMultiplier(forceMultiplier);
|
|
|
|
auto triggerPos = m_Parent->GetPosition();
|
|
auto targetPos = targetEntity->GetPosition();
|
|
|
|
// normalize the vectors to get the direction
|
|
auto delta = targetPos - triggerPos;
|
|
auto length = delta.Length();
|
|
NiPoint3 direction = delta / length;
|
|
phantomPhysicsComponent->SetDirection(direction);
|
|
|
|
Game::entityManager->SerializeEntity(m_Parent);
|
|
}
|
|
|
|
void TriggerComponent::HandleSetTimer(Entity* targetEntity, std::vector<std::string> argArray) {
|
|
if (argArray.size() != 2) {
|
|
LOG_DEBUG("Not enough variables!");
|
|
return;
|
|
}
|
|
const float time = GeneralUtils::TryParse<float>(argArray.at(1)).value_or(0.0f);
|
|
m_Parent->AddTimer(argArray.at(0), time);
|
|
}
|
|
|
|
void TriggerComponent::HandleCancelTimer(Entity* targetEntity, std::string args) {
|
|
m_Parent->CancelTimer(args);
|
|
}
|
|
|
|
void TriggerComponent::HandlePlayCinematic(Entity* targetEntity, std::vector<std::string> argArray) {
|
|
float leadIn = -1.0;
|
|
auto wait = eEndBehavior::RETURN;
|
|
bool unlock = true;
|
|
bool leaveLocked = false;
|
|
bool hidePlayer = false;
|
|
|
|
if (argArray.size() >= 2) {
|
|
leadIn = GeneralUtils::TryParse<float>(argArray.at(1)).value_or(leadIn);
|
|
if (argArray.size() >= 3 && argArray.at(2) == "wait") {
|
|
wait = eEndBehavior::WAIT;
|
|
if (argArray.size() >= 4 && argArray.at(3) == "unlock") {
|
|
unlock = false;
|
|
if (argArray.size() >= 5 && argArray.at(4) == "leavelocked") {
|
|
leaveLocked = true;
|
|
if (argArray.size() >= 6 && argArray.at(5) == "hideplayer") {
|
|
hidePlayer = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GameMessages::PlayCinematic cinematic;
|
|
cinematic.target = targetEntity->GetObjectID();
|
|
cinematic.pathName = GeneralUtils::UTF8ToUTF16(argArray.at(0));
|
|
cinematic.allowGhostUpdates = true;
|
|
cinematic.bCloseMultiInteract = true;
|
|
cinematic.bSendServerNotify = false;
|
|
cinematic.bUseControlledObjectForAudioListener = false;
|
|
cinematic.endBehavior = wait;
|
|
cinematic.hidePlayerDuringCine = hidePlayer;
|
|
cinematic.leadIn = leadIn;
|
|
cinematic.leavePlayerLockedWhenFinished = leaveLocked;
|
|
cinematic.lockPlayer = unlock;
|
|
cinematic.Send(targetEntity->GetSystemAddress());
|
|
}
|
|
|
|
void TriggerComponent::HandleToggleBBB(Entity* targetEntity, std::string args) {
|
|
auto* character = targetEntity->GetCharacter();
|
|
if (!character) {
|
|
LOG_DEBUG("Character was not found!");
|
|
return;
|
|
}
|
|
bool buildMode = !(character->GetBuildMode());
|
|
if (args == "enter") buildMode = true;
|
|
else if (args == "exit") buildMode = false;
|
|
character->SetBuildMode(buildMode);
|
|
}
|
|
|
|
void TriggerComponent::HandleUpdateMission(Entity* targetEntity, std::vector<std::string> argArray) {
|
|
// there are only explore tasks used
|
|
// If others need to be implemented for modding
|
|
// then we need a good way to convert this from a string to that enum
|
|
if (argArray.at(0) != "exploretask") return;
|
|
MissionComponent* missionComponent = targetEntity->GetComponent<MissionComponent>();
|
|
if (!missionComponent) {
|
|
LOG_DEBUG("Mission component not found!");
|
|
return;
|
|
}
|
|
missionComponent->Progress(eMissionTaskType::EXPLORE, 0, 0, argArray.at(4));
|
|
}
|
|
|
|
void TriggerComponent::HandlePlayEffect(Entity* targetEntity, std::vector<std::string> argArray) {
|
|
if (argArray.size() < 3) return;
|
|
const auto effectID = GeneralUtils::TryParse<int32_t>(argArray.at(1));
|
|
if (!effectID) return;
|
|
std::u16string effectType = GeneralUtils::UTF8ToUTF16(argArray.at(2));
|
|
|
|
float priority = 1;
|
|
if (argArray.size() == 4) {
|
|
priority = GeneralUtils::TryParse<float>(argArray.at(3)).value_or(priority);
|
|
}
|
|
|
|
GameMessages::PlayFXEffect fx(targetEntity->GetObjectID(), effectID.value(), effectType, argArray.at(0));
|
|
fx.priority = priority;
|
|
fx.Send(UNASSIGNED_SYSTEM_ADDRESS);
|
|
}
|
|
|
|
void TriggerComponent::HandleCastSkill(Entity* targetEntity, std::string args) {
|
|
auto* skillComponent = targetEntity->GetComponent<SkillComponent>();
|
|
if (!skillComponent) {
|
|
LOG_DEBUG("Skill component not found!");
|
|
return;
|
|
}
|
|
const uint32_t skillId = GeneralUtils::TryParse<uint32_t>(args).value_or(0);
|
|
skillComponent->CastSkill(skillId, targetEntity->GetObjectID());
|
|
}
|
|
|
|
void TriggerComponent::HandleSetPhysicsVolumeEffect(Entity* targetEntity, std::vector<std::string> argArray) {
|
|
auto* phantomPhysicsComponent = targetEntity->GetComponent<PhantomPhysicsComponent>();
|
|
if (!phantomPhysicsComponent) {
|
|
LOG_DEBUG("Phantom Physics component not found!");
|
|
return;
|
|
}
|
|
phantomPhysicsComponent->SetPhysicsEffectActive(true);
|
|
ePhysicsEffectType effectType = ePhysicsEffectType::PUSH;
|
|
if (!argArray.empty()) {
|
|
std::transform(argArray.at(0).begin(), argArray.at(0).end(), argArray.at(0).begin(), ::tolower); //Transform to lowercase
|
|
if (argArray.at(0) == "push") effectType = ePhysicsEffectType::PUSH;
|
|
else if (argArray.at(0) == "attract") effectType = ePhysicsEffectType::ATTRACT;
|
|
else if (argArray.at(0) == "repulse") effectType = ePhysicsEffectType::REPULSE;
|
|
else if (argArray.at(0) == "gravity") effectType = ePhysicsEffectType::GRAVITY_SCALE;
|
|
else if (argArray.at(0) == "friction") effectType = ePhysicsEffectType::FRICTION;
|
|
}
|
|
|
|
phantomPhysicsComponent->SetEffectType(effectType);
|
|
if (argArray.size() > 1) {
|
|
phantomPhysicsComponent->SetDirectionalMultiplier(GeneralUtils::TryParse(argArray.at(1), 0.0f));
|
|
}
|
|
if (argArray.size() > 4) {
|
|
const NiPoint3 direction =
|
|
GeneralUtils::TryParse(argArray.at(2), argArray.at(3), argArray.at(4), NiPoint3Constant::ZERO);
|
|
|
|
phantomPhysicsComponent->SetDirection(direction);
|
|
}
|
|
if (argArray.size() > 6) {
|
|
const uint32_t min = GeneralUtils::TryParse(argArray.at(6), 0);
|
|
phantomPhysicsComponent->SetMin(min);
|
|
|
|
const uint32_t max = GeneralUtils::TryParse(argArray.at(7), 0);
|
|
phantomPhysicsComponent->SetMax(max);
|
|
}
|
|
|
|
Game::entityManager->SerializeEntity(targetEntity);
|
|
}
|
|
|
|
void TriggerComponent::HandleSetPhysicsVolumeStatus(Entity* targetEntity, std::string args) {
|
|
auto* phantomPhysicsComponent = targetEntity->GetComponent<PhantomPhysicsComponent>();
|
|
if (!phantomPhysicsComponent) {
|
|
LOG_DEBUG("Phantom Physics component not found!");
|
|
return;
|
|
}
|
|
phantomPhysicsComponent->SetPhysicsEffectActive(args == "On");
|
|
Game::entityManager->SerializeEntity(targetEntity);
|
|
}
|
|
|
|
void TriggerComponent::HandleActivateSpawnerNetwork(std::string args) {
|
|
for (auto* spawner : Game::zoneManager->GetSpawnersByName(args)) {
|
|
if (spawner) spawner->Activate();
|
|
}
|
|
}
|
|
|
|
void TriggerComponent::HandleDeactivateSpawnerNetwork(std::string args) {
|
|
for (auto* spawner : Game::zoneManager->GetSpawnersByName(args)) {
|
|
if (spawner) spawner->Deactivate();
|
|
}
|
|
}
|
|
|
|
void TriggerComponent::HandleResetSpawnerNetwork(std::string args) {
|
|
for (auto* spawner : Game::zoneManager->GetSpawnersByName(args)) {
|
|
if (spawner) spawner->Reset();
|
|
}
|
|
}
|
|
|
|
void TriggerComponent::HandleDestroySpawnerNetworkObjects(std::string args) {
|
|
for (auto* spawner : Game::zoneManager->GetSpawnersByName(args)) {
|
|
if (spawner) spawner->DestroyAllEntities();
|
|
}
|
|
}
|
|
|
|
void TriggerComponent::HandleActivatePhysics(Entity* targetEntity, std::string args) {
|
|
if (args != "true" && args != "false") {
|
|
LOG_DEBUG("Invalid argument for ActivatePhysics Trigger: %s", args.c_str());
|
|
return;
|
|
}
|
|
|
|
auto* const phantomPhysicsComponent = targetEntity->GetComponent<PhantomPhysicsComponent>();
|
|
if (!phantomPhysicsComponent) {
|
|
LOG_DEBUG("ActivatePhysics on %llu:%i which has no phantom physics", targetEntity->GetObjectID(), targetEntity->GetLOT());
|
|
return;
|
|
}
|
|
|
|
phantomPhysicsComponent->SetPhysicsActive(args == "true");
|
|
}
|
|
|
|
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) {
|
|
auto index = GeneralUtils::TryParse<int32_t>(argArray.at(1));
|
|
if (!index) return;
|
|
// movementAIComponent->SetPathStartingWaypointIndex(index.value());
|
|
}
|
|
if (argArray.size() >= 3 && argArray.at(2) == "1") {
|
|
// movementAIComponent->ReversePath();
|
|
}
|
|
}
|
|
|
|
void TriggerComponent::HandleTurnAroundOnPath(Entity* targetEntity) {
|
|
auto* movementAIComponent = targetEntity->GetComponent<MovementAIComponent>();
|
|
// if (movementAIComponent) 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) movementAIComponent->Pause();
|
|
}
|
|
|
|
void TriggerComponent::HandleStartPathing(Entity* targetEntity) {
|
|
auto* movementAIComponent = targetEntity->GetComponent<MovementAIComponent>();
|
|
// if (movementAIComponent) movementAIComponent->Resume();
|
|
}
|