Implement some more trigger event calls and command handlers (#989)

* Implement some trigger event calls
and command handlers

* add zone summary dimissed GM

* break and remove log

* some cleanup in Gather Targets
and blocking out

* fix default value of unlock for play cinematic

* Log on errors
add enum for physics effect type
simplify nipoint3 logic
check arg count
add enum for End behavior

* tryparse for nipoint3

* totally didn't forget to include it

* bleh c++ is blah

* ???

* address feedback

* Fix for #1028
This commit is contained in:
Aaron Kimbrell
2023-03-25 05:26:39 -05:00
committed by GitHub
parent 72ca0f13ff
commit c415d0520a
32 changed files with 461 additions and 152 deletions

View File

@@ -763,7 +763,7 @@ void Entity::Initialize() {
no_ghosting:
TriggerEvent(eTriggerEventType::CREATE);
TriggerEvent(eTriggerEventType::CREATE, this);
if (m_Character) {
auto* controllablePhysicsComponent = GetComponent<ControllablePhysicsComponent>();
@@ -1390,7 +1390,7 @@ void Entity::OnEmoteReceived(const int32_t emote, Entity* target) {
}
void Entity::OnUse(Entity* originator) {
TriggerEvent(eTriggerEventType::INTERACT);
TriggerEvent(eTriggerEventType::INTERACT, originator);
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) {
script->OnUse(this, originator);
@@ -1412,6 +1412,7 @@ void Entity::OnHitOrHealResult(Entity* attacker, int32_t damage) {
}
void Entity::OnHit(Entity* attacker) {
TriggerEvent(eTriggerEventType::HIT, attacker);
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) {
script->OnHit(this, attacker);
}

View File

@@ -163,6 +163,8 @@ void EntityManager::DestroyEntity(Entity* entity) {
return;
}
entity->TriggerEvent(eTriggerEventType::DESTROY, entity);
const auto id = entity->GetObjectID();
if (std::count(m_EntitiesToDelete.begin(), m_EntitiesToDelete.end(), id)) {
@@ -588,7 +590,7 @@ void EntityManager::ScheduleForKill(Entity* entity) {
SwitchComponent* switchComp = entity->GetComponent<SwitchComponent>();
if (switchComp) {
entity->TriggerEvent(eTriggerEventType::DEACTIVATED);
entity->TriggerEvent(eTriggerEventType::DEACTIVATED, entity);
}
const auto objectId = entity->GetObjectID();

View File

@@ -7,6 +7,7 @@
#include "dLogger.h"
#include "GameMessages.h"
#include <BitStream.h>
#include "eTriggerEventType.h"
BouncerComponent::BouncerComponent(Entity* parent) : Component(parent) {
m_PetEnabled = false;
@@ -46,8 +47,10 @@ void BouncerComponent::SetPetBouncerEnabled(bool value) {
EntityManager::Instance()->SerializeEntity(m_Parent);
if (value) {
m_Parent->TriggerEvent(eTriggerEventType::PET_ON_SWITCH, m_Parent);
GameMessages::SendPlayFXEffect(m_Parent->GetObjectID(), 1513, u"create", "PetOnSwitch", LWOOBJID_EMPTY, 1, 1, true);
} else {
m_Parent->TriggerEvent(eTriggerEventType::PET_OFF_SWITCH, m_Parent);
GameMessages::SendStopFXEffect(m_Parent, true, "PetOnSwitch");
}

View File

@@ -14,6 +14,7 @@
#include "EntityManager.h"
#include "ControllablePhysicsComponent.h"
#include "GameMessages.h"
#include "ePhysicsEffectType.h"
#include "CDClientManager.h"
#include "CDComponentsRegistryTable.h"
@@ -36,7 +37,7 @@ PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent) : Component(par
m_PositionInfoDirty = false;
m_IsPhysicsEffectActive = false;
m_EffectType = 0;
m_EffectType = ePhysicsEffectType::PUSH;
m_DirectionalMultiplier = 0.0f;
m_MinMax = false;
@@ -405,7 +406,7 @@ void PhantomPhysicsComponent::SetDirectionalMultiplier(float mul) {
m_EffectInfoDirty = true;
}
void PhantomPhysicsComponent::SetEffectType(uint32_t type) {
void PhantomPhysicsComponent::SetEffectType(ePhysicsEffectType type) {
m_EffectType = type;
m_EffectInfoDirty = true;
}

View File

@@ -17,6 +17,7 @@
class LDFBaseData;
class Entity;
class dpEntity;
enum class ePhysicsEffectType : uint32_t ;
/**
* Allows the creation of phantom physics for an entity: a physics object that is generally invisible but can be
@@ -103,13 +104,13 @@ public:
* Returns the effect that's currently active, defaults to 0
* @return the effect that's currently active
*/
uint32_t GetEffectType() const { return m_EffectType; }
ePhysicsEffectType GetEffectType() const { return m_EffectType; }
/**
* Sets the effect that's currently active
* @param type the effect to set
*/
void SetEffectType(uint32_t type);
void SetEffectType(ePhysicsEffectType type);
/**
* Returns the Physics entity for the component
@@ -168,7 +169,7 @@ private:
/**
* The physics effect that's currently active, defaults to 0
*/
uint32_t m_EffectType;
ePhysicsEffectType m_EffectType;
/**
* A scaling multiplier to add to the directional vector

View File

@@ -8,6 +8,7 @@
#include "CharacterComponent.h"
#include "MissionComponent.h"
#include "eMissionTaskType.h"
#include "eTriggerEventType.h"
#include "dServer.h"
#include "PacketUtils.h"
@@ -495,6 +496,8 @@ void RebuildComponent::CompleteRebuild(Entity* user) {
for (const auto& callback : m_RebuildCompleteCallbacks)
callback(user);
m_Parent->TriggerEvent(eTriggerEventType::REBUILD_COMPLETE, user);
auto* movingPlatform = m_Parent->GetComponent<MovingPlatformComponent>();
if (movingPlatform != nullptr) {
movingPlatform->OnCompleteRebuild();

View File

@@ -43,7 +43,7 @@ void SwitchComponent::EntityEnter(Entity* entity) {
}
m_Active = true;
if (!m_Parent) return;
m_Parent->TriggerEvent(eTriggerEventType::ACTIVATED);
m_Parent->TriggerEvent(eTriggerEventType::ACTIVATED, entity);
const auto grpName = m_Parent->GetVarAsString(u"grp_name");
@@ -79,7 +79,7 @@ void SwitchComponent::Update(float deltaTime) {
if (m_Timer <= 0.0f) {
m_Active = false;
if (!m_Parent) return;
m_Parent->TriggerEvent(eTriggerEventType::DEACTIVATED);
m_Parent->TriggerEvent(eTriggerEventType::DEACTIVATED, m_Parent);
const auto grpName = m_Parent->GetVarAsString(u"grp_name");

View File

@@ -1,10 +1,19 @@
#include "TriggerComponent.h"
#include "dZoneManager.h"
#include "LUTriggers.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 "CDMissionTasksTable.h"
#include "Player.h"
#include "RebuildComponent.h"
#include "SkillComponent.h"
#include "eEndBehavior.h"
TriggerComponent::TriggerComponent(Entity* parent, const std::string triggerInfo): Component(parent) {
m_Parent = parent;
@@ -51,19 +60,37 @@ void TriggerComponent::HandleTriggerCommand(LUTriggers::Command* command, Entity
case eTriggerCommandType::FIRE_EVENT:
HandleFireEvent(targetEntity, command->args);
break;
case eTriggerCommandType::DESTROY_OBJ: break;
case eTriggerCommandType::TOGGLE_TRIGGER: break;
case eTriggerCommandType::RESET_REBUILD: 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: break;
case eTriggerCommandType::SET_PICK_TYPE: break;
case eTriggerCommandType::MOVE_OBJECT: break;
case eTriggerCommandType::ROTATE_OBJECT: break;
case eTriggerCommandType::PUSH_OBJECT: break;
case eTriggerCommandType::REPEL_OBJECT: 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: break;
case eTriggerCommandType::CANCEL_TIMER: break;
case eTriggerCommandType::PLAY_CINEMATIC: break;
case eTriggerCommandType::TOGGLE_BBB: 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;
@@ -75,8 +102,43 @@ void TriggerComponent::HandleTriggerCommand(LUTriggers::Command* command, Entity
case eTriggerCommandType::STOP_PATHING: break;
case eTriggerCommandType::START_PATHING: break;
case eTriggerCommandType::LOCK_OR_UNLOCK_CONTROLS: break;
case eTriggerCommandType::PLAY_EFFECT: break;
case eTriggerCommandType::STOP_EFFECT: break;
case eTriggerCommandType::PLAY_EFFECT:
HandlePlayEffect(targetEntity, argArray);
break;
case eTriggerCommandType::STOP_EFFECT:
GameMessages::SendStopFXEffect(targetEntity, true, command->args);
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;
@@ -87,20 +149,7 @@ void TriggerComponent::HandleTriggerCommand(LUTriggers::Command* command, Entity
case eTriggerCommandType::STOP_3D_AMBIENT_SOUND: break;
case eTriggerCommandType::ACTIVATE_MIXER_PROGRAM: break;
case eTriggerCommandType::DEACTIVATE_MIXER_PROGRAM: break;
case eTriggerCommandType::CAST_SKILL: break;
case eTriggerCommandType::DISPLAY_ZONE_SUMMARY: break;
case eTriggerCommandType::SET_PHYSICS_VOLUME_EFFECT:
HandleSetPhysicsVolume(targetEntity, argArray, command->target);
break;
case eTriggerCommandType::SET_PHYSICS_VOLUME_STATUS: break;
case eTriggerCommandType::SET_MODEL_TO_BUILD: break;
case eTriggerCommandType::SPAWN_MODEL_BRICKS: break;
case eTriggerCommandType::ACTIVATE_SPAWNER_NETWORK: break;
case eTriggerCommandType::DEACTIVATE_SPAWNER_NETWORK: break;
case eTriggerCommandType::RESET_SPAWNER_NETWORK: break;
case eTriggerCommandType::DESTROY_SPAWNER_NETWORK_OBJECTS: break;
case eTriggerCommandType::GO_TO_WAYPOINT: break;
case eTriggerCommandType::ACTIVATE_PHYSICS: break;
// DEPRECATED BLOCK END
default:
Game::logger->LogDebug("TriggerComponent", "Event %i was not handled!", command->id);
break;
@@ -113,70 +162,262 @@ std::vector<Entity*> TriggerComponent::GatherTargets(LUTriggers::Command* comman
if (command->target == "self") entities.push_back(m_Parent);
else if (command->target == "zone") { /*TODO*/ }
else if (command->target == "target") { /*TODO*/ }
else if (command->target == "targetTeam") { /*TODO*/ }
else if (command->target == "objGroup") entities = EntityManager::Instance()->GetEntitiesInGroup(command->targetName);
else if (command->target == "allPlayers") { /*TODO*/ }
else if (command->target == "allNPCs") { /*TODO*/ }
if (optionalTarget) entities.push_back(optionalTarget);
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 = EntityManager::Instance()->GetEntity(memberId);
if (member) entities.push_back(member);
}
} else if (command->target == "objGroup") entities = EntityManager::Instance()->GetEntitiesInGroup(command->targetName);
else if (command->target == "allPlayers") {
for (auto* player : Player::GetAllPlayers()) {
entities.push_back(player);
}
} else if (command->target == "allNPCs") { /*UNUSED*/ }
return entities;
}
void TriggerComponent::HandleSetPhysicsVolume(Entity* targetEntity, std::vector<std::string> argArray, std::string target) {
PhantomPhysicsComponent* phanPhys = m_Parent->GetComponent<PhantomPhysicsComponent>();
if (!phanPhys) return;
phanPhys->SetPhysicsEffectActive(true);
uint32_t effectType = 0;
std::transform(argArray.at(0).begin(), argArray.at(0).end(), argArray.at(0).begin(), ::tolower); //Transform to lowercase
if (argArray.at(0) == "push") effectType = 0;
else if (argArray.at(0) == "attract") effectType = 1;
else if (argArray.at(0) == "repulse") effectType = 2;
else if (argArray.at(0) == "gravity") effectType = 3;
else if (argArray.at(0) == "friction") effectType = 4;
phanPhys->SetEffectType(effectType);
phanPhys->SetDirectionalMultiplier(std::stof(argArray.at(1)));
if (argArray.size() > 4) {
NiPoint3 direction = NiPoint3::ZERO;
GeneralUtils::TryParse<float>(argArray.at(2), direction.x);
GeneralUtils::TryParse<float>(argArray.at(3), direction.y);
GeneralUtils::TryParse<float>(argArray.at(4), direction.z);
phanPhys->SetDirection(direction);
}
if (argArray.size() > 5) {
uint32_t min;
GeneralUtils::TryParse<uint32_t>(argArray.at(6), min);
phanPhys->SetMin(min);
uint32_t max;
GeneralUtils::TryParse<uint32_t>(argArray.at(7), max);
phanPhys->SetMax(max);
}
// TODO: why is this contruct and not serialize?
if (target == "self") EntityManager::Instance()->ConstructEntity(m_Parent);
}
void TriggerComponent::HandleUpdateMission(Entity* targetEntity, std::vector<std::string> argArray) {
CDMissionTasksTable* missionTasksTable = CDClientManager::Instance().GetTable<CDMissionTasksTable>();
std::vector<CDMissionTasks> missionTasks = missionTasksTable->Query([=](CDMissionTasks entry) {
return (entry.targetGroup == argArray.at(4));
});
for (const CDMissionTasks& task : missionTasks) {
MissionComponent* missionComponent = targetEntity->GetComponent<MissionComponent>();
if (!missionComponent) continue;
missionComponent->ForceProgress(task.id, task.uid, std::stoi(argArray.at(2)));
}
}
void TriggerComponent::HandleFireEvent(Entity* targetEntity, std::string args) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(targetEntity)) {
script->OnFireEventServerSide(targetEntity, m_Parent, args, 0, 0, 0);
}
}
void TriggerComponent::HandleDestroyObject(Entity* targetEntity, std::string args){
uint32_t killType;
GeneralUtils::TryParse<uint32_t>(args, killType);
targetEntity->Smash(m_Parent->GetObjectID(), static_cast<eKillType>(killType));
}
void TriggerComponent::HandleToggleTrigger(Entity* targetEntity, std::string args){
auto* triggerComponent = targetEntity->GetComponent<TriggerComponent>();
if (!triggerComponent) {
Game::logger->Log("TriggerComponent::HandleToggleTrigger", "Trigger component not found!");
return;
}
triggerComponent->SetTriggerEnabled(args == "1");
}
void TriggerComponent::HandleResetRebuild(Entity* targetEntity, std::string args){
auto* rebuildComponent = targetEntity->GetComponent<RebuildComponent>();
if (!rebuildComponent) {
Game::logger->Log("TriggerComponent::HandleResetRebuild", "Rebuild component not found!");
return;
}
rebuildComponent->ResetRebuild(args == "1");
}
void TriggerComponent::HandleMoveObject(Entity* targetEntity, std::vector<std::string> argArray){
if (argArray.size() <= 2) return;
auto position = targetEntity->GetPosition();
NiPoint3 offset = NiPoint3::ZERO;
GeneralUtils::TryParse(argArray.at(0), argArray.at(1), argArray.at(2), offset);
position += offset;
targetEntity->SetPosition(position);
}
void TriggerComponent::HandleRotateObject(Entity* targetEntity, std::vector<std::string> argArray){
if (argArray.size() <= 2) return;
NiPoint3 vector = NiPoint3::ZERO;
GeneralUtils::TryParse(argArray.at(0), argArray.at(1), argArray.at(2), vector);
NiQuaternion rotation = NiQuaternion::FromEulerAngles(vector);
targetEntity->SetRotation(rotation);
}
void TriggerComponent::HandlePushObject(Entity* targetEntity, std::vector<std::string> argArray){
auto* phantomPhysicsComponent = m_Parent->GetComponent<PhantomPhysicsComponent>();
if (!phantomPhysicsComponent) {
Game::logger->Log("TriggerComponent::HandlePushObject", "Phantom Physics component not found!");
return;
}
phantomPhysicsComponent->SetPhysicsEffectActive(true);
phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::PUSH);
phantomPhysicsComponent->SetDirectionalMultiplier(1);
NiPoint3 direction = NiPoint3::ZERO;
GeneralUtils::TryParse(argArray.at(0), argArray.at(1), argArray.at(2), direction);
phantomPhysicsComponent->SetDirection(direction);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void TriggerComponent::HandleRepelObject(Entity* targetEntity, std::string args){
auto* phantomPhysicsComponent = m_Parent->GetComponent<PhantomPhysicsComponent>();
if (!phantomPhysicsComponent) {
Game::logger->Log("TriggerComponent::HandleRepelObject", "Phantom Physics component not found!");
return;
}
float forceMultiplier;
GeneralUtils::TryParse<float>(args, forceMultiplier);
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);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
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) {
GeneralUtils::TryParse<float>(argArray.at(1), 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::SendPlayCinematic(targetEntity->GetObjectID(), GeneralUtils::UTF8ToUTF16(argArray.at(0)), targetEntity->GetSystemAddress(), true, true, false, false, wait, hidePlayer, leadIn, leaveLocked, unlock);
}
void TriggerComponent::HandleToggleBBB(Entity* targetEntity, std::string args) {
auto* character = targetEntity->GetCharacter();
if (!character) {
Game::logger->Log("TriggerComponent::HandleToggleBBB", "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){
Game::logger->Log("TriggerComponent::HandleUpdateMission", "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;
int32_t effectID = 0;
if (!GeneralUtils::TryParse<int32_t>(argArray.at(1), effectID)) return;
std::u16string effectType = GeneralUtils::UTF8ToUTF16(argArray.at(2));
float priority = 1;
if (argArray.size() == 4) GeneralUtils::TryParse<float>(argArray.at(3), priority);
GameMessages::SendPlayFXEffect(targetEntity, effectID, effectType, argArray.at(0), LWOOBJID_EMPTY, priority);
}
void TriggerComponent::HandleCastSkill(Entity* targetEntity, std::string args){
auto* skillComponent = targetEntity->GetComponent<SkillComponent>();
if (!skillComponent) {
Game::logger->Log("TriggerComponent::HandleCastSkill", "Skill component not found!");
return;
}
uint32_t skillId;
GeneralUtils::TryParse<uint32_t>(args, skillId);
skillComponent->CastSkill(skillId, targetEntity->GetObjectID());
}
void TriggerComponent::HandleSetPhysicsVolumeEffect(Entity* targetEntity, std::vector<std::string> argArray) {
auto* phantomPhysicsComponent = targetEntity->GetComponent<PhantomPhysicsComponent>();
if (!phantomPhysicsComponent) {
Game::logger->Log("TriggerComponent::HandleSetPhysicsVolumeEffect", "Phantom Physics component not found!");
return;
}
phantomPhysicsComponent->SetPhysicsEffectActive(true);
ePhysicsEffectType effectType = ePhysicsEffectType::PUSH;
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);
phantomPhysicsComponent->SetDirectionalMultiplier(std::stof(argArray.at(1)));
if (argArray.size() > 4) {
NiPoint3 direction = NiPoint3::ZERO;
GeneralUtils::TryParse(argArray.at(2), argArray.at(3), argArray.at(4), direction);
phantomPhysicsComponent->SetDirection(direction);
}
if (argArray.size() > 5) {
uint32_t min;
GeneralUtils::TryParse<uint32_t>(argArray.at(6), min);
phantomPhysicsComponent->SetMin(min);
uint32_t max;
GeneralUtils::TryParse<uint32_t>(argArray.at(7), max);
phantomPhysicsComponent->SetMax(max);
}
EntityManager::Instance()->SerializeEntity(targetEntity);
}
void TriggerComponent::HandleSetPhysicsVolumeStatus(Entity* targetEntity, std::string args) {
auto* phantomPhysicsComponent = targetEntity->GetComponent<PhantomPhysicsComponent>();
if (!phantomPhysicsComponent) {
Game::logger->Log("TriggerComponent::HandleSetPhysicsVolumeEffect", "Phantom Physics component not found!");
return;
}
phantomPhysicsComponent->SetPhysicsEffectActive(args == "On");
EntityManager::Instance()->SerializeEntity(targetEntity);
}
void TriggerComponent::HandleActivateSpawnerNetwork(std::string args){
for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) {
if (spawner) spawner->Activate();
}
}
void TriggerComponent::HandleDeactivateSpawnerNetwork(std::string args){
for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) {
if (spawner) spawner->Deactivate();
}
}
void TriggerComponent::HandleResetSpawnerNetwork(std::string args){
for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) {
if (spawner) spawner->Reset();
}
}
void TriggerComponent::HandleDestroySpawnerNetworkObjects(std::string args){
for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) {
if (spawner) spawner->DestroyAllEntities();
}
}
void TriggerComponent::HandleActivatePhysics(Entity* targetEntity, std::string args) {
if (args == "true") {
// TODO add physics entity if there isn't one
} else if (args == "false"){
// TODO remove Phsyics entity if there is one
} else {
Game::logger->LogDebug("TriggerComponent", "Invalid argument for ActivatePhysics Trigger: %s", args.c_str());
}
}

View File

@@ -2,13 +2,9 @@
#define __TRIGGERCOMPONENT__H__
#include "Component.h"
#include "LUTriggers.h"
#include "eReplicaComponentType.h"
namespace LUTriggers {
struct Trigger;
struct Command;
};
class TriggerComponent : public Component {
public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::TRIGGER;
@@ -17,18 +13,35 @@ public:
void TriggerEvent(eTriggerEventType event, Entity* optionalTarget = nullptr);
LUTriggers::Trigger* GetTrigger() const { return m_Trigger; }
void SetTriggerEnabled(bool enabled){ m_Trigger->enabled = enabled; };
private:
void HandleTriggerCommand(LUTriggers::Command* command, Entity* optionalTarget);
std::vector<std::string> ParseArgs(std::string args);
std::vector<Entity*> GatherTargets(LUTriggers::Command* command, Entity* optionalTarget);
// Trigger Event Handlers
void HandleSetPhysicsVolume(Entity* targetEntity, std::vector<std::string> argArray, std::string target);
void HandleUpdateMission(Entity* targetEntity, std::vector<std::string> argArray);
void HandleFireEvent(Entity* targetEntity, std::string args);
void HandleCastSkill(Entity* targetEntity, uint32_t skillID);
void HandleDestroyObject(Entity* targetEntity, std::string args);
void HandleToggleTrigger(Entity* targetEntity, std::string args);
void HandleResetRebuild(Entity* targetEntity, std::string args);
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);
void HandleRepelObject(Entity* targetEntity, std::string args);
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 HandlePlayEffect(Entity* targetEntity, std::vector<std::string> argArray);
void HandleCastSkill(Entity* targetEntity, std::string args);
void HandleSetPhysicsVolumeEffect(Entity* targetEntity, std::vector<std::string> argArray);
void HandleSetPhysicsVolumeStatus(Entity* targetEntity, std::string args);
void HandleActivateSpawnerNetwork(std::string args);
void HandleDeactivateSpawnerNetwork(std::string args);
void HandleResetSpawnerNetwork(std::string args);
void HandleDestroySpawnerNetworkObjects(std::string args);
void HandleActivatePhysics(Entity* targetEntity, std::string args);
LUTriggers::Trigger* m_Trigger;
};

View File

@@ -673,6 +673,9 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
case GAME_MSG_ACTIVATE_BUBBLE_BUFF:
GameMessages::HandleActivateBubbleBuff(inStream, entity);
break;
case GAME_MSG_ZONE_SUMMARY_DISMISSED:
GameMessages::HandleZoneSummaryDismissed(inStream, entity);
break;
default:
// Game::logger->Log("GameMessageHandler", "Unknown game message ID: %i", messageID);
break;

View File

@@ -34,6 +34,7 @@
#include "eRacingTaskParam.h"
#include "eMissionTaskType.h"
#include "eMissionState.h"
#include "eTriggerEventType.h"
#include <sstream>
#include <future>
@@ -2813,7 +2814,7 @@ void GameMessages::HandleSetConsumableItem(RakNet::BitStream* inStream, Entity*
void GameMessages::SendPlayCinematic(LWOOBJID objectId, std::u16string pathName, const SystemAddress& sysAddr,
bool allowGhostUpdates, bool bCloseMultiInteract, bool bSendServerNotify, bool bUseControlledObjectForAudioListener,
int endBehavior, bool hidePlayerDuringCine, float leadIn, bool leavePlayerLockedWhenFinished,
eEndBehavior endBehavior, bool hidePlayerDuringCine, float leadIn, bool leavePlayerLockedWhenFinished,
bool lockPlayer, bool result, bool skipIfSamePath, float startTimeAdvance) {
CBITSTREAM;
CMSGHEADER;
@@ -2826,8 +2827,8 @@ void GameMessages::SendPlayCinematic(LWOOBJID objectId, std::u16string pathName,
bitStream.Write(bSendServerNotify);
bitStream.Write(bUseControlledObjectForAudioListener);
bitStream.Write(endBehavior != 0);
if (endBehavior != 0) bitStream.Write(endBehavior);
bitStream.Write(endBehavior != eEndBehavior::RETURN);
if (endBehavior != eEndBehavior::RETURN) bitStream.Write(endBehavior);
bitStream.Write(hidePlayerDuringCine);
@@ -6155,6 +6156,13 @@ void GameMessages::SendDeactivateBubbleBuffFromServer(LWOOBJID objectId, const S
SEND_PACKET;
}
void GameMessages::HandleZoneSummaryDismissed(RakNet::BitStream* inStream, Entity* entity) {
LWOOBJID player_id;
inStream->Read<LWOOBJID>(player_id);
auto target = EntityManager::Instance()->GetEntity(player_id);
entity->TriggerEvent(eTriggerEventType::ZONE_SUMMARY_DISMISSED, target);
};
void GameMessages::SendSetNamebillboardState(const SystemAddress& sysAddr, LWOOBJID objectId) {
CBITSTREAM;
CMSGHEADER;

View File

@@ -7,6 +7,7 @@
#include <vector>
#include "eMovementPlatformState.h"
#include "NiPoint3.h"
#include "eEndBehavior.h"
class AMFValue;
class Entity;
@@ -266,7 +267,7 @@ namespace GameMessages {
void SendPlayCinematic(LWOOBJID objectId, std::u16string pathName, const SystemAddress& sysAddr,
bool allowGhostUpdates = true, bool bCloseMultiInteract = true, bool bSendServerNotify = false, bool bUseControlledObjectForAudioListener = false,
int endBehavior = 0, bool hidePlayerDuringCine = false, float leadIn = -1, bool leavePlayerLockedWhenFinished = false,
eEndBehavior endBehavior = eEndBehavior::RETURN, bool hidePlayerDuringCine = false, float leadIn = -1, bool leavePlayerLockedWhenFinished = false,
bool lockPlayer = true, bool result = false, bool skipIfSamePath = false, float startTimeAdvance = 0);
void SendEndCinematic(LWOOBJID objectID, std::u16string pathName, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS,
@@ -633,6 +634,8 @@ namespace GameMessages {
void SendActivateBubbleBuffFromServer(LWOOBJID objectId, const SystemAddress& sysAddr);
void SendDeactivateBubbleBuffFromServer(LWOOBJID objectId, const SystemAddress& sysAddr);
void HandleZoneSummaryDismissed(RakNet::BitStream* inStream, Entity* entity);
};
#endif // GAMEMESSAGES_H

View File

@@ -2018,7 +2018,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
auto* phantomPhysicsComponent = closest->GetComponent<PhantomPhysicsComponent>();
if (phantomPhysicsComponent != nullptr) {
ChatPackets::SendSystemMessage(sysAddr, u"Type: " + (GeneralUtils::to_u16string(phantomPhysicsComponent->GetEffectType())));
ChatPackets::SendSystemMessage(sysAddr, u"Type: " + (GeneralUtils::to_u16string(static_cast<uint32_t>(phantomPhysicsComponent->GetEffectType()))));
const auto dir = phantomPhysicsComponent->GetDirection();
ChatPackets::SendSystemMessage(sysAddr, u"Direction: <" + (GeneralUtils::to_u16string(dir.x)) + u", " + (GeneralUtils::to_u16string(dir.y)) + u", " + (GeneralUtils::to_u16string(dir.z)) + u">");
ChatPackets::SendSystemMessage(sysAddr, u"Multiplier: " + (GeneralUtils::to_u16string(phantomPhysicsComponent->GetDirectionalMultiplier())));