mirror of
https://github.com/Squareville/wonderland-server.git
synced 2026-01-15 10:44:50 -06:00
118 lines
4.5 KiB
C++
118 lines
4.5 KiB
C++
#include "NpFelix.h"
|
|
#include "Entity.h"
|
|
#include "Character.h"
|
|
#include "eMissionState.h"
|
|
#include "MissionComponent.h"
|
|
#include "eTerminateType.h"
|
|
#include "RenderComponent.h"
|
|
#include "eStateChangeType.h"
|
|
#include "Amf3.h"
|
|
#include <ranges>
|
|
|
|
void NpFelix::OnStartup(Entity* self) {
|
|
// Already initialized for a given lot or is not a lot we need to set this up for
|
|
if (m_TeleportArgs.contains(self->GetLOT()) || !m_SceneLotMap.contains(self->GetLOT())) return;
|
|
auto& teleportArgs = m_TeleportArgs[self->GetLOT()];
|
|
|
|
teleportArgs.Insert("strIdentifier", "FastTravel");
|
|
teleportArgs.Insert("title", "%[UI_CHOICE_DESTINATION]");
|
|
|
|
auto& choiceOptions = *teleportArgs.InsertArray("options");
|
|
// insert the scene image into the map
|
|
for (const auto& [secondLot, sceneId] : m_SceneLotMap) {
|
|
// Skip this object
|
|
if (secondLot == self->GetLOT()) continue;
|
|
|
|
auto& sceneArgs = *choiceOptions.PushArray();
|
|
const auto sceneIdStr = std::to_string(sceneId);
|
|
sceneArgs.Insert("image", "textures/ui/zone_thumnails/np_scene" + sceneIdStr + ".dds");
|
|
sceneArgs.Insert("caption", "%[UI_CHOICE_FELIX_SCENE" + sceneIdStr + "]");
|
|
sceneArgs.Insert("identifier", "felix" + sceneIdStr + "spawn");
|
|
sceneArgs.Insert("tooltipText", "%[UI_CHOICE_FELIX_SCENE" + sceneIdStr + "_HOVER]");
|
|
}
|
|
}
|
|
|
|
void DoStun(const Entity& player, const eStateChangeType state) {
|
|
GameMessages::SendSetStunned(player.GetObjectID(), state, player.GetSystemAddress(), LWOOBJID_EMPTY,
|
|
/* bCantAttack */ true,
|
|
/* bCantEquip */ true,
|
|
/* bCantInteract */ true,
|
|
/* bCantJump */ true,
|
|
/* bCantMove */ true,
|
|
/* bCantTurn */ true,
|
|
/* bCantUseItem */ true,
|
|
/* bDontTerminateInteract */ true,
|
|
/* bIgnoreImmunity */ true
|
|
);
|
|
}
|
|
|
|
void UnstunPlayer(const Entity& player) {
|
|
DoStun(player, eStateChangeType::POP);
|
|
}
|
|
|
|
void StunPlayer(const Entity& player) {
|
|
DoStun(player, eStateChangeType::PUSH);
|
|
}
|
|
|
|
void NpFelix::OnUse(Entity* self, Entity* player) {
|
|
if (!player || !m_TeleportArgs.contains(self->GetLOT())) return;
|
|
auto& teleportArgs = m_TeleportArgs[self->GetLOT()];
|
|
teleportArgs.Insert("callbackClient", std::to_string(self->GetObjectID()));
|
|
|
|
// check if the player has completed the mission
|
|
auto missionComponent = player->GetComponent<MissionComponent>();
|
|
if (!missionComponent) return;
|
|
if (missionComponent->GetMissionState(m_MissionId) != eMissionState::COMPLETE) return;
|
|
|
|
GameMessages::SendUIMessageServerToSingleClient(player, player->GetSystemAddress(), "QueueChoiceBox", teleportArgs);
|
|
|
|
StunPlayer(*player);
|
|
}
|
|
|
|
void NpFelix::OnMessageBoxResponse(Entity* self, Entity* sender, int32_t button, const std::u16string& identifier, const std::u16string& userData) {
|
|
if (!m_TeleportArgs.contains(self->GetLOT()) || !m_SceneLotMap.contains(self->GetLOT()) || !sender) return;
|
|
|
|
if (button != 1) {
|
|
GameMessages::SendTerminateInteraction(sender->GetObjectID(), eTerminateType::FROM_INTERACTION, sender->GetObjectID());
|
|
UnstunPlayer(*sender);
|
|
} else {
|
|
const auto& teleportArgs = m_TeleportArgs.find(self->GetLOT())->second;
|
|
const auto senderObjId = sender->GetObjectID();
|
|
const auto senderSysAddr = sender->GetSystemAddress();
|
|
const auto identifierAsStr = GeneralUtils::UTF16ToWTF8(identifier);
|
|
|
|
auto time = RenderComponent::PlayAnimation(sender, "felix-teleport") + 1.0f;
|
|
GameMessages::SendPlayFXEffect(senderObjId, 20158, u"felix-teleport", "");
|
|
sender->AddCallbackTimer(time, [sender, senderObjId, senderSysAddr, identifierAsStr]() {
|
|
auto felixSpawn = Game::entityManager->GetEntitiesInGroup(identifierAsStr);
|
|
if (felixSpawn.empty()) return;
|
|
|
|
const auto felixEntity = felixSpawn[0];
|
|
if (!felixEntity) return;
|
|
|
|
const auto newPos = felixEntity->GetPosition();
|
|
const auto newRot = felixEntity->GetRotation();
|
|
GameMessages::SendTeleport(senderObjId, newPos, newRot, senderSysAddr, true);
|
|
if (!sender) return;
|
|
|
|
const auto time = RenderComponent::PlayAnimation(sender, "tube-resurrect");
|
|
sender->AddCallbackTimer(time, [sender]() {
|
|
if (!sender) return;
|
|
UnstunPlayer(*sender);
|
|
});
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
void NpFelix::OnChoiceBoxResponse(Entity* self, Entity* sender, int32_t button, const std::u16string& buttonIdentifier, const std::u16string& identifier) {
|
|
if (!sender) return;
|
|
|
|
if (button != -1) {
|
|
GameMessages::SendDisplayMessageBox(sender->GetObjectID(), true, self->GetObjectID(), buttonIdentifier, 0, u"%[UI_CHOICE_FELIX_CONFIRM]", u"", sender->GetSystemAddress());
|
|
} else {
|
|
GameMessages::SendTerminateInteraction(sender->GetObjectID(), eTerminateType::FROM_INTERACTION, self->GetObjectID());
|
|
UnstunPlayer(*sender);
|
|
}
|
|
}
|