diff --git a/dGame/UserManager.cpp b/dGame/UserManager.cpp index 8579d882..1a7aef5e 100644 --- a/dGame/UserManager.cpp +++ b/dGame/UserManager.cpp @@ -29,6 +29,7 @@ #include "eChatMessageType.h" #include "BitStreamUtils.h" #include "CheatDetection.h" +#include "dConfig.h" UserManager* UserManager::m_Address = nullptr; @@ -516,7 +517,14 @@ void UserManager::LoginCharacter(const SystemAddress& sysAddr, uint32_t playerID Database::Get()->UpdateLastLoggedInCharacter(playerID); uint32_t zoneID = character->GetZoneID(); - if (zoneID == LWOZONEID_INVALID) zoneID = 1000; //Send char to VE + if (zoneID == LWOZONEID_INVALID) { + const std::string& defaultWorld = Game::config->GetValue("default_world"); + if (!defaultWorld.empty()) { + zoneID = std::stoul(defaultWorld); + } else { + zoneID = 1000; //Send char to VE + } + } ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, zoneID, character->GetZoneClone(), false, [=](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) { LOG("Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i", character->GetName().c_str(), zoneID, zoneInstance, zoneClone, mythranShift == true ? "true" : "false", serverIP.c_str(), serverPort); diff --git a/dGame/dCinema/Recorder.cpp b/dGame/dCinema/Recorder.cpp index 71ef5369..8c269906 100644 --- a/dGame/dCinema/Recorder.cpp +++ b/dGame/dCinema/Recorder.cpp @@ -322,6 +322,18 @@ void Recorder::ActingDispatch(Entity* actor, const std::vector& records } } + auto* cinematicRecord = dynamic_cast(record); + + if (cinematicRecord) { + if (variables != nullptr) { + auto* playerEntity = Game::entityManager->GetEntity(variables->player); + + if (playerEntity) { + GameMessages::SendPlayCinematic(playerEntity->GetObjectID(), GeneralUtils::UTF8ToUTF16(cinematicRecord->cinematic), playerEntity->GetSystemAddress()); + } + } + } + // Check if the record is a visibility record auto* visibilityRecord = dynamic_cast(record); @@ -518,6 +530,8 @@ void Cinema::Recording::Recorder::LoadRecords(tinyxml2::XMLElement* root, std::v record = new SpawnRecord(); } else if (name == "MissionRecord") { record = new MissionRecord(); + } else if (name == "CinematicRecord") { + record = new CinematicRecord(); } else { LOG("Unknown record type: %s", name.c_str()); continue; @@ -1468,4 +1482,26 @@ void Cinema::Recording::MissionRecord::Deserialize(tinyxml2::XMLElement* element m_Delay = element->DoubleAttribute("t"); } +Cinema::Recording::CinematicRecord::CinematicRecord(const std::string& cinematic) { + this->cinematic = cinematic; +} + +void Cinema::Recording::CinematicRecord::Act(Entity* actor) { +} + +void Cinema::Recording::CinematicRecord::Serialize(tinyxml2::XMLDocument& document, tinyxml2::XMLElement* parent) { + auto* element = document.NewElement("CinematicRecord"); + + element->SetAttribute("cinematic", cinematic.c_str()); + + element->SetAttribute("t", m_Delay); + + parent->InsertEndChild(element); +} + +void Cinema::Recording::CinematicRecord::Deserialize(tinyxml2::XMLElement* element) { + cinematic = element->Attribute("cinematic"); + + m_Delay = element->DoubleAttribute("t"); +} diff --git a/dGame/dCinema/Recorder.h b/dGame/dCinema/Recorder.h index 25f54fb3..1b727fe5 100644 --- a/dGame/dCinema/Recorder.h +++ b/dGame/dCinema/Recorder.h @@ -454,4 +454,20 @@ public: void Deserialize(tinyxml2::XMLElement* element) override; }; +class CinematicRecord : public Record +{ +public: + std::string cinematic; + + CinematicRecord() = default; + + CinematicRecord(const std::string& cinematic); + + void Act(Entity* actor) override; + + void Serialize(tinyxml2::XMLDocument& document, tinyxml2::XMLElement* parent) override; + + void Deserialize(tinyxml2::XMLElement* element) override; +}; + } diff --git a/dGame/dCinema/Scene.cpp b/dGame/dCinema/Scene.cpp index b74e0670..8a698967 100644 --- a/dGame/dCinema/Scene.cpp +++ b/dGame/dCinema/Scene.cpp @@ -15,6 +15,7 @@ #include "InventoryComponent.h" #include "MovementAIComponent.h" #include "Recorder.h" +#include "GhostComponent.h" using namespace Cinema; @@ -195,6 +196,22 @@ void Cinema::Scene::AutoLoadScenesForZone(LWOMAPID zone) { .requiredLevel = eGameMasterLevel::LEAD_MODERATOR }); + SlashCommandHandler::RegisterCommand(Command{ + .help = "", + .info = "", + .aliases = { "cinematic" }, + .handle = CommandCinematic, + .requiredLevel = eGameMasterLevel::LEAD_MODERATOR + }); + + SlashCommandHandler::RegisterCommand(Command{ + .help = "", + .info = "", + .aliases = { "ghost" }, + .handle = CommandGhostReference, + .requiredLevel = eGameMasterLevel::LEAD_MODERATOR + }); + const auto& scenesRoot = Game::config->GetValue("scenes_directory"); if (scenesRoot.empty()) { @@ -697,3 +714,29 @@ void Cinema::Scene::CommandCompanion(Entity* entity, const SystemAddress& sysAdd Cinema::Recording::CompanionRecord::SetCompanion(actor, follow); }); } + +void Cinema::Scene::CommandCinematic(Entity* entity, const SystemAddress& sysAddr, const std::string args) { + const auto splitArgs = GeneralUtils::SplitString(args, ' '); + if (splitArgs.empty()) return; + + const auto path = splitArgs[0]; + + GameMessages::SendPlayCinematic(entity->GetObjectID(), GeneralUtils::UTF8ToUTF16(path), sysAddr); +} + +void Cinema::Scene::CommandGhostReference(Entity* entity, const SystemAddress& sysAddr, const std::string args) { + auto* ghostComponent = entity->GetComponent(); + + if (ghostComponent == nullptr) { + ChatPackets::SendSystemMessage(sysAddr, u"Entity does not have a ghost component."); + return; + } + + const auto& ref = ghostComponent->GetGhostReferencePoint(); + + std::stringstream ss; + + ss << "<" << ref.x << ", " << ref.y << ", " << ref.z << ">"; + + ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::UTF8ToUTF16(ss.str())); +} diff --git a/dGame/dCinema/Scene.h b/dGame/dCinema/Scene.h index 531b563a..fa62ff56 100644 --- a/dGame/dCinema/Scene.h +++ b/dGame/dCinema/Scene.h @@ -134,6 +134,8 @@ private: static void CommandSceneAct(Entity* entity, const SystemAddress& sysAddr, const std::string args); static void CommandSceneSetup(Entity* entity, const SystemAddress& sysAddr, const std::string args); static void CommandCompanion(Entity* entity, const SystemAddress& sysAddr, const std::string args); + static void CommandCinematic(Entity* entity, const SystemAddress& sysAddr, const std::string args); + static void CommandGhostReference(Entity* entity, const SystemAddress& sysAddr, const std::string args); }; } // namespace Cinema