mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-11-14 15:57:13 +00:00
The script (with L_BASE_SWITCH_ACTIVATED_SERVER) asks the switches in the platform's switchGroup to tell it when they are activated and deactivated, and sends the platform to waypoint 1 on the one and back to waypoint 0 on the other. The NJ monastery's ice and lightning attic platforms (LOTs 14539 and 14376) run it. A switch can now be asked for that (SwitchComponent:: AddActivationCallback). Where live's switch tells its group that it has loaded, the platform here looks for its switches again each second until it has found one. The script was on the list of scripts left out, with a note that its platform does not exist; it is taken off the list. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
172 lines
4.6 KiB
C++
172 lines
4.6 KiB
C++
#include "SwitchComponent.h"
|
|
#include "ObjectMessages.h"
|
|
#include "EntityManager.h"
|
|
#include "eTriggerEventType.h"
|
|
#include "RenderComponent.h"
|
|
#include "DestroyableComponent.h"
|
|
#include "EffectsMessages.h"
|
|
|
|
std::vector<SwitchComponent*> SwitchComponent::petSwitches;
|
|
|
|
SwitchComponent::SwitchComponent(Entity* parent, const int32_t componentID) : Component(parent, componentID) {
|
|
RegisterMsg(&SwitchComponent::OnRequestUse);
|
|
m_Active = false;
|
|
|
|
m_QuickBuild = m_Parent->GetComponent<QuickBuildComponent>();
|
|
}
|
|
|
|
// The level config: the reset time and the factions this responds to
|
|
void SwitchComponent::LoadConfigData() {
|
|
m_ResetTime = m_Parent->GetVarAs<int32_t>(u"switch_reset_time");
|
|
|
|
|
|
const auto factions = GeneralUtils::SplitString(m_Parent->GetVar<std::u16string>(u"respond_to_faction"), u':');
|
|
for (const auto& faction : factions) {
|
|
auto factionID = GeneralUtils::TryParse<int32_t>(GeneralUtils::UTF16ToWTF8(faction));
|
|
if (!factionID) continue;
|
|
m_FactionsToRespondTo.push_back(factionID.value());
|
|
}
|
|
}
|
|
|
|
SwitchComponent::~SwitchComponent() {
|
|
const auto& iterator = std::find(petSwitches.begin(), petSwitches.end(), this);
|
|
|
|
if (iterator != petSwitches.end()) {
|
|
petSwitches.erase(iterator);
|
|
}
|
|
}
|
|
|
|
void SwitchComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
|
outBitStream.Write(m_Active);
|
|
}
|
|
|
|
void SwitchComponent::EnterIfResponding(Entity* originator) {
|
|
const auto* const destroyableComponent = originator->GetComponent<DestroyableComponent>();
|
|
if (!destroyableComponent) return;
|
|
for (const auto faction : m_FactionsToRespondTo) {
|
|
if (destroyableComponent->HasFaction(faction)) {
|
|
EntityEnter(originator);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool SwitchComponent::OnRequestUse(GameMessages::RequestUseEvent& event) {
|
|
if (event.msg.IsMissionChoice()) return false;
|
|
EnterIfResponding(event.user);
|
|
return true;
|
|
}
|
|
|
|
void SwitchComponent::SetActive(bool active) {
|
|
m_Active = active;
|
|
|
|
if (m_PetBouncer != nullptr) {
|
|
m_PetBouncer->SetPetBouncerEnabled(active);
|
|
}
|
|
}
|
|
|
|
bool SwitchComponent::GetActive() const {
|
|
return m_Active;
|
|
}
|
|
|
|
void SwitchComponent::EntityEnter(Entity* entity) {
|
|
if (!m_Active) {
|
|
if (m_QuickBuild) {
|
|
if (m_QuickBuild->GetState() != eQuickBuildState::COMPLETED) return;
|
|
}
|
|
m_Active = true;
|
|
if (!m_Parent) return;
|
|
m_Parent->TriggerEvent(eTriggerEventType::ACTIVATED, entity);
|
|
for (const auto& callback : std::vector(m_ActivationCallbacks)) callback(true);
|
|
|
|
const auto grpName = m_Parent->GetVarAsString(u"grp_name");
|
|
|
|
if (!grpName.empty()) {
|
|
const auto entities = Game::entityManager->GetEntitiesInGroup(grpName);
|
|
|
|
for (auto* entity : entities) {
|
|
entity->OnFireEventServerSide(entity, "OnActivated");
|
|
}
|
|
}
|
|
|
|
m_Timer = m_ResetTime;
|
|
|
|
if (m_PetBouncer != nullptr) {
|
|
GameMessages::PlayFXEffect(m_Parent->GetObjectID(), 2602, u"pettriggeractive", "BounceEffect").Send(UNASSIGNED_SYSTEM_ADDRESS);
|
|
// Live played "launch" here; "engaged" is played when a pet arrives on the switch
|
|
RenderComponent::PlayAnimation(m_Parent, u"launch");
|
|
m_PetBouncer->SetPetBouncerEnabled(true);
|
|
} else {
|
|
Game::entityManager->SerializeEntity(m_Parent);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
void SwitchComponent::EntityLeave(Entity* entity) {
|
|
|
|
}
|
|
|
|
void SwitchComponent::Run(float deltaTime) {
|
|
if (m_Active) {
|
|
m_Timer -= deltaTime;
|
|
|
|
if (m_Timer <= 0.0f) {
|
|
m_Active = false;
|
|
if (!m_Parent) return;
|
|
m_Parent->TriggerEvent(eTriggerEventType::DEACTIVATED, m_Parent);
|
|
for (const auto& callback : std::vector(m_ActivationCallbacks)) callback(false);
|
|
|
|
const auto grpName = m_Parent->GetVarAsString(u"grp_name");
|
|
|
|
if (!grpName.empty()) {
|
|
const auto entities = Game::entityManager->GetEntitiesInGroup(grpName);
|
|
|
|
for (auto* entity : entities) {
|
|
entity->OnFireEventServerSide(entity, "OnDectivated");
|
|
}
|
|
}
|
|
|
|
if (m_PetBouncer != nullptr) {
|
|
m_PetBouncer->SetPetBouncerEnabled(false);
|
|
} else {
|
|
Game::entityManager->SerializeEntity(m_Parent);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Entity* SwitchComponent::GetParentEntity() const {
|
|
return m_Parent;
|
|
}
|
|
|
|
SwitchComponent* SwitchComponent::GetClosestSwitch(NiPoint3 position) {
|
|
float closestDistance = 0;
|
|
SwitchComponent* closest = nullptr;
|
|
|
|
for (SwitchComponent* petSwitch : petSwitches) {
|
|
float distance = Vector3::DistanceSquared(petSwitch->m_Parent->GetPosition(), position);
|
|
|
|
if (closest == nullptr || distance < closestDistance) {
|
|
closestDistance = distance;
|
|
closest = petSwitch;
|
|
}
|
|
}
|
|
|
|
return closest;
|
|
}
|
|
|
|
|
|
void SwitchComponent::SetPetBouncer(BouncerComponent* value) {
|
|
m_PetBouncer = value;
|
|
|
|
if (value != nullptr) {
|
|
m_PetBouncer->SetPetEnabled(true);
|
|
petSwitches.push_back(this);
|
|
}
|
|
}
|
|
|
|
BouncerComponent* SwitchComponent::GetPetBouncer() const {
|
|
return m_PetBouncer;
|
|
}
|