From fcbd273cffa0d5724ef10fdaa742cc983308249f Mon Sep 17 00:00:00 2001 From: Unreal Karaulov Date: Mon, 18 Dec 2023 08:34:31 +0300 Subject: [PATCH] Fix error in fgd parser while merge fgds Fix error in fgd parser while merge fgds --- cfg/language.ini | 2 -- cfg/language_ru.ini | 2 -- src/bsp/Bsp.cpp | 8 +++---- src/editor/Fgd.cpp | 41 ++++++++++++++++++++++++++------ src/editor/Fgd.h | 13 +++++----- src/editor/Gui.cpp | 58 ++++++++++++++++++++++++++++++--------------- 6 files changed, 84 insertions(+), 40 deletions(-) diff --git a/cfg/language.ini b/cfg/language.ini index a077cce8..8028a841 100644 --- a/cfg/language.ini +++ b/cfg/language.ini @@ -651,7 +651,6 @@ LANG_0651 = Texture browser LANG_0652 = Internal LANG_0653 = Internal Names LANG_0654 = Class: -LANG_0655 = classname_popup LANG_0656 = Change Class LANG_0657 = ##tabs LANG_0658 = Attributes @@ -1095,7 +1094,6 @@ LANG_1100 = Map LANG_1101 = Debug LANG_1102 = TEST PVS VIS DATA LANG_1103 = Keyvalue Editor -LANG_1104 = classname_popup LANG_1105 = No entity selected LANG_1106 = keyvalcols LANG_1107 = ##xpos diff --git a/cfg/language_ru.ini b/cfg/language_ru.ini index 6d78db67..fb4968c0 100644 --- a/cfg/language_ru.ini +++ b/cfg/language_ru.ini @@ -651,7 +651,6 @@ LANG_0651 = Браузер текстур LANG_0652 = Вшитые LANG_0653 = Используемые LANG_0654 = Класс: -LANG_0655 = classname_popup LANG_0656 = Сменить класс LANG_0657 = ##tabs LANG_0658 = Атрибуты @@ -1095,7 +1094,6 @@ LANG_1100 = Карта LANG_1101 = Отладка LANG_1102 = Tест PVS-данных VIS LANG_1103 = Свойства сущности -LANG_1104 = classname_popup LANG_1105 = Сущности не выбраны LANG_1106 = keyvalcols LANG_1107 = ##xpos diff --git a/src/bsp/Bsp.cpp b/src/bsp/Bsp.cpp index f321497a..b5954b7b 100644 --- a/src/bsp/Bsp.cpp +++ b/src/bsp/Bsp.cpp @@ -6326,7 +6326,7 @@ int Bsp::duplicate_model(int modelIdx) append_lump(LUMP_EDGES, &newEdges[0], sizeof(BSPEDGE32) * newEdges.size()); if (newFaces.size()) { - if (g_verbose) + /*if (g_verbose) { print_log("Origin model faces: {}\n", models[modelIdx].nFaces); print_log("Base light offset = {} copy faces {}\n", lightDataLength, newFaces.size()); @@ -6334,7 +6334,7 @@ int Bsp::duplicate_model(int modelIdx) { print_log("Face {} light offset = {}\n", i, newFaces[i].nLightmapOffset); } - } + }*/ append_lump(LUMP_FACES, &newFaces[0], sizeof(BSPFACE32) * newFaces.size()); } if (newNodes.size()) @@ -6349,11 +6349,11 @@ int Bsp::duplicate_model(int modelIdx) append_lump(LUMP_VERTICES, &newVerts[0], sizeof(vec3) * newVerts.size()); if (newLightmaps.size()) { - if (g_verbose) + /*if (g_verbose) { print_log("Added lightmap, size {}\n", newLightmaps.size()); print_log("Data {}x{}x{}\n", newLightmaps[0].r, newLightmaps[0].g, newLightmaps[0].b); - } + }*/ append_lump(LUMP_LIGHTING, &newLightmaps[0], sizeof(COLOR3) * newLightmaps.size()); save_undo_lightmaps(); resize_all_lightmaps(); diff --git a/src/editor/Fgd.cpp b/src/editor/Fgd.cpp index e538ca22..ce9446fe 100644 --- a/src/editor/Fgd.cpp +++ b/src/editor/Fgd.cpp @@ -30,7 +30,7 @@ Fgd::~Fgd() } } -FgdClass* Fgd::getFgdClass(const std::string & cname) +FgdClass* Fgd::getFgdClass(const std::string& cname) { auto it = std::find_if(classes.begin(), classes.end(), [&cname](const auto& fgdClass) { return fgdClass->name == cname; @@ -39,6 +39,15 @@ FgdClass* Fgd::getFgdClass(const std::string & cname) return (it != classes.end()) ? *it : NULL; } +FgdClass* Fgd::getFgdClass(const std::string& cname, int type) +{ + auto it = std::find_if(classes.begin(), classes.end(), [&cname,&type](const auto& fgdClass) { + return fgdClass->name == cname && fgdClass->classType == type; + }); + + return (it != classes.end()) ? *it : NULL; +} + void Fgd::merge(Fgd* other) { if (path.empty() && other->path.size()) @@ -66,6 +75,10 @@ void Fgd::merge(Fgd* other) classes.push_back(new FgdClass(*otherClass)); } } + + processClassInheritance(); + createEntGroups(); + setSpawnflagNames(); } bool Fgd::parse() @@ -392,18 +405,18 @@ void Fgd::parseClassHeader(FgdClass& fgdClass) } } - if (headerParts.size() == 1) + if (headerParts.size() <= 1) { print_log(get_localized_string(LANG_1048), lineNum, name); return; } + std::vector nameParts = splitStringIgnoringQuotes(headerParts[1], ":"); if (nameParts.size() >= 1) { fgdClass.name = trimSpaces(nameParts[0]); // strips brackets if they're there - fgdClass.name = fgdClass.name.substr(0, fgdClass.name.find(' ')); - + // fgdClass.name = fgdClass.name.substr(0, fgdClass.name.find(' ')); nameParts.erase(nameParts.begin()); } if (nameParts.size() >= 1) @@ -772,6 +785,9 @@ void FgdClass::getBaseClasses(Fgd* fgd, std::vector& inheritanceList) void Fgd::createEntGroups() { + solidEntGroups.clear(); + pointEntGroups.clear(); + std::set addedPointGroups; std::set addedSolidGroups; @@ -780,7 +796,12 @@ void Fgd::createEntGroups() if (classes[i]->classType == FGD_CLASS_BASE || classes[i]->name == "worldspawn") continue; std::string cname = classes[i]->name; - std::string groupName = cname.substr(0, cname.find('_')); + std::string groupName = cname; + + if (cname.find('_') != std::string::npos) + { + groupName = cname.substr(0, cname.find('_')); + } bool isPointEnt = classes[i]->classType == FGD_CLASS_POINT; @@ -796,21 +817,27 @@ void Fgd::createEntGroups() targetSet.insert(groupName); } + bool added = false; for (int k = 0; k < targetGroup.size(); k++) { if (targetGroup[k].groupName == groupName) { + added = true; targetGroup[k].classes.push_back(classes[i]); break; } } + if (!added && targetGroup.size()) + { + targetGroup[0].classes.push_back(classes[i]); + } } FgdGroup otherPointEnts; otherPointEnts.groupName = "other"; for (int i = 0; i < pointEntGroups.size(); i++) { - if (pointEntGroups[i].classes.size() == 1) + if (pointEntGroups[i].classes.size() <= 1) { otherPointEnts.classes.push_back(pointEntGroups[i].classes[0]); pointEntGroups.erase(pointEntGroups.begin() + i); @@ -823,7 +850,7 @@ void Fgd::createEntGroups() otherSolidEnts.groupName = "other"; for (int i = 0; i < solidEntGroups.size(); i++) { - if (solidEntGroups[i].classes.size() == 1) + if (solidEntGroups[i].classes.size() <= 1) { otherSolidEnts.classes.push_back(solidEntGroups[i].classes[0]); solidEntGroups.erase(solidEntGroups.begin() + i); diff --git a/src/editor/Fgd.h b/src/editor/Fgd.h index c642a7a1..601c9a97 100644 --- a/src/editor/Fgd.h +++ b/src/editor/Fgd.h @@ -3,16 +3,16 @@ #include "Wad.h" #include "Entity.h" -enum FGD_CLASS_TYPES +enum FGD_CLASS_TYPES : int { - FGD_CLASS_BASE, + FGD_CLASS_BASE = 0, FGD_CLASS_SOLID, FGD_CLASS_POINT }; -enum FGD_KEY_TYPES +enum FGD_KEY_TYPES : int { - FGD_KEY_INTEGER, + FGD_KEY_INTEGER = 0, FGD_KEY_STRING, FGD_KEY_CHOICES, FGD_KEY_FLAGS, @@ -91,7 +91,7 @@ struct FgdClass // default to the purple cube mins = vec3(-8, -8, -8); maxs = vec3(8, 8, 8); - color = {220, 0, 220}; + color = { 220, 0, 220 }; offset = vec3(0, 0, 0); modelSkin = modelBody = modelSequence = 0; } @@ -128,7 +128,8 @@ class Fgd bool parse(); void merge(Fgd* other); - FgdClass* getFgdClass(const std::string & cname); + FgdClass* getFgdClass(const std::string& cname); + FgdClass* getFgdClass(const std::string& cname, int type); private: int lineNum = 0; diff --git a/src/editor/Gui.cpp b/src/editor/Gui.cpp index cdbe82bc..be6c5c96 100644 --- a/src/editor/Gui.cpp +++ b/src/editor/Gui.cpp @@ -438,7 +438,7 @@ void ExportModel(Bsp* src_map, int id, int ExportType, bool movemodel) while (tmpMap->models[0].nVisLeafs >= tmpMap->leafCount) tmpMap->create_leaf(CONTENTS_EMPTY); - + tmpMap->models[0].nVisLeafs = tmpMap->leafCount - 1; for (int i = 0; i < tmpMap->leafCount; i++) @@ -825,8 +825,8 @@ void Gui::drawBspContexMenu() ImGui::BeginTooltip(); ImGui::TextUnformatted(get_localized_string(LANG_0465).c_str()); ImGui::EndTooltip(); - } - + } + /*if (ImGui::MenuItem("ADD TO WORLDSPAWN!", 0, false, !app->isLoading && allowDuplicate)) { print_log(get_localized_string(LANG_1054), app->pickInfo.selectedEnts.size()); @@ -3969,20 +3969,44 @@ void Gui::drawKeyvalueEditor() Entity* ent = map->ents[entIdx]; std::string cname = ent->keyvalues["classname"]; - FgdClass* fgdClass = app->fgd->getFgdClass(cname); + FgdClass* fgdClass = app->fgd->getFgdClass(cname, FGD_CLASS_POINT); + std::vector targetGroup = app->fgd->pointEntGroups; + + + if (!fgdClass || (ent->hasKey("model") && + (ent->keyvalues["model"].starts_with('*') || toLowerCase(ent->keyvalues["model"]).ends_with(".bsp")))) + { + FgdClass* tmpfgdClass = app->fgd->getFgdClass(cname, FGD_CLASS_SOLID); + if (tmpfgdClass) + { + targetGroup = app->fgd->solidEntGroups; + fgdClass = tmpfgdClass; + } + } ImGui::PushFont(largeFont); ImGui::AlignTextToFramePadding(); ImGui::Text(get_localized_string(LANG_0654).c_str()); ImGui::SameLine(); if (cname != "worldspawn") { + if (!targetGroup.size()) + { + ImGui::BeginDisabled(); + } + if (ImGui::Button((" " + cname + " ").c_str())) - ImGui::OpenPopup(get_localized_string(LANG_0655).c_str()); + ImGui::OpenPopup("classname_popup"); + + if (!targetGroup.size()) + { + ImGui::EndDisabled(); + } } else { ImGui::Text(cname.c_str()); } + ImGui::PopFont(); if (fgdClass) @@ -4000,27 +4024,18 @@ void Gui::drawKeyvalueEditor() } - if (ImGui::BeginPopup(get_localized_string(LANG_1104).c_str())) + if (ImGui::BeginPopup("classname_popup")) { ImGui::Text(get_localized_string(LANG_0656).c_str()); ImGui::Separator(); - std::vector targetGroup = app->fgd->pointEntGroups; - - if (fgdClass) + for (FgdGroup& group : targetGroup) { - if (fgdClass->classType == FGD_CLASS_TYPES::FGD_CLASS_SOLID) + if (!group.classes.size()) { - targetGroup = app->fgd->solidEntGroups; + ImGui::BeginDisabled(); } - } - else if (ent->hasKey("model") && ent->keyvalues["model"].starts_with('*')) - { - targetGroup = app->fgd->solidEntGroups; - } - for (FgdGroup& group : targetGroup) - { if (ImGui::BeginMenu(group.groupName.c_str())) { for (int k = 0; k < group.classes.size(); k++) @@ -4035,6 +4050,11 @@ void Gui::drawKeyvalueEditor() ImGui::EndMenu(); } + + if (!group.classes.size()) + { + ImGui::EndDisabled(); + } } ImGui::EndPopup(); @@ -5531,7 +5551,7 @@ void Gui::drawLog() ImGui::PushStyleColor(ImGuiCol_Text, imguiColorFromConsole(color_buffer_copy[line_no])); clipper.ItemsHeight = ImGui::GetTextLineHeight(); ImGui::TextUnformatted(log_buffer_copy[line_no].c_str()); - if (line_no < log_buffer_copy.size() && log_buffer_copy[line_no].size() && log_buffer_copy[line_no][log_buffer_copy[line_no].size() - 1] != '\n') + if (line_no < log_buffer_copy.size() && log_buffer_copy[line_no].size() && log_buffer_copy[line_no][log_buffer_copy[line_no].size() - 1] != '\n') { clipper.ItemsHeight = 0.0f; ImGui::SameLine();