mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-11-22 13:37:22 +00:00
Merge pull request #1272 from DarkflameUniverse/vanity-reload-and-spawners
feat: Vanity reload and vanity spawners
This commit is contained in:
commit
4167d98667
@ -15,6 +15,10 @@
|
|||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "BinaryPathFinder.h"
|
#include "BinaryPathFinder.h"
|
||||||
#include "EntityInfo.h"
|
#include "EntityInfo.h"
|
||||||
|
#include "Spawner.h"
|
||||||
|
#include "dZoneManager.h"
|
||||||
|
#include "../dWorldServer/ObjectIDManager.h"
|
||||||
|
#include "Level.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
@ -29,6 +33,21 @@ void VanityUtilities::SpawnVanity() {
|
|||||||
|
|
||||||
const uint32_t zoneID = Game::server->GetZoneID();
|
const uint32_t zoneID = Game::server->GetZoneID();
|
||||||
|
|
||||||
|
for (const auto& npc : m_NPCs) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_NPCs.clear();
|
||||||
|
m_Parties.clear();
|
||||||
|
m_PartyPhrases.clear();
|
||||||
|
|
||||||
ParseXML((BinaryPathFinder::GetBinaryDir() / "vanity/NPC.xml").string());
|
ParseXML((BinaryPathFinder::GetBinaryDir() / "vanity/NPC.xml").string());
|
||||||
|
|
||||||
// Loop through all parties
|
// Loop through all parties
|
||||||
@ -53,7 +72,7 @@ void VanityUtilities::SpawnVanity() {
|
|||||||
|
|
||||||
// Loop through all locations
|
// Loop through all locations
|
||||||
for (const auto& location : party.m_Locations) {
|
for (const auto& location : party.m_Locations) {
|
||||||
rate = GeneralUtils::GenerateRandomNumber<float>(0, 1);
|
rate = GeneralUtils::GenerateRandomNumber<float>(0, 1);
|
||||||
if (0.75f < rate) {
|
if (0.75f < rate) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -66,10 +85,11 @@ void VanityUtilities::SpawnVanity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto& npc = npcList[npcIndex];
|
auto& npc = npcList[npcIndex];
|
||||||
|
// Skip spawners
|
||||||
|
if (npc.m_LOT == 176) continue;
|
||||||
|
|
||||||
taken.push_back(npcIndex);
|
taken.push_back(npcIndex);
|
||||||
|
|
||||||
// Spawn the NPC
|
|
||||||
LOG("ldf size is %i", npc.ldf.size());
|
LOG("ldf size is %i", npc.ldf.size());
|
||||||
if (npc.ldf.empty()) {
|
if (npc.ldf.empty()) {
|
||||||
npc.ldf = {
|
npc.ldf = {
|
||||||
@ -79,13 +99,16 @@ void VanityUtilities::SpawnVanity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Spawn the NPC
|
// Spawn the NPC
|
||||||
auto* npcEntity = SpawnNPC(npc.m_LOT, npc.m_Name, location.m_Position, location.m_Rotation, npc.m_Equipment, npc.ldf);
|
if (npc.m_LOT == 176){
|
||||||
if (!npc.m_Phrases.empty()) {
|
npc.m_ID = SpawnSpawner(npc.m_LOT, location.m_Position, location.m_Rotation, npc.ldf);
|
||||||
npcEntity->SetVar<std::vector<std::string>>(u"chats", m_PartyPhrases);
|
} else {
|
||||||
SetupNPCTalk(npcEntity);
|
auto* npcEntity = SpawnNPC(npc.m_LOT, npc.m_Name, location.m_Position, location.m_Rotation, npc.m_Equipment, npc.ldf);
|
||||||
|
if (!npc.m_Phrases.empty()) {
|
||||||
|
npcEntity->SetVar<std::vector<std::string>>(u"chats", m_PartyPhrases);
|
||||||
|
SetupNPCTalk(npcEntity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,23 +134,28 @@ void VanityUtilities::SpawnVanity() {
|
|||||||
new LDFData<std::u16string>(u"custom_script_client", u"scripts\\ai\\SPEC\\MISSION_MINIGAME_CLIENT.lua")
|
new LDFData<std::u16string>(u"custom_script_client", u"scripts\\ai\\SPEC\\MISSION_MINIGAME_CLIENT.lua")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (npc.m_LOT == 176){
|
||||||
|
npc.m_ID = SpawnSpawner(npc.m_LOT, location.m_Position, location.m_Rotation, npc.ldf);
|
||||||
|
} else {
|
||||||
|
// Spawn the NPC
|
||||||
|
auto* npcEntity = SpawnNPC(npc.m_LOT, npc.m_Name, location.m_Position, location.m_Rotation, npc.m_Equipment, npc.ldf);
|
||||||
|
if (!npcEntity) continue;
|
||||||
|
npc.m_ID = npcEntity->GetObjectID();
|
||||||
|
if (!npc.m_Phrases.empty()){
|
||||||
|
npcEntity->SetVar<std::vector<std::string>>(u"chats", npc.m_Phrases);
|
||||||
|
|
||||||
// Spawn the NPC
|
auto* scriptComponent = npcEntity->GetComponent<ScriptComponent>();
|
||||||
auto* npcEntity = SpawnNPC(npc.m_LOT, npc.m_Name, location.m_Position, location.m_Rotation, npc.m_Equipment, npc.ldf);
|
|
||||||
if (!npc.m_Phrases.empty()){
|
|
||||||
npcEntity->SetVar<std::vector<std::string>>(u"chats", npc.m_Phrases);
|
|
||||||
|
|
||||||
auto* scriptComponent = npcEntity->GetComponent<ScriptComponent>();
|
if (scriptComponent && !npc.m_Script.empty()) {
|
||||||
|
scriptComponent->SetScript(npc.m_Script);
|
||||||
|
scriptComponent->SetSerialized(false);
|
||||||
|
|
||||||
if (scriptComponent && !npc.m_Script.empty()) {
|
for (const auto& npc : npc.m_Flags) {
|
||||||
scriptComponent->SetScript(npc.m_Script);
|
npcEntity->SetVar<bool>(GeneralUtils::ASCIIToUTF16(npc.first), npc.second);
|
||||||
scriptComponent->SetSerialized(false);
|
}
|
||||||
|
|
||||||
for (const auto& npc : npc.m_Flags) {
|
|
||||||
npcEntity->SetVar<bool>(GeneralUtils::ASCIIToUTF16(npc.first), npc.second);
|
|
||||||
}
|
}
|
||||||
|
SetupNPCTalk(npcEntity);
|
||||||
}
|
}
|
||||||
SetupNPCTalk(npcEntity);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,8 +177,21 @@ void VanityUtilities::SpawnVanity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity* VanityUtilities::SpawnNPC(LOT lot, const std::string& name, const NiPoint3& position,
|
LWOOBJID VanityUtilities::SpawnSpawner(LOT lot, const NiPoint3& position, const NiQuaternion& rotation, const std::vector<LDFBaseData*>& ldf){
|
||||||
const NiQuaternion& rotation, const std::vector<LOT>& inventory, const std::vector<LDFBaseData*>& ldf) {
|
SceneObject obj;
|
||||||
|
obj.lot = lot;
|
||||||
|
// guratantee we have no collisions
|
||||||
|
do {
|
||||||
|
obj.id = ObjectIDManager::Instance()->GenerateObjectID();
|
||||||
|
} while(Game::zoneManager->GetSpawner(obj.id));
|
||||||
|
obj.position = position;
|
||||||
|
obj.rotation = rotation;
|
||||||
|
obj.settings = ldf;
|
||||||
|
Level::MakeSpawner(obj);
|
||||||
|
return obj.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity* VanityUtilities::SpawnNPC(LOT lot, const std::string& name, const NiPoint3& position, const NiQuaternion& rotation, const std::vector<LOT>& inventory, const std::vector<LDFBaseData*>& ldf) {
|
||||||
EntityInfo info;
|
EntityInfo info;
|
||||||
info.lot = lot;
|
info.lot = lot;
|
||||||
info.pos = position;
|
info.pos = position;
|
||||||
|
@ -13,6 +13,7 @@ struct VanityNPCLocation
|
|||||||
|
|
||||||
struct VanityNPC
|
struct VanityNPC
|
||||||
{
|
{
|
||||||
|
LWOOBJID m_ID = LWOOBJID_EMPTY;
|
||||||
std::string m_Name;
|
std::string m_Name;
|
||||||
LOT m_LOT;
|
LOT m_LOT;
|
||||||
std::vector<LOT> m_Equipment;
|
std::vector<LOT> m_Equipment;
|
||||||
@ -44,6 +45,13 @@ public:
|
|||||||
const std::vector<LDFBaseData*>& ldf
|
const std::vector<LDFBaseData*>& ldf
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static LWOOBJID SpawnSpawner(
|
||||||
|
LOT lot,
|
||||||
|
const NiPoint3& position,
|
||||||
|
const NiQuaternion& rotation,
|
||||||
|
const std::vector<LDFBaseData*>& ldf
|
||||||
|
);
|
||||||
|
|
||||||
static std::string ParseMarkdown(
|
static std::string ParseMarkdown(
|
||||||
const std::string& file
|
const std::string& file
|
||||||
);
|
);
|
||||||
|
@ -38,6 +38,76 @@ Level::~Level() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Level::MakeSpawner(SceneObject obj){
|
||||||
|
SpawnerInfo spawnInfo = SpawnerInfo();
|
||||||
|
SpawnerNode* node = new SpawnerNode();
|
||||||
|
spawnInfo.templateID = obj.lot;
|
||||||
|
spawnInfo.spawnerID = obj.id;
|
||||||
|
spawnInfo.templateScale = obj.scale;
|
||||||
|
node->position = obj.position;
|
||||||
|
node->rotation = obj.rotation;
|
||||||
|
node->config = obj.settings;
|
||||||
|
spawnInfo.nodes.push_back(node);
|
||||||
|
for (LDFBaseData* data : obj.settings) {
|
||||||
|
if (data) {
|
||||||
|
if (data->GetKey() == u"spawntemplate") {
|
||||||
|
spawnInfo.templateID = std::stoi(data->GetValueAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->GetKey() == u"spawner_node_id") {
|
||||||
|
node->nodeID = std::stoi(data->GetValueAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->GetKey() == u"spawner_name") {
|
||||||
|
spawnInfo.name = data->GetValueAsString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->GetKey() == u"max_to_spawn") {
|
||||||
|
spawnInfo.maxToSpawn = std::stoi(data->GetValueAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->GetKey() == u"spawner_active_on_load") {
|
||||||
|
spawnInfo.activeOnLoad = std::stoi(data->GetValueAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->GetKey() == u"active_on_load") {
|
||||||
|
spawnInfo.activeOnLoad = std::stoi(data->GetValueAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->GetKey() == u"respawn") {
|
||||||
|
if (data->GetValueType() == eLDFType::LDF_TYPE_FLOAT) // Floats are in seconds
|
||||||
|
{
|
||||||
|
spawnInfo.respawnTime = std::stof(data->GetValueAsString());
|
||||||
|
} else if (data->GetValueType() == eLDFType::LDF_TYPE_U32) // Ints are in ms?
|
||||||
|
{
|
||||||
|
spawnInfo.respawnTime = std::stoul(data->GetValueAsString()) / 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (data->GetKey() == u"spawnsGroupOnSmash") {
|
||||||
|
spawnInfo.spawnsOnSmash = std::stoi(data->GetValueAsString());
|
||||||
|
}
|
||||||
|
if (data->GetKey() == u"spawnNetNameForSpawnGroupOnSmash") {
|
||||||
|
spawnInfo.spawnOnSmashGroupName = data->GetValueAsString();
|
||||||
|
}
|
||||||
|
if (data->GetKey() == u"groupID") { // Load object groups
|
||||||
|
std::string groupStr = data->GetValueAsString();
|
||||||
|
spawnInfo.groups = GeneralUtils::SplitString(groupStr, ';');
|
||||||
|
spawnInfo.groups.erase(spawnInfo.groups.end() - 1);
|
||||||
|
}
|
||||||
|
if (data->GetKey() == u"no_auto_spawn") {
|
||||||
|
spawnInfo.noAutoSpawn = static_cast<LDFData<bool>*>(data)->GetValue();
|
||||||
|
}
|
||||||
|
if (data->GetKey() == u"no_timed_spawn") {
|
||||||
|
spawnInfo.noTimedSpawn = static_cast<LDFData<bool>*>(data)->GetValue();
|
||||||
|
}
|
||||||
|
if (data->GetKey() == u"spawnActivator") {
|
||||||
|
spawnInfo.spawnActivator = static_cast<LDFData<bool>*>(data)->GetValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Game::zoneManager->MakeSpawner(spawnInfo);
|
||||||
|
}
|
||||||
|
|
||||||
const void Level::PrintAllObjects() {
|
const void Level::PrintAllObjects() {
|
||||||
for (std::map<uint32_t, Header>::iterator it = m_ChunkHeaders.begin(); it != m_ChunkHeaders.end(); ++it) {
|
for (std::map<uint32_t, Header>::iterator it = m_ChunkHeaders.begin(); it != m_ChunkHeaders.end(); ++it) {
|
||||||
if (it->second.id == Level::ChunkTypeID::SceneObjectData) {
|
if (it->second.id == Level::ChunkTypeID::SceneObjectData) {
|
||||||
@ -230,74 +300,7 @@ void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (obj.lot == 176) { //Spawner
|
if (obj.lot == 176) { //Spawner
|
||||||
SpawnerInfo spawnInfo = SpawnerInfo();
|
MakeSpawner(obj);
|
||||||
SpawnerNode* node = new SpawnerNode();
|
|
||||||
spawnInfo.templateID = obj.lot;
|
|
||||||
spawnInfo.spawnerID = obj.id;
|
|
||||||
spawnInfo.templateScale = obj.scale;
|
|
||||||
node->position = obj.position;
|
|
||||||
node->rotation = obj.rotation;
|
|
||||||
node->config = obj.settings;
|
|
||||||
spawnInfo.nodes.push_back(node);
|
|
||||||
for (LDFBaseData* data : obj.settings) {
|
|
||||||
if (data) {
|
|
||||||
if (data->GetKey() == u"spawntemplate") {
|
|
||||||
spawnInfo.templateID = std::stoi(data->GetValueAsString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data->GetKey() == u"spawner_node_id") {
|
|
||||||
node->nodeID = std::stoi(data->GetValueAsString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data->GetKey() == u"spawner_name") {
|
|
||||||
spawnInfo.name = data->GetValueAsString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data->GetKey() == u"max_to_spawn") {
|
|
||||||
spawnInfo.maxToSpawn = std::stoi(data->GetValueAsString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data->GetKey() == u"spawner_active_on_load") {
|
|
||||||
spawnInfo.activeOnLoad = std::stoi(data->GetValueAsString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data->GetKey() == u"active_on_load") {
|
|
||||||
spawnInfo.activeOnLoad = std::stoi(data->GetValueAsString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data->GetKey() == u"respawn") {
|
|
||||||
if (data->GetValueType() == eLDFType::LDF_TYPE_FLOAT) // Floats are in seconds
|
|
||||||
{
|
|
||||||
spawnInfo.respawnTime = std::stof(data->GetValueAsString());
|
|
||||||
} else if (data->GetValueType() == eLDFType::LDF_TYPE_U32) // Ints are in ms?
|
|
||||||
{
|
|
||||||
spawnInfo.respawnTime = std::stoul(data->GetValueAsString()) / 1000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data->GetKey() == u"spawnsGroupOnSmash") {
|
|
||||||
spawnInfo.spawnsOnSmash = std::stoi(data->GetValueAsString());
|
|
||||||
}
|
|
||||||
if (data->GetKey() == u"spawnNetNameForSpawnGroupOnSmash") {
|
|
||||||
spawnInfo.spawnOnSmashGroupName = data->GetValueAsString();
|
|
||||||
}
|
|
||||||
if (data->GetKey() == u"groupID") { // Load object groups
|
|
||||||
std::string groupStr = data->GetValueAsString();
|
|
||||||
spawnInfo.groups = GeneralUtils::SplitString(groupStr, ';');
|
|
||||||
spawnInfo.groups.erase(spawnInfo.groups.end() - 1);
|
|
||||||
}
|
|
||||||
if (data->GetKey() == u"no_auto_spawn") {
|
|
||||||
spawnInfo.noAutoSpawn = static_cast<LDFData<bool>*>(data)->GetValue();
|
|
||||||
}
|
|
||||||
if (data->GetKey() == u"no_timed_spawn") {
|
|
||||||
spawnInfo.noTimedSpawn = static_cast<LDFData<bool>*>(data)->GetValue();
|
|
||||||
}
|
|
||||||
if (data->GetKey() == u"spawnActivator") {
|
|
||||||
spawnInfo.spawnActivator = static_cast<LDFData<bool>*>(data)->GetValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Spawner* spawner = new Spawner(spawnInfo);
|
|
||||||
Game::zoneManager->AddSpawner(obj.id, spawner);
|
|
||||||
} else { //Regular object
|
} else { //Regular object
|
||||||
EntityInfo info;
|
EntityInfo info;
|
||||||
info.spawnerID = 0;
|
info.spawnerID = 0;
|
||||||
|
@ -54,6 +54,8 @@ public:
|
|||||||
Level(Zone* parentZone, const std::string& filepath);
|
Level(Zone* parentZone, const std::string& filepath);
|
||||||
~Level();
|
~Level();
|
||||||
|
|
||||||
|
static void MakeSpawner(SceneObject obj);
|
||||||
|
|
||||||
const void PrintAllObjects();
|
const void PrintAllObjects();
|
||||||
|
|
||||||
std::map<uint32_t, Header> m_ChunkHeaders;
|
std::map<uint32_t, Header> m_ChunkHeaders;
|
||||||
|
Loading…
Reference in New Issue
Block a user