diff --git a/cfg/language.ini b/cfg/language.ini index 66b9c47b..b6b866b9 100644 --- a/cfg/language.ini +++ b/cfg/language.ini @@ -1179,5 +1179,6 @@ LANG_1177 = Clipnodes LANG_1178 = ent_context LANG_1179 = (WIP) LANG_1180 = No entity selected +LANG_FGD_BAD_OFFSET = ERROR: Expected 3 components in offset() property (line {}) in FGD {}\n LANG_DUMP_TEX = Dump Textures LANG_DUMP_TEX_DESC = Dump all loaded textures to .png files. \ No newline at end of file diff --git a/src/bsp/Entity.cpp b/src/bsp/Entity.cpp index e9efa37b..cc8f8b5e 100644 --- a/src/bsp/Entity.cpp +++ b/src/bsp/Entity.cpp @@ -4,22 +4,15 @@ #include "util.h" #include -Entity::Entity(const std::string& classname) -{ - cachedModelIdx = -2; - targetsCached = false; - rendermode = kRenderNormal; - renderamt = 0; - renderfx = kRenderFxNone; - rendercolor = vec3(1.0f, 1.0f, 1.0f); - setOrAddKeyvalue("classname", classname); -} void Entity::addKeyvalue(const std::string key, const std::string value, bool multisupport) { if (!strlen(key)) return; + if (key == "origin") + originInited = false; + int dup = 1; if (keyvalues.find(key) == keyvalues.end()) { @@ -200,7 +193,11 @@ bool Entity::isWorldSpawn() vec3 Entity::getOrigin() { - return hasKey("origin") ? parseVector(keyvalues["origin"]) : vec3(); + if (originInited) + return origin; + originInited = true; + origin = hasKey("origin") ? parseVector(keyvalues["origin"]) : vec3(); + return origin; } // TODO: maybe store this in a text file or something diff --git a/src/bsp/Entity.h b/src/bsp/Entity.h index 751193be..d8b727cd 100644 --- a/src/bsp/Entity.h +++ b/src/bsp/Entity.h @@ -22,19 +22,27 @@ class Entity renderamt = 0; renderfx = kRenderFxNone; rendercolor = vec3(1.0f, 1.0f, 1.0f); + origin = vec3(0.0f, 0.0f, 0.0f); + originInited = false; } - Entity(const std::string& classname); - ~Entity(void) + + Entity(const std::string& classname) { - cachedTargets.clear(); - keyOrder.clear(); - keyvalues.clear(); cachedModelIdx = -2; targetsCached = false; rendermode = kRenderNormal; renderamt = 0; renderfx = kRenderFxNone; rendercolor = vec3(1.0f, 1.0f, 1.0f); + originInited = false; + setOrAddKeyvalue("classname", classname); + } + + ~Entity(void) + { + cachedTargets.clear(); + keyOrder.clear(); + keyvalues.clear(); } void addKeyvalue(const std::string key, const std::string value, bool multisupport = false); @@ -67,6 +75,8 @@ class Entity size_t getMemoryUsage(); // aproximate + bool originInited = false; + vec3 origin = vec3(0.0f, 0.0f, 0.0f); int rendermode = kRenderNormal; int renderamt = 0; int renderfx = kRenderFxNone; diff --git a/src/editor/Fgd.cpp b/src/editor/Fgd.cpp index e5e57562..0bf977d0 100644 --- a/src/editor/Fgd.cpp +++ b/src/editor/Fgd.cpp @@ -224,14 +224,27 @@ void Fgd::parseClassHeader(FgdClass& fgdClass) if (nums.size() == 3) { - fgdClass.color = {(unsigned char)atoi(nums[0].c_str()), (unsigned char)atoi(nums[1].c_str()), (unsigned char)atoi(nums[2].c_str())}; + fgdClass.color = { (unsigned char)atoi(nums[0].c_str()), (unsigned char)atoi(nums[1].c_str()), (unsigned char)atoi(nums[2].c_str()) }; } else { - logf(get_localized_string(LANG_0306),lineNum,name); + logf(get_localized_string(LANG_0306), lineNum, name); } fgdClass.colorSet = true; } + else if (lpart.starts_with("offset(")) + { + std::vector nums = splitString(getValueInParens(typeParts[i]), " "); + + if (nums.size() == 3) + { + fgdClass.offset = { (float)atof(nums[0].c_str()), (float)atof(nums[1].c_str()),(float)atof(nums[2].c_str()) }; + } + else + { + logf(get_localized_string("LANG_FGD_BAD_OFFSET"), lineNum, name); + } + } else if (lpart.starts_with("studio(")) { std::string mdlpath = getValueInParens(typeParts[i]); diff --git a/src/editor/Fgd.h b/src/editor/Fgd.h index 754a3740..26b748f9 100644 --- a/src/editor/Fgd.h +++ b/src/editor/Fgd.h @@ -66,6 +66,7 @@ struct FgdClass vec3 mins; vec3 maxs; COLOR3 color; + vec3 offset; hashmap otherTypes; // unrecognized types // if false, then need to get props from the base class @@ -87,6 +88,7 @@ struct FgdClass mins = vec3(-8, -8, -8); maxs = vec3(8, 8, 8); color = {220, 0, 220}; + offset = vec3(0, 0, 0); modelSkin = modelBody = modelSequence = 0; } diff --git a/src/editor/Renderer.cpp b/src/editor/Renderer.cpp index d3811696..eaa59a8a 100644 --- a/src/editor/Renderer.cpp +++ b/src/editor/Renderer.cpp @@ -135,7 +135,6 @@ Renderer::Renderer() logf(get_localized_string(LANG_0902)); return; } - showDragAxes = true; g_settings.loadDefault(); g_settings.load(); @@ -225,6 +224,8 @@ Renderer::Renderer() oldLeftMouse = curLeftMouse = oldRightMouse = curRightMouse = 0; + blockMoving = false; + showDragAxes = true; gui->init(); @@ -349,21 +350,21 @@ void Renderer::renderLoop() glDepthMask(GL_TRUE); glDepthFunc(GL_LESS); - {//Update keyboard / mouse state - oldLeftMouse = curLeftMouse; - curLeftMouse = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT); - oldRightMouse = curRightMouse; - curRightMouse = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT); + //Update keyboard / mouse state + oldLeftMouse = curLeftMouse; + curLeftMouse = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT); + oldRightMouse = curRightMouse; + curRightMouse = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT); - DebugKeyPressed = pressed[GLFW_KEY_F1]; + DebugKeyPressed = pressed[GLFW_KEY_F1]; - anyCtrlPressed = pressed[GLFW_KEY_LEFT_CONTROL] || pressed[GLFW_KEY_RIGHT_CONTROL]; - anyAltPressed = pressed[GLFW_KEY_LEFT_ALT] || pressed[GLFW_KEY_RIGHT_ALT]; - anyShiftPressed = pressed[GLFW_KEY_LEFT_SHIFT] || pressed[GLFW_KEY_RIGHT_SHIFT]; + anyCtrlPressed = pressed[GLFW_KEY_LEFT_CONTROL] || pressed[GLFW_KEY_RIGHT_CONTROL]; + anyAltPressed = pressed[GLFW_KEY_LEFT_ALT] || pressed[GLFW_KEY_RIGHT_ALT]; + anyShiftPressed = pressed[GLFW_KEY_LEFT_SHIFT] || pressed[GLFW_KEY_RIGHT_SHIFT]; + + oldControl = canControl; + canControl = /*!gui->imgui_io->WantCaptureKeyboard && */ !gui->imgui_io->WantTextInput && !gui->imgui_io->WantCaptureMouseUnlessPopupClose; - oldControl = canControl; - canControl = /*!gui->imgui_io->WantCaptureKeyboard && */ !gui->imgui_io->WantTextInput && !gui->imgui_io->WantCaptureMouseUnlessPopupClose; - } if (curTime - lastTitleTime > 0.5) { @@ -1005,7 +1006,6 @@ void Renderer::drawEntConnections() void Renderer::controls() { - static bool blockMoving = false; if (blockMoving) { @@ -1797,6 +1797,7 @@ bool Renderer::transformAxisControls() axisDragStart = rounded; tmpEnt->setOrAddKeyvalue("origin", (rounded - getEntOffset(map, tmpEnt)).toKeyvalueString()); + map->getBspRender()->refreshEnt(tmpEntIdx); updateEntConnectionPositions(); diff --git a/src/editor/Renderer.h b/src/editor/Renderer.h index c5df7c5a..1d3adaac 100644 --- a/src/editor/Renderer.h +++ b/src/editor/Renderer.h @@ -165,6 +165,7 @@ class Renderer int transformMode = TRANSFORM_MODE_MOVE; int transformTarget = TRANSFORM_OBJECT; int pickMode = PICK_OBJECT; + bool blockMoving = false; bool showDragAxes = true; bool pickClickHeld = true; // true if the mouse button is still held after picking an object vec3 axisDragStart; diff --git a/src/util/util.cpp b/src/util/util.cpp index bb3e99d8..fdbcecc7 100644 --- a/src/util/util.cpp +++ b/src/util/util.cpp @@ -244,21 +244,21 @@ std::string toLowerCase(const std::string& s) return ret; } -std::string trimSpaces(std::string s) +std::string trimSpaces(const std::string & str) { - // Remove white space indents - size_t lineStart = s.find_first_not_of(" \t\n\r"); - if (lineStart == std::string::npos) - return ""; - - // Remove spaces after the last character - size_t lineEnd = s.find_last_not_of(" \t\n\r"); - if (lineEnd != std::string::npos && lineEnd < s.length() - 1) - s = s.substr(lineStart, (lineEnd + 1) - lineStart); - else - s = s.substr(lineStart); + if (str.empty()) + { + return str; + } - return s; + std::string result = str; + while (!result.empty() && std::isspace(result.front())) { + result.erase(result.begin()); + } + while (!result.empty() && std::isspace(result.back())) { + result.pop_back(); + } + return result; } int getTextureSizeInBytes(BSPMIPTEX* bspTexture, bool palette) diff --git a/src/util/util.h b/src/util/util.h index a5c3101f..ca580eef 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -104,7 +104,7 @@ void removeDir(const std::string& dirName); std::string toLowerCase(const std::string& s); -std::string trimSpaces(std::string s); +std::string trimSpaces(const std::string& str); int getTextureSizeInBytes(BSPMIPTEX* bspTexture, bool palette = false);