Merge remote-tracking branch 'myk002/blueprint_in_blueprints' into develop

develop
lethosor 2020-07-17 17:32:59 -04:00
commit 35d659091d
No known key found for this signature in database
GPG Key ID: 76A269552F4F58C1
6 changed files with 100 additions and 25 deletions

@ -100,6 +100,7 @@ Milo Christiansen milochristiansen
MithrilTuxedo MithrilTuxedo
mizipzor mizipzor
moversti moversti
Myk Taylor myk002
napagokc napagokc
Neil Little nmlittle
Nick Rart nickrart comestible

@ -46,6 +46,8 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
- `RemoteFortressReader`: fixed a couple crashes that could result from decoding invalid enum items (``site_realization_building_type`` and ``improvement_type``)
## Misc Improvements
- `blueprint`: now writes blueprints to the ``blueprints/`` subfolder instead of the df root folder
- `blueprint`: now automatically creates folder trees when organizing blueprints into subfolders (e.g. ``blueprint 30 30 1 rooms/dining dig`` will create the file ``blueprints/rooms/dining-dig.csv``); previously it would fail if the ``blueprints/rooms/`` directory didn't already exist
- `confirm`: added a confirmation dialog for convicting dwarves of crimes
## Lua

@ -2365,6 +2365,7 @@ static const LuaWrapper::FunctionReg dfhack_filesystem_module[] = {
WRAPM(Filesystem, getcwd),
WRAPM(Filesystem, chdir),
WRAPM(Filesystem, mkdir),
WRAPM(Filesystem, mkdir_recursive),
WRAPM(Filesystem, rmdir),
WRAPM(Filesystem, exists),
WRAPM(Filesystem, isfile),

@ -149,6 +149,7 @@ namespace DFHack {
DFHACK_EXPORT bool chdir (std::string path);
DFHACK_EXPORT std::string getcwd ();
DFHACK_EXPORT bool mkdir (std::string path);
DFHACK_EXPORT bool mkdir_recursive (std::string path);
DFHACK_EXPORT bool rmdir (std::string path);
DFHACK_EXPORT bool stat (std::string path, STAT_STRUCT &info);
DFHACK_EXPORT bool exists (std::string path);

@ -45,6 +45,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <algorithm>
#include <string>
#include "modules/Filesystem.h"
@ -82,6 +83,37 @@ bool Filesystem::mkdir (std::string path)
return fail == 0;
}
static bool mkdir_recursive_impl (std::string path)
{
size_t last_slash = path.find_last_of("/");
if (last_slash != std::string::npos)
{
std::string parent_path = path.substr(0, last_slash);
bool parent_exists = mkdir_recursive_impl(parent_path);
if (!parent_exists)
{
return false;
}
}
return (Filesystem::mkdir(path) || errno == EEXIST) && Filesystem::isdir(path);
}
bool Filesystem::mkdir_recursive (std::string path)
{
#ifdef _WIN32
// normalize to forward slashes
std::replace(path.begin(), path.end(), '\\', '/');
#endif
if (path.size() > FILENAME_MAX)
{
// path too long
return false;
}
return mkdir_recursive_impl(path);
}
bool Filesystem::rmdir (std::string path)
{
int fail;

@ -3,12 +3,14 @@
//Translates a region of tiles specified by the cursor and arguments/prompts into a series of blueprint files suitable for digfort/buildingplan/quickfort
#include <algorithm>
#include <sstream>
#include <Console.h>
#include <PluginManager.h>
#include "LuaTools.h"
#include "modules/Buildings.h"
#include "modules/Filesystem.h"
#include "modules/Gui.h"
#include "modules/MapCache.h"
@ -62,9 +64,10 @@ command_result help(color_ostream &out)
<< " defaults to generating all blueprints" << endl
<< endl
<< "blueprint translates a portion of your fortress into blueprints suitable for" << endl
<< " digfort/fortplan/quickfort. Blueprints are created in the DF folder with names" << endl
<< " following a \"name-phase.csv\" pattern. Translation starts at the current" << endl
<< " cursor location and includes all tiles in the range specified." << endl;
<< " digfort/fortplan/quickfort. Blueprints are created in the \"blueprints\"" << endl
<< " subdirectory of the DF folder with names following a \"name-phase.csv\" pattern." << endl
<< " Translation starts at the current cursor location and includes all tiles in the" << endl
<< " range specified." << endl;
return CR_OK;
}
@ -557,32 +560,55 @@ string get_tile_query(df::building* b)
return " ";
}
command_result do_transform(DFCoord start, DFCoord end, string name, uint32_t phases)
void init_stream(ofstream &out, std::string basename, std::string target)
{
std::ostringstream out_path;
out_path << basename << "-" << target << ".csv";
out.open(out_path.str(), ofstream::trunc);
out << "#" << target << endl;
}
command_result do_transform(DFCoord start, DFCoord end, string name, uint32_t phases, std::ostringstream &err)
{
ofstream dig, build, place, query;
std::string basename = "blueprints/" + name;
#ifdef _WIN32
// normalize to forward slashes
std::replace(basename.begin(), basename.end(), '\\', '/');
#endif
size_t last_slash = basename.find_last_of("/");
std::string parent_path = basename.substr(0, last_slash);
// create output directory if it doesn't already exist
std::error_code ec;
if (!Filesystem::mkdir_recursive(parent_path))
{
err << "could not create output directory: '" << parent_path << "'";
return CR_FAILURE;
}
if (phases & QUERY)
{
//query = ofstream((name + "-query.csv").c_str(), ofstream::trunc);
query.open(name+"-query.csv", ofstream::trunc);
query << "#query" << endl;
init_stream(query, basename, "query");
}
if (phases & PLACE)
{
//place = ofstream(name + "-place.csv", ofstream::trunc);
place.open(name+"-place.csv", ofstream::trunc);
place << "#place" << endl;
init_stream(place, basename, "place");
}
if (phases & BUILD)
{
//build = ofstream(name + "-build.csv", ofstream::trunc);
build.open(name+"-build.csv", ofstream::trunc);
build << "#build" << endl;
init_stream(build, basename, "build");
}
if (phases & DIG)
{
//dig = ofstream(name + "-dig.csv", ofstream::trunc);
dig.open(name+"-dig.csv", ofstream::trunc);
dig << "#dig" << endl;
init_stream(dig, basename, "dig");
}
if (start.x > end.x)
{
@ -675,18 +701,27 @@ command_result blueprint(color_ostream &out, vector<string> &parameters)
}
DFCoord start (x, y, z);
DFCoord end (x + stoi(parameters[0]), y + stoi(parameters[1]), z + stoi(parameters[2]));
if (parameters.size() == 4)
return do_transform(start, end, parameters[3], DIG | BUILD | PLACE | QUERY);
uint32_t option = 0;
if (cmd_option_exists(parameters, "dig"))
option |= DIG;
if (cmd_option_exists(parameters, "build"))
option |= BUILD;
if (cmd_option_exists(parameters, "place"))
option |= PLACE;
if (cmd_option_exists(parameters, "query"))
option |= QUERY;
return do_transform(start, end, parameters[3], option);
if (parameters.size() == 4)
{
option = DIG | BUILD | PLACE | QUERY;
}
else
{
if (cmd_option_exists(parameters, "dig"))
option |= DIG;
if (cmd_option_exists(parameters, "build"))
option |= BUILD;
if (cmd_option_exists(parameters, "place"))
option |= PLACE;
if (cmd_option_exists(parameters, "query"))
option |= QUERY;
}
std::ostringstream err;
DFHack::command_result result = do_transform(start, end, parameters[3], option, err);
if (result != CR_OK)
out.printerr("%s\n", err.str().c_str());
return result;
}
static int create(lua_State *L, uint32_t options) {
@ -701,9 +736,12 @@ static int create(lua_State *L, uint32_t options) {
luaL_argerror(L, 2, "invalid end position");
string filename(lua_tostring(L, 3));
lua_pushboolean(L, do_transform(start, end, filename, options));
std::ostringstream err;
DFHack::command_result result = do_transform(start, end, filename, options, err);
if (result != CR_OK)
luaL_error(L, "%s", err.str().c_str());
lua_pushboolean(L, result);
return 1;
}
static int dig(lua_State *L) {