diff options
| author | Alexander Gavrilov | 2012-08-25 10:37:03 +0400 |
|---|---|---|
| committer | Alexander Gavrilov | 2012-08-25 10:37:03 +0400 |
| commit | 41ad42d0fdeae7d387186e66d9eb4117a3cf9e7d (patch) | |
| tree | b4bc91a1b977eb4bf39d7c618ff169b774176c44 | |
| parent | 21904fd607d0f2037782e28ff7284300663931ab (diff) | |
| download | dfhack-41ad42d0fdeae7d387186e66d9eb4117a3cf9e7d.tar.gz dfhack-41ad42d0fdeae7d387186e66d9eb4117a3cf9e7d.tar.bz2 dfhack-41ad42d0fdeae7d387186e66d9eb4117a3cf9e7d.tar.xz | |
Expose the liquids plugin engine to lua, and make a wrapper gui script.
| -rw-r--r-- | dfhack.init-example | 3 | ||||
| -rw-r--r-- | library/include/modules/Gui.h | 3 | ||||
| -rw-r--r-- | library/lua/gui.lua | 5 | ||||
| -rw-r--r-- | library/lua/gui/dwarfmode.lua | 52 | ||||
| -rw-r--r-- | library/modules/Gui.cpp | 17 | ||||
| -rw-r--r-- | plugins/liquids.cpp | 328 | ||||
| -rw-r--r-- | plugins/lua/liquids.lua | 11 | ||||
| -rw-r--r-- | scripts/gui/liquids.lua | 201 |
8 files changed, 491 insertions, 129 deletions
diff --git a/dfhack.init-example b/dfhack.init-example index c9408e37..552b2b3a 100644 --- a/dfhack.init-example +++ b/dfhack.init-example @@ -48,3 +48,6 @@ keybinding add Ctrl-M@dwarfmode/QueryBuilding/Some gui/mechanisms # browse rooms of same owner keybinding add Alt-R@dwarfmode/QueryBuilding/Some gui/room-list.work + +# interface for the liquids plugin +keybinding add Alt-L@dwarfmode/LookAround gui/liquids diff --git a/library/include/modules/Gui.h b/library/include/modules/Gui.h index 273d84ce..58f22241 100644 --- a/library/include/modules/Gui.h +++ b/library/include/modules/Gui.h @@ -97,6 +97,9 @@ namespace DFHack /* * Cursor and window coords */ + DFHACK_EXPORT df::coord getViewportPos(); + DFHACK_EXPORT df::coord getCursorPos(); + DFHACK_EXPORT bool getViewCoords (int32_t &x, int32_t &y, int32_t &z); DFHACK_EXPORT bool setViewCoords (const int32_t x, const int32_t y, const int32_t z); diff --git a/library/lua/gui.lua b/library/lua/gui.lua index ac032166..9e189ea1 100644 --- a/library/lua/gui.lua +++ b/library/lua/gui.lua @@ -18,7 +18,7 @@ function simulateInput(screen,...) error('Invalid keycode: '..arg) end end - if type(arg) == 'number' then + if type(kv) == 'number' then keys[#keys+1] = kv end end @@ -277,6 +277,9 @@ end function Screen:onDismiss() end +function Screen:onDestroy() +end + function Screen:onResize(w,h) self:updateLayout() end diff --git a/library/lua/gui/dwarfmode.lua b/library/lua/gui/dwarfmode.lua index c1a8bcb9..1f7ae1b0 100644 --- a/library/lua/gui/dwarfmode.lua +++ b/library/lua/gui/dwarfmode.lua @@ -6,6 +6,9 @@ local gui = require('gui') local utils = require('utils') local dscreen = dfhack.screen + +local g_cursor = df.global.cursor +local g_sel_rect = df.global.selection_rect local world_map = df.global.world.map AREA_MAP_WIDTH = 23 @@ -43,8 +46,8 @@ function getPanelLayout() end function getCursorPos() - if df.global.cursor.x ~= -30000 then - return copyall(df.global.cursor) + if g_cursor ~= -30000 then + return copyall(g_cursor) end end @@ -56,6 +59,51 @@ function clearCursorPos() df.global.cursor = xyz2pos(nil) end +function getSelection() + local p1, p2 + if g_sel_rect.start_x ~= -30000 then + p1 = xyz2pos(g_sel_rect.start_x, g_sel_rect.start_y, g_sel_rect.start_z) + end + if g_sel_rect.end_x ~= -30000 then + p2 = xyz2pos(g_sel_rect.end_x, g_sel_rect.end_y, g_sel_rect.end_z) + end + return p1, p2 +end + +function setSelectionStart(pos) + g_sel_rect.start_x = pos.x + g_sel_rect.start_y = pos.y + g_sel_rect.start_z = pos.z +end + +function setSelectionEnd(pos) + g_sel_rect.end_x = pos.x + g_sel_rect.end_y = pos.y + g_sel_rect.end_z = pos.z +end + +function clearSelection() + g_sel_rect.start_x = -30000 + g_sel_rect.start_y = -30000 + g_sel_rect.start_z = -30000 + g_sel_rect.end_x = -30000 + g_sel_rect.end_y = -30000 + g_sel_rect.end_z = -30000 +end + +function getSelectionRange(p1, p2) + local r1 = xyz2pos( + math.min(p1.x, p2.x), math.min(p1.y, p2.y), math.min(p1.z, p2.z) + ) + local r2 = xyz2pos( + math.max(p1.x, p2.x), math.max(p1.y, p2.y), math.max(p1.z, p2.z) + ) + local sz = xyz2pos( + r2.x - r1.x + 1, r2.y - r1.y + 1, r2.z - r1.z + 1 + ) + return r1, sz, r2 +end + Viewport = defclass(Viewport) function Viewport.make(map,x,y,z) diff --git a/library/modules/Gui.cpp b/library/modules/Gui.cpp index 91a17e99..0f28860b 100644 --- a/library/modules/Gui.cpp +++ b/library/modules/Gui.cpp @@ -998,6 +998,23 @@ df::viewscreen *Gui::getCurViewscreen(bool skip_dismissed) return ws; } +df::coord Gui::getViewportPos() +{ + if (!df::global::window_x || !df::global::window_y || !df::global::window_z) + return df::coord(0,0,0); + + return df::coord(*df::global::window_x, *df::global::window_y, *df::global::window_z); +} + +df::coord Gui::getCursorPos() +{ + using df::global::cursor; + if (!cursor) + return df::coord(); + + return df::coord(cursor->x, cursor->y, cursor->z); +} + bool Gui::getViewCoords (int32_t &x, int32_t &y, int32_t &z) { x = *df::global::window_x; diff --git a/plugins/liquids.cpp b/plugins/liquids.cpp index b036e4fa..b078b48f 100644 --- a/plugins/liquids.cpp +++ b/plugins/liquids.cpp @@ -27,6 +27,7 @@ #include <set> #include <cstdlib> #include <sstream> +#include <memory> using std::vector; using std::string; using std::endl; @@ -41,6 +42,7 @@ using std::set; #include "modules/Gui.h" #include "TileTypes.h" #include "modules/MapCache.h" +#include "LuaTools.h" #include "Brushes.h" using namespace MapExtras; using namespace DFHack; @@ -50,7 +52,6 @@ CommandHistory liquids_hist; command_result df_liquids (color_ostream &out, vector <string> & parameters); command_result df_liquids_here (color_ostream &out, vector <string> & parameters); -command_result df_liquids_execute (color_ostream &out); DFHACK_PLUGIN("liquids"); @@ -74,13 +75,49 @@ DFhackCExport command_result plugin_shutdown ( color_ostream &out ) return CR_OK; } -// static stuff to be remembered between sessions -static string brushname = "point"; -static string mode="magma"; -static string flowmode="f+"; -static string _setmode ="s."; -static unsigned int amount = 7; -static int width = 1, height = 1, z_levels = 1; +enum BrushType { + B_POINT, B_RANGE, B_BLOCK, B_COLUMN, B_FLOOD +}; + +static const char *brush_name[] = { + "point", "range", "block", "column", "flood", NULL +}; + +enum PaintMode { + P_WATER, P_MAGMA, P_OBSIDIAN, P_OBSIDIAN_FLOOR, + P_RIVER_SOURCE, P_FLOW_BITS, P_WCLEAN +}; + +static const char *paint_mode_name[] = { + "water", "magma", "obsidian", "obsidian_floor", + "riversource", "flowbits", "wclean", NULL +}; + +enum ModifyMode { + M_INC, M_KEEP, M_DEC +}; + +static const char *modify_mode_name[] = { + "+", ".", "-", NULL +}; + +struct OperationMode { + BrushType brush; + PaintMode paint; + ModifyMode flowmode; + ModifyMode setmode; + unsigned int amount; + df::coord size; + + OperationMode() : + brush(B_POINT), paint(P_MAGMA), + flowmode(M_INC), setmode(M_KEEP), amount(7), + size(1,1,1) + {} +} cur_mode; + +command_result df_liquids_execute(color_ostream &out); +command_result df_liquids_execute(color_ostream &out, OperationMode &mode, df::coord pos); command_result df_liquids (color_ostream &out_, vector <string> & parameters) { @@ -117,10 +154,11 @@ command_result df_liquids (color_ostream &out_, vector <string> & parameters) string input = ""; std::stringstream str; - str <<"[" << mode << ":" << brushname; - if (brushname == "range") - str << "(w" << width << ":h" << height << ":z" << z_levels << ")"; - str << ":" << amount << ":" << flowmode << ":" << _setmode << "]#"; + str <<"[" << paint_mode_name[cur_mode.paint] << ":" << brush_name[cur_mode.brush]; + if (cur_mode.brush == B_RANGE) + str << "(w" << cur_mode.size.x << ":h" << cur_mode.size.y << ":z" << cur_mode.size.z << ")"; + str << ":" << cur_mode.amount << ":f" << modify_mode_name[cur_mode.flowmode] + << ":s" << modify_mode_name[cur_mode.setmode] << "]#"; if(out.lineedit(str.str(),input,liquids_hist) == -1) return CR_FAILURE; liquids_hist.add(input); @@ -168,38 +206,39 @@ command_result df_liquids (color_ostream &out_, vector <string> & parameters) } else if(command == "m") { - mode = "magma"; + cur_mode.paint = P_MAGMA; } else if(command == "o") { - mode = "obsidian"; + cur_mode.paint = P_OBSIDIAN; } else if(command == "of") { - mode = "obsidian_floor"; + cur_mode.paint = P_OBSIDIAN_FLOOR; } else if(command == "w") { - mode = "water"; + cur_mode.paint = P_WATER; } else if(command == "f") { - mode = "flowbits"; + cur_mode.paint = P_FLOW_BITS; } else if(command == "rs") { - mode = "riversource"; + cur_mode.paint = P_RIVER_SOURCE; } else if(command == "wclean") { - mode = "wclean"; + cur_mode.paint = P_WCLEAN; } else if(command == "point" || command == "p") { - brushname = "point"; + cur_mode.brush = B_POINT; } else if(command == "range" || command == "r") { + int width, height, z_levels; command_result res = parseRectangle(out, commands, 1, commands.size(), width, height, z_levels); if (res != CR_OK) @@ -209,24 +248,26 @@ command_result df_liquids (color_ostream &out_, vector <string> & parameters) if (width == 1 && height == 1 && z_levels == 1) { - brushname = "point"; + cur_mode.brush = B_POINT; + cur_mode.size = df::coord(1, 1, 1); } else { - brushname = "range"; + cur_mode.brush = B_RANGE; + cur_mode.size = df::coord(width, height, z_levels); } } else if(command == "block") { - brushname = "block"; + cur_mode.brush = B_BLOCK; } else if(command == "column") { - brushname = "column"; + cur_mode.brush = B_COLUMN; } else if(command == "flood") { - brushname = "flood"; + cur_mode.brush = B_FLOOD; } else if(command == "q") { @@ -234,45 +275,45 @@ command_result df_liquids (color_ostream &out_, vector <string> & parameters) } else if(command == "f+") { - flowmode = "f+"; + cur_mode.flowmode = M_INC; } else if(command == "f-") { - flowmode = "f-"; + cur_mode.flowmode = M_DEC; } else if(command == "f.") { - flowmode = "f."; + cur_mode.flowmode = M_KEEP; } else if(command == "s+") { - _setmode = "s+"; + cur_mode.setmode = M_INC; } else if(command == "s-") { - _setmode = "s-"; + cur_mode.setmode = M_DEC; } else if(command == "s.") { - _setmode = "s."; + cur_mode.setmode = M_KEEP; } // blah blah, bad code, bite me. else if(command == "0") - amount = 0; + cur_mode.amount = 0; else if(command == "1") - amount = 1; + cur_mode.amount = 1; else if(command == "2") - amount = 2; + cur_mode.amount = 2; else if(command == "3") - amount = 3; + cur_mode.amount = 3; else if(command == "4") - amount = 4; + cur_mode.amount = 4; else if(command == "5") - amount = 5; + cur_mode.amount = 5; else if(command == "6") - amount = 6; + cur_mode.amount = 6; else if(command == "7") - amount = 7; + cur_mode.amount = 7; else if(command.empty()) { df_liquids_execute(out); @@ -298,78 +339,78 @@ command_result df_liquids_here (color_ostream &out, vector <string> & parameters } out.print("Run liquids-here with these parameters: "); - out << "[" << mode << ":" << brushname; - if (brushname == "range") - out << "(w" << width << ":h" << height << ":z" << z_levels << ")"; - out << ":" << amount << ":" << flowmode << ":" << _setmode << "]\n"; + out << "[" << paint_mode_name[cur_mode.paint] << ":" << brush_name[cur_mode.brush]; + if (cur_mode.brush == B_RANGE) + out << "(w" << cur_mode.size.x << ":h" << cur_mode.size.y << ":z" << cur_mode.size.z << ")"; + out << ":" << cur_mode.amount << ":f" << modify_mode_name[cur_mode.flowmode] + << ":" << modify_mode_name[cur_mode.setmode] << "]\n"; return df_liquids_execute(out); } command_result df_liquids_execute(color_ostream &out) { - // create brush type depending on old parameters - Brush * brush; + CoreSuspender suspend; - if (brushname == "point") - { - brush = new RectangleBrush(1,1,1,0,0,0); - //width = 1; - //height = 1; - //z_levels = 1; - } - else if (brushname == "range") + auto cursor = Gui::getCursorPos(); + if (!cursor.isValid()) { - brush = new RectangleBrush(width,height,z_levels,0,0,0); + out.printerr("Can't get cursor coords! Make sure you have a cursor active in DF.\n"); + return CR_WRONG_USAGE; } - else if(brushname == "block") + + auto rv = df_liquids_execute(out, cur_mode, cursor); + if (rv == CR_OK) + out << "OK" << endl; + return rv; +} + +command_result df_liquids_execute(color_ostream &out, OperationMode &cur_mode, df::coord cursor) +{ + // create brush type depending on old parameters + Brush *brush; + + switch (cur_mode.brush) { + case B_POINT: + brush = new RectangleBrush(1,1,1,0,0,0); + break; + case B_RANGE: + brush = new RectangleBrush(cur_mode.size.x,cur_mode.size.y,cur_mode.size.z,0,0,0); + break; + case B_BLOCK: brush = new BlockBrush(); - } - else if(brushname == "column") - { + break; + case B_COLUMN: brush = new ColumnBrush(); - } - else if(brushname == "flood") - { + break; + case B_FLOOD: brush = new FloodBrush(&Core::getInstance()); - } - else - { + break; + default: // this should never happen! out << "Old brushtype is invalid! Resetting to point brush.\n"; - brushname = "point"; - width = 1; - height = 1; - z_levels = 1; - brush = new RectangleBrush(width,height,z_levels,0,0,0); + cur_mode.brush = B_POINT; + brush = new RectangleBrush(1,1,1,0,0,0); } - CoreSuspender suspend; + std::auto_ptr<Brush> brush_ref(brush); - do + if (!Maps::IsValid()) { - if (!Maps::IsValid()) - { - out << "Can't see any DF map loaded." << endl; - break;; - } - int32_t x,y,z; - if(!Gui::getCursorCoords(x,y,z)) - { - out << "Can't get cursor coords! Make sure you have a cursor active in DF." << endl; - break; - } - out << "cursor coords: " << x << "/" << y << "/" << z << endl; - MapCache mcache; - DFHack::DFCoord cursor(x,y,z); - coord_vec all_tiles = brush->points(mcache,cursor); - out << "working..." << endl; + out << "Can't see any DF map loaded." << endl; + return CR_FAILURE; + } + + MapCache mcache; + coord_vec all_tiles = brush->points(mcache,cursor); - // Force the game to recompute its walkability cache - df::global::world->reindex_pathfinding = true; + // Force the game to recompute its walkability cache + df::global::world->reindex_pathfinding = true; - if(mode == "obsidian") + switch (cur_mode.paint) + { + case P_OBSIDIAN: { coord_vec::iterator iter = all_tiles.begin(); while (iter != all_tiles.end()) @@ -383,8 +424,9 @@ command_result df_liquids_execute(color_ostream &out) mcache.setDesignationAt(*iter, des); iter ++; } + break; } - if(mode == "obsidian_floor") + case P_OBSIDIAN_FLOOR: { coord_vec::iterator iter = all_tiles.begin(); while (iter != all_tiles.end()) @@ -392,8 +434,9 @@ command_result df_liquids_execute(color_ostream &out) mcache.setTiletypeAt(*iter, findRandomVariant(tiletype::LavaFloor1)); iter ++; } + break; } - else if(mode == "riversource") + case P_RIVER_SOURCE: { coord_vec::iterator iter = all_tiles.begin(); while (iter != all_tiles.end()) @@ -413,8 +456,9 @@ command_result df_liquids_execute(color_ostream &out) iter++; } + break; } - else if(mode=="wclean") + case P_WCLEAN: { coord_vec::iterator iter = all_tiles.begin(); while (iter != all_tiles.end()) @@ -426,8 +470,11 @@ command_result df_liquids_execute(color_ostream &out) mcache.setDesignationAt(current,des); iter++; } + break; } - else if(mode== "magma" || mode== "water" || mode == "flowbits") + case P_MAGMA: + case P_WATER: + case P_FLOW_BITS: { set <Block *> seen_blocks; coord_vec::iterator iter = all_tiles.begin(); @@ -450,30 +497,29 @@ command_result df_liquids_execute(color_ostream &out) iter++; continue; } - if(mode != "flowbits") + if(cur_mode.paint != P_FLOW_BITS) { unsigned old_amount = des.bits.flow_size; unsigned new_amount = old_amount; df::tile_liquid old_liquid = des.bits.liquid_type; df::tile_liquid new_liquid = old_liquid; // Compute new liquid type and amount - if(_setmode == "s.") - { - new_amount = amount; - } - else if(_setmode == "s+") - { - if(old_amount < amount) - new_amount = amount; - } - else if(_setmode == "s-") + switch (cur_mode.setmode) { - if (old_amount > amount) - new_amount = amount; + case M_KEEP: + new_amount = cur_mode.amount; + break; + case M_INC: + if(old_amount < cur_mode.amount) + new_amount = cur_mode.amount; + break; + case M_DEC: + if (old_amount > cur_mode.amount) + new_amount = cur_mode.amount; } - if (mode == "magma") + if (cur_mode.paint == P_MAGMA) new_liquid = tile_liquid::Magma; - else if (mode == "water") + else if (cur_mode.paint == P_WATER) new_liquid = tile_liquid::Water; // Store new amount and type des.bits.flow_size = new_amount; @@ -508,34 +554,64 @@ command_result df_liquids_execute(color_ostream &out) set <Block *>::iterator biter = seen_blocks.begin(); while (biter != seen_blocks.end()) { - if(flowmode == "f+") + switch (cur_mode.flowmode) { + case M_INC: (*biter)->enableBlockUpdates(true); - } - else if(flowmode == "f-") - { + break; + case M_DEC: if (auto block = (*biter)->getRaw()) { block->flags.bits.update_liquid = false; block->flags.bits.update_liquid_twice = false; } - } - else - { - auto bflags = (*biter)->BlockFlags(); - out << "flow bit 1 = " << bflags.bits.update_liquid << endl; - out << "flow bit 2 = " << bflags.bits.update_liquid_twice << endl; + break; + case M_KEEP: + { + auto bflags = (*biter)->BlockFlags(); + out << "flow bit 1 = " << bflags.bits.update_liquid << endl; + out << "flow bit 2 = " << bflags.bits.update_liquid_twice << endl; + } } biter ++; } + break; } - if(mcache.WriteAll()) - out << "OK" << endl; - else - out << "Something failed horribly! RUN!" << endl; - } while (0); + } + + if(!mcache.WriteAll()) + { + out << "Something failed horribly! RUN!" << endl; + return CR_FAILURE; + } - // cleanup - delete brush; return CR_OK; } + +static int paint(lua_State *L) +{ + df::coord pos; + OperationMode mode; + + lua_settop(L, 7); + Lua::CheckDFAssign(L, &pos, 1); + if (!pos.isValid()) + luaL_argerror(L, 1, "invalid cursor position"); + mode.brush = (BrushType)luaL_checkoption(L, 2, NULL, brush_name); + mode.paint = (PaintMode)luaL_checkoption(L, 3, NULL, paint_mode_name); + mode.amount = luaL_optint(L, 4, 7); + if (mode.amount < 0 || mode.amount > 7) + luaL_argerror(L, 4, "invalid liquid amount"); + if (!lua_isnil(L, 5)) + Lua::CheckDFAssign(L, &mode.size, 5); + mode.setmode = (ModifyMode)luaL_checkoption(L, 6, ".", modify_mode_name); + mode.flowmode = (ModifyMode)luaL_checkoption(L, 7, "+", modify_mode_name); + + lua_pushboolean(L, df_liquids_execute(*Lua::GetOutput(L), mode, pos)); + return 1; +} + +DFHACK_PLUGIN_LUA_COMMANDS { + DFHACK_LUA_COMMAND(paint), + DFHACK_LUA_END +}; diff --git a/plugins/lua/liquids.lua b/plugins/lua/liquids.lua new file mode 100644 index 00000000..22ce4da3 --- /dev/null +++ b/plugins/lua/liquids.lua @@ -0,0 +1,11 @@ +local _ENV = mkmodule('plugins.liquids') + +--[[ + + Native functions: + + * paint(pos,brush,paint,amount,size,setmode,flowmode) + +--]] + +return _ENV
\ No newline at end of file diff --git a/scripts/gui/liquids.lua b/scripts/gui/liquids.lua new file mode 100644 index 00000000..27df49e9 --- /dev/null +++ b/scripts/gui/liquids.lua @@ -0,0 +1,201 @@ +-- Interface front-end for liquids plugin. + +local utils = require 'utils' +local gui = require 'gui' +local guidm = require 'gui.dwarfmode' + +local liquids = require('plugins.liquids') + +local sel_rect = df.global.selection_rect + +local brushes = { + { tag = 'range', caption = 'Rectangle', range = true }, + { tag = 'block', caption = '16x16 block' }, + { tag = 'column', caption = 'Column' }, + { tag = 'flood', caption = 'Flood' }, +} + +local paints = { + { tag = 'water', caption = 'Water', liquid = true, key = 'w' }, + { tag = 'magma', caption = 'Magma', liquid = true, key = 'l' }, + { tag = 'obsidian', caption = 'Obsidian Wall' }, + { tag = 'obsidian_floor', caption = 'Obsidian Floor' }, + { tag = 'riversource', caption = 'River Source' }, + { tag = 'flowbits', caption = 'Flow Updates' }, + { tag = 'wclean', caption = 'Clean Salt/Stagnant' }, +} + +local flowbits = { + { tag = '+', caption = 'Enable Updates' }, + { tag = '-', caption = 'Disable Updates' }, + { tag = '.', caption = 'Keep Updates' }, +} + +local setmode = { + { tag = '.', caption = 'Set Exactly' }, + { tag = '+', caption = 'Only Increase' }, + { tag = '-', caption = 'Only Decrease' }, +} + +Toggle = defclass(Toggle) + +function Toggle:init(items) + self:init_fields{ + items = items, + selected = 1 + } + return self +end + +function Toggle:get() + return self.items[self.selected] +end + +function Toggle:render(dc) + local item = self:get() + if item then + dc:string(item.caption) + if item.key then + dc:string(" ("):string(item.key, COLOR_LIGHTGREEN):string(")") + end + else + dc:string('NONE', COLOR_RED) + end +end + +function Toggle:step(delta) + if #self.items > 1 then + delta = delta or 1 + self.selected = 1 + (self.selected + delta - 1) % #self.items + end +end + +LiquidsUI = defclass(LiquidsUI, guidm.MenuOverlay) + +LiquidsUI.focus_path = 'liquids' + +function LiquidsUI:init() + self:init_fields{ + brush = mkinstance(Toggle):init(brushes), + paint = mkinstance(Toggle):init(paints), + flow = mkinstance(Toggle):init(flowbits), + set = mkinstance(Toggle):init(setmode), + amount = 7, + } + guidm.MenuOverlay.init(self) + return self +end + +function LiquidsUI:onDestroy() + guidm.clearSelection() +end + +function LiquidsUI:onRenderBody(dc) + dc:clear():seek(1,1):string("Paint Liquids Cheat", COLOR_WHITE) + + local cursor = guidm.getCursorPos() + local block = dfhack.maps.getTileBlock(cursor) + local tile = block.tiletype[cursor.x%16][cursor.y%16] + local dsgn = block.designation[cursor.x%16][cursor.y%16] + + dc:seek(2,3):string(df.tiletype.attrs[tile].caption, COLOR_CYAN):newline(2) + + if dsgn.flow_size > 0 then + if dsgn.liquid_type == df.tile_liquid.Magma then + dc:pen(COLOR_RED):string("Magma") + else + dc:pen(COLOR_BLUE) + if dsgn.water_stagnant then dc:string("Stagnant ") end + if dsgn.water_salt then dc:string("Salty ") end + dc:string("Water") + end + dc:string(" ["..dsgn.flow_size.."/7]") + else + dc:string('No Liquid', COLOR_DARKGREY) + end + + dc:newline():pen(COLOR_GREY) + + dc:newline(1):string("b", COLOR_LIGHTGREEN):string(": ") + self.brush:render(dc) + dc:newline(1):string("p", COLOR_LIGHTGREEN):string(": ") + self.paint:render(dc) + + local liquid = self.paint:get().liquid + + dc:newline() + if liquid then + dc:newline(1):string("Amount: "..self.amount) + dc:advance(1):string("("):string("-+", COLOR_LIGHTGREEN):string(")") + dc:newline(3):string("s", COLOR_LIGHTGREEN):string(": ") + self.set:render(dc) + else + dc:advance(0,2) + end + + dc:newline():newline(1):string("f", COLOR_LIGHTGREEN):string(": ") + self.flow:render(dc) + + dc:newline():newline(1):pen(COLOR_WHITE) + dc:string("Esc", COLOR_LIGHTGREEN):string(": Back, ") + dc:string("Enter", COLOR_LIGHTGREEN):string(": Paint") +end + +function LiquidsUI:onInput(keys) + local liquid = self.paint:get().liquid + if keys.CUSTOM_B then + self.brush:step() + elseif keys.CUSTOM_P then + self.paint:step() + elseif liquid and keys.SECONDSCROLL_UP then + self.amount = math.max(0, self.amount-1) + elseif liquid and keys.SECONDSCROLL_DOWN then + self.amount = math.min(7, self.amount+1) + elseif liquid and keys.CUSTOM_S then + self.set:step() + elseif keys.CUSTOM_F then + self.flow:step() + elseif keys.LEAVESCREEN then + if guidm.getSelection() then + guidm.clearSelection() + return + end + self:dismiss() + self:sendInputToParent('CURSOR_DOWN_Z') + self:sendInputToParent('CURSOR_UP_Z') + elseif keys.SELECT then + local cursor = guidm.getCursorPos() + local sp = guidm.getSelection() + local size = nil + if self.brush:get().range then + if not sp then + guidm.setSelectionStart(cursor) + return + else + guidm.clearSelection() + cursor, size = guidm.getSelectionRange(cursor, sp) + end + else + guidm.clearSelection() + end + liquids.paint( + cursor, + self.brush:get().tag, self.paint:get().tag, + self.amount, size, + self.set:get().tag, self.flow:get().tag + ) + elseif self:propagateMoveKeys(keys) then + return + elseif keys.D_LOOK_ARENA_WATER then + self.paint.selected = 1 + elseif keys.D_LOOK_ARENA_MAGMA then + self.paint.selected = 2 + end +end + +if not string.match(dfhack.gui.getCurFocus(), '^dwarfmode/LookAround') then + qerror("This script requires the main dwarfmode view in 'k' mode") +end + +local list = mkinstance(LiquidsUI):init() +list:show() |
