DarkflameServer/dGame/dComponents/RailActivatorComponent.cpp
2023-07-11 00:23:27 -07:00

143 lines
5.4 KiB
C++

#include <algorithm>
#include "RailActivatorComponent.h"
#include "CDClientManager.h"
#include "CDRailActivatorComponent.h"
#include "Entity.h"
#include "GameMessages.h"
#include "QuickBuildComponent.h"
#include "Game.h"
#include "dLogger.h"
#include "RenderComponent.h"
#include "EntityManager.h"
#include "eStateChangeType.h"
RailActivatorComponent::RailActivatorComponent(Entity* parent, int32_t componentID) : Component(parent) {
m_ComponentID = componentID;
}
void RailActivatorComponent::LoadConfigData() {
m_Path = m_ParentEntity->GetVar<std::u16string>(u"rail_path");
m_PathDirection = m_ParentEntity->GetVar<bool>(u"rail_path_direction");
m_PathStart = m_ParentEntity->GetVar<uint32_t>(u"rail_path_start");
m_DamageImmune = m_ParentEntity->GetVar<bool>(u"rail_activator_damage_immune");
m_NoAggro = m_ParentEntity->GetVar<bool>(u"rail_no_aggro");
m_NotifyArrived = m_ParentEntity->GetVar<bool>(u"rail_notify_activator_arrived");
m_ShowNameBillboard = m_ParentEntity->GetVar<bool>(u"rail_show_name_billboard");
m_UseDB = m_ParentEntity->GetVar<bool>(u"rail_use_db");
}
void RailActivatorComponent::LoadTemplateData() {
const auto tableData = CDClientManager::Instance().GetTable<CDRailActivatorComponentTable>()->GetEntryByID(m_ComponentID);
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_CameraLocked = tableData.cameraLocked;
m_CollisionEnabled = tableData.playerCollision;
}
void RailActivatorComponent::OnUse(Entity* originator) {
auto* quickBuildComponent = m_ParentEntity->GetComponent<QuickBuildComponent>();
if (quickBuildComponent && quickBuildComponent->GetState() != eRebuildState::COMPLETED) return;
// Don't want it to be destroyed while a player is using it
if (quickBuildComponent) {
quickBuildComponent->SetResetTime(quickBuildComponent->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));
}
float animationLength = 0.5f;
if (!m_StartAnimation.empty()) {
animationLength = RenderComponent::PlayAnimation(originator, m_StartAnimation);
}
const auto originatorID = originator->GetObjectID();
m_ParentEntity->AddCallbackTimer(animationLength, [originatorID, this]() {
auto* originator = EntityManager::Instance()->GetEntity(originatorID);
if (!originator) 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_ParentEntity->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()) return;
// 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()) {
RenderComponent::PlayAnimation(originator, m_LoopAnimation);
}
GameMessages::SendSetRailMovement(originator->GetObjectID(), m_PathDirection, m_Path, m_PathStart,
originator->GetSystemAddress(), m_ComponentID,
m_ParentEntity->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* quickBuildComponent = m_ParentEntity->GetComponent<QuickBuildComponent>();
// Set back reset time
if (quickBuildComponent) {
quickBuildComponent->SetResetTime(quickBuildComponent->GetResetTime() - 10.0f);
}
if (std::find(m_EntitiesOnRail.begin(), m_EntitiesOnRail.end(), originator->GetObjectID()) == m_EntitiesOnRail.end()) return;
// 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()) {
RenderComponent::PlayAnimation(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());
}