diff --git a/CMakeLists.txt b/CMakeLists.txt index 602550b74..b13acece1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,10 @@ # main project file. use it from a build sub-folder, see COMPILE for details +## setting the build type. +IF(NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") + SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Release RelWithDebInfo.") +ENDIF() + ## some generic CMake magic cmake_minimum_required(VERSION 2.8 FATAL_ERROR) project(dfhack) @@ -14,11 +19,6 @@ if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") message(FATAL_ERROR "In-source builds are not allowed.") endif() -## setting the build type. -IF(NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") - SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Release RelWithDebInfo.") -ENDIF() - # set up versioning. set(DF_VERSION_MAJOR "0") set(DF_VERSION_MINOR "31") diff --git a/plugins/vdig.cpp b/plugins/vdig.cpp index 65e763478..f8b2ea3fb 100644 --- a/plugins/vdig.cpp +++ b/plugins/vdig.cpp @@ -9,7 +9,7 @@ #include #include #include - +#include using std::vector; using std::string; using std::stack; @@ -63,8 +63,8 @@ DFhackCExport command_result digcircle (Core * c, vector & parameters) static bool filled = false; static circle_what what = circle_set; static e_designation type = designation_default; - static int r = 0; - auto saved_r = r; + static int diameter = 0; + auto saved_d = diameter; bool force_help = false; for(int i = 0; i < parameters.size();i++) { @@ -112,14 +112,14 @@ DFhackCExport command_result digcircle (Core * c, vector & parameters) { type = designation_channel; } - else if (!from_string(r,parameters[i], std::dec)) + else if (!from_string(diameter,parameters[i], std::dec)) { - r = saved_r; + diameter = saved_d; } } - if(r < 0) - r = -r; - if(force_help || r == 0) + if(diameter < 0) + diameter = -diameter; + if(force_help || diameter == 0) { c->con.print( "A command for easy designation of filled and hollow circles.\n" "\n" @@ -137,7 +137,7 @@ DFhackCExport command_result digcircle (Core * c, vector & parameters) " xstair = staircase up/down\n" " chan = dig channel\n" "\n" - " # = radius in tiles (default = 0)\n" + " # = diameter in tiles (default = 0)\n" "\n" "After you have set the options, the command called with no options\n" "repeats with the last selected parameters:\n" @@ -173,10 +173,16 @@ DFhackCExport command_result digcircle (Core * c, vector & parameters) auto b = MCache.BlockAt(at/16); if(!b || !b->valid) return false; - if(x == 0 || x == x_max - 1) + if(x == 0 || x == x_max * 16 - 1) + { + //c->con.print("not digging map border\n"); return false; - if(y == 0 || y == y_max - 1) + } + if(y == 0 || y == y_max * 16 - 1) + { + //c->con.print("not digging map border\n"); return false; + } uint16_t tt = MCache.tiletypeAt(at); t_designation des = MCache.designationAt(at); // could be potentially used to locate hidden constructions? @@ -242,53 +248,71 @@ DFhackCExport command_result digcircle (Core * c, vector & parameters) } return true; }; - int f = 1 - r; - int ddF_x = 1; - int ddF_y = -2 * r; - int x = 0; - int y = r; - if(!filled) - { - dig(cx, cy + r, cz); - dig(cx, cy - r, cz); - dig(cx + r, cy, cz); - dig(cx - r, cy, cz); + int r = diameter / 2; + int iter; + bool adjust; + if(diameter % 2) + { + // paint center + if(filled) + { + lineY(cx - r, cx + r, cy, cz); + } + else + { + dig(cx - r, cy, cz); + dig(cx + r, cy, cz); + } + adjust = false; + iter = 2; } else { - lineX(cy-r, cy+r, cx, cz); - lineY(cx-r, cx+r, cy, cz); + adjust = true; + iter = 1; } - - while(x < y) - { - if(f >= 0) - { - y--; - ddF_y += 2; - f += ddF_y; + int lastwhole = r; + for(; iter <= diameter - 1; iter +=2) + { + // top, bottom coords + int top = cy - ((iter + 1) / 2) + adjust; + int bottom = cy + ((iter + 1) / 2); + // see where the current 'line' intersects the circle + double val = std::sqrt(diameter*diameter - iter*iter); + // adjust for circles with odd diameter + if(!adjust) + val -= 1; + // map the found value to the DF grid + double whole; + double fraction = std::modf(val / 2.0, & whole); + if (fraction > 0.5) + whole += 1.0; + int right = cx + whole; + int left = cx - whole + adjust; + int diff = lastwhole - whole; + // paint + if(filled || iter == diameter - 1) + { + lineY(left, right, top , cz); + lineY(left, right, bottom , cz); } - x++; - ddF_x += 2; - f += ddF_x; - if(!filled) + else { - dig(cx + x, cy + y, cz); - dig(cx - x, cy + y, cz); - dig(cx + x, cy - y, cz); - dig(cx - x, cy - y, cz); - dig(cx + y, cy + x, cz); - dig(cx - y, cy + x, cz); - dig(cx + y, cy - x, cz); - dig(cx - y, cy - x, cz); + dig(left, top, cz); + dig(left, bottom, cz); + dig(right, top, cz); + dig(right, bottom, cz); } - else + if(!filled && diff > 1) { - lineY(cx-x, cx+x, cy+y, cz); - lineY(cx-x, cx+x, cy-y, cz); - lineY(cx-y, cx+y, cy+x, cz); - lineY(cx-y, cx+y, cy-x, cz); + int lright = cx + lastwhole; + int lleft = cx - lastwhole + adjust; + lineY(lleft + 1, left - 1, top + 1 , cz); + lineY(right + 1, lright - 1, top + 1 , cz); + lineY(lleft + 1, left - 1, bottom - 1 , cz); + lineY(right + 1, lright - 1, bottom - 1 , cz); } + lastwhole = whole; } MCache.WriteAll(); c->Resume();