add --cursor and --quiet options to tiletypes-here

develop
myk002 2021-06-07 05:16:00 -07:00
parent dde589967a
commit a09f4d9b63
No known key found for this signature in database
GPG Key ID: 8A39CA0FA0C16E78
4 changed files with 144 additions and 34 deletions

@ -2702,9 +2702,15 @@ For more details, use ``tiletypes help``.
tiletypes-command tiletypes-command
----------------- -----------------
Runs tiletypes commands, separated by ;. This makes it possible to change Runs tiletypes commands, separated by ``;``. This makes it possible to change
tiletypes modes from a hotkey or via dfhack-run. tiletypes modes from a hotkey or via dfhack-run.
Example::
tiletypes-command p any ; p s wall ; p sp normal
This resets the paint filter to unsmoothed walls.
.. _tiletypes-here: .. _tiletypes-here:
tiletypes-here tiletypes-here
@ -2712,6 +2718,16 @@ tiletypes-here
Apply the current tiletypes options at the in-game cursor position, including Apply the current tiletypes options at the in-game cursor position, including
the brush. Can be used from a hotkey. the brush. Can be used from a hotkey.
Options:
:``-c``, ``--cursor <x>,<y>,<z>``:
Use the specified map coordinates instead of the current cursor position. If
this option is specified, then an active game map cursor is not necessary.
:``-h``, ``--help``:
Show command help text.
:``-q``, ``--quiet``:
Suppress non-error status output.
.. _tiletypes-here-point: .. _tiletypes-here-point:
tiletypes-here-point tiletypes-here-point
@ -2719,6 +2735,8 @@ tiletypes-here-point
Apply the current tiletypes options at the in-game cursor position to a single Apply the current tiletypes options at the in-game cursor position to a single
tile. Can be used from a hotkey. tile. Can be used from a hotkey.
This command supports the same options as `tiletypes-here` above.
.. _tubefill: .. _tubefill:
tubefill tubefill

@ -167,7 +167,7 @@ if(BUILD_SUPPORTED)
dfhack_plugin(stocks stocks.cpp) dfhack_plugin(stocks stocks.cpp)
dfhack_plugin(strangemood strangemood.cpp) dfhack_plugin(strangemood strangemood.cpp)
dfhack_plugin(tailor tailor.cpp) dfhack_plugin(tailor tailor.cpp)
dfhack_plugin(tiletypes tiletypes.cpp Brushes.h) dfhack_plugin(tiletypes tiletypes.cpp Brushes.h LINK_LIBRARIES lua)
dfhack_plugin(title-folder title-folder.cpp) dfhack_plugin(title-folder title-folder.cpp)
dfhack_plugin(title-version title-version.cpp) dfhack_plugin(title-version title-version.cpp)
dfhack_plugin(trackstop trackstop.cpp) dfhack_plugin(trackstop trackstop.cpp)

@ -0,0 +1,29 @@
local _ENV = mkmodule('plugins.tiletypes')
local utils = require('utils')
local function parse_cursor(opts, arg)
local _, _, x, y, z = arg:find('^%s*(%d+)%s*,%s*(%d+)%s*,%s*(%d+)%s*$')
if not x then
qerror(('invalid argument for --cursor option: "%s"; expected format' ..
' is "<x>,<y>,<z>", for example: "30,60,150"'):format(arg))
end
opts.cursor.x = tonumber(x)
opts.cursor.y = tonumber(y)
opts.cursor.z = tonumber(z)
end
function parse_commandline(opts, ...)
local positionals = utils.processArgsGetopt({...}, {
{'c', 'cursor', hasArg=true,
handler=function(arg) parse_cursor(opts, arg) end},
{'h', 'help', handler=function() opts.help = true end},
{'q', 'quiet', handler=function() opts.quiet = true end},
})
if positionals[1] == 'help' or positionals[1] == '?' then
opts.help = true
end
end
return _ENV

@ -34,6 +34,7 @@ using std::set;
#include "Console.h" #include "Console.h"
#include "Core.h" #include "Core.h"
#include "Export.h" #include "Export.h"
#include "LuaTools.h"
#include "PluginManager.h" #include "PluginManager.h"
#include "TileTypes.h" #include "TileTypes.h"
@ -53,6 +54,25 @@ using namespace df::enums;
DFHACK_PLUGIN("tiletypes"); DFHACK_PLUGIN("tiletypes");
REQUIRE_GLOBAL(world); REQUIRE_GLOBAL(world);
struct tiletypes_options {
// whether to display help
bool help = false;
bool quiet = false;
// if set, then use this position instead of the active game cursor
df::coord cursor;
static struct_identity _identity;
};
static const struct_field_info tiletypes_options_fields[] = {
{ struct_field_info::PRIMITIVE, "help", offsetof(tiletypes_options, help), &df::identity_traits<bool>::identity, 0, 0 },
{ struct_field_info::PRIMITIVE, "quiet", offsetof(tiletypes_options, quiet), &df::identity_traits<bool>::identity, 0, 0 },
{ struct_field_info::SUBSTRUCT, "cursor", offsetof(tiletypes_options, cursor), &df::coord::_identity, 0, 0 },
{ struct_field_info::END }
};
struct_identity tiletypes_options::_identity(sizeof(tiletypes_options), &df::allocator_fn<tiletypes_options>, NULL, "tiletypes_options", NULL, tiletypes_options_fields);
CommandHistory tiletypes_hist; CommandHistory tiletypes_hist;
command_result df_tiletypes (color_ostream &out, vector <string> & parameters); command_result df_tiletypes (color_ostream &out, vector <string> & parameters);
@ -713,7 +733,8 @@ bool processTileType(color_ostream & out, TileType &paint, std::vector<std::stri
return found; return found;
} }
command_result executePaintJob(color_ostream &out) command_result executePaintJob(color_ostream &out,
const tiletypes_options &opts)
{ {
if (paint.empty()) if (paint.empty())
{ {
@ -722,24 +743,36 @@ command_result executePaintJob(color_ostream &out)
} }
CoreSuspender suspend; CoreSuspender suspend;
uint32_t x_max = 0, y_max = 0, z_max = 0;
int32_t x = 0, y = 0, z = 0;
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
out.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
uint32_t x_max = 0, y_max = 0, z_max = 0;
Maps::getSize(x_max, y_max, z_max); Maps::getSize(x_max, y_max, z_max);
if (!Gui::getCursorCoords(x,y,z)) DFCoord cursor;
if (Maps::isValidTilePos(opts.cursor))
{ {
out.printerr("Can't get cursor coords! Make sure you have a cursor active in DF.\n"); cursor = opts.cursor;
return CR_FAILURE; }
else
{
int32_t x = 0, y = 0, z = 0;
if (!Gui::getCursorCoords(x,y,z))
{
out.printerr("Can't get cursor coords! Make sure you have a cursor active in DF or specify the --cursor option.\n");
return CR_FAILURE;
}
cursor = DFCoord(x, y, z);
} }
out.print("Cursor coords: (%d, %d, %d)\n", x, y, z);
DFHack::DFCoord cursor(x,y,z); if (!opts.quiet)
out.print("Cursor coords: (%d, %d, %d)\n",
cursor.x, cursor.y, cursor.z);
MapExtras::MapCache map; MapExtras::MapCache map;
coord_vec all_tiles = brush->points(map, cursor); coord_vec all_tiles = brush->points(map, cursor);
out.print("working...\n"); out.print("working...\n");
@ -877,12 +910,13 @@ command_result executePaintJob(color_ostream &out)
if (failures > 0) if (failures > 0)
out.printerr("Could not update %d tiles of %zu.\n", failures, all_tiles.size()); out.printerr("Could not update %d tiles of %zu.\n", failures, all_tiles.size());
else else if (!opts.quiet)
out.print("Processed %zu tiles.\n", all_tiles.size()); out.print("Processed %zu tiles.\n", all_tiles.size());
if (map.WriteAll()) if (map.WriteAll())
{ {
out.print("OK\n"); if (!opts.quiet)
out.print("OK\n");
return CR_OK; return CR_OK;
} }
else else
@ -894,9 +928,10 @@ command_result executePaintJob(color_ostream &out)
command_result processCommand(color_ostream &out, std::vector<std::string> &commands, int start, int end, bool & endLoop, bool hasConsole = false) command_result processCommand(color_ostream &out, std::vector<std::string> &commands, int start, int end, bool & endLoop, bool hasConsole = false)
{ {
tiletypes_options opts;
if (commands.size() == size_t(start)) if (commands.size() == size_t(start))
{ {
return executePaintJob(out); return executePaintJob(out, opts);
} }
int loc = start; int loc = start;
@ -951,7 +986,7 @@ command_result processCommand(color_ostream &out, std::vector<std::string> &comm
} }
else if (command == "run" || command.empty()) else if (command == "run" || command.empty())
{ {
executePaintJob(out); executePaintJob(out, opts);
} }
return CR_OK; return CR_OK;
@ -1028,43 +1063,71 @@ command_result df_tiletypes_command (color_ostream &out, vector <string> & param
return CR_OK; return CR_OK;
} }
static bool get_options(color_ostream &out,
tiletypes_options &opts,
const vector<string> &parameters)
{
auto L = Lua::Core::State;
Lua::StackUnwinder top(L);
if (!lua_checkstack(L, parameters.size() + 2) ||
!Lua::PushModulePublic(
out, L, "plugins.tiletypes", "parse_commandline"))
{
out.printerr("Failed to load tiletypes Lua code\n");
return false;
}
Lua::Push(L, &opts);
for (const string &param : parameters)
Lua::Push(L, param);
if (!Lua::SafeCall(out, L, parameters.size() + 1, 0))
return false;
return true;
}
command_result df_tiletypes_here (color_ostream &out, vector <string> & parameters) command_result df_tiletypes_here (color_ostream &out, vector <string> & parameters)
{ {
for(size_t i = 0; i < parameters.size();i++) tiletypes_options opts;
if (!get_options(out, opts, parameters) || opts.help)
{ {
if(parameters[i] == "help" || parameters[i] == "?") out << "This command is supposed to be mapped to a hotkey." << endl;
{ out << "It will use the current/last parameters set in tiletypes (including brush settings!)." << endl;
out << "This command is supposed to be mapped to a hotkey." << endl; return opts.help ? CR_OK : CR_FAILURE;
out << "It will use the current/last parameters set in tiletypes (including brush settings!)." << endl;
return CR_OK;
}
} }
out.print("Run tiletypes-here with these parameters: "); if (!opts.quiet)
printState(out); {
out.print("Run tiletypes-here with these parameters: ");
printState(out);
}
return executePaintJob(out); return executePaintJob(out, opts);
} }
command_result df_tiletypes_here_point (color_ostream &out, vector <string> & parameters) command_result df_tiletypes_here_point (color_ostream &out, vector <string> & parameters)
{ {
for(size_t i = 0; i < parameters.size();i++) tiletypes_options opts;
if (!get_options(out, opts, parameters) || opts.help)
{ {
if(parameters[i] == "help" || parameters[i] == "?") out << "This command is supposed to be mapped to a hotkey." << endl;
{ out << "It will use the current/last parameters set in tiletypes (except with a point brush)." << endl;
out << "This command is supposed to be mapped to a hotkey." << endl; return opts.help ? CR_OK : CR_FAILURE;
out << "It will use the current/last parameters set in tiletypes (except with a point brush)." << endl;
return CR_OK;
}
} }
Brush *old = brush; Brush *old = brush;
brush = new RectangleBrush(1, 1); brush = new RectangleBrush(1, 1);
out.print("Run tiletypes-here with these parameters: "); if (!opts.quiet)
printState(out); {
out.print("Run tiletypes-here-point with these parameters: ");
printState(out);
}
command_result rv = executePaintJob(out); command_result rv = executePaintJob(out, opts);
delete brush; delete brush;
brush = old; brush = old;