mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-11-22 05:27:19 +00:00
7b819d508b
commitf4311e593f
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Nov 16 22:16:50 2024 -0600 temp fix for MSVC debug builds commit0e81c69de8
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Nov 16 21:11:04 2024 -0600 CMakePresets indentation commitd7aa52a0fc
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Nov 16 21:03:37 2024 -0600 use DLU_CONFIG_DIR envvar commitd1bfe9f15d
Merge:6e781da2
de3fe931
Author: jadebenn <jonahbenn@yahoo.com> Date: Sat Nov 16 20:24:05 2024 -0600 Merge branch 'main' into MSVCCompilerFlags commit6e781da2e7
Merge:6ccd72c6
3a6123fe
Author: jadebenn <jonahbenn@yahoo.com> Date: Sat Apr 13 18:15:16 2024 -0500 Merge remote-tracking branch 'upstream/main' into MSVCCompilerFlags commit6ccd72c6a9
Author: jadebenn <jonahbenn@yahoo.com> Date: Sat Apr 13 17:48:58 2024 -0500 add RelWithDebInfo presets and move -Werror flag into presets.json commitb96cfd71a4
Merge:c4adcee8
1ee45639
Author: jadebenn <jonahbenn@yahoo.com> Date: Tue Apr 9 01:47:17 2024 -0500 Merge remote-tracking branch 'upstream/main' into MSVCCompilerFlags commitc4adcee8e8
Merge:7f9fcb5b
28ce8ac5
Author: jadebenn <jonahbenn@yahoo.com> Date: Mon Apr 8 22:30:35 2024 -0500 Merge remote-tracking branch 'upstream/main' into MSVCCompilerFlags commit7f9fcb5b75
Author: jadebenn <jonahbenn@yahoo.com> Date: Mon Apr 8 22:10:01 2024 -0500 change gnu and clang build directories to enable consistent artifact generation commit553740e8a0
Author: jadebenn <jonahbenn@yahoo.com> Date: Mon Apr 8 21:38:34 2024 -0500 update build presets commit39a8029fda
Author: jadebenn <jonahbenn@yahoo.com> Date: Mon Apr 8 20:30:06 2024 -0500 update github actions commit7eae64f8a6
Author: jadebenn <jonahbenn@yahoo.com> Date: Mon Apr 8 20:18:46 2024 -0500 disable /WX on MSVC commit24d3bc0ce6
Author: jadebenn <jonahbenn@yahoo.com> Date: Mon Apr 8 20:11:59 2024 -0500 altered cmake configuration scripts commit368f4ccabf
Author: jadebenn <jonahbenn@yahoo.com> Date: Sat Apr 6 23:00:04 2024 -0500 change defaults commit7d7ea68bf9
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 22:23:32 2024 -0500 fix preset commit57d0b12f9b
Author: jadebenn <jonahbenn@yahoo.com> Date: Sat Apr 6 21:50:32 2024 -0500 expand cmake presets commitaa62d357bb
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 20:50:26 2024 -0500 rename gcc to gnu commitd6e4edd886
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 20:27:20 2024 -0500 change runtime output dir commitabe413f239
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 20:22:47 2024 -0500 debug try 2 commitc6c771b892
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 20:16:00 2024 -0500 add debug messages (again) commit6c6966afd2
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 19:46:58 2024 -0500 was not actually fixed commitfab74c90b6
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 19:37:02 2024 -0500 are these messages actually somehow fixing the issue? commita4b6b7c0d9
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 19:27:34 2024 -0500 see if this re-breaks mac commit07626f8ebb
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 19:04:59 2024 -0500 back to debug messages commitbdf9adc0e8
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 18:47:55 2024 -0500 Revert "try disabling an apple-specific build rule" This reverts commit45ec66e976
. commit8154207848
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 18:47:53 2024 -0500 Revert "more fiddling with mac test builds" This reverts commit0f843c02c9
. commit8f5c10d158
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 18:47:52 2024 -0500 Revert "try and narrow down the macos build failure cause" This reverts commit5fd86833fa
. commit54876bf886
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 18:47:50 2024 -0500 Revert "try stripping out all the custom macos test logic again" This reverts commitcc15a26ce8
. commit8af35727a6
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 18:47:48 2024 -0500 Revert "I'm really just throwing everything to the wall and seeing what sticks" This reverts commit1a05b027fe
. commite143f22ada
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 18:47:46 2024 -0500 Revert "more macos tinkering" This reverts commit829ec35b57
. commit495e70c376
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 18:47:44 2024 -0500 Revert "implib" This reverts commitd41349d6ed
. commit37dbb52104
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 18:47:42 2024 -0500 Revert "try manual link directory specification" This reverts commit0c2d40632e
. commitce568189fc
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 18:47:40 2024 -0500 Revert "save me" This reverts commitbd73aa21a9
. commitc420a72016
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 18:47:36 2024 -0500 Revert "aaaaaaaaa" This reverts commit338279c396
. commitdccac945bb
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 18:47:08 2024 -0500 Revert "paths paths paths" This reverts commit9a7d86aa6c
. commit9a7d86aa6c
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 18:39:08 2024 -0500 paths paths paths commit338279c396
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 18:29:01 2024 -0500 aaaaaaaaa commitbd73aa21a9
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 18:21:16 2024 -0500 save me commit0c2d40632e
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 18:09:03 2024 -0500 try manual link directory specification commitd41349d6ed
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 17:52:20 2024 -0500 implib commit829ec35b57
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 17:43:47 2024 -0500 more macos tinkering commit1a05b027fe
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 17:18:41 2024 -0500 I'm really just throwing everything to the wall and seeing what sticks commitcc15a26ce8
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 17:09:45 2024 -0500 try stripping out all the custom macos test logic again commit5fd86833fa
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 16:54:53 2024 -0500 try and narrow down the macos build failure cause commit0f843c02c9
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 16:47:19 2024 -0500 more fiddling with mac test builds commit45ec66e976
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 16:29:29 2024 -0500 try disabling an apple-specific build rule commit6e41423dc3
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 04:01:07 2024 -0500 one last MacOS try for the night commitbc79a17ddb
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 03:50:41 2024 -0500 try fixing macos build commitd6031ce9f5
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 03:04:52 2024 -0500 try zero-initializinng this struct to solve docker issue commit24cbd94a80
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Apr 6 02:34:36 2024 -0500 attempted docker fix commit7812f27330
Merge:ef8029d4
18c27b14
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Fri Apr 5 23:32:29 2024 -0500 Merge branch 'main' into MSVCCompilerFlags commitef8029d46f
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Fri Apr 5 23:30:26 2024 -0500 update cmake configs commit04a7bc2b8d
Author: jadebenn <jonahbenn@yahoo.com> Date: Fri Apr 5 21:00:23 2024 -0500 edit build script commit9fc6b4e973
Author: jadebenn <jonahbenn@yahoo.com> Date: Fri Apr 5 18:10:09 2024 -0500 fix build directory issue commita19afaaab0
Author: jadebenn <jonahbenn@yahoo.com> Date: Fri Apr 5 18:06:37 2024 -0500 update .gitignore commit426d34a0aa
Author: jadebenn <jonahbenn@yahoo.com> Date: Fri Apr 5 17:58:19 2024 -0500 unexclude toolchain dir commit9ce7d9043c
Author: jadebenn <jonahbenn@yahoo.com> Date: Fri Apr 5 17:55:02 2024 -0500 updated cmake workflows commitdb5c10c331
Author: jadebenn <jonahbenn@yahoo.com> Date: Fri Apr 5 16:58:00 2024 -0500 temporarily remove macos build for testing purposes commitf7da00ff89
Merge:145f97cf
661e0939
Author: jadebenn <jonahbenn@yahoo.com> Date: Fri Apr 5 16:51:39 2024 -0500 Merge branch 'MSVCCompilerFlags' of https://github.com/jadebenn/DarkflameServer into MSVCCompilerFlags commit145f97cfdc
Author: jadebenn <jonahbenn@yahoo.com> Date: Fri Apr 5 16:50:39 2024 -0500 build reorganization and experimental clang support commit661e0939b7
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Wed Apr 3 22:13:11 2024 -0500 fix typo in windows preset commit018e5707d7
Author: jadebenn <jonahbenn@yahoo.com> Date: Wed Apr 3 20:30:33 2024 -0500 try using compiler flags for mac instead commit81e5f059d5
Author: jadebenn <jonahbenn@yahoo.com> Date: Wed Apr 3 20:20:31 2024 -0500 macos refuses to work :( commita3d70197f2
Author: jadebenn <jonahbenn@yahoo.com> Date: Wed Apr 3 20:13:37 2024 -0500 try adding build types back to mac commit005d439a4a
Author: jadebenn <jonahbenn@yahoo.com> Date: Wed Apr 3 19:58:44 2024 -0500 edit macos presets commitbba825f0c8
Author: jadebenn <jonahbenn@yahoo.com> Date: Wed Apr 3 19:48:20 2024 -0500 update CMake presets commit199c8224a5
Merge:1116ba83
c1c5db65
Author: jadebenn <jonahbenn@yahoo.com> Date: Wed Apr 3 19:00:39 2024 -0500 Merge remote-tracking branch 'upstream/main' into MSVCCompilerFlags commit1116ba8306
Merge:9316bd6e
c7b3d9e8
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sun Feb 11 21:03:02 2024 -0600 Merge branch 'DarkflameUniverse:main' into MSVCCompilerFlags commit9316bd6eeb
Merge:62fb8ad0
29666a1f
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Feb 10 21:02:52 2024 -0600 Merge branch 'DarkflameUniverse:main' into MSVCCompilerFlags commit62fb8ad071
Merge:d5089b72
24f94edf
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Thu Feb 8 21:41:50 2024 -0600 Merge branch 'DarkflameUniverse:main' into MSVCCompilerFlags commitd5089b72cc
Author: jadebenn <jonahbenn@yahoo.com> Date: Sun Feb 4 16:26:38 2024 -0600 add Linux debug preset commit7c9f56ff76
Author: jadebenn <jonahbenn@yahoo.com> Date: Sat Feb 3 16:02:53 2024 -0600 move out g++ O2 flag commit6cc99fae42
Merge:96276391
050184c5
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Sat Feb 3 02:41:43 2024 -0600 Merge branch 'DarkflameUniverse:main' into MSVCCompilerFlags commit962763916d
Author: jadebenn <jonahbenn@yahoo.com> Date: Tue Jan 30 22:00:49 2024 -0600 export the compile commands so I can see if they're having any effect commit4b7d1d6593
Author: jadebenn <jonahbenn@yahoo.com> Date: Tue Jan 30 21:49:24 2024 -0600 trying 'init' flags instead commit3fa80063e9
Author: jadebenn <jonahbenn@yahoo.com> Date: Tue Jan 30 21:13:47 2024 -0600 ONE MORE TIME commitae2115c68d
Author: jadebenn <jonahbenn@yahoo.com> Date: Tue Jan 30 20:52:33 2024 -0600 final(?) try for now commit119937f5d9
Author: jadebenn <jonahbenn@yahoo.com> Date: Tue Jan 30 20:34:44 2024 -0600 ditto commitab39754597
Author: jadebenn <jonahbenn@yahoo.com> Date: Tue Jan 30 20:34:41 2024 -0600 testing if these even have any effect commite7058be3dc
Author: jadebenn <jonahbenn@yahoo.com> Date: Tue Jan 30 20:28:05 2024 -0600 third test commit10d7776fb2
Author: jadebenn <jonahbenn@yahoo.com> Date: Tue Jan 30 19:33:59 2024 -0600 trying more variations on the flags commit70f3756098
Author: jadebenn <jonahbenn@yahoo.com> Date: Tue Jan 30 18:49:46 2024 -0600 testing commit9b7c593ae9
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Tue Jan 30 08:49:53 2024 -0600 Update CMakePresets.json commit8a34544d0e
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Tue Jan 30 08:44:29 2024 -0600 test moving flags to json commitb682f13fa9
Merge:2239507d
d78b5087
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Mon Jan 29 22:49:29 2024 -0600 Merge branch 'DarkflameUniverse:main' into MSVCCompilerFlags commit2239507d3c
Author: jadebenn <jadebenn@users.noreply.github.com> Date: Mon Jan 29 06:14:47 2024 -0600 Add MSVC optimization flags
429 lines
13 KiB
C++
429 lines
13 KiB
C++
#include "VanityUtilities.h"
|
|
|
|
#include "DestroyableComponent.h"
|
|
#include "EntityManager.h"
|
|
#include "GameMessages.h"
|
|
#include "InventoryComponent.h"
|
|
#include "PhantomPhysicsComponent.h"
|
|
#include "ProximityMonitorComponent.h"
|
|
#include "ScriptComponent.h"
|
|
#include "dCommonVars.h"
|
|
#include "dConfig.h"
|
|
#include "dServer.h"
|
|
#include "tinyxml2.h"
|
|
#include "Game.h"
|
|
#include "Logger.h"
|
|
#include "BinaryPathFinder.h"
|
|
#include "EntityInfo.h"
|
|
#include "Spawner.h"
|
|
#include "dZoneManager.h"
|
|
#include "ObjectIDManager.h"
|
|
#include "Level.h"
|
|
|
|
#include <fstream>
|
|
|
|
|
|
namespace {
|
|
std::vector<VanityObject> objects;
|
|
std::set<std::string> loadedFiles;
|
|
}
|
|
|
|
void SetupNPCTalk(Entity* npc);
|
|
void NPCTalk(Entity* npc);
|
|
void ParseXml(const std::string& file);
|
|
LWOOBJID SpawnSpawner(const VanityObject& object, const VanityObjectLocation& location);
|
|
Entity* SpawnObject(const VanityObject& object, const VanityObjectLocation& location);
|
|
VanityObject* GetObject(const std::string& name);
|
|
|
|
void VanityUtilities::SpawnVanity() {
|
|
const uint32_t zoneID = Game::server->GetZoneID();
|
|
|
|
if (zoneID == 1200) {
|
|
{
|
|
EntityInfo info;
|
|
info.lot = 8139;
|
|
info.pos = { 259.5f, 246.4f, -705.2f };
|
|
info.rot = { 0.0f, 0.0f, 1.0f, 0.0f };
|
|
info.spawnerID = Game::entityManager->GetZoneControlEntity()->GetObjectID();
|
|
info.settings = {
|
|
new LDFData<bool>(u"hasCustomText", true),
|
|
new LDFData<std::string>(u"customText", ParseMarkdown((BinaryPathFinder::GetBinaryDir() / "vanity/TESTAMENT.md").string()))
|
|
};
|
|
|
|
auto* entity = Game::entityManager->CreateEntity(info);
|
|
Game::entityManager->ConstructEntity(entity);
|
|
}
|
|
}
|
|
|
|
if (Game::config->GetValue("disable_vanity") == "1") return;
|
|
|
|
for (const auto& npc : objects) {
|
|
if (npc.m_ID == LWOOBJID_EMPTY) continue;
|
|
if (npc.m_LOT == 176){
|
|
Game::zoneManager->RemoveSpawner(npc.m_ID);
|
|
} else{
|
|
auto* entity = Game::entityManager->GetEntity(npc.m_ID);
|
|
if (!entity) continue;
|
|
entity->Smash(LWOOBJID_EMPTY, eKillType::VIOLENT);
|
|
}
|
|
}
|
|
|
|
objects.clear();
|
|
loadedFiles.clear();
|
|
|
|
ParseXml((BinaryPathFinder::GetBinaryDir() / "vanity/root.xml").string());
|
|
|
|
// Loop through all objects
|
|
for (auto& object : objects) {
|
|
if (object.m_Locations.find(Game::server->GetZoneID()) == object.m_Locations.end()) continue;
|
|
|
|
const std::vector<VanityObjectLocation>& locations = object.m_Locations.at(Game::server->GetZoneID());
|
|
|
|
// Pick a random location
|
|
const auto& location = locations[GeneralUtils::GenerateRandomNumber<int>(
|
|
static_cast<size_t>(0), static_cast<size_t>(locations.size() - 1))];
|
|
|
|
float rate = GeneralUtils::GenerateRandomNumber<float>(0, 1);
|
|
if (location.m_Chance < rate) continue;
|
|
|
|
if (object.m_LOT == 176){
|
|
object.m_ID = SpawnSpawner(object, location);
|
|
} else {
|
|
// Spawn the NPC
|
|
auto* objectEntity = SpawnObject(object, location);
|
|
if (!objectEntity) continue;
|
|
object.m_ID = objectEntity->GetObjectID();
|
|
if (!object.m_Phrases.empty()){
|
|
objectEntity->SetVar<std::vector<std::string>>(u"chats", object.m_Phrases);
|
|
SetupNPCTalk(objectEntity);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LWOOBJID SpawnSpawner(const VanityObject& object, const VanityObjectLocation& location) {
|
|
SceneObject obj{};
|
|
obj.lot = object.m_LOT;
|
|
// guratantee we have no collisions
|
|
do {
|
|
obj.id = ObjectIDManager::GenerateObjectID();
|
|
} while(Game::zoneManager->GetSpawner(obj.id));
|
|
obj.position = location.m_Position;
|
|
obj.rotation = location.m_Rotation;
|
|
obj.settings = object.m_Config;
|
|
Level::MakeSpawner(obj);
|
|
return obj.id;
|
|
}
|
|
|
|
Entity* SpawnObject(const VanityObject& object, const VanityObjectLocation& location) {
|
|
EntityInfo info;
|
|
info.lot = object.m_LOT;
|
|
info.pos = location.m_Position;
|
|
info.rot = location.m_Rotation;
|
|
info.scale = location.m_Scale;
|
|
info.spawnerID = Game::entityManager->GetZoneControlEntity()->GetObjectID();
|
|
info.settings = object.m_Config;
|
|
|
|
auto* entity = Game::entityManager->CreateEntity(info);
|
|
if (!object.m_Name.empty()) entity->SetVar(u"npcName", object.m_Name);
|
|
if (entity->GetVar<bool>(u"noGhosting")) entity->SetIsGhostingCandidate(false);
|
|
|
|
auto* inventoryComponent = entity->GetComponent<InventoryComponent>();
|
|
if (inventoryComponent && !object.m_Equipment.empty()) {
|
|
inventoryComponent->SetNPCItems(object.m_Equipment);
|
|
}
|
|
|
|
auto* destroyableComponent = entity->GetComponent<DestroyableComponent>();
|
|
if (destroyableComponent) {
|
|
destroyableComponent->SetIsGMImmune(true);
|
|
destroyableComponent->SetMaxHealth(0);
|
|
destroyableComponent->SetHealth(0);
|
|
}
|
|
|
|
Game::entityManager->ConstructEntity(entity);
|
|
|
|
return entity;
|
|
}
|
|
|
|
void ParseXml(const std::string& file) {
|
|
if (loadedFiles.contains(file)){
|
|
LOG("Trying to load vanity file %s twice!!!", file.c_str());
|
|
return;
|
|
}
|
|
loadedFiles.insert(file);
|
|
// Read the entire file
|
|
std::ifstream xmlFile(file);
|
|
std::string xml((std::istreambuf_iterator<char>(xmlFile)), std::istreambuf_iterator<char>());
|
|
|
|
// Parse the XML
|
|
tinyxml2::XMLDocument doc;
|
|
doc.Parse(xml.c_str(), xml.size());
|
|
|
|
// Read the objects
|
|
auto* files = doc.FirstChildElement("files");
|
|
if (files) {
|
|
for (auto* file = files->FirstChildElement("file"); file != nullptr; file = file->NextSiblingElement("file")) {
|
|
std::string enabled = file->Attribute("enabled");
|
|
std::string filename = file->Attribute("name");
|
|
if (enabled != "1") {
|
|
continue;
|
|
}
|
|
ParseXml((BinaryPathFinder::GetBinaryDir() / "vanity" / filename).string());
|
|
}
|
|
}
|
|
|
|
// Read the objects
|
|
auto* objectsElement = doc.FirstChildElement("objects");
|
|
const uint32_t currentZoneID = Game::server->GetZoneID();
|
|
if (objectsElement) {
|
|
for (auto* object = objectsElement->FirstChildElement("object"); object != nullptr; object = object->NextSiblingElement("object")) {
|
|
// for use later when adding to the vector of VanityObjects
|
|
bool useLocationsAsRandomSpawnPoint = false;
|
|
// Get the NPC name
|
|
auto* name = object->Attribute("name");
|
|
|
|
if (!name) name = "";
|
|
|
|
// Get the NPC lot
|
|
auto lot = GeneralUtils::TryParse<LOT>(object->Attribute("lot")).value_or(LOT_NULL);
|
|
|
|
if (lot == LOT_NULL) {
|
|
LOG("Failed to parse object lot");
|
|
continue;
|
|
}
|
|
|
|
// Get the equipment
|
|
auto* equipment = object->FirstChildElement("equipment");
|
|
std::vector<LOT> inventory;
|
|
|
|
if (equipment) {
|
|
auto* text = equipment->GetText();
|
|
|
|
if (text != nullptr) {
|
|
std::string equipmentString(text);
|
|
|
|
std::vector<std::string> splitEquipment = GeneralUtils::SplitString(equipmentString, ',');
|
|
|
|
for (auto& item : splitEquipment) {
|
|
// remove spaces for tryParse to work
|
|
item.erase(remove_if(item.begin(), item.end(), isspace), item.end());
|
|
auto itemInt = GeneralUtils::TryParse<uint32_t>(item);
|
|
if (itemInt) inventory.push_back(itemInt.value());
|
|
}
|
|
}
|
|
}
|
|
|
|
// Get the phrases
|
|
auto* phrases = object->FirstChildElement("phrases");
|
|
std::vector<std::string> phraseList = {};
|
|
if (phrases) {
|
|
for (auto* phrase = phrases->FirstChildElement("phrase"); phrase != nullptr;
|
|
phrase = phrase->NextSiblingElement("phrase")) {
|
|
// Get the phrase
|
|
auto* text = phrase->GetText();
|
|
if (text == nullptr) {
|
|
LOG("Failed to parse NPC phrase");
|
|
continue;
|
|
}
|
|
phraseList.push_back(text);
|
|
}
|
|
}
|
|
|
|
auto* configElement = object->FirstChildElement("config");
|
|
std::vector<std::u16string> keys = {};
|
|
std::vector<LDFBaseData*> config = {};
|
|
if(configElement) {
|
|
for (auto* key = configElement->FirstChildElement("key"); key != nullptr;
|
|
key = key->NextSiblingElement("key")) {
|
|
// Get the config data
|
|
auto* data = key->GetText();
|
|
if (!data) continue;
|
|
|
|
LDFBaseData* configData = LDFBaseData::DataFromString(data);
|
|
if (configData->GetKey() == u"useLocationsAsRandomSpawnPoint" && configData->GetValueType() == eLDFType::LDF_TYPE_BOOLEAN){
|
|
useLocationsAsRandomSpawnPoint = static_cast<bool>(configData);
|
|
continue;
|
|
}
|
|
keys.push_back(configData->GetKey());
|
|
config.push_back(configData);
|
|
}
|
|
}
|
|
if (!keys.empty()) config.push_back(new LDFData<std::vector<std::u16string>>(u"syncLDF", keys));
|
|
|
|
VanityObject objectData {
|
|
.m_Name = name,
|
|
.m_LOT = lot,
|
|
.m_Equipment = inventory,
|
|
.m_Phrases = phraseList,
|
|
.m_Config = config
|
|
};
|
|
|
|
// Get the locations
|
|
auto* locations = object->FirstChildElement("locations");
|
|
|
|
if (locations == nullptr) {
|
|
LOG("Failed to parse NPC locations");
|
|
continue;
|
|
}
|
|
|
|
for (auto* location = locations->FirstChildElement("location"); location != nullptr;
|
|
location = location->NextSiblingElement("location")) {
|
|
|
|
// Get the location data
|
|
auto zoneID = GeneralUtils::TryParse<uint32_t>(location->Attribute("zone"));
|
|
auto x = GeneralUtils::TryParse<float>(location->Attribute("x"));
|
|
auto y = GeneralUtils::TryParse<float>(location->Attribute("y"));
|
|
auto z = GeneralUtils::TryParse<float>(location->Attribute("z"));
|
|
auto rw = GeneralUtils::TryParse<float>(location->Attribute("rw"));
|
|
auto rx = GeneralUtils::TryParse<float>(location->Attribute("rx"));
|
|
auto ry = GeneralUtils::TryParse<float>(location->Attribute("ry"));
|
|
auto rz = GeneralUtils::TryParse<float>(location->Attribute("rz"));
|
|
|
|
if (!zoneID || !x || !y || !z || !rw || !rx || !ry || !rz) {
|
|
LOG("Failed to parse NPC location data");
|
|
continue;
|
|
}
|
|
|
|
if (zoneID.value() != currentZoneID) {
|
|
continue;
|
|
}
|
|
|
|
VanityObjectLocation locationData {
|
|
.m_Position = { x.value(), y.value(), z.value() },
|
|
.m_Rotation = { rw.value(), rx.value(), ry.value(), rz.value() },
|
|
};
|
|
|
|
if (location->Attribute("chance")) {
|
|
locationData.m_Chance = GeneralUtils::TryParse<float>(location->Attribute("chance")).value_or(1.0f);
|
|
}
|
|
|
|
if (location->Attribute("scale")) {
|
|
locationData.m_Scale = GeneralUtils::TryParse<float>(location->Attribute("scale")).value_or(1.0f);
|
|
}
|
|
|
|
const auto& it = objectData.m_Locations.find(zoneID.value());
|
|
|
|
if (it != objectData.m_Locations.end()) {
|
|
it->second.push_back(locationData);
|
|
} else {
|
|
std::vector<VanityObjectLocation> locations;
|
|
locations.push_back(locationData);
|
|
objectData.m_Locations.insert(std::make_pair(zoneID.value(), locations));
|
|
}
|
|
|
|
if (!useLocationsAsRandomSpawnPoint) {
|
|
objects.push_back(objectData);
|
|
objectData.m_Locations.clear();
|
|
}
|
|
}
|
|
|
|
if (useLocationsAsRandomSpawnPoint && !objectData.m_Locations.empty()) {
|
|
objects.push_back(objectData);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
VanityObject* VanityUtilities::GetObject(const std::string& name) {
|
|
for (size_t i = 0; i < objects.size(); i++) {
|
|
if (objects[i].m_Name == name) {
|
|
return &objects[i];
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
std::string VanityUtilities::ParseMarkdown(const std::string& file) {
|
|
// This function will read the file and return the content formatted as ASCII text.
|
|
|
|
// Read the file into a string
|
|
std::ifstream t(file);
|
|
std::stringstream output;
|
|
// If the file does not exist, return a useful error.
|
|
if (!t.good()) {
|
|
output << "File ";
|
|
output << file.substr(file.rfind("/") + 1);
|
|
output << " not found!\nContact your DarkflameServer admin\nor find the server source at https://github.com/DarkflameUniverse/DarkflameServer";
|
|
return output.str();
|
|
}
|
|
|
|
std::stringstream buffer;
|
|
buffer << t.rdbuf();
|
|
std::string fileContents = buffer.str();
|
|
|
|
// Loop through all lines in the file.
|
|
// Replace all instances of the markdown syntax with the corresponding HTML.
|
|
// Only care about headers
|
|
std::string line;
|
|
std::stringstream ss;
|
|
ss << fileContents;
|
|
while (std::getline(ss, line)) {
|
|
|
|
#define TOSTRING(x) #x
|
|
|
|
#ifndef STRINGIFY
|
|
#define STRINGIFY(x) TOSTRING(x)
|
|
#endif
|
|
// Replace "__TIMESTAMP__" with the __TIMESTAMP__
|
|
GeneralUtils::ReplaceInString(line, "__TIMESTAMP__", __TIMESTAMP__);
|
|
// Replace "__VERSION__" with the PROJECT_VERSION
|
|
GeneralUtils::ReplaceInString(line, "__VERSION__", Game::projectVersion);
|
|
// Replace "__SOURCE__" with SOURCE
|
|
GeneralUtils::ReplaceInString(line, "__SOURCE__", Game::config->GetValue("source"));
|
|
// Replace "__LICENSE__" with LICENSE
|
|
GeneralUtils::ReplaceInString(line, "__LICENSE__", "AGPL-3.0");
|
|
|
|
if (line.find("##") != std::string::npos) {
|
|
// Add "<font size='18' color='#000000'>" before the header
|
|
output << "<font size=\"14\" color=\"#000000\">";
|
|
// Add the header without the markdown syntax
|
|
output << line.substr(3);
|
|
|
|
output << "</font>";
|
|
} else if (line.find("#") != std::string::npos) {
|
|
// Add "<font size='18' color='#000000'>" before the header
|
|
output << "<font size=\"18\" color=\"#000000\">";
|
|
// Add the header without the markdown syntax
|
|
output << line.substr(2);
|
|
|
|
output << "</font>";
|
|
} else {
|
|
output << line;
|
|
}
|
|
|
|
output << "\n";
|
|
}
|
|
|
|
return output.str();
|
|
}
|
|
|
|
void SetupNPCTalk(Entity* npc) {
|
|
npc->AddCallbackTimer(15.0f, [npc]() { NPCTalk(npc); });
|
|
|
|
npc->SetProximityRadius(20.0f, "talk");
|
|
}
|
|
|
|
void NPCTalk(Entity* npc) {
|
|
auto* proximityMonitorComponent = npc->GetComponent<ProximityMonitorComponent>();
|
|
|
|
if (!proximityMonitorComponent->GetProximityObjects("talk").empty()) {
|
|
const auto& chats = npc->GetVar<std::vector<std::string>>(u"chats");
|
|
|
|
if (chats.empty()) {
|
|
return;
|
|
}
|
|
|
|
const auto& selected
|
|
= chats[GeneralUtils::GenerateRandomNumber<int32_t>(0, static_cast<int32_t>(chats.size() - 1))];
|
|
|
|
GameMessages::SendNotifyClientZoneObject(
|
|
npc->GetObjectID(), u"sendToclient_bubble", 0, 0, npc->GetObjectID(), selected, UNASSIGNED_SYSTEM_ADDRESS);
|
|
}
|
|
|
|
Game::entityManager->SerializeEntity(npc);
|
|
|
|
const float nextTime = GeneralUtils::GenerateRandomNumber<float>(15, 60);
|
|
|
|
npc->AddCallbackTimer(nextTime, [npc]() { NPCTalk(npc); });
|
|
}
|