#include #include "RailActivatorComponent.h" #include "CDClientManager.h" #include "CDRailActivatorComponent.h" #include "Entity.h" #include "GameMessages.h" #include "RebuildComponent.h" #include "Game.h" #include "dLogger.h" RailActivatorComponent::RailActivatorComponent(Entity* parent, int32_t componentID) : Component(parent) { m_ComponentID = componentID; const auto tableData = CDClientManager::Instance().GetTable()->GetEntryByID(componentID);; m_Path = parent->GetVar(u"rail_path"); m_PathDirection = parent->GetVar(u"rail_path_direction"); m_PathStart = parent->GetVar(u"rail_path_start"); m_StartSound = tableData.startSound; m_loopSound = tableData.loopSound; m_StopSound = tableData.stopSound; m_StartAnimation = tableData.startAnimation; m_LoopAnimation = tableData.loopAnimation; m_StopAnimation = tableData.stopAnimation; m_StartEffect = tableData.startEffectID; m_LoopEffect = tableData.loopEffectID; m_StopEffect = tableData.stopEffectID; m_DamageImmune = parent->GetVar(u"rail_activator_damage_immune"); m_NoAggro = parent->GetVar(u"rail_no_aggro"); m_NotifyArrived = parent->GetVar(u"rail_notify_activator_arrived"); m_ShowNameBillboard = parent->GetVar(u"rail_show_name_billboard"); m_UseDB = parent->GetVar(u"rail_use_db"); m_CameraLocked = tableData.cameraLocked; m_CollisionEnabled = tableData.playerCollision; } RailActivatorComponent::~RailActivatorComponent() = default; void RailActivatorComponent::OnUse(Entity* originator) { auto* rebuildComponent = m_Parent->GetComponent(); if (rebuildComponent != nullptr && rebuildComponent->GetState() != REBUILD_COMPLETED) return; if (rebuildComponent != nullptr) { // Don't want it to be destroyed while a player is using it rebuildComponent->SetResetTime(rebuildComponent->GetResetTime() + 10.0f); } m_EntitiesOnRail.push_back(originator->GetObjectID()); // Start the initial effects if (!m_StartEffect.second.empty()) { GameMessages::SendPlayFXEffect(originator->GetObjectID(), m_StartEffect.first, m_StartEffect.second, std::to_string(m_StartEffect.first)); } if (!m_StartAnimation.empty()) { GameMessages::SendPlayAnimation(originator, m_StartAnimation); } float animationLength; if (m_StartAnimation == u"whirlwind-rail-up-earth") { animationLength = 1.5f; } else if (m_StartAnimation == u"whirlwind-rail-up-lightning") { animationLength = 0.5f; } else if (m_StartAnimation == u"whirlwind-rail-up-ice") { animationLength = 0.5f; } else if (m_StartAnimation == u"whirlwind-rail-up-fire") { animationLength = 0.5f; } else { animationLength = 0.5f; } const auto originatorID = originator->GetObjectID(); m_Parent->AddCallbackTimer(animationLength, [originatorID, this]() { auto* originator = EntityManager::Instance()->GetEntity(originatorID); if (originator == nullptr) { return; } GameMessages::SendStartRailMovement(originator->GetObjectID(), m_Path, m_StartSound, m_loopSound, m_StopSound, originator->GetSystemAddress(), m_PathStart, m_PathDirection, m_DamageImmune, m_NoAggro, m_NotifyArrived, m_ShowNameBillboard, m_CameraLocked, m_CollisionEnabled, m_UseDB, m_ComponentID, m_Parent->GetObjectID()); }); } void RailActivatorComponent::OnRailMovementReady(Entity* originator) const { // Stun the originator GameMessages::SendSetStunned(originator->GetObjectID(), eStateChangeType::PUSH, originator->GetSystemAddress(), LWOOBJID_EMPTY, true, true, true, true, true, true, true ); if (std::find(m_EntitiesOnRail.begin(), m_EntitiesOnRail.end(), originator->GetObjectID()) != m_EntitiesOnRail.end()) { // Stop the initial effects if (!m_StartEffect.second.empty()) { GameMessages::SendStopFXEffect(originator, false, std::to_string(m_StartEffect.first)); } // Start the looping effects if (!m_LoopEffect.second.empty()) { GameMessages::SendPlayFXEffect(originator->GetObjectID(), m_LoopEffect.first, m_LoopEffect.second, std::to_string(m_LoopEffect.first)); } if (!m_LoopAnimation.empty()) { GameMessages::SendPlayAnimation(originator, m_LoopAnimation); } GameMessages::SendSetRailMovement(originator->GetObjectID(), m_PathDirection, m_Path, m_PathStart, originator->GetSystemAddress(), m_ComponentID, m_Parent->GetObjectID()); } } void RailActivatorComponent::OnCancelRailMovement(Entity* originator) { // Remove the stun from the originator GameMessages::SendSetStunned(originator->GetObjectID(), eStateChangeType::POP, originator->GetSystemAddress(), LWOOBJID_EMPTY, true, true, true, true, true, true, true ); auto* rebuildComponent = m_Parent->GetComponent(); if (rebuildComponent != nullptr) { // Set back reset time rebuildComponent->SetResetTime(rebuildComponent->GetResetTime() - 10.0f); } if (std::find(m_EntitiesOnRail.begin(), m_EntitiesOnRail.end(), originator->GetObjectID()) != m_EntitiesOnRail.end()) { // Stop the looping effects if (!m_LoopEffect.second.empty()) { GameMessages::SendStopFXEffect(originator, false, std::to_string(m_LoopEffect.first)); } // Start the end effects if (!m_StopEffect.second.empty()) { GameMessages::SendPlayFXEffect(originator->GetObjectID(), m_StopEffect.first, m_StopEffect.second, std::to_string(m_StopEffect.first)); } if (!m_StopAnimation.empty()) { GameMessages::SendPlayAnimation(originator, m_StopAnimation); } // Remove the player after they've signalled they're done railing m_EntitiesOnRail.erase(std::remove(m_EntitiesOnRail.begin(), m_EntitiesOnRail.end(), originator->GetObjectID()), m_EntitiesOnRail.end()); } }