Add ldf controlls to vanity npc tools

make vanity npc use more forgiving
This commit is contained in:
Aaron Kimbre 2023-01-11 01:10:14 -06:00
parent e67f310632
commit ce39e3ad6b
2 changed files with 69 additions and 59 deletions

View File

@ -65,17 +65,21 @@ void VanityUtilities::SpawnVanity() {
npcIndex = GeneralUtils::GenerateRandomNumber<uint32_t>(0, npcList.size() - 1); npcIndex = GeneralUtils::GenerateRandomNumber<uint32_t>(0, npcList.size() - 1);
} }
const auto& npc = npcList[npcIndex]; auto& npc = npcList[npcIndex];
taken.push_back(npcIndex); taken.push_back(npcIndex);
// Spawn the NPC // Spawn the NPC
std::vector<LDFBaseData*> data = { new LDFData<std::vector<std::u16string>>( Game::logger->Log("VanityUtilities", "ldf size is %i", npc.ldf.size());
u"syncLDF", { u"custom_script_client" }), if (npc.ldf.empty()) {
new LDFData<std::u16string>(u"custom_script_client", u"scripts\\ai\\SPEC\\MISSION_MINIGAME_CLIENT.lua") }; npc.ldf = {
new LDFData<std::vector<std::u16string>>(u"syncLDF", { u"custom_script_client" }),
new LDFData<std::u16string>(u"custom_script_client", u"scripts\\ai\\SPEC\\MISSION_MINIGAME_CLIENT.lua")
};
}
// Spawn the NPC // Spawn the NPC
auto* npcEntity = SpawnNPC(npc.m_LOT, npc.m_Name, location.m_Position, location.m_Rotation, npc.m_Equipment, data); auto* npcEntity = SpawnNPC(npc.m_LOT, npc.m_Name, location.m_Position, location.m_Rotation, npc.m_Equipment, npc.ldf);
npcEntity->SetVar<std::vector<std::string>>(u"chats", m_PartyPhrases); npcEntity->SetVar<std::vector<std::string>>(u"chats", m_PartyPhrases);
@ -86,11 +90,11 @@ void VanityUtilities::SpawnVanity() {
} }
// Loop through all NPCs // Loop through all NPCs
for (const auto& pair : m_NPCs) { for (auto& npc : m_NPCs) {
if (pair.m_Locations.find(Game::server->GetZoneID()) == pair.m_Locations.end()) if (npc.m_Locations.find(Game::server->GetZoneID()) == npc.m_Locations.end())
continue; continue;
const std::vector<VanityNPCLocation>& locations = pair.m_Locations.at(Game::server->GetZoneID()); const std::vector<VanityNPCLocation>& locations = npc.m_Locations.at(Game::server->GetZoneID());
// Pick a random location // Pick a random location
const auto& location = locations[GeneralUtils::GenerateRandomNumber<int>( const auto& location = locations[GeneralUtils::GenerateRandomNumber<int>(
@ -101,27 +105,30 @@ void VanityUtilities::SpawnVanity() {
continue; continue;
} }
std::vector<LDFBaseData*> data = { new LDFData<std::vector<std::u16string>>( if (npc.ldf.empty()) {
u"syncLDF", { u"custom_script_client" }), npc.ldf = {
new LDFData<std::u16string>(u"custom_script_client", u"scripts\\ai\\SPEC\\MISSION_MINIGAME_CLIENT.lua") }; new LDFData<std::vector<std::u16string>>(u"syncLDF", { u"custom_script_client" }),
new LDFData<std::u16string>(u"custom_script_client", u"scripts\\ai\\SPEC\\MISSION_MINIGAME_CLIENT.lua")
};
}
// Spawn the NPC // Spawn the NPC
auto* npc = SpawnNPC(pair.m_LOT, pair.m_Name, location.m_Position, location.m_Rotation, pair.m_Equipment, data); auto* npcEntity = SpawnNPC(npc.m_LOT, npc.m_Name, location.m_Position, location.m_Rotation, npc.m_Equipment, npc.ldf);
npc->SetVar<std::vector<std::string>>(u"chats", pair.m_Phrases); npcEntity->SetVar<std::vector<std::string>>(u"chats", npc.m_Phrases);
auto* scriptComponent = npc->GetComponent<ScriptComponent>(); auto* scriptComponent = npcEntity->GetComponent<ScriptComponent>();
if (scriptComponent != nullptr) { if (scriptComponent != nullptr) {
scriptComponent->SetScript(pair.m_Script); scriptComponent->SetScript(npc.m_Script);
scriptComponent->SetSerialized(false); scriptComponent->SetSerialized(false);
for (const auto& pair : pair.m_Flags) { for (const auto& npc : npc.m_Flags) {
npc->SetVar<bool>(GeneralUtils::ASCIIToUTF16(pair.first), pair.second); npcEntity->SetVar<bool>(GeneralUtils::ASCIIToUTF16(npc.first), npc.second);
} }
} }
SetupNPCTalk(npc); SetupNPCTalk(npcEntity);
} }
if (zoneID == 1200) { if (zoneID == 1200) {
@ -266,10 +273,7 @@ void VanityUtilities::ParseXML(const std::string& file) {
// Get the NPC name // Get the NPC name
auto* name = npc->Attribute("name"); auto* name = npc->Attribute("name");
if (name == nullptr) { if (!name) name = "";
Game::logger->Log("VanityUtilities", "Failed to parse NPC name");
continue;
}
// Get the NPC lot // Get the NPC lot
auto* lot = npc->Attribute("lot"); auto* lot = npc->Attribute("lot");
@ -281,16 +285,11 @@ void VanityUtilities::ParseXML(const std::string& file) {
// Get the equipment // Get the equipment
auto* equipment = npc->FirstChildElement("equipment"); auto* equipment = npc->FirstChildElement("equipment");
if (equipment == nullptr) {
Game::logger->Log("VanityUtilities", "Failed to parse NPC equipment");
continue;
}
auto* text = equipment->GetText();
std::vector<LOT> inventory; std::vector<LOT> inventory;
if (equipment) {
auto* text = equipment->GetText();
if (text != nullptr) { if (text != nullptr) {
std::string equipmentString(text); std::string equipmentString(text);
@ -300,45 +299,54 @@ void VanityUtilities::ParseXML(const std::string& file) {
inventory.push_back(std::stoi(item)); inventory.push_back(std::stoi(item));
} }
} }
}
// Get the phrases // Get the phrases
auto* phrases = npc->FirstChildElement("phrases"); auto* phrases = npc->FirstChildElement("phrases");
if (phrases == nullptr) { std::vector<std::string> phraseList = {};
Game::logger->Log("VanityUtilities", "Failed to parse NPC phrases");
continue;
}
std::vector<std::string> phraseList;
if (phrases) {
for (auto* phrase = phrases->FirstChildElement("phrase"); phrase != nullptr; for (auto* phrase = phrases->FirstChildElement("phrase"); phrase != nullptr;
phrase = phrase->NextSiblingElement("phrase")) { phrase = phrase->NextSiblingElement("phrase")) {
// Get the phrase // Get the phrase
auto* text = phrase->GetText(); auto* text = phrase->GetText();
if (text == nullptr) { if (text == nullptr) {
Game::logger->Log("VanityUtilities", "Failed to parse NPC phrase"); Game::logger->Log("VanityUtilities", "Failed to parse NPC phrase");
continue; continue;
} }
phraseList.push_back(text); phraseList.push_back(text);
} }
}
// Get the script // Get the script
auto* scriptElement = npc->FirstChildElement("script"); auto* scriptElement = npc->FirstChildElement("script");
std::string scriptName; std::string scriptName = "";
if (scriptElement != nullptr) { if (scriptElement != nullptr) {
auto* scriptNameAttribute = scriptElement->Attribute("name"); auto* scriptNameAttribute = scriptElement->Attribute("name");
if (scriptNameAttribute) scriptName = scriptNameAttribute;
if (scriptNameAttribute == nullptr) {
Game::logger->Log("VanityUtilities", "Failed to parse NPC script name");
continue;
} }
scriptName = scriptNameAttribute; auto* ldfElement = npc->FirstChildElement("ldf");
std::vector<std::u16string> keys = {};
std::vector<LDFBaseData*> ldf = {};
if(ldfElement) {
for (auto* entry = ldfElement->FirstChildElement("entry"); entry != nullptr;
entry = entry->NextSiblingElement("entry")) {
// Get the ldf data
auto* data = entry->Attribute("data");
if (!data) continue;
LDFBaseData* ldfData = LDFBaseData::DataFromString(data);
keys.push_back(ldfData->GetKey());
ldf.push_back(ldfData);
} }
}
if (!keys.empty()) ldf.push_back(new LDFData<std::vector<std::u16string>>(u"syncLDF", keys));
VanityNPC npcData; VanityNPC npcData;
npcData.m_Name = name; npcData.m_Name = name;
@ -346,6 +354,7 @@ void VanityUtilities::ParseXML(const std::string& file) {
npcData.m_Equipment = inventory; npcData.m_Equipment = inventory;
npcData.m_Phrases = phraseList; npcData.m_Phrases = phraseList;
npcData.m_Script = scriptName; npcData.m_Script = scriptName;
npcData.ldf = ldf;
// Get flags // Get flags
auto* flags = npc->FirstChildElement("flags"); auto* flags = npc->FirstChildElement("flags");

View File

@ -20,6 +20,7 @@ struct VanityNPC
std::string m_Script; std::string m_Script;
std::map<std::string, bool> m_Flags; std::map<std::string, bool> m_Flags;
std::map<uint32_t, std::vector<VanityNPCLocation>> m_Locations; std::map<uint32_t, std::vector<VanityNPCLocation>> m_Locations;
std::vector<LDFBaseData*> ldf;
}; };
struct VanityParty struct VanityParty