From d15b189e50c9b5f1cc620448469d7c4c9e39b360 Mon Sep 17 00:00:00 2001 From: James Logsdon Date: Wed, 4 Feb 2015 00:47:47 -0500 Subject: [PATCH 01/22] Add a note about build targets on OSX Yosemite --- Compile.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Compile.rst b/Compile.rst index bf5d3f9b6..74fd178a1 100644 --- a/Compile.rst +++ b/Compile.rst @@ -160,6 +160,13 @@ Snow Leopard Changes In /library/LuaTypes.cpp, change line 467 to ``int len = strlen((char*)ptr);`` +Yoesmite Changes +================ + +If you have issues building after upgrading to Yosemite, try definining the folliwing environment variable: + + export MACOSX_DEPLOYMENT_TARGET=10.9 + ======= Windows ======= From 3f9d3dc110c96a8765d87986931faaa888080747 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 13 Feb 2015 15:14:31 -0500 Subject: [PATCH 02/22] Use unix line endings in isoworldremote.proto --- plugins/proto/isoworldremote.proto | 152 ++++++++++++++--------------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/plugins/proto/isoworldremote.proto b/plugins/proto/isoworldremote.proto index 811df6dfa..4faad5f01 100644 --- a/plugins/proto/isoworldremote.proto +++ b/plugins/proto/isoworldremote.proto @@ -1,76 +1,76 @@ -package isoworldremote; - -//Describes a very basic material structure for the map embark -option optimize_for = LITE_RUNTIME; - -enum BasicMaterial { - AIR = 0; - OTHER = 1; - INORGANIC = 2; - LIQUID = 3; - PLANT = 4; - WOOD = 5; -}; - -enum LiquidType { - ICE = 0; - WATER = 1; - MAGMA = 2; -} - -enum BasicShape { - NONE = 0; - OPEN = 1; - WALL = 3; - FLOOR = 4; - RAMP_UP = 5; - RAMP_DOWN = 6; -} - -message ColorDefinition { - required int32 red = 1; - required int32 green = 2; - required int32 blue = 3; -} - -message EmbarkTileLayer { - repeated BasicMaterial mat_type_table = 4 [packed=true]; - repeated int32 mat_subtype_table = 5 [packed=true]; - repeated BasicShape tile_shape_table = 6 [packed=true]; - repeated ColorDefinition tile_color_table = 7; -} - -message EmbarkTile { - required int32 world_x = 1; - required int32 world_y = 2; - required sint32 world_z = 3; - repeated EmbarkTileLayer tile_layer = 4; - optional int32 current_year = 5; - optional int32 current_season = 6; - optional bool is_valid = 7; -} - -message TileRequest { - optional int32 want_x = 1; - optional int32 want_y = 2; -} - -message MapRequest { - optional string save_folder = 1; -} - -message MapReply { - required bool available = 1; - optional int32 region_x = 2; - optional int32 region_y = 3; - optional int32 region_size_x = 4; - optional int32 region_size_y = 5; - optional int32 current_year = 6; - optional int32 current_season = 7; -} - -message RawNames { - required bool available = 1; - repeated string inorganic = 2; - repeated string organic = 3; -} \ No newline at end of file +package isoworldremote; + +//Describes a very basic material structure for the map embark +option optimize_for = LITE_RUNTIME; + +enum BasicMaterial { + AIR = 0; + OTHER = 1; + INORGANIC = 2; + LIQUID = 3; + PLANT = 4; + WOOD = 5; +}; + +enum LiquidType { + ICE = 0; + WATER = 1; + MAGMA = 2; +} + +enum BasicShape { + NONE = 0; + OPEN = 1; + WALL = 3; + FLOOR = 4; + RAMP_UP = 5; + RAMP_DOWN = 6; +} + +message ColorDefinition { + required int32 red = 1; + required int32 green = 2; + required int32 blue = 3; +} + +message EmbarkTileLayer { + repeated BasicMaterial mat_type_table = 4 [packed=true]; + repeated int32 mat_subtype_table = 5 [packed=true]; + repeated BasicShape tile_shape_table = 6 [packed=true]; + repeated ColorDefinition tile_color_table = 7; +} + +message EmbarkTile { + required int32 world_x = 1; + required int32 world_y = 2; + required sint32 world_z = 3; + repeated EmbarkTileLayer tile_layer = 4; + optional int32 current_year = 5; + optional int32 current_season = 6; + optional bool is_valid = 7; +} + +message TileRequest { + optional int32 want_x = 1; + optional int32 want_y = 2; +} + +message MapRequest { + optional string save_folder = 1; +} + +message MapReply { + required bool available = 1; + optional int32 region_x = 2; + optional int32 region_y = 3; + optional int32 region_size_x = 4; + optional int32 region_size_y = 5; + optional int32 current_year = 6; + optional int32 current_season = 7; +} + +message RawNames { + required bool available = 1; + repeated string inorganic = 2; + repeated string organic = 3; +} From a8a8fc43effb757b5a8fbe4e86fae1cb0b83ef57 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 13 Feb 2015 17:56:29 -0500 Subject: [PATCH 03/22] Add df2console() wrapper Closes #522 --- library/LuaApi.cpp | 2 ++ library/MiscUtils.cpp | 16 ++++++++++++++++ library/include/MiscUtils.h | 1 + 3 files changed, 19 insertions(+) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 64d27038c..26e158368 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -1282,6 +1282,7 @@ static bool isMapLoaded() { return Core::getInstance().isMapLoaded(); } static std::string df2utf(std::string s) { return DF2UTF(s); } static std::string utf2df(std::string s) { return UTF2DF(s); } +static std::string df2console(std::string s) { return DF2CONSOLE(s); } static const LuaWrapper::FunctionReg dfhack_module[] = { WRAP(getOSType), @@ -1294,6 +1295,7 @@ static const LuaWrapper::FunctionReg dfhack_module[] = { WRAPM(Translation, TranslateName), WRAP(df2utf), WRAP(utf2df), + WRAP(df2console), { NULL, NULL } }; diff --git a/library/MiscUtils.cpp b/library/MiscUtils.cpp index 53c403026..823b676eb 100644 --- a/library/MiscUtils.cpp +++ b/library/MiscUtils.cpp @@ -347,3 +347,19 @@ std::string UTF2DF(const std::string &in) out.resize(pos); return out; } + +DFHACK_EXPORT std::string DF2CONSOLE(const std::string &in) +{ + bool is_utf = false; +#ifdef LINUX_BUILD + std::string locale = ""; + if (getenv("LANG")) + locale += getenv("LANG"); + if (getenv("LC_CTYPE")) + locale += getenv("LC_CTYPE"); + locale = toUpper(locale); + is_utf = (locale.find("UTF-8") != std::string::npos) || + (locale.find("UTF8") != std::string::npos); +#endif + return is_utf ? DF2UTF(in) : in; +} diff --git a/library/include/MiscUtils.h b/library/include/MiscUtils.h index 660699d7a..653e37f47 100644 --- a/library/include/MiscUtils.h +++ b/library/include/MiscUtils.h @@ -348,3 +348,4 @@ DFHACK_EXPORT std::string stl_vsprintf(const char *fmt, va_list args); // Conversion between CP437 and UTF-8 DFHACK_EXPORT std::string UTF2DF(const std::string &in); DFHACK_EXPORT std::string DF2UTF(const std::string &in); +DFHACK_EXPORT std::string DF2CONSOLE(const std::string &in); From 49e53db0635eb194ab46e5e3dae54259b39bb1c7 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 13 Feb 2015 18:35:20 -0500 Subject: [PATCH 04/22] Update NEWS --- NEWS | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index a5993610f..2f790e653 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ DFHack Future Internals Lua scripts will only be reloaded if necessary Added support for onLoadMap/onUnloadMap.init scripts + Added df2console() wrapper, useful for printing DF (CP437-encoded) text to the console in a portable way New internal commands: hide/show: hide and show the console on Windows sc-script: Allows additional scripts to be run when certain events occur (similar to onLoad*.init scripts) @@ -22,6 +23,8 @@ DFHack Future tradereq-pet-gender: Displays pet genders on the trade request screen Removed Misc Improvements + exportlegends: 'info' and 'all' exports legends_plus xml with more data for legends utilities + remotefortressreader: Exposes more information DFHack 0.40.24-r2 Internals @@ -71,7 +74,6 @@ DFHack 0.40.24-r2 Removed Misc Improvements Multiline commands are now possible inside dfhack.init scripts. See dfhack.init-example for example usage. - exportlegends: 'info' and 'all' exports legends_plus xml with more data for legends utilities DFHack 0.40.24-r1 Internals From cf7b59596576fba7a7b74e2f8b241dd9c1822dbf Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 14 Feb 2015 19:59:17 -0500 Subject: [PATCH 05/22] Add python linter --- travis/lint.py | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 travis/lint.py diff --git a/travis/lint.py b/travis/lint.py new file mode 100644 index 000000000..9b0840586 --- /dev/null +++ b/travis/lint.py @@ -0,0 +1,89 @@ +import re, os, sys + +valid_extensions = ['c', 'cpp', 'h', 'hpp', 'mm', 'lua', 'rb', 'proto', + 'init', 'init-example'] +path_blacklist = [ + 'library/include/df/', + 'plugins/stonesense/allegro', + 'plugins/isoworld/allegro', + 'plugins/isoworld/agui', +] + +def valid_file(filename): + return len(filter(lambda ext: filename.endswith('.' + ext), valid_extensions)) and \ + not len(filter(lambda path: path.replace('\\', '/') in filename.replace('\\', '/'), path_blacklist)) + +success = True +def error(msg): + global success + success = False + sys.stderr.write(msg + '\n') + +class LinterError(Exception): pass + +class Linter(object): + def check(self, lines): + failures = [] + for i, line in enumerate(lines): + if not self.check_line(line): + failures.append(i) + if len(failures): + raise LinterError('%s: %s' % (self.msg, self.display_lines(failures, len(lines)))) + + def display_lines(self, lines, total): + if len(lines) == total - 1: + return 'entire file' + if not len(lines): + # should never happen + return 'nowhere' + s = 'lines ' if len(lines) != 1 else 'line ' + range_start = range_end = lines[0] + for i, line in enumerate(lines): + if line > range_start + 1 or i == len(lines) - 1: + if i == len(lines) - 1: + range_end = line + if range_start == range_end: + s += ('%i, ' % range_end) + else: + s += ('%i-%i, ' % (range_start, range_end)) + range_start = range_end = line + else: + range_end = line + return s.rstrip(' ').rstrip(',') + +class NewlineLinter(Linter): + msg = 'Contains DOS-style newlines' + def check_line(self, line): + return '\r' not in line + +class TrailingWhitespaceLinter(Linter): + msg = 'Contains trailing whitespace' + def check_line(self, line): + line = line.replace('\r', '') + return not line.endswith(' ') and not line.endswith('\t') + +linters = [NewlineLinter(), TrailingWhitespaceLinter()] + +root_path = os.path.abspath(sys.argv[1] if len(sys.argv) > 1 else '.') +path_blacklist.append(root_path + '/.git') +path_blacklist.append(root_path + '/build') + +for cur, dirnames, filenames in os.walk(root_path): + for filename in filenames: + full_path = os.path.join(cur, filename) + rel_path = full_path.replace(root_path, '.') + if not valid_file(full_path): + continue + with open(full_path, 'rb') as f: + lines = f.read().split('\n') + for linter in linters: + try: + linter.check(lines) + except LinterError as e: + error('%s: %s' % (rel_path, e)) + +if success: + print('All linters completed successfully') + sys.exit(0) +else: + sys.exit(1) From a19ca89e9fdeba89ce20c252ad8d24947c6ea76f Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 14 Feb 2015 20:10:48 -0500 Subject: [PATCH 06/22] Add .travis.yml --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..4653cf18c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,2 @@ +script: +- python travis/lint.py From f91a5767cd0df3e27471805c486d3220edcc40c6 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 14 Feb 2015 21:43:10 -0500 Subject: [PATCH 07/22] Fix line numbers --- travis/lint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/travis/lint.py b/travis/lint.py index 9b0840586..298907fec 100644 --- a/travis/lint.py +++ b/travis/lint.py @@ -26,7 +26,7 @@ class Linter(object): failures = [] for i, line in enumerate(lines): if not self.check_line(line): - failures.append(i) + failures.append(i + 1) if len(failures): raise LinterError('%s: %s' % (self.msg, self.display_lines(failures, len(lines)))) From 7b29538485101bdfeab6e660394f336823d1d532 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 14 Feb 2015 22:07:57 -0500 Subject: [PATCH 08/22] Check for tabs and fix more line number issues --- travis/lint.py | 65 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/travis/lint.py b/travis/lint.py index 298907fec..b0e1f61ad 100644 --- a/travis/lint.py +++ b/travis/lint.py @@ -36,19 +36,23 @@ class Linter(object): if not len(lines): # should never happen return 'nowhere' - s = 'lines ' if len(lines) != 1 else 'line ' + if len(lines) == 1: + return 'line %i' % lines[0] + s = 'lines ' range_start = range_end = lines[0] for i, line in enumerate(lines): - if line > range_start + 1 or i == len(lines) - 1: - if i == len(lines) - 1: - range_end = line + if line > range_end + 1: if range_start == range_end: s += ('%i, ' % range_end) else: s += ('%i-%i, ' % (range_start, range_end)) range_start = range_end = line + if i == len(lines) - 1: + s += ('%i' % line) else: range_end = line + if i == len(lines) - 1: + s += ('%i-%i, ' % (range_start, range_end)) return s.rstrip(' ').rstrip(',') class NewlineLinter(Linter): @@ -62,28 +66,37 @@ class TrailingWhitespaceLinter(Linter): line = line.replace('\r', '') return not line.endswith(' ') and not line.endswith('\t') -linters = [NewlineLinter(), TrailingWhitespaceLinter()] +class TabLinter(Linter): + msg = 'Contains tabs' + def check_line(self, line): + return '\t' not in line + +linters = [NewlineLinter(), TrailingWhitespaceLinter(), TabLinter()] + +def main(): + root_path = os.path.abspath(sys.argv[1] if len(sys.argv) > 1 else '.') + path_blacklist.append(root_path + '/.git') + path_blacklist.append(root_path + '/build') -root_path = os.path.abspath(sys.argv[1] if len(sys.argv) > 1 else '.') -path_blacklist.append(root_path + '/.git') -path_blacklist.append(root_path + '/build') + for cur, dirnames, filenames in os.walk(root_path): + for filename in filenames: + full_path = os.path.join(cur, filename) + rel_path = full_path.replace(root_path, '.') + if not valid_file(full_path): + continue + with open(full_path, 'rb') as f: + lines = f.read().split('\n') + for linter in linters: + try: + linter.check(lines) + except LinterError as e: + error('%s: %s' % (rel_path, e)) -for cur, dirnames, filenames in os.walk(root_path): - for filename in filenames: - full_path = os.path.join(cur, filename) - rel_path = full_path.replace(root_path, '.') - if not valid_file(full_path): - continue - with open(full_path, 'rb') as f: - lines = f.read().split('\n') - for linter in linters: - try: - linter.check(lines) - except LinterError as e: - error('%s: %s' % (rel_path, e)) + if success: + print('All linters completed successfully') + sys.exit(0) + else: + sys.exit(1) -if success: - print('All linters completed successfully') - sys.exit(0) -else: - sys.exit(1) +if __name__ == '__main__': + main() From 2c744035ab8eba8f55bfda255050c8b7bd69156d Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 14 Feb 2015 22:13:10 -0500 Subject: [PATCH 09/22] lint: Avoid checking depends/ for now --- travis/lint.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/travis/lint.py b/travis/lint.py index b0e1f61ad..597f427c8 100644 --- a/travis/lint.py +++ b/travis/lint.py @@ -7,6 +7,9 @@ path_blacklist = [ 'plugins/stonesense/allegro', 'plugins/isoworld/allegro', 'plugins/isoworld/agui', + 'depends/', + '.git/', + 'build', ] def valid_file(filename): @@ -75,8 +78,8 @@ linters = [NewlineLinter(), TrailingWhitespaceLinter(), TabLinter()] def main(): root_path = os.path.abspath(sys.argv[1] if len(sys.argv) > 1 else '.') - path_blacklist.append(root_path + '/.git') - path_blacklist.append(root_path + '/build') + global path_blacklist + path_blacklist = map(lambda s: os.path.join(root_path, s), path_blacklist) for cur, dirnames, filenames in os.walk(root_path): for filename in filenames: From 739964cb2511e831216580c8fb0defd69bcc70ae Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 14 Feb 2015 22:25:10 -0500 Subject: [PATCH 10/22] Allow linter to fix some issues automatically --- travis/lint.py | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/travis/lint.py b/travis/lint.py index 597f427c8..8e48fe6da 100644 --- a/travis/lint.py +++ b/travis/lint.py @@ -33,6 +33,10 @@ class Linter(object): if len(failures): raise LinterError('%s: %s' % (self.msg, self.display_lines(failures, len(lines)))) + def fix(self, lines): + for i in range(len(lines)): + lines[i] = self.fix_line(lines[i]) + def display_lines(self, lines, total): if len(lines) == total - 1: return 'entire file' @@ -62,22 +66,29 @@ class NewlineLinter(Linter): msg = 'Contains DOS-style newlines' def check_line(self, line): return '\r' not in line + def fix_line(self, line): + return line.replace('\r', '') class TrailingWhitespaceLinter(Linter): msg = 'Contains trailing whitespace' def check_line(self, line): line = line.replace('\r', '') return not line.endswith(' ') and not line.endswith('\t') + def fix_line(self, line): + return line.rstrip('\t ') class TabLinter(Linter): msg = 'Contains tabs' def check_line(self, line): return '\t' not in line + def fix_line(self, line): + return line.replace('\t', ' ') linters = [NewlineLinter(), TrailingWhitespaceLinter(), TabLinter()] def main(): root_path = os.path.abspath(sys.argv[1] if len(sys.argv) > 1 else '.') + fix = (len(sys.argv) > 2 and sys.argv[2] == '--fix') global path_blacklist path_blacklist = map(lambda s: os.path.join(root_path, s), path_blacklist) @@ -87,13 +98,19 @@ def main(): rel_path = full_path.replace(root_path, '.') if not valid_file(full_path): continue + lines = [] with open(full_path, 'rb') as f: lines = f.read().split('\n') - for linter in linters: - try: - linter.check(lines) - except LinterError as e: - error('%s: %s' % (rel_path, e)) + for linter in linters: + try: + linter.check(lines) + except LinterError as e: + error('%s: %s' % (rel_path, e)) + if fix: + linter.fix(lines) + contents = '\n'.join(lines) + with open(full_path, 'wb') as f: + f.write(contents) if success: print('All linters completed successfully') From 10cfef055320d39b27c3d32470450077b400b1e9 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 14 Feb 2015 22:53:06 -0500 Subject: [PATCH 11/22] Fix whitespace issues --- library/Core.cpp | 4 +- library/Hooks-windows.cpp | 18 +- library/include/DataDefs.h | 2 +- library/include/Pragma.h | 2 +- library/include/SDL_keysym.h | 2 +- library/include/TileTypes.h | 2 +- library/include/modules/Buildings.h | 28 +- library/include/modules/EventManager.h | 6 +- library/include/modules/MapCache.h | 2 +- library/include/modules/Maps.h | 2 +- library/include/modules/Windows.h | 2 +- library/include/wdirent.h | 14 +- library/lua/dfhack/workshops.lua | 14 +- library/lua/dumper.lua | 30 +- library/lua/gui/buildings.lua | 6 +- library/lua/makeown.lua | 536 +++++------ library/modules/EventManager.cpp | 102 +-- library/modules/Items.cpp | 8 +- library/modules/Maps.cpp | 12 +- library/modules/Units.cpp | 12 +- plugins/Dfusion/dfusion.cpp | 6 +- plugins/Dfusion/include/hexsearch.h | 38 +- plugins/Dfusion/include/lua_Hexsearch.h | 18 +- plugins/Dfusion/include/lua_Misc.h | 28 +- plugins/Dfusion/include/luamain.h | 12 +- plugins/Dfusion/src/OutFile.cpp | 2 +- plugins/Dfusion/src/hexsearch.cpp | 172 ++-- plugins/Dfusion/src/lua_Hexsearch.cpp | 62 +- plugins/Dfusion/src/lua_Misc.cpp | 58 +- plugins/Dfusion/src/lua_Process.cpp | 332 +++---- plugins/autochop.cpp | 6 +- plugins/autodump.cpp | 2 +- plugins/automaterial.cpp | 22 +- plugins/automelt.cpp | 2 +- plugins/autotrade.cpp | 6 +- plugins/blueprint.cpp | 14 +- plugins/building-hacks.cpp | 2 +- plugins/buildingplan-lib.cpp | 966 ++++++++++---------- plugins/buildingplan-lib.h | 10 +- plugins/buildingplan.cpp | 10 +- plugins/catsplosion.cpp | 2 +- plugins/changeitem.cpp | 6 +- plugins/changelayer.cpp | 30 +- plugins/createitem.cpp | 2 +- plugins/cursecheck.cpp | 24 +- plugins/devel/autolabor2.cpp | 838 ++++++++--------- plugins/devel/buildprobe.cpp | 2 +- plugins/devel/eventExample.cpp | 8 +- plugins/devel/itemhacks.cpp | 4 +- plugins/devel/memview.cpp | 378 ++++---- plugins/devel/tiles.cpp | 2 +- plugins/devel/vectors.cpp | 4 +- plugins/dig.cpp | 18 +- plugins/digFlood.cpp | 56 +- plugins/diggingInvaders/assignJob.cpp | 24 +- plugins/diggingInvaders/diggingInvaders.cpp | 54 +- plugins/diggingInvaders/edgeCost.cpp | 50 +- plugins/diggingInvaders/edgeCost.h | 2 +- plugins/dwarfexport/dwarfexport.cpp | 8 +- plugins/dwarfmonitor.cpp | 4 +- plugins/eventful.cpp | 2 +- plugins/fastdwarf.cpp | 2 +- plugins/filltraffic.cpp | 58 +- plugins/fixpositions.cpp | 2 +- plugins/follow.cpp | 2 +- plugins/fortplan.cpp | 604 ++++++------ plugins/hotkeys.cpp | 8 +- plugins/infiniteSky.cpp | 10 +- plugins/isoworldremote.cpp | 108 +-- plugins/liquids.cpp | 2 +- plugins/lua/building-hacks.lua | 122 +-- plugins/lua/dfusion.lua | 42 +- plugins/lua/dfusion/adv_tools.lua | 172 ++-- plugins/lua/dfusion/embark.lua | 26 +- plugins/lua/dfusion/friendship.lua | 14 +- plugins/lua/dfusion/tools.lua | 350 +++---- plugins/lua/eventful.lua | 8 +- plugins/lua/stockflow.lua | 216 ++--- plugins/mapexport/mapexport.cpp | 10 +- plugins/mapexport/proto/Tile.proto | 38 +- plugins/misery.cpp | 18 +- plugins/petcapRemover.cpp | 20 +- plugins/probe.cpp | 8 +- plugins/prospector.cpp | 2 +- plugins/proto/RemoteFortressReader.proto | 272 +++--- plugins/proto/isoworldremote.proto | 84 +- plugins/regrass.cpp | 8 +- plugins/rendermax/renderer_light.cpp | 110 +-- plugins/rendermax/renderer_light.hpp | 28 +- plugins/rendermax/renderer_opengl.hpp | 40 +- plugins/rendermax/rendermax.cpp | 6 +- plugins/rendermax/rendermax.lua | 448 ++++----- plugins/resume.cpp | 4 +- plugins/ruby/building.rb | 2 +- plugins/ruby/unit.rb | 6 +- plugins/seedwatch.cpp | 4 +- plugins/stockflow.cpp | 116 +-- plugins/stocks.cpp | 18 +- plugins/strangemood.cpp | 4 +- plugins/trackstop.cpp | 78 +- plugins/treefarm.cpp | 18 +- plugins/uicommon.h | 28 +- plugins/workNow.cpp | 10 +- plugins/workflow.cpp | 2 +- scripts/add-thought.lua | 10 +- scripts/autofarm.rb | 352 +++---- scripts/autounsuspend.rb | 78 +- scripts/create-items.rb | 354 +++---- scripts/deathcause.rb | 134 +-- scripts/devel/light.lua | 588 ++++++------ scripts/devel/scanitemother.rb | 2 +- scripts/devel/spawn-unit-helper.rb | 8 +- scripts/digfort.rb | 130 +-- scripts/drain-aquifer.lua | 4 +- scripts/exterminate.rb | 302 +++--- scripts/fix/blood-del.lua | 2 +- scripts/fix/loyaltycascade.rb | 128 +-- scripts/fix/stuckdoors.rb | 50 +- scripts/forum-dwarves.lua | 42 +- scripts/full-heal.lua | 12 +- scripts/gaydar.lua | 6 +- scripts/growcrops.rb | 98 +- scripts/gui/advfort.lua | 88 +- scripts/gui/advfort_items.lua | 4 +- scripts/gui/companion-order.lua | 50 +- scripts/gui/dfstatus.lua | 20 +- scripts/gui/gm-editor.lua | 36 +- scripts/gui/hack-wish.lua | 40 +- scripts/gui/mod-manager.lua | 206 ++--- scripts/gui/unit-info-viewer.lua | 20 +- scripts/hfs-pit.lua | 14 +- scripts/lever.rb | 248 ++--- scripts/locate-ore.rb | 168 ++-- scripts/log-region.lua | 2 +- scripts/make-monarch.lua | 2 +- scripts/markdown.lua | 112 +-- scripts/masspit.rb | 80 +- scripts/modtools/force.lua | 2 +- scripts/modtools/interaction-trigger.lua | 2 +- scripts/modtools/item-trigger.lua | 14 +- scripts/modtools/random-trigger.lua | 2 +- scripts/modtools/reaction-trigger.lua | 8 +- scripts/multicmd.rb | 8 +- scripts/position.lua | 4 +- scripts/show-unit-syndromes.rb | 40 +- scripts/source.rb | 166 ++-- scripts/startdwarf.rb | 18 +- scripts/stripcaged.rb | 408 ++++----- scripts/superdwarf.rb | 152 +-- scripts/undump-buildings.lua | 2 +- scripts/unsuspend.rb | 34 +- 151 files changed, 5734 insertions(+), 5734 deletions(-) diff --git a/library/Core.cpp b/library/Core.cpp index d7c090701..cba4fe42f 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -1601,8 +1601,8 @@ void Core::onUpdate(color_ostream &out) void Core::handleLoadAndUnloadScripts(color_ostream& out, state_change_event event) { if (!df::global::world) - return; - //TODO: use different separators for windows + return; + //TODO: use different separators for windows #ifdef _WIN32 static const std::string separator = "\\"; #else diff --git a/library/Hooks-windows.cpp b/library/Hooks-windows.cpp index 16109c6c1..552d9c186 100644 --- a/library/Hooks-windows.cpp +++ b/library/Hooks-windows.cpp @@ -143,7 +143,7 @@ DFhackCExport uint32_t SDL_GetTicks(void) /***** Surfaces SDL_CreateRGBSurface SDL_Surface * SDLCALL SDL_CreateRGBSurface - (Uint32 flags, int width, int height, int depth, + (Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); SDL_CreateRGBSurfaceFrom @@ -216,7 +216,7 @@ SDL_SaveBMP_RW SDL_SetAlpha int SDLCALL SDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha); - + SDL_SetColorKey int SDLCALL SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key); @@ -311,16 +311,16 @@ DFhackCExport int SDL_UpperBlit(DFHack::DFSDL_Surface* src, DFHack::DFSDL_Rect* /***** Even more surface SDL_GL_GetAttribute int SDLCALL SDL_GL_GetAttribute(SDL_GLattr attr, int* value); - + SDL_GL_SetAttribute int SDLCALL SDL_GL_SetAttribute(SDL_GLattr attr, int value); - + SDL_WM_SetCaption void SDLCALL SDL_WM_SetCaption(const char *title, const char *icon); - + SDL_WM_SetIcon void SDLCALL SDL_WM_SetIcon(SDL_Surface *icon, Uint8 *mask); - + SDL_FillRect int SDLCALL SDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color); */ @@ -787,7 +787,7 @@ bool FirstCall() _SDL_mutexP = (int (*)(vPtr))GetProcAddress(realSDLlib,"SDL_mutexP"); _SDL_mutexV = (int (*)(vPtr))GetProcAddress(realSDLlib,"SDL_mutexV"); _SDL_strlcpy = (size_t (*)(char*, const char*, size_t))GetProcAddress(realSDLlib,"SDL_strlcpy"); - + // stuff for SDL_Image _SDL_ClearError = (void (*)())GetProcAddress(realSDLlib,"SDL_ClearError"); _SDL_Error = (void (*)(int))GetProcAddress(realSDLlib,"SDL_Error"); @@ -799,7 +799,7 @@ bool FirstCall() _SDL_SetError = (void (*)(const char*, ...))GetProcAddress(realSDLlib,"SDL_SetError"); _SDL_UnloadObject = (void (*)(vPtr))GetProcAddress(realSDLlib,"SDL_UnloadObject"); _SDL_FillRect = (int (*)(void*,void*,uint32_t))GetProcAddress(realSDLlib,"SDL_FillRect"); - + // new in DF 0.31.04 _SDL_CreateSemaphore = (void* (*)(uint32_t))GetProcAddress(realSDLlib,"SDL_CreateSemaphore"); _SDL_CreateThread = (vPtr (*)(int (*fn)(void *), void *data))GetProcAddress(realSDLlib,"SDL_CreateThread"); @@ -812,7 +812,7 @@ bool FirstCall() _SDL_SemTryWait = (int (*)(void *))GetProcAddress(realSDLlib,"SDL_SemTryWait"); _SDL_SemWait = (int (*)(void *))GetProcAddress(realSDLlib,"SDL_SemWait"); _SDL_ThreadID = (uint32_t (*)(void))GetProcAddress(realSDLlib,"SDL_ThreadID"); - + _SDL_EnableUNICODE(1); fprintf(stderr,"Initized HOOKS!\n"); diff --git a/library/include/DataDefs.h b/library/include/DataDefs.h index 3bb62a2c1..513ee5ff2 100644 --- a/library/include/DataDefs.h +++ b/library/include/DataDefs.h @@ -345,7 +345,7 @@ namespace DFHack bool is_direct_instance(virtual_ptr instance_ptr) { if (!instance_ptr) return false; - return vtable_ptr ? (vtable_ptr == get_vtable(instance_ptr)) + return vtable_ptr ? (vtable_ptr == get_vtable(instance_ptr)) : (this == get(instance_ptr)); } diff --git a/library/include/Pragma.h b/library/include/Pragma.h index 7a7e8268f..8f82b8d3c 100644 --- a/library/include/Pragma.h +++ b/library/include/Pragma.h @@ -42,7 +42,7 @@ distribution. /** * [peterix@peterix dfhack]$ man wcscpy_s * No manual entry for wcscpy_s - * + * * Proprietary extensions. */ // disable stupid diff --git a/library/include/SDL_keysym.h b/library/include/SDL_keysym.h index 4f01cfa9c..b73c93a92 100644 --- a/library/include/SDL_keysym.h +++ b/library/include/SDL_keysym.h @@ -78,7 +78,7 @@ namespace SDL K_GREATER = 62, K_QUESTION = 63, K_AT = 64, - /* + /* Skip uppercase letters */ K_LEFTBRACKET = 91, diff --git a/library/include/TileTypes.h b/library/include/TileTypes.h index 1ac58f221..f547eaec1 100644 --- a/library/include/TileTypes.h +++ b/library/include/TileTypes.h @@ -335,7 +335,7 @@ namespace DFHack * zilpin: Find a tile type similar to the one given, but with a different class. * Useful for tile-editing operations. * If no match found, returns the sourceType - * + * * @todo Definitely needs improvement for wall directions, etc. */ DFHACK_EXPORT df::tiletype findSimilarTileType( const df::tiletype sourceTileType, const df::tiletype_shape tshape ); diff --git a/library/include/modules/Buildings.h b/library/include/modules/Buildings.h index 5d0005963..1d939665f 100644 --- a/library/include/modules/Buildings.h +++ b/library/include/modules/Buildings.h @@ -193,14 +193,14 @@ void clearBuildings(color_ostream& out); /** * Iterates over the items stored on a stockpile. * (For stockpiles with containers, yields the containers, not their contents.) - * + * * Usage: - * + * * Buildings::StockpileIterator stored; * for (stored.begin(stockpile); !stored.done(); ++stored) { * df::item *item = *stored; * } - * + * * Implementation detail: Uses tile blocks for speed. * For each tile block that contains at least part of the stockpile, * starting at the top left and moving right, row by row, @@ -212,14 +212,14 @@ class DFHACK_EXPORT StockpileIterator : public std::iteratorx1, stockpile->y1, stockpile->z); current = 0; } - + while (current >= block->items.size()) { // Out of items in this block; find the next block to search. if (block->map_pos.x + 16 < stockpile->x2) { @@ -246,39 +246,39 @@ public: return *this; } } - + // If the current item isn't properly stored, move on to the next. item = df::item::find(block->items[current]); if (!item->flags.bits.on_ground) { continue; } - + if (!Buildings::containsTile(stockpile, item->pos, false)) { continue; } - + // Ignore empty bins, barrels, and wheelbarrows assigned here. if (item->isAssignedToThisStockpile(stockpile->id)) { auto ref = Items::getGeneralRef(item, df::general_ref_type::CONTAINS_ITEM); if (!ref) continue; } - + // Found a valid item; yield it. break; } - + return *this; } - + void begin(df::building_stockpilest* sp) { stockpile = sp; operator++(); } - + df::item* operator*() { return item; } - + bool done() { return block == NULL; } diff --git a/library/include/modules/EventManager.h b/library/include/modules/EventManager.h index 7d5596f16..6e4be47be 100644 --- a/library/include/modules/EventManager.h +++ b/library/include/modules/EventManager.h @@ -59,7 +59,7 @@ namespace DFHack { } }; - + struct InventoryItem { //it has to keep the id of an item because the item itself may have been deallocated int32_t itemId; @@ -74,7 +74,7 @@ namespace DFHack { InventoryChangeData() {} InventoryChangeData(int32_t id_in, InventoryItem* old_in, InventoryItem* new_in): unitId(id_in), item_old(old_in), item_new(new_in) {} }; - + struct UnitAttackData { int32_t attacker; int32_t defender; @@ -89,7 +89,7 @@ namespace DFHack { int32_t attackReport; int32_t defendReport; }; - + DFHACK_EXPORT void registerListener(EventType::EventType e, EventHandler handler, Plugin* plugin); DFHACK_EXPORT int32_t registerTick(EventHandler handler, int32_t when, Plugin* plugin, bool absolute=false); DFHACK_EXPORT void unregister(EventType::EventType e, EventHandler handler, Plugin* plugin); diff --git a/library/include/modules/MapCache.h b/library/include/modules/MapCache.h index 153f819a8..b1d411ab8 100644 --- a/library/include/modules/MapCache.h +++ b/library/include/modules/MapCache.h @@ -72,7 +72,7 @@ class BlockInfo Block *mblock; MapCache *parent; df::map_block *block; - df::map_block_column *column; //for plants + df::map_block_column *column; //for plants public: enum GroundType { diff --git a/library/include/modules/Maps.h b/library/include/modules/Maps.h index 0d00b966f..7ce594522 100644 --- a/library/include/modules/Maps.h +++ b/library/include/modules/Maps.h @@ -181,7 +181,7 @@ extern DFHACK_EXPORT bool IsValid(); * Method for reading the geological surrounding of the currently loaded region. * assign is a reference to an array of nine vectors of unsigned words that are to be filled with the data * array is indexed by the BiomeOffset enum - * + * * I omitted resolving the layer matgloss in this API, because it would * introduce overhead by calling some method for each tile. You have to do it * yourself. diff --git a/library/include/modules/Windows.h b/library/include/modules/Windows.h index 700b88851..f77d0d031 100644 --- a/library/include/modules/Windows.h +++ b/library/include/modules/Windows.h @@ -63,7 +63,7 @@ namespace Windows uint8_t bright; }; - + // our silly painter things and window things follow. class df_window; struct df_tilebuf diff --git a/library/include/wdirent.h b/library/include/wdirent.h index 445d040dc..d059b4030 100644 --- a/library/include/wdirent.h +++ b/library/include/wdirent.h @@ -138,13 +138,13 @@ * only defined for compatibility. These macros should always return false * on Windows. */ -#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFFIFO) -#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) -#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) -#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) -#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) -#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) -#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) +#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFFIFO) +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) +#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) +#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) +#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) #ifdef __cplusplus extern "C" { diff --git a/library/lua/dfhack/workshops.lua b/library/lua/dfhack/workshops.lua index eaad57de1..9fbe4c08a 100644 --- a/library/lua/dfhack/workshops.lua +++ b/library/lua/dfhack/workshops.lua @@ -41,7 +41,7 @@ jobs_furnace={ }, --[[ [df.furnace_type.MetalsmithsForge]={ unpack(concat(furnaces,mechanism,anvil,crafts,coins,flask)) - + }, ]] --MetalsmithsForge, @@ -86,7 +86,7 @@ jobs_furnace={ }, } jobs_workshop={ - + [df.workshop_type.Jewelers]={ { name="cut gems", @@ -146,7 +146,7 @@ jobs_workshop={ items={{}}, job_fields={job_type=df.job_type.ConstructArmorStand} }, - + { name="construct blocks", items={{}}, @@ -226,13 +226,13 @@ jobs_workshop={ [df.workshop_type.Carpenters]={ --training weapons, wooden shields defaults={item_type=df.item_type.WOOD,vector_id=df.job_item_vector_id.WOOD}, - + { name="make barrel", items={{}}, job_fields={job_type=df.job_type.MakeBarrel} }, - + { name="make bucket", items={{}}, @@ -550,7 +550,7 @@ function getJobs(buildingId,workshopId,customId) c_jobs=jobs_workshop[workshopId] elseif buildingId==df.building_type.Furnace then c_jobs=jobs_furnace[workshopId] - + if workshopId == df.furnace_type.Smelter or workshopId == df.furnace_type.MagmaSmelter then c_jobs=utils.clone(c_jobs,true) addSmeltJobs(c_jobs,workshopId == df.furnace_type.Smelter) @@ -563,7 +563,7 @@ function getJobs(buildingId,workshopId,customId) else c_jobs=utils.clone(c_jobs,true) end - + addReactionJobs(c_jobs,buildingId,workshopId,customId) for jobId,contents in pairs(c_jobs) do if jobId~="defaults" then diff --git a/library/lua/dumper.lua b/library/lua/dumper.lua index 44e787db2..52865f0a2 100644 --- a/library/lua/dumper.lua +++ b/library/lua/dumper.lua @@ -27,22 +27,22 @@ local _ENV = mkmodule('dumper') local dumplua_closure = [[ local closures = {} -local function closure(t) +local function closure(t) closures[#closures+1] = t t[1] = assert(loadstring(t[1])) return t[1] end for _,t in pairs(closures) do - for i = 2,#t do - debug.setupvalue(t[1], i-1, t[i]) - end + for i = 2,#t do + debug.setupvalue(t[1], i-1, t[i]) + end end ]] local lua_reserved_keywords = { - 'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', - 'function', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat', + 'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', + 'function', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat', 'return', 'then', 'true', 'until', 'while' } local function keys(t) @@ -63,7 +63,7 @@ local function keys(t) end local c_functions = {} -for _,lib in pairs{'_G', 'string', 'table', 'math', +for _,lib in pairs{'_G', 'string', 'table', 'math', 'io', 'os', 'coroutine', 'package', 'debug'} do local t = _G[lib] or {} lib = lib .. "." @@ -79,9 +79,9 @@ function DataDumper(value, varname, fastmode, ident, indent_step) indent_step = indent_step or 2 local defined, dumplua = {} -- Local variables for speed optimization - local string_format, type, string_dump, string_rep = + local string_format, type, string_dump, string_rep = string.format, type, string.dump, string.rep - local tostring, pairs, table_concat = + local tostring, pairs, table_concat = tostring, pairs, table.concat local keycache, strvalcache, out, closure_cnt = {}, {}, {}, 0 setmetatable(strvalcache, {__index = function(t,value) @@ -94,8 +94,8 @@ function DataDumper(value, varname, fastmode, ident, indent_step) number = function(value) return value end, boolean = function(value) return tostring(value) end, ['nil'] = function(value) return 'nil' end, - ['function'] = function(value) - return string_format("loadstring(%q)", string_dump(value)) + ['function'] = function(value) + return string_format("loadstring(%q)", string_dump(value)) end, userdata = function() error("Cannot dump userdata") end, thread = function() error("Cannot dump threads") end, @@ -124,7 +124,7 @@ function DataDumper(value, varname, fastmode, ident, indent_step) for _,k in ipairs(lua_reserved_keywords) do keycache[k] = '["'..k..'"] = ' end - if fastmode then + if fastmode then fcts.table = function (value) -- Table value local numidx = 1 @@ -142,9 +142,9 @@ function DataDumper(value, varname, fastmode, ident, indent_step) out[#out] = string.sub(out[#out], 1, -2); end out[#out+1] = "}" - return "" + return "" end - else + else fcts.table = function (value, ident, path) if test_defined(value, path) then return "nil" end -- Table value @@ -174,7 +174,7 @@ function DataDumper(value, varname, fastmode, ident, indent_step) if totallen > 80 then sep = "\n" .. string_rep(' ', indent_step*(ident+1)) end - str = "{"..sep..table_concat(str, ","..sep).." "..sep:sub(1,-1-indent_step).."}" + str = "{"..sep..table_concat(str, ","..sep).." "..sep:sub(1,-1-indent_step).."}" if meta then sep = sep:sub(1,-3) return "setmetatable("..sep..str..","..sep..metastr..sep:sub(1,-3)..")" diff --git a/library/lua/gui/buildings.lua b/library/lua/gui/buildings.lua index 97bc884da..ae9219171 100644 --- a/library/lua/gui/buildings.lua +++ b/library/lua/gui/buildings.lua @@ -129,9 +129,9 @@ function BuildingDialog:initBuiltinMode() cb = self:callback('initCustomMode') }) end - - - + + + for i=0,df.building_type._last_item do if (not WORKSHOP_ABSTRACT[i] or self.use_abstract)and not WORKSHOP_SPECIAL[i] then self:addBuilding(choices, df.building_type[i], i, -1,-1,nil) diff --git a/library/lua/makeown.lua b/library/lua/makeown.lua index 3de6584a4..bf3d8077c 100644 --- a/library/lua/makeown.lua +++ b/library/lua/makeown.lua @@ -1,300 +1,300 @@ local _ENV = mkmodule('makeown') --[[ 'tweak makeown' as a lua include - make_own(unit) -- removes foreign flags, sets civ_id to fort civ_id, and sets clothes ownership - make_citizen(unit) -- called by make_own if unit.race == fort race - - eventually ought to migrate to hack/lua/plugins/tweak.lua - and local _ENV = mkmodule('plugin.tweak') - in order to link to functions in the compiled plugin (when/if they become available to lua) + make_own(unit) -- removes foreign flags, sets civ_id to fort civ_id, and sets clothes ownership + make_citizen(unit) -- called by make_own if unit.race == fort race + + eventually ought to migrate to hack/lua/plugins/tweak.lua + and local _ENV = mkmodule('plugin.tweak') + in order to link to functions in the compiled plugin (when/if they become available to lua) --]] local utils = require 'utils' local function fix_clothing_ownership(unit) - -- extracted/translated from tweak makeown plugin - -- to be called by tweak-fixmigrant/makeown - -- units forced into the fort by removing the flags do not own their clothes - -- which has the result that they drop all their clothes and become unhappy because they are naked - -- so we need to make them own their clothes and add them to their uniform - local fixcount = 0 --int fixcount = 0; - for j=0,#unit.inventory-1 do --for(size_t j=0; jinventory.size(); j++) - local inv_item = unit.inventory[j] --unidf::unit_inventory_item* inv_item = unit->inventory[j]; - local item = inv_item.item --df::item* item = inv_item->item; - -- unforbid items (for the case of kidnapping caravan escorts who have their stuff forbidden by default) - -- moved forbid false to inside if so that armor/weapons stay equiped + -- extracted/translated from tweak makeown plugin + -- to be called by tweak-fixmigrant/makeown + -- units forced into the fort by removing the flags do not own their clothes + -- which has the result that they drop all their clothes and become unhappy because they are naked + -- so we need to make them own their clothes and add them to their uniform + local fixcount = 0 --int fixcount = 0; + for j=0,#unit.inventory-1 do --for(size_t j=0; jinventory.size(); j++) + local inv_item = unit.inventory[j] --unidf::unit_inventory_item* inv_item = unit->inventory[j]; + local item = inv_item.item --df::item* item = inv_item->item; + -- unforbid items (for the case of kidnapping caravan escorts who have their stuff forbidden by default) + -- moved forbid false to inside if so that armor/weapons stay equiped if inv_item.mode == df.unit_inventory_item.T_mode.Worn then --if(inv_item->mode == df::unit_inventory_item::T_mode::Worn) - -- ignore armor? - -- it could be leather boots, for example, in which case it would not be nice to forbid ownership - --if(item->getEffectiveArmorLevel() != 0) - -- continue; + -- ignore armor? + -- it could be leather boots, for example, in which case it would not be nice to forbid ownership + --if(item->getEffectiveArmorLevel() != 0) + -- continue; - if not dfhack.items.getOwner(item) then --if(!Items::getOwner(item)) - if dfhack.items.setOwner(item,unit) then --if(Items::setOwner(item, unit)) - item.flags.forbid = false --inv_item->item->flags.bits.forbid = 0; - -- add to uniform, so they know they should wear their clothes - unit.military.uniforms[0]:insert('#',item.id) --insert_into_vector(unit->military.uniforms[0], item->id); - fixcount = fixcount + 1 --fixcount++; + if not dfhack.items.getOwner(item) then --if(!Items::getOwner(item)) + if dfhack.items.setOwner(item,unit) then --if(Items::setOwner(item, unit)) + item.flags.forbid = false --inv_item->item->flags.bits.forbid = 0; + -- add to uniform, so they know they should wear their clothes + unit.military.uniforms[0]:insert('#',item.id) --insert_into_vector(unit->military.uniforms[0], item->id); + fixcount = fixcount + 1 --fixcount++; else - ----out << "could not change ownership for item!" << endl; - print("Makeown: could not change ownership for an item!") - end - end - end - end - -- clear uniform_drop (without this they would drop their clothes and pick them up some time later) - -- dirty? - unit.military.uniform_drop:resize(0) --unit->military.uniform_drop.clear(); - ----out << "ownership for " << fixcount << " clothes fixed" << endl; - print("Makeown: claimed ownership for "..tostring(fixcount).." worn items") - --return true --return CR_OK; + ----out << "could not change ownership for item!" << endl; + print("Makeown: could not change ownership for an item!") + end + end + end + end + -- clear uniform_drop (without this they would drop their clothes and pick them up some time later) + -- dirty? + unit.military.uniform_drop:resize(0) --unit->military.uniform_drop.clear(); + ----out << "ownership for " << fixcount << " clothes fixed" << endl; + print("Makeown: claimed ownership for "..tostring(fixcount).." worn items") + --return true --return CR_OK; end local function entity_link(hf, eid, do_event, add, replace_idx) - do_event = (do_event == nil) and true or do_event - add = (add == nil) and true or add - replace_idx = replace_idx or -1 - - local link = add and df.histfig_entity_link_memberst:new() or df.histfig_entity_link_former_memberst:new() - link.entity_id = eid - if replace_idx > -1 then - local e = hf.entity_links[replace_idx] - link.link_strength = (e.link_strength > 3) and (e.link_strength - 2) or e.link_strength - hf.entity_links[replace_idx] = link -- replace member link with former member link - e:delete() - else - link.link_strength = 100 - hf.entity_links:insert('#', link) - end - if do_event then - event = add and df.history_event_add_hf_entity_linkst:new() or df.history_event_remove_hf_entity_linkst:new() - event.year = df.global.cur_year - event.seconds = df.global.cur_year_tick - event.civ = eid - event.histfig = hf.id - event.link_type = 0 - event.position_id = -1 - event.id = df.global.hist_event_next_id - df.global.world.history.events:insert('#',event) - df.global.hist_event_next_id = df.global.hist_event_next_id + 1 - end + do_event = (do_event == nil) and true or do_event + add = (add == nil) and true or add + replace_idx = replace_idx or -1 + + local link = add and df.histfig_entity_link_memberst:new() or df.histfig_entity_link_former_memberst:new() + link.entity_id = eid + if replace_idx > -1 then + local e = hf.entity_links[replace_idx] + link.link_strength = (e.link_strength > 3) and (e.link_strength - 2) or e.link_strength + hf.entity_links[replace_idx] = link -- replace member link with former member link + e:delete() + else + link.link_strength = 100 + hf.entity_links:insert('#', link) + end + if do_event then + event = add and df.history_event_add_hf_entity_linkst:new() or df.history_event_remove_hf_entity_linkst:new() + event.year = df.global.cur_year + event.seconds = df.global.cur_year_tick + event.civ = eid + event.histfig = hf.id + event.link_type = 0 + event.position_id = -1 + event.id = df.global.hist_event_next_id + df.global.world.history.events:insert('#',event) + df.global.hist_event_next_id = df.global.hist_event_next_id + 1 + end end local function change_state(hf, site_id, pos) - hf.info.unk_14.unk_0 = 3 -- state? arrived? - hf.info.unk_14.region:assign(pos) - hf.info.unk_14.site = site_id - event = df.history_event_change_hf_statest:new() - event.year = df.global.cur_year - event.seconds = df.global.cur_year_tick - event.hfid = hf.id - event.state = 3 - event.site = site_id - event.region_pos:assign(pos) - event.substate = -1; event.region = -1; event.layer = -1; - event.id = df.global.hist_event_next_id - df.global.world.history.events:insert('#',event) - df.global.hist_event_next_id = df.global.hist_event_next_id + 1 + hf.info.unk_14.unk_0 = 3 -- state? arrived? + hf.info.unk_14.region:assign(pos) + hf.info.unk_14.site = site_id + event = df.history_event_change_hf_statest:new() + event.year = df.global.cur_year + event.seconds = df.global.cur_year_tick + event.hfid = hf.id + event.state = 3 + event.site = site_id + event.region_pos:assign(pos) + event.substate = -1; event.region = -1; event.layer = -1; + event.id = df.global.hist_event_next_id + df.global.world.history.events:insert('#',event) + df.global.hist_event_next_id = df.global.hist_event_next_id + 1 end function make_citizen(unit) - local dfg = df.global - local civ_id = dfg.ui.civ_id - local group_id = dfg.ui.group_id - local events = dfg.world.history.events - local fortent = dfg.ui.main.fortress_entity - local civent = fortent and df.historical_entity.find(fortent.entity_links[0].target) - -- utils.binsearch(dfg.world.entities.all, fortent.entity_links[0].target, 'id') - local event - local region_pos = df.world_site.find(dfg.ui.site_id).pos -- used with state events and hf state - - local hf - -- assume that hf id 1 and hf id 2 are equal. I am unaware of instances of when they are not. - -- occationally a unit does not have both flags set (missing flags1.important_historical_figure) - -- and I don't know what that means yet. - if unit.flags1.important_historical_figure and unit.flags2.important_historical_figure then - -- aready hf, find it (unlikely to happen) - hf = utils.binsearch(dfg.world.history.figures, unit.hist_figure_id, 'id') - --elseif unit.flags1.important_historical_figure or unit.flags2.important_historical_figure then - -- something wrong, try to fix it? - --[[ - if unit.hist_figure_id == -1 then - unit.hist_figure_id = unit.hist_figure_id2 - end - if unit.hist_figure_id > -1 then - unit.hist_figure_id2 = unit.hist_figure_id - unit.flags1.important_historical_figure = true - unit.flags2.important_historical_figure = true - hf = utils.binsearch(dfg.world.history.figures, unit.hist_figure_id, 'id') - else - unit.flags1.important_historical_figure = false - unit.flags2.important_historical_figure = false - end - --]] - --else - -- make one - end - --local new_hf = false - if not hf then - --new_hf = true - hf = df.historical_figure:new() - hf.profession = unit.profession - hf.race = unit.race - hf.caste = unit.caste - hf.sex = unit.sex - hf.appeared_year = dfg.cur_year - hf.born_year = unit.relations.birth_year - hf.born_seconds = unit.relations.birth_time - hf.curse_year = unit.relations.curse_year - hf.curse_seconds = unit.relations.curse_time - hf.anon_1 = unit.relations.anon_2 - hf.anon_2 = unit.relations.anon_3 - hf.old_year = unit.relations.old_year - hf.old_seconds = unit.relations.old_time - hf.died_year = -1 - hf.died_seconds = -1 - hf.name:assign(unit.name) - hf.civ_id = unit.civ_id - hf.population_id = unit.population_id - hf.breed_id = -1 - hf.unit_id = unit.id - hf.id = dfg.hist_figure_next_id -- id must be set before adding links (for the events) - - --history_event_add_hf_entity_linkst not reported for civ on starting 7 - entity_link(hf, civ_id, false) -- so lets skip event here - entity_link(hf, group_id) - - hf.info = df.historical_figure_info:new() - hf.info.unk_14 = df.historical_figure_info.T_unk_14:new() -- hf state? - --unk_14.region_id = -1; unk_14.beast_id = -1; unk_14.unk_14 = 0 - hf.info.unk_14.unk_18 = -1; hf.info.unk_14.unk_1c = -1 - -- set values that seem related to state and do event - change_state(hf, dfg.ui.site_id, region_pos) - - - --lets skip skills for now - --local skills = df.historical_figure_info.T_skills:new() -- skills snap shot - -- ... - --info.skills = skills - - dfg.world.history.figures:insert('#', hf) - dfg.hist_figure_next_id = dfg.hist_figure_next_id + 1 - - --new_hf_loc = df.global.world.history.figures[#df.global.world.history.figures - 1] - fortent.histfig_ids:insert('#', hf.id) - fortent.hist_figures:insert('#', hf) - civent.histfig_ids:insert('#', hf.id) - civent.hist_figures:insert('#', hf) - - unit.flags1.important_historical_figure = true - unit.flags2.important_historical_figure = true - unit.hist_figure_id = hf.id - unit.hist_figure_id2 = hf.id - print("Makeown-citizen: created historical figure") - else - -- only insert into civ/fort if not already there - -- Migrants change previous histfig_entity_link_memberst to histfig_entity_link_former_memberst - -- for group entities, add link_member for new group, and reports events for remove from group, - -- remove from civ, change state, add civ, and add group - - hf.civ_id = civ_id -- ensure current civ_id + local dfg = df.global + local civ_id = dfg.ui.civ_id + local group_id = dfg.ui.group_id + local events = dfg.world.history.events + local fortent = dfg.ui.main.fortress_entity + local civent = fortent and df.historical_entity.find(fortent.entity_links[0].target) + -- utils.binsearch(dfg.world.entities.all, fortent.entity_links[0].target, 'id') + local event + local region_pos = df.world_site.find(dfg.ui.site_id).pos -- used with state events and hf state + + local hf + -- assume that hf id 1 and hf id 2 are equal. I am unaware of instances of when they are not. + -- occationally a unit does not have both flags set (missing flags1.important_historical_figure) + -- and I don't know what that means yet. + if unit.flags1.important_historical_figure and unit.flags2.important_historical_figure then + -- aready hf, find it (unlikely to happen) + hf = utils.binsearch(dfg.world.history.figures, unit.hist_figure_id, 'id') + --elseif unit.flags1.important_historical_figure or unit.flags2.important_historical_figure then + -- something wrong, try to fix it? + --[[ + if unit.hist_figure_id == -1 then + unit.hist_figure_id = unit.hist_figure_id2 + end + if unit.hist_figure_id > -1 then + unit.hist_figure_id2 = unit.hist_figure_id + unit.flags1.important_historical_figure = true + unit.flags2.important_historical_figure = true + hf = utils.binsearch(dfg.world.history.figures, unit.hist_figure_id, 'id') + else + unit.flags1.important_historical_figure = false + unit.flags2.important_historical_figure = false + end + --]] + --else + -- make one + end + --local new_hf = false + if not hf then + --new_hf = true + hf = df.historical_figure:new() + hf.profession = unit.profession + hf.race = unit.race + hf.caste = unit.caste + hf.sex = unit.sex + hf.appeared_year = dfg.cur_year + hf.born_year = unit.relations.birth_year + hf.born_seconds = unit.relations.birth_time + hf.curse_year = unit.relations.curse_year + hf.curse_seconds = unit.relations.curse_time + hf.anon_1 = unit.relations.anon_2 + hf.anon_2 = unit.relations.anon_3 + hf.old_year = unit.relations.old_year + hf.old_seconds = unit.relations.old_time + hf.died_year = -1 + hf.died_seconds = -1 + hf.name:assign(unit.name) + hf.civ_id = unit.civ_id + hf.population_id = unit.population_id + hf.breed_id = -1 + hf.unit_id = unit.id + hf.id = dfg.hist_figure_next_id -- id must be set before adding links (for the events) + + --history_event_add_hf_entity_linkst not reported for civ on starting 7 + entity_link(hf, civ_id, false) -- so lets skip event here + entity_link(hf, group_id) + + hf.info = df.historical_figure_info:new() + hf.info.unk_14 = df.historical_figure_info.T_unk_14:new() -- hf state? + --unk_14.region_id = -1; unk_14.beast_id = -1; unk_14.unk_14 = 0 + hf.info.unk_14.unk_18 = -1; hf.info.unk_14.unk_1c = -1 + -- set values that seem related to state and do event + change_state(hf, dfg.ui.site_id, region_pos) + + + --lets skip skills for now + --local skills = df.historical_figure_info.T_skills:new() -- skills snap shot + -- ... + --info.skills = skills + + dfg.world.history.figures:insert('#', hf) + dfg.hist_figure_next_id = dfg.hist_figure_next_id + 1 + + --new_hf_loc = df.global.world.history.figures[#df.global.world.history.figures - 1] + fortent.histfig_ids:insert('#', hf.id) + fortent.hist_figures:insert('#', hf) + civent.histfig_ids:insert('#', hf.id) + civent.hist_figures:insert('#', hf) + + unit.flags1.important_historical_figure = true + unit.flags2.important_historical_figure = true + unit.hist_figure_id = hf.id + unit.hist_figure_id2 = hf.id + print("Makeown-citizen: created historical figure") + else + -- only insert into civ/fort if not already there + -- Migrants change previous histfig_entity_link_memberst to histfig_entity_link_former_memberst + -- for group entities, add link_member for new group, and reports events for remove from group, + -- remove from civ, change state, add civ, and add group + + hf.civ_id = civ_id -- ensure current civ_id + + local found_civlink = false + local found_fortlink = false + local v = hf.entity_links + for k=#v-1,0,-1 do + if df.histfig_entity_link_memberst:is_instance(v[k]) then + entity_link(hf, v[k].entity_id, true, false, k) + end + end + + if hf.info and hf.info.unk_14 then + change_state(hf, dfg.ui.site_id, region_pos) + -- leave info nil if not found for now + end + + if not found_civlink then entity_link(hf,civ_id) end + if not found_fortlink then entity_link(hf,group_id) end + + --change entity_links + local found = false + for _,v in ipairs(civent.histfig_ids) do + if v == hf.id then found = true; break end + end + if not found then + civent.histfig_ids:insert('#', hf.id) + civent.hist_figures:insert('#', hf) + end + found = false + for _,v in ipairs(fortent.histfig_ids) do + if v == hf.id then found = true; break end + end + if not found then + fortent.histfig_ids:insert('#', hf.id) + fortent.hist_figures:insert('#', hf) + end + print("Makeown-citizen: migrated historical figure") + end -- hf - local found_civlink = false - local found_fortlink = false - local v = hf.entity_links - for k=#v-1,0,-1 do - if df.histfig_entity_link_memberst:is_instance(v[k]) then - entity_link(hf, v[k].entity_id, true, false, k) - end - end - - if hf.info and hf.info.unk_14 then - change_state(hf, dfg.ui.site_id, region_pos) - -- leave info nil if not found for now - end - - if not found_civlink then entity_link(hf,civ_id) end - if not found_fortlink then entity_link(hf,group_id) end - - --change entity_links - local found = false - for _,v in ipairs(civent.histfig_ids) do - if v == hf.id then found = true; break end - end - if not found then - civent.histfig_ids:insert('#', hf.id) - civent.hist_figures:insert('#', hf) - end - found = false - for _,v in ipairs(fortent.histfig_ids) do - if v == hf.id then found = true; break end - end - if not found then - fortent.histfig_ids:insert('#', hf.id) - fortent.hist_figures:insert('#', hf) - end - print("Makeown-citizen: migrated historical figure") - end -- hf + local nemesis = dfhack.units.getNemesis(unit) + if not nemesis then + nemesis = df.nemesis_record:new() + nemesis.figure = hf + nemesis.unit = unit + nemesis.unit_id = unit.id + nemesis.save_file_id = civent.save_file_id + nemesis.unk10, nemesis.unk11, nemesis.unk12 = -1, -1, -1 + --group_leader_id = -1 + nemesis.id = dfg.nemesis_next_id + nemesis.member_idx = civent.next_member_idx + civent.next_member_idx = civent.next_member_idx + 1 - local nemesis = dfhack.units.getNemesis(unit) - if not nemesis then - nemesis = df.nemesis_record:new() - nemesis.figure = hf - nemesis.unit = unit - nemesis.unit_id = unit.id - nemesis.save_file_id = civent.save_file_id - nemesis.unk10, nemesis.unk11, nemesis.unk12 = -1, -1, -1 - --group_leader_id = -1 - nemesis.id = dfg.nemesis_next_id - nemesis.member_idx = civent.next_member_idx - civent.next_member_idx = civent.next_member_idx + 1 + dfg.world.nemesis.all:insert('#', nemesis) + dfg.nemesis_next_id = dfg.nemesis_next_id + 1 - dfg.world.nemesis.all:insert('#', nemesis) - dfg.nemesis_next_id = dfg.nemesis_next_id + 1 + nemesis_link = df.general_ref_is_nemesisst:new() + nemesis_link.nemesis_id = nemesis.id + unit.general_refs:insert('#', nemesis_link) - nemesis_link = df.general_ref_is_nemesisst:new() - nemesis_link.nemesis_id = nemesis.id - unit.general_refs:insert('#', nemesis_link) - - --new_nemesis_loc = df.global.world.nemesis.all[#df.global.world.nemesis.all - 1] - fortent.nemesis_ids:insert('#', nemesis.id) - fortent.nemesis:insert('#', nemesis) - civent.nemesis_ids:insert('#', nemesis.id) - civent.nemesis:insert('#', nemesis) - print("Makeown-citizen: created nemesis entry") - else-- only insert into civ/fort if not already there - local found = false - for _,v in ipairs(civent.nemesis_ids) do - if v == nemesis.id then found = true; break end - end - if not found then - civent.nemesis_ids:insert('#', nemesis.id) - civent.nemesis:insert('#', nemesis) - end - found = false - for _,v in ipairs(fortent.nemesis_ids) do - if v == nemesis.id then found = true; break end - end - if not found then - fortent.nemesis_ids:insert('#', nemesis.id) - fortent.nemesis:insert('#', nemesis) - end - print("Makeown-citizen: migrated nemesis entry") - end -- nemesis + --new_nemesis_loc = df.global.world.nemesis.all[#df.global.world.nemesis.all - 1] + fortent.nemesis_ids:insert('#', nemesis.id) + fortent.nemesis:insert('#', nemesis) + civent.nemesis_ids:insert('#', nemesis.id) + civent.nemesis:insert('#', nemesis) + print("Makeown-citizen: created nemesis entry") + else-- only insert into civ/fort if not already there + local found = false + for _,v in ipairs(civent.nemesis_ids) do + if v == nemesis.id then found = true; break end + end + if not found then + civent.nemesis_ids:insert('#', nemesis.id) + civent.nemesis:insert('#', nemesis) + end + found = false + for _,v in ipairs(fortent.nemesis_ids) do + if v == nemesis.id then found = true; break end + end + if not found then + fortent.nemesis_ids:insert('#', nemesis.id) + fortent.nemesis:insert('#', nemesis) + end + print("Makeown-citizen: migrated nemesis entry") + end -- nemesis end function make_own(unit) - --tweak makeown - unit.flags2.resident = false; unit.flags1.merchant = false; unit.flags1.forest = false; - unit.civ_id = df.global.ui.civ_id - if unit.profession == df.profession.MERCHANT then unit.profession = df.profession.TRADER end - if unit.profession2 == df.profession.MERCHANT then unit.profession2 = df.profession.TRADER end - fix_clothing_ownership(unit) - if unit.race == df.global.ui.race_id then - make_citizen(unit) - end + --tweak makeown + unit.flags2.resident = false; unit.flags1.merchant = false; unit.flags1.forest = false; + unit.civ_id = df.global.ui.civ_id + if unit.profession == df.profession.MERCHANT then unit.profession = df.profession.TRADER end + if unit.profession2 == df.profession.MERCHANT then unit.profession2 = df.profession.TRADER end + fix_clothing_ownership(unit) + if unit.race == df.global.ui.race_id then + make_citizen(unit) + end end diff --git a/library/modules/EventManager.cpp b/library/modules/EventManager.cpp index 46178d818..6384e897c 100644 --- a/library/modules/EventManager.cpp +++ b/library/modules/EventManager.cpp @@ -111,7 +111,7 @@ void DFHack::EventManager::unregisterAll(Plugin* plugin) { for ( auto i = handlers[EventType::TICK].find(plugin); i != handlers[EventType::TICK].end(); i++ ) { if ( (*i).first != plugin ) break; - + removeFromTickQueue((*i).second); } for ( size_t a = 0; a < (size_t)EventType::EVENT_MAX; a++ ) { @@ -248,12 +248,12 @@ void DFHack::EventManager::onStateChange(color_ostream& out, state_change_event return; if (!df::global::world) return; - + nextItem = *df::global::item_next_id; nextBuilding = *df::global::building_next_id; nextInvasion = df::global::ui->invasions.next_id; lastJobId = -1 + *df::global::job_next_id; - + constructions.clear(); for ( auto i = df::global::world->constructions.begin(); i != df::global::world->constructions.end(); i++ ) { df::construction* constr = *i; @@ -296,7 +296,7 @@ void DFHack::EventManager::onStateChange(color_ostream& out, state_change_event for ( size_t a = 0; a < EventType::EVENT_MAX; a++ ) { eventLastTick[a] = -1;//-1000000; } - + gameLoaded = true; } } @@ -309,7 +309,7 @@ void DFHack::EventManager::manageEvents(color_ostream& out) { return; CoreSuspender suspender; - + int32_t tick = df::global::world->frame_counter; for ( size_t a = 0; a < EventType::EVENT_MAX; a++ ) { @@ -323,10 +323,10 @@ void DFHack::EventManager::manageEvents(color_ostream& out) { eventFrequency = bob.freq; } else eventFrequency = 1; - + if ( tick >= eventLastTick[a] && tick - eventLastTick[a] < eventFrequency ) continue; - + eventManager[a](out); eventLastTick[a] = tick; } @@ -369,12 +369,12 @@ static void manageJobInitiatedEvent(color_ostream& out) { lastJobId = *df::global::job_next_id - 1; return; } - + if ( lastJobId+1 == *df::global::job_next_id ) { return; //no new jobs } multimap copy(handlers[EventType::JOB_INITIATED].begin(), handlers[EventType::JOB_INITIATED].end()); - + for ( df::job_list_link* link = &df::global::world->job_list; link != NULL; link = link->next ) { if ( link->item == NULL ) continue; @@ -384,7 +384,7 @@ static void manageJobInitiatedEvent(color_ostream& out) { (*i).second.eventHandler(out, (void*)link->item); } } - + lastJobId = *df::global::job_next_id - 1; } @@ -402,7 +402,7 @@ static void manageJobCompletedEvent(color_ostream& out) { return; int32_t tick0 = eventLastTick[EventType::JOB_COMPLETED]; int32_t tick1 = df::global::world->frame_counter; - + multimap copy(handlers[EventType::JOB_COMPLETED].begin(), handlers[EventType::JOB_COMPLETED].end()); map nowJobs; for ( df::job_list_link* link = &df::global::world->job_list; link != NULL; link = link->next ) { @@ -410,14 +410,14 @@ static void manageJobCompletedEvent(color_ostream& out) { continue; nowJobs[link->item->id] = link->item; } - + #if 0 //testing info on job initiation/completion //newly allocated jobs for ( auto j = nowJobs.begin(); j != nowJobs.end(); j++ ) { if ( prevJobs.find((*j).first) != prevJobs.end() ) continue; - + df::job& job1 = *(*j).second; out.print("new job\n" " location : 0x%X\n" @@ -445,12 +445,12 @@ static void manageJobCompletedEvent(color_ostream& out) { continue; } df::job& job1 = *(*j).second; - + if ( job0.flags.bits.working == job1.flags.bits.working && (job0.completion_timer == job1.completion_timer || (job1.completion_timer > 0 && job0.completion_timer-1 == job1.completion_timer)) && getWorkerID(&job0) == getWorkerID(&job1) ) continue; - + out.print("job change\n" " location : 0x%X -> 0x%X\n" " id : %d -> %d\n" @@ -472,12 +472,12 @@ static void manageJobCompletedEvent(color_ostream& out) { ); } #endif - + for ( auto i = prevJobs.begin(); i != prevJobs.end(); i++ ) { //if it happened within a tick, must have been cancelled by the user or a plugin: not completed if ( tick1 <= tick0 ) continue; - + if ( nowJobs.find((*i).first) != nowJobs.end() ) { //could have just finished if it's a repeat job df::job& job0 = *(*i).second; @@ -488,19 +488,19 @@ static void manageJobCompletedEvent(color_ostream& out) { continue; if ( job1.completion_timer != -1 ) continue; - + //still false positive if cancelled at EXACTLY the right time, but experiments show this doesn't happen for ( auto j = copy.begin(); j != copy.end(); j++ ) { (*j).second.eventHandler(out, (void*)&job0); } continue; } - + //recently finished or cancelled job df::job& job0 = *(*i).second; if ( job0.flags.bits.repeat || job0.completion_timer != 0 ) continue; - + for ( auto j = copy.begin(); j != copy.end(); j++ ) { (*j).second.eventHandler(out, (void*)&job0); } @@ -511,7 +511,7 @@ static void manageJobCompletedEvent(color_ostream& out) { Job::deleteJobStruct((*i).second, true); } prevJobs.clear(); - + //create new jobs for ( auto j = nowJobs.begin(); j != nowJobs.end(); j++ ) { /*map::iterator i = prevJobs.find((*j).first); @@ -538,7 +538,7 @@ static void manageUnitDeathEvent(color_ostream& out) { //dead: if dead since last check, trigger events if ( livingUnits.find(unit->id) == livingUnits.end() ) continue; - + for ( auto i = copy.begin(); i != copy.end(); i++ ) { (*i).second.eventHandler(out, (void*)unit->id); } @@ -554,7 +554,7 @@ static void manageItemCreationEvent(color_ostream& out) { if ( nextItem >= *df::global::item_next_id ) { return; } - + multimap copy(handlers[EventType::ITEM_CREATED].begin(), handlers[EventType::ITEM_CREATED].end()); size_t index = df::item::binsearch_index(df::global::world->items.all, nextItem, false); if ( index != 0 ) index--; @@ -607,7 +607,7 @@ static void manageBuildingEvent(color_ostream& out) { } } nextBuilding = *df::global::building_next_id; - + //now alert people about destroyed buildings for ( auto a = buildings.begin(); a != buildings.end(); ) { int32_t id = *a; @@ -616,7 +616,7 @@ static void manageBuildingEvent(color_ostream& out) { a++; continue; } - + for ( auto b = copy.begin(); b != copy.end(); b++ ) { EventHandler bob = (*b).second; bob.eventHandler(out, (void*)id); @@ -629,7 +629,7 @@ static void manageConstructionEvent(color_ostream& out) { if (!df::global::world) return; //unordered_set constructionsNow(df::global::world->constructions.begin(), df::global::world->constructions.end()); - + multimap copy(handlers[EventType::CONSTRUCTION].begin(), handlers[EventType::CONSTRUCTION].end()); for ( auto a = constructions.begin(); a != constructions.end(); ) { df::construction& construction = (*a).second; @@ -645,7 +645,7 @@ static void manageConstructionEvent(color_ostream& out) { } a = constructions.erase(a); } - + //for ( auto a = constructionsNow.begin(); a != constructionsNow.end(); a++ ) { for ( auto a = df::global::world->constructions.begin(); a != df::global::world->constructions.end(); a++ ) { df::construction* construction = *a; @@ -680,7 +680,7 @@ static void manageSyndromeEvent(color_ostream& out) { highestTime = startTime; if ( startTime <= lastSyndromeTime ) continue; - + SyndromeData data(unit->id, b); for ( auto c = copy.begin(); c != copy.end(); c++ ) { EventHandler handle = (*c).second; @@ -710,7 +710,7 @@ static void manageEquipmentEvent(color_ostream& out) { if (!df::global::world) return; multimap copy(handlers[EventType::INVENTORY_CHANGE].begin(), handlers[EventType::INVENTORY_CHANGE].end()); - + unordered_map itemIdToInventoryItem; unordered_set currentlyEquipped; for ( auto a = df::global::world->units.all.begin(); a != df::global::world->units.all.end(); a++ ) { @@ -720,7 +720,7 @@ static void manageEquipmentEvent(color_ostream& out) { /*if ( unit->flags1.bits.dead ) continue; */ - + auto oldEquipment = equipmentLog.find(unit->id); bool hadEquipment = oldEquipment != equipmentLog.end(); vector* temp; @@ -750,13 +750,13 @@ static void manageEquipmentEvent(color_ostream& out) { continue; } InventoryItem item_old = (*c).second; - + df::unit_inventory_item& item0 = item_old.item; df::unit_inventory_item& item1 = item_new.item; if ( item0.mode == item1.mode && item0.body_part_id == item1.body_part_id && item0.wound_id == item1.wound_id ) continue; //some sort of change in how it's equipped - + InventoryChangeData data(unit->id, &item_old, &item_new); for ( auto h = copy.begin(); h != copy.end(); h++ ) { EventHandler handle = (*h).second; @@ -777,7 +777,7 @@ static void manageEquipmentEvent(color_ostream& out) { } if ( !hadEquipment ) delete temp; - + //update equipment vector& equipment = equipmentLog[unit->id]; equipment.clear(); @@ -795,7 +795,7 @@ static void updateReportToRelevantUnits() { if ( df::global::world->frame_counter <= reportToRelevantUnitsTime ) return; reportToRelevantUnitsTime = df::global::world->frame_counter; - + for ( size_t a = 0; a < df::global::world->units.all.size(); a++ ) { df::unit* unit = df::global::world->units.all[a]; for ( int16_t b = df::enum_traits::first_item_value; b <= df::enum_traits::last_item_value; b++ ) { @@ -862,7 +862,7 @@ static void manageUnitAttackEvent(color_ostream& out) { strikeReports.insert(report->id); } } - + if ( strikeReports.empty() ) return; updateReportToRelevantUnits(); @@ -883,37 +883,37 @@ static void manageUnitAttackEvent(color_ostream& out) { break; reportStr = reportStr + report2->text; } - + std::vector& relevantUnits = reportToRelevantUnits[report->id]; if ( relevantUnits.size() != 2 ) { continue; } - + df::unit* unit1 = df::unit::find(relevantUnits[0]); df::unit* unit2 = df::unit::find(relevantUnits[1]); - + df::unit_wound* wound1 = getWound(unit1,unit2); df::unit_wound* wound2 = getWound(unit2,unit1); - + if ( wound1 && !alreadyDone[unit1->id][unit2->id] ) { UnitAttackData data; data.attacker = unit1->id; data.defender = unit2->id; data.wound = wound1->id; - + alreadyDone[data.attacker][data.defender] = 1; for ( auto b = copy.begin(); b != copy.end(); b++ ) { EventHandler handle = (*b).second; handle.eventHandler(out, (void*)&data); } } - + if ( wound2 && !alreadyDone[unit1->id][unit2->id] ) { UnitAttackData data; data.attacker = unit2->id; data.defender = unit1->id; data.wound = wound2->id; - + alreadyDone[data.attacker][data.defender] = 1; for ( auto b = copy.begin(); b != copy.end(); b++ ) { EventHandler handle = (*b).second; @@ -932,7 +932,7 @@ static void manageUnitAttackEvent(color_ostream& out) { handle.eventHandler(out, (void*)&data); } } - + if ( unit2->flags1.bits.dead ) { UnitAttackData data; data.attacker = unit1->id; @@ -944,7 +944,7 @@ static void manageUnitAttackEvent(color_ostream& out) { handle.eventHandler(out, (void*)&data); } } - + if ( !wound1 && !wound2 ) { //if ( unit1->flags1.bits.dead || unit2->flags1.bits.dead ) // continue; @@ -992,7 +992,7 @@ static std::string getVerb(df::unit* unit, std::string reportStr) { static InteractionData getAttacker(color_ostream& out, df::report* attackEvent, df::unit* lastAttacker, df::report* defendEvent, vector& relevantUnits) { vector attackers = relevantUnits; vector defenders = relevantUnits; - + //find valid interactions: TODO /*map > validInteractions; for ( size_t a = 0; a < relevantUnits.size(); a++ ) { @@ -1000,7 +1000,7 @@ static InteractionData getAttacker(color_ostream& out, df::report* attackEvent, vector& interactions = validInteractions[unit->id]; for ( size_t b = 0; b < unit->body. }*/ - + //if attackEvent // attacker must be same location // attacker name must start attack str @@ -1019,7 +1019,7 @@ static InteractionData getAttacker(color_ostream& out, df::report* attackEvent, a--; continue; } - + std::string verbC = getVerb(attackers[a], attackEvent->text); if ( verbC.length() == 0 ) { attackers.erase(attackers.begin()+a); @@ -1029,7 +1029,7 @@ static InteractionData getAttacker(color_ostream& out, df::report* attackEvent, attackVerb = verbC; } } - + //if defendEvent // defender must be same location // defender name must start defend str @@ -1052,7 +1052,7 @@ static InteractionData getAttacker(color_ostream& out, df::report* attackEvent, defendVerb = verbC; } } - + //keep in mind one attacker zero defenders is perfectly valid for self-cast if ( attackers.size() == 1 && defenders.size() == 1 && attackers[0] == defenders[0] ) { //out.print("%s,%d\n",__FILE__,__LINE__); @@ -1070,7 +1070,7 @@ static InteractionData getAttacker(color_ostream& out, df::report* attackEvent, defenders.erase(a); } } - + //if trying attack-defend pair and it fails to find attacker, try defend only InteractionData result = /*(InteractionData)*/ { std::string(), std::string(), -1, -1, -1, -1 }; if ( attackers.size() > 1 ) { @@ -1141,7 +1141,7 @@ static void manageInteractionEvent(color_ostream& out) { } if ( a < reports.size() ) updateReportToRelevantUnits(); - + df::report* lastAttackEvent = NULL; df::unit* lastAttacker = NULL; df::unit* lastDefender = NULL; diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp index 253e09468..eaa3b7ad2 100644 --- a/library/modules/Items.cpp +++ b/library/modules/Items.cpp @@ -1362,23 +1362,23 @@ int32_t Items::createItem(df::item_type item_type, int16_t item_subtype, int16_t prod->product_dimension = 1; break; } - + //makeItem vector out_items; vector in_reag; vector in_items; - + df::enums::game_type::game_type type = *df::global::gametype; prod->produce(unit, &out_items, &in_reag, &in_items, 1, job_skill::NONE, df::historical_entity::find(unit->civ_id), ((type == df::enums::game_type::DWARF_MAIN) || (type == df::enums::game_type::DWARF_RECLAIM)) ? df::world_site::find(df::global::ui->site_id) : NULL); if ( out_items.size() != 1 ) return -1; - + for (size_t a = 0; a < out_items.size(); a++ ) { out_items[a]->moveToGround(unit->pos.x, unit->pos.y, unit->pos.z); } - + return out_items[0]->id; } diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index 8a1a6a7e3..1114107ec 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -204,7 +204,7 @@ df::map_block *Maps::ensureTileBlock (int32_t x, int32_t y, int32_t z) slot->temperature_1[tx][ty] = column[z2]->temperature_1[tx][ty]; slot->temperature_2[tx][ty] = column[z2]->temperature_2[tx][ty]; } - + df::global::world->map.map_blocks.push_back(slot); return slot; } @@ -593,7 +593,7 @@ bool Maps::canStepBetween(df::coord pos1, df::coord pos2) if ( !index_tile(block1->walkable,pos1) || !index_tile(block2->walkable,pos2) ) { return false; } - + if ( block1->designation[pos1.x&0xF][pos1.y&0xF].bits.flow_size >= 4 || block2->designation[pos2.x&0xF][pos2.y&0xF].bits.flow_size >= 4 ) return false; @@ -640,7 +640,7 @@ bool Maps::canStepBetween(df::coord pos1, df::coord pos2) } if ( !foundWall ) return false; //unusable ramp - + //there has to be an unforbidden hatch above the ramp if ( index_tile(block2->occupancy,pos2).bits.building != tile_building_occ::Dynamic ) return false; @@ -657,7 +657,7 @@ bool Maps::canStepBetween(df::coord pos1, df::coord pos2) } return false; } - + //diagonal up: has to be a ramp if ( shape1 == tiletype_shape::RAMP /*&& shape2 == tiletype_shape::RAMP*/ ) { df::coord up = df::coord(pos1.x,pos1.y,pos1.z+1); @@ -681,11 +681,11 @@ bool Maps::canStepBetween(df::coord pos1, df::coord pos2) df::tiletype_shape shapeUp = ENUM_ATTR(tiletype,shape,*typeUp); if ( shapeUp != tiletype_shape::RAMP_TOP ) return false; - + df::map_block* blockUp = getTileBlock(up); if ( !blockUp ) return false; - + df::tile_building_occ occupancy = index_tile(blockUp->occupancy,up).bits.building; if ( occupancy == tile_building_occ::Obstacle || occupancy == tile_building_occ::Floored || occupancy == tile_building_occ::Impassable ) return false; diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index a040521bd..99c0ebca7 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -1616,12 +1616,12 @@ std::string Units::getCasteProfessionName(int race, int casteid, df::profession { std::string prof, race_prefix; - if (pid < (df::profession)0 || !is_valid_enum_item(pid)) - return ""; - int16_t current_race = df::global::ui->race_id; - if (df::global::gamemode && *df::global::gamemode == df::game_mode::ADVENTURE) - current_race = world->units.active[0]->race; - bool use_race_prefix = (race >= 0 && race != current_race); + if (pid < (df::profession)0 || !is_valid_enum_item(pid)) + return ""; + int16_t current_race = df::global::ui->race_id; + if (df::global::gamemode && *df::global::gamemode == df::game_mode::ADVENTURE) + current_race = world->units.active[0]->race; + bool use_race_prefix = (race >= 0 && race != current_race); if (auto creature = df::creature_raw::find(race)) { diff --git a/plugins/Dfusion/dfusion.cpp b/plugins/Dfusion/dfusion.cpp index 15bcfa7a8..a40c0379d 100644 --- a/plugins/Dfusion/dfusion.cpp +++ b/plugins/Dfusion/dfusion.cpp @@ -25,7 +25,7 @@ DFHACK_PLUGIN("dfusion") static int loadObjectFile(lua_State* L) { std::string path; - + path=luaL_checkstring(L,1); OutFile::File f(path); @@ -36,7 +36,7 @@ static int loadObjectFile(lua_State* L) lua_setfield(L,table_pos,"data_size"); char* buf=new char[size]; f.GetText(buf); - + //Lua::PushDFObject(L,DFHack::,buf); //Lua::Push(L,buf); lua_pushlightuserdata(L,buf); @@ -52,7 +52,7 @@ static int loadObjectFile(lua_State* L) Lua::Push(L,symbols[i].pos); lua_setfield(L,-2,"pos"); - + lua_settable(L,-3); } lua_setfield(L,table_pos,"symbols"); diff --git a/plugins/Dfusion/include/hexsearch.h b/plugins/Dfusion/include/hexsearch.h index 6cbc978ce..e4faf5862 100644 --- a/plugins/Dfusion/include/hexsearch.h +++ b/plugins/Dfusion/include/hexsearch.h @@ -9,29 +9,29 @@ class Hexsearch { public: - typedef std::vector SearchArgType; - enum SearchConst //TODO add more - { - ANYBYTE=0x101,DWORD_,ANYDWORD,ADDRESS - }; + typedef std::vector SearchArgType; + enum SearchConst //TODO add more + { + ANYBYTE=0x101,DWORD_,ANYDWORD,ADDRESS + }; - Hexsearch(const SearchArgType &args,char * startpos,char * endpos); - ~Hexsearch(); + Hexsearch(const SearchArgType &args,char * startpos,char * endpos); + ~Hexsearch(); - void Reset(){pos_=startpos_;}; - void SetStart(char * pos){pos_=pos;}; + void Reset(){pos_=startpos_;}; + void SetStart(char * pos){pos_=pos;}; + + void * FindNext(); + std::vector FindAll(); - void * FindNext(); - std::vector FindAll(); - private: - bool Compare(int a,int b); - void ReparseArgs(); - SearchArgType args_; - char * pos_,* startpos_,* endpos_; - std::vector BadCharShifts,GoodSuffixShift; - void PrepareGoodSuffixTable(); - void PrepareBadCharShift(); + bool Compare(int a,int b); + void ReparseArgs(); + SearchArgType args_; + char * pos_,* startpos_,* endpos_; + std::vector BadCharShifts,GoodSuffixShift; + void PrepareGoodSuffixTable(); + void PrepareBadCharShift(); }; #endif \ No newline at end of file diff --git a/plugins/Dfusion/include/lua_Hexsearch.h b/plugins/Dfusion/include/lua_Hexsearch.h index 2dfa78af8..bb9950a23 100644 --- a/plugins/Dfusion/include/lua_Hexsearch.h +++ b/plugins/Dfusion/include/lua_Hexsearch.h @@ -11,19 +11,19 @@ namespace lua class Hexsearch { - int tblid; - ::Hexsearch *p; + int tblid; + ::Hexsearch *p; public: - Hexsearch(lua_State *L,int id); - ~Hexsearch(); + Hexsearch(lua_State *L,int id); + ~Hexsearch(); - int GetTableId(){return tblid;}; + int GetTableId(){return tblid;}; - int find(lua_State *L); - int findall(lua_State *L); - int reset(lua_State *L); + int find(lua_State *L); + int findall(lua_State *L); + int reset(lua_State *L); - DEF_LUNE(Hexsearch); + DEF_LUNE(Hexsearch); }; void RegisterHexsearch(lua::state &st); diff --git a/plugins/Dfusion/include/lua_Misc.h b/plugins/Dfusion/include/lua_Misc.h index ff4611456..a0fd3475b 100644 --- a/plugins/Dfusion/include/lua_Misc.h +++ b/plugins/Dfusion/include/lua_Misc.h @@ -18,25 +18,25 @@ class PlugManager { public: - mapPlugs GetList(){return plugs;}; + mapPlugs GetList(){return plugs;}; uint32_t AddNewPlug(std::string name,uint32_t size,uint32_t loc=0); uint32_t FindPlugin(std::string name); static PlugManager &GetInst() - { - void *p; - p=DFHack::Core::getInstance().GetData("dfusion_manager"); - if(p==0) - { - p=new PlugManager; - DFHack::Core::getInstance().RegisterData(p,"dfusion_manager"); - } - return *static_cast(p); - }; + { + void *p; + p=DFHack::Core::getInstance().GetData("dfusion_manager"); + if(p==0) + { + p=new PlugManager; + DFHack::Core::getInstance().RegisterData(p,"dfusion_manager"); + } + return *static_cast(p); + }; protected: - private: - PlugManager(){}; - mapPlugs plugs; + private: + PlugManager(){}; + mapPlugs plugs; }; void RegisterMisc(lua::state &st); diff --git a/plugins/Dfusion/include/luamain.h b/plugins/Dfusion/include/luamain.h index 379407437..35349f622 100644 --- a/plugins/Dfusion/include/luamain.h +++ b/plugins/Dfusion/include/luamain.h @@ -16,7 +16,7 @@ using std::string; namespace lua { - //global lua state singleton + //global lua state singleton class glua { public: @@ -26,13 +26,13 @@ namespace lua static glua *ptr; state mystate; }; - //registers basic lua commands + //registers basic lua commands void RegBasics(lua::state &L); - //dumps lua function trace, useless unless called from lua. + //dumps lua function trace, useless unless called from lua. string DebugDump(lua::state &L); - //register functions, first registers into global scope, second into current table - void RegFunctions(lua::state &L,luaL_Reg const *arr); - void RegFunctionsLocal(lua::state &L,luaL_Reg const *arr); + //register functions, first registers into global scope, second into current table + void RegFunctions(lua::state &L,luaL_Reg const *arr); + void RegFunctionsLocal(lua::state &L,luaL_Reg const *arr); } diff --git a/plugins/Dfusion/src/OutFile.cpp b/plugins/Dfusion/src/OutFile.cpp index 5617175f8..44c473e33 100644 --- a/plugins/Dfusion/src/OutFile.cpp +++ b/plugins/Dfusion/src/OutFile.cpp @@ -5,7 +5,7 @@ File::File(std::string path) { //mystream.exceptions ( std::fstream::eofbit | std::fstream::failbit | std::fstream::badbit ); mystream.open(path.c_str(),std::fstream::binary|std::ios::in|std::ios::out); - + if(mystream) { diff --git a/plugins/Dfusion/src/hexsearch.cpp b/plugins/Dfusion/src/hexsearch.cpp index 30dcf26f8..08e38b414 100644 --- a/plugins/Dfusion/src/hexsearch.cpp +++ b/plugins/Dfusion/src/hexsearch.cpp @@ -3,7 +3,7 @@ Hexsearch::Hexsearch(const SearchArgType &args,char * startpos,char * endpos):args_(args),pos_(startpos),startpos_(startpos),endpos_(endpos) { - ReparseArgs(); + ReparseArgs(); } Hexsearch::~Hexsearch() { @@ -11,106 +11,106 @@ Hexsearch::~Hexsearch() } inline bool Hexsearch::Compare(int a,int b) { - if(b==Hexsearch::ANYBYTE) - return true; - if(a==b) - return true; - return false; + if(b==Hexsearch::ANYBYTE) + return true; + if(a==b) + return true; + return false; } void Hexsearch::ReparseArgs() { - union - { - uint32_t val; - uint8_t bytes[4]; - }B; - SearchArgType targ; - targ=args_; - args_.clear(); - for(size_t i=0;ireadByte(pos_,buf[0]); - if(Compare(buf[0],args_[0])) - { - p->read(pos_,args_.size(),buf); - for(size_t i=0;ireadByte(pos_,buf[0]); + if(Compare(buf[0],args_[0])) + { + p->read(pos_,args_.size(),buf); + for(size_t i=0;i Hexsearch::FindAll() { - std::vector ret; - void * cpos=pos_; - while(cpos!=0) - { - cpos=FindNext(); - if(cpos!=0) - ret.push_back(cpos); - } - return ret; + std::vector ret; + void * cpos=pos_; + while(cpos!=0) + { + cpos=FindNext(); + if(cpos!=0) + ret.push_back(cpos); + } + return ret; } void Hexsearch::PrepareBadCharShift() { - BadCharShifts.resize(256,-1); - int i=0; - for(SearchArgType::reverse_iterator it=args_.rbegin();it!=args_.rend();it++) - { - BadCharShifts[*it]=i; - i++; - } + BadCharShifts.resize(256,-1); + int i=0; + for(SearchArgType::reverse_iterator it=args_.rbegin();it!=args_.rend();it++) + { + BadCharShifts[*it]=i; + i++; + } } void Hexsearch::PrepareGoodSuffixTable() { - GoodSuffixShift.resize(args_.size()+1,0); + GoodSuffixShift.resize(args_.size()+1,0); } \ No newline at end of file diff --git a/plugins/Dfusion/src/lua_Hexsearch.cpp b/plugins/Dfusion/src/lua_Hexsearch.cpp index 84cf5527e..c50892f75 100644 --- a/plugins/Dfusion/src/lua_Hexsearch.cpp +++ b/plugins/Dfusion/src/lua_Hexsearch.cpp @@ -2,60 +2,60 @@ int lua::Hexsearch::find(lua_State *L) { lua::state st(L); - void * pos=p->FindNext(); - st.push(reinterpret_cast(pos)); - return 1; + void * pos=p->FindNext(); + st.push(reinterpret_cast(pos)); + return 1; } int lua::Hexsearch::findall(lua_State *L) { lua::state st(L); - std::vector pos=p->FindAll(); - st.newtable(); - for(unsigned i=0;i(pos[i])); - st.settable(); - } - return 1; + std::vector pos=p->FindAll(); + st.newtable(); + for(unsigned i=0;i(pos[i])); + st.settable(); + } + return 1; } lua::Hexsearch::Hexsearch(lua_State *L,int id):tblid(id) { lua::state st(L); - char * start,* end; - ::Hexsearch::SearchArgType args; - start= (char *)st.as(1); - end=(char *)st.as(2); - for(int i=3;i<=st.gettop();i++) - { - args.push_back(st.as(i)); - } - p=new ::Hexsearch(args,start,end); + char * start,* end; + ::Hexsearch::SearchArgType args; + start= (char *)st.as(1); + end=(char *)st.as(2); + for(int i=3;i<=st.gettop();i++) + { + args.push_back(st.as(i)); + } + p=new ::Hexsearch(args,start,end); } lua::Hexsearch::~Hexsearch() { - delete p; + delete p; } int lua::Hexsearch::reset(lua_State *L) { lua::state st(L); - p->Reset(); - return 0; + p->Reset(); + return 0; } IMP_LUNE(lua::Hexsearch,hexsearch); LUNE_METHODS_START(lua::Hexsearch) - method(lua::Hexsearch,find), - method(lua::Hexsearch,findall), - method(lua::Hexsearch,reset), + method(lua::Hexsearch,find), + method(lua::Hexsearch,findall), + method(lua::Hexsearch,reset), LUNE_METHODS_END(); #define __ADDCONST(name) st.push(::Hexsearch:: name); st.setglobal(#name) void lua::RegisterHexsearch(lua::state &st) { - Lune::Register(st); - __ADDCONST(ANYBYTE); - __ADDCONST(ANYDWORD); - __ADDCONST(DWORD_); + Lune::Register(st); + __ADDCONST(ANYBYTE); + __ADDCONST(ANYDWORD); + __ADDCONST(DWORD_); } #undef __ADDCONST diff --git a/plugins/Dfusion/src/lua_Misc.cpp b/plugins/Dfusion/src/lua_Misc.cpp index 6a06781fd..7faf1c45c 100644 --- a/plugins/Dfusion/src/lua_Misc.cpp +++ b/plugins/Dfusion/src/lua_Misc.cpp @@ -1,21 +1,21 @@ #include "lua_Misc.h" uint32_t lua::PlugManager::AddNewPlug(std::string name,uint32_t size,uint32_t loc) { - void *p; - if(size!=0) - p=new unsigned char[size]; - else - p=(void*)loc; - plugs[name]=p; - return (uint32_t)p; + void *p; + if(size!=0) + p=new unsigned char[size]; + else + p=(void*)loc; + plugs[name]=p; + return (uint32_t)p; } uint32_t lua::PlugManager::FindPlugin(std::string name) { - mapPlugs::iterator it=plugs.find(name); - if(it!=plugs.end()) - return (uint32_t)it->second; - else - return 0; + mapPlugs::iterator it=plugs.find(name); + if(it!=plugs.end()) + return (uint32_t)it->second; + else + return 0; } @@ -24,10 +24,10 @@ static int LoadMod(lua_State *L) lua::state st(L); std::string modfile=st.as(1); std::string modname=st.as(2); - uint32_t size_add=st.as(0,3); + uint32_t size_add=st.as(0,3); OutFile::File f(modfile); uint32_t size=f.GetTextSize(); - uint32_t pos=lua::PlugManager::GetInst().AddNewPlug(modname,size+size_add); + uint32_t pos=lua::PlugManager::GetInst().AddNewPlug(modname,size+size_add); char *buf; buf=new char[size]; f.GetText(buf); @@ -133,22 +133,22 @@ static int GetMod(lua_State *L) const luaL_Reg lua_misc_func[]= { - {"loadmod",LoadMod}, - {"getmod",GetMod}, - {"loadobj",LoadObj}, - {"loadobjsymbols",LoadObjSymbols}, - {"findmarker",FindMarker}, - {"newmod",NewMod}, - {NULL,NULL} + {"loadmod",LoadMod}, + {"getmod",GetMod}, + {"loadobj",LoadObj}, + {"loadobjsymbols",LoadObjSymbols}, + {"findmarker",FindMarker}, + {"newmod",NewMod}, + {NULL,NULL} }; void lua::RegisterMisc(lua::state &st) { - st.getglobal("engine"); - if(st.is()) - { - st.pop(); - st.newtable(); - } - lua::RegFunctionsLocal(st, lua_misc_func); - st.setglobal("engine"); + st.getglobal("engine"); + if(st.is()) + { + st.pop(); + st.newtable(); + } + lua::RegFunctionsLocal(st, lua_misc_func); + st.setglobal("engine"); } diff --git a/plugins/Dfusion/src/lua_Process.cpp b/plugins/Dfusion/src/lua_Process.cpp index 5d36c6246..cd02ababc 100644 --- a/plugins/Dfusion/src/lua_Process.cpp +++ b/plugins/Dfusion/src/lua_Process.cpp @@ -2,268 +2,268 @@ static DFHack::Process* GetProcessPtr(lua::state &st) { - return DFHack::Core::getInstance().p; + return DFHack::Core::getInstance().p; } static int lua_Process_readDWord(lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); - uint32_t ret=c->readDWord( (void *) st.as(1)); - st.push(ret); - return 1; + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); + uint32_t ret=c->readDWord( (void *) st.as(1)); + st.push(ret); + return 1; } static int lua_Process_writeDWord(lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); c->writeDWord((void *) st.as(1),st.as(2)); - return 0; + return 0; } static int lua_Process_readFloat(lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); float ret=c->readFloat((void *) st.as(1)); - st.push(ret); - return 1; + st.push(ret); + return 1; } static int lua_Process_readWord(lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); uint16_t ret=c->readWord((void *) st.as(1)); - st.push(ret); - return 1; + st.push(ret); + return 1; } static int lua_Process_writeWord(lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); c->writeWord((void *) st.as(1),st.as(2)); - return 0; + return 0; } static int lua_Process_readByte(lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); uint8_t ret=c->readByte((void *) st.as(1)); - st.push(ret); - return 1; + st.push(ret); + return 1; } static int lua_Process_writeByte(lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); c->writeByte((void *) st.as(1),st.as(2)); - return 0; + return 0; } static int lua_Process_read(lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); - size_t len=st.as(2); - uint8_t* buf; - - if(!st.is(3)) - buf=(uint8_t*)lua_touserdata(st,3); - else - buf=new uint8_t[len]; + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); + size_t len=st.as(2); + uint8_t* buf; + + if(!st.is(3)) + buf=(uint8_t*)lua_touserdata(st,3); + else + buf=new uint8_t[len]; c->read((void *) st.as(1),len,buf); - st.pushlightuserdata(buf); - return 1; + st.pushlightuserdata(buf); + return 1; } static int lua_Process_write(lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); c-> write((void *) st.as(1),st.as(2),static_cast(lua_touserdata(st,3))); - return 0; + return 0; } static int lua_Process_readSTLString (lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); std::string r=c->readSTLString((void *) st.as(1)); - st.push(r); - return 1; + st.push(r); + return 1; } static int lua_Process_writeSTLString(lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); c->writeSTLString((void *) st.as(1),st.as(2)); - return 0; + return 0; } static int lua_Process_copySTLString(lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); c->copySTLString((void *) st.as(1),st.as(2)); - return 0; + return 0; } static int lua_Process_doReadClassName(lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); - std::string r=c->doReadClassName((void*)st.as(1)); - st.push(r); - return 1; + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); + std::string r=c->doReadClassName((void*)st.as(1)); + st.push(r); + return 1; } static int lua_Process_readClassName(lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); - std::string r=c->readClassName((void*)st.as(1)); - st.push(r); - return 1; + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); + std::string r=c->readClassName((void*)st.as(1)); + st.push(r); + return 1; } static int lua_Process_readCString (lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); std::string r=c->readCString((void *) st.as(1)); - st.push(r); - return 1; + st.push(r); + return 1; } static int lua_Process_isSuspended(lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); - st.push(c->isSuspended()); - return 1; + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); + st.push(c->isSuspended()); + return 1; } static int lua_Process_isIdentified(lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); - st.push(c->isIdentified()); - return 1; + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); + st.push(c->isIdentified()); + return 1; } static int lua_Process_getMemRanges(lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); - std::vector ranges; - c->getMemRanges(ranges); - st.newtable(); - for(size_t i=0;i ranges; + c->getMemRanges(ranges); + st.newtable(); + for(size_t i=0;igetBase(); - st.push(base); - return 1; + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); + uint32_t base=c->getBase(); + st.push(base); + return 1; } /*static int lua_Process_getPID(lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); - int ret=c->getPID(); - st.push(ret); - return 1; + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); + int ret=c->getPID(); + st.push(ret); + return 1; }*/ static int lua_Process_getPath(lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); - std::string ret=c->getPath(); - st.push(ret); - return 1; + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); + std::string ret=c->getPath(); + st.push(ret); + return 1; } static int lua_Process_setPermisions(lua_State *S) { - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); - DFHack::t_memrange range,trange; + lua::state st(S); + DFHack::Process* c=GetProcessPtr(st); + DFHack::t_memrange range,trange; - st.getfield("start",1); - range.start= (void *)st.as(); - st.pop(); - st.getfield("end",1); - range.end= (void *)st.as(); - st.pop(); + st.getfield("start",1); + range.start= (void *)st.as(); + st.pop(); + st.getfield("end",1); + range.end= (void *)st.as(); + st.pop(); - st.getfield("read",2); - trange.read=st.as(); - st.pop(); - st.getfield("write",2); - trange.write=st.as(); - st.pop(); - st.getfield("execute",2); - trange.execute=st.as(); - st.pop(); + st.getfield("read",2); + trange.read=st.as(); + st.pop(); + st.getfield("write",2); + trange.write=st.as(); + st.pop(); + st.getfield("execute",2); + trange.execute=st.as(); + st.pop(); - c->setPermisions(range,trange); + c->setPermisions(range,trange); - return 0; + return 0; } #define PROC_FUNC(name) {#name,lua_Process_ ## name} const luaL_Reg lua_process_func[]= { - PROC_FUNC(readDWord), - PROC_FUNC(writeDWord), - PROC_FUNC(readFloat), - PROC_FUNC(readWord), - PROC_FUNC(writeWord), - PROC_FUNC(readByte), - PROC_FUNC(writeByte), - PROC_FUNC(read), - PROC_FUNC(write), - PROC_FUNC(readSTLString), - PROC_FUNC(writeSTLString), - PROC_FUNC(copySTLString), - PROC_FUNC(doReadClassName), - PROC_FUNC(readClassName), - PROC_FUNC(readCString ), - PROC_FUNC(isSuspended), - PROC_FUNC(isIdentified), - PROC_FUNC(getMemRanges), - PROC_FUNC(getBase), - //PROC_FUNC(getPID), //not implemented - PROC_FUNC(getPath), - PROC_FUNC(setPermisions), - {NULL,NULL} + PROC_FUNC(readDWord), + PROC_FUNC(writeDWord), + PROC_FUNC(readFloat), + PROC_FUNC(readWord), + PROC_FUNC(writeWord), + PROC_FUNC(readByte), + PROC_FUNC(writeByte), + PROC_FUNC(read), + PROC_FUNC(write), + PROC_FUNC(readSTLString), + PROC_FUNC(writeSTLString), + PROC_FUNC(copySTLString), + PROC_FUNC(doReadClassName), + PROC_FUNC(readClassName), + PROC_FUNC(readCString ), + PROC_FUNC(isSuspended), + PROC_FUNC(isIdentified), + PROC_FUNC(getMemRanges), + PROC_FUNC(getBase), + //PROC_FUNC(getPID), //not implemented + PROC_FUNC(getPath), + PROC_FUNC(setPermisions), + {NULL,NULL} }; #undef PROC_FUNC void lua::RegisterProcess(lua::state &st) { - st.getglobal("Process"); - if(st.is()) - { - st.pop(); - st.newtable(); - } + st.getglobal("Process"); + if(st.is()) + { + st.pop(); + st.newtable(); + } - lua::RegFunctionsLocal(st, lua_process_func); + lua::RegFunctionsLocal(st, lua_process_func); - st.setglobal("Process"); + st.setglobal("Process"); } diff --git a/plugins/autochop.cpp b/plugins/autochop.cpp index ee5f6c492..3009877f1 100644 --- a/plugins/autochop.cpp +++ b/plugins/autochop.cpp @@ -1,4 +1,4 @@ -// automatically chop trees +// automatically chop trees #include "uicommon.h" @@ -549,7 +549,7 @@ public: } std::string getFocusString() { return "autochop"; } - + void updateAutochopBurrows() { watchedBurrows.clear(); @@ -586,7 +586,7 @@ struct autochop_hook : public df::viewscreen_dwarfmodest using namespace df::enums::ui_sidebar_mode; return (ui->main.mode == DesignateChopTrees); } - + void sendKey(const df::interface_key &key) { set tmp; diff --git a/plugins/autodump.cpp b/plugins/autodump.cpp index efb58a10c..944288001 100644 --- a/plugins/autodump.cpp +++ b/plugins/autodump.cpp @@ -220,7 +220,7 @@ struct dump_hook : public df::viewscreen_dwarfmodest links += sp->links.give_to_workshop.size(); links += sp->links.take_from_workshop.size(); bool state = monitor.isMonitored(sp); - + if (links + 12 >= y) { y = dims.y2; OutputString(COLOR_WHITE, x, y, "Auto: "); diff --git a/plugins/automaterial.cpp b/plugins/automaterial.cpp index b49b04ee8..56b94483b 100644 --- a/plugins/automaterial.cpp +++ b/plugins/automaterial.cpp @@ -59,8 +59,8 @@ struct MaterialDescriptor bool matches(const MaterialDescriptor &a) const { - return a.valid && valid && - a.type == type && + return a.valid && valid && + a.type == type && a.index == index && a.item_type == item_type && a.item_subtype == item_subtype; @@ -141,15 +141,15 @@ static bool allow_future_placement = false; static inline bool in_material_choice_stage() { - return Gui::build_selector_hotkey(Core::getTopViewscreen()) && + return Gui::build_selector_hotkey(Core::getTopViewscreen()) && ui_build_selector->building_type == df::building_type::Construction && - ui->main.mode == ui_sidebar_mode::Build && + ui->main.mode == ui_sidebar_mode::Build && ui_build_selector->stage == 2; } static inline bool in_placement_stage() { - return Gui::dwarfmode_hotkey(Core::getTopViewscreen()) && + return Gui::dwarfmode_hotkey(Core::getTopViewscreen()) && ui->main.mode == ui_sidebar_mode::Build && ui_build_selector && ui_build_selector->building_type == df::building_type::Construction && @@ -158,7 +158,7 @@ static inline bool in_placement_stage() static inline bool in_type_choice_stage() { - return Gui::dwarfmode_hotkey(Core::getTopViewscreen()) && + return Gui::dwarfmode_hotkey(Core::getTopViewscreen()) && ui->main.mode == ui_sidebar_mode::Build && ui_build_selector && ui_build_selector->building_type < 0; @@ -269,7 +269,7 @@ static bool check_autoselect(MaterialDescriptor &material, bool toggle) size_t idx; if (is_material_in_autoselect(idx, material)) { - if (toggle) + if (toggle) vector_erase_at(get_curr_constr_prefs(), idx); return true; @@ -440,7 +440,7 @@ static bool is_valid_building_site(building_site &site, bool orthogonal_check, b } else if (orthogonal_check) { - if (shape != tiletype_shape::RAMP && + if (shape != tiletype_shape::RAMP && shape_basic != tiletype_shape_basic::Floor && shape_basic != tiletype_shape_basic::Stair) return false; @@ -945,7 +945,7 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest { // First valid site is guaranteed to be anchored, either on a tile or against a valid orthogonal tile // Use it as an anchor point to generate materials list - anchor = valid_building_sites.front(); + anchor = valid_building_sites.front(); valid_building_sites.pop_front(); valid_building_sites.push_back(anchor); } @@ -1057,8 +1057,8 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest int16_t last_used_constr_subtype = (in_material_choice_stage()) ? ui_build_selector->building_subtype : -1; INTERPOSE_NEXT(feed)(input); - if (revert_to_last_used_type && - last_used_constr_subtype >= 0 && + if (revert_to_last_used_type && + last_used_constr_subtype >= 0 && in_type_choice_stage() && hotkeys.find(last_used_constr_subtype) != hotkeys.end()) { diff --git a/plugins/automelt.cpp b/plugins/automelt.cpp index ccbf3489c..620ed622e 100644 --- a/plugins/automelt.cpp +++ b/plugins/automelt.cpp @@ -226,7 +226,7 @@ struct melt_hook : public df::viewscreen_dwarfmodest int left_margin = dims.menu_x1 + 1; int x = left_margin; int y = dims.y2 - 6; - + int links = 0; links += sp->links.give_to_pile.size(); links += sp->links.take_from_pile.size(); diff --git a/plugins/autotrade.cpp b/plugins/autotrade.cpp index e238cc514..aa7a35494 100644 --- a/plugins/autotrade.cpp +++ b/plugins/autotrade.cpp @@ -142,7 +142,7 @@ static bool check_mandates(df::item *item) if (mandate->mode != 0) continue; - if (item->getType() != mandate->item_type || + if (item->getType() != mandate->item_type || (mandate->item_subtype != -1 && item->getSubtype() != mandate->item_subtype)) continue; @@ -421,14 +421,14 @@ struct trade_hook : public df::viewscreen_dwarfmodest int left_margin = dims.menu_x1 + 1; int x = left_margin; int y = dims.y2 - 5; - + int links = 0; links += sp->links.give_to_pile.size(); links += sp->links.take_from_pile.size(); links += sp->links.give_to_workshop.size(); links += sp->links.take_from_workshop.size(); bool state = monitor.isMonitored(sp); - + if (links + 12 >= y) { y = dims.y2; OutputString(COLOR_WHITE, x, y, "Auto: "); diff --git a/plugins/blueprint.cpp b/plugins/blueprint.cpp index e32d4a20a..b9047a14e 100644 --- a/plugins/blueprint.cpp +++ b/plugins/blueprint.cpp @@ -72,12 +72,12 @@ pair get_building_size(df::building* b) char get_tile_dig(MapExtras::MapCache mc, int32_t x, int32_t y, int32_t z) { - df::tiletype tt = mc.tiletypeAt(DFCoord(x, y, z)); + df::tiletype tt = mc.tiletypeAt(DFCoord(x, y, z)); df::tiletype_shape ts = tileShape(tt); switch (ts) { case tiletype_shape::EMPTY: - case tiletype_shape::RAMP_TOP: + case tiletype_shape::RAMP_TOP: return 'h'; case tiletype_shape::FLOOR: case tiletype_shape::BOULDER: @@ -102,7 +102,7 @@ char get_tile_dig(MapExtras::MapCache mc, int32_t x, int32_t y, int32_t z) string get_tile_build(uint32_t x, uint32_t y, df::building* b) { - if (! b) + if (! b) return " "; bool at_nw_corner = x == b->x1 && y == b->y1; bool at_se_corner = x == b->x2 && y == b->y2; @@ -366,7 +366,7 @@ string get_tile_build(uint32_t x, uint32_t y, df::building* b) out << "CS"; if (ts->use_dump) { - if (ts->dump_x_shift == 0) + if (ts->dump_x_shift == 0) { if (ts->dump_y_shift > 0) out << "dd"; @@ -429,7 +429,7 @@ string get_tile_build(uint32_t x, uint32_t y, df::building* b) case building_type::AxleVertical: return "Mv"; case building_type::Rollers: - if (! at_nw_corner) + if (! at_nw_corner) return "`"; out << "Mr"; switch (((df::building_rollersst*) b)->direction) @@ -440,7 +440,7 @@ string get_tile_build(uint32_t x, uint32_t y, df::building* b) out << "s"; case screw_pump_direction::FromSouth: out << "s"; - case screw_pump_direction::FromWest: + case screw_pump_direction::FromWest: out << "s"; } out << "(" << size.first << "x" << size.second << ")"; @@ -533,7 +533,7 @@ string get_tile_place(uint32_t x, uint32_t y, df::building* b) out << "p"; break; case df::stockpile_group_set::mask_armor: - out << "d"; + out << "d"; break; default: //multiple stockpile type return "`"; diff --git a/plugins/building-hacks.cpp b/plugins/building-hacks.cpp index 152e4568b..62349e519 100644 --- a/plugins/building-hacks.cpp +++ b/plugins/building-hacks.cpp @@ -332,7 +332,7 @@ static int addBuilding(lua_State* L) newDefinition.connections.can_connect.push_back(-1);//TODO add this too... newDefinition.connections.tiles.push_back(df::coord(x,y,0)); - + lua_pop(L,1); } lua_pop(L,1); diff --git a/plugins/buildingplan-lib.cpp b/plugins/buildingplan-lib.cpp index 58c4b8aca..a25ee7b93 100644 --- a/plugins/buildingplan-lib.cpp +++ b/plugins/buildingplan-lib.cpp @@ -20,641 +20,641 @@ static std::string material_to_string_fn(DFHack::MaterialInfo m) { return m.toSt bool ItemFilter::matchesMask(DFHack::MaterialInfo &mat) { - return (mat_mask.whole) ? mat.matches(mat_mask) : true; + return (mat_mask.whole) ? mat.matches(mat_mask) : true; } bool ItemFilter::matches(const df::dfhack_material_category mask) const { - return mask.whole & mat_mask.whole; + return mask.whole & mat_mask.whole; } bool ItemFilter::matches(DFHack::MaterialInfo &material) const { - for (auto it = materials.begin(); it != materials.end(); ++it) - if (material.matches(*it)) - return true; - return false; + for (auto it = materials.begin(); it != materials.end(); ++it) + if (material.matches(*it)) + return true; + return false; } bool ItemFilter::matches(df::item *item) { - if (item->getQuality() < min_quality) - return false; + if (item->getQuality() < min_quality) + return false; - if (decorated_only && !item->hasImprovements()) - return false; + if (decorated_only && !item->hasImprovements()) + return false; - auto imattype = item->getActualMaterial(); - auto imatindex = item->getActualMaterialIndex(); - auto item_mat = DFHack::MaterialInfo(imattype, imatindex); + auto imattype = item->getActualMaterial(); + auto imatindex = item->getActualMaterialIndex(); + auto item_mat = DFHack::MaterialInfo(imattype, imatindex); - return (materials.size() == 0) ? matchesMask(item_mat) : matches(item_mat); + return (materials.size() == 0) ? matchesMask(item_mat) : matches(item_mat); } std::vector ItemFilter::getMaterialFilterAsVector() { - std::vector descriptions; + std::vector descriptions; - transform_(materials, descriptions, material_to_string_fn); + transform_(materials, descriptions, material_to_string_fn); - if (descriptions.size() == 0) - bitfield_to_string(&descriptions, mat_mask); + if (descriptions.size() == 0) + bitfield_to_string(&descriptions, mat_mask); - if (descriptions.size() == 0) - descriptions.push_back("any"); + if (descriptions.size() == 0) + descriptions.push_back("any"); - return descriptions; + return descriptions; } std::string ItemFilter::getMaterialFilterAsSerial() { - std::string str; + std::string str; - str.append(bitfield_to_string(mat_mask, ",")); - str.append("/"); - if (materials.size() > 0) - { - for (size_t i = 0; i < materials.size(); i++) - str.append(materials[i].getToken() + ","); + str.append(bitfield_to_string(mat_mask, ",")); + str.append("/"); + if (materials.size() > 0) + { + for (size_t i = 0; i < materials.size(); i++) + str.append(materials[i].getToken() + ","); - if (str[str.size()-1] == ',') - str.resize(str.size () - 1); - } + if (str[str.size()-1] == ',') + str.resize(str.size () - 1); + } - return str; + return str; } bool ItemFilter::parseSerializedMaterialTokens(std::string str) { - valid = false; - std::vector tokens; - split_string(&tokens, str, "/"); - - if (tokens.size() > 0 && !tokens[0].empty()) - { - if (!parseJobMaterialCategory(&mat_mask, tokens[0])) - return false; - } - - if (tokens.size() > 1 && !tokens[1].empty()) - { - std::vector mat_names; - split_string(&mat_names, tokens[1], ","); - for (auto m = mat_names.begin(); m != mat_names.end(); m++) - { - DFHack::MaterialInfo material; - if (!material.find(*m) || !material.isValid()) - return false; - - materials.push_back(material); - } - } - - valid = true; - return true; + valid = false; + std::vector tokens; + split_string(&tokens, str, "/"); + + if (tokens.size() > 0 && !tokens[0].empty()) + { + if (!parseJobMaterialCategory(&mat_mask, tokens[0])) + return false; + } + + if (tokens.size() > 1 && !tokens[1].empty()) + { + std::vector mat_names; + split_string(&mat_names, tokens[1], ","); + for (auto m = mat_names.begin(); m != mat_names.end(); m++) + { + DFHack::MaterialInfo material; + if (!material.find(*m) || !material.isValid()) + return false; + + materials.push_back(material); + } + } + + valid = true; + return true; } std::string ItemFilter::getMinQuality() { - return ENUM_KEY_STR(item_quality, min_quality); + return ENUM_KEY_STR(item_quality, min_quality); } bool ItemFilter::isValid() { - return valid; + return valid; } void ItemFilter::clear() { - mat_mask.whole = 0; - materials.clear(); + mat_mask.whole = 0; + materials.clear(); } static DFHack::MaterialInfo &material_info_identity_fn(DFHack::MaterialInfo &m) { return m; } ViewscreenChooseMaterial::ViewscreenChooseMaterial(ItemFilter *filter) { - selected_column = 0; - masks_column.setTitle("Type"); - masks_column.multiselect = true; - masks_column.allow_search = false; - masks_column.left_margin = 2; - materials_column.left_margin = MAX_MASK + 3; - materials_column.setTitle("Material"); - materials_column.multiselect = true; - this->filter = filter; + selected_column = 0; + masks_column.setTitle("Type"); + masks_column.multiselect = true; + masks_column.allow_search = false; + masks_column.left_margin = 2; + materials_column.left_margin = MAX_MASK + 3; + materials_column.setTitle("Material"); + materials_column.multiselect = true; + this->filter = filter; - masks_column.changeHighlight(0); + masks_column.changeHighlight(0); - populateMasks(); - populateMaterials(); + populateMasks(); + populateMaterials(); - masks_column.selectDefaultEntry(); - materials_column.selectDefaultEntry(); - materials_column.changeHighlight(0); + masks_column.selectDefaultEntry(); + materials_column.selectDefaultEntry(); + materials_column.changeHighlight(0); } void ViewscreenChooseMaterial::feed(set *input) { - bool key_processed = false; - switch (selected_column) - { - case 0: - key_processed = masks_column.feed(input); - if (input->count(interface_key::SELECT)) - populateMaterials(); // Redo materials lists based on category selection - break; - case 1: - key_processed = materials_column.feed(input); - break; - } - - if (key_processed) - return; - - if (input->count(interface_key::LEAVESCREEN)) - { - input->clear(); - Screen::dismiss(this); - return; - } - if (input->count(interface_key::CUSTOM_SHIFT_C)) - { - filter->clear(); - masks_column.clearSelection(); - materials_column.clearSelection(); - populateMaterials(); - } - else if (input->count(interface_key::SEC_SELECT)) - { - // Convert list selections to material filters - - - filter->mat_mask.whole = 0; - filter->materials.clear(); - - // Category masks - auto masks = masks_column.getSelectedElems(); - for (auto it = masks.begin(); it != masks.end(); ++it) - filter->mat_mask.whole |= it->whole; - - // Specific materials - auto materials = materials_column.getSelectedElems(); - transform_(materials, filter->materials, material_info_identity_fn); - - Screen::dismiss(this); - } - else if (input->count(interface_key::CURSOR_LEFT)) - { - --selected_column; - validateColumn(); - } - else if (input->count(interface_key::CURSOR_RIGHT)) - { - selected_column++; - validateColumn(); - } - else if (enabler->tracking_on && enabler->mouse_lbut) - { - if (masks_column.setHighlightByMouse()) - selected_column = 0; - else if (materials_column.setHighlightByMouse()) - selected_column = 1; - - enabler->mouse_lbut = enabler->mouse_rbut = 0; - } + bool key_processed = false; + switch (selected_column) + { + case 0: + key_processed = masks_column.feed(input); + if (input->count(interface_key::SELECT)) + populateMaterials(); // Redo materials lists based on category selection + break; + case 1: + key_processed = materials_column.feed(input); + break; + } + + if (key_processed) + return; + + if (input->count(interface_key::LEAVESCREEN)) + { + input->clear(); + Screen::dismiss(this); + return; + } + if (input->count(interface_key::CUSTOM_SHIFT_C)) + { + filter->clear(); + masks_column.clearSelection(); + materials_column.clearSelection(); + populateMaterials(); + } + else if (input->count(interface_key::SEC_SELECT)) + { + // Convert list selections to material filters + + + filter->mat_mask.whole = 0; + filter->materials.clear(); + + // Category masks + auto masks = masks_column.getSelectedElems(); + for (auto it = masks.begin(); it != masks.end(); ++it) + filter->mat_mask.whole |= it->whole; + + // Specific materials + auto materials = materials_column.getSelectedElems(); + transform_(materials, filter->materials, material_info_identity_fn); + + Screen::dismiss(this); + } + else if (input->count(interface_key::CURSOR_LEFT)) + { + --selected_column; + validateColumn(); + } + else if (input->count(interface_key::CURSOR_RIGHT)) + { + selected_column++; + validateColumn(); + } + else if (enabler->tracking_on && enabler->mouse_lbut) + { + if (masks_column.setHighlightByMouse()) + selected_column = 0; + else if (materials_column.setHighlightByMouse()) + selected_column = 1; + + enabler->mouse_lbut = enabler->mouse_rbut = 0; + } } void ViewscreenChooseMaterial::render() { - if (Screen::isDismissed(this)) - return; + if (Screen::isDismissed(this)) + return; - dfhack_viewscreen::render(); + dfhack_viewscreen::render(); - Screen::clear(); - Screen::drawBorder(" Building Material "); + Screen::clear(); + Screen::drawBorder(" Building Material "); - masks_column.display(selected_column == 0); - materials_column.display(selected_column == 1); + masks_column.display(selected_column == 0); + materials_column.display(selected_column == 1); - int32_t y = gps->dimy - 3; - int32_t x = 2; - OutputHotkeyString(x, y, "Toggle", "Enter"); - x += 3; - OutputHotkeyString(x, y, "Save", "Shift-Enter"); - x += 3; - OutputHotkeyString(x, y, "Clear", "C"); - x += 3; - OutputHotkeyString(x, y, "Cancel", "Esc"); + int32_t y = gps->dimy - 3; + int32_t x = 2; + OutputHotkeyString(x, y, "Toggle", "Enter"); + x += 3; + OutputHotkeyString(x, y, "Save", "Shift-Enter"); + x += 3; + OutputHotkeyString(x, y, "Clear", "C"); + x += 3; + OutputHotkeyString(x, y, "Cancel", "Esc"); } // START Room Reservation ReservedRoom::ReservedRoom(df::building *building, std::string noble_code) { - this->building = building; - config = DFHack::World::AddPersistentData("buildingplan/reservedroom"); - config.val() = noble_code; - config.ival(1) = building->id; - pos = df::coord(building->centerx, building->centery, building->z); + this->building = building; + config = DFHack::World::AddPersistentData("buildingplan/reservedroom"); + config.val() = noble_code; + config.ival(1) = building->id; + pos = df::coord(building->centerx, building->centery, building->z); } ReservedRoom::ReservedRoom(PersistentDataItem &config, color_ostream &out) { - this->config = config; + this->config = config; - building = df::building::find(config.ival(1)); - if (!building) - return; - pos = df::coord(building->centerx, building->centery, building->z); + building = df::building::find(config.ival(1)); + if (!building) + return; + pos = df::coord(building->centerx, building->centery, building->z); } bool ReservedRoom::checkRoomAssignment() { - if (!isValid()) - return false; - - auto np = getOwnersNobleCode(); - bool correctOwner = false; - for (auto iter = np.begin(); iter != np.end(); iter++) - { - if (iter->position->code == getCode()) - { - correctOwner = true; - break; - } - } - - if (correctOwner) - return true; - - for (auto iter = world->units.active.begin(); iter != world->units.active.end(); iter++) - { - df::unit* unit = *iter; - if (!Units::isCitizen(unit)) - continue; - - if (DFHack::Units::isDead(unit)) - continue; - - np = getUniqueNoblePositions(unit); - for (auto iter = np.begin(); iter != np.end(); iter++) - { - if (iter->position->code == getCode()) - { - Buildings::setOwner(building, unit); - break; - } - } - } - - return true; + if (!isValid()) + return false; + + auto np = getOwnersNobleCode(); + bool correctOwner = false; + for (auto iter = np.begin(); iter != np.end(); iter++) + { + if (iter->position->code == getCode()) + { + correctOwner = true; + break; + } + } + + if (correctOwner) + return true; + + for (auto iter = world->units.active.begin(); iter != world->units.active.end(); iter++) + { + df::unit* unit = *iter; + if (!Units::isCitizen(unit)) + continue; + + if (DFHack::Units::isDead(unit)) + continue; + + np = getUniqueNoblePositions(unit); + for (auto iter = np.begin(); iter != np.end(); iter++) + { + if (iter->position->code == getCode()) + { + Buildings::setOwner(building, unit); + break; + } + } + } + + return true; } std::string RoomMonitor::getReservedNobleCode(int32_t buildingId) { - for (auto iter = reservedRooms.begin(); iter != reservedRooms.end(); iter++) - { - if (buildingId == iter->getId()) - return iter->getCode(); - } + for (auto iter = reservedRooms.begin(); iter != reservedRooms.end(); iter++) + { + if (buildingId == iter->getId()) + return iter->getCode(); + } - return ""; + return ""; } void RoomMonitor::toggleRoomForPosition(int32_t buildingId, std::string noble_code) { - bool found = false; - for (auto iter = reservedRooms.begin(); iter != reservedRooms.end(); iter++) - { - if (buildingId != iter->getId()) - { - continue; - } - else - { - if (noble_code == iter->getCode()) - { - iter->remove(); - reservedRooms.erase(iter); - } - else - { - iter->setCode(noble_code); - } - found = true; - break; - } - } - - if (!found) - { - ReservedRoom room(df::building::find(buildingId), noble_code); - reservedRooms.push_back(room); - } + bool found = false; + for (auto iter = reservedRooms.begin(); iter != reservedRooms.end(); iter++) + { + if (buildingId != iter->getId()) + { + continue; + } + else + { + if (noble_code == iter->getCode()) + { + iter->remove(); + reservedRooms.erase(iter); + } + else + { + iter->setCode(noble_code); + } + found = true; + break; + } + } + + if (!found) + { + ReservedRoom room(df::building::find(buildingId), noble_code); + reservedRooms.push_back(room); + } } void RoomMonitor::doCycle() { - for (auto iter = reservedRooms.begin(); iter != reservedRooms.end();) - { - if (iter->checkRoomAssignment()) - { - ++iter; - } - else - { - iter->remove(); - iter = reservedRooms.erase(iter); - } - } + for (auto iter = reservedRooms.begin(); iter != reservedRooms.end();) + { + if (iter->checkRoomAssignment()) + { + ++iter; + } + else + { + iter->remove(); + iter = reservedRooms.erase(iter); + } + } } void RoomMonitor::reset(color_ostream &out) { - reservedRooms.clear(); - std::vector items; - DFHack::World::GetPersistentData(&items, "buildingplan/reservedroom"); + reservedRooms.clear(); + std::vector items; + DFHack::World::GetPersistentData(&items, "buildingplan/reservedroom"); - for (auto i = items.begin(); i != items.end(); i++) - { - ReservedRoom rr(*i, out); - if (rr.isValid()) - addRoom(rr); - } + for (auto i = items.begin(); i != items.end(); i++) + { + ReservedRoom rr(*i, out); + if (rr.isValid()) + addRoom(rr); + } } static void delete_item_fn(df::job_item *x) { delete x; } -// START Planning +// START Planning PlannedBuilding::PlannedBuilding(df::building *building, ItemFilter *filter) { - this->building = building; - this->filter = *filter; - pos = df::coord(building->centerx, building->centery, building->z); - config = DFHack::World::AddPersistentData("buildingplan/constraints"); - config.val() = filter->getMaterialFilterAsSerial(); - config.ival(1) = building->id; - config.ival(2) = filter->min_quality + 1; - config.ival(3) = static_cast(filter->decorated_only) + 1; + this->building = building; + this->filter = *filter; + pos = df::coord(building->centerx, building->centery, building->z); + config = DFHack::World::AddPersistentData("buildingplan/constraints"); + config.val() = filter->getMaterialFilterAsSerial(); + config.ival(1) = building->id; + config.ival(2) = filter->min_quality + 1; + config.ival(3) = static_cast(filter->decorated_only) + 1; } PlannedBuilding::PlannedBuilding(PersistentDataItem &config, color_ostream &out) { - this->config = config; + this->config = config; - if (!filter.parseSerializedMaterialTokens(config.val())) - { - out.printerr("Buildingplan: Cannot parse filter: %s\nDiscarding.", config.val().c_str()); - return; - } + if (!filter.parseSerializedMaterialTokens(config.val())) + { + out.printerr("Buildingplan: Cannot parse filter: %s\nDiscarding.", config.val().c_str()); + return; + } - building = df::building::find(config.ival(1)); - if (!building) - return; + building = df::building::find(config.ival(1)); + if (!building) + return; - pos = df::coord(building->centerx, building->centery, building->z); - filter.min_quality = static_cast(config.ival(2) - 1); - filter.decorated_only = config.ival(3) - 1; + pos = df::coord(building->centerx, building->centery, building->z); + filter.min_quality = static_cast(config.ival(2) - 1); + filter.decorated_only = config.ival(3) - 1; } bool PlannedBuilding::assignClosestItem(std::vector *items_vector) { - decltype(items_vector->begin()) closest_item; - int32_t closest_distance = -1; - for (auto item_iter = items_vector->begin(); item_iter != items_vector->end(); item_iter++) - { - auto item = *item_iter; - if (!filter.matches(item)) - continue; - - auto pos = item->pos; - auto distance = abs(pos.x - building->centerx) + - abs(pos.y - building->centery) + - abs(pos.z - building->z) * 50; - - if (closest_distance > -1 && distance >= closest_distance) - continue; - - closest_distance = distance; - closest_item = item_iter; - } - - if (closest_distance > -1 && assignItem(*closest_item)) - { - debug("Item assigned"); - items_vector->erase(closest_item); - remove(); - return true; - } - - return false; + decltype(items_vector->begin()) closest_item; + int32_t closest_distance = -1; + for (auto item_iter = items_vector->begin(); item_iter != items_vector->end(); item_iter++) + { + auto item = *item_iter; + if (!filter.matches(item)) + continue; + + auto pos = item->pos; + auto distance = abs(pos.x - building->centerx) + + abs(pos.y - building->centery) + + abs(pos.z - building->z) * 50; + + if (closest_distance > -1 && distance >= closest_distance) + continue; + + closest_distance = distance; + closest_item = item_iter; + } + + if (closest_distance > -1 && assignItem(*closest_item)) + { + debug("Item assigned"); + items_vector->erase(closest_item); + remove(); + return true; + } + + return false; } bool PlannedBuilding::assignItem(df::item *item) { - auto ref = df::allocate(); - if (!ref) - { - Core::printerr("Could not allocate general_ref_building_holderst\n"); - return false; - } - - ref->building_id = building->id; - - if (building->jobs.size() != 1) - return false; - - auto job = building->jobs[0]; - - for_each_(job->job_items, delete_item_fn); - job->job_items.clear(); - job->flags.bits.suspend = false; - - bool rough = false; - Job::attachJobItem(job, item, df::job_item_ref::Hauled); - if (item->getType() == item_type::BOULDER) - rough = true; - building->mat_type = item->getMaterial(); - building->mat_index = item->getMaterialIndex(); - - job->mat_type = building->mat_type; - job->mat_index = building->mat_index; - - if (building->needsDesign()) - { - auto act = (df::building_actual *) building; - act->design = new df::building_design(); - act->design->flags.bits.rough = rough; - } - - return true; + auto ref = df::allocate(); + if (!ref) + { + Core::printerr("Could not allocate general_ref_building_holderst\n"); + return false; + } + + ref->building_id = building->id; + + if (building->jobs.size() != 1) + return false; + + auto job = building->jobs[0]; + + for_each_(job->job_items, delete_item_fn); + job->job_items.clear(); + job->flags.bits.suspend = false; + + bool rough = false; + Job::attachJobItem(job, item, df::job_item_ref::Hauled); + if (item->getType() == item_type::BOULDER) + rough = true; + building->mat_type = item->getMaterial(); + building->mat_index = item->getMaterialIndex(); + + job->mat_type = building->mat_type; + job->mat_index = building->mat_index; + + if (building->needsDesign()) + { + auto act = (df::building_actual *) building; + act->design = new df::building_design(); + act->design->flags.bits.rough = rough; + } + + return true; } bool PlannedBuilding::isValid() { - bool valid = filter.isValid() && - building && Buildings::findAtTile(pos) == building && - building->getBuildStage() == 0; + bool valid = filter.isValid() && + building && Buildings::findAtTile(pos) == building && + building->getBuildStage() == 0; - if (!valid) - remove(); + if (!valid) + remove(); - return valid; + return valid; } void Planner::reset(color_ostream &out) { - planned_buildings.clear(); - std::vector items; - DFHack::World::GetPersistentData(&items, "buildingplan/constraints"); + planned_buildings.clear(); + std::vector items; + DFHack::World::GetPersistentData(&items, "buildingplan/constraints"); - for (auto i = items.begin(); i != items.end(); i++) - { - PlannedBuilding pb(*i, out); - if (pb.isValid()) - planned_buildings.push_back(pb); - } + for (auto i = items.begin(); i != items.end(); i++) + { + PlannedBuilding pb(*i, out); + if (pb.isValid()) + planned_buildings.push_back(pb); + } } void Planner::initialize() { - std::vector item_names; - typedef df::enum_traits item_types; - int size = item_types::last_item_value - item_types::first_item_value+1; - for (size_t i = 1; i < size; i++) - { - is_relevant_item_type[(df::item_type) (i-1)] = false; - std::string item_name = toLower(item_types::key_table[i]); - std::string item_name_clean; - for (auto c = item_name.begin(); c != item_name.end(); c++) - { - if (*c == '_') - continue; - item_name_clean += *c; - } - item_names.push_back(item_name_clean); - } - - typedef df::enum_traits building_types; - size = building_types::last_item_value - building_types::first_item_value+1; - for (size_t i = 1; i < size; i++) - { - auto building_type = (df::building_type) (i-1); - if (building_type == building_type::Weapon || building_type == building_type::Floodgate) - continue; - - std::string building_name = toLower(building_types::key_table[i]); - for (size_t j = 0; j < item_names.size(); j++) - { - if (building_name == item_names[j]) - { - auto btype = (df::building_type) (i-1); - auto itype = (df::item_type) j; - - item_for_building_type[btype] = itype; - default_item_filters[btype] = ItemFilter(); - available_item_vectors[itype] = std::vector(); - is_relevant_item_type[itype] = true; - - if (planmode_enabled.find(btype) == planmode_enabled.end()) - { - planmode_enabled[btype] = false; - } - } - } - } + std::vector item_names; + typedef df::enum_traits item_types; + int size = item_types::last_item_value - item_types::first_item_value+1; + for (size_t i = 1; i < size; i++) + { + is_relevant_item_type[(df::item_type) (i-1)] = false; + std::string item_name = toLower(item_types::key_table[i]); + std::string item_name_clean; + for (auto c = item_name.begin(); c != item_name.end(); c++) + { + if (*c == '_') + continue; + item_name_clean += *c; + } + item_names.push_back(item_name_clean); + } + + typedef df::enum_traits building_types; + size = building_types::last_item_value - building_types::first_item_value+1; + for (size_t i = 1; i < size; i++) + { + auto building_type = (df::building_type) (i-1); + if (building_type == building_type::Weapon || building_type == building_type::Floodgate) + continue; + + std::string building_name = toLower(building_types::key_table[i]); + for (size_t j = 0; j < item_names.size(); j++) + { + if (building_name == item_names[j]) + { + auto btype = (df::building_type) (i-1); + auto itype = (df::item_type) j; + + item_for_building_type[btype] = itype; + default_item_filters[btype] = ItemFilter(); + available_item_vectors[itype] = std::vector(); + is_relevant_item_type[itype] = true; + + if (planmode_enabled.find(btype) == planmode_enabled.end()) + { + planmode_enabled[btype] = false; + } + } + } + } } void Planner::doCycle() { - debug("Running Cycle"); - if (planned_buildings.size() == 0) - return; - - debug("Planned count: " + int_to_string(planned_buildings.size())); - - gather_available_items(); - for (auto building_iter = planned_buildings.begin(); building_iter != planned_buildings.end();) - { - if (building_iter->isValid()) - { - if (show_debugging) - debug(std::string("Trying to allocate ") + enum_item_key_str(building_iter->getType())); - - auto required_item_type = item_for_building_type[building_iter->getType()]; - auto items_vector = &available_item_vectors[required_item_type]; - if (items_vector->size() == 0 || !building_iter->assignClosestItem(items_vector)) - { - debug("Unable to allocate an item"); - ++building_iter; - continue; - } - } - debug("Removing building plan"); - building_iter = planned_buildings.erase(building_iter); - } + debug("Running Cycle"); + if (planned_buildings.size() == 0) + return; + + debug("Planned count: " + int_to_string(planned_buildings.size())); + + gather_available_items(); + for (auto building_iter = planned_buildings.begin(); building_iter != planned_buildings.end();) + { + if (building_iter->isValid()) + { + if (show_debugging) + debug(std::string("Trying to allocate ") + enum_item_key_str(building_iter->getType())); + + auto required_item_type = item_for_building_type[building_iter->getType()]; + auto items_vector = &available_item_vectors[required_item_type]; + if (items_vector->size() == 0 || !building_iter->assignClosestItem(items_vector)) + { + debug("Unable to allocate an item"); + ++building_iter; + continue; + } + } + debug("Removing building plan"); + building_iter = planned_buildings.erase(building_iter); + } } bool Planner::allocatePlannedBuilding(df::building_type type) { - coord32_t cursor; - if (!DFHack::Gui::getCursorCoords(cursor.x, cursor.y, cursor.z)) - return false; - - auto newinst = Buildings::allocInstance(cursor.get_coord16(), type); - if (!newinst) - return false; - - df::job_item *filter = new df::job_item(); - filter->item_type = item_type::NONE; - filter->mat_index = 0; - filter->flags2.bits.building_material = true; - std::vector filters; - filters.push_back(filter); - - if (!Buildings::constructWithFilters(newinst, filters)) - { - delete newinst; - return false; - } - - for (auto iter = newinst->jobs.begin(); iter != newinst->jobs.end(); iter++) - { - (*iter)->flags.bits.suspend = true; - } - - if (type == building_type::Door) - { - auto door = virtual_cast(newinst); - if (door) - door->door_flags.bits.pet_passable = true; - } - - addPlannedBuilding(newinst); - - return true; + coord32_t cursor; + if (!DFHack::Gui::getCursorCoords(cursor.x, cursor.y, cursor.z)) + return false; + + auto newinst = Buildings::allocInstance(cursor.get_coord16(), type); + if (!newinst) + return false; + + df::job_item *filter = new df::job_item(); + filter->item_type = item_type::NONE; + filter->mat_index = 0; + filter->flags2.bits.building_material = true; + std::vector filters; + filters.push_back(filter); + + if (!Buildings::constructWithFilters(newinst, filters)) + { + delete newinst; + return false; + } + + for (auto iter = newinst->jobs.begin(); iter != newinst->jobs.end(); iter++) + { + (*iter)->flags.bits.suspend = true; + } + + if (type == building_type::Door) + { + auto door = virtual_cast(newinst); + if (door) + door->door_flags.bits.pet_passable = true; + } + + addPlannedBuilding(newinst); + + return true; } PlannedBuilding *Planner::getSelectedPlannedBuilding() { - for (auto building_iter = planned_buildings.begin(); building_iter != planned_buildings.end(); building_iter++) - { - if (building_iter->isCurrentlySelectedBuilding()) - { - return &(*building_iter); - } - } + for (auto building_iter = planned_buildings.begin(); building_iter != planned_buildings.end(); building_iter++) + { + if (building_iter->isCurrentlySelectedBuilding()) + { + return &(*building_iter); + } + } - return nullptr; + return nullptr; } void Planner::cycleDefaultQuality(df::building_type type) { - auto quality = &getDefaultItemFilterForType(type)->min_quality; - *quality = static_cast(*quality + 1); - if (*quality == item_quality::Artifact) - (*quality) = item_quality::Ordinary; + auto quality = &getDefaultItemFilterForType(type)->min_quality; + *quality = static_cast(*quality + 1); + if (*quality == item_quality::Artifact) + (*quality) = item_quality::Ordinary; } \ No newline at end of file diff --git a/plugins/buildingplan-lib.h b/plugins/buildingplan-lib.h index 76f123cd8..7b2be66cb 100644 --- a/plugins/buildingplan-lib.h +++ b/plugins/buildingplan-lib.h @@ -52,8 +52,8 @@ struct MaterialDescriptor bool matches(const MaterialDescriptor &a) const { - return a.valid && valid && - a.type == type && + return a.valid && valid && + a.type == type && a.index == index && a.item_type == item_type && a.item_subtype == item_subtype; @@ -190,7 +190,7 @@ private: masks_column.filterDisplay(); } - + void populateMaterials() { materials_column.clear(); @@ -248,7 +248,7 @@ private: materials_column.sort(); } - void addMaterialEntry(df::dfhack_material_category &selected_category, + void addMaterialEntry(df::dfhack_material_category &selected_category, MaterialInfo &material, std::string name) { if (!selected_category.whole || material.matches(selected_category)) @@ -350,7 +350,7 @@ private: } }; -// START Planning +// START Planning class PlannedBuilding { public: diff --git a/plugins/buildingplan.cpp b/plugins/buildingplan.cpp index 5a5b9cf0b..d3cdef923 100644 --- a/plugins/buildingplan.cpp +++ b/plugins/buildingplan.cpp @@ -51,7 +51,7 @@ struct buildingplan_hook : public df::viewscreen_dwarfmodest bool isInPlannedBuildingQueryMode() { - return (ui->main.mode == df::ui_sidebar_mode::QueryBuilding || + return (ui->main.mode == df::ui_sidebar_mode::QueryBuilding || ui->main.mode == df::ui_sidebar_mode::BuildingItems) && planner.getSelectedPlannedBuilding(); } @@ -91,7 +91,7 @@ struct buildingplan_hook : public df::viewscreen_dwarfmodest { if (getNoblePositionOfSelectedBuildingOwner().size() > 0) return canReserveRoom(world->selected_building); - else + else return false; } @@ -119,7 +119,7 @@ struct buildingplan_hook : public df::viewscreen_dwarfmodest { show_help = true; } - + if (is_planmode_enabled(type)) { if (planner.inQuickFortMode() && planner.in_dummmy_screen) @@ -184,7 +184,7 @@ struct buildingplan_hook : public df::viewscreen_dwarfmodest { planner.removeSelectedPlannedBuilding(); // Remove persistent data } - + } else if (isInNobleRoomQueryMode()) { @@ -347,7 +347,7 @@ static command_result buildingplan_cmd(color_ostream &out, vector & par { show_debugging = (toLower(parameters[1]) == "on"); out << "Debugging " << ((show_debugging) ? "enabled" : "disabled") << endl; - } + } } return CR_OK; diff --git a/plugins/catsplosion.cpp b/plugins/catsplosion.cpp index a714a47a5..1e68268eb 100644 --- a/plugins/catsplosion.cpp +++ b/plugins/catsplosion.cpp @@ -92,7 +92,7 @@ command_result catsplosion (color_ostream &out, std::vector & para female_counts[raw->creature_id].size(); //auto initialize the females as well } } - + // print (optional) //if (showcreatures == 1) { diff --git a/plugins/changeitem.cpp b/plugins/changeitem.cpp index b73f24097..52d9e7ab9 100644 --- a/plugins/changeitem.cpp +++ b/plugins/changeitem.cpp @@ -127,7 +127,7 @@ command_result df_changeitem(color_ostream &out, vector & parameters) for (size_t i = 0; i < parameters.size(); i++) { string & p = parameters[i]; - + if (p == "help" || p == "?") { out << changeitem_help << endl; @@ -328,7 +328,7 @@ command_result changeitem_execute( out << " quality: " << describeQuality(item->getQuality()) << endl; //if(item->isImproved()) // out << " imp.quality: " << describeQuality(item->getImprovementQuality()) << endl; - out << " material: " << mat_old.getToken() << endl; + out << " material: " << mat_old.getToken() << endl; return CR_OK; } @@ -350,7 +350,7 @@ command_result changeitem_execute( // fixme: changing material of cloth items needs more work... // <_Q> cloth items have a "CLOTH" improvement which tells you about the cloth that was used to make it - + if(force||(mat_old.subtype == mat_new.subtype && mat_old.mode==mat_new.mode)) { item->setMaterial(mat_new.type); diff --git a/plugins/changelayer.cpp b/plugins/changelayer.cpp index 727fae56c..64e932609 100644 --- a/plugins/changelayer.cpp +++ b/plugins/changelayer.cpp @@ -32,8 +32,8 @@ DFHACK_PLUGIN("changelayer"); REQUIRE_GLOBAL(world); REQUIRE_GLOBAL(cursor); -const string changelayer_help = - " Allows to change the material of whole geology layers.\n" +const string changelayer_help = + " Allows to change the material of whole geology layers.\n" " Can have impact on all surrounding regions, not only your embark!\n" " By default changing stone to soil and vice versa is not allowed.\n" " By default changes only the layer at the cursor position.\n" @@ -47,7 +47,7 @@ const string changelayer_help = " all_biomes - Change layer for all biomes on your map.\n" " Result may be undesirable since the same layer\n" " can AND WILL be on different z-levels for different biomes.\n" - " Use the tool 'probe' to get an idea how layers and biomes\n" + " Use the tool 'probe' to get an idea how layers and biomes\n" " are distributed on your map.\n" " all_layers - Change all layers on your map.\n" " Candy mountain, anyone?\n" @@ -70,7 +70,7 @@ const string changelayer_help = " changelayer MARBLE allbiomes alllayers\n" " Convert all layers of all biomes into marble.\n"; -const string changelayer_trouble = +const string changelayer_trouble = "Known problems with changelayer:\n\n" " Nothing happens, the material stays the old.\n" " Pause/unpause the game and/or move the cursor a bit. Then retry.\n" @@ -108,7 +108,7 @@ static bool warned = false; command_result changelayer (color_ostream &out, std::vector & parameters) { - CoreSuspender suspend; + CoreSuspender suspend; string material; bool force = false; @@ -209,13 +209,13 @@ command_result changelayer (color_ostream &out, std::vector & para // there is no Maps::WriteGeology or whatever, and I didn't want to mess with the library and add it // so I copied the stuff which reads the geology information and modified it to be able to change it - // + // // a more elegant solution would probably look like this: - // 1) modify Maps::ReadGeology to accept and fill one more optional vector + // 1) modify Maps::ReadGeology to accept and fill one more optional vector // where the geolayer ids of the 9 biomes are stored // 2) call ReadGeology here, modify the data in the vectors without having to do all that map stuff // 3) write Maps::WriteGeology, pass the vectors, let it do it's work - // Step 1) is optional, but it would make implementing 3) easier. + // Step 1) is optional, but it would make implementing 3) easier. // Otherwise that "check which geo_index is used by biome X" loop would need to be done again. // no need to touch the same geology more than once @@ -226,17 +226,17 @@ command_result changelayer (color_ostream &out, std::vector & para // iterate over 8 surrounding regions + local region for (int i = eNorthWest; i < eBiomeCount; i++) { - if(verbose) + if(verbose) out << "---Biome: " << i; if(!all_biomes && i!=biome) { - if(verbose) + if(verbose) out << "-skipping" << endl; continue; } else { - if(verbose) + if(verbose) out << "-checking" << endl; } @@ -304,9 +304,9 @@ command_result changelayer (color_ostream &out, std::vector & para if(conversionAllowed(out, mat_new, mat_old, force)) { if(verbose) - out << "changing geolayer " << j - << " from " << mat_old.getToken() - << " to " << mat_new.getToken() + out << "changing geolayer " << j + << " from " << mat_old.getToken() + << " to " << mat_new.getToken() << endl; geolayers[j]->mat_index = mat_new.index; } @@ -329,7 +329,7 @@ command_result changelayer (color_ostream &out, std::vector & para } out.print("Done.\n"); - + // Give control back to DF. return CR_OK; } diff --git a/plugins/createitem.cpp b/plugins/createitem.cpp index c4c0c6ebb..1fc663d07 100644 --- a/plugins/createitem.cpp +++ b/plugins/createitem.cpp @@ -326,7 +326,7 @@ command_result df_createitem (color_ostream &out, vector & parameters) out.printerr("The creature you specified has no such caste!\n"); return CR_FAILURE; } - } + } } if (mat_type == -1) { diff --git a/plugins/cursecheck.cpp b/plugins/cursecheck.cpp index dc7fd2f3c..e33c85855 100644 --- a/plugins/cursecheck.cpp +++ b/plugins/cursecheck.cpp @@ -127,7 +127,7 @@ void setUnitNickname(df::unit *unit, const std::string &nick) std::string determineCurse(df::unit * unit) { string cursetype = "unknown"; - + // ghosts: ghostly, duh // as of DF 34.05 and higher vampire ghosts and the like should not be possible // if they get reintroduced later it will become necessary to watch 'ghostly' seperately @@ -140,17 +140,17 @@ std::string determineCurse(df::unit * unit) cursetype = "zombie"; // necromancers: alive, don't eat, don't drink, don't age - if(!unit->curse.add_tags1.bits.NOT_LIVING - && unit->curse.add_tags1.bits.NO_EAT - && unit->curse.add_tags1.bits.NO_DRINK + if(!unit->curse.add_tags1.bits.NOT_LIVING + && unit->curse.add_tags1.bits.NO_EAT + && unit->curse.add_tags1.bits.NO_DRINK && unit->curse.add_tags2.bits.NO_AGING ) cursetype = "necromancer"; // werecreatures: alive, DO eat, DO drink, don't age - if(!unit->curse.add_tags1.bits.NOT_LIVING - && !unit->curse.add_tags1.bits.NO_EAT - && !unit->curse.add_tags1.bits.NO_DRINK + if(!unit->curse.add_tags1.bits.NOT_LIVING + && !unit->curse.add_tags1.bits.NO_EAT + && !unit->curse.add_tags1.bits.NO_DRINK && unit->curse.add_tags2.bits.NO_AGING ) cursetype = "werebeast"; @@ -199,7 +199,7 @@ command_result cursecheck (color_ostream &out, vector & parameters) if(parameters[i] == "verbose") { // verbose makes no sense without enabling details - giveDetails = true; + giveDetails = true; verbose = true; } } @@ -234,7 +234,7 @@ command_result cursecheck (color_ostream &out, vector & parameters) cursecount++; string cursetype = determineCurse(unit); - + if(giveNick) { setUnitNickname(unit, cursetype); //"CURSED"); @@ -266,12 +266,12 @@ command_result cursecheck (color_ostream &out, vector & parameters) { missing = true; } - + out.print("born in %d, cursed in %d to be a %s. (%s%s%s)\n", unit->relations.birth_year, unit->relations.curse_year, cursetype.c_str(), - // technically most cursed creatures are undead, + // technically most cursed creatures are undead, // therefore output 'active' if they are not completely dead unit->flags1.bits.dead ? "deceased" : "active", unit->flags3.bits.ghostly ? "-ghostly" : "", @@ -298,6 +298,6 @@ command_result cursecheck (color_ostream &out, vector & parameters) out.print("Number of cursed creatures on map: %d \n", cursecount); else out.print("Number of cursed creatures on tile: %d \n", cursecount); - + return CR_OK; } diff --git a/plugins/devel/autolabor2.cpp b/plugins/devel/autolabor2.cpp index c328989a7..aca30ad3e 100644 --- a/plugins/devel/autolabor2.cpp +++ b/plugins/devel/autolabor2.cpp @@ -377,9 +377,9 @@ struct labor_info int maximum_dwarfs() { return config.ival(2); } void set_maximum_dwarfs(int maximum_dwarfs) { config.ival(2) = maximum_dwarfs; } - int time_since_last_assigned() - { - return (*df::global::cur_year - config.ival(3)) * 403200 + *df::global::cur_year_tick - config.ival(4); + int time_since_last_assigned() + { + return (*df::global::cur_year - config.ival(3)) * 403200 + *df::global::cur_year_tick - config.ival(4); } void mark_assigned() { config.ival(3) = (* df::global::cur_year); @@ -496,14 +496,14 @@ struct dwarf_info_t df::unit_labor using_labor; - dwarf_info_t(df::unit* dw) : dwarf(dw), clear_all(false), + dwarf_info_t(df::unit* dw) : dwarf(dw), clear_all(false), state(OTHER), high_skill(0), has_children(false), armed(false) { - for (int e = TOOL_NONE; e < TOOLS_MAX; e++) + for (int e = TOOL_NONE; e < TOOLS_MAX; e++) has_tool[e] = false; } - void set_labor(df::unit_labor labor) + void set_labor(df::unit_labor labor) { if (labor >= 0 && labor <= ENUM_LAST_ITEM(unit_labor)) { @@ -511,7 +511,7 @@ struct dwarf_info_t } } - void clear_labor(df::unit_labor labor) + void clear_labor(df::unit_labor labor) { if (labor >= 0 && labor <= ENUM_LAST_ITEM(unit_labor)) { @@ -521,7 +521,7 @@ struct dwarf_info_t }; -/* +/* * Here starts all the complicated stuff to try to deduce labors from jobs. * This is all way more complicated than it really ought to be, but I have * not found a way to make it simpler. @@ -529,124 +529,124 @@ struct dwarf_info_t static df::unit_labor hauling_labor_map[] = { - df::unit_labor::HAUL_ITEM, /* BAR */ - df::unit_labor::HAUL_STONE, /* SMALLGEM */ - df::unit_labor::HAUL_ITEM, /* BLOCKS */ - df::unit_labor::HAUL_STONE, /* ROUGH */ - df::unit_labor::HAUL_STONE, /* BOULDER */ - df::unit_labor::HAUL_WOOD, /* WOOD */ - df::unit_labor::HAUL_FURNITURE, /* DOOR */ - df::unit_labor::HAUL_FURNITURE, /* FLOODGATE */ - df::unit_labor::HAUL_FURNITURE, /* BED */ - df::unit_labor::HAUL_FURNITURE, /* CHAIR */ - df::unit_labor::HAUL_ITEM, /* CHAIN */ - df::unit_labor::HAUL_ITEM, /* FLASK */ - df::unit_labor::HAUL_ITEM, /* GOBLET */ - df::unit_labor::HAUL_ITEM, /* INSTRUMENT */ - df::unit_labor::HAUL_ITEM, /* TOY */ - df::unit_labor::HAUL_FURNITURE, /* WINDOW */ - df::unit_labor::HAUL_ANIMAL, /* CAGE */ - df::unit_labor::HAUL_ITEM, /* BARREL */ - df::unit_labor::HAUL_ITEM, /* BUCKET */ - df::unit_labor::HAUL_ANIMAL, /* ANIMALTRAP */ - df::unit_labor::HAUL_FURNITURE, /* TABLE */ - df::unit_labor::HAUL_FURNITURE, /* COFFIN */ - df::unit_labor::HAUL_FURNITURE, /* STATUE */ - df::unit_labor::HAUL_REFUSE, /* CORPSE */ - df::unit_labor::HAUL_ITEM, /* WEAPON */ - df::unit_labor::HAUL_ITEM, /* ARMOR */ - df::unit_labor::HAUL_ITEM, /* SHOES */ - df::unit_labor::HAUL_ITEM, /* SHIELD */ - df::unit_labor::HAUL_ITEM, /* HELM */ - df::unit_labor::HAUL_ITEM, /* GLOVES */ - df::unit_labor::HAUL_FURNITURE, /* BOX */ - df::unit_labor::HAUL_ITEM, /* BIN */ - df::unit_labor::HAUL_FURNITURE, /* ARMORSTAND */ - df::unit_labor::HAUL_FURNITURE, /* WEAPONRACK */ - df::unit_labor::HAUL_FURNITURE, /* CABINET */ - df::unit_labor::HAUL_ITEM, /* FIGURINE */ - df::unit_labor::HAUL_ITEM, /* AMULET */ - df::unit_labor::HAUL_ITEM, /* SCEPTER */ - df::unit_labor::HAUL_ITEM, /* AMMO */ - df::unit_labor::HAUL_ITEM, /* CROWN */ - df::unit_labor::HAUL_ITEM, /* RING */ - df::unit_labor::HAUL_ITEM, /* EARRING */ - df::unit_labor::HAUL_ITEM, /* BRACELET */ - df::unit_labor::HAUL_ITEM, /* GEM */ - df::unit_labor::HAUL_FURNITURE, /* ANVIL */ - df::unit_labor::HAUL_REFUSE, /* CORPSEPIECE */ - df::unit_labor::HAUL_REFUSE, /* REMAINS */ - df::unit_labor::HAUL_FOOD, /* MEAT */ - df::unit_labor::HAUL_FOOD, /* FISH */ - df::unit_labor::HAUL_FOOD, /* FISH_RAW */ - df::unit_labor::HAUL_REFUSE, /* VERMIN */ - df::unit_labor::HAUL_ITEM, /* PET */ - df::unit_labor::HAUL_FOOD, /* SEEDS */ - df::unit_labor::HAUL_FOOD, /* PLANT */ - df::unit_labor::HAUL_ITEM, /* SKIN_TANNED */ - df::unit_labor::HAUL_FOOD, /* LEAVES */ - df::unit_labor::HAUL_ITEM, /* THREAD */ - df::unit_labor::HAUL_ITEM, /* CLOTH */ - df::unit_labor::HAUL_ITEM, /* TOTEM */ - df::unit_labor::HAUL_ITEM, /* PANTS */ - df::unit_labor::HAUL_ITEM, /* BACKPACK */ - df::unit_labor::HAUL_ITEM, /* QUIVER */ - df::unit_labor::HAUL_FURNITURE, /* CATAPULTPARTS */ - df::unit_labor::HAUL_FURNITURE, /* BALLISTAPARTS */ - df::unit_labor::HAUL_FURNITURE, /* SIEGEAMMO */ - df::unit_labor::HAUL_FURNITURE, /* BALLISTAARROWHEAD */ - df::unit_labor::HAUL_FURNITURE, /* TRAPPARTS */ - df::unit_labor::HAUL_FURNITURE, /* TRAPCOMP */ - df::unit_labor::HAUL_FOOD, /* DRINK */ - df::unit_labor::HAUL_FOOD, /* POWDER_MISC */ - df::unit_labor::HAUL_FOOD, /* CHEESE */ - df::unit_labor::HAUL_FOOD, /* FOOD */ - df::unit_labor::HAUL_FOOD, /* LIQUID_MISC */ - df::unit_labor::HAUL_ITEM, /* COIN */ - df::unit_labor::HAUL_FOOD, /* GLOB */ - df::unit_labor::HAUL_STONE, /* ROCK */ - df::unit_labor::HAUL_FURNITURE, /* PIPE_SECTION */ - df::unit_labor::HAUL_FURNITURE, /* HATCH_COVER */ - df::unit_labor::HAUL_FURNITURE, /* GRATE */ - df::unit_labor::HAUL_FURNITURE, /* QUERN */ - df::unit_labor::HAUL_FURNITURE, /* MILLSTONE */ - df::unit_labor::HAUL_ITEM, /* SPLINT */ - df::unit_labor::HAUL_ITEM, /* CRUTCH */ - df::unit_labor::HAUL_FURNITURE, /* TRACTION_BENCH */ - df::unit_labor::HAUL_ITEM, /* ORTHOPEDIC_CAST */ - df::unit_labor::HAUL_ITEM, /* TOOL */ - df::unit_labor::HAUL_FURNITURE, /* SLAB */ - df::unit_labor::HAUL_FOOD, /* EGG */ - df::unit_labor::HAUL_ITEM, /* BOOK */ + df::unit_labor::HAUL_ITEM, /* BAR */ + df::unit_labor::HAUL_STONE, /* SMALLGEM */ + df::unit_labor::HAUL_ITEM, /* BLOCKS */ + df::unit_labor::HAUL_STONE, /* ROUGH */ + df::unit_labor::HAUL_STONE, /* BOULDER */ + df::unit_labor::HAUL_WOOD, /* WOOD */ + df::unit_labor::HAUL_FURNITURE, /* DOOR */ + df::unit_labor::HAUL_FURNITURE, /* FLOODGATE */ + df::unit_labor::HAUL_FURNITURE, /* BED */ + df::unit_labor::HAUL_FURNITURE, /* CHAIR */ + df::unit_labor::HAUL_ITEM, /* CHAIN */ + df::unit_labor::HAUL_ITEM, /* FLASK */ + df::unit_labor::HAUL_ITEM, /* GOBLET */ + df::unit_labor::HAUL_ITEM, /* INSTRUMENT */ + df::unit_labor::HAUL_ITEM, /* TOY */ + df::unit_labor::HAUL_FURNITURE, /* WINDOW */ + df::unit_labor::HAUL_ANIMAL, /* CAGE */ + df::unit_labor::HAUL_ITEM, /* BARREL */ + df::unit_labor::HAUL_ITEM, /* BUCKET */ + df::unit_labor::HAUL_ANIMAL, /* ANIMALTRAP */ + df::unit_labor::HAUL_FURNITURE, /* TABLE */ + df::unit_labor::HAUL_FURNITURE, /* COFFIN */ + df::unit_labor::HAUL_FURNITURE, /* STATUE */ + df::unit_labor::HAUL_REFUSE, /* CORPSE */ + df::unit_labor::HAUL_ITEM, /* WEAPON */ + df::unit_labor::HAUL_ITEM, /* ARMOR */ + df::unit_labor::HAUL_ITEM, /* SHOES */ + df::unit_labor::HAUL_ITEM, /* SHIELD */ + df::unit_labor::HAUL_ITEM, /* HELM */ + df::unit_labor::HAUL_ITEM, /* GLOVES */ + df::unit_labor::HAUL_FURNITURE, /* BOX */ + df::unit_labor::HAUL_ITEM, /* BIN */ + df::unit_labor::HAUL_FURNITURE, /* ARMORSTAND */ + df::unit_labor::HAUL_FURNITURE, /* WEAPONRACK */ + df::unit_labor::HAUL_FURNITURE, /* CABINET */ + df::unit_labor::HAUL_ITEM, /* FIGURINE */ + df::unit_labor::HAUL_ITEM, /* AMULET */ + df::unit_labor::HAUL_ITEM, /* SCEPTER */ + df::unit_labor::HAUL_ITEM, /* AMMO */ + df::unit_labor::HAUL_ITEM, /* CROWN */ + df::unit_labor::HAUL_ITEM, /* RING */ + df::unit_labor::HAUL_ITEM, /* EARRING */ + df::unit_labor::HAUL_ITEM, /* BRACELET */ + df::unit_labor::HAUL_ITEM, /* GEM */ + df::unit_labor::HAUL_FURNITURE, /* ANVIL */ + df::unit_labor::HAUL_REFUSE, /* CORPSEPIECE */ + df::unit_labor::HAUL_REFUSE, /* REMAINS */ + df::unit_labor::HAUL_FOOD, /* MEAT */ + df::unit_labor::HAUL_FOOD, /* FISH */ + df::unit_labor::HAUL_FOOD, /* FISH_RAW */ + df::unit_labor::HAUL_REFUSE, /* VERMIN */ + df::unit_labor::HAUL_ITEM, /* PET */ + df::unit_labor::HAUL_FOOD, /* SEEDS */ + df::unit_labor::HAUL_FOOD, /* PLANT */ + df::unit_labor::HAUL_ITEM, /* SKIN_TANNED */ + df::unit_labor::HAUL_FOOD, /* LEAVES */ + df::unit_labor::HAUL_ITEM, /* THREAD */ + df::unit_labor::HAUL_ITEM, /* CLOTH */ + df::unit_labor::HAUL_ITEM, /* TOTEM */ + df::unit_labor::HAUL_ITEM, /* PANTS */ + df::unit_labor::HAUL_ITEM, /* BACKPACK */ + df::unit_labor::HAUL_ITEM, /* QUIVER */ + df::unit_labor::HAUL_FURNITURE, /* CATAPULTPARTS */ + df::unit_labor::HAUL_FURNITURE, /* BALLISTAPARTS */ + df::unit_labor::HAUL_FURNITURE, /* SIEGEAMMO */ + df::unit_labor::HAUL_FURNITURE, /* BALLISTAARROWHEAD */ + df::unit_labor::HAUL_FURNITURE, /* TRAPPARTS */ + df::unit_labor::HAUL_FURNITURE, /* TRAPCOMP */ + df::unit_labor::HAUL_FOOD, /* DRINK */ + df::unit_labor::HAUL_FOOD, /* POWDER_MISC */ + df::unit_labor::HAUL_FOOD, /* CHEESE */ + df::unit_labor::HAUL_FOOD, /* FOOD */ + df::unit_labor::HAUL_FOOD, /* LIQUID_MISC */ + df::unit_labor::HAUL_ITEM, /* COIN */ + df::unit_labor::HAUL_FOOD, /* GLOB */ + df::unit_labor::HAUL_STONE, /* ROCK */ + df::unit_labor::HAUL_FURNITURE, /* PIPE_SECTION */ + df::unit_labor::HAUL_FURNITURE, /* HATCH_COVER */ + df::unit_labor::HAUL_FURNITURE, /* GRATE */ + df::unit_labor::HAUL_FURNITURE, /* QUERN */ + df::unit_labor::HAUL_FURNITURE, /* MILLSTONE */ + df::unit_labor::HAUL_ITEM, /* SPLINT */ + df::unit_labor::HAUL_ITEM, /* CRUTCH */ + df::unit_labor::HAUL_FURNITURE, /* TRACTION_BENCH */ + df::unit_labor::HAUL_ITEM, /* ORTHOPEDIC_CAST */ + df::unit_labor::HAUL_ITEM, /* TOOL */ + df::unit_labor::HAUL_FURNITURE, /* SLAB */ + df::unit_labor::HAUL_FOOD, /* EGG */ + df::unit_labor::HAUL_ITEM, /* BOOK */ }; -static df::unit_labor workshop_build_labor[] = +static df::unit_labor workshop_build_labor[] = { - /* Carpenters */ df::unit_labor::CARPENTER, - /* Farmers */ df::unit_labor::PROCESS_PLANT, - /* Masons */ df::unit_labor::MASON, - /* Craftsdwarfs */ df::unit_labor::STONE_CRAFT, - /* Jewelers */ df::unit_labor::CUT_GEM, - /* MetalsmithsForge */ df::unit_labor::METAL_CRAFT, - /* MagmaForge */ df::unit_labor::METAL_CRAFT, - /* Bowyers */ df::unit_labor::BOWYER, - /* Mechanics */ df::unit_labor::MECHANIC, - /* Siege */ df::unit_labor::SIEGECRAFT, - /* Butchers */ df::unit_labor::BUTCHER, - /* Leatherworks */ df::unit_labor::LEATHER, - /* Tanners */ df::unit_labor::TANNER, - /* Clothiers */ df::unit_labor::CLOTHESMAKER, - /* Fishery */ df::unit_labor::CLEAN_FISH, - /* Still */ df::unit_labor::BREWER, - /* Loom */ df::unit_labor::WEAVER, - /* Quern */ df::unit_labor::MILLER, - /* Kennels */ df::unit_labor::ANIMALTRAIN, - /* Kitchen */ df::unit_labor::COOK, - /* Ashery */ df::unit_labor::LYE_MAKING, - /* Dyers */ df::unit_labor::DYER, - /* Millstone */ df::unit_labor::MILLER, - /* Custom */ df::unit_labor::NONE, - /* Tool */ df::unit_labor::NONE + /* Carpenters */ df::unit_labor::CARPENTER, + /* Farmers */ df::unit_labor::PROCESS_PLANT, + /* Masons */ df::unit_labor::MASON, + /* Craftsdwarfs */ df::unit_labor::STONE_CRAFT, + /* Jewelers */ df::unit_labor::CUT_GEM, + /* MetalsmithsForge */ df::unit_labor::METAL_CRAFT, + /* MagmaForge */ df::unit_labor::METAL_CRAFT, + /* Bowyers */ df::unit_labor::BOWYER, + /* Mechanics */ df::unit_labor::MECHANIC, + /* Siege */ df::unit_labor::SIEGECRAFT, + /* Butchers */ df::unit_labor::BUTCHER, + /* Leatherworks */ df::unit_labor::LEATHER, + /* Tanners */ df::unit_labor::TANNER, + /* Clothiers */ df::unit_labor::CLOTHESMAKER, + /* Fishery */ df::unit_labor::CLEAN_FISH, + /* Still */ df::unit_labor::BREWER, + /* Loom */ df::unit_labor::WEAVER, + /* Quern */ df::unit_labor::MILLER, + /* Kennels */ df::unit_labor::ANIMALTRAIN, + /* Kitchen */ df::unit_labor::COOK, + /* Ashery */ df::unit_labor::LYE_MAKING, + /* Dyers */ df::unit_labor::DYER, + /* Millstone */ df::unit_labor::MILLER, + /* Custom */ df::unit_labor::NONE, + /* Tool */ df::unit_labor::NONE }; static df::building* get_building_from_job(df::job* j) @@ -663,7 +663,7 @@ static df::building* get_building_from_job(df::job* j) return 0; } -static df::unit_labor construction_build_labor (df::item* i) +static df::unit_labor construction_build_labor (df::item* i) { MaterialInfo matinfo; if (i && matinfo.decode(i)) @@ -693,25 +693,25 @@ void debug (char* fmt, ...) class JobLaborMapper { private: - class jlfunc + class jlfunc { public: virtual df::unit_labor get_labor(df::job* j) = 0; }; - class jlfunc_const : public jlfunc + class jlfunc_const : public jlfunc { private: df::unit_labor labor; public: - df::unit_labor get_labor(df::job* j) + df::unit_labor get_labor(df::job* j) { return labor; } jlfunc_const(df::unit_labor l) : labor(l) {}; }; - class jlfunc_hauling : public jlfunc + class jlfunc_hauling : public jlfunc { public: df::unit_labor get_labor(df::job* j) @@ -729,7 +729,7 @@ private: } } - if (item && item->flags.bits.container) + if (item && item->flags.bits.container) { for (auto a = item->general_refs.begin(); a != item->general_refs.end(); a++) { @@ -750,7 +750,7 @@ private: jlfunc_hauling() {}; }; - class jlfunc_construct_bld : public jlfunc + class jlfunc_construct_bld : public jlfunc { public: df::unit_labor get_labor(df::job* j) @@ -759,7 +759,7 @@ private: return df::unit_labor::NONE; df::building* bld = get_building_from_job (j); - switch (bld->getType()) + switch (bld->getType()) { case df::building_type::Hive: return df::unit_labor::BEEKEEPING; @@ -768,12 +768,12 @@ private: df::building_workshopst* ws = (df::building_workshopst*) bld; if (ws->design && !ws->design->flags.bits.designed) return df::unit_labor::ARCHITECT; - if (ws->type == df::workshop_type::Custom) + if (ws->type == df::workshop_type::Custom) { df::building_def* def = df::building_def::find(ws->custom_type); return def->build_labors[0]; - } - else + } + else return workshop_build_labor[ws->type]; } break; @@ -849,7 +849,7 @@ private: jlfunc_construct_bld() {} }; - class jlfunc_destroy_bld : public jlfunc + class jlfunc_destroy_bld : public jlfunc { public: df::unit_labor get_labor(df::job* j) @@ -857,19 +857,19 @@ private: df::building* bld = get_building_from_job (j); df::building_type type = bld->getType(); - switch (bld->getType()) + switch (bld->getType()) { case df::building_type::Hive: return df::unit_labor::BEEKEEPING; case df::building_type::Workshop: { df::building_workshopst* ws = (df::building_workshopst*) bld; - if (ws->type == df::workshop_type::Custom) + if (ws->type == df::workshop_type::Custom) { df::building_def* def = df::building_def::find(ws->custom_type); return def->build_labors[0]; - } - else + } + else return workshop_build_labor[ws->type]; } break; @@ -943,7 +943,7 @@ private: jlfunc_destroy_bld() {} }; - class jlfunc_make : public jlfunc + class jlfunc_make : public jlfunc { private: df::unit_labor metaltype; @@ -954,31 +954,31 @@ private: if (bld->getType() == df::building_type::Workshop) { df::workshop_type type = ((df::building_workshopst*)(bld))->type; - switch (type) + switch (type) { case df::workshop_type::Craftsdwarfs: { df::item_type jobitem = j->job_items[0]->item_type; - switch (jobitem) + switch (jobitem) { case df::item_type::BOULDER: return df::unit_labor::STONE_CRAFT; case df::item_type::NONE: - if (j->material_category.bits.bone || + if (j->material_category.bits.bone || j->material_category.bits.horn || j->material_category.bits.tooth) return df::unit_labor::BONE_CARVE; else { debug ("AUTOLABOR: Cannot deduce labor for make crafts job (not bone)\n"); - return df::unit_labor::NONE; + return df::unit_labor::NONE; } case df::item_type::WOOD: return df::unit_labor::WOOD_CRAFT; default: - debug ("AUTOLABOR: Cannot deduce labor for make crafts job, item type %s\n", + debug ("AUTOLABOR: Cannot deduce labor for make crafts job, item type %s\n", ENUM_KEY_STR(item_type, jobitem).c_str()); - return df::unit_labor::NONE; + return df::unit_labor::NONE; } } case df::workshop_type::Masons: @@ -995,13 +995,13 @@ private: default: debug ("AUTOLABOR: Cannot deduce labor for make job, workshop type %s\n", ENUM_KEY_STR(workshop_type, type).c_str()); - return df::unit_labor::NONE; + return df::unit_labor::NONE; } } else if (bld->getType() == df::building_type::Furnace) { df::furnace_type type = ((df::building_furnacest*)(bld))->type; - switch (type) + switch (type) { case df::furnace_type::MagmaGlassFurnace: case df::furnace_type::GlassFurnace: @@ -1009,20 +1009,20 @@ private: default: debug ("AUTOLABOR: Cannot deduce labor for make job, furnace type %s\n", ENUM_KEY_STR(furnace_type, type).c_str()); - return df::unit_labor::NONE; + return df::unit_labor::NONE; } } debug ("AUTOLABOR: Cannot deduce labor for make job, building type %s\n", ENUM_KEY_STR(building_type, bld->getType()).c_str()); - return df::unit_labor::NONE; + return df::unit_labor::NONE; } jlfunc_make (df::unit_labor mt) : metaltype(mt) {} }; - class jlfunc_custom : public jlfunc + class jlfunc_custom : public jlfunc { public: df::unit_labor get_labor(df::job* j) @@ -1059,7 +1059,7 @@ private: std::map job_to_labor_table; public: - ~JobLaborMapper() + ~JobLaborMapper() { std::set log; @@ -1075,7 +1075,7 @@ public: FOR_ENUM_ITEMS (job_type, j) { - if (j < 0) + if (j < 0) continue; jlfunc* p = job_to_labor_table[j]; @@ -1088,9 +1088,9 @@ public: } } - JobLaborMapper() + JobLaborMapper() { - jlfunc* jlf_hauling = new jlfunc_hauling(); + jlfunc* jlf_hauling = new jlfunc_hauling(); jlfunc* jlf_make_furniture = new jlfunc_make(df::unit_labor::FORGE_FURNITURE); jlfunc* jlf_make_object = new jlfunc_make(df::unit_labor::METAL_CRAFT); jlfunc* jlf_make_armor = new jlfunc_make(df::unit_labor::FORGE_ARMOR); @@ -1098,236 +1098,236 @@ public: jlfunc* jlf_no_labor = jlf_const(df::unit_labor::NONE); - job_to_labor_table[df::job_type::CarveFortification] = jlf_const(df::unit_labor::DETAIL); - job_to_labor_table[df::job_type::DetailWall] = jlf_const(df::unit_labor::DETAIL); - job_to_labor_table[df::job_type::DetailFloor] = jlf_const(df::unit_labor::DETAIL); - job_to_labor_table[df::job_type::Dig] = jlf_const(df::unit_labor::MINE); - job_to_labor_table[df::job_type::CarveUpwardStaircase] = jlf_const(df::unit_labor::MINE); + job_to_labor_table[df::job_type::CarveFortification] = jlf_const(df::unit_labor::DETAIL); + job_to_labor_table[df::job_type::DetailWall] = jlf_const(df::unit_labor::DETAIL); + job_to_labor_table[df::job_type::DetailFloor] = jlf_const(df::unit_labor::DETAIL); + job_to_labor_table[df::job_type::Dig] = jlf_const(df::unit_labor::MINE); + job_to_labor_table[df::job_type::CarveUpwardStaircase] = jlf_const(df::unit_labor::MINE); job_to_labor_table[df::job_type::CarveDownwardStaircase] = jlf_const(df::unit_labor::MINE); - job_to_labor_table[df::job_type::CarveUpDownStaircase] = jlf_const(df::unit_labor::MINE); - job_to_labor_table[df::job_type::CarveRamp] = jlf_const(df::unit_labor::MINE); - job_to_labor_table[df::job_type::DigChannel] = jlf_const(df::unit_labor::MINE); - job_to_labor_table[df::job_type::FellTree] = jlf_const(df::unit_labor::CUTWOOD); - job_to_labor_table[df::job_type::GatherPlants] = jlf_const(df::unit_labor::HERBALIST); - job_to_labor_table[df::job_type::RemoveConstruction] = jlf_no_labor; - job_to_labor_table[df::job_type::CollectWebs] = jlf_const(df::unit_labor::WEAVER); - job_to_labor_table[df::job_type::BringItemToDepot] = jlf_no_labor; - job_to_labor_table[df::job_type::BringItemToShop] = jlf_no_labor; - job_to_labor_table[df::job_type::Eat] = jlf_no_labor; - job_to_labor_table[df::job_type::GetProvisions] = jlf_no_labor; - job_to_labor_table[df::job_type::Drink] = jlf_no_labor; - job_to_labor_table[df::job_type::Drink2] = jlf_no_labor; - job_to_labor_table[df::job_type::FillWaterskin] = jlf_no_labor; - job_to_labor_table[df::job_type::FillWaterskin2] = jlf_no_labor; - job_to_labor_table[df::job_type::Sleep] = jlf_no_labor; - job_to_labor_table[df::job_type::CollectSand] = jlf_const(df::unit_labor::HAUL_ITEM); - job_to_labor_table[df::job_type::Fish] = jlf_const(df::unit_labor::FISH); - job_to_labor_table[df::job_type::Hunt] = jlf_const(df::unit_labor::HUNT); - job_to_labor_table[df::job_type::HuntVermin] = jlf_no_labor; - job_to_labor_table[df::job_type::Kidnap] = jlf_no_labor; - job_to_labor_table[df::job_type::BeatCriminal] = jlf_no_labor; - job_to_labor_table[df::job_type::StartingFistFight] = jlf_no_labor; - job_to_labor_table[df::job_type::CollectTaxes] = jlf_no_labor; - job_to_labor_table[df::job_type::GuardTaxCollector] = jlf_no_labor; - job_to_labor_table[df::job_type::CatchLiveLandAnimal] = jlf_const(df::unit_labor::HUNT); - job_to_labor_table[df::job_type::CatchLiveFish] = jlf_const(df::unit_labor::FISH); - job_to_labor_table[df::job_type::ReturnKill] = jlf_no_labor; - job_to_labor_table[df::job_type::CheckChest] = jlf_no_labor; - job_to_labor_table[df::job_type::StoreOwnedItem] = jlf_no_labor; - job_to_labor_table[df::job_type::PlaceItemInTomb] = jlf_const(df::unit_labor::HAUL_BODY); - job_to_labor_table[df::job_type::StoreItemInStockpile] = jlf_hauling; - job_to_labor_table[df::job_type::StoreItemInBag] = jlf_hauling; - job_to_labor_table[df::job_type::StoreItemInHospital] = jlf_hauling; - job_to_labor_table[df::job_type::StoreItemInChest] = jlf_hauling; - job_to_labor_table[df::job_type::StoreItemInCabinet] = jlf_hauling; - job_to_labor_table[df::job_type::StoreWeapon] = jlf_hauling; - job_to_labor_table[df::job_type::StoreArmor] = jlf_hauling; - job_to_labor_table[df::job_type::StoreItemInBarrel] = jlf_hauling; - job_to_labor_table[df::job_type::StoreItemInBin] = jlf_const(df::unit_labor::HAUL_ITEM); - job_to_labor_table[df::job_type::SeekArtifact] = jlf_no_labor; - job_to_labor_table[df::job_type::SeekInfant] = jlf_no_labor; - job_to_labor_table[df::job_type::AttendParty] = jlf_no_labor; - job_to_labor_table[df::job_type::GoShopping] = jlf_no_labor; - job_to_labor_table[df::job_type::GoShopping2] = jlf_no_labor; - job_to_labor_table[df::job_type::Clean] = jlf_const(df::unit_labor::CLEAN); - job_to_labor_table[df::job_type::Rest] = jlf_no_labor; - job_to_labor_table[df::job_type::PickupEquipment] = jlf_no_labor; - job_to_labor_table[df::job_type::DumpItem] = jlf_const(df::unit_labor::HAUL_REFUSE); - job_to_labor_table[df::job_type::StrangeMoodCrafter] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodJeweller] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodForge] = jlf_no_labor; + job_to_labor_table[df::job_type::CarveUpDownStaircase] = jlf_const(df::unit_labor::MINE); + job_to_labor_table[df::job_type::CarveRamp] = jlf_const(df::unit_labor::MINE); + job_to_labor_table[df::job_type::DigChannel] = jlf_const(df::unit_labor::MINE); + job_to_labor_table[df::job_type::FellTree] = jlf_const(df::unit_labor::CUTWOOD); + job_to_labor_table[df::job_type::GatherPlants] = jlf_const(df::unit_labor::HERBALIST); + job_to_labor_table[df::job_type::RemoveConstruction] = jlf_no_labor; + job_to_labor_table[df::job_type::CollectWebs] = jlf_const(df::unit_labor::WEAVER); + job_to_labor_table[df::job_type::BringItemToDepot] = jlf_no_labor; + job_to_labor_table[df::job_type::BringItemToShop] = jlf_no_labor; + job_to_labor_table[df::job_type::Eat] = jlf_no_labor; + job_to_labor_table[df::job_type::GetProvisions] = jlf_no_labor; + job_to_labor_table[df::job_type::Drink] = jlf_no_labor; + job_to_labor_table[df::job_type::Drink2] = jlf_no_labor; + job_to_labor_table[df::job_type::FillWaterskin] = jlf_no_labor; + job_to_labor_table[df::job_type::FillWaterskin2] = jlf_no_labor; + job_to_labor_table[df::job_type::Sleep] = jlf_no_labor; + job_to_labor_table[df::job_type::CollectSand] = jlf_const(df::unit_labor::HAUL_ITEM); + job_to_labor_table[df::job_type::Fish] = jlf_const(df::unit_labor::FISH); + job_to_labor_table[df::job_type::Hunt] = jlf_const(df::unit_labor::HUNT); + job_to_labor_table[df::job_type::HuntVermin] = jlf_no_labor; + job_to_labor_table[df::job_type::Kidnap] = jlf_no_labor; + job_to_labor_table[df::job_type::BeatCriminal] = jlf_no_labor; + job_to_labor_table[df::job_type::StartingFistFight] = jlf_no_labor; + job_to_labor_table[df::job_type::CollectTaxes] = jlf_no_labor; + job_to_labor_table[df::job_type::GuardTaxCollector] = jlf_no_labor; + job_to_labor_table[df::job_type::CatchLiveLandAnimal] = jlf_const(df::unit_labor::HUNT); + job_to_labor_table[df::job_type::CatchLiveFish] = jlf_const(df::unit_labor::FISH); + job_to_labor_table[df::job_type::ReturnKill] = jlf_no_labor; + job_to_labor_table[df::job_type::CheckChest] = jlf_no_labor; + job_to_labor_table[df::job_type::StoreOwnedItem] = jlf_no_labor; + job_to_labor_table[df::job_type::PlaceItemInTomb] = jlf_const(df::unit_labor::HAUL_BODY); + job_to_labor_table[df::job_type::StoreItemInStockpile] = jlf_hauling; + job_to_labor_table[df::job_type::StoreItemInBag] = jlf_hauling; + job_to_labor_table[df::job_type::StoreItemInHospital] = jlf_hauling; + job_to_labor_table[df::job_type::StoreItemInChest] = jlf_hauling; + job_to_labor_table[df::job_type::StoreItemInCabinet] = jlf_hauling; + job_to_labor_table[df::job_type::StoreWeapon] = jlf_hauling; + job_to_labor_table[df::job_type::StoreArmor] = jlf_hauling; + job_to_labor_table[df::job_type::StoreItemInBarrel] = jlf_hauling; + job_to_labor_table[df::job_type::StoreItemInBin] = jlf_const(df::unit_labor::HAUL_ITEM); + job_to_labor_table[df::job_type::SeekArtifact] = jlf_no_labor; + job_to_labor_table[df::job_type::SeekInfant] = jlf_no_labor; + job_to_labor_table[df::job_type::AttendParty] = jlf_no_labor; + job_to_labor_table[df::job_type::GoShopping] = jlf_no_labor; + job_to_labor_table[df::job_type::GoShopping2] = jlf_no_labor; + job_to_labor_table[df::job_type::Clean] = jlf_const(df::unit_labor::CLEAN); + job_to_labor_table[df::job_type::Rest] = jlf_no_labor; + job_to_labor_table[df::job_type::PickupEquipment] = jlf_no_labor; + job_to_labor_table[df::job_type::DumpItem] = jlf_const(df::unit_labor::HAUL_REFUSE); + job_to_labor_table[df::job_type::StrangeMoodCrafter] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodJeweller] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodForge] = jlf_no_labor; job_to_labor_table[df::job_type::StrangeMoodMagmaForge] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodBrooding] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodFell] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodCarpenter] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodMason] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodBowyer] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodTanner] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodWeaver] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodBrooding] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodFell] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodCarpenter] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodMason] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodBowyer] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodTanner] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodWeaver] = jlf_no_labor; job_to_labor_table[df::job_type::StrangeMoodGlassmaker] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodMechanics] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodMechanics] = jlf_no_labor; job_to_labor_table[df::job_type::ConstructBuilding] = new jlfunc_construct_bld(); - job_to_labor_table[df::job_type::ConstructDoor] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructFloodgate] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructBed] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructThrone] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructCoffin] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructTable] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructChest] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructBin] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructArmorStand] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructWeaponRack] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructCabinet] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructStatue] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructBlocks] = jlf_make_furniture; - job_to_labor_table[df::job_type::MakeRawGlass] = jlf_const(df::unit_labor::GLASSMAKER); - job_to_labor_table[df::job_type::MakeCrafts] = jlf_make_object; - job_to_labor_table[df::job_type::MintCoins] = jlf_const(df::unit_labor::METAL_CRAFT); - job_to_labor_table[df::job_type::CutGems] = jlf_const(df::unit_labor::CUT_GEM); - job_to_labor_table[df::job_type::CutGlass] = jlf_const(df::unit_labor::CUT_GEM); - job_to_labor_table[df::job_type::EncrustWithGems] = jlf_const(df::unit_labor::ENCRUST_GEM); - job_to_labor_table[df::job_type::EncrustWithGlass] = jlf_const(df::unit_labor::ENCRUST_GEM); - job_to_labor_table[df::job_type::DestroyBuilding] = new jlfunc_destroy_bld(); - job_to_labor_table[df::job_type::SmeltOre] = jlf_const(df::unit_labor::SMELT); - job_to_labor_table[df::job_type::MeltMetalObject] = jlf_const(df::unit_labor::SMELT); - job_to_labor_table[df::job_type::ExtractMetalStrands] = jlf_const(df::unit_labor::EXTRACT_STRAND); - job_to_labor_table[df::job_type::PlantSeeds] = jlf_const(df::unit_labor::PLANT); - job_to_labor_table[df::job_type::HarvestPlants] = jlf_const(df::unit_labor::PLANT); - job_to_labor_table[df::job_type::TrainHuntingAnimal] = jlf_const(df::unit_labor::ANIMALTRAIN); - job_to_labor_table[df::job_type::TrainWarAnimal] = jlf_const(df::unit_labor::ANIMALTRAIN); - job_to_labor_table[df::job_type::MakeWeapon] = jlf_make_weapon; - job_to_labor_table[df::job_type::ForgeAnvil] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructDoor] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructFloodgate] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructBed] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructThrone] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructCoffin] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructTable] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructChest] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructBin] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructArmorStand] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructWeaponRack] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructCabinet] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructStatue] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructBlocks] = jlf_make_furniture; + job_to_labor_table[df::job_type::MakeRawGlass] = jlf_const(df::unit_labor::GLASSMAKER); + job_to_labor_table[df::job_type::MakeCrafts] = jlf_make_object; + job_to_labor_table[df::job_type::MintCoins] = jlf_const(df::unit_labor::METAL_CRAFT); + job_to_labor_table[df::job_type::CutGems] = jlf_const(df::unit_labor::CUT_GEM); + job_to_labor_table[df::job_type::CutGlass] = jlf_const(df::unit_labor::CUT_GEM); + job_to_labor_table[df::job_type::EncrustWithGems] = jlf_const(df::unit_labor::ENCRUST_GEM); + job_to_labor_table[df::job_type::EncrustWithGlass] = jlf_const(df::unit_labor::ENCRUST_GEM); + job_to_labor_table[df::job_type::DestroyBuilding] = new jlfunc_destroy_bld(); + job_to_labor_table[df::job_type::SmeltOre] = jlf_const(df::unit_labor::SMELT); + job_to_labor_table[df::job_type::MeltMetalObject] = jlf_const(df::unit_labor::SMELT); + job_to_labor_table[df::job_type::ExtractMetalStrands] = jlf_const(df::unit_labor::EXTRACT_STRAND); + job_to_labor_table[df::job_type::PlantSeeds] = jlf_const(df::unit_labor::PLANT); + job_to_labor_table[df::job_type::HarvestPlants] = jlf_const(df::unit_labor::PLANT); + job_to_labor_table[df::job_type::TrainHuntingAnimal] = jlf_const(df::unit_labor::ANIMALTRAIN); + job_to_labor_table[df::job_type::TrainWarAnimal] = jlf_const(df::unit_labor::ANIMALTRAIN); + job_to_labor_table[df::job_type::MakeWeapon] = jlf_make_weapon; + job_to_labor_table[df::job_type::ForgeAnvil] = jlf_make_furniture; job_to_labor_table[df::job_type::ConstructCatapultParts] = jlf_const(df::unit_labor::SIEGECRAFT); job_to_labor_table[df::job_type::ConstructBallistaParts] = jlf_const(df::unit_labor::SIEGECRAFT); - job_to_labor_table[df::job_type::MakeArmor] = jlf_make_armor; - job_to_labor_table[df::job_type::MakeHelm] = jlf_make_armor; - job_to_labor_table[df::job_type::MakePants] = jlf_make_armor; - job_to_labor_table[df::job_type::StudWith] = jlf_make_object; - job_to_labor_table[df::job_type::ButcherAnimal] = jlf_const(df::unit_labor::BUTCHER); - job_to_labor_table[df::job_type::PrepareRawFish] = jlf_const(df::unit_labor::CLEAN_FISH); - job_to_labor_table[df::job_type::MillPlants] = jlf_const(df::unit_labor::MILLER); - job_to_labor_table[df::job_type::BaitTrap] = jlf_const(df::unit_labor::TRAPPER); - job_to_labor_table[df::job_type::MilkCreature] = jlf_const(df::unit_labor::MILK); - job_to_labor_table[df::job_type::MakeCheese] = jlf_const(df::unit_labor::MAKE_CHEESE); - job_to_labor_table[df::job_type::ProcessPlants] = jlf_const(df::unit_labor::PROCESS_PLANT); - job_to_labor_table[df::job_type::ProcessPlantsBag] = jlf_const(df::unit_labor::PROCESS_PLANT); - job_to_labor_table[df::job_type::ProcessPlantsVial] = jlf_const(df::unit_labor::PROCESS_PLANT); - job_to_labor_table[df::job_type::ProcessPlantsBarrel] = jlf_const(df::unit_labor::PROCESS_PLANT); - job_to_labor_table[df::job_type::PrepareMeal] = jlf_const(df::unit_labor::COOK); - job_to_labor_table[df::job_type::WeaveCloth] = jlf_const(df::unit_labor::WEAVER); - job_to_labor_table[df::job_type::MakeGloves] = jlf_make_armor; - job_to_labor_table[df::job_type::MakeShoes] = jlf_make_armor; - job_to_labor_table[df::job_type::MakeShield] = jlf_make_armor; - job_to_labor_table[df::job_type::MakeCage] = jlf_make_furniture; - job_to_labor_table[df::job_type::MakeChain] = jlf_make_object; - job_to_labor_table[df::job_type::MakeFlask] = jlf_make_object; - job_to_labor_table[df::job_type::MakeGoblet] = jlf_make_object; - job_to_labor_table[df::job_type::MakeInstrument] = jlf_make_object; - job_to_labor_table[df::job_type::MakeToy] = jlf_make_object; - job_to_labor_table[df::job_type::MakeAnimalTrap] = jlf_const(df::unit_labor::TRAPPER); - job_to_labor_table[df::job_type::MakeBarrel] = jlf_make_furniture; - job_to_labor_table[df::job_type::MakeBucket] = jlf_make_furniture; - job_to_labor_table[df::job_type::MakeWindow] = jlf_make_furniture; - job_to_labor_table[df::job_type::MakeTotem] = jlf_const(df::unit_labor::BONE_CARVE); - job_to_labor_table[df::job_type::MakeAmmo] = jlf_make_weapon; - job_to_labor_table[df::job_type::DecorateWith] = jlf_make_object; - job_to_labor_table[df::job_type::MakeBackpack] = jlf_make_object; - job_to_labor_table[df::job_type::MakeQuiver] = jlf_make_armor; + job_to_labor_table[df::job_type::MakeArmor] = jlf_make_armor; + job_to_labor_table[df::job_type::MakeHelm] = jlf_make_armor; + job_to_labor_table[df::job_type::MakePants] = jlf_make_armor; + job_to_labor_table[df::job_type::StudWith] = jlf_make_object; + job_to_labor_table[df::job_type::ButcherAnimal] = jlf_const(df::unit_labor::BUTCHER); + job_to_labor_table[df::job_type::PrepareRawFish] = jlf_const(df::unit_labor::CLEAN_FISH); + job_to_labor_table[df::job_type::MillPlants] = jlf_const(df::unit_labor::MILLER); + job_to_labor_table[df::job_type::BaitTrap] = jlf_const(df::unit_labor::TRAPPER); + job_to_labor_table[df::job_type::MilkCreature] = jlf_const(df::unit_labor::MILK); + job_to_labor_table[df::job_type::MakeCheese] = jlf_const(df::unit_labor::MAKE_CHEESE); + job_to_labor_table[df::job_type::ProcessPlants] = jlf_const(df::unit_labor::PROCESS_PLANT); + job_to_labor_table[df::job_type::ProcessPlantsBag] = jlf_const(df::unit_labor::PROCESS_PLANT); + job_to_labor_table[df::job_type::ProcessPlantsVial] = jlf_const(df::unit_labor::PROCESS_PLANT); + job_to_labor_table[df::job_type::ProcessPlantsBarrel] = jlf_const(df::unit_labor::PROCESS_PLANT); + job_to_labor_table[df::job_type::PrepareMeal] = jlf_const(df::unit_labor::COOK); + job_to_labor_table[df::job_type::WeaveCloth] = jlf_const(df::unit_labor::WEAVER); + job_to_labor_table[df::job_type::MakeGloves] = jlf_make_armor; + job_to_labor_table[df::job_type::MakeShoes] = jlf_make_armor; + job_to_labor_table[df::job_type::MakeShield] = jlf_make_armor; + job_to_labor_table[df::job_type::MakeCage] = jlf_make_furniture; + job_to_labor_table[df::job_type::MakeChain] = jlf_make_object; + job_to_labor_table[df::job_type::MakeFlask] = jlf_make_object; + job_to_labor_table[df::job_type::MakeGoblet] = jlf_make_object; + job_to_labor_table[df::job_type::MakeInstrument] = jlf_make_object; + job_to_labor_table[df::job_type::MakeToy] = jlf_make_object; + job_to_labor_table[df::job_type::MakeAnimalTrap] = jlf_const(df::unit_labor::TRAPPER); + job_to_labor_table[df::job_type::MakeBarrel] = jlf_make_furniture; + job_to_labor_table[df::job_type::MakeBucket] = jlf_make_furniture; + job_to_labor_table[df::job_type::MakeWindow] = jlf_make_furniture; + job_to_labor_table[df::job_type::MakeTotem] = jlf_const(df::unit_labor::BONE_CARVE); + job_to_labor_table[df::job_type::MakeAmmo] = jlf_make_weapon; + job_to_labor_table[df::job_type::DecorateWith] = jlf_make_object; + job_to_labor_table[df::job_type::MakeBackpack] = jlf_make_object; + job_to_labor_table[df::job_type::MakeQuiver] = jlf_make_armor; job_to_labor_table[df::job_type::MakeBallistaArrowHead] = jlf_make_weapon; - job_to_labor_table[df::job_type::AssembleSiegeAmmo] = jlf_const(df::unit_labor::SIEGECRAFT); - job_to_labor_table[df::job_type::LoadCatapult] = jlf_const(df::unit_labor::SIEGEOPERATE); - job_to_labor_table[df::job_type::LoadBallista] = jlf_const(df::unit_labor::SIEGEOPERATE); - job_to_labor_table[df::job_type::FireCatapult] = jlf_const(df::unit_labor::SIEGEOPERATE); - job_to_labor_table[df::job_type::FireBallista] = jlf_const(df::unit_labor::SIEGEOPERATE); - job_to_labor_table[df::job_type::ConstructMechanisms] = jlf_const(df::unit_labor::MECHANIC); - job_to_labor_table[df::job_type::MakeTrapComponent] = jlf_const(df::unit_labor::MECHANIC) ; - job_to_labor_table[df::job_type::LoadCageTrap] = jlf_const(df::unit_labor::MECHANIC) ; - job_to_labor_table[df::job_type::LoadStoneTrap] = jlf_const(df::unit_labor::MECHANIC) ; - job_to_labor_table[df::job_type::LoadWeaponTrap] = jlf_const(df::unit_labor::MECHANIC) ; - job_to_labor_table[df::job_type::CleanTrap] = jlf_const(df::unit_labor::MECHANIC) ; - job_to_labor_table[df::job_type::CastSpell] = jlf_no_labor; + job_to_labor_table[df::job_type::AssembleSiegeAmmo] = jlf_const(df::unit_labor::SIEGECRAFT); + job_to_labor_table[df::job_type::LoadCatapult] = jlf_const(df::unit_labor::SIEGEOPERATE); + job_to_labor_table[df::job_type::LoadBallista] = jlf_const(df::unit_labor::SIEGEOPERATE); + job_to_labor_table[df::job_type::FireCatapult] = jlf_const(df::unit_labor::SIEGEOPERATE); + job_to_labor_table[df::job_type::FireBallista] = jlf_const(df::unit_labor::SIEGEOPERATE); + job_to_labor_table[df::job_type::ConstructMechanisms] = jlf_const(df::unit_labor::MECHANIC); + job_to_labor_table[df::job_type::MakeTrapComponent] = jlf_const(df::unit_labor::MECHANIC) ; + job_to_labor_table[df::job_type::LoadCageTrap] = jlf_const(df::unit_labor::MECHANIC) ; + job_to_labor_table[df::job_type::LoadStoneTrap] = jlf_const(df::unit_labor::MECHANIC) ; + job_to_labor_table[df::job_type::LoadWeaponTrap] = jlf_const(df::unit_labor::MECHANIC) ; + job_to_labor_table[df::job_type::CleanTrap] = jlf_const(df::unit_labor::MECHANIC) ; + job_to_labor_table[df::job_type::CastSpell] = jlf_no_labor; job_to_labor_table[df::job_type::LinkBuildingToTrigger] = jlf_const(df::unit_labor::MECHANIC) ; - job_to_labor_table[df::job_type::PullLever] = jlf_no_labor; - job_to_labor_table[df::job_type::BrewDrink] = jlf_const(df::unit_labor::BREWER) ; - job_to_labor_table[df::job_type::ExtractFromPlants] = jlf_const(df::unit_labor::HERBALIST) ; - job_to_labor_table[df::job_type::ExtractFromRawFish] = jlf_const(df::unit_labor::DISSECT_FISH) ; + job_to_labor_table[df::job_type::PullLever] = jlf_no_labor; + job_to_labor_table[df::job_type::BrewDrink] = jlf_const(df::unit_labor::BREWER) ; + job_to_labor_table[df::job_type::ExtractFromPlants] = jlf_const(df::unit_labor::HERBALIST) ; + job_to_labor_table[df::job_type::ExtractFromRawFish] = jlf_const(df::unit_labor::DISSECT_FISH) ; job_to_labor_table[df::job_type::ExtractFromLandAnimal] = jlf_const(df::unit_labor::DISSECT_VERMIN) ; - job_to_labor_table[df::job_type::TameVermin] = jlf_const(df::unit_labor::ANIMALTRAIN) ; - job_to_labor_table[df::job_type::TameAnimal] = jlf_const(df::unit_labor::ANIMALTRAIN) ; - job_to_labor_table[df::job_type::ChainAnimal] = jlf_no_labor; - job_to_labor_table[df::job_type::UnchainAnimal] = jlf_no_labor; - job_to_labor_table[df::job_type::UnchainPet] = jlf_no_labor; - job_to_labor_table[df::job_type::ReleaseLargeCreature] = jlf_no_labor; - job_to_labor_table[df::job_type::ReleasePet] = jlf_no_labor; - job_to_labor_table[df::job_type::ReleaseSmallCreature] = jlf_no_labor; - job_to_labor_table[df::job_type::HandleSmallCreature] = jlf_no_labor; - job_to_labor_table[df::job_type::HandleLargeCreature] = jlf_no_labor; - job_to_labor_table[df::job_type::CageLargeCreature] = jlf_no_labor; - job_to_labor_table[df::job_type::CageSmallCreature] = jlf_no_labor; - job_to_labor_table[df::job_type::RecoverWounded] = jlf_const(df::unit_labor::RECOVER_WOUNDED); - job_to_labor_table[df::job_type::DiagnosePatient] = jlf_const(df::unit_labor::DIAGNOSE) ; - job_to_labor_table[df::job_type::ImmobilizeBreak] = jlf_const(df::unit_labor::BONE_SETTING) ; - job_to_labor_table[df::job_type::DressWound] = jlf_const(df::unit_labor::DRESSING_WOUNDS) ; - job_to_labor_table[df::job_type::CleanPatient] = jlf_const(df::unit_labor::DRESSING_WOUNDS) ; - job_to_labor_table[df::job_type::Surgery] = jlf_const(df::unit_labor::SURGERY) ; - job_to_labor_table[df::job_type::Suture] = jlf_const(df::unit_labor::SUTURING); - job_to_labor_table[df::job_type::SetBone] = jlf_const(df::unit_labor::BONE_SETTING) ; - job_to_labor_table[df::job_type::PlaceInTraction] = jlf_const(df::unit_labor::BONE_SETTING) ; - job_to_labor_table[df::job_type::DrainAquarium] = jlf_no_labor; - job_to_labor_table[df::job_type::FillAquarium] = jlf_no_labor; - job_to_labor_table[df::job_type::FillPond] = jlf_no_labor; - job_to_labor_table[df::job_type::GiveWater] = jlf_const(df::unit_labor::FEED_WATER_CIVILIANS) ; - job_to_labor_table[df::job_type::GiveFood] = jlf_const(df::unit_labor::FEED_WATER_CIVILIANS) ; - job_to_labor_table[df::job_type::GiveWater2] = jlf_no_labor; - job_to_labor_table[df::job_type::GiveFood2] = jlf_no_labor; - job_to_labor_table[df::job_type::RecoverPet] = jlf_no_labor; - job_to_labor_table[df::job_type::PitLargeAnimal] = jlf_no_labor; - job_to_labor_table[df::job_type::PitSmallAnimal] = jlf_no_labor; - job_to_labor_table[df::job_type::SlaughterAnimal] = jlf_const(df::unit_labor::BUTCHER); - job_to_labor_table[df::job_type::MakeCharcoal] = jlf_const(df::unit_labor::BURN_WOOD); - job_to_labor_table[df::job_type::MakeAsh] = jlf_const(df::unit_labor::BURN_WOOD); - job_to_labor_table[df::job_type::MakeLye] = jlf_const(df::unit_labor::LYE_MAKING); - job_to_labor_table[df::job_type::MakePotashFromLye] = jlf_const(df::unit_labor::POTASH_MAKING); - job_to_labor_table[df::job_type::FertilizeField] = jlf_const(df::unit_labor::PLANT); - job_to_labor_table[df::job_type::MakePotashFromAsh] = jlf_const(df::unit_labor::POTASH_MAKING); - job_to_labor_table[df::job_type::DyeThread] = jlf_const(df::unit_labor::DYER); - job_to_labor_table[df::job_type::DyeCloth] = jlf_const(df::unit_labor::DYER); - job_to_labor_table[df::job_type::SewImage] = jlf_make_object; - job_to_labor_table[df::job_type::MakePipeSection] = jlf_make_furniture; - job_to_labor_table[df::job_type::OperatePump] = jlf_const(df::unit_labor::OPERATE_PUMP); - job_to_labor_table[df::job_type::ManageWorkOrders] = jlf_no_labor; + job_to_labor_table[df::job_type::TameVermin] = jlf_const(df::unit_labor::ANIMALTRAIN) ; + job_to_labor_table[df::job_type::TameAnimal] = jlf_const(df::unit_labor::ANIMALTRAIN) ; + job_to_labor_table[df::job_type::ChainAnimal] = jlf_no_labor; + job_to_labor_table[df::job_type::UnchainAnimal] = jlf_no_labor; + job_to_labor_table[df::job_type::UnchainPet] = jlf_no_labor; + job_to_labor_table[df::job_type::ReleaseLargeCreature] = jlf_no_labor; + job_to_labor_table[df::job_type::ReleasePet] = jlf_no_labor; + job_to_labor_table[df::job_type::ReleaseSmallCreature] = jlf_no_labor; + job_to_labor_table[df::job_type::HandleSmallCreature] = jlf_no_labor; + job_to_labor_table[df::job_type::HandleLargeCreature] = jlf_no_labor; + job_to_labor_table[df::job_type::CageLargeCreature] = jlf_no_labor; + job_to_labor_table[df::job_type::CageSmallCreature] = jlf_no_labor; + job_to_labor_table[df::job_type::RecoverWounded] = jlf_const(df::unit_labor::RECOVER_WOUNDED); + job_to_labor_table[df::job_type::DiagnosePatient] = jlf_const(df::unit_labor::DIAGNOSE) ; + job_to_labor_table[df::job_type::ImmobilizeBreak] = jlf_const(df::unit_labor::BONE_SETTING) ; + job_to_labor_table[df::job_type::DressWound] = jlf_const(df::unit_labor::DRESSING_WOUNDS) ; + job_to_labor_table[df::job_type::CleanPatient] = jlf_const(df::unit_labor::DRESSING_WOUNDS) ; + job_to_labor_table[df::job_type::Surgery] = jlf_const(df::unit_labor::SURGERY) ; + job_to_labor_table[df::job_type::Suture] = jlf_const(df::unit_labor::SUTURING); + job_to_labor_table[df::job_type::SetBone] = jlf_const(df::unit_labor::BONE_SETTING) ; + job_to_labor_table[df::job_type::PlaceInTraction] = jlf_const(df::unit_labor::BONE_SETTING) ; + job_to_labor_table[df::job_type::DrainAquarium] = jlf_no_labor; + job_to_labor_table[df::job_type::FillAquarium] = jlf_no_labor; + job_to_labor_table[df::job_type::FillPond] = jlf_no_labor; + job_to_labor_table[df::job_type::GiveWater] = jlf_const(df::unit_labor::FEED_WATER_CIVILIANS) ; + job_to_labor_table[df::job_type::GiveFood] = jlf_const(df::unit_labor::FEED_WATER_CIVILIANS) ; + job_to_labor_table[df::job_type::GiveWater2] = jlf_no_labor; + job_to_labor_table[df::job_type::GiveFood2] = jlf_no_labor; + job_to_labor_table[df::job_type::RecoverPet] = jlf_no_labor; + job_to_labor_table[df::job_type::PitLargeAnimal] = jlf_no_labor; + job_to_labor_table[df::job_type::PitSmallAnimal] = jlf_no_labor; + job_to_labor_table[df::job_type::SlaughterAnimal] = jlf_const(df::unit_labor::BUTCHER); + job_to_labor_table[df::job_type::MakeCharcoal] = jlf_const(df::unit_labor::BURN_WOOD); + job_to_labor_table[df::job_type::MakeAsh] = jlf_const(df::unit_labor::BURN_WOOD); + job_to_labor_table[df::job_type::MakeLye] = jlf_const(df::unit_labor::LYE_MAKING); + job_to_labor_table[df::job_type::MakePotashFromLye] = jlf_const(df::unit_labor::POTASH_MAKING); + job_to_labor_table[df::job_type::FertilizeField] = jlf_const(df::unit_labor::PLANT); + job_to_labor_table[df::job_type::MakePotashFromAsh] = jlf_const(df::unit_labor::POTASH_MAKING); + job_to_labor_table[df::job_type::DyeThread] = jlf_const(df::unit_labor::DYER); + job_to_labor_table[df::job_type::DyeCloth] = jlf_const(df::unit_labor::DYER); + job_to_labor_table[df::job_type::SewImage] = jlf_make_object; + job_to_labor_table[df::job_type::MakePipeSection] = jlf_make_furniture; + job_to_labor_table[df::job_type::OperatePump] = jlf_const(df::unit_labor::OPERATE_PUMP); + job_to_labor_table[df::job_type::ManageWorkOrders] = jlf_no_labor; job_to_labor_table[df::job_type::UpdateStockpileRecords] = jlf_no_labor; - job_to_labor_table[df::job_type::TradeAtDepot] = jlf_no_labor; - job_to_labor_table[df::job_type::ConstructHatchCover] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructGrate] = jlf_make_furniture; - job_to_labor_table[df::job_type::RemoveStairs] = jlf_const(df::unit_labor::MINE); - job_to_labor_table[df::job_type::ConstructQuern] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructMillstone] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructSplint] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructCrutch] = jlf_make_furniture; + job_to_labor_table[df::job_type::TradeAtDepot] = jlf_no_labor; + job_to_labor_table[df::job_type::ConstructHatchCover] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructGrate] = jlf_make_furniture; + job_to_labor_table[df::job_type::RemoveStairs] = jlf_const(df::unit_labor::MINE); + job_to_labor_table[df::job_type::ConstructQuern] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructMillstone] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructSplint] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructCrutch] = jlf_make_furniture; job_to_labor_table[df::job_type::ConstructTractionBench] = jlf_const(df::unit_labor::MECHANIC); - job_to_labor_table[df::job_type::CleanSelf] = jlf_no_labor; - job_to_labor_table[df::job_type::BringCrutch] = jlf_const(df::unit_labor::BONE_SETTING); - job_to_labor_table[df::job_type::ApplyCast] = jlf_const(df::unit_labor::BONE_SETTING); + job_to_labor_table[df::job_type::CleanSelf] = jlf_no_labor; + job_to_labor_table[df::job_type::BringCrutch] = jlf_const(df::unit_labor::BONE_SETTING); + job_to_labor_table[df::job_type::ApplyCast] = jlf_const(df::unit_labor::BONE_SETTING); job_to_labor_table[df::job_type::CustomReaction] = new jlfunc_custom(); - job_to_labor_table[df::job_type::ConstructSlab] = jlf_make_furniture; - job_to_labor_table[df::job_type::EngraveSlab] = jlf_const(df::unit_labor::DETAIL); - job_to_labor_table[df::job_type::ShearCreature] = jlf_const(df::unit_labor::SHEARER); - job_to_labor_table[df::job_type::SpinThread] = jlf_const(df::unit_labor::SPINNER); - job_to_labor_table[df::job_type::PenLargeAnimal] = jlf_no_labor; - job_to_labor_table[df::job_type::PenSmallAnimal] = jlf_no_labor; - job_to_labor_table[df::job_type::MakeTool] = jlf_make_furniture; - job_to_labor_table[df::job_type::CollectClay] = jlf_const(df::unit_labor::POTTERY); - job_to_labor_table[df::job_type::InstallColonyInHive] = jlf_const(df::unit_labor::BEEKEEPING); - job_to_labor_table[df::job_type::CollectHiveProducts] = jlf_const(df::unit_labor::BEEKEEPING); - job_to_labor_table[df::job_type::CauseTrouble] = jlf_no_labor; - job_to_labor_table[df::job_type::DrinkBlood] = jlf_no_labor; - job_to_labor_table[df::job_type::ReportCrime] = jlf_no_labor; - job_to_labor_table[df::job_type::ExecuteCriminal] = jlf_no_labor; - job_to_labor_table[df::job_type::TrainAnimal] = jlf_const(df::unit_labor::ANIMALTRAIN); - job_to_labor_table[df::job_type::CarveTrack] = jlf_const(df::unit_labor::DETAIL); - job_to_labor_table[df::job_type::PushTrackVehicle] = jlf_const(df::unit_labor::PUSH_HAUL_VEHICLE); - job_to_labor_table[df::job_type::PlaceTrackVehicle] = jlf_const(df::unit_labor::PUSH_HAUL_VEHICLE); + job_to_labor_table[df::job_type::ConstructSlab] = jlf_make_furniture; + job_to_labor_table[df::job_type::EngraveSlab] = jlf_const(df::unit_labor::DETAIL); + job_to_labor_table[df::job_type::ShearCreature] = jlf_const(df::unit_labor::SHEARER); + job_to_labor_table[df::job_type::SpinThread] = jlf_const(df::unit_labor::SPINNER); + job_to_labor_table[df::job_type::PenLargeAnimal] = jlf_no_labor; + job_to_labor_table[df::job_type::PenSmallAnimal] = jlf_no_labor; + job_to_labor_table[df::job_type::MakeTool] = jlf_make_furniture; + job_to_labor_table[df::job_type::CollectClay] = jlf_const(df::unit_labor::POTTERY); + job_to_labor_table[df::job_type::InstallColonyInHive] = jlf_const(df::unit_labor::BEEKEEPING); + job_to_labor_table[df::job_type::CollectHiveProducts] = jlf_const(df::unit_labor::BEEKEEPING); + job_to_labor_table[df::job_type::CauseTrouble] = jlf_no_labor; + job_to_labor_table[df::job_type::DrinkBlood] = jlf_no_labor; + job_to_labor_table[df::job_type::ReportCrime] = jlf_no_labor; + job_to_labor_table[df::job_type::ExecuteCriminal] = jlf_no_labor; + job_to_labor_table[df::job_type::TrainAnimal] = jlf_const(df::unit_labor::ANIMALTRAIN); + job_to_labor_table[df::job_type::CarveTrack] = jlf_const(df::unit_labor::DETAIL); + job_to_labor_table[df::job_type::PushTrackVehicle] = jlf_const(df::unit_labor::PUSH_HAUL_VEHICLE); + job_to_labor_table[df::job_type::PlaceTrackVehicle] = jlf_const(df::unit_labor::PUSH_HAUL_VEHICLE); job_to_labor_table[df::job_type::StoreItemInVehicle] = jlf_const(df::unit_labor::PUSH_HAUL_VEHICLE); }; @@ -1344,7 +1344,7 @@ public: } } return df::unit_labor::NONE; - } + } df::unit_labor labor; @@ -1505,7 +1505,7 @@ DFhackCExport command_result plugin_init ( color_ostream &out, std::vector designation[x][y].bits.dig; - if (dig != df::enums::tile_dig_designation::No) + if (dig != df::enums::tile_dig_designation::No) { df::tiletype tt = bl->tiletype[x][y]; df::tiletype_shape tts = ENUM_ATTR(tiletype, shape, tt); - switch (tts) + switch (tts) { case df::enums::tiletype_shape::TREE: tree_count++; break; @@ -1687,7 +1687,7 @@ private: if (item->flags.whole & bad_flags.whole) continue; - if (!item->isWeapon()) + if (!item->isWeapon()) continue; df::itemdef_weaponst* weapondef = ((df::item_weaponst*)item)->subtype; @@ -1710,7 +1710,7 @@ private: for (df::job_list_link* jll = world->job_list.next; jll; jll = jll->next) { df::job* j = jll->item; - if (!j) + if (!j) continue; if (j->flags.bits.suspend || j->flags.bits.item_lost) @@ -1727,7 +1727,7 @@ private: bld = ((df::general_ref_building_holderst *)(j->general_refs[r]))->building_id; } - if (bld != -1) + if (bld != -1) { df::building* b = binsearch_in_vector(world->buildings.all, bld); int fjid = -1; @@ -1748,7 +1748,7 @@ private: df::unit_labor labor = labor_mapper->find_job_labor (j); - if (labor != df::unit_labor::NONE) + if (labor != df::unit_labor::NONE) { labor_needed[labor]++; @@ -1903,7 +1903,7 @@ private: FOR_ENUM_ITEMS(unit_labor, l) { - if (l == df::unit_labor::NONE) + if (l == df::unit_labor::NONE) continue; if (dwarf->dwarf->status.labors[l]) if (state == IDLE) @@ -1917,27 +1917,27 @@ private: out.print("Dwarf \"%s\": state %s %d\n", dwarf->dwarf->name.first_name.c_str(), state_names[dwarf->state], dwarf->clear_all); // determine if dwarf has medical needs - if (dwarf->dwarf->health) + if (dwarf->dwarf->health) { - if (dwarf->dwarf->health->flags.bits.needs_recovery) + if (dwarf->dwarf->health->flags.bits.needs_recovery) cnt_recover_wounded++; - if (dwarf->dwarf->health->flags.bits.rq_diagnosis) + if (dwarf->dwarf->health->flags.bits.rq_diagnosis) cnt_diagnosis++; - if (dwarf->dwarf->health->flags.bits.rq_immobilize) + if (dwarf->dwarf->health->flags.bits.rq_immobilize) cnt_immobilize++; - if (dwarf->dwarf->health->flags.bits.rq_dressing) + if (dwarf->dwarf->health->flags.bits.rq_dressing) cnt_dressing++; - if (dwarf->dwarf->health->flags.bits.rq_cleaning) + if (dwarf->dwarf->health->flags.bits.rq_cleaning) cnt_cleaning++; - if (dwarf->dwarf->health->flags.bits.rq_surgery) + if (dwarf->dwarf->health->flags.bits.rq_surgery) cnt_surgery++; - if (dwarf->dwarf->health->flags.bits.rq_suture) + if (dwarf->dwarf->health->flags.bits.rq_suture) cnt_suture++; - if (dwarf->dwarf->health->flags.bits.rq_setting) + if (dwarf->dwarf->health->flags.bits.rq_setting) cnt_setting++; - if (dwarf->dwarf->health->flags.bits.rq_traction) + if (dwarf->dwarf->health->flags.bits.rq_traction) cnt_traction++; - if (dwarf->dwarf->health->flags.bits.rq_crutch) + if (dwarf->dwarf->health->flags.bits.rq_crutch) cnt_crutch++; } @@ -1956,7 +1956,7 @@ private: df::job_skill skill = labor_to_skill[labor]; if (skill != df::job_skill::NONE) { - int skill_level = Units::getNominalSkill(dwarf->dwarf, skill, false); + int skill_level = Units::getNominalSkill(dwarf->dwarf, skill, false); high_skill = std::max(high_skill, skill_level); } } @@ -1976,19 +1976,19 @@ private: if (weaponsk == df::job_skill::AXE) { dwarf->has_tool[TOOL_AXE] = true; - if (state != IDLE) + if (state != IDLE) tool_count[TOOL_AXE]--; } else if (weaponsk == df::job_skill::MINING) { dwarf->has_tool[TOOL_PICK] = 1; - if (state != IDLE) + if (state != IDLE) tool_count[TOOL_PICK]--; } else if (rangesk == df::job_skill::CROSSBOW) { dwarf->has_tool[TOOL_CROSSBOW] = 1; - if (state != IDLE) + if (state != IDLE) tool_count[TOOL_CROSSBOW]--; } } @@ -1996,11 +1996,11 @@ private: // clear labors of dwarfs with clear_all set - if (dwarf->clear_all) + if (dwarf->clear_all) { FOR_ENUM_ITEMS(unit_labor, labor) { - if (labor == unit_labor::NONE) + if (labor == unit_labor::NONE) continue; dwarf->clear_labor(labor); @@ -2012,7 +2012,7 @@ private: } } - } + } public: void process() @@ -2045,7 +2045,7 @@ public: count_map_designations(); - // collect current job list + // collect current job list collect_job_list(); @@ -2067,7 +2067,7 @@ public: // add job entries for health care labor_needed[df::unit_labor::RECOVER_WOUNDED] += cnt_recover_wounded; - labor_needed[df::unit_labor::DIAGNOSE] += cnt_diagnosis; + labor_needed[df::unit_labor::DIAGNOSE] += cnt_diagnosis; labor_needed[df::unit_labor::BONE_SETTING] += cnt_immobilize; labor_needed[df::unit_labor::DRESSING_WOUNDS] += cnt_dressing; labor_needed[df::unit_labor::DRESSING_WOUNDS] += cnt_cleaning; @@ -2084,7 +2084,7 @@ public: labor_needed[df::unit_labor::HAUL_STONE] += world->stockpile.num_jobs[1]; labor_needed[df::unit_labor::HAUL_WOOD] += world->stockpile.num_jobs[2]; labor_needed[df::unit_labor::HAUL_ITEM] += world->stockpile.num_jobs[3]; - labor_needed[df::unit_labor::HAUL_ITEM] += world->stockpile.num_jobs[4]; + labor_needed[df::unit_labor::HAUL_ITEM] += world->stockpile.num_jobs[4]; labor_needed[df::unit_labor::HAUL_BODY] += world->stockpile.num_jobs[5]; labor_needed[df::unit_labor::HAUL_FOOD] += world->stockpile.num_jobs[6]; labor_needed[df::unit_labor::HAUL_REFUSE] += world->stockpile.num_jobs[7]; @@ -2094,12 +2094,12 @@ public: // add entries for vehicle hauling for (auto v = world->vehicles.all.begin(); v != world->vehicles.all.end(); v++) - if ((*v)->route_id != -1) + if ((*v)->route_id != -1) labor_needed[df::unit_labor::PUSH_HAUL_VEHICLE]++; // add fishing & hunting - labor_needed[df::unit_labor::FISH] = + labor_needed[df::unit_labor::FISH] = (isOptionEnabled(CF_ALLOW_FISHING) && has_fishery) ? 1 : 0; labor_needed[df::unit_labor::HUNT] = @@ -2141,7 +2141,7 @@ public: { out.print ("labor_needed [%s] = %d, outside = %d, idle = %d\n", ENUM_KEY_STR(unit_labor, i->first).c_str(), i->second, labor_outside[i->first], labor_infos[i->first].idle_dwarfs); - } + } } priority_queue> pq; @@ -2152,7 +2152,7 @@ public: if (labor_infos[l].maximum_dwarfs() > 0 && i->second > labor_infos[l].maximum_dwarfs()) i->second = labor_infos[l].maximum_dwarfs(); - if (i->second > 0) + if (i->second > 0) { int priority = labor_infos[l].priority(); priority += labor_infos[l].time_since_last_assigned()/12; @@ -2169,7 +2169,7 @@ public: int av = available_dwarfs.size(); - while (!pq.empty() && av > 0) + while (!pq.empty() && av > 0) { df::unit_labor labor = pq.top().second; int priority = pq.top().first; @@ -2180,7 +2180,7 @@ public: if (print_debug) out.print("Will assign: %s priority %d (%d)\n", ENUM_KEY_STR(unit_labor, labor).c_str(), priority, to_assign[labor]); - if (--labor_needed[labor] > 0) + if (--labor_needed[labor] > 0) { priority /= 2; pq.push(make_pair(priority, labor)); @@ -2204,9 +2204,9 @@ public: int best_score = INT_MIN; df::unit_labor best_labor = df::unit_labor::CLEAN; - for (auto j = to_assign.begin(); j != to_assign.end(); j++) + for (auto j = to_assign.begin(); j != to_assign.end(); j++) { - if (j->second <= 0) + if (j->second <= 0) continue; df::unit_labor labor = j->first; @@ -2217,7 +2217,7 @@ public: dwarf_info_t* d = (*k); int skill_level = 0; int xp = 0; - if (skill != df::job_skill::NONE) + if (skill != df::job_skill::NONE) { skill_level = Units::getEffectiveSkill(d->dwarf, skill); xp = Units::getExperience(d->dwarf, skill, false); @@ -2229,7 +2229,7 @@ public: else score += 1000; if (default_labor_infos[labor].tool != TOOL_NONE && - d->has_tool[default_labor_infos[labor].tool]) + d->has_tool[default_labor_infos[labor].tool]) score += 5000; if (d->has_children && labor_outside[labor]) score -= 15000; @@ -2368,7 +2368,7 @@ void print_labor (df::unit_labor labor, color_ostream &out) out << "priority " << labor_infos[labor].priority() << ", maximum " << labor_infos[labor].maximum_dwarfs() << ", currently " << labor_infos[labor].active_dwarfs << " dwarfs (" - << labor_infos[labor].busy_dwarfs << " busy, " + << labor_infos[labor].busy_dwarfs << " busy, " << labor_infos[labor].idle_dwarfs << " idle)" << endl; } @@ -2423,7 +2423,7 @@ command_result autolabor (color_ostream &out, std::vector & parame bool enable = (parameters[0] == "enable"); return plugin_enable(out, enable); } - else if (parameters.size() == 3 && + else if (parameters.size() == 3 && (parameters[0] == "max" || parameters[0] == "priority")) { if (!enable_autolabor) @@ -2444,7 +2444,7 @@ command_result autolabor (color_ostream &out, std::vector & parame if (parameters[2] == "none") v = 0; - else + else v = atoi (parameters[2].c_str()); if (parameters[0] == "max") diff --git a/plugins/devel/buildprobe.cpp b/plugins/devel/buildprobe.cpp index 17e95237f..ca7a2ad96 100644 --- a/plugins/devel/buildprobe.cpp +++ b/plugins/devel/buildprobe.cpp @@ -91,7 +91,7 @@ command_result writeFlag (color_ostream &out, vector & parameters) case '7': value = parameters[0][0] - '0'; break; - + default: out.print("Invalid value specified\n"); return CR_FAILURE; diff --git a/plugins/devel/eventExample.cpp b/plugins/devel/eventExample.cpp index 5a827f18e..35c5253b4 100644 --- a/plugins/devel/eventExample.cpp +++ b/plugins/devel/eventExample.cpp @@ -70,7 +70,7 @@ command_result eventExample(color_ostream& out, vector& parameters) { } } */ - + EventManager::EventHandler initiateHandler(jobInitiated, 1); EventManager::EventHandler completeHandler(jobCompleted, 0); EventManager::EventHandler timeHandler(timePassed, 1); @@ -82,7 +82,7 @@ command_result eventExample(color_ostream& out, vector& parameters) { EventManager::EventHandler invasionHandler(invasion, 1000); EventManager::EventHandler unitAttackHandler(unitAttack, 1); EventManager::unregisterAll(plugin_self); - + EventManager::registerListener(EventManager::EventType::JOB_INITIATED, initiateHandler, plugin_self); EventManager::registerListener(EventManager::EventType::JOB_COMPLETED, completeHandler, plugin_self); EventManager::registerListener(EventManager::EventType::UNIT_DEATH, deathHandler, plugin_self); @@ -105,7 +105,7 @@ command_result eventExample(color_ostream& out, vector& parameters) { timeHandler.freq = t; EventManager::unregister(EventManager::EventType::TICK, timeHandler, plugin_self); EventManager::unregister(EventManager::EventType::TICK, timeHandler, plugin_self); - + out.print("Events registered.\n"); return CR_OK; } @@ -159,7 +159,7 @@ void construction(color_ostream& out, void* ptr) { out.print(" construction destroyed\n"); else out.print(" construction created\n"); - + } void syndrome(color_ostream& out, void* ptr) { diff --git a/plugins/devel/itemhacks.cpp b/plugins/devel/itemhacks.cpp index af17a8acb..b2c1918c6 100644 --- a/plugins/devel/itemhacks.cpp +++ b/plugins/devel/itemhacks.cpp @@ -65,12 +65,12 @@ public: t_itemflags &f = itm->origin->flags; - return (f.unk1 || f.unk2 || f.unk3 || f.unk4 || + return (f.unk1 || f.unk2 || f.unk3 || f.unk4 || f.unk6 || f.unk7 || f.unk10 || f.unk11); } - virtual void postPrint(DFHack::dfh_item *itm) + virtual void postPrint(DFHack::dfh_item *itm) { std::vector flags; diff --git a/plugins/devel/memview.cpp b/plugins/devel/memview.cpp index 6a4baa295..171f4b854 100644 --- a/plugins/devel/memview.cpp +++ b/plugins/devel/memview.cpp @@ -1,189 +1,189 @@ -#include "Core.h" -#include "Console.h" -#include "PluginManager.h" -#include "MemAccess.h" -#include "MiscUtils.h" -#include //not sure if correct -#include -#include -#include - -using std::vector; -using std::string; -using namespace DFHack; - -uint64_t timeLast=0; -static tthread::mutex* mymutex=0; - -DFHACK_PLUGIN_IS_ENABLED(is_enabled); - -struct memory_data -{ - void * addr; - size_t len; - size_t refresh; - int state; - uint8_t *buf,*lbuf; - vector ranges; -}memdata; -enum HEXVIEW_STATES -{ - STATE_OFF,STATE_ON -}; -command_result memview (color_ostream &out, vector & parameters); - -DFHACK_PLUGIN("memview"); - -DFhackCExport command_result plugin_init (color_ostream &out, std::vector &commands) -{ - commands.push_back(PluginCommand("memview","Shows memory in real time. Params: adrr length refresh_rate. If addr==0 then stop viewing",memview)); - memdata.state=STATE_OFF; - mymutex=new tthread::mutex; - return CR_OK; -} -size_t convert(const std::string& p,bool ishex=false) -{ - size_t ret; - std::stringstream conv; - if(ishex) - conv<>ret; - return ret; -} -bool isAddr(uint32_t *trg,vector & ranges) -{ - if(trg[0]%4==0) - for(size_t i=0;i & ranges) -{ - const size_t page_size=16; - - for(size_t i=0;i31)&&(buf[j+i]<128)) //only printable ascii - con.print("%c",buf[j+i]); - else - con.print("."); - //con.print("\n"); - } - con.print("\n"); -} -void Deinit() -{ - if(memdata.state==STATE_ON) - { - is_enabled = false; - memdata.state=STATE_OFF; - delete [] memdata.buf; - delete [] memdata.lbuf; - } -} -DFhackCExport command_result plugin_onupdate (color_ostream &out) -{ - - mymutex->lock(); - if(memdata.state==STATE_OFF) - { - mymutex->unlock(); - return CR_OK; - } - //Console &con=out; - uint64_t time2 = GetTimeMs64(); - uint64_t delta = time2-timeLast; - - if(memdata.refresh!=0) - if(deltaunlock(); - return CR_OK; - } - timeLast = time2; - - Core::getInstance().p->read(memdata.addr,memdata.len,memdata.buf); - outputHex(memdata.buf,memdata.lbuf,memdata.len,(size_t)memdata.addr,out,memdata.ranges); - memcpy(memdata.lbuf, memdata.buf, memdata.len); - if(memdata.refresh==0) - Deinit(); - mymutex->unlock(); - return CR_OK; - -} -command_result memview (color_ostream &out, vector & parameters) -{ - mymutex->lock(); - Core::getInstance().p->getMemRanges(memdata.ranges); - memdata.addr=(void *)convert(parameters[0],true); - if(memdata.addr==0) - { - Deinit(); - memdata.state=STATE_OFF; - is_enabled = false; - mymutex->unlock(); - return CR_OK; - } - else - { - Deinit(); - bool isValid=false; - for(size_t i=0;iunlock(); - return CR_OK; - } - is_enabled = true; - memdata.state=STATE_ON; - } - if(parameters.size()>1) - memdata.len=convert(parameters[1]); - else - memdata.len=20*16; - - if(parameters.size()>2) - memdata.refresh=convert(parameters[2]); - else - memdata.refresh=0; - - memdata.buf=new uint8_t[memdata.len]; - memdata.lbuf=new uint8_t[memdata.len]; - Core::getInstance().p->getMemRanges(memdata.ranges); - mymutex->unlock(); - return CR_OK; -} -DFhackCExport command_result plugin_shutdown (color_ostream &out) -{ - mymutex->lock(); - Deinit(); - delete mymutex; - mymutex->unlock(); - return CR_OK; -} +#include "Core.h" +#include "Console.h" +#include "PluginManager.h" +#include "MemAccess.h" +#include "MiscUtils.h" +#include //not sure if correct +#include +#include +#include + +using std::vector; +using std::string; +using namespace DFHack; + +uint64_t timeLast=0; +static tthread::mutex* mymutex=0; + +DFHACK_PLUGIN_IS_ENABLED(is_enabled); + +struct memory_data +{ + void * addr; + size_t len; + size_t refresh; + int state; + uint8_t *buf,*lbuf; + vector ranges; +}memdata; +enum HEXVIEW_STATES +{ + STATE_OFF,STATE_ON +}; +command_result memview (color_ostream &out, vector & parameters); + +DFHACK_PLUGIN("memview"); + +DFhackCExport command_result plugin_init (color_ostream &out, std::vector &commands) +{ + commands.push_back(PluginCommand("memview","Shows memory in real time. Params: adrr length refresh_rate. If addr==0 then stop viewing",memview)); + memdata.state=STATE_OFF; + mymutex=new tthread::mutex; + return CR_OK; +} +size_t convert(const std::string& p,bool ishex=false) +{ + size_t ret; + std::stringstream conv; + if(ishex) + conv<>ret; + return ret; +} +bool isAddr(uint32_t *trg,vector & ranges) +{ + if(trg[0]%4==0) + for(size_t i=0;i & ranges) +{ + const size_t page_size=16; + + for(size_t i=0;i31)&&(buf[j+i]<128)) //only printable ascii + con.print("%c",buf[j+i]); + else + con.print("."); + //con.print("\n"); + } + con.print("\n"); +} +void Deinit() +{ + if(memdata.state==STATE_ON) + { + is_enabled = false; + memdata.state=STATE_OFF; + delete [] memdata.buf; + delete [] memdata.lbuf; + } +} +DFhackCExport command_result plugin_onupdate (color_ostream &out) +{ + + mymutex->lock(); + if(memdata.state==STATE_OFF) + { + mymutex->unlock(); + return CR_OK; + } + //Console &con=out; + uint64_t time2 = GetTimeMs64(); + uint64_t delta = time2-timeLast; + + if(memdata.refresh!=0) + if(deltaunlock(); + return CR_OK; + } + timeLast = time2; + + Core::getInstance().p->read(memdata.addr,memdata.len,memdata.buf); + outputHex(memdata.buf,memdata.lbuf,memdata.len,(size_t)memdata.addr,out,memdata.ranges); + memcpy(memdata.lbuf, memdata.buf, memdata.len); + if(memdata.refresh==0) + Deinit(); + mymutex->unlock(); + return CR_OK; + +} +command_result memview (color_ostream &out, vector & parameters) +{ + mymutex->lock(); + Core::getInstance().p->getMemRanges(memdata.ranges); + memdata.addr=(void *)convert(parameters[0],true); + if(memdata.addr==0) + { + Deinit(); + memdata.state=STATE_OFF; + is_enabled = false; + mymutex->unlock(); + return CR_OK; + } + else + { + Deinit(); + bool isValid=false; + for(size_t i=0;iunlock(); + return CR_OK; + } + is_enabled = true; + memdata.state=STATE_ON; + } + if(parameters.size()>1) + memdata.len=convert(parameters[1]); + else + memdata.len=20*16; + + if(parameters.size()>2) + memdata.refresh=convert(parameters[2]); + else + memdata.refresh=0; + + memdata.buf=new uint8_t[memdata.len]; + memdata.lbuf=new uint8_t[memdata.len]; + Core::getInstance().p->getMemRanges(memdata.ranges); + mymutex->unlock(); + return CR_OK; +} +DFhackCExport command_result plugin_shutdown (color_ostream &out) +{ + mymutex->lock(); + Deinit(); + delete mymutex; + mymutex->unlock(); + return CR_OK; +} diff --git a/plugins/devel/tiles.cpp b/plugins/devel/tiles.cpp index 972b7fd0d..61640257a 100644 --- a/plugins/devel/tiles.cpp +++ b/plugins/devel/tiles.cpp @@ -527,7 +527,7 @@ command_result df_tiles (Core * c, vector & parameters) } else { - cout << "flow bit 1 = " << bflags.bits.liquid_1 << endl; + cout << "flow bit 1 = " << bflags.bits.liquid_1 << endl; cout << "flow bit 2 = " << bflags.bits.liquid_2 << endl; } biter ++; diff --git a/plugins/devel/vectors.cpp b/plugins/devel/vectors.cpp index 0a453634b..91d333c45 100644 --- a/plugins/devel/vectors.cpp +++ b/plugins/devel/vectors.cpp @@ -156,7 +156,7 @@ command_result df_vectors (color_ostream &con, vector & parameters) vectorsUsage(con); return CR_FAILURE; } - + if (!hexOrDec(parameters[1], bytes)) { vectorsUsage(con); @@ -273,7 +273,7 @@ command_result df_clearvec (color_ostream &con, vector & parameters) vectorsUsage(con); return CR_FAILURE; } - + if (!hexOrDec(parameters[1], bytes)) { vectorsUsage(con); diff --git a/plugins/dig.cpp b/plugins/dig.cpp index 922a47477..0d49535ad 100644 --- a/plugins/dig.cpp +++ b/plugins/dig.cpp @@ -1156,7 +1156,7 @@ command_result diglx (color_ostream &out, vector & parameters) return digl(out,lol); } -// TODO: +// TODO: // digl and digv share the longish floodfill code and only use different conditions // to check if a tile should be marked for digging or not. // to make the plugin a bit smaller and cleaner a main execute method would be nice @@ -1377,7 +1377,7 @@ command_result digtype (color_ostream &out, vector & parameters) out.printerr("Too many parameters.\n"); return CR_FAILURE; } - + uint32_t targetDigType; if ( parameters.size() == 1 ) { @@ -1406,13 +1406,13 @@ command_result digtype (color_ostream &out, vector & parameters) { targetDigType = -1; } - + if (!Maps::IsValid()) { out.printerr("Map is not available!\n"); return CR_FAILURE; } - + int32_t cx, cy, cz; uint32_t xMax,yMax,zMax; Maps::getSize(xMax,yMax,zMax); @@ -1436,7 +1436,7 @@ command_result digtype (color_ostream &out, vector & parameters) return CR_FAILURE; } out.print("(%d,%d,%d) tiletype: %d, veinmat: %d, designation: 0x%x ... DIGGING!\n", cx,cy,cz, tt, veinmat, baseDes.whole); - + if ( targetDigType != -1 ) { baseDes.bits.dig = (tile_dig_designation::tile_dig_designation)targetDigType; @@ -1448,7 +1448,7 @@ command_result digtype (color_ostream &out, vector & parameters) baseDes.bits.dig = tile_dig_designation::Default; } } - + for( uint32_t z = 0; z < zMax; z++ ) { for( uint32_t x = 1; x < tileXMax-1; x++ ) @@ -1462,7 +1462,7 @@ command_result digtype (color_ostream &out, vector & parameters) tt = mCache->tiletypeAt(current); if (!DFHack::isWallTerrain(tt)) continue; - + //designate it for digging df::tile_designation des = mCache->designationAt(current); if ( !mCache->testCoord(current) ) @@ -1471,14 +1471,14 @@ command_result digtype (color_ostream &out, vector & parameters) delete mCache; return CR_FAILURE; } - + df::tile_designation designation = mCache->designationAt(current); designation.bits.dig = baseDes.bits.dig; mCache->setDesignationAt(current, designation); } } } - + mCache->WriteAll(); delete mCache; return CR_OK; diff --git a/plugins/digFlood.cpp b/plugins/digFlood.cpp index 4538e7d3e..6668f9994 100644 --- a/plugins/digFlood.cpp +++ b/plugins/digFlood.cpp @@ -38,7 +38,7 @@ set autodigMaterials; DFhackCExport command_result plugin_enable(color_ostream& out, bool enable) { if (enabled == enable) return CR_OK; - + enabled = enable; if ( enabled ) { EventManager::registerListener(EventManager::EventType::JOB_COMPLETED, digHandler, plugin_self); @@ -79,31 +79,31 @@ void onDig(color_ostream& out, void* ptr) { df::job* job = (df::job*)ptr; if ( job->completion_timer > 0 ) return; - + if ( job->job_type != df::enums::job_type::Dig && - job->job_type != df::enums::job_type::CarveUpwardStaircase && - job->job_type != df::enums::job_type::CarveDownwardStaircase && - job->job_type != df::enums::job_type::CarveUpDownStaircase && - job->job_type != df::enums::job_type::CarveRamp && + job->job_type != df::enums::job_type::CarveUpwardStaircase && + job->job_type != df::enums::job_type::CarveDownwardStaircase && + job->job_type != df::enums::job_type::CarveUpDownStaircase && + job->job_type != df::enums::job_type::CarveRamp && job->job_type != df::enums::job_type::DigChannel ) return; - + set jobLocations; for ( df::job_list_link* link = &world->job_list; link != NULL; link = link->next ) { if ( link->item == NULL ) continue; - + if ( link->item->job_type != df::enums::job_type::Dig && - link->item->job_type != df::enums::job_type::CarveUpwardStaircase && - link->item->job_type != df::enums::job_type::CarveDownwardStaircase && - link->item->job_type != df::enums::job_type::CarveUpDownStaircase && - link->item->job_type != df::enums::job_type::CarveRamp && + link->item->job_type != df::enums::job_type::CarveUpwardStaircase && + link->item->job_type != df::enums::job_type::CarveDownwardStaircase && + link->item->job_type != df::enums::job_type::CarveUpDownStaircase && + link->item->job_type != df::enums::job_type::CarveRamp && link->item->job_type != df::enums::job_type::DigChannel ) continue; - + jobLocations.insert(link->item->pos); } - + MapExtras::MapCache cache; df::coord pos = job->pos; for ( int16_t a = -1; a <= 1; a++ ) { @@ -118,23 +118,23 @@ void maybeExplore(color_ostream& out, MapExtras::MapCache& cache, df::coord pt, if ( !Maps::isValidTilePos(pt) ) { return; } - + df::map_block* block = Maps::getTileBlock(pt); if (!block) return; - + if ( block->designation[pt.x&0xF][pt.y&0xF].bits.hidden ) return; - + df::tiletype type = block->tiletype[pt.x&0xF][pt.y&0xF]; if ( ENUM_ATTR(tiletype, material, type) != df::enums::tiletype_material::MINERAL ) return; if ( ENUM_ATTR(tiletype, shape, type) != df::enums::tiletype_shape::WALL ) return; - + if ( block->designation[pt.x&0xF][pt.y&0xF].bits.dig != df::enums::tile_dig_designation::No ) return; - + uint32_t xMax,yMax,zMax; Maps::getSize(xMax,yMax,zMax); if ( pt.x == 0 || pt.y == 0 || pt.x+1 == xMax*16 || pt.y+1 == yMax*16 ) @@ -142,7 +142,7 @@ void maybeExplore(color_ostream& out, MapExtras::MapCache& cache, df::coord pt, if ( jobLocations.find(pt) != jobLocations.end() ) { return; } - + int16_t mat = cache.veinMaterialAt(pt); if ( mat == -1 ) return; @@ -152,7 +152,7 @@ void maybeExplore(color_ostream& out, MapExtras::MapCache& cache, df::coord pt, return; } } - + block->designation[pt.x&0xF][pt.y&0xF].bits.dig = df::enums::tile_dig_designation::Default; block->flags.bits.designated = true; // *process_dig = true; @@ -174,12 +174,12 @@ command_result digFlood (color_ostream &out, std::vector & paramet adding = true; continue; } - + if ( parameters[a] == "CLEAR" ) { autodigMaterials.clear(); continue; } - + if ( parameters[a] == "digAll0" ) { digAll = false; continue; @@ -188,7 +188,7 @@ command_result digFlood (color_ostream &out, std::vector & paramet digAll = true; continue; } - + for ( size_t b = 0; b < world->raws.inorganics.size(); b++ ) { df::inorganic_raw* inorganic = world->raws.inorganics[b]; if ( parameters[a] == inorganic->id ) { @@ -199,16 +199,16 @@ command_result digFlood (color_ostream &out, std::vector & paramet goto loop; } } - + out.print("Could not find material \"%s\".\n", parameters[a].c_str()); return CR_WRONG_USAGE; - + loop: continue; } - + autodigMaterials.insert(toAdd.begin(), toAdd.end()); for ( auto a = toRemove.begin(); a != toRemove.end(); a++ ) autodigMaterials.erase(*a); - + return CR_OK; } diff --git a/plugins/diggingInvaders/assignJob.cpp b/plugins/diggingInvaders/assignJob.cpp index eff2de4ad..57aa6ed6f 100644 --- a/plugins/diggingInvaders/assignJob.cpp +++ b/plugins/diggingInvaders/assignJob.cpp @@ -53,7 +53,7 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map (%d,%d,%d)\n", pt1.x,pt1.y,pt1.z, pt2.x,pt2.y,pt2.z); - + int32_t jobId = -1; - + df::map_block* block1 = Maps::getTileBlock(pt1); df::map_block* block2 = Maps::getTileBlock(pt2); bool passable1 = block1->walkable[pt1.x&0xF][pt1.y&0xF]; bool passable2 = block2->walkable[pt2.x&0xF][pt2.y&0xF]; - + df::coord location; df::building* building = Buildings::findAtTile(pt2); df::coord buildingPos = pt2; @@ -202,7 +202,7 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_mapid; job->completion_timer = abilities.jobDelay[CostDimension::Dig]; - + //TODO: test if he already has a pick bool hasPick = false; for ( size_t a = 0; a < firstInvader->inventory.size(); a++ ) { @@ -219,10 +219,10 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_mapid; - + //create and give a pick //based on createitem.cpp df::reaction_product_itemst *prod = NULL; @@ -240,7 +240,7 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_mapprobability = 100; prod->count = 1; prod->product_dimension = 1; - + vector out_items; vector in_reag; vector in_items; prod->produce(firstInvader, &out_items, &in_reag, &in_items, 1, df::job_skill::NONE, df::historical_entity::find(firstInvader->civ_id), df::world_site::find(df::global::ui->site_id)); - + if ( out_items.size() != 1 ) { out.print("%s, %d: wrong size: %d.\n", __FILE__, __LINE__, out_items.size()); return -1; } out_items[0]->moveToGround(firstInvader->pos.x, firstInvader->pos.y, firstInvader->pos.z); - + #if 0 //check for existing item there for ( size_t a = 0; a < firstInvader->inventory.size(); a++ ) { @@ -276,7 +276,7 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_mapbody.weapon_bp); - + delete prod; } } diff --git a/plugins/diggingInvaders/diggingInvaders.cpp b/plugins/diggingInvaders/diggingInvaders.cpp index cd171f527..8be58fd32 100644 --- a/plugins/diggingInvaders/diggingInvaders.cpp +++ b/plugins/diggingInvaders/diggingInvaders.cpp @@ -141,7 +141,7 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector *pointCost; PointComp(unordered_map *p): pointCost(p) { - + } - + int32_t operator()(df::coord p1, df::coord p2) { if ( p1 == p2 ) return 0; auto i1 = pointCost->find(p1); @@ -246,11 +246,11 @@ command_result diggingInvadersCommand(color_ostream& out, std::vector= parameters.size() ) return CR_WRONG_USAGE; - + string raceString = parameters[a+1]; if ( digAbilities.find(raceString) == digAbilities.end() ) { DigAbilities bob; @@ -258,7 +258,7 @@ command_result diggingInvadersCommand(color_ostream& out, std::vector> value; @@ -291,15 +291,15 @@ command_result diggingInvadersCommand(color_ostream& out, std::vector= parameters.size() ) return CR_WRONG_USAGE; - + string raceString = parameters[a+1]; - + if ( digAbilities.find(raceString) == digAbilities.end() ) { out.print("Race %s does not have dig abilities assigned.\n", raceString.c_str()); return CR_WRONG_USAGE; } DigAbilities& abilities = digAbilities[raceString]; - + df::coord bob = Gui::getCursorPos(); out.print("(%d,%d,%d), (%d,%d,%d): cost = %lld\n", lastDebugEdgeCostPoint.x, lastDebugEdgeCostPoint.y, lastDebugEdgeCostPoint.z, bob.x, bob.y, bob.z, getEdgeCost(out, lastDebugEdgeCostPoint, bob, abilities)); lastDebugEdgeCostPoint = bob; @@ -325,7 +325,7 @@ command_result diggingInvadersCommand(color_ostream& out, std::vectorjob.current_job && lastDigger->job.current_job->id == lastInvasionJob ) { @@ -381,7 +381,7 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) { } //out.print("%s,%d: lastDigger = %d, last job = %d, last digger's job = %d\n", __FILE__, __LINE__, lastInvasionDigger, lastInvasionJob, !lastDigger ? -1 : (!lastDigger->job.current_job ? -1 : lastDigger->job.current_job->id)); lastInvasionDigger = lastInvasionJob = -1; - + clearDijkstra(); unordered_set invaderConnectivity; unordered_set localConnectivity; @@ -446,13 +446,13 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) { return; } } - + df::unit* firstInvader = df::unit::find(invaders[0]); if ( firstInvader == NULL ) { fringe.clear(); return; } - + df::creature_raw* creature_raw = df::creature_raw::find(firstInvader->race); if ( creature_raw == NULL || digAbilities.find(creature_raw->creature_id) == digAbilities.end() ) { //inappropriate digger: no dig abilities @@ -464,13 +464,13 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) { //out << firstInvader->id << endl; //out << firstInvader->pos.x << ", " << firstInvader->pos.y << ", " << firstInvader->pos.z << endl; //out << __LINE__ << endl; - + uint32_t xMax, yMax, zMax; Maps::getSize(xMax,yMax,zMax); xMax *= 16; yMax *= 16; MapExtras::MapCache cache; - + clock_t t0 = clock(); clock_t totalEdgeTime = 0; int32_t edgesExpanded = 0; @@ -486,7 +486,7 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) { break; } closedSet.insert(pt); - + if ( localPts.find(pt) != localPts.end() ) { localPtsFound++; if ( true || localPtsFound >= localPts.size() ) { @@ -537,7 +537,7 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) { unordered_set requiresZNeg; unordered_set requiresZPos; - + //find important edges Edge firstImportantEdge(df::coord(), df::coord(), -1); //df::coord closest; @@ -551,7 +551,7 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) { continue; //closest = pt; //closestCostEstimate = costMap[closest]; - //if ( workNeeded[pt] == 0 ) + //if ( workNeeded[pt] == 0 ) // continue; while ( parentMap.find(pt) != parentMap.end() ) { //out.print("(%d,%d,%d)\n", pt.x, pt.y, pt.z); @@ -563,7 +563,7 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) { } //closestCostActual += cost; if ( Maps::canStepBetween(parent, pt) ) { - + } else { if ( pt.x == parent.x && pt.y == parent.y ) { if ( pt.z < parent.z ) { @@ -586,14 +586,14 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) { } if ( firstImportantEdge.p1 == df::coord() ) return; - + /* if ( closestCostActual != closestCostEstimate ) { out.print("%s,%d: closest = (%d,%d,%d), estimate = %lld != actual = %lld\n", __FILE__, __LINE__, closest.x,closest.y,closest.z, closestCostEstimate, closestCostActual); return; } */ - + assignJob(out, firstImportantEdge, parentMap, costMap, invaders, requiresZNeg, requiresZPos, cache, abilities); lastInvasionDigger = firstInvader->id; lastInvasionJob = firstInvader->job.current_job ? firstInvader->job.current_job->id : -1; @@ -605,7 +605,7 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) { if ( invaderJobs.find(job->id) == invaderJobs.end() ) { continue; } - + //cancel it job->flags.bits.item_lost = 1; out.print("%s,%d: cancelling job %d.\n", __FILE__,__LINE__, job->id); diff --git a/plugins/diggingInvaders/edgeCost.cpp b/plugins/diggingInvaders/edgeCost.cpp index 66f2810e2..c9e83fa14 100644 --- a/plugins/diggingInvaders/edgeCost.cpp +++ b/plugins/diggingInvaders/edgeCost.cpp @@ -57,34 +57,34 @@ cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilitie cost_t cost = abilities.costWeight[CostDimension::Walk]; if ( cost < 0 ) return -1; - + if ( Maps::getTileBlock(pt1) == NULL || Maps::getTileBlock(pt2) == NULL ) return -1; - + df::tiletype* type2 = Maps::getTileType(pt2); df::tiletype_shape shape2 = ENUM_ATTR(tiletype, shape, *type2); - + if ( Maps::getTileBlock(pt1)->designation[pt1.x&0xF][pt1.y&0xF].bits.flow_size >= 4 ) return -1; if ( Maps::getTileBlock(pt2)->designation[pt2.x&0xF][pt2.y&0xF].bits.flow_size >= 4 ) return -1; - + if ( shape2 == df::enums::tiletype_shape::EMPTY ) { return -1; } - + if ( shape2 == df::enums::tiletype_shape::BRANCH || shape2 == df::enums::tiletype_shape::TRUNK_BRANCH || shape2 == df::enums::tiletype_shape::TWIG ) return -1; - + /* if () { df::map_block* temp = Maps::getTileBlock(df::coord(pt1.x,pt1.y,pt1.z-1)); if ( temp && temp->designation[pt1.x&0xF][pt1.y&0xF] } */ - + if ( Maps::canStepBetween(pt1, pt2) ) { return cost; } @@ -93,11 +93,11 @@ cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilitie if ( building2 ) { if ( abilities.costWeight[CostDimension::DestroyBuilding] < 0 ) return -1; - cost += abilities.costWeight[CostDimension::DestroyBuilding]; + cost += abilities.costWeight[CostDimension::DestroyBuilding]; if ( dx*dx + dy*dy > 1 ) return -1; } - + bool construction2 = ENUM_ATTR(tiletype, material, *type2) == df::enums::tiletype_material::CONSTRUCTION; if ( construction2 ) { //smooth or not? @@ -113,7 +113,7 @@ cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilitie cost += abilities.costWeight[CostDimension::DestroyRoughConstruction]; } } - + if ( dz == 0 ) { if ( !building2 && !construction2 ) { //it has to be a wall @@ -143,7 +143,7 @@ cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilitie } cost += abilities.costWeight[CostDimension::Dig]; } - + bool walkable_high1 = shape1 == df::tiletype_shape::STAIR_UP || shape1 == df::tiletype_shape::STAIR_UPDOWN; if ( !walkable_high1 ) { if ( shape1 != df::enums::tiletype_shape::WALL ) { @@ -154,7 +154,7 @@ cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilitie } cost += abilities.costWeight[CostDimension::Dig]; } - + if ( building2 ) { //moving up through an open bridge or a usable hatch is fine. other buildings are not bool unforbiddenHatch = false; @@ -188,7 +188,7 @@ cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilitie if ( !unforbiddenHatch && !inactiveBridge ) return -1; } - + /*bool forbidden = false; if ( building2 && building2->getType() == df::building_type::Hatch ) { df::building_hatchst* hatch = (df::building_hatchst*)building2; @@ -202,7 +202,7 @@ cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilitie if ( !walkable_high2 ) { if ( building2 || construction2 ) return -1; - + if ( shape2 != df::enums::tiletype_shape::WALL ) return -1; if ( abilities.costWeight[CostDimension::Dig] < 0 ) { @@ -240,14 +240,14 @@ cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilitie if ( bridge->direction == df::building_bridgest::T_direction::Down && pt1.y == bridge->y2 ) return -1; } - + bool forbidden = false; if ( building1 && building1->getType() == df::building_type::Hatch ) { df::building_hatchst* hatch = (df::building_hatchst*)building1; if ( hatch->door_flags.bits.forbidden || hatch->door_flags.bits.closed && hatch->door_flags.bits.operated_by_mechanisms ) forbidden = true; } - + //you can deconstruct a hatch from the side if ( building1 && forbidden /*&& building1->getType() == df::building_type::Hatch*/ ) { /* @@ -300,7 +300,7 @@ cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilitie if ( minCost == -1 ) return -1; cost += minCost; - + */ //note: assignJob is not ready for this level of sophistication, so don't allow it return -1; @@ -312,7 +312,7 @@ cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilitie return -1; } } - + return cost; } @@ -329,7 +329,7 @@ cost_t getEdgeCostOld(color_ostream& out, df::coord pt1, df::coord pt2) { return cost; return 100 + cost; } - + Maps::ensureTileBlock(pt1); Maps::ensureTileBlock(pt2); df::tiletype* type1 = Maps::getTileType(pt1); @@ -404,7 +404,7 @@ cost_t getEdgeCostOld(color_ostream& out, df::coord pt1, df::coord pt2) { if ( shape2 == df::enums::tiletype_shape::RAMP_TOP ) { return -1; } - + //it has to be a wall if ( shape2 != df::enums::tiletype_shape::WALL ) { out << "shape = " << (int32_t)shape2 << endl; @@ -427,15 +427,15 @@ cost_t getEdgeCostOld(color_ostream& out, df::coord pt1, df::coord pt2) { cost += costWeight[CostDimension::Dig]; return cost; } - + //descending if ( passable_high2 ) return cost; - + if ( building2 || construction2 ) { return -1; } - + //must be a wall? if ( shape2 != df::enums::tiletype_shape::WALL ) { out.print("%s, line %n: WTF?\n", __FILE__, __LINE__); @@ -445,7 +445,7 @@ cost_t getEdgeCostOld(color_ostream& out, df::coord pt1, df::coord pt2) { cost += costWeight[CostDimension::Dig]; return cost; } - + //moving diagonally return -1; } @@ -455,7 +455,7 @@ vector* getEdgeSet(color_ostream &out, df::coord point, MapExtras::MapCach //vector* result = new vector(26); vector* result = new vector(); result->reserve(26); - + //size_t count = 0; for ( int32_t dx = -1; dx <= 1; dx++ ) { for ( int32_t dy = -1; dy <= 1; dy++ ) { diff --git a/plugins/diggingInvaders/edgeCost.h b/plugins/diggingInvaders/edgeCost.h index 80c49d882..560fec109 100644 --- a/plugins/diggingInvaders/edgeCost.h +++ b/plugins/diggingInvaders/edgeCost.h @@ -56,7 +56,7 @@ public: cost = -1; } Edge(const Edge& e): p1(e.p1), p2(e.p2), cost(e.cost) { - + } Edge(df::coord p1In, df::coord p2In, cost_t costIn): cost(costIn) { if ( p2In < p1In ) { diff --git a/plugins/dwarfexport/dwarfexport.cpp b/plugins/dwarfexport/dwarfexport.cpp index 4a78332cc..8355573be 100644 --- a/plugins/dwarfexport/dwarfexport.cpp +++ b/plugins/dwarfexport/dwarfexport.cpp @@ -103,7 +103,7 @@ static void printAttributes(color_ostream &con, df::unit* cre, ostream& out) { static void printTraits(color_ostream &con, df::unit* cre, ostream& out) { - + out << " " << endl; df::unit_soul * s = cre->status.current_soul; if (s) @@ -120,7 +120,7 @@ static void printTraits(color_ostream &con, df::unit* cre, ostream& out) } */ out << "" << endl; - + } } out << " " << endl; @@ -189,7 +189,7 @@ static void export_dwarf(color_ostream &con, df::unit* cre, ostream& out) { info += Translation::TranslateName(&cre->name, false); info[0] = toupper(info[0]); con.print("Exporting %s\n", info.c_str()); - + out << " " << endl; element("Name", info.c_str(), out); element("Nickname", cre->name.nickname.c_str(), out); @@ -225,7 +225,7 @@ command_result export_dwarves (color_ostream &con, std::vector & p uint32_t civ = ui->civ_id; outf << "" << endl << "" << endl; - + for (int i = 0; i < world->units.all.size(); ++i) { df::unit* cre = world->units.all[i]; diff --git a/plugins/dwarfmonitor.cpp b/plugins/dwarfmonitor.cpp index 9a7d1f30c..c44bf64d5 100644 --- a/plugins/dwarfmonitor.cpp +++ b/plugins/dwarfmonitor.cpp @@ -1720,8 +1720,8 @@ struct dwarf_monitor_hook : public df::viewscreen_dwarfmodest ostringstream date_str; auto month = World::ReadCurrentMonth() + 1; auto day = World::ReadCurrentDay(); - date_str << "Date:" << World::ReadCurrentYear() << "-" << - ((month < 10) ? "0" : "") << month << "-" << + date_str << "Date:" << World::ReadCurrentYear() << "-" << + ((month < 10) ? "0" : "") << month << "-" << ((day < 10) ? "0" : "") << day; OutputString(COLOR_GREY, x, y, date_str.str()); diff --git a/plugins/eventful.cpp b/plugins/eventful.cpp index f984ad579..3a8b6da7a 100644 --- a/plugins/eventful.cpp +++ b/plugins/eventful.cpp @@ -463,7 +463,7 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan break; case SC_WORLD_UNLOADED: world_specific_hooks(out,false); - + break; default: break; diff --git a/plugins/fastdwarf.cpp b/plugins/fastdwarf.cpp index 47b2d5cac..bbfa5d1d8 100644 --- a/plugins/fastdwarf.cpp +++ b/plugins/fastdwarf.cpp @@ -247,6 +247,6 @@ DFhackCExport command_result plugin_init ( color_ostream &out, std::vector & par command_result restrictIce(color_ostream &out, std::vector & params) { - return setAllMatching(out, restrictIceProc); + return setAllMatching(out, restrictIceProc); } //Helper function for writing new functions that check every tile on the map. @@ -383,29 +383,29 @@ void allRestricted(DFCoord coord, MapExtras::MapCache &map) //Restrict traffic if tile is visible and liquid is present. void restrictLiquidProc(DFCoord coord, MapExtras::MapCache &map) { - df::tile_designation des = map.designationAt(coord); - if ((des.bits.hidden == 0) && (des.bits.flow_size != 0)) - { - des.bits.traffic = tile_traffic::Restricted; - map.setDesignationAt(coord, des); - } + df::tile_designation des = map.designationAt(coord); + if ((des.bits.hidden == 0) && (des.bits.flow_size != 0)) + { + des.bits.traffic = tile_traffic::Restricted; + map.setDesignationAt(coord, des); + } } //Restrict traffice if tile is above visible ice wall. void restrictIceProc(DFCoord coord, MapExtras::MapCache &map) { - //There is no ice below the bottom of the map. - if (coord.z == 0) - return; - - DFCoord tile_below = DFCoord(coord.x, coord.y, coord.z - 1); - df::tiletype tt = map.tiletypeAt(tile_below); - df::tile_designation des = map.designationAt(tile_below); - - if ((des.bits.hidden == 0) && (tileMaterial(tt) == tiletype_material::FROZEN_LIQUID)) - { - des = map.designationAt(coord); - des.bits.traffic = tile_traffic::Restricted; - map.setDesignationAt(coord, des); - } + //There is no ice below the bottom of the map. + if (coord.z == 0) + return; + + DFCoord tile_below = DFCoord(coord.x, coord.y, coord.z - 1); + df::tiletype tt = map.tiletypeAt(tile_below); + df::tile_designation des = map.designationAt(tile_below); + + if ((des.bits.hidden == 0) && (tileMaterial(tt) == tiletype_material::FROZEN_LIQUID)) + { + des = map.designationAt(coord); + des.bits.traffic = tile_traffic::Restricted; + map.setDesignationAt(coord, des); + } } diff --git a/plugins/fixpositions.cpp b/plugins/fixpositions.cpp index 7a22fd2b8..e136ee0a9 100644 --- a/plugins/fixpositions.cpp +++ b/plugins/fixpositions.cpp @@ -46,7 +46,7 @@ command_result df_fixdiplomats (color_ostream &out, vector ¶meters) for (int j = 0; j < ent->positions.own.size(); j++) { pos = ent->positions.own[j]; - if (pos->responsibilities[entity_position_responsibility::MAKE_INTRODUCTIONS] && + if (pos->responsibilities[entity_position_responsibility::MAKE_INTRODUCTIONS] && pos->responsibilities[entity_position_responsibility::MAKE_PEACE_AGREEMENTS] && pos->responsibilities[entity_position_responsibility::MAKE_TOPIC_AGREEMENTS]) { diff --git a/plugins/follow.cpp b/plugins/follow.cpp index ff0a94787..323b0a498 100644 --- a/plugins/follow.cpp +++ b/plugins/follow.cpp @@ -126,7 +126,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) Gui::setCursorCoords(c_x - (prevX-x), c_y - (prevY-y), z); //Save this round's stuff for next time so we can monitor for changes made by the user - prevX = x; + prevX = x; prevY = y; prevZ = z; prevMenuWidth = menu_width; diff --git a/plugins/fortplan.cpp b/plugins/fortplan.cpp index cbd4bd346..4187f2d0a 100644 --- a/plugins/fortplan.cpp +++ b/plugins/fortplan.cpp @@ -9,30 +9,30 @@ DFHACK_PLUGIN("fortplan"); command_result fortplan(color_ostream &out, vector & params); struct BuildingInfo { - std::string code; - df::building_type type; - df::furnace_type furnaceType; - df::workshop_type workshopType; - df::trap_type trapType; - std::string name; - bool variableSize; - int defaultHeight; - int defaultWidth; - bool hasCustomOptions; - - BuildingInfo(std::string theCode, df::building_type theType, std::string theName, int height, int width) { - code = theCode; - type = theType; - name = theName; - variableSize = false; - defaultHeight = height; - defaultWidth = width; - hasCustomOptions = false; - } - - bool allocate() { - return planner.allocatePlannedBuilding(type); - } + std::string code; + df::building_type type; + df::furnace_type furnaceType; + df::workshop_type workshopType; + df::trap_type trapType; + std::string name; + bool variableSize; + int defaultHeight; + int defaultWidth; + bool hasCustomOptions; + + BuildingInfo(std::string theCode, df::building_type theType, std::string theName, int height, int width) { + code = theCode; + type = theType; + name = theName; + variableSize = false; + defaultHeight = height; + defaultWidth = width; + hasCustomOptions = false; + } + + bool allocate() { + return planner.allocatePlannedBuilding(type); + } }; class MatchesCode @@ -54,34 +54,34 @@ DFhackCExport command_result plugin_init ( color_ostream &out, vector > tokenizeFile(std::string filename) { - std::ifstream infile(filename.c_str()); - std::vector> fileTokens(128, std::vector(128)); - std::vector>::size_type x, y; - if (!infile.good()) { - throw -1; - } - std::string line; - y = 0; - while (std::getline(infile, line)) { - x = 0; - if (strcmp(line.substr(0,1).c_str(),"#")==0) { - fileTokens[y++][0] = line; - continue; - } - int start = 0; - auto nextInd = line.find(','); - std::string curCell = line.substr(start,nextInd-start); - do { - fileTokens[y][x] = curCell; - start = nextInd+1; - nextInd = line.find(',',start); - curCell = line.substr(start,nextInd-start); - x++; - } while (nextInd != line.npos); - y++; - } - return fileTokens; -} + std::ifstream infile(filename.c_str()); + std::vector> fileTokens(128, std::vector(128)); + std::vector>::size_type x, y; + if (!infile.good()) { + throw -1; + } + std::string line; + y = 0; + while (std::getline(infile, line)) { + x = 0; + if (strcmp(line.substr(0,1).c_str(),"#")==0) { + fileTokens[y++][0] = line; + continue; + } + int start = 0; + auto nextInd = line.find(','); + std::string curCell = line.substr(start,nextInd-start); + do { + fileTokens[y][x] = curCell; + start = nextInd+1; + nextInd = line.find(',',start); + curCell = line.substr(start,nextInd-start); + x++; + } while (nextInd != line.npos); + y++; + } + return fileTokens; +} command_result fortplan(color_ostream &out, vector & params) { auto & con = out; std::vector> layout(128, std::vector(128)); - if (params.size()) { - coord32_t cursor; - coord32_t userCursor; - coord32_t startCursor; - if (!DFHack::Gui::getCursorCoords(cursor.x, cursor.y, cursor.z)) { - con.print("You must have an active in-game cursor.\n"); - return CR_FAILURE; - } - DFHack::Gui::getCursorCoords(startCursor.x, startCursor.y, startCursor.z); - userCursor = startCursor; - - std::string cwd = Filesystem::getcwd(); - std::string filename = cwd+"/"+params[0]; - con.print("Loading file '%s'...\n",filename.c_str()); - try { - layout = tokenizeFile(filename); - } catch (int e) { - con.print("Could not open the file.\n"); - return CR_FAILURE; - } - if (!is_enabled) { - plugin_enable(out, true); - } - con.print("Loaded.\n"); - std::vector>::size_type x, y; - bool started = false; - for (y = 0; y < layout.size(); y++) { - x = 0; - auto hashBuild = layout[y][x].find("#build"); - if (hashBuild != layout[y][x].npos) { - auto startLoc = layout[y][x].find("start("); - if (startLoc != layout[y][x].npos) { - startLoc += 6; - auto nextDelimiter = layout[y][x].find(";",startLoc); - std::string startXStr = layout[y][x].substr(startLoc,nextDelimiter-startLoc); - int startXOffset = std::stoi(startXStr); - startLoc = nextDelimiter+1; - nextDelimiter = layout[y][x].find(";",startLoc); - std::string startYStr = layout[y][x].substr(startLoc,nextDelimiter-startLoc); - int startYOffset = std::stoi(startYStr); - startCursor.x -= startXOffset; - startCursor.y -= startYOffset; - DFHack::Gui::setCursorCoords(startCursor.x,startCursor.y,startCursor.z); - started = true; - - auto startEnd = layout[y][x].find(")",nextDelimiter); - - con.print("Starting at (%d,%d,%d) which is described as: %s\n",startCursor.x,startCursor.y,startCursor.z,layout[y][x].substr(nextDelimiter+1,startEnd-nextDelimiter).c_str()); - std::string desc = layout[y][x].substr(startEnd+1); - if (desc.size()>0) { - con.print("Description of this plan: %s\n",desc.c_str()); - } - continue; - } else { - con.print("No start location found for this block\n"); - } - } else if (!started) { - con.print("Not a build file: %s\n",layout[y][x].c_str()); - break; - } - - for (x = 0; x < layout[y].size(); x++) { - if (strcmp(layout[y][x].substr(0,1).c_str(),"#")==0) { - continue; - } - - if (strcmp(layout[y][x].c_str(),"`")!=0) { - auto dataIndex = layout[y][x].find("("); - std::string curCode; - std::vector curData; - if (dataIndex != layout[y][x].npos) { - curCode = layout[y][x].substr(0,dataIndex); - int dataStart = dataIndex+1; - auto nextDataStart = layout[y][x].find(",",dataStart); - while (nextDataStart!=layout[y][x].npos) { - std::string nextData = layout[y][x].substr(dataStart,nextDataStart); - if (strcmp(nextData.substr(nextData.size()-1,1).c_str(),")")==0) { - nextData = nextData.substr(0,nextData.size()-1); - } - curData.push_back(nextData); - dataStart = nextDataStart+1; - nextDataStart = layout[y][x].find(",",dataStart); - } - } else { - curCode = layout[y][x]; - } - //con.print("Found a cell with '%s' in it (layout[y][x] %d:%d-%d)\n",layout[y][x].c_str(),lineNum,start,nextInd); - auto buildingIndex = std::find_if(buildings.begin(), buildings.end(), MatchesCode(curCode.c_str())); - - // = std::find(validInstructions.begin(), validInstructions.end(), layout[y][x]); - if(buildingIndex == buildings.end()) { - //con.print("That is not a valid code.\n"); - } else { - //con.print("I can build that!\n"); - BuildingInfo buildingInfo = *buildingIndex; - if (buildingInfo.variableSize || buildingInfo.defaultHeight > 1 || buildingInfo.defaultWidth > 1) { - //con.print("Found a building at (%d,%d) called %s, which has a size %dx%d or variable size\n",x,y,buildingInfo.name.c_str(),buildingInfo.defaultWidth, buildingInfo.defaultHeight); - // TODO: Make this function smarter, able to determine the exact shape - // and location of the building - // For now, we just assume that we are always looking at the top left - // corner of where it is located in the input file - coord32_t buildingSize; - if (!buildingInfo.variableSize) { - bool single = true; - bool block = true; - std::vector>::size_type checkX, checkY; - int yOffset = ((buildingInfo.defaultHeight-1)/2); - int xOffset = ((buildingInfo.defaultWidth-1)/2); - //con.print(" - Checking to see if it's a single, with %d<=x<%d and %d<=y<%d...\n",x-xOffset,x+xOffset,y-yOffset,y+yOffset); - // First, check to see if this is in the center of an empty square of its default size - for (checkY = y-yOffset; checkY <= (y+yOffset); checkY++) { - for (checkX = x-xOffset; checkX <= (x+xOffset); checkX++) { - if (checkX==x && checkY==y) { - continue; - } - auto checkDataIndex = layout[checkY][checkX].find("("); - std::string checkCode; - if (checkDataIndex != layout[checkY][checkX].npos) { - checkCode = layout[checkY][checkX].substr(0,checkDataIndex); - } else { - checkCode = layout[checkY][checkX]; - } - - con.print(" - Code at (%d,%d) is '%s': ",checkX,checkY,checkCode.c_str()); - auto checkIndex = std::find_if(buildings.begin(), buildings.end(), MatchesCode(checkCode.c_str())); - //if (checkIndex == buildings.end()) { - // con.print("this is not a valid code, so we keep going.\n"); - // continue; - //} - //if (curCode.compare(layout[checkY][checkX]) != 0) { - if (checkIndex != buildings.end()) { - //con.print("this is a building, so we break.\n"); - single = false; - break; - } else { - //con.print("this is not a building, so we keep going.\n"); - } - } - if (!single) { - //con.print("Not a single. Moving forward.\n"); - break; - } - } - if (!single) { - // If that's not the case, check to see if this is the top-left corner of - // a square of its default size - //con.print(" - It's not single; checking to see if it's a block...\n"); - for (checkY = y; checkY < (y+buildingInfo.defaultHeight); checkY++) { - for (checkX = x; checkX < (x+buildingInfo.defaultWidth); checkX++) { - if (checkX==x && checkY==y) { - continue; - } - auto checkDataIndex = layout[checkY][checkX].find("("); - std::string checkCode; - if (checkDataIndex != layout[checkY][checkX].npos) { - checkCode = layout[checkY][checkX].substr(0,checkDataIndex); - } else { - checkCode = layout[checkY][checkX]; - } - - //con.print(" - Code at (%d,%d) is '%s': ",checkX,checkY,checkCode.c_str()); - if (curCode.compare(checkCode) != 0) { - //con.print("this is not the same as '%s', so we break.\n",curCode.c_str()); - block = false; - break; - } else { - //con.print("this is the same as '%s', so we erase it and move on.\n",curCode.c_str()); - layout[checkY][checkX] = "``"; - } - } - if (!block) { - //con.print("Not a block. Moving forward.\n"); - break; - } - } - } - - if (single) { - //con.print("Placing a building with code '%s' centered at (%d,%d) and default size %dx%d.\n",curCode.c_str(),x,y,buildingInfo.defaultWidth,buildingInfo.defaultHeight); - coord32_t offsetCursor = cursor; - offsetCursor.x -= xOffset; - offsetCursor.y -= yOffset; - DFHack::Gui::setCursorCoords(offsetCursor.x, offsetCursor.y, offsetCursor.z); - if (!buildingInfo.allocate()) { - con.print("*** There was an error placing building with code '%s' centered at (%d,%d).\n",curCode.c_str(),x,y); - } - DFHack::Gui::setCursorCoords(cursor.x, cursor.y, cursor.z); - } else if (block) { - //con.print("Placing a building with code '%s' with corner at (%d,%d) and default size %dx%d.\n",curCode.c_str(),x,y,buildingInfo.defaultWidth,buildingInfo.defaultHeight); - if (!buildingInfo.allocate()) { - con.print("*** There was an error placing building with code '%s' with corner at (%d,%d).\n",curCode.c_str(),x,y); - } - } else { - con.print("*** Found a code '%s' at (%d,%d) for a building with default size %dx%d with an invalid size designation.\n",curCode.c_str(),x,y,buildingInfo.defaultWidth,buildingInfo.defaultHeight); - } - } else { - //buildingSize = findBuildingExtent(layout, x, y, -1, -1, out); - //con.print(" - The building has variable size %dx%d\n",buildingSize.x, buildingSize.y); - //con.print(" - The building has a variable size, which is not yet handled.\n"); - } - } else { - //con.print("Building a(n) %s.\n",buildingInfo.name.c_str()); - if (!buildingInfo.allocate()) { - con.print("*** There was an error placing the %s at (%d,%d).\n",buildingInfo.name.c_str(),x,y); - } - } - } - } - cursor.x++; - DFHack::Gui::setCursorCoords(cursor.x, cursor.y, cursor.z); - } - - cursor.y++; - cursor.x = startCursor.x; - - } - DFHack::Gui::setCursorCoords(userCursor.x, userCursor.y, userCursor.z); - con.print("Done with file.\n"); - } else { - con.print("You must supply a filename to read.\n"); - } - - return CR_OK; + if (params.size()) { + coord32_t cursor; + coord32_t userCursor; + coord32_t startCursor; + if (!DFHack::Gui::getCursorCoords(cursor.x, cursor.y, cursor.z)) { + con.print("You must have an active in-game cursor.\n"); + return CR_FAILURE; + } + DFHack::Gui::getCursorCoords(startCursor.x, startCursor.y, startCursor.z); + userCursor = startCursor; + + std::string cwd = Filesystem::getcwd(); + std::string filename = cwd+"/"+params[0]; + con.print("Loading file '%s'...\n",filename.c_str()); + try { + layout = tokenizeFile(filename); + } catch (int e) { + con.print("Could not open the file.\n"); + return CR_FAILURE; + } + if (!is_enabled) { + plugin_enable(out, true); + } + con.print("Loaded.\n"); + std::vector>::size_type x, y; + bool started = false; + for (y = 0; y < layout.size(); y++) { + x = 0; + auto hashBuild = layout[y][x].find("#build"); + if (hashBuild != layout[y][x].npos) { + auto startLoc = layout[y][x].find("start("); + if (startLoc != layout[y][x].npos) { + startLoc += 6; + auto nextDelimiter = layout[y][x].find(";",startLoc); + std::string startXStr = layout[y][x].substr(startLoc,nextDelimiter-startLoc); + int startXOffset = std::stoi(startXStr); + startLoc = nextDelimiter+1; + nextDelimiter = layout[y][x].find(";",startLoc); + std::string startYStr = layout[y][x].substr(startLoc,nextDelimiter-startLoc); + int startYOffset = std::stoi(startYStr); + startCursor.x -= startXOffset; + startCursor.y -= startYOffset; + DFHack::Gui::setCursorCoords(startCursor.x,startCursor.y,startCursor.z); + started = true; + + auto startEnd = layout[y][x].find(")",nextDelimiter); + + con.print("Starting at (%d,%d,%d) which is described as: %s\n",startCursor.x,startCursor.y,startCursor.z,layout[y][x].substr(nextDelimiter+1,startEnd-nextDelimiter).c_str()); + std::string desc = layout[y][x].substr(startEnd+1); + if (desc.size()>0) { + con.print("Description of this plan: %s\n",desc.c_str()); + } + continue; + } else { + con.print("No start location found for this block\n"); + } + } else if (!started) { + con.print("Not a build file: %s\n",layout[y][x].c_str()); + break; + } + + for (x = 0; x < layout[y].size(); x++) { + if (strcmp(layout[y][x].substr(0,1).c_str(),"#")==0) { + continue; + } + + if (strcmp(layout[y][x].c_str(),"`")!=0) { + auto dataIndex = layout[y][x].find("("); + std::string curCode; + std::vector curData; + if (dataIndex != layout[y][x].npos) { + curCode = layout[y][x].substr(0,dataIndex); + int dataStart = dataIndex+1; + auto nextDataStart = layout[y][x].find(",",dataStart); + while (nextDataStart!=layout[y][x].npos) { + std::string nextData = layout[y][x].substr(dataStart,nextDataStart); + if (strcmp(nextData.substr(nextData.size()-1,1).c_str(),")")==0) { + nextData = nextData.substr(0,nextData.size()-1); + } + curData.push_back(nextData); + dataStart = nextDataStart+1; + nextDataStart = layout[y][x].find(",",dataStart); + } + } else { + curCode = layout[y][x]; + } + //con.print("Found a cell with '%s' in it (layout[y][x] %d:%d-%d)\n",layout[y][x].c_str(),lineNum,start,nextInd); + auto buildingIndex = std::find_if(buildings.begin(), buildings.end(), MatchesCode(curCode.c_str())); + + // = std::find(validInstructions.begin(), validInstructions.end(), layout[y][x]); + if(buildingIndex == buildings.end()) { + //con.print("That is not a valid code.\n"); + } else { + //con.print("I can build that!\n"); + BuildingInfo buildingInfo = *buildingIndex; + if (buildingInfo.variableSize || buildingInfo.defaultHeight > 1 || buildingInfo.defaultWidth > 1) { + //con.print("Found a building at (%d,%d) called %s, which has a size %dx%d or variable size\n",x,y,buildingInfo.name.c_str(),buildingInfo.defaultWidth, buildingInfo.defaultHeight); + // TODO: Make this function smarter, able to determine the exact shape + // and location of the building + // For now, we just assume that we are always looking at the top left + // corner of where it is located in the input file + coord32_t buildingSize; + if (!buildingInfo.variableSize) { + bool single = true; + bool block = true; + std::vector>::size_type checkX, checkY; + int yOffset = ((buildingInfo.defaultHeight-1)/2); + int xOffset = ((buildingInfo.defaultWidth-1)/2); + //con.print(" - Checking to see if it's a single, with %d<=x<%d and %d<=y<%d...\n",x-xOffset,x+xOffset,y-yOffset,y+yOffset); + // First, check to see if this is in the center of an empty square of its default size + for (checkY = y-yOffset; checkY <= (y+yOffset); checkY++) { + for (checkX = x-xOffset; checkX <= (x+xOffset); checkX++) { + if (checkX==x && checkY==y) { + continue; + } + auto checkDataIndex = layout[checkY][checkX].find("("); + std::string checkCode; + if (checkDataIndex != layout[checkY][checkX].npos) { + checkCode = layout[checkY][checkX].substr(0,checkDataIndex); + } else { + checkCode = layout[checkY][checkX]; + } + + con.print(" - Code at (%d,%d) is '%s': ",checkX,checkY,checkCode.c_str()); + auto checkIndex = std::find_if(buildings.begin(), buildings.end(), MatchesCode(checkCode.c_str())); + //if (checkIndex == buildings.end()) { + // con.print("this is not a valid code, so we keep going.\n"); + // continue; + //} + //if (curCode.compare(layout[checkY][checkX]) != 0) { + if (checkIndex != buildings.end()) { + //con.print("this is a building, so we break.\n"); + single = false; + break; + } else { + //con.print("this is not a building, so we keep going.\n"); + } + } + if (!single) { + //con.print("Not a single. Moving forward.\n"); + break; + } + } + if (!single) { + // If that's not the case, check to see if this is the top-left corner of + // a square of its default size + //con.print(" - It's not single; checking to see if it's a block...\n"); + for (checkY = y; checkY < (y+buildingInfo.defaultHeight); checkY++) { + for (checkX = x; checkX < (x+buildingInfo.defaultWidth); checkX++) { + if (checkX==x && checkY==y) { + continue; + } + auto checkDataIndex = layout[checkY][checkX].find("("); + std::string checkCode; + if (checkDataIndex != layout[checkY][checkX].npos) { + checkCode = layout[checkY][checkX].substr(0,checkDataIndex); + } else { + checkCode = layout[checkY][checkX]; + } + + //con.print(" - Code at (%d,%d) is '%s': ",checkX,checkY,checkCode.c_str()); + if (curCode.compare(checkCode) != 0) { + //con.print("this is not the same as '%s', so we break.\n",curCode.c_str()); + block = false; + break; + } else { + //con.print("this is the same as '%s', so we erase it and move on.\n",curCode.c_str()); + layout[checkY][checkX] = "``"; + } + } + if (!block) { + //con.print("Not a block. Moving forward.\n"); + break; + } + } + } + + if (single) { + //con.print("Placing a building with code '%s' centered at (%d,%d) and default size %dx%d.\n",curCode.c_str(),x,y,buildingInfo.defaultWidth,buildingInfo.defaultHeight); + coord32_t offsetCursor = cursor; + offsetCursor.x -= xOffset; + offsetCursor.y -= yOffset; + DFHack::Gui::setCursorCoords(offsetCursor.x, offsetCursor.y, offsetCursor.z); + if (!buildingInfo.allocate()) { + con.print("*** There was an error placing building with code '%s' centered at (%d,%d).\n",curCode.c_str(),x,y); + } + DFHack::Gui::setCursorCoords(cursor.x, cursor.y, cursor.z); + } else if (block) { + //con.print("Placing a building with code '%s' with corner at (%d,%d) and default size %dx%d.\n",curCode.c_str(),x,y,buildingInfo.defaultWidth,buildingInfo.defaultHeight); + if (!buildingInfo.allocate()) { + con.print("*** There was an error placing building with code '%s' with corner at (%d,%d).\n",curCode.c_str(),x,y); + } + } else { + con.print("*** Found a code '%s' at (%d,%d) for a building with default size %dx%d with an invalid size designation.\n",curCode.c_str(),x,y,buildingInfo.defaultWidth,buildingInfo.defaultHeight); + } + } else { + //buildingSize = findBuildingExtent(layout, x, y, -1, -1, out); + //con.print(" - The building has variable size %dx%d\n",buildingSize.x, buildingSize.y); + //con.print(" - The building has a variable size, which is not yet handled.\n"); + } + } else { + //con.print("Building a(n) %s.\n",buildingInfo.name.c_str()); + if (!buildingInfo.allocate()) { + con.print("*** There was an error placing the %s at (%d,%d).\n",buildingInfo.name.c_str(),x,y); + } + } + } + } + cursor.x++; + DFHack::Gui::setCursorCoords(cursor.x, cursor.y, cursor.z); + } + + cursor.y++; + cursor.x = startCursor.x; + + } + DFHack::Gui::setCursorCoords(userCursor.x, userCursor.y, userCursor.z); + con.print("Done with file.\n"); + } else { + con.print("You must supply a filename to read.\n"); + } + + return CR_OK; } diff --git a/plugins/hotkeys.cpp b/plugins/hotkeys.cpp index 52c2e2eac..7709c0719 100644 --- a/plugins/hotkeys.cpp +++ b/plugins/hotkeys.cpp @@ -108,7 +108,7 @@ static bool close_hotkeys_screen() return false; Screen::dismiss(Core::getTopViewscreen()); - for_each_(sorted_keys, [] (const string &sym) + for_each_(sorted_keys, [] (const string &sym) { Core::getInstance().ClearKeyBindings(sym + "@dfhack/viewscreen_hotkeys"); }); sorted_keys.clear(); return true; @@ -147,7 +147,7 @@ public: hotkeys_column.clear(); int max_key_length = 0; - for_each_(sorted_keys, [&] (const string &sym) + for_each_(sorted_keys, [&] (const string &sym) { if (sym.length() > max_key_length) { max_key_length = sym.length(); } }); int padding = max_key_length + 2; @@ -200,7 +200,7 @@ public: x += 3; OutputHotkeyString(x, y, "Invoke", "Enter or Hotkey"); - + x += 3; OutputToggleString(x, y, "Show Usage", "u", show_usage); @@ -255,7 +255,7 @@ public: } } - virtual std::string getFocusString() + virtual std::string getFocusString() { return "viewscreen_hotkeys"; } diff --git a/plugins/infiniteSky.cpp b/plugins/infiniteSky.cpp index f2853f128..a1fc8f63a 100644 --- a/plugins/infiniteSky.cpp +++ b/plugins/infiniteSky.cpp @@ -31,9 +31,9 @@ command_result infiniteSky (color_ostream &out, std::vector & para DFhackCExport command_result plugin_init ( color_ostream &out, std::vector &commands) { commands.push_back(PluginCommand( - "infiniteSky", + "infiniteSky", "Creates new sky levels on request, or as you construct up.", - infiniteSky, false, + infiniteSky, false, "Usage:\n" " infiniteSky\n" " creates one more z-level\n" @@ -88,7 +88,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) if ( mode.g_mode != df::enums::game_mode::DWARF ) return CR_OK; } - + if ( world->constructions.size() == constructionSize ) return CR_OK; int32_t zNow = world->map.z_count_block; @@ -101,7 +101,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) ///break; } constructionSize = world->constructions.size(); - + return CR_OK; } @@ -152,7 +152,7 @@ void doInfiniteSky(color_ostream& out, int32_t howMany) { delete[] world->map_extras.z_level_flags; world->map_extras.z_level_flags = flags; } - + } DFhackCExport command_result plugin_enable(color_ostream &out, bool enable) diff --git a/plugins/isoworldremote.cpp b/plugins/isoworldremote.cpp index 607035d7b..017fb45f6 100644 --- a/plugins/isoworldremote.cpp +++ b/plugins/isoworldremote.cpp @@ -130,39 +130,39 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) // CoreSuspender suspend; // // Actually do something here. Yay. // out.print("Doing a test...\n"); -// MapExtras::MapCache MC; -// EmbarkTile test_tile; -// if(!gather_embark_tile(0,0, &test_tile, &MC)) -// return CR_FAILURE; -// //test-write the file to check it. -// std::ofstream output_file("tile.p", std::ios_base::binary); -// output_file << test_tile.SerializeAsString(); -// output_file.close(); +// MapExtras::MapCache MC; +// EmbarkTile test_tile; +// if(!gather_embark_tile(0,0, &test_tile, &MC)) +// return CR_FAILURE; +// //test-write the file to check it. +// std::ofstream output_file("tile.p", std::ios_base::binary); +// output_file << test_tile.SerializeAsString(); +// output_file.close(); // -// //load it again to verify. -// std::ifstream input_file("tile.p", std::ios_base::binary); -// std::string input_string( (std::istreambuf_iterator(input_file) ), +// //load it again to verify. +// std::ifstream input_file("tile.p", std::ios_base::binary); +// std::string input_string( (std::istreambuf_iterator(input_file) ), // (std::istreambuf_iterator() ) ); -// EmbarkTile verify_tile; -// verify_tile.ParseFromString(input_string); -// //write contents to text file. -// std::ofstream debug_text("tile.txt", std::ios_base::trunc); -// debug_text << "world coords:" << verify_tile.world_x()<< "," << verify_tile.world_y()<< "," << verify_tile.world_z() << std::endl; -// for(int i = 0; i < verify_tile.tile_layer_size(); i++) { -// debug_text << "layer: " << i << std::endl; -// for(int j = 0; j < 48; j++) { -// debug_text << " "; -// for(int k = 0; k < 48; k++) { -// debug_text << verify_tile.tile_layer(i).mat_type_table(j*48+k) << ","; -// } -// debug_text << " "; -// for(int k = 0; k < 48; k++) { -// debug_text << std::setw(3) << verify_tile.tile_layer(i).mat_subtype_table(j*48+k) << ","; -// } -// debug_text << std::endl; -// } -// debug_text << std::endl; -// } +// EmbarkTile verify_tile; +// verify_tile.ParseFromString(input_string); +// //write contents to text file. +// std::ofstream debug_text("tile.txt", std::ios_base::trunc); +// debug_text << "world coords:" << verify_tile.world_x()<< "," << verify_tile.world_y()<< "," << verify_tile.world_z() << std::endl; +// for(int i = 0; i < verify_tile.tile_layer_size(); i++) { +// debug_text << "layer: " << i << std::endl; +// for(int j = 0; j < 48; j++) { +// debug_text << " "; +// for(int k = 0; k < 48; k++) { +// debug_text << verify_tile.tile_layer(i).mat_type_table(j*48+k) << ","; +// } +// debug_text << " "; +// for(int k = 0; k < 48; k++) { +// debug_text << std::setw(3) << verify_tile.tile_layer(i).mat_subtype_table(j*48+k) << ","; +// } +// debug_text << std::endl; +// } +// debug_text << std::endl; +// } // // Give control back to DF. // return CR_OK; //} @@ -197,12 +197,12 @@ static command_result GetEmbarkInfo(color_ostream &stream, const MapRequest *in, out->set_available(false); return CR_OK; } - if (in->has_save_folder()) { //If no save folder is given, it means we don't care. - if (!(in->save_folder() == world->cur_savegame.save_dir || in->save_folder() == "ANY")) { //isoworld has a different map loaded, don't bother trying to load tiles for it, we don't have them. - out->set_available(false); - return CR_OK; - } - } + if (in->has_save_folder()) { //If no save folder is given, it means we don't care. + if (!(in->save_folder() == world->cur_savegame.save_dir || in->save_folder() == "ANY")) { //isoworld has a different map loaded, don't bother trying to load tiles for it, we don't have them. + out->set_available(false); + return CR_OK; + } + } out->set_available(true); out->set_current_year(*cur_year); out->set_current_season(*cur_season); @@ -219,8 +219,8 @@ int coord_to_index_48(int x, int y) { bool gather_embark_tile(int EmbX, int EmbY, EmbarkTile * tile, MapExtras::MapCache * MP) { tile->set_is_valid(false); - tile->set_world_x(world->map.region_x + (EmbX/3)); - tile->set_world_y(world->map.region_y + (EmbY/3)); + tile->set_world_x(world->map.region_x + (EmbX/3)); + tile->set_world_y(world->map.region_y + (EmbY/3)); tile->set_world_z(world->map.region_z + 1); //adding one because floors get shifted one downwards. tile->set_current_year(*cur_year); tile->set_current_season(*cur_season); @@ -245,7 +245,7 @@ bool gather_embark_tile_layer(int EmbX, int EmbY, int EmbZ, EmbarkTileLayer * ti int num_valid_blocks = 0; for(int yy = 0; yy < 3; yy++) { for(int xx = 0; xx < 3; xx++) { - DFCoord current_coord, upper_coord; + DFCoord current_coord, upper_coord; current_coord.x = EmbX+xx; current_coord.y = EmbY+yy; current_coord.z = EmbZ; @@ -283,7 +283,7 @@ bool gather_embark_tile_layer(int EmbX, int EmbY, int EmbZ, EmbarkTileLayer * ti num_valid_blocks++; } else if(designation.bits.flow_size && (tileShapeBasic(tileShape(upper_tile)) != tiletype_shape_basic::Floor)) { //Contains either water or lava. - tile->set_mat_type_table(array_index, BasicMaterial::LIQUID); + tile->set_mat_type_table(array_index, BasicMaterial::LIQUID); if(designation.bits.liquid_type) //Magma tile->set_mat_subtype_table(array_index, LiquidType::MAGMA); else //water @@ -291,29 +291,29 @@ bool gather_embark_tile_layer(int EmbX, int EmbY, int EmbZ, EmbarkTileLayer * ti num_valid_blocks++; } else if(((tileShapeBasic(tileShape(tile_type)) != tiletype_shape_basic::Open) || - (tileShapeBasic(tileShape(upper_tile)) == tiletype_shape_basic::Floor)) && - ((tileShapeBasic(tileShape(tile_type)) != tiletype_shape_basic::Floor) || + (tileShapeBasic(tileShape(upper_tile)) == tiletype_shape_basic::Floor)) && + ((tileShapeBasic(tileShape(tile_type)) != tiletype_shape_basic::Floor) || (tileShapeBasic(tileShape(upper_tile)) == tiletype_shape_basic::Floor))) { //if the upper tile is a floor, we don't skip, otherwise we do. if(actual_mat.mat_type == builtin_mats::INORGANIC) { //inorganic - tile->set_mat_type_table(array_index, BasicMaterial::INORGANIC); + tile->set_mat_type_table(array_index, BasicMaterial::INORGANIC); tile->set_mat_subtype_table(array_index, actual_mat.mat_index); } else if(actual_mat.mat_type == 419) { //Growing plants - tile->set_mat_type_table(array_index, BasicMaterial::PLANT); + tile->set_mat_type_table(array_index, BasicMaterial::PLANT); tile->set_mat_subtype_table(array_index, actual_mat.mat_index); } else if(actual_mat.mat_type >= 420) { //Wooden constructions. Different from growing plants. - tile->set_mat_type_table(array_index, BasicMaterial::WOOD); + tile->set_mat_type_table(array_index, BasicMaterial::WOOD); tile->set_mat_subtype_table(array_index, actual_mat.mat_index); } else { //Unknown and unsupported stuff. Will just be drawn as grey. - tile->set_mat_type_table(array_index, BasicMaterial::OTHER); + tile->set_mat_type_table(array_index, BasicMaterial::OTHER); tile->set_mat_subtype_table(array_index, actual_mat.mat_type); } num_valid_blocks++; } else { - tile->set_mat_type_table(array_index, BasicMaterial::AIR); + tile->set_mat_type_table(array_index, BasicMaterial::AIR); } } } @@ -344,12 +344,12 @@ static command_result GetRawNames(color_ostream &stream, const MapRequest *in, R out->set_available(false); return CR_OK; } - if (in->has_save_folder()) { //If no save folder is given, it means we don't care. - if (!(in->save_folder() == world->cur_savegame.save_dir || in->save_folder() == "ANY")) { //isoworld has a different map loaded, don't bother trying to load tiles for it, we don't have them. - out->set_available(false); - return CR_OK; - } - } + if (in->has_save_folder()) { //If no save folder is given, it means we don't care. + if (!(in->save_folder() == world->cur_savegame.save_dir || in->save_folder() == "ANY")) { //isoworld has a different map loaded, don't bother trying to load tiles for it, we don't have them. + out->set_available(false); + return CR_OK; + } + } out->set_available(true); for(int i = 0; i < world->raws.inorganics.size(); i++){ out->add_inorganic(world->raws.inorganics[i]->id); diff --git a/plugins/liquids.cpp b/plugins/liquids.cpp index 68229aaa3..1953728a4 100644 --- a/plugins/liquids.cpp +++ b/plugins/liquids.cpp @@ -611,7 +611,7 @@ command_result df_liquids_execute(color_ostream &out, OperationMode &cur_mode, d case M_KEEP: { auto bflags = (*biter)->BlockFlags(); - out << "flow bit 1 = " << bflags.bits.update_liquid << endl; + out << "flow bit 1 = " << bflags.bits.update_liquid << endl; out << "flow bit 2 = " << bflags.bits.update_liquid_twice << endl; } } diff --git a/plugins/lua/building-hacks.lua b/plugins/lua/building-hacks.lua index 033a01d5d..00a7fe3f2 100644 --- a/plugins/lua/building-hacks.lua +++ b/plugins/lua/building-hacks.lua @@ -1,24 +1,24 @@ local _ENV = mkmodule('plugins.building-hacks') --[[ - from native: - addBuilding(custom type,impassible fix (bool), consumed power, produced power, list of connection points, - update skip(0/nil to disable),table of frames,frame to tick ratio (-1 for machine control)) - from here: - registerBuilding{ - name -- custom workshop id e.g. SOAPMAKER << required! - fix_impassible -- make impassible tiles impassible to liquids too - consume -- how much machine power is needed to work - produce -- how much machine power is produced - gears -- a table or {x=?,y=?} of connection points for machines - action -- a table of number (how much ticks to skip) and a function which gets called on shop update - animate -- a table of - frames -- a table of - tables of 4 numbers (tile,fore,back,bright) OR - empty table (tile not modified) OR + from native: + addBuilding(custom type,impassible fix (bool), consumed power, produced power, list of connection points, + update skip(0/nil to disable),table of frames,frame to tick ratio (-1 for machine control)) + from here: + registerBuilding{ + name -- custom workshop id e.g. SOAPMAKER << required! + fix_impassible -- make impassible tiles impassible to liquids too + consume -- how much machine power is needed to work + produce -- how much machine power is produced + gears -- a table or {x=?,y=?} of connection points for machines + action -- a table of number (how much ticks to skip) and a function which gets called on shop update + animate -- a table of + frames -- a table of + tables of 4 numbers (tile,fore,back,bright) OR + empty table (tile not modified) OR {x= y= + 4 numbers like in first case} -- this generates full frame even, usefull for animations that change little (1-2 tiles) - frameLenght -- how many ticks does one frame take OR - isMechanical -- a bool that says to try to match to mechanical system (i.e. how gears are turning) - } + frameLenght -- how many ticks does one frame take OR + isMechanical -- a bool that says to try to match to mechanical system (i.e. how gears are turning) + } ]] _registeredStuff={} local function unregall(state) @@ -29,23 +29,23 @@ local function unregall(state) end end local function onUpdateLocal(workshop) - local f=_registeredStuff[workshop:getCustomType()] - if f then - f(workshop) - end + local f=_registeredStuff[workshop:getCustomType()] + if f then + f(workshop) + end end local function findCustomWorkshop(name) - local raws=df.global.world.raws.buildings.all - for k,v in ipairs(raws) do - if v.code==name then - return v - end - end + local raws=df.global.world.raws.buildings.all + for k,v in ipairs(raws) do + if v.code==name then + return v + end + end end local function registerUpdateAction(shopId,callback) - _registeredStuff[shopId]=callback - onUpdateAction._library=onUpdateLocal - dfhack.onStateChange.building_hacks=unregall + _registeredStuff[shopId]=callback + onUpdateAction._library=onUpdateLocal + dfhack.onStateChange.building_hacks=unregall end local function generateFrame(tiles,w,h) local mTiles={} @@ -66,7 +66,7 @@ local function generateFrame(tiles,w,h) return ret end local function processFrames(shop_def,frames) - local w,h=shop_def.dim_x,shop_def.dim_y + local w,h=shop_def.dim_x,shop_def.dim_y for frame_id,frame in ipairs(frames) do if frame[1].x~=nil then frames[frame_id]=generateFrame(frame,w,h) @@ -75,35 +75,35 @@ local function processFrames(shop_def,frames) return frames end function registerBuilding(args) - local shop_def=findCustomWorkshop(args.name) - local shop_id=shop_def.id - local fix_impassible - if args.fix_impassible then - fix_impassible=1 - else - fix_impassible=0 - end - local consume=args.consume or 0 - local produce=args.produce or 0 - local gears=args.gears or {} - local action=args.action --could be nil - local updateSkip=0 - if action~=nil then - updateSkip=action[1] - registerUpdateAction(shop_id,action[2]) - end - local animate=args.animate - local frameLength=1 - local frames - if animate~=nil then - frameLength=animate.frameLength - if animate.isMechanical then - frameLength=-1 - end - frames=processFrames(shop_def,animate.frames) - end - local roomSubset=args.canBeRoomSubset or -1 - addBuilding(shop_id,fix_impassible,consume,produce,gears,updateSkip,frames,frameLength,roomSubset) + local shop_def=findCustomWorkshop(args.name) + local shop_id=shop_def.id + local fix_impassible + if args.fix_impassible then + fix_impassible=1 + else + fix_impassible=0 + end + local consume=args.consume or 0 + local produce=args.produce or 0 + local gears=args.gears or {} + local action=args.action --could be nil + local updateSkip=0 + if action~=nil then + updateSkip=action[1] + registerUpdateAction(shop_id,action[2]) + end + local animate=args.animate + local frameLength=1 + local frames + if animate~=nil then + frameLength=animate.frameLength + if animate.isMechanical then + frameLength=-1 + end + frames=processFrames(shop_def,animate.frames) + end + local roomSubset=args.canBeRoomSubset or -1 + addBuilding(shop_id,fix_impassible,consume,produce,gears,updateSkip,frames,frameLength,roomSubset) end return _ENV \ No newline at end of file diff --git a/plugins/lua/dfusion.lua b/plugins/lua/dfusion.lua index 29272ce9e..7ba601e6a 100644 --- a/plugins/lua/dfusion.lua +++ b/plugins/lua/dfusion.lua @@ -54,7 +54,7 @@ function BinaryPatch:apply() if not self:test() then error(string.format("pre-data for binary patch does not match expected")) end - + local post_buf=df.new('uint8_t',#self.pre_data) for k,v in ipairs(self.pre_data) do if self.data[k]==nil then @@ -83,7 +83,7 @@ function BinaryPatch:remove(delete) error("can't remove BinaryPatch, not applied.") end local arr=ms.CheckedArray.new('uint8_t',self.address,self.address+#self.pre_data) - + local post_buf=df.new('uint8_t',#self.pre_data) for k,v in pairs(self.pre_data) do post_buf[k-1]=v @@ -112,7 +112,7 @@ plugins=plugins or {} BinaryPlugin=defclass(BinaryPlugin) BinaryPlugin.ATTRS {filename=DEFAULT_NIL,reloc_table={},name=DEFAULT_NIL} function BinaryPlugin:init(args) - + end function BinaryPlugin:postinit(args) if self.name==nil then error("Not a valid plugin name!") end @@ -211,26 +211,26 @@ function SimpleMenu:init(args) self.items={} end function SimpleMenu:add(name,entry,hints) - table.insert(self.items,{entry,name,hints}) + table.insert(self.items,{entry,name,hints}) end function SimpleMenu:display() - print("Select choice (q exits):") - for p,c in pairs(self.items) do - print(string.format("%3d).%s",p,c[2])) - end - local ans - repeat - local r - r=dfhack.lineedit() - if r==nil then return end - if r=='q' then return end - ans=tonumber(r) - - if ans==nil or not(ans<=#self.items and ans>0) then - print("Invalid choice.") - end - - until ans~=nil and (ans<=#self.items and ans>0) + print("Select choice (q exits):") + for p,c in pairs(self.items) do + print(string.format("%3d).%s",p,c[2])) + end + local ans + repeat + local r + r=dfhack.lineedit() + if r==nil then return end + if r=='q' then return end + ans=tonumber(r) + + if ans==nil or not(ans<=#self.items and ans>0) then + print("Invalid choice.") + end + + until ans~=nil and (ans<=#self.items and ans>0) if type(self.items[ans][1])=="function" then self.items[ans][1]() else diff --git a/plugins/lua/dfusion/adv_tools.lua b/plugins/lua/dfusion/adv_tools.lua index a17898808..39497590f 100644 --- a/plugins/lua/dfusion/adv_tools.lua +++ b/plugins/lua/dfusion/adv_tools.lua @@ -3,99 +3,99 @@ local dfu=require("plugins.dfusion") local tools=require("plugins.dfusion.tools") menu=dfu.SimpleMenu() function Reincarnate(trg_unit,swap_soul) --only for adventurer i guess - if swap_soul==nil then - swap_soul=true - end - local adv=trg_unit or df.global.world.units.active[0] - if adv.flags1.dead==false then - qerror("You are not dead (yet)!") - end - local hist_fig=dfhack.units.getNemesis(adv).figure - if hist_fig==nil then - qerror("No historical figure for adventurer...") - end - local events=df.global.world.history.events - local trg_hist_fig - for i=#events-1,0,-1 do -- reverse search because almost always it will be last entry - if df.history_event_hist_figure_diedst:is_instance(events[i]) then - --print("is instance:"..i) - if events[i].victim_hf==hist_fig.id then - --print("Is same id:"..i) - trg_hist_fig=events[i].slayer_hf - if trg_hist_fig then - trg_hist_fig=df.historical_figure.find(trg_hist_fig) - end - break - end - end - end - if trg_hist_fig ==nil then - qerror("Slayer not found") - end - - local trg_unit=trg_hist_fig.unit_id - if trg_unit==nil then - qerror("Unit id not found!") - end - local trg_unit_final=df.unit.find(trg_unit) - - change_adv(trg_unit_final) - if swap_soul then --actually add a soul... - t_soul=adv.status.current_soul - adv.status.current_soul=df.NULL - adv.status.souls:resize(0) - trg_unit_final.status.current_soul=t_soul - trg_unit_final.status.souls:insert(#trg_unit_final.status.souls,t_soul) - end + if swap_soul==nil then + swap_soul=true + end + local adv=trg_unit or df.global.world.units.active[0] + if adv.flags1.dead==false then + qerror("You are not dead (yet)!") + end + local hist_fig=dfhack.units.getNemesis(adv).figure + if hist_fig==nil then + qerror("No historical figure for adventurer...") + end + local events=df.global.world.history.events + local trg_hist_fig + for i=#events-1,0,-1 do -- reverse search because almost always it will be last entry + if df.history_event_hist_figure_diedst:is_instance(events[i]) then + --print("is instance:"..i) + if events[i].victim_hf==hist_fig.id then + --print("Is same id:"..i) + trg_hist_fig=events[i].slayer_hf + if trg_hist_fig then + trg_hist_fig=df.historical_figure.find(trg_hist_fig) + end + break + end + end + end + if trg_hist_fig ==nil then + qerror("Slayer not found") + end + + local trg_unit=trg_hist_fig.unit_id + if trg_unit==nil then + qerror("Unit id not found!") + end + local trg_unit_final=df.unit.find(trg_unit) + + change_adv(trg_unit_final) + if swap_soul then --actually add a soul... + t_soul=adv.status.current_soul + adv.status.current_soul=df.NULL + adv.status.souls:resize(0) + trg_unit_final.status.current_soul=t_soul + trg_unit_final.status.souls:insert(#trg_unit_final.status.souls,t_soul) + end end menu:add("Reincarnate",Reincarnate,{{df.unit,"optional"}})-- bool, optional function change_adv(unit,nemesis) - if nemesis==nil then - nemesis=true --default value is nemesis switch too. - end - if unit==nil then - unit=dfhack.gui.getSelectedUnit()--getCreatureAtPointer() - end - if unit==nil then - error("Invalid unit!") - end - local other=df.global.world.units.active - local unit_indx - for k,v in pairs(other) do - if v==unit then - unit_indx=k - break - end - end - if unit_indx==nil then - error("Unit not found in array?!") --should not happen - end - other[unit_indx]=other[0] - other[0]=unit - if nemesis then --basicly copied from advtools plugin... - local nem=dfhack.units.getNemesis(unit) - local other_nem=dfhack.units.getNemesis(other[unit_indx]) - if other_nem then - other_nem.flags[0]=false - other_nem.flags[1]=true - end - if nem then - nem.flags[0]=true - nem.flags[2]=true - for k,v in pairs(df.global.world.nemesis.all) do - if v.id==nem.id then - df.global.ui_advmode.player_id=k - end - end - else - qerror("Current unit does not have nemesis record, further working not guaranteed") - end - end + if nemesis==nil then + nemesis=true --default value is nemesis switch too. + end + if unit==nil then + unit=dfhack.gui.getSelectedUnit()--getCreatureAtPointer() + end + if unit==nil then + error("Invalid unit!") + end + local other=df.global.world.units.active + local unit_indx + for k,v in pairs(other) do + if v==unit then + unit_indx=k + break + end + end + if unit_indx==nil then + error("Unit not found in array?!") --should not happen + end + other[unit_indx]=other[0] + other[0]=unit + if nemesis then --basicly copied from advtools plugin... + local nem=dfhack.units.getNemesis(unit) + local other_nem=dfhack.units.getNemesis(other[unit_indx]) + if other_nem then + other_nem.flags[0]=false + other_nem.flags[1]=true + end + if nem then + nem.flags[0]=true + nem.flags[2]=true + for k,v in pairs(df.global.world.nemesis.all) do + if v.id==nem.id then + df.global.ui_advmode.player_id=k + end + end + else + qerror("Current unit does not have nemesis record, further working not guaranteed") + end + end end menu:add("Change adventurer",change_adv) function log_pos() local adv=df.global.world.units.active[0] - + local wmap=df.global.world.map local sub_pos={x=adv.pos.x,y=adv.pos.y,z=adv.pos.z} local region_pos={x=wmap.region_x,y=wmap.region_y,z=wmap.region_z} diff --git a/plugins/lua/dfusion/embark.lua b/plugins/lua/dfusion/embark.lua index 6e5df4eef..2b63a4c5b 100644 --- a/plugins/lua/dfusion/embark.lua +++ b/plugins/lua/dfusion/embark.lua @@ -14,7 +14,7 @@ if myos=="windows" then error("caste and race count must be less then "..MAX_RACES) end local n_to_id=require("plugins.dfusion.tools").build_race_names() - + local ids={} for k,v in pairs(races) do local race=v[1] or v @@ -30,7 +30,7 @@ if myos=="windows" then if race_caste_data~=nil then self:parseRaces(race_caste_data) end - + if stoff==nil then error("address for start_dwarf_count not found!") end @@ -41,8 +41,8 @@ if myos=="windows" then for k,v in ipairs(tmp_table) do table.insert(needle,v) end - - local mem=ms.get_code_segment() + + local mem=ms.get_code_segment() print(mem.uint8_t:addr2idx(stoff)) print(mem.uint8_t:find(needle,mem.uint8_t:addr2idx(stoff))) local _,trg_offset=mem.uint8_t:find(needle,mem.uint8_t:addr2idx(stoff),nil)--maybe endoff=stoff+bignumber @@ -58,31 +58,31 @@ if myos=="windows" then if caste_offset==nil or caste_offset-stoff>1000 then error("Caste change code not found or found too far!") end - + self.disable_castes=self.disable_castes or dfu.BinaryPatch{pre_data={0x83,0xc8,0xff},data={0x90,0x90,0x90},address=caste_offset,name="custom_embark_caste_disable"} self.disable_castes:apply() - - + + self:setEmbarkParty(self.race_caste_data) local caste_array=self:get_or_alloc("caste_array","uint16_t",MAX_RACES) local race_array=self:get_or_alloc("race_array","uint16_t",MAX_RACES) - + local race_array_off,caste_array_off local _ _,race_array_off=df.sizeof(race_array) _,caste_array_off=df.sizeof(caste_array) self:set_marker_dword("race",caste_array_off) --hehe... mixed them up i guess... self:set_marker_dword("caste",race_array_off) - + self:move_to_df() self.call_patch:apply() self.installed=true end - + function CustomEmbark:setEmbarkParty(racesAndCastes) local stoff=dfhack.internal.getAddress('start_dwarf_count') - - + + if self.dwarfcount== nil then self.dwarfcount=dfu.BinaryPatch{pre_data=dfu.dwordToTable(7),data=dfu.dwordToTable(#self.race_caste_data),address=stoff,name="custom_embark_embarkcount"} self.dwarfcount:apply() @@ -91,7 +91,7 @@ if myos=="windows" then end local caste_array=self:get_or_alloc("caste_array","uint16_t",MAX_RACES) local race_array=self:get_or_alloc("race_array","uint16_t",MAX_RACES) - + for k,v in ipairs(self.race_caste_data) do caste_array[k-1]=v[2] or -1 race_array[k-1]=v[1] diff --git a/plugins/lua/dfusion/friendship.lua b/plugins/lua/dfusion/friendship.lua index 81996fccf..5cdc3e7d3 100644 --- a/plugins/lua/dfusion/friendship.lua +++ b/plugins/lua/dfusion/friendship.lua @@ -13,7 +13,7 @@ function FriendshipRainbow:findall_needles(codesg,needle) -- todo move to memsca local cidx,caddr=codesg.uint8_t:find(needle) local ret={} while cidx~=nil do - table.insert(ret,{cidx,caddr}) + table.insert(ret,{cidx,caddr}) cidx,caddr=codesg.uint8_t:find(needle,cidx+1) end return ret @@ -23,10 +23,10 @@ function FriendshipRainbow:find_one(codesg,needle,crace) return self:findall_needles(codesg,needle) end function FriendshipRainbow:find_all() - local code=ms.get_code_segment() + local code=ms.get_code_segment() local locations={} local _,crace=df.sizeof(df.global.ui:_field("race_id")) - + dfu.concatTables(locations,self:find_one(code,{0x66,0xa1},crace)) --mov ax,[ptr] dfu.concatTables(locations,self:find_one(code,{0xa1},crace)) --mov ax,[ptr] local registers= @@ -40,11 +40,11 @@ function FriendshipRainbow:find_all() --0x2d, --ebp not used? } for k,reg in ipairs(registers) do - + dfu.concatTables(locations,self:find_one(code,{0x0f,0xbf,reg},crace)) --movsx reg,[ptr] dfu.concatTables(locations,self:find_one(code,{0x66,0x8b,reg},crace)) --mov reg,[ptr] end - + return self:filter_locations(code,locations) end function FriendshipRainbow:filter_locations(codesg,locations) @@ -57,7 +57,7 @@ function FriendshipRainbow:filter_locations(codesg,locations) 0xb8,0xbb,0xb9,0xba,0xbe,0xbf} for _,entry in ipairs(locations) do for _,r in ipairs(registers) do - + local idx,addr=codesg.uint8_t:find({0x39,r,0x8c,0x00,0x00,0x00}, codesg.uint8_t:addr2idx(entry[2]),codesg.uint8_t:addr2idx(entry[2])+MAX_CODE_DIST) if addr then @@ -90,7 +90,7 @@ function FriendshipRainbow:set_races(arr) local n_to_id=require("plugins.dfusion.tools").build_race_names() local ids={} for k,v in ipairs(self.race_data) do -- to check if all races are valid. - ids[k]=n_to_id[v] + ids[k]=n_to_id[v] end for k,v in ipairs(ids) do arr[k-1]=ids[k] diff --git a/plugins/lua/dfusion/tools.lua b/plugins/lua/dfusion/tools.lua index b2cbcf8e2..7a94e09ed 100644 --- a/plugins/lua/dfusion/tools.lua +++ b/plugins/lua/dfusion/tools.lua @@ -19,205 +19,205 @@ function build_race_names() return RaceNames end end -function setrace(name) - local RaceTable=build_race_names() - print("Your current race is:"..df.global.world.raws.creatures.all[df.global.ui.race_id].creature_id) - local id - if name == nil then - print("Type new race's token name in full caps (q to quit):") - repeat - local entry=dfhack.lineedit() - if entry=="q" then - return - end - id=RaceTable[entry] - until id~=nil - else - id=RaceTable[name] - if id==nil then - error("Name not found!") - end - end - df.global.ui.race_id=id +function setrace(name) + local RaceTable=build_race_names() + print("Your current race is:"..df.global.world.raws.creatures.all[df.global.ui.race_id].creature_id) + local id + if name == nil then + print("Type new race's token name in full caps (q to quit):") + repeat + local entry=dfhack.lineedit() + if entry=="q" then + return + end + id=RaceTable[entry] + until id~=nil + else + id=RaceTable[name] + if id==nil then + error("Name not found!") + end + end + df.global.ui.race_id=id end menu:add("Set current race",setrace) -function GiveSentience(names) - local RaceTable=build_race_names() --slow.If loaded don't load again +function GiveSentience(names) + local RaceTable=build_race_names() --slow.If loaded don't load again local id,ids - if names ==nil then - ids={} - print("Type race's token name in full caps to give sentience to:") - repeat - id=dfhack.lineedit() - id=RaceTable[entry] + if names ==nil then + ids={} + print("Type race's token name in full caps to give sentience to:") + repeat + id=dfhack.lineedit() + id=RaceTable[entry] if id~=nil then table.insert(ids,id) end - until id==nil - - else - ids={} - for _,name in pairs(names) do - id=RaceTable[name] - table.insert(ids,id) - end - end - for _,id in pairs(ids) do - local races=df.global.world.raws.creatures.all + until id==nil - local castes=races[id].caste - print(string.format("Caste count:%i",#castes)) - for i =0,#castes-1 do - - print("Caste name:"..castes[i].caste_id.."...") - - local flags=castes[i].flags - --print(string.format("%x",flagoffset)) - if flags.CAN_SPEAK then - print("\tis sentient.") - else - print("\tnon sentient. Allocating IQ...") - flags.CAN_SPEAK=true - end - end - end + else + ids={} + for _,name in pairs(names) do + id=RaceTable[name] + table.insert(ids,id) + end + end + for _,id in pairs(ids) do + local races=df.global.world.raws.creatures.all + + local castes=races[id].caste + print(string.format("Caste count:%i",#castes)) + for i =0,#castes-1 do + + print("Caste name:"..castes[i].caste_id.."...") + + local flags=castes[i].flags + --print(string.format("%x",flagoffset)) + if flags.CAN_SPEAK then + print("\tis sentient.") + else + print("\tnon sentient. Allocating IQ...") + flags.CAN_SPEAK=true + end + end + end end menu:add("Give Sentience",GiveSentience) function MakeFollow(unit,trgunit) - if unit == nil then - unit=dfhack.gui.getSelectedUnit() - end - if unit== nil then - error("Invalid creature") - end - if trgunit==nil then - trgunit=df.global.world.units.active[0] - end - unit.relations.group_leader_id=trgunit.id - local u_nem=dfhack.units.getNemesis(unit) - local t_nem=dfhack.units.getNemesis(trgunit) - if u_nem then - u_nem.group_leader_id=t_nem.id - end - if t_nem and u_nem then - t_nem.companions:insert(#t_nem.companions,u_nem.id) - end + if unit == nil then + unit=dfhack.gui.getSelectedUnit() + end + if unit== nil then + error("Invalid creature") + end + if trgunit==nil then + trgunit=df.global.world.units.active[0] + end + unit.relations.group_leader_id=trgunit.id + local u_nem=dfhack.units.getNemesis(unit) + local t_nem=dfhack.units.getNemesis(trgunit) + if u_nem then + u_nem.group_leader_id=t_nem.id + end + if t_nem and u_nem then + t_nem.companions:insert(#t_nem.companions,u_nem.id) + end end menu:add("Make creature follow",MakeFollow) function project(unit,trg) --TODO add to menu? - if unit==nil then - unit=getCreatureAtPointer() - end - - if unit==nil then - error("Failed to project unit. Unit not selected/valid") - end - -- todo: add projectile to world, point to unit, add flag to unit, add gen-ref to projectile. - local p=df.proj_unitst:new() - local startpos={x=unit.pos.x,y=unit.pos.y,z=unit.pos.z} - p.origin_pos=startpos - p.target_pos=trg - p.cur_pos=startpos - p.prev_pos=startpos - p.unit=unit - --- wtf stuff - p.unk14=100 - p.unk16=-1 - p.unk23=-1 - p.fall_delay=5 - p.fall_counter=5 - p.collided=true - -- end wtf - local citem=df.global.world.proj_list - local maxid=1 - local newlink=df.proj_list_link:new() - newlink.item=p - while citem.item~= nil do - if citem.item.id>maxid then maxid=citem.item.id end - if citem.next ~= nil then - citem=citem.next - else - break - end - end - p.id=maxid+1 - newlink.prev=citem - citem.next=newlink - local proj_ref=df.general_ref_projectile:new() - proj_ref.projectile_id=p.id - unit.general_refs:insert(#unit.general_refs,proj_ref) - unit.flags1.projectile=true + if unit==nil then + unit=getCreatureAtPointer() + end + + if unit==nil then + error("Failed to project unit. Unit not selected/valid") + end + -- todo: add projectile to world, point to unit, add flag to unit, add gen-ref to projectile. + local p=df.proj_unitst:new() + local startpos={x=unit.pos.x,y=unit.pos.y,z=unit.pos.z} + p.origin_pos=startpos + p.target_pos=trg + p.cur_pos=startpos + p.prev_pos=startpos + p.unit=unit + --- wtf stuff + p.unk14=100 + p.unk16=-1 + p.unk23=-1 + p.fall_delay=5 + p.fall_counter=5 + p.collided=true + -- end wtf + local citem=df.global.world.proj_list + local maxid=1 + local newlink=df.proj_list_link:new() + newlink.item=p + while citem.item~= nil do + if citem.item.id>maxid then maxid=citem.item.id end + if citem.next ~= nil then + citem=citem.next + else + break + end + end + p.id=maxid+1 + newlink.prev=citem + citem.next=newlink + local proj_ref=df.general_ref_projectile:new() + proj_ref.projectile_id=p.id + unit.general_refs:insert(#unit.general_refs,proj_ref) + unit.flags1.projectile=true end function empregnate(unit) - if unit==nil then - unit=dfhack.gui.getSelectedUnit() - end - if unit==nil then - error("Failed to empregnate. Unit not selected/valid") - end - if unit.curse then - unit.curse.add_tags2.STERILE=false - end - local genes = unit.appearance.genes - if unit.relations.pregnancy_genes == nil then - print("creating preg ptr.") - if false then - print(string.format("%x %x",df.sizeof(unit.relations:_field("pregnancy_genes")))) - return - end - unit.relations.pregnancy_genes = { new = true, assign = genes } - end - local ngenes = unit.relations.pregnancy_genes - if #ngenes.appearance ~= #genes.appearance or #ngenes.colors ~= #genes.colors then - print("Array sizes incorrect, fixing.") - ngenes:assign(genes); - end - print("Setting preg timer.") - unit.relations.pregnancy_timer=10 - unit.relations.pregnancy_caste=1 + if unit==nil then + unit=dfhack.gui.getSelectedUnit() + end + if unit==nil then + error("Failed to empregnate. Unit not selected/valid") + end + if unit.curse then + unit.curse.add_tags2.STERILE=false + end + local genes = unit.appearance.genes + if unit.relations.pregnancy_genes == nil then + print("creating preg ptr.") + if false then + print(string.format("%x %x",df.sizeof(unit.relations:_field("pregnancy_genes")))) + return + end + unit.relations.pregnancy_genes = { new = true, assign = genes } + end + local ngenes = unit.relations.pregnancy_genes + if #ngenes.appearance ~= #genes.appearance or #ngenes.colors ~= #genes.colors then + print("Array sizes incorrect, fixing.") + ngenes:assign(genes); + end + print("Setting preg timer.") + unit.relations.pregnancy_timer=10 + unit.relations.pregnancy_caste=1 end menu:add("Empregnate",empregnate) function healunit(unit) if unit==nil then - unit=dfhack.gui.getSelectedUnit() - end + unit=dfhack.gui.getSelectedUnit() + end + + if unit==nil then + error("Failed to Heal unit. Unit not selected/valid") + end - if unit==nil then - error("Failed to Heal unit. Unit not selected/valid") - end - unit.body.wounds:resize(0) -- memory leak here :/ - unit.body.blood_count=unit.body.blood_max - --set flags for standing and grasping... - unit.status2.limbs_stand_max=4 - unit.status2.limbs_stand_count=4 - unit.status2.limbs_grasp_max=4 - unit.status2.limbs_grasp_count=4 - --should also set temperatures, and flags for breath etc... - unit.flags1.dead=false - unit.flags2.calculated_bodyparts=false - unit.flags2.calculated_nerves=false - unit.flags2.circulatory_spray=false - unit.flags2.vision_good=true - unit.flags2.vision_damaged=false - unit.flags2.vision_missing=false - unit.counters.winded=0 - unit.counters.unconscious=0 - for k,v in pairs(unit.body.components) do - for kk,vv in pairs(v) do - if k == 'body_part_status' then v[kk].whole = 0 else v[kk] = 0 end - end - end + unit.body.blood_count=unit.body.blood_max + --set flags for standing and grasping... + unit.status2.limbs_stand_max=4 + unit.status2.limbs_stand_count=4 + unit.status2.limbs_grasp_max=4 + unit.status2.limbs_grasp_count=4 + --should also set temperatures, and flags for breath etc... + unit.flags1.dead=false + unit.flags2.calculated_bodyparts=false + unit.flags2.calculated_nerves=false + unit.flags2.circulatory_spray=false + unit.flags2.vision_good=true + unit.flags2.vision_damaged=false + unit.flags2.vision_missing=false + unit.counters.winded=0 + unit.counters.unconscious=0 + for k,v in pairs(unit.body.components) do + for kk,vv in pairs(v) do + if k == 'body_part_status' then v[kk].whole = 0 else v[kk] = 0 end + end + end end menu:add("Heal unit",healunit) function powerup(unit,labor_rating,military_rating,skills) if unit==nil then - unit=dfhack.gui.getSelectedUnit() - end - if unit==nil then - error("Failed to power up unit. Unit not selected/valid") - end - + unit=dfhack.gui.getSelectedUnit() + end + if unit==nil then + error("Failed to power up unit. Unit not selected/valid") + end + if unit.status.current_soul== nil then error("Failed to power up unit. Unit has no soul") end @@ -237,7 +237,7 @@ function powerup(unit,labor_rating,military_rating,skills) end utils.insert_or_update(unit.status.current_soul.skills, { new = true, id = sv, rating = new_rating, experience = (new_rating * 500) + (new_rating * (new_rating - 1)) * 50}, 'id') end - + end menu:add("Power up",powerup) return _ENV diff --git a/plugins/lua/eventful.lua b/plugins/lua/eventful.lua index e8bd38827..a1093b372 100644 --- a/plugins/lua/eventful.lua +++ b/plugins/lua/eventful.lua @@ -1,7 +1,7 @@ local _ENV = mkmodule('plugins.eventful') --[[ - - + + --]] local function getShopName(btype,bsubtype,bcustom) local typenames_shop={[df.workshop_type.Carpenters]="CARPENTERS",[df.workshop_type.Farmers]="FARMERS", @@ -22,13 +22,13 @@ local function getShopName(btype,bsubtype,bcustom) [df.furnace_type.MagmaGlassFurnace]="MAGMA_GLASS_FURNACE",[df.furnace_type.MagmaKiln]="MAGMA_KILN", [df.furnace_type.Kiln]="KILN"} if btype==df.building_type.Workshop then - if typenames_shop[bsubtype]~=nil then + if typenames_shop[bsubtype]~=nil then return typenames_shop[bsubtype] else return df.building_def_workshopst.find(bcustom).code end elseif btype==df.building_type.Furnace then - if typenames_furnace[bsubtype]~=nil then + if typenames_furnace[bsubtype]~=nil then return typenames_furnace[bsubtype] else return df.building_def_furnacest.find(bcustom).code diff --git a/plugins/lua/stockflow.lua b/plugins/lua/stockflow.lua index d1c06525a..27efdf6c4 100644 --- a/plugins/lua/stockflow.lua +++ b/plugins/lua/stockflow.lua @@ -62,7 +62,7 @@ function list_orders() print("Stockpile #"..num, name, trigger) listed = true end - + if not listed then print("No manager jobs have been set for your stockpiles.") print("Use j in a stockpile menu to create one...") @@ -79,7 +79,7 @@ function start_bookkeeping() result[reaction_id] = amount end end - + jobs_to_create = result end @@ -89,7 +89,7 @@ function finish_bookkeeping() for reaction, amount in pairs(jobs_to_create) do create_orders(reaction_list[reaction].order, amount) end - + jobs_to_create = {} end @@ -98,7 +98,7 @@ function stockpile_settings(sp) if not order then return "No job selected", "" end - + return order.entry.value, trigger_name(order) end @@ -138,7 +138,7 @@ function collect_orders() end end end - + return result end @@ -158,12 +158,12 @@ function reaction_entry(job_type, values, name) mat_type = -1, mat_index = -1, } - + if values then -- Override default attributes. order:assign(values) end - + return { name = name or df.job_type.attrs[job_type].caption, order = order, @@ -175,20 +175,20 @@ function resource_reactions(reactions, job_type, mat_info, keys, items, options) for key, value in pairs(mat_info.management) do values[key] = value end - + for _, itemid in ipairs(keys) do local itemdef = items[itemid] local start = options.verb or mat_info.verb or "Make" if options.adjective then start = start.." "..itemdef.adjective end - + if (not options.permissible) or options.permissible(itemdef) then local item_name = " "..itemdef[options.name_field or "name"] if options.capitalize then item_name = string.gsub(item_name, " .", string.upper) end - + values.item_subtype = itemid table.insert(reactions, reaction_entry(job_type, values, start.." "..mat_info.adjective..item_name)) end @@ -202,7 +202,7 @@ function material_reactions(reactions, itemtypes, mat_info) if row[3] then line = line.." "..row[3] end - + table.insert(reactions, reaction_entry(row[1], mat_info.management, line)) end end @@ -225,38 +225,38 @@ function collect_reactions() -- but I currently can only find it while the job selection screen is active. -- Even that list doesn't seem to include their names. local result = {} - + -- A few task types are obsolete in newer DF versions. local v34 = string.match(dfhack.getDFVersion(), "v0.34") - + -- Caching the enumeration might not be important, but saves lookups. local job_types = df.job_type - + local materials = { rock = { adjective = "rock", management = {mat_type = 0}, }, } - + for _, name in ipairs{"wood", "cloth", "leather", "silk", "yarn", "bone", "shell", "tooth", "horn", "pearl"} do materials[name] = { adjective = name, management = {material_category = {[name] = true}}, } end - + materials.wood.adjective = "wooden" materials.tooth.adjective = "ivory/tooth" materials.leather.clothing_flag = "LEATHER" - + -- Collection and Entrapment table.insert(result, reaction_entry(job_types.CollectWebs)) table.insert(result, reaction_entry(job_types.CollectSand)) table.insert(result, reaction_entry(job_types.CollectClay)) table.insert(result, reaction_entry(job_types.CatchLiveLandAnimal)) table.insert(result, reaction_entry(job_types.CatchLiveFish)) - + -- Cutting, encrusting, and metal extraction. local rock_types = df.global.world.raws.inorganics for rock_id = #rock_types-1, 0, -1 do @@ -267,35 +267,35 @@ function collect_reactions() mat_type = 0, mat_index = rock_id, }, "Cut "..rock_name)) - + table.insert(result, reaction_entry(job_types.EncrustWithGems, { mat_type = 0, mat_index = rock_id, item_category = {finished_goods = true}, }, "Encrust Finished Goods With "..rock_name)) - + table.insert(result, reaction_entry(job_types.EncrustWithGems, { mat_type = 0, mat_index = rock_id, item_category = {furniture = true}, }, "Encrust Furniture With "..rock_name)) - + table.insert(result, reaction_entry(job_types.EncrustWithGems, { mat_type = 0, mat_index = rock_id, item_category = {ammo = true}, }, "Encrust Ammo With "..rock_name)) end - + if #rock_types[rock_id].metal_ore.mat_index > 0 then table.insert(result, reaction_entry(job_types.SmeltOre, {mat_type = 0, mat_index = rock_id}, "Smelt "..rock_name.." Ore")) end - + if #rock_types[rock_id].thread_metal.mat_index > 0 then table.insert(result, reaction_entry(job_types.ExtractMetalStrands, {mat_type = 0, mat_index = rock_id})) end end - + -- Glass cutting and encrusting, with different job numbers. -- We could search the entire table, but glass is less subject to raws. local glass_types = df.global.world.raws.mat_table.builtin @@ -309,61 +309,61 @@ function collect_reactions() adjective = glass_name, management = {mat_type = glass_id}, }) - + table.insert(result, reaction_entry(job_types.CutGlass, {mat_type = glass_id}, "Cut "..glass_name)) - + table.insert(result, reaction_entry(job_types.EncrustWithGlass, { mat_type = glass_id, item_category = {finished_goods = true}, }, "Encrust Finished Goods With "..glass_name)) - + table.insert(result, reaction_entry(job_types.EncrustWithGlass, { mat_type = glass_id, item_category = {furniture = true}, }, "Encrust Furniture With "..glass_name)) - + table.insert(result, reaction_entry(job_types.EncrustWithGlass, { mat_type = glass_id, item_category = {ammo = true}, }, "Encrust Ammo With "..glass_name)) end end - + -- Dyeing table.insert(result, reaction_entry(job_types.DyeThread)) table.insert(result, reaction_entry(job_types.DyeCloth)) - + -- Sew Image local cloth_mats = {materials.cloth, materials.silk, materials.yarn, materials.leather} for _, material in ipairs(cloth_mats) do material_reactions(result, {{job_types.SewImage, "Sew", "Image"}}, material) end - + for _, spec in ipairs{materials.bone, materials.shell, materials.tooth, materials.horn, materials.pearl} do material_reactions(result, {{job_types.DecorateWith, "Decorate With"}}, spec) end - + table.insert(result, reaction_entry(job_types.MakeTotem)) table.insert(result, reaction_entry(job_types.ButcherAnimal)) table.insert(result, reaction_entry(job_types.MillPlants)) table.insert(result, reaction_entry(job_types.MakePotashFromLye)) table.insert(result, reaction_entry(job_types.MakePotashFromAsh)) - + -- Kitchen table.insert(result, reaction_entry(job_types.PrepareMeal, {mat_type = 2}, "Prepare Easy Meal")) table.insert(result, reaction_entry(job_types.PrepareMeal, {mat_type = 3}, "Prepare Fine Meal")) table.insert(result, reaction_entry(job_types.PrepareMeal, {mat_type = 4}, "Prepare Lavish Meal")) - + if v34 then -- Brew Drink table.insert(result, reaction_entry(job_types.BrewDrink)) end - + -- Weaving table.insert(result, reaction_entry(job_types.WeaveCloth, {material_category = {plant = true}}, "Weave Thread into Cloth")) table.insert(result, reaction_entry(job_types.WeaveCloth, {material_category = {silk = true}}, "Weave Thread into Silk")) table.insert(result, reaction_entry(job_types.WeaveCloth, {material_category = {yarn = true}}, "Weave Yarn into Cloth")) - + -- Extracts, farmer's workshop, and wood burning table.insert(result, reaction_entry(job_types.ExtractFromPlants)) table.insert(result, reaction_entry(job_types.ExtractFromRawFish)) @@ -382,7 +382,7 @@ function collect_reactions() table.insert(result, reaction_entry(job_types.ProcessPlantsBarrel)) table.insert(result, reaction_entry(job_types.MakeCharcoal)) table.insert(result, reaction_entry(job_types.MakeAsh)) - + -- Reactions defined in the raws. -- Not all reactions are allowed to the civilization. -- That includes "Make sharp rock" by default. @@ -392,7 +392,7 @@ function collect_reactions() local name = string.gsub(reaction.name, "^.", string.upper) table.insert(result, reaction_entry(job_types.CustomReaction, {reaction_name = reaction.code}, name)) end - + -- Metal forging local itemdefs = df.global.world.raws.itemdefs for rock_id = 0, #rock_types - 1 do @@ -403,76 +403,76 @@ function collect_reactions() management = {mat_type = 0, mat_index = rock_id}, verb = "Forge", } - + if material.flags.IS_METAL then table.insert(result, reaction_entry(job_types.StudWith, mat_flags.management, "Stud With "..rock_name)) - + if material.flags.ITEMS_WEAPON then -- Todo: Are these really the right flags to check? resource_reactions(result, job_types.MakeWeapon, mat_flags, entity.resources.weapon_type, itemdefs.weapons, { permissible = (function(itemdef) return itemdef.skill_ranged == -1 end), }) - + -- Is this entirely disconnected from the entity? material_reactions(result, {{MakeBallistaArrowHead, "Forge", "Ballista Arrow Head"}}, mat_flags) - + resource_reactions(result, job_types.MakeTrapComponent, mat_flags, entity.resources.trapcomp_type, itemdefs.trapcomps, { adjective = true, }) - + resource_reactions(result, job_types.AssembleSiegeAmmo, mat_flags, entity.resources.siegeammo_type, itemdefs.siege_ammo, { verb = "Assemble", }) end - + if material.flags.ITEMS_WEAPON_RANGED then resource_reactions(result, job_types.MakeWeapon, mat_flags, entity.resources.weapon_type, itemdefs.weapons, { permissible = (function(itemdef) return itemdef.skill_ranged >= 0 end), }) end - + if material.flags.ITEMS_DIGGER then -- Todo: Ranged or training digging weapons? resource_reactions(result, job_types.MakeWeapon, mat_flags, entity.resources.digger_type, itemdefs.weapons, { }) end - + if material.flags.ITEMS_AMMO then resource_reactions(result, job_types.MakeAmmo, mat_flags, entity.resources.ammo_type, itemdefs.ammo, { name_field = "name_plural", }) end - + if material.flags.ITEMS_ANVIL then material_reactions(result, {{job_types.ForgeAnvil, "Forge", "Anvil"}}, mat_flags) end - + if material.flags.ITEMS_ARMOR then local metalclothing = (function(itemdef) return itemdef.props.flags.METAL end) clothing_reactions(result, mat_flags, metalclothing) resource_reactions(result, job_types.MakeShield, mat_flags, entity.resources.shield_type, itemdefs.shields, { }) end - + if material.flags.ITEMS_SOFT then local metalclothing = (function(itemdef) return itemdef.props.flags.SOFT and not itemdef.props.flags.METAL end) clothing_reactions(result, mat_flags, metalclothing) end - + if material.flags.ITEMS_HARD then resource_reactions(result, job_types.MakeTool, mat_flags, entity.resources.tool_type, itemdefs.tools, { permissible = (function(itemdef) return itemdef.flags.HARD_MAT end), capitalize = true, }) end - + if material.flags.ITEMS_METAL then resource_reactions(result, job_types.MakeTool, mat_flags, entity.resources.tool_type, itemdefs.tools, { permissible = (function(itemdef) return itemdef.flags.METAL_MAT end), capitalize = true, }) end - + if material.flags.ITEMS_HARD then material_reactions(result, { {job_types.ConstructDoor, "Construct", "Door"}, @@ -505,7 +505,7 @@ function collect_reactions() {job_types.MakeCrafts, "Make", "Crafts"}, }, mat_flags) end - + if material.flags.ITEMS_SOFT then material_reactions(result, { {job_types.MakeBackpack, "Make", "Backpack"}, @@ -516,26 +516,26 @@ function collect_reactions() end end end - + -- Traction Bench table.insert(result, reaction_entry(job_types.ConstructTractionBench)) - + -- Non-metal weapons resource_reactions(result, job_types.MakeWeapon, materials.wood, entity.resources.weapon_type, itemdefs.weapons, { permissible = (function(itemdef) return itemdef.skill_ranged >= 0 end), }) - + resource_reactions(result, job_types.MakeWeapon, materials.wood, entity.resources.training_weapon_type, itemdefs.weapons, { }) - + resource_reactions(result, job_types.MakeWeapon, materials.bone, entity.resources.weapon_type, itemdefs.weapons, { permissible = (function(itemdef) return itemdef.skill_ranged >= 0 end), }) - + resource_reactions(result, job_types.MakeWeapon, materials.rock, entity.resources.weapon_type, itemdefs.weapons, { permissible = (function(itemdef) return itemdef.flags.CAN_STONE end), }) - + -- Wooden items -- Closely related to the ITEMS_HARD list. material_reactions(result, { @@ -552,12 +552,12 @@ function collect_reactions() {job_types.MakeGoblet, "Make", "Cup"}, {job_types.MakeInstrument, "Make", "Instrument"}, }, materials.wood) - + resource_reactions(result, job_types.MakeTool, materials.wood, entity.resources.tool_type, itemdefs.tools, { -- permissible = (function(itemdef) return itemdef.flags.WOOD_MAT end), capitalize = true, }) - + material_reactions(result, { {job_types.MakeToy, "Make", "Toy"}, {job_types.ConstructBlocks, "Construct", "Blocks"}, @@ -570,12 +570,12 @@ function collect_reactions() {job_types.MakeCage, "Make", "Cage"}, {job_types.MakePipeSection, "Make", "Pipe Section"}, }, materials.wood) - + resource_reactions(result, job_types.MakeTrapComponent, materials.wood, entity.resources.trapcomp_type, itemdefs.trapcomps, { permissible = (function(itemdef) return itemdef.flags.WOOD end), adjective = true, }) - + -- Rock items material_reactions(result, { {job_types.ConstructDoor, "Construct", "Door"}, @@ -591,12 +591,12 @@ function collect_reactions() {job_types.MakeGoblet, "Make", "Mug"}, {job_types.MakeInstrument, "Make", "Instrument"}, }, materials.rock) - + resource_reactions(result, job_types.MakeTool, materials.rock, entity.resources.tool_type, itemdefs.tools, { permissible = (function(itemdef) return itemdef.flags.HARD_MAT end), capitalize = true, }) - + material_reactions(result, { {job_types.MakeToy, "Make", "Toy"}, {job_types.ConstructQuern, "Construct", "Quern"}, @@ -605,7 +605,7 @@ function collect_reactions() {job_types.ConstructStatue, "Construct", "Statue"}, {job_types.ConstructBlocks, "Construct", "Blocks"}, }, materials.rock) - + -- Glass items for _, mat_info in ipairs(glasses) do material_reactions(result, { @@ -622,12 +622,12 @@ function collect_reactions() {job_types.MakeGoblet, "Make", "Goblet"}, {job_types.MakeInstrument, "Make", "Instrument"}, }, mat_info) - + resource_reactions(result, job_types.MakeTool, mat_info, entity.resources.tool_type, itemdefs.tools, { permissible = (function(itemdef) return itemdef.flags.HARD_MAT end), capitalize = true, }) - + material_reactions(result, { {job_types.MakeToy, "Make", "Toy"}, {job_types.ConstructStatue, "Construct", "Statue"}, @@ -635,44 +635,44 @@ function collect_reactions() {job_types.MakeCage, "Make", "Terrarium"}, {job_types.MakePipeSection, "Make", "Tube"}, }, mat_info) - + resource_reactions(result, job_types.MakeTrapComponent, mat_info, entity.resources.trapcomp_type, itemdefs.trapcomps, { adjective = true, }) end - + -- Bed, specified as wooden. table.insert(result, reaction_entry(job_types.ConstructBed, materials.wood.management)) - + -- Windows for _, mat_info in ipairs(glasses) do material_reactions(result, { {job_types.MakeWindow, "Make", "Window"}, }, mat_info) end - + -- Rock Mechanisms table.insert(result, reaction_entry(job_types.ConstructMechanisms, materials.rock.management)) - + resource_reactions(result, job_types.AssembleSiegeAmmo, materials.wood, entity.resources.siegeammo_type, itemdefs.siege_ammo, { verb = "Assemble", }) - + for _, mat_info in ipairs(glasses) do material_reactions(result, { {job_types.MakeRawGlass, "Make Raw", nil}, }, mat_info) end - + material_reactions(result, { {job_types.MakeBackpack, "Make", "Backpack"}, {job_types.MakeQuiver, "Make", "Quiver"}, }, materials.leather) - + for _, material in ipairs(cloth_mats) do clothing_reactions(result, material, (function(itemdef) return itemdef.props.flags[material.clothing_flag or "SOFT"] end)) end - + -- Boxes, Bags, and Ropes local boxmats = { {mats = {materials.wood}, box = "Chest"}, @@ -693,7 +693,7 @@ function collect_reactions() end end end - + for _, mat in ipairs{ materials.wood, materials.rock, @@ -709,28 +709,28 @@ function collect_reactions() } do material_reactions(result, {{job_types.MakeCrafts, "Make", "Crafts"}}, mat) end - + -- Siege engine parts table.insert(result, reaction_entry(job_types.ConstructCatapultParts, materials.wood.management)) table.insert(result, reaction_entry(job_types.ConstructBallistaParts, materials.wood.management)) - + for _, mat in ipairs{materials.wood, materials.bone} do resource_reactions(result, job_types.MakeAmmo, mat, entity.resources.ammo_type, itemdefs.ammo, { name_field = "name_plural", }) end - + -- BARRED and SCALED as flag names don't quite seem to fit, here. clothing_reactions(result, materials.bone, (function(itemdef) return itemdef.props.flags.BARRED end)) clothing_reactions(result, materials.shell, (function(itemdef) return itemdef.props.flags.SCALED end)) - + for _, mat in ipairs{materials.wood, materials.leather} do resource_reactions(result, job_types.MakeShield, mat, entity.resources.shield_type, itemdefs.shields, {}) end - + -- Melt a Metal Object table.insert(result, reaction_entry(job_types.MeltMetalObject)) - + return result end @@ -782,7 +782,7 @@ function screen:onInput(keys) self.search_string = self.search_string .. string.upper(char) end end - + self:refilter() end @@ -799,7 +799,7 @@ function matchall(haystack, needles) return false end end - + return true end @@ -815,16 +815,16 @@ function splitstring(full, pattern) elseif start > n then result[#result+1] = string.sub(full, n, start - 1) end - + if stop < n then -- The pattern matches an empty string. -- Avoid an infinite loop. break end - + n = stop + 1 end - + return result end @@ -839,18 +839,18 @@ function screen:refilter() } end end - + if self.position < 1 then self.position = #filtered elseif self.position > #filtered then self.position = 1 end - + local start = 1 while self.position >= start + PageSize*2 do start = start + PageSize*2 end - + local displayed = {} for n = 0, PageSize*2 - 1 do local item = filtered[start + n] @@ -858,7 +858,7 @@ function screen:refilter() break end local name = item.name - + local x = 1 local y = FirstRow + n if n >= PageSize then @@ -866,12 +866,12 @@ function screen:refilter() y = y - PageSize name = " "..name end - + local color = COLOR_CYAN if start + n == self.position then color = COLOR_LIGHTCYAN end - + displayed[n + 1] = { x = x, y = y, @@ -879,7 +879,7 @@ function screen:refilter() color = color, } end - + self.reactions = filtered self.displayed = displayed end @@ -917,18 +917,18 @@ function orders_match(a, b) "mat_type", "mat_index", } - + for _, fieldname in ipairs(fields) do if a[fieldname] ~= b[fieldname] then return false end end - + local subtables = { "item_category", "material_category", } - + for _, fieldname in ipairs(subtables) do local aa = a[fieldname] local bb = b[fieldname] @@ -938,7 +938,7 @@ function orders_match(a, b) end end end - + return true end @@ -953,13 +953,13 @@ function order_quantity(order, quantity) end end end - + if amount > 30 then -- Respect the quantity limit. -- With this many in the queue, we can wait for the next cycle. return 30 end - + return amount end @@ -993,7 +993,7 @@ function countContents(container, settings) total = total + 1 end end - + return total end @@ -1009,7 +1009,7 @@ function check_stockpiles(verbose) result[reaction] = (result[reaction] or 0) + amount end end - + return result end @@ -1030,7 +1030,7 @@ function check_pile(sp, verbose) end end end - + for _, item in ipairs(dfhack.buildings.getStockpileContents(sp)) do if item:isAssignedToThisStockpile(sp.id) then -- This is a bin or barrel associated with the stockpile. @@ -1039,14 +1039,14 @@ function check_pile(sp, verbose) filled = filled + 1 end end - + if verbose then print("Stockpile #"..sp.stockpile_number, string.format("%3d spaces", numspaces), string.format("%4d items", filled), string.format("%4d empty spaces", empty)) end - + return filled, empty end @@ -1094,7 +1094,7 @@ function matches_stockpile(item, settings) elseif df.item_threadst:is_instance(item) then return settings.flags.cloth end - + return true end diff --git a/plugins/mapexport/mapexport.cpp b/plugins/mapexport/mapexport.cpp index 9d1ba1c1d..0c69eeb68 100644 --- a/plugins/mapexport/mapexport.cpp +++ b/plugins/mapexport/mapexport.cpp @@ -149,7 +149,7 @@ command_result mapexport (color_ostream &out, std::vector & parame protomap.set_z_size(z_max); out << "Writing material dictionary..." << std::endl; - + for (size_t i = 0; i < world->raws.inorganics.size(); i++) { dfproto::Material *protomaterial = protomap.add_inorganic_material(); @@ -173,10 +173,10 @@ command_result mapexport (color_ostream &out, std::vector & parame constructionMaterials[construction->pos] = std::make_pair(construction->mat_index, construction->mat_type); } } - + coded_output->WriteVarint32(protomap.ByteSize()); protomap.SerializeToCodedStream(coded_output); - + DFHack::t_feature blockFeatureGlobal; DFHack::t_feature blockFeatureLocal; @@ -239,7 +239,7 @@ command_result mapexport (color_ostream &out, std::vector & parame prototile->set_tile_material(toProto(tileMaterial(type))); df::coord map_pos = df::coord(b_x*16+x,b_y*16+y,z); - + switch (tileMaterial(type)) { case tiletype_material::SOIL: @@ -300,7 +300,7 @@ command_result mapexport (color_ostream &out, std::vector & parame } } } - + coded_output->WriteVarint32(protoblock.ByteSize()); protoblock.SerializeToCodedStream(coded_output); } // block x diff --git a/plugins/mapexport/proto/Tile.proto b/plugins/mapexport/proto/Tile.proto index b7f8fcb4a..77f3e5bc3 100644 --- a/plugins/mapexport/proto/Tile.proto +++ b/plugins/mapexport/proto/Tile.proto @@ -5,23 +5,23 @@ message Tile { enum TileType { - EMPTY = 0; - FLOOR = 1; - BOULDER = 2; - PEBBLES = 3; - WALL = 4; - FORTIFICATION = 5; - STAIR_UP = 6; - STAIR_DOWN = 7; - STAIR_UPDOWN = 8; - RAMP = 9; - RAMP_TOP = 10; - BROOK_BED = 11; - BROOK_TOP = 12; - TREE = 13; - SAPLING = 14; - SHRUB = 15; - ENDLESS_PIT = 16; + EMPTY = 0; + FLOOR = 1; + BOULDER = 2; + PEBBLES = 3; + WALL = 4; + FORTIFICATION = 5; + STAIR_UP = 6; + STAIR_DOWN = 7; + STAIR_UPDOWN = 8; + RAMP = 9; + RAMP_TOP = 10; + BROOK_BED = 11; + BROOK_TOP = 12; + TREE = 13; + SAPLING = 14; + SHRUB = 15; + ENDLESS_PIT = 16; } enum LiquidType { @@ -49,8 +49,8 @@ message Tile MAGMA_TYPE = 16; DRIFTWOOD = 17; POOL = 18; - BROOK = 19; - RIVER = 20; + BROOK = 19; + RIVER = 20; } required uint32 x = 1; required uint32 y = 2; diff --git a/plugins/misery.cpp b/plugins/misery.cpp index bc4ba3777..00c844f1d 100644 --- a/plugins/misery.cpp +++ b/plugins/misery.cpp @@ -49,7 +49,7 @@ DFhackCExport command_result plugin_onupdate(color_ostream& out) { } return CR_OK; } - + if ( !wasLoaded ) { wasLoaded = true; } @@ -59,7 +59,7 @@ DFhackCExport command_result plugin_onupdate(color_ostream& out) { return CR_OK; } count = 0; - + int32_t race_id = ui->race_id; int32_t civ_id = ui->civ_id; for ( size_t a = 0; a < world->units.all.size(); a++ ) { @@ -69,7 +69,7 @@ DFhackCExport command_result plugin_onupdate(color_ostream& out) { continue; if ( unit->flags1.bits.dead ) continue; - + int processedThoughtCount; map::iterator i = processedThoughtCountTable.find(unit->id); if ( i == processedThoughtCountTable.end() ) { @@ -78,13 +78,13 @@ DFhackCExport command_result plugin_onupdate(color_ostream& out) { } else { processedThoughtCount = (*i).second; } - + if ( processedThoughtCount == unit->status.recent_events.size() ) { continue; } else if ( processedThoughtCount > unit->status.recent_events.size() ) { processedThoughtCount = unit->status.recent_events.size(); } - + //don't reprocess any old thoughts vector newThoughts; for ( size_t b = processedThoughtCount; b < unit->status.recent_events.size(); b++ ) { @@ -120,7 +120,7 @@ DFhackCExport command_result plugin_onupdate(color_ostream& out) { } processedThoughtCountTable[unit->id] = unit->status.recent_events.size(); } - + return CR_OK; } @@ -159,11 +159,11 @@ command_result misery(color_ostream &out, vector& parameters) { out.printerr("misery can only be enabled in fortress mode with a fully-loaded game.\n"); return CR_FAILURE; } - + if ( parameters.size() < 1 || parameters.size() > 2 ) { return CR_WRONG_USAGE; } - + if ( parameters[0] == "disable" ) { if ( parameters.size() > 1 ) { return CR_WRONG_USAGE; @@ -197,7 +197,7 @@ command_result misery(color_ostream &out, vector& parameters) { factor = a; is_enabled = factor > 1; } - + return CR_OK; } diff --git a/plugins/petcapRemover.cpp b/plugins/petcapRemover.cpp index 6c0724024..ee33f6670 100644 --- a/plugins/petcapRemover.cpp +++ b/plugins/petcapRemover.cpp @@ -90,7 +90,7 @@ void impregnateMany() { else females[unit->race].push_back(a); } - + for ( auto i = females.begin(); i != females.end(); i++ ) { int32_t race = i->first; vector& femalesList = i->second; @@ -99,10 +99,10 @@ void impregnateMany() { break; vector compatibles; df::coord pos1 = units[femalesList[a]]->pos; - + if ( males.find(i->first) == males.end() ) continue; - + vector& malesList = males[i->first]; for ( size_t b = 0; b < malesList.size(); b++ ) { df::coord pos2 = units[malesList[b]]->pos; @@ -111,7 +111,7 @@ void impregnateMany() { } if ( compatibles.empty() ) continue; - + size_t maleIndex = (size_t)(compatibles.size()*((float)rand() / (1+(float)RAND_MAX))); if ( impregnate(units[femalesList[a]], units[compatibles[maleIndex]]) ) popcount[race]++; @@ -124,7 +124,7 @@ bool impregnate(df::unit* female, df::unit* male) { return false; if ( female->relations.pregnancy_genes ) return false; - + df::unit_genes* preg = new df::unit_genes; *preg = male->appearance.genes; female->relations.pregnancy_genes = preg; @@ -138,7 +138,7 @@ void tickHandler(color_ostream& out, void* data) { return; CoreSuspender suspend; impregnateMany(); - + EventManager::unregisterAll(plugin_self); EventManager::EventHandler handle(tickHandler, howOften); EventManager::registerTick(handle, howOften, plugin_self); @@ -147,7 +147,7 @@ void tickHandler(color_ostream& out, void* data) { command_result petcapRemover (color_ostream &out, std::vector & parameters) { CoreSuspender suspend; - + for ( size_t a = 0; a < parameters.size(); a++ ) { if ( parameters[a] == "every" ) { if ( a+1 >= parameters.size() ) @@ -186,18 +186,18 @@ command_result petcapRemover (color_ostream &out, std::vector & pa out.print("%s, line %d: invalid argument: %s\n", __FILE__, __LINE__, parameters[a].c_str()); return CR_WRONG_USAGE; } - + if ( howOften < 0 ) { is_enabled = false; return CR_OK; } - + is_enabled = true; EventManager::unregisterAll(plugin_self); EventManager::EventHandler handle(tickHandler, howOften); EventManager::registerTick(handle, howOften, plugin_self); out.print("petcapRemover: howOften = every %d ticks, popcap per species = %d, preg time = %d ticks.\n", howOften, popcap, pregtime); - + return CR_OK; } diff --git a/plugins/probe.cpp b/plugins/probe.cpp index 045326d62..0dae3d6eb 100644 --- a/plugins/probe.cpp +++ b/plugins/probe.cpp @@ -84,7 +84,7 @@ command_result df_cprobe (color_ostream &out, vector & parameters) if(unit->pos.x == cursorX && unit->pos.y == cursorY && unit->pos.z == cursorZ) { out.print("Creature %d, race %d (%x), civ %d (%x)\n", unit->id, unit->race, unit->race, unit->civ_id, unit->civ_id); - + for(size_t j=0; jinventory.size(); j++) { df::unit_inventory_item* inv_item = unit->inventory[j]; @@ -101,7 +101,7 @@ command_result df_cprobe (color_ostream &out, vector & parameters) out << endl; } } - + // don't leave loop, there may be more than 1 creature at the cursor position //break; } @@ -242,7 +242,7 @@ command_result df_probe (color_ostream &out, vector & parameters) const char* surroundings[] = { "Serene", "Mirthful", "Joyous Wilds", "Calm", "Wilderness", "Untamed Wilds", "Sinister", "Haunted", "Terrifying" }; // biome, geolayer - out << "biome: " << des.bits.biome << " (" << + out << "biome: " << des.bits.biome << " (" << "region id=" << biome->region_id << ", " << surroundings[surr] << ", " << "savagery " << biome->savagery << ", " << @@ -345,7 +345,7 @@ command_result df_probe (color_ostream &out, vector & parameters) out << "no grow" << endl; for(size_t e=0; egetType(); switch(blevtype) diff --git a/plugins/prospector.cpp b/plugins/prospector.cpp index 995dea9ba..5497735e7 100644 --- a/plugins/prospector.cpp +++ b/plugins/prospector.cpp @@ -153,7 +153,7 @@ void printMats(color_ostream &con, MatMap &mat, std::vector &materials, bool { if(it->first >= materials.size()) { - con << "Bad index: " << it->first << " out of " + con << "Bad index: " << it->first << " out of " << materials.size() << endl; continue; } diff --git a/plugins/proto/RemoteFortressReader.proto b/plugins/proto/RemoteFortressReader.proto index f1e611132..4ff78f1af 100644 --- a/plugins/proto/RemoteFortressReader.proto +++ b/plugins/proto/RemoteFortressReader.proto @@ -4,205 +4,205 @@ package RemoteFortressReader; option optimize_for = LITE_RUNTIME; //We use shapes, etc, because the actual tiletypes may differ between DF versions. -enum TiletypeShape +enum TiletypeShape { - NO_SHAPE = -1; - EMPTY = 0; - FLOOR = 1; - BOULDER = 2; - PEBBLES = 3; - WALL = 4; - FORTIFICATION = 5; - STAIR_UP = 6; - STAIR_DOWN = 7; - STAIR_UPDOWN = 8; - RAMP = 9; - RAMP_TOP = 10; - BROOK_BED = 11; - BROOK_TOP = 12; - TREE_SHAPE = 13; - SAPLING = 14; - SHRUB = 15; - ENDLESS_PIT = 16; - BRANCH = 17; - TRUNK_BRANCH = 18; - TWIG = 19; + NO_SHAPE = -1; + EMPTY = 0; + FLOOR = 1; + BOULDER = 2; + PEBBLES = 3; + WALL = 4; + FORTIFICATION = 5; + STAIR_UP = 6; + STAIR_DOWN = 7; + STAIR_UPDOWN = 8; + RAMP = 9; + RAMP_TOP = 10; + BROOK_BED = 11; + BROOK_TOP = 12; + TREE_SHAPE = 13; + SAPLING = 14; + SHRUB = 15; + ENDLESS_PIT = 16; + BRANCH = 17; + TRUNK_BRANCH = 18; + TWIG = 19; } -enum TiletypeSpecial +enum TiletypeSpecial { - NO_SPECIAL = -1; - NORMAL = 0; - RIVER_SOURCE = 1; - WATERFALL = 2; - SMOOTH = 3; - FURROWED = 4; - WET = 5; - DEAD = 6; - WORN_1 = 7; - WORN_2 = 8; - WORN_3 = 9; - TRACK = 10; - SMOOTH_DEAD = 11; + NO_SPECIAL = -1; + NORMAL = 0; + RIVER_SOURCE = 1; + WATERFALL = 2; + SMOOTH = 3; + FURROWED = 4; + WET = 5; + DEAD = 6; + WORN_1 = 7; + WORN_2 = 8; + WORN_3 = 9; + TRACK = 10; + SMOOTH_DEAD = 11; }; -enum TiletypeMaterial +enum TiletypeMaterial { - NO_MATERIAL = -1; - AIR = 0; - SOIL = 1; - STONE = 2; - FEATURE = 3; - LAVA_STONE = 4; - MINERAL = 5; - FROZEN_LIQUID = 6; - CONSTRUCTION = 7; - GRASS_LIGHT = 8; - GRASS_DARK = 9; - GRASS_DRY = 10; - GRASS_DEAD = 11; - PLANT = 12; - HFS = 13; - CAMPFIRE = 14; - FIRE = 15; - ASHES = 16; - MAGMA = 17; - DRIFTWOOD = 18; - POOL = 19; - BROOK = 20; - RIVER = 21; - ROOT = 22; - TREE_MATERIAL = 23; - MUSHROOM = 24; - UNDERWORLD_GATE = 25; + NO_MATERIAL = -1; + AIR = 0; + SOIL = 1; + STONE = 2; + FEATURE = 3; + LAVA_STONE = 4; + MINERAL = 5; + FROZEN_LIQUID = 6; + CONSTRUCTION = 7; + GRASS_LIGHT = 8; + GRASS_DARK = 9; + GRASS_DRY = 10; + GRASS_DEAD = 11; + PLANT = 12; + HFS = 13; + CAMPFIRE = 14; + FIRE = 15; + ASHES = 16; + MAGMA = 17; + DRIFTWOOD = 18; + POOL = 19; + BROOK = 20; + RIVER = 21; + ROOT = 22; + TREE_MATERIAL = 23; + MUSHROOM = 24; + UNDERWORLD_GATE = 25; } enum TiletypeVariant { - NO_VARIANT = -1; - VAR_1 = 0; - VAR_2 = 1; - VAR_3 = 2; - VAR_4 = 3; + NO_VARIANT = -1; + VAR_1 = 0; + VAR_2 = 1; + VAR_3 = 2; + VAR_4 = 3; }; message Tiletype { - required int32 id = 1; - optional string name = 2; - optional string caption = 3; - optional TiletypeShape shape = 4; - optional TiletypeSpecial special = 5; - optional TiletypeMaterial material = 6; - optional TiletypeVariant variant = 7; - optional string direction = 8; + required int32 id = 1; + optional string name = 2; + optional string caption = 3; + optional TiletypeShape shape = 4; + optional TiletypeSpecial special = 5; + optional TiletypeMaterial material = 6; + optional TiletypeVariant variant = 7; + optional string direction = 8; }; message TiletypeList { - repeated Tiletype tiletype_list = 1; + repeated Tiletype tiletype_list = 1; } message MapBlock { - required int32 map_x = 1; - required int32 map_y = 2; - required int32 map_z = 3; - repeated int32 tiles = 4; - repeated MatPair materials = 5; - repeated MatPair layer_materials = 6; - repeated MatPair vein_materials = 7; - repeated MatPair base_materials = 8; - repeated int32 magma = 9; - repeated int32 water = 10; + required int32 map_x = 1; + required int32 map_y = 2; + required int32 map_z = 3; + repeated int32 tiles = 4; + repeated MatPair materials = 5; + repeated MatPair layer_materials = 6; + repeated MatPair vein_materials = 7; + repeated MatPair base_materials = 8; + repeated int32 magma = 9; + repeated int32 water = 10; } message MatPair { - required int32 mat_type = 1; - required int32 mat_index = 2; + required int32 mat_type = 1; + required int32 mat_index = 2; } message ColorDefinition { - required int32 red = 1; - required int32 green = 2; - required int32 blue = 3; + required int32 red = 1; + required int32 green = 2; + required int32 blue = 3; } message MaterialDefinition{ - required MatPair mat_pair = 1; - optional string id = 2; - optional string name = 3; - optional ColorDefinition state_color = 4; //Simplifying colors to assume room temperature. + required MatPair mat_pair = 1; + optional string id = 2; + optional string name = 3; + optional ColorDefinition state_color = 4; //Simplifying colors to assume room temperature. } message MaterialList{ - repeated MaterialDefinition material_list = 1; + repeated MaterialDefinition material_list = 1; } message UnitDefinition { - required int32 id = 1; - optional bool isValid = 2; - optional int32 pos_x = 3; - optional int32 pos_y = 4; - optional int32 pos_z = 5; + required int32 id = 1; + optional bool isValid = 2; + optional int32 pos_x = 3; + optional int32 pos_y = 4; + optional int32 pos_z = 5; } message UnitList { - repeated UnitDefinition creature_list = 1; + repeated UnitDefinition creature_list = 1; } message BlockRequest { - optional int32 blocks_needed = 1; - optional int32 min_x = 2; - optional int32 max_x = 3; - optional int32 min_y = 4; - optional int32 max_y = 5; - optional int32 min_z = 6; - optional int32 max_z = 7; + optional int32 blocks_needed = 1; + optional int32 min_x = 2; + optional int32 max_x = 3; + optional int32 min_y = 4; + optional int32 max_y = 5; + optional int32 min_z = 6; + optional int32 max_z = 7; } message BlockList { - repeated MapBlock map_blocks = 1; - optional int32 map_x = 2; - optional int32 map_y = 3; + repeated MapBlock map_blocks = 1; + optional int32 map_x = 2; + optional int32 map_y = 3; } message PlantDef { - required int32 pos_x = 1; - required int32 pos_y = 2; - required int32 pos_z = 3; - required int32 index = 4; + required int32 pos_x = 1; + required int32 pos_y = 2; + required int32 pos_z = 3; + required int32 index = 4; } message PlantList { - repeated PlantDef plant_list = 1; + repeated PlantDef plant_list = 1; } message ViewInfo { - optional int32 view_pos_x = 1; - optional int32 view_pos_y = 2; - optional int32 view_pos_z = 3; - optional int32 view_size_x = 4; - optional int32 view_size_y = 5; - optional int32 cursor_pos_x = 6; - optional int32 cursor_pos_y = 7; - optional int32 cursor_pos_z = 8; + optional int32 view_pos_x = 1; + optional int32 view_pos_y = 2; + optional int32 view_pos_z = 3; + optional int32 view_size_x = 4; + optional int32 view_size_y = 5; + optional int32 cursor_pos_x = 6; + optional int32 cursor_pos_y = 7; + optional int32 cursor_pos_z = 8; } message MapInfo { - optional int32 block_size_x = 1; - optional int32 block_size_y = 2; - optional int32 block_size_z = 3; - optional int32 block_pos_x = 4; - optional int32 block_pos_y = 5; - optional int32 block_pos_z = 6; - optional string world_name = 7; - optional string world_name_english = 8; - optional string save_name = 9; + optional int32 block_size_x = 1; + optional int32 block_size_y = 2; + optional int32 block_size_z = 3; + optional int32 block_pos_x = 4; + optional int32 block_pos_y = 5; + optional int32 block_pos_z = 6; + optional string world_name = 7; + optional string world_name_english = 8; + optional string save_name = 9; } \ No newline at end of file diff --git a/plugins/proto/isoworldremote.proto b/plugins/proto/isoworldremote.proto index 4faad5f01..d160d9968 100644 --- a/plugins/proto/isoworldremote.proto +++ b/plugins/proto/isoworldremote.proto @@ -4,73 +4,73 @@ package isoworldremote; option optimize_for = LITE_RUNTIME; enum BasicMaterial { - AIR = 0; - OTHER = 1; - INORGANIC = 2; - LIQUID = 3; - PLANT = 4; - WOOD = 5; + AIR = 0; + OTHER = 1; + INORGANIC = 2; + LIQUID = 3; + PLANT = 4; + WOOD = 5; }; enum LiquidType { - ICE = 0; - WATER = 1; - MAGMA = 2; + ICE = 0; + WATER = 1; + MAGMA = 2; } enum BasicShape { - NONE = 0; - OPEN = 1; - WALL = 3; - FLOOR = 4; - RAMP_UP = 5; - RAMP_DOWN = 6; + NONE = 0; + OPEN = 1; + WALL = 3; + FLOOR = 4; + RAMP_UP = 5; + RAMP_DOWN = 6; } message ColorDefinition { - required int32 red = 1; - required int32 green = 2; - required int32 blue = 3; + required int32 red = 1; + required int32 green = 2; + required int32 blue = 3; } message EmbarkTileLayer { - repeated BasicMaterial mat_type_table = 4 [packed=true]; - repeated int32 mat_subtype_table = 5 [packed=true]; - repeated BasicShape tile_shape_table = 6 [packed=true]; - repeated ColorDefinition tile_color_table = 7; + repeated BasicMaterial mat_type_table = 4 [packed=true]; + repeated int32 mat_subtype_table = 5 [packed=true]; + repeated BasicShape tile_shape_table = 6 [packed=true]; + repeated ColorDefinition tile_color_table = 7; } message EmbarkTile { - required int32 world_x = 1; - required int32 world_y = 2; - required sint32 world_z = 3; - repeated EmbarkTileLayer tile_layer = 4; - optional int32 current_year = 5; - optional int32 current_season = 6; - optional bool is_valid = 7; + required int32 world_x = 1; + required int32 world_y = 2; + required sint32 world_z = 3; + repeated EmbarkTileLayer tile_layer = 4; + optional int32 current_year = 5; + optional int32 current_season = 6; + optional bool is_valid = 7; } message TileRequest { - optional int32 want_x = 1; - optional int32 want_y = 2; + optional int32 want_x = 1; + optional int32 want_y = 2; } message MapRequest { - optional string save_folder = 1; + optional string save_folder = 1; } message MapReply { - required bool available = 1; - optional int32 region_x = 2; - optional int32 region_y = 3; - optional int32 region_size_x = 4; - optional int32 region_size_y = 5; - optional int32 current_year = 6; - optional int32 current_season = 7; + required bool available = 1; + optional int32 region_x = 2; + optional int32 region_y = 3; + optional int32 region_size_x = 4; + optional int32 region_size_y = 5; + optional int32 current_year = 6; + optional int32 current_season = 7; } message RawNames { - required bool available = 1; - repeated string inorganic = 2; - repeated string organic = 3; + required bool available = 1; + repeated string inorganic = 2; + repeated string organic = 3; } diff --git a/plugins/regrass.cpp b/plugins/regrass.cpp index 22b6a6747..0cac5bd77 100644 --- a/plugins/regrass.cpp +++ b/plugins/regrass.cpp @@ -60,7 +60,7 @@ command_result df_regrass (color_ostream &out, vector & parameters) // check block for grass events before looking at 16x16 tiles df::block_square_event_grassst * grev = NULL; for(size_t e=0; eblock_events.size(); e++) - { + { df::block_square_event * blev = cur->block_events[e]; df::block_square_event_type blevtype = blev->getType(); if(blevtype == df::block_square_event_type::grass) @@ -103,7 +103,7 @@ command_result df_regrass (color_ostream &out, vector & parameters) if(max) { for(size_t e=0; eblock_events.size(); e++) - { + { df::block_square_event * blev = cur->block_events[e]; df::block_square_event_type blevtype = blev->getType(); if(blevtype == df::block_square_event_type::grass) @@ -118,7 +118,7 @@ command_result df_regrass (color_ostream &out, vector & parameters) // try to find the 'original' event bool regrew = false; for(size_t e=0; eblock_events.size(); e++) - { + { df::block_square_event * blev = cur->block_events[e]; df::block_square_event_type blevtype = blev->getType(); if(blevtype == df::block_square_event_type::grass) @@ -138,7 +138,7 @@ command_result df_regrass (color_ostream &out, vector & parameters) { vector gr_evs; for(size_t e=0; eblock_events.size(); e++) - { + { df::block_square_event * blev = cur->block_events[e]; df::block_square_event_type blevtype = blev->getType(); if(blevtype == df::block_square_event_type::grass) diff --git a/plugins/rendermax/renderer_light.cpp b/plugins/rendermax/renderer_light.cpp index 8a213a6e3..7dd6d46bc 100644 --- a/plugins/rendermax/renderer_light.cpp +++ b/plugins/rendermax/renderer_light.cpp @@ -79,7 +79,7 @@ rect2d getMapViewport() } else return mkrect_wh(0,0,0,0); - + } int w=gps->dimx; int h=gps->dimy; @@ -88,7 +88,7 @@ rect2d getMapViewport() int menu_x2=w-MENU_WIDTH-2; int menu_x1=area_x2-MENU_WIDTH-1; int view_rb=w-1; - + int area_pos=*df::global::ui_area_map_width; int menu_pos=*df::global::ui_menu_width; if(area_pos<3) @@ -97,7 +97,7 @@ rect2d getMapViewport() } if (menu_posmain.mode!=0) { - if (menu_pos >= area_pos) + if (menu_pos >= area_pos) menu_pos = area_pos-1; int menu_x = menu_x2; if(menu_pos < 2) menu_x = menu_x1; @@ -128,7 +128,7 @@ void lightingEngineViewscreen::reinit() void plotCircle(int xm, int ym, int r,const std::function& setPixel) { - int x = -r, y = 0, err = 2-2*r; /* II. Quadrant */ + int x = -r, y = 0, err = 2-2*r; /* II. Quadrant */ do { setPixel(xm-x, ym+y); /* I. Quadrant */ setPixel(xm-y, ym-x); /* II. Quadrant */ @@ -156,7 +156,7 @@ void plotSquare(int xm, int ym, int r,const std::function& setPix void plotLine(int x0, int y0, int x1, int y1,rgbf power,const std::function& setPixel) { int dx = abs(x1-x0), sx = x0& setPixel,bool skip_hack=false) { - + int dx = abs(x1-x0), sx = x0& setPixelAA) { int dx = abs(x1-x0), sx = x0= -dx) { /* x step */ if (x0 == x1) break; - + if (e2+dy < ed) { str=1-(e2+dy)/(float)ed; @@ -240,11 +240,11 @@ void plotLineAA(int x0, int y0, int x1, int y1,rgbf power,const std::functionlightGrid); rect2d vp=getMapViewport(); - + myRenderer->invalidateRect(vp.first.x,vp.first.y,vp.second.x-vp.first.x,vp.second.y-vp.first.y); } void lightingEngineViewscreen::preRender() { - + } void lightingEngineViewscreen::fixAdvMode(int mode) { - + MapExtras::MapCache mc; const rgbf dim(levelDim,levelDim,levelDim); rect2d vp=getMapViewport(); @@ -413,7 +413,7 @@ matLightDef* lightingEngineViewscreen::getMaterialDef( int matType,int matIndex auto it=matDefs.find(std::make_pair(matType,matIndex)); if(it!=matDefs.end()) return &it->second; - else + else return NULL; } buildingLightDef* lightingEngineViewscreen::getBuildingDef( df::building* bld ) @@ -421,7 +421,7 @@ buildingLightDef* lightingEngineViewscreen::getBuildingDef( df::building* bld ) auto it=buildingDefs.find(std::make_tuple((int)bld->getType(),(int)bld->getSubtype(),(int)bld->getCustomType())); if(it!=buildingDefs.end()) return &it->second; - else + else return NULL; } creatureLightDef* lightingEngineViewscreen::getCreatureDef(df::unit* u) @@ -502,10 +502,10 @@ rgbf lightingEngineViewscreen::propogateSun(MapExtras::Block* b, int x,int y,con else if(basicShapeIce==df::tiletype_shape_basic::Floor || basicShapeIce==df::tiletype_shape_basic::Ramp || shapeIce==df::tiletype_shape::STAIR_UP) if(!lastLevel) ret*=matIce.transparency.pow(1.0f/7.0f); - } - + } + lightDef=getMaterialDef(mat.mat_type,mat.mat_index); - + if(!lightDef || !lightDef->isTransparent) lightDef=&matWall; if(basic_shape==df::tiletype_shape_basic::Wall) @@ -514,9 +514,9 @@ rgbf lightingEngineViewscreen::propogateSun(MapExtras::Block* b, int x,int y,con } else if(basic_shape==df::tiletype_shape_basic::Floor || basic_shape==df::tiletype_shape_basic::Ramp || shape==df::tiletype_shape::STAIR_UP) { - + if(!lastLevel) - ret*=lightDef->transparency.pow(1.0f/7.0f); + ret*=lightDef->transparency.pow(1.0f/7.0f); } else if(shape==df::tiletype_shape::STAIR_DOWN || shape==df::tiletype_shape::STAIR_UPDOWN) { @@ -574,7 +574,7 @@ void lightingEngineViewscreen::doSun(const lightSource& sky,MapExtras::MapCache& rgbf& curCell=cellArray[block_x][block_y]; curCell=propogateSun(b,block_x,block_y,curCell,z==window_z); if(curCell.dot(curCell)<0.003f) - emptyCell++; + emptyCell++; } } if(emptyCell==256) @@ -622,10 +622,10 @@ void lightingEngineViewscreen::doOcupancyAndLights() } else daycol= fmod(dayHour,24.0f)/24.0f; //1->12h 0->24h - + rgbf sky_col=getSkyColor(daycol); lightSource sky(sky_col, -1);//auto calculate best size - + MapExtras::MapCache cache; doSun(sky,cache); @@ -640,7 +640,7 @@ void lightingEngineViewscreen::doOcupancyAndLights() blockVp.second=(window2d+vpSize)/16; blockVp.second.x=std::min(blockVp.second.x,(int16_t)df::global::world->map.x_count_block); blockVp.second.y=std::min(blockVp.second.y,(int16_t)df::global::world->map.y_count_block); - + for(int blockX=blockVp.first.x;blockX<=blockVp.second.x;blockX++) for(int blockY=blockVp.first.y;blockY<=blockVp.second.y;blockY++) { @@ -648,7 +648,7 @@ void lightingEngineViewscreen::doOcupancyAndLights() MapExtras::Block* bDown=cache.BlockAt(DFCoord(blockX,blockY,window_z-1)); if(!b) continue; //empty blocks fixed by sun propagation - + for(int block_x = 0; block_x < 16; block_x++) for(int block_y = 0; block_y < 16; block_y++) { @@ -662,7 +662,7 @@ void lightingEngineViewscreen::doOcupancyAndLights() int tile=getIndex(pos.x,pos.y); rgbf& curCell=ocupancy[tile]; curCell=matAmbience.transparency; - + df::tiletype type = b->tiletypeAt(gpos); df::tile_designation d = b->DesignationAt(gpos); @@ -677,9 +677,9 @@ void lightingEngineViewscreen::doOcupancyAndLights() bool is_floor=!ENUM_ATTR(tiletype_shape,passable_low,shape); df::tiletype_shape_basic basic_shape = ENUM_ATTR(tiletype_shape, basic_shape, shape); df::tiletype_material tileMat= ENUM_ATTR(tiletype,material,type); - + DFHack::t_matpair mat=b->staticMaterialAt(gpos); - + matLightDef* lightDef=getMaterialDef(mat.mat_type,mat.mat_index); if(!lightDef || !lightDef->isTransparent) lightDef=&matWall; @@ -698,7 +698,7 @@ void lightingEngineViewscreen::doOcupancyAndLights() { applyMaterial(tile,matWater, (float)d.bits.flow_size/7.0f, (float)d.bits.flow_size/7.0f); } - if(d.bits.liquid_type && d.bits.flow_size>0) + if(d.bits.liquid_type && d.bits.flow_size>0) { applyMaterial(tile,matLava,(float)d.bits.flow_size/7.0f,(float)d.bits.flow_size/7.0f); } @@ -713,10 +713,10 @@ void lightingEngineViewscreen::doOcupancyAndLights() } } } - + } - + df::map_block* block=b->getRaw(); if(!block) continue; @@ -749,7 +749,7 @@ void lightingEngineViewscreen::doOcupancyAndLights() } } } - + //blood and other goo for(int i=0;iblock_events.size();i++) { @@ -829,12 +829,12 @@ void lightingEngineViewscreen::doOcupancyAndLights() } } } - + //buildings for(size_t i = 0; i < df::global::world->buildings.all.size(); i++) { df::building *bld = df::global::world->buildings.all[i]; - + if(window_z!=bld->z) continue; if(bld->getBuildStage()getMaxBuildStage()) //only work if fully built @@ -846,7 +846,7 @@ void lightingEngineViewscreen::doOcupancyAndLights() p2=worldToViewportCoord(p2,vp,window2d); if(isInRect(p1,vp)||isInRect(p2,vp)) { - + int tile; if(isInRect(p1,vp)) tile=getIndex(p1.x,p1.y); //TODO multitile buildings. How they would work? @@ -868,8 +868,8 @@ void lightingEngineViewscreen::doOcupancyAndLights() if(!gate->gate_flags.bits.closed) continue; } - - + + if(def->useMaterial) { matLightDef* mat=getMaterialDef(bld->mat_type,bld->mat_index); @@ -903,7 +903,7 @@ void lightingEngineViewscreen::doOcupancyAndLights() } } } - + } rgbf lua_parseLightCell(lua_State* L) { @@ -937,7 +937,7 @@ rgbf lua_parseLightCell(lua_State* L) lua_pop(L,1) matLightDef lua_parseMatDef(lua_State* L) { - + matLightDef ret; lua_getfield(L,-1,"tr"); if(ret.isTransparent=!lua_isnil(L,-1)) @@ -987,7 +987,7 @@ int lightingEngineViewscreen::parseMaterials(lua_State* L) int index=lua_tonumber(L,-2); //os->print("\tProcessing index:%d\n",index); engine->matDefs[std::make_pair(type,index)]=lua_parseMatDef(L); - + lua_pop(L, 1); } lua_pop(L, 1); @@ -1174,17 +1174,17 @@ void lightingEngineViewscreen::loadSettings() std::string rawFolder; if(df::global::world->cur_savegame.save_dir!="") { - rawFolder= "data/save/" + (df::global::world->cur_savegame.save_dir) + "/raw/"; + rawFolder= "data/save/" + (df::global::world->cur_savegame.save_dir) + "/raw/"; } else { - rawFolder= "raw/"; + rawFolder= "raw/"; } const std::string settingsfile=rawFolder+"rendermax.lua"; CoreSuspender lock; color_ostream_proxy out(Core::getInstance().getConsole()); - + lua_State* s=DFHack::Lua::Core::State; lua_newtable(s); int env=lua_gettop(s); @@ -1202,7 +1202,7 @@ void lightingEngineViewscreen::loadSettings() else { lua_pushvalue(s,env); - + if(Lua::SafeCall(out,s,1,0)) { lua_pushcfunction(s, parseMaterials); @@ -1235,7 +1235,7 @@ void lightingEngineViewscreen::loadSettings() Lua::SafeCall(out,s,2,0); out.print("%d items loaded\n",itemDefs.size()); } - + } } catch(std::exception& e) @@ -1272,8 +1272,8 @@ void lightThread::run() if(dispatch.occlusion.size()!=canvas.size()) //oh no somebody resized stuff canvas.resize(dispatch.occlusion.size()); } - - + + { //get my rectangle (any will do) tthread::lock_guard guard(dispatch.unprocessedMutex); if (dispatch.unprocessed.size()==0) @@ -1287,13 +1287,13 @@ void lightThread::run() { dispatch.occlusionReady=false; } - + } work(); { tthread::lock_guard guard(dispatch.writeLock); combine();//write it back - dispatch.writeCount++; + dispatch.writeCount++; } dispatch.writesDone.notify_one();//tell about it to the dispatch. } @@ -1311,7 +1311,7 @@ void lightThread::work() void lightThread::combine() { - for(int i=0;i0.00001f) //if we needed to light up the suroundings, then raycast { - + plotSquare(x,y,radius, std::bind(&lightThread::doRay,this,power,x,y,_1,_2,num_diffuse)); } @@ -1438,7 +1438,7 @@ void lightThreadDispatch::shutdown() for(int i=0;iisDone=true; - + } occlusionDone.notify_all();//if stuck signal that you are done with stuff. for(int i=0;i nthread(new lightThread(*this)); nthread->myThread=new tthread::thread(&threadStub,nthread.get()); threadPool.push_back(std::move(nthread)); diff --git a/plugins/rendermax/renderer_light.hpp b/plugins/rendermax/renderer_light.hpp index 357ddaf85..ec1561c76 100644 --- a/plugins/rendermax/renderer_light.hpp +++ b/plugins/rendermax/renderer_light.hpp @@ -53,7 +53,7 @@ private: float intensity=(light.r+light.g+light.b)/3.0; light_adaptation=intensity*influence+light_adaptation*(1-influence); float delta=light_adaptation-intensity; - + rgbf ret; ret.r=light.r-delta; ret.g=light.g-delta; @@ -65,7 +65,7 @@ private: 2. light adapted, real=dark -> darker delta>0 multiplier<1 3. dark adapted, real=light -> lighter delta<0 multiplier>1 */ - //if light_adaptation/intensity!=0 then draw + //if light_adaptation/intensity!=0 then draw } void colorizeTile(int x,int y) @@ -98,7 +98,7 @@ private: { reinitLightGrid(df::global::gps->dimy,df::global::gps->dimx); } - + public: tthread::fast_mutex dataMutex; std::vector lightGrid; @@ -106,19 +106,19 @@ public: { reinitLightGrid(); } - virtual void update_tile(int32_t x, int32_t y) { + virtual void update_tile(int32_t x, int32_t y) { renderer_wrap::update_tile(x,y); tthread::lock_guard guard(dataMutex); colorizeTile(x,y); }; - virtual void update_all() { + virtual void update_all() { renderer_wrap::update_all(); tthread::lock_guard guard(dataMutex); for (int x = 0; x < df::global::gps->dimx; x++) for (int y = 0; y < df::global::gps->dimy; y++) colorizeTile(x,y); }; - virtual void grid_resize(int32_t w, int32_t h) { + virtual void grid_resize(int32_t w, int32_t h) { renderer_wrap::grid_resize(w,h); reinitLightGrid(w,h); }; @@ -150,7 +150,7 @@ public: virtual void loadSettings()=0; virtual void clear()=0; - + virtual void setHour(float h)=0; virtual void debug(bool enable)=0; protected: @@ -205,7 +205,7 @@ struct buildingLightDef }; struct itemLightDef { - matLightDef light; + matLightDef light; bool haul; bool equiped; bool onGround; @@ -276,7 +276,7 @@ class lightingEngineViewscreen:public lightingEngine { public: lightingEngineViewscreen(renderer_light* target); - ~lightingEngineViewscreen(); + ~lightingEngineViewscreen(); void reinit(); void calculate(); @@ -289,14 +289,14 @@ public: private: void fixAdvMode(int mode); df::coord2d worldToViewportCoord(const df::coord2d& in,const DFHack::rect2d& r,const df::coord2d& window2d) ; - + void doSun(const lightSource& sky,MapExtras::MapCache& map); void doOcupancyAndLights(); rgbf propogateSun(MapExtras::Block* b, int x,int y,const rgbf& in,bool lastLevel); void doRay(std::vector & target, rgbf power,int cx,int cy,int tx,int ty); void doFovs(); - void doLight(std::vector & target, int index); + void doLight(std::vector & target, int index); rgbf lightUpCell(std::vector & target, rgbf power,int dx,int dy,int tx,int ty); bool addLight(int tileId,const lightSource& light); void addOclusion(int tileId,const rgbf& c,float thickness); @@ -310,7 +310,7 @@ private: void applyMaterial(int tileId,const matLightDef& mat,float size=1, float thickness = 1); //try to find and apply material, if failed return false, and if def!=null then apply def. bool applyMaterial(int tileId,int matType,int matIndex,float size=1,float thickness = 1,const matLightDef* def=NULL); - + size_t inline getIndex(int x,int y) { return x*h+y; @@ -333,7 +333,7 @@ private: int getW()const {return w;} int getH()const {return h;} public: - void lightWorkerThread(void * arg); + void lightWorkerThread(void * arg); private: rgbf getSkyColor(float v); bool doDebug; @@ -343,7 +343,7 @@ private: float dayHour; //<0 to cycle std::vector dayColors; // a gradient of colors, first to 0, last to 24 ///set up sane settings if setting file does not exist. - void defaultSettings(); + void defaultSettings(); static int parseMaterials(lua_State* L); static int parseSpecial(lua_State* L); diff --git a/plugins/rendermax/renderer_opengl.hpp b/plugins/rendermax/renderer_opengl.hpp index 085bdf48a..76a45918c 100644 --- a/plugins/rendermax/renderer_opengl.hpp +++ b/plugins/rendermax/renderer_opengl.hpp @@ -79,46 +79,46 @@ public: { copy_from_inner(); } - virtual void update_tile(int32_t x, int32_t y) { + virtual void update_tile(int32_t x, int32_t y) { copy_to_inner(); parent->update_tile(x,y); }; - virtual void update_all() { + virtual void update_all() { copy_to_inner(); parent->update_all(); }; - virtual void render() { + virtual void render() { copy_to_inner(); parent->render(); }; - virtual void set_fullscreen() { + virtual void set_fullscreen() { copy_to_inner(); parent->set_fullscreen(); copy_from_inner(); }; - virtual void zoom(df::zoom_commands z) { + virtual void zoom(df::zoom_commands z) { copy_to_inner(); parent->zoom(z); copy_from_inner(); }; - virtual void resize(int32_t w, int32_t h) { + virtual void resize(int32_t w, int32_t h) { copy_to_inner(); parent->resize(w,h); copy_from_inner(); }; - virtual void grid_resize(int32_t w, int32_t h) { + virtual void grid_resize(int32_t w, int32_t h) { copy_to_inner(); parent->grid_resize(w,h); copy_from_inner(); }; - virtual ~renderer_wrap() { + virtual ~renderer_wrap() { df::global::enabler->renderer=parent; }; - virtual bool get_mouse_coords(int32_t* x, int32_t* y) { + virtual bool get_mouse_coords(int32_t* x, int32_t* y) { return parent->get_mouse_coords(x,y); }; - virtual bool uses_opengl() { + virtual bool uses_opengl() { return parent->uses_opengl(); }; void invalidateRect(int32_t x,int32_t y,int32_t w,int32_t h) @@ -152,7 +152,7 @@ private: float *bg = p->bg + tile * 4 * 6; float *tex = p->tex + tile * 2 * 6; const float val=1/2.0; - + float r=rFloat()*val - val/2; float g=rFloat()*val - val/2; float b=rFloat()*val - val/2; @@ -176,11 +176,11 @@ public: renderer_trippy(renderer* parent):renderer_wrap(parent) { } - virtual void update_tile(int32_t x, int32_t y) { + virtual void update_tile(int32_t x, int32_t y) { renderer_wrap::update_tile(x,y); colorizeTile(x,y); }; - virtual void update_all() { + virtual void update_all() { renderer_wrap::update_all(); for (int x = 0; x < df::global::gps->dimx; x++) for (int y = 0; y < df::global::gps->dimy; y++) @@ -193,7 +193,7 @@ struct rgbf float r,g,b; rgbf():r(0),g(0),b(0) { - + } rgbf(float r,float g,float b):r(r),g(g),b(b) { @@ -295,14 +295,14 @@ public: { reinitLightGrid(); } - virtual void update_tile(int32_t x, int32_t y) { + virtual void update_tile(int32_t x, int32_t y) { renderer_wrap::update_tile(x,y); tthread::lock_guard guard(dataMutex); colorizeTile(x,y); //some sort of mutex or sth? //and then map read }; - virtual void update_all() { + virtual void update_all() { renderer_wrap::update_all(); tthread::lock_guard guard(dataMutex); for (int x = 0; x < df::global::gps->dimx; x++) @@ -322,7 +322,7 @@ public: renderer_wrap::zoom(z); reinitLightGrid(); } - virtual void grid_resize(int32_t w, int32_t h) { + virtual void grid_resize(int32_t w, int32_t h) { renderer_wrap::grid_resize(w,h); reinitLightGrid(w,h); }; @@ -388,14 +388,14 @@ public: { reinitGrids(); } - virtual void update_tile(int32_t x, int32_t y) { + virtual void update_tile(int32_t x, int32_t y) { renderer_wrap::update_tile(x,y); tthread::lock_guard guard(dataMutex); overwriteTile(x,y); //some sort of mutex or sth? //and then map read }; - virtual void update_all() { + virtual void update_all() { renderer_wrap::update_all(); tthread::lock_guard guard(dataMutex); for (int x = 0; x < df::global::gps->dimx; x++) @@ -405,7 +405,7 @@ public: //and then map read //same stuff for all of them i guess... }; - virtual void grid_resize(int32_t w, int32_t h) { + virtual void grid_resize(int32_t w, int32_t h) { renderer_wrap::grid_resize(w,h); reinitGrids(w,h); }; diff --git a/plugins/rendermax/rendermax.cpp b/plugins/rendermax/rendermax.cpp index a2edd3b0a..2140743ca 100644 --- a/plugins/rendermax/rendermax.cpp +++ b/plugins/rendermax/rendermax.cpp @@ -106,7 +106,7 @@ void removeOld() } if(current_mode!=MODE_DEFAULT) delete enabler->renderer; - + current_mode=MODE_DEFAULT; } void installNew(df::renderer* r,RENDERER_MODE newMode) @@ -411,7 +411,7 @@ static command_result rendermax(color_ostream &out, vector & parameters renderer_light *myRender=new renderer_light(enabler->renderer); installNew(myRender,MODE_LIGHT); engine=new lightingEngineViewscreen(myRender); - + if (Core::getInstance().isWorldLoaded()) plugin_onstatechange(out, SC_WORLD_LOADED); } @@ -446,7 +446,7 @@ static command_result rendermax(color_ostream &out, vector & parameters } else out.printerr("Light mode already enabled"); - + return CR_OK; } else if(cmd=="disable") diff --git a/plugins/rendermax/rendermax.lua b/plugins/rendermax/rendermax.lua index d26b3d2c1..f1cfa9020 100644 --- a/plugins/rendermax/rendermax.lua +++ b/plugins/rendermax/rendermax.lua @@ -1,225 +1,225 @@ ---scroll down to the end for configuration -ret={...} -ret=ret[1] -ret.materials={} -ret.buildings={} -ret.special={} -ret.items={} -ret.creatures={} -for k,v in pairs(ret) do - _ENV[k]=v -end --- add material by id (index,mat pair or token string or a type number), flags is a table of strings --- supported flags (but not implemented): --- flicker -function addMaterial(id,transparency,emitance,radius,flags) - local matinfo - if type(id)=="string" then - matinfo=dfhack.matinfo.find(id) - elseif type(id)=="table" then - matinfo=dfhack.matinfo.decode(id[1],id[2]) - else - matinfo=dfhack.matinfo.decode(id,0) - end - if matinfo==nil then - error("Material not found") - end - materials[matinfo.type]=materials[matinfo.type] or {} - materials[matinfo.type][matinfo.index]=makeMaterialDef(transparency,emitance,radius,flags) -end -function buildingLookUp(id) - local tokens={} - local lookup={ Workshop=df.workshop_type,Furnace=df.furnace_type,Trap=df.trap_type, - SiegeEngine=df.siegeengine_type} - for i in string.gmatch(id, "[^:]+") do - table.insert(tokens,i) - end - local ret={} - ret.type=df.building_type[tokens[1]] - if tokens[2] then - local type_array=lookup[tokens[1]] - if type_array then - ret.subtype=type_array[tokens[2]] - end - if tokens[2]=="Custom" and tokens[3] then --TODO cache for faster lookup - if ret.type==df.building_type.Workshop then - for k,v in pairs(df.global.world.raws.buildings.workshops) do - if v.code==tokens[3] then - ret.custom=v.id - return ret - end - end - elseif ret.type==df.building_type.Furnace then - for k,v in pairs(df.global.world.raws.buildings.furnaces) do - if v.code==tokens[3] then - ret.custom=v.id - return ret - end - end - end - end - qerror("Invalid custom building:"..tokens[3]) - end - return ret -end -function itemLookup(id) - local ret={} - local tokens={} - for i in string.gmatch(id, "[^:]+") do - table.insert(tokens,i) - end - ret.type=df.item_type[tokens[1]] - ret.subtype=-1 - if tokens[2] then - for k,v in ipairs(df.global.world.raws.itemdefs.all) do --todo lookup correct itemdef - if v.id==tokens[2] then - ret.subtype=v.subtype - return ret - end - end - qerror("Failed item subtype lookup:"..tokens[2]) - end - return ret -end -function creatureLookup(id) - local ret={} - local tokens={} - for i in string.gmatch(id, "[^:]+") do - table.insert(tokens,i) - end - for k,v in ipairs(df.global.world.raws.creatures.all) do - if v.creature_id==tokens[1] then - ret.type=k - if tokens[2] then - for k,v in ipairs(v.caste) do - if v.caste_id==tokens[2] then - ret.subtype=k - break - end - end - if ret.subtype==nil then - qerror("caste "..tokens[2].." for "..tokens[1].." not found") - end - end - return ret - end - end - qerror("Failed to find race:"..tokens[1]) -end --- add creature by id ("DWARF" or "DWARF:MALE") --- supported flags: -function addCreature(id,transparency,emitance,radius,flags) - local crId=creatureLookup(id) - local mat=makeMaterialDef(transparency,emitance,radius,flags) - table.insert(creatures,{race=crId.type,caste=crId.subtype or -1, light=mat}) -end --- add item by id ( "TOTEM" or "WEAPON:PICK" or "WEAPON" for all the weapon types) --- supported flags: --- hauling --active when hauled TODO::currently all mean same thing... --- equiped --active while equiped TODO::currently all mean same thing... --- inBuilding --active in building TODO::currently all mean same thing... --- contained --active in container TODO::currently all mean same thing... --- onGround --active on ground --- useMaterial --uses material, but the defined things overwrite -function addItem(id,transparency,emitance,radius,flags) - local itemId=itemLookup(id) - local mat=makeMaterialDef(transparency,emitance,radius,flags) - table.insert(items,{["type"]=itemId.type,subtype=itemId.subtype,light=mat}) -end --- add building by id (string e.g. "Statue" or "Workshop:Masons", flags is a table of strings --- supported flags: --- useMaterial --uses material, but the defined things overwrite --- poweredOnly --glow only when powered -function addBuilding(id,transparency,emitance,radius,flags,size,thickness) - size=size or 1 - thickness=thickness or 1 - local bld=buildingLookUp(id) - local mat=makeMaterialDef(transparency,emitance,radius,flags) - mat.size=size - mat.thickness=thickness - buildings[bld.type]=buildings[bld.type] or {} - if bld.subtype then - if bld.custom then - buildings[bld.type][bld.subtype]=buildings[bld.type][bld.subtype] or {} - buildings[bld.type][bld.subtype][bld.custom]=mat - else - buildings[bld.type][bld.subtype]={[-1]=mat} - end - else - buildings[bld.type][-1]={[-1]=mat} - end -end -function makeMaterialDef(transparency,emitance,radius,flags) - local flg - if flags then - flg={} - for k,v in ipairs(flags) do - flg[v]=true - end - end - return {tr=transparency,em=emitance,rad=radius,flags=flg} -end -function colorFrom16(col16) - local col=df.global.enabler.ccolor[col16] - return {col[0],col[1],col[2]} -end -function addGems() - for k,v in pairs(df.global.world.raws.inorganics) do - if v.material.flags.IS_GEM then - addMaterial("INORGANIC:"..v.id,colorFrom16(v.material.tile_color[0]+v.material.tile_color[2]*8)) - end - end -end ------------------------------------------------------------------------- ----------------- Configuration Starts Here ------------------------- ------------------------------------------------------------------------- -is_computer_quantum=false -- will enable more costly parts in the future ---special things -special.LAVA=makeMaterialDef({0.8,0.2,0.2},{0.8,0.2,0.2},5) -special.WATER=makeMaterialDef({0.5,0.5,0.8}) -special.FROZEN_LIQUID=makeMaterialDef({0.2,0.7,0.9}) -- ice -special.AMBIENT=makeMaterialDef({0.85,0.85,0.85}) --ambient fog -special.CURSOR=makeMaterialDef({1,1,1},{0.96,0.84,0.03},11, {"flicker"}) -special.CITIZEN=makeMaterialDef(nil,{0.80,0.80,0.90},6) -special.LevelDim=0.2 -- darkness. Do not set to 0 -special.dayHour=-1 -- <0 cycle, else hour of the day -special.dayColors={ {0,0,0}, --dark at 0 hours - {0.6,0.5,0.5}, --reddish twilight - {1,1,1}, --fullbright at 12 hours - {0.5,0.5,0.5}, - {0,0,0}} --dark at 24 hours -special.daySpeed=1 -- 1->1200 cur_year_ticks per day. 2->600 ticks -special.diffusionCount=1 -- split beam max 1 times to mimic diffuse lights -special.advMode=0 -- 1 or 0 different modes for adv mode. 0-> use df vision system, - -- 1(does not work)->everything visible, let rendermax light do the work ---TODO dragonfire ---materials - - --- glasses -addMaterial("GLASS_GREEN",{0.1,0.9,0.5}) -addMaterial("GLASS_CLEAR",{0.5,0.95,0.9}) -addMaterial("GLASS_CRYSTAL",{0.75,0.95,0.95}) --- Plants -addMaterial("PLANT:TOWER_CAP",nil,{0.65,0.65,0.65},6) -addMaterial("PLANT:MUSHROOM_CUP_DIMPLE",nil,{0.03,0.03,0.5},3) -addMaterial("PLANT:CAVE MOSS",nil,{0.1,0.1,0.4},2) -addMaterial("PLANT:MUSHROOM_HELMET_PLUMP",nil,{0.2,0.1,0.6},2) --- inorganics -addMaterial("INORGANIC:ADAMANTINE",{0.1,0.3,0.3},{0.1,0.3,0.3},4) --- creature stuff -addMaterial("CREATURE:DRAGON:BLOOD",nil,{0.6,0.1,0.1},4) -addGems() ---buildings -addBuilding("Statue",{1,1,1},{0.9,0.75,0.3},8) -addBuilding("Bed",{1,1,1},{0.3,0.2,0.0},2) -addBuilding("WindowGlass",nil,nil,0,{"useMaterial"}) -addBuilding("WindowGem",nil,nil,0,{"useMaterial"}) -addBuilding("Door",nil,nil,0,{"useMaterial"}) -- special case, only closed door obstruct/emit light -addBuilding("Floodgate",nil,nil,0,{"useMaterial"}) -- special case, only closed door obstruct/emit light ---creatures -addCreature("ELEMENTMAN_MAGMA",{0.8,0.2,0.2},{0.8,0.2,0.2},5) ---items -addItem("GEM",nil,nil,{"useMaterial","onGround"}) -addItem("ROUGH",nil,nil,{"useMaterial","onGround"}) +--scroll down to the end for configuration +ret={...} +ret=ret[1] +ret.materials={} +ret.buildings={} +ret.special={} +ret.items={} +ret.creatures={} +for k,v in pairs(ret) do + _ENV[k]=v +end +-- add material by id (index,mat pair or token string or a type number), flags is a table of strings +-- supported flags (but not implemented): +-- flicker +function addMaterial(id,transparency,emitance,radius,flags) + local matinfo + if type(id)=="string" then + matinfo=dfhack.matinfo.find(id) + elseif type(id)=="table" then + matinfo=dfhack.matinfo.decode(id[1],id[2]) + else + matinfo=dfhack.matinfo.decode(id,0) + end + if matinfo==nil then + error("Material not found") + end + materials[matinfo.type]=materials[matinfo.type] or {} + materials[matinfo.type][matinfo.index]=makeMaterialDef(transparency,emitance,radius,flags) +end +function buildingLookUp(id) + local tokens={} + local lookup={ Workshop=df.workshop_type,Furnace=df.furnace_type,Trap=df.trap_type, + SiegeEngine=df.siegeengine_type} + for i in string.gmatch(id, "[^:]+") do + table.insert(tokens,i) + end + local ret={} + ret.type=df.building_type[tokens[1]] + if tokens[2] then + local type_array=lookup[tokens[1]] + if type_array then + ret.subtype=type_array[tokens[2]] + end + if tokens[2]=="Custom" and tokens[3] then --TODO cache for faster lookup + if ret.type==df.building_type.Workshop then + for k,v in pairs(df.global.world.raws.buildings.workshops) do + if v.code==tokens[3] then + ret.custom=v.id + return ret + end + end + elseif ret.type==df.building_type.Furnace then + for k,v in pairs(df.global.world.raws.buildings.furnaces) do + if v.code==tokens[3] then + ret.custom=v.id + return ret + end + end + end + end + qerror("Invalid custom building:"..tokens[3]) + end + return ret +end +function itemLookup(id) + local ret={} + local tokens={} + for i in string.gmatch(id, "[^:]+") do + table.insert(tokens,i) + end + ret.type=df.item_type[tokens[1]] + ret.subtype=-1 + if tokens[2] then + for k,v in ipairs(df.global.world.raws.itemdefs.all) do --todo lookup correct itemdef + if v.id==tokens[2] then + ret.subtype=v.subtype + return ret + end + end + qerror("Failed item subtype lookup:"..tokens[2]) + end + return ret +end +function creatureLookup(id) + local ret={} + local tokens={} + for i in string.gmatch(id, "[^:]+") do + table.insert(tokens,i) + end + for k,v in ipairs(df.global.world.raws.creatures.all) do + if v.creature_id==tokens[1] then + ret.type=k + if tokens[2] then + for k,v in ipairs(v.caste) do + if v.caste_id==tokens[2] then + ret.subtype=k + break + end + end + if ret.subtype==nil then + qerror("caste "..tokens[2].." for "..tokens[1].." not found") + end + end + return ret + end + end + qerror("Failed to find race:"..tokens[1]) +end +-- add creature by id ("DWARF" or "DWARF:MALE") +-- supported flags: +function addCreature(id,transparency,emitance,radius,flags) + local crId=creatureLookup(id) + local mat=makeMaterialDef(transparency,emitance,radius,flags) + table.insert(creatures,{race=crId.type,caste=crId.subtype or -1, light=mat}) +end +-- add item by id ( "TOTEM" or "WEAPON:PICK" or "WEAPON" for all the weapon types) +-- supported flags: +-- hauling --active when hauled TODO::currently all mean same thing... +-- equiped --active while equiped TODO::currently all mean same thing... +-- inBuilding --active in building TODO::currently all mean same thing... +-- contained --active in container TODO::currently all mean same thing... +-- onGround --active on ground +-- useMaterial --uses material, but the defined things overwrite +function addItem(id,transparency,emitance,radius,flags) + local itemId=itemLookup(id) + local mat=makeMaterialDef(transparency,emitance,radius,flags) + table.insert(items,{["type"]=itemId.type,subtype=itemId.subtype,light=mat}) +end +-- add building by id (string e.g. "Statue" or "Workshop:Masons", flags is a table of strings +-- supported flags: +-- useMaterial --uses material, but the defined things overwrite +-- poweredOnly --glow only when powered +function addBuilding(id,transparency,emitance,radius,flags,size,thickness) + size=size or 1 + thickness=thickness or 1 + local bld=buildingLookUp(id) + local mat=makeMaterialDef(transparency,emitance,radius,flags) + mat.size=size + mat.thickness=thickness + buildings[bld.type]=buildings[bld.type] or {} + if bld.subtype then + if bld.custom then + buildings[bld.type][bld.subtype]=buildings[bld.type][bld.subtype] or {} + buildings[bld.type][bld.subtype][bld.custom]=mat + else + buildings[bld.type][bld.subtype]={[-1]=mat} + end + else + buildings[bld.type][-1]={[-1]=mat} + end +end +function makeMaterialDef(transparency,emitance,radius,flags) + local flg + if flags then + flg={} + for k,v in ipairs(flags) do + flg[v]=true + end + end + return {tr=transparency,em=emitance,rad=radius,flags=flg} +end +function colorFrom16(col16) + local col=df.global.enabler.ccolor[col16] + return {col[0],col[1],col[2]} +end +function addGems() + for k,v in pairs(df.global.world.raws.inorganics) do + if v.material.flags.IS_GEM then + addMaterial("INORGANIC:"..v.id,colorFrom16(v.material.tile_color[0]+v.material.tile_color[2]*8)) + end + end +end +------------------------------------------------------------------------ +---------------- Configuration Starts Here ------------------------- +------------------------------------------------------------------------ +is_computer_quantum=false -- will enable more costly parts in the future +--special things +special.LAVA=makeMaterialDef({0.8,0.2,0.2},{0.8,0.2,0.2},5) +special.WATER=makeMaterialDef({0.5,0.5,0.8}) +special.FROZEN_LIQUID=makeMaterialDef({0.2,0.7,0.9}) -- ice +special.AMBIENT=makeMaterialDef({0.85,0.85,0.85}) --ambient fog +special.CURSOR=makeMaterialDef({1,1,1},{0.96,0.84,0.03},11, {"flicker"}) +special.CITIZEN=makeMaterialDef(nil,{0.80,0.80,0.90},6) +special.LevelDim=0.2 -- darkness. Do not set to 0 +special.dayHour=-1 -- <0 cycle, else hour of the day +special.dayColors={ {0,0,0}, --dark at 0 hours + {0.6,0.5,0.5}, --reddish twilight + {1,1,1}, --fullbright at 12 hours + {0.5,0.5,0.5}, + {0,0,0}} --dark at 24 hours +special.daySpeed=1 -- 1->1200 cur_year_ticks per day. 2->600 ticks +special.diffusionCount=1 -- split beam max 1 times to mimic diffuse lights +special.advMode=0 -- 1 or 0 different modes for adv mode. 0-> use df vision system, + -- 1(does not work)->everything visible, let rendermax light do the work +--TODO dragonfire +--materials + + +-- glasses +addMaterial("GLASS_GREEN",{0.1,0.9,0.5}) +addMaterial("GLASS_CLEAR",{0.5,0.95,0.9}) +addMaterial("GLASS_CRYSTAL",{0.75,0.95,0.95}) +-- Plants +addMaterial("PLANT:TOWER_CAP",nil,{0.65,0.65,0.65},6) +addMaterial("PLANT:MUSHROOM_CUP_DIMPLE",nil,{0.03,0.03,0.5},3) +addMaterial("PLANT:CAVE MOSS",nil,{0.1,0.1,0.4},2) +addMaterial("PLANT:MUSHROOM_HELMET_PLUMP",nil,{0.2,0.1,0.6},2) +-- inorganics +addMaterial("INORGANIC:ADAMANTINE",{0.1,0.3,0.3},{0.1,0.3,0.3},4) +-- creature stuff +addMaterial("CREATURE:DRAGON:BLOOD",nil,{0.6,0.1,0.1},4) +addGems() +--buildings +addBuilding("Statue",{1,1,1},{0.9,0.75,0.3},8) +addBuilding("Bed",{1,1,1},{0.3,0.2,0.0},2) +addBuilding("WindowGlass",nil,nil,0,{"useMaterial"}) +addBuilding("WindowGem",nil,nil,0,{"useMaterial"}) +addBuilding("Door",nil,nil,0,{"useMaterial"}) -- special case, only closed door obstruct/emit light +addBuilding("Floodgate",nil,nil,0,{"useMaterial"}) -- special case, only closed door obstruct/emit light +--creatures +addCreature("ELEMENTMAN_MAGMA",{0.8,0.2,0.2},{0.8,0.2,0.2},5) +--items +addItem("GEM",nil,nil,{"useMaterial","onGround"}) +addItem("ROUGH",nil,nil,{"useMaterial","onGround"}) addItem("SMALLGEM",nil,nil,{"useMaterial","onGround"}) diff --git a/plugins/resume.cpp b/plugins/resume.cpp index e0db688ff..56a43b14e 100644 --- a/plugins/resume.cpp +++ b/plugins/resume.cpp @@ -56,7 +56,7 @@ static void for_each_(vector &v, Fn func) for_each(v.begin(), v.end(), func); } -template +template static void transform_(vector &src, vector &dst, Fn func) { transform(src.begin(), src.end(), back_inserter(dst), func); @@ -299,7 +299,7 @@ DFhackCExport command_result plugin_init ( color_ostream &out, std::vector & parameters) World::ReadGameMode(gm);// FIXME: check return value // if game mode isn't fortress mode - if(gm.g_mode != game_mode::DWARF || + if(gm.g_mode != game_mode::DWARF || !(gm.g_type == game_type::DWARF_MAIN || gm.g_type == game_type::DWARF_RECLAIM)) { // just print the help @@ -310,7 +310,7 @@ DFhackCExport command_result plugin_onupdate(color_ostream &out) t_gamemodes gm; World::ReadGameMode(gm);// FIXME: check return value // if game mode isn't fortress mode - if(gm.g_mode != game_mode::DWARF || + if(gm.g_mode != game_mode::DWARF || !(gm.g_type == game_type::DWARF_MAIN || gm.g_type == game_type::DWARF_RECLAIM)) { // stop running. diff --git a/plugins/stockflow.cpp b/plugins/stockflow.cpp index 33068479e..abbda87af 100644 --- a/plugins/stockflow.cpp +++ b/plugins/stockflow.cpp @@ -65,7 +65,7 @@ class LuaHelper { public: void cycle(color_ostream &out) { bool found = false; - + if (fast) { // Ignore the bookkeeper; either gather or enqueue orders every cycle. found = !bookkeeping; @@ -80,7 +80,7 @@ public: } } } - + if (found && !bookkeeping) { command_method("start_bookkeeping", out); bookkeeping = true; @@ -89,7 +89,7 @@ public: bookkeeping = false; } } - + void init() { stockpile_id = -1; initialized = false; @@ -105,96 +105,96 @@ public: initialized = false; return command_method("clear_caches", out); } - + return true; } - + bool command_method(const char *method, color_ostream &out) { // Calls a lua function with no parameters. - + // Suspension is required for "stockflow enable" from the command line, // but may be overkill for other situations. CoreSuspender suspend; - + auto L = Lua::Core::State; Lua::StackUnwinder top(L); - + if (!lua_checkstack(L, 1)) return false; - + if (!Lua::PushModulePublic(out, L, "plugins.stockflow", method)) return false; - + if (!Lua::SafeCall(out, L, 0, 0)) return false; - + return true; } - + bool stockpile_method(const char *method, building_stockpilest *sp) { // Combines the select_order and toggle_trigger method calls, // because they share the same signature. CoreSuspendClaimer suspend; - + auto L = Lua::Core::State; color_ostream_proxy out(Core::getInstance().getConsole()); - + Lua::StackUnwinder top(L); - + if (!lua_checkstack(L, 2)) return false; - + if (!Lua::PushModulePublic(out, L, "plugins.stockflow", method)) return false; - + Lua::Push(L, sp); - + if (!Lua::SafeCall(out, L, 1, 0)) return false; - + // Invalidate the string cache. stockpile_id = -1; - + return true; } - + bool collect_settings(building_stockpilest *sp) { // Find strings representing the job to order, and the trigger condition. // There might be a memory leak here; C++ is odd like that. auto L = Lua::Core::State; color_ostream_proxy out(Core::getInstance().getConsole()); - + CoreSuspendClaimer suspend; Lua::StackUnwinder top(L); - + if (!lua_checkstack(L, 2)) return false; - + if (!Lua::PushModulePublic(out, L, "plugins.stockflow", "stockpile_settings")) return false; - + Lua::Push(L, sp); - + if (!Lua::SafeCall(out, L, 1, 2)) return false; - + if (!lua_isstring(L, -1)) return false; - + current_trigger = lua_tostring(L, -1); lua_pop(L, 1); - + if (!lua_isstring(L, -1)) return false; - + current_job = lua_tostring(L, -1); lua_pop(L, 1); - + stockpile_id = sp->id; - + return true; } - + void draw(building_stockpilest *sp) { if (sp->id != stockpile_id) { if (!collect_settings(sp)) { @@ -202,12 +202,12 @@ public: return; } } - + auto dims = Gui::getDwarfmodeViewDims(); int left_margin = dims.menu_x1 + 1; int x = left_margin; int y = dims.y2 - 3; - + int links = 0; links += sp->links.give_to_pile.size(); links += sp->links.take_from_pile.size(); @@ -215,7 +215,7 @@ public: links += sp->links.take_from_workshop.size(); if (links + 12 >= y) y += 1; - + OutputHotkeyString(x, y, current_job, "j", true, left_margin, COLOR_WHITE, COLOR_LIGHTRED); if (*current_trigger) OutputHotkeyString(x, y, current_trigger, " J", true, left_margin, COLOR_WHITE, COLOR_LIGHTRED); @@ -235,9 +235,9 @@ static LuaHelper helper; #define DELTA_TICKS 600 DFhackCExport command_result plugin_onupdate(color_ostream &out) { - if (!enabled) + if (!enabled) return CR_OK; - + if (!Maps::IsValid()) return CR_OK; @@ -262,39 +262,39 @@ DFhackCExport command_result plugin_onupdate(color_ostream &out) { */ struct stockflow_hook : public df::viewscreen_dwarfmodest { typedef df::viewscreen_dwarfmodest interpose_base; - + bool handleInput(set *input) { building_stockpilest *sp = get_selected_stockpile(); if (!sp) return false; - + if (input->count(interface_key::CUSTOM_J)) { // Select a new order for this stockpile. if (!helper.stockpile_method("select_order", sp)) { Core::printerr("Stockflow order selection failed!\n"); } - + return true; } else if (input->count(interface_key::CUSTOM_SHIFT_J)) { // Toggle the order trigger for this stockpile. if (!helper.stockpile_method("toggle_trigger", sp)) { Core::printerr("Stockflow trigger toggle failed!\n"); } - + return true; } - + return false; } - + DEFINE_VMETHOD_INTERPOSE(void, feed, (set *input)) { if (!handleInput(input)) INTERPOSE_NEXT(feed)(input); } - + DEFINE_VMETHOD_INTERPOSE(void, render, ()) { INTERPOSE_NEXT(render)(); - + building_stockpilest *sp = get_selected_stockpile(); if (sp) helper.draw(sp); @@ -310,17 +310,17 @@ static bool apply_hooks(color_ostream &out, bool enabling) { out.printerr("Stockflow needs graphics.\n"); return false; } - + if (!INTERPOSE_HOOK(stockflow_hook, feed).apply(enabling) || !INTERPOSE_HOOK(stockflow_hook, render).apply(enabling)) { out.printerr("Could not %s stockflow hooks!\n", enabling? "insert": "remove"); return false; } - + if (!helper.reset(out, enabling && Maps::IsValid())) { out.printerr("Could not reset stockflow world data!\n"); return false; } - + return true; } @@ -344,12 +344,12 @@ static command_result stockflow_cmd(color_ostream &out, vector & parame out.printerr("Stockflow is not currently enabled.\n"); return CR_FAILURE; } - + if (!Maps::IsValid()) { out.printerr("You haven't loaded a map yet.\n"); return CR_FAILURE; } - + // Tell Lua to list any saved stockpile orders. return helper.command_method("list_orders", out)? CR_OK: CR_FAILURE; } else if (parameters[0] != "status") { @@ -358,13 +358,13 @@ static command_result stockflow_cmd(color_ostream &out, vector & parame } else if (parameters.size() > 1) { return CR_WRONG_USAGE; } - + if (desired != enabled) { if (!apply_hooks(out, desired)) { return CR_FAILURE; } } - + out.print("Stockflow is %s %s%s.\n", (desired == enabled)? "currently": "now", desired? "enabled": "disabled", fast? ", in fast mode": ""); enabled = desired; return CR_OK; @@ -383,7 +383,7 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan return CR_FAILURE; } } - + return CR_OK; } @@ -394,10 +394,10 @@ DFhackCExport command_result plugin_enable(color_ostream& out, bool enable) { if (!apply_hooks(out, enable)) { return CR_FAILURE; } - + enabled = enable; } - + return CR_OK; } @@ -407,10 +407,10 @@ DFhackCExport command_result plugin_init(color_ostream &out, std::vector mode != 0) continue; - if (item->getType() != mandate->item_type || + if (item->getType() != mandate->item_type || (mandate->item_subtype != -1 && item->getSubtype() != mandate->item_subtype)) continue; @@ -622,7 +622,7 @@ public: apply_to_all = false; hide_unflagged = false; - + checked_flags.bits.in_job = true; checked_flags.bits.rotten = true; checked_flags.bits.owned = true; @@ -923,7 +923,7 @@ public: ++y; OutputHotkeyString(x, y, "Min Wear: ", "Shift-W"); OutputString(COLOR_BROWN, x, y, int_to_string(min_wear), true, left_margin); - + ++y; OutputString(COLOR_BROWN, x, y, "Actions ("); OutputString(COLOR_LIGHTGREEN, x, y, int_to_string(items_column.getDisplayedListSize())); @@ -1006,7 +1006,7 @@ private: pos.y = cage_building->centery; pos.z = cage_building->z; } - + return pos; } @@ -1179,11 +1179,11 @@ private: bool caged = is_item_in_cage_cache(item); if (extra_hide_flags.hide_in_cages && caged) continue; - + if (extra_hide_flags.hide_in_inventory && container->flags.bits.in_inventory) continue; - if (hide_unflagged && (!(item->flags.whole & checked_flags.whole) && + if (hide_unflagged && (!(item->flags.whole & checked_flags.whole) && !trade_marked && !caged && !container->flags.bits.in_inventory)) { continue; @@ -1258,14 +1258,14 @@ private: items_column.display_start_offset = last_display_offset; } } - + string getItemHash(df::item *item) { auto label = get_item_label(item, true); auto quality = static_cast(item->getQuality()); auto quality_enum = static_cast(quality); auto quality_string = ENUM_KEY_STR(item_quality, quality_enum); - auto hash = label + quality_string + int_to_string(item->flags.whole & checked_flags.whole) + " " + + auto hash = label + quality_string + int_to_string(item->flags.whole & checked_flags.whole) + " " + int_to_string(item->hasImprovements()); return hash; @@ -1365,7 +1365,7 @@ struct stocks_stockpile_hook : public df::viewscreen_dwarfmodest int left_margin = dims.menu_x1 + 1; int x = left_margin; int y = dims.y2 - 4; - + int links = 0; links += sp->links.give_to_pile.size(); links += sp->links.take_from_pile.size(); diff --git a/plugins/strangemood.cpp b/plugins/strangemood.cpp index 22bafc056..8ad245c7c 100644 --- a/plugins/strangemood.cpp +++ b/plugins/strangemood.cpp @@ -628,7 +628,7 @@ command_result df_strangemood (color_ostream &out, vector & parameters) out.printerr("Chosen unit '%s' has active job, cannot start mood!\n", Translation::TranslateName(&unit->name, false).c_str()); return CR_FAILURE; } - + ui->mood_cooldown = 1000; // If no mood type was specified, pick one randomly if (type == mood_type::None) @@ -696,7 +696,7 @@ command_result df_strangemood (color_ostream &out, vector & parameters) unit->mood = type; unit->relations.mood_copy = unit->mood; Gui::showAutoAnnouncement(announcement_type::STRANGE_MOOD, unit->pos, msg, color, bright); - + // TODO: make sure unit drops any wrestle items unit->job.mood_timeout = 50000; unit->flags1.bits.has_mood = true; diff --git a/plugins/trackstop.cpp b/plugins/trackstop.cpp index 7729b24cc..9999a899f 100644 --- a/plugins/trackstop.cpp +++ b/plugins/trackstop.cpp @@ -34,7 +34,7 @@ REQUIRE_GLOBAL(world); */ struct trackstop_hook : public df::viewscreen_dwarfmodest { typedef df::viewscreen_dwarfmodest interpose_base; - + enum Friction { Lowest = 10, Low = 50, @@ -42,29 +42,29 @@ struct trackstop_hook : public df::viewscreen_dwarfmodest { High = 10000, Highest = 50000 }; - + building_trapst *get_selected_trackstop() { if (!Gui::dwarfmode_hotkey(Core::getTopViewscreen()) || ui->main.mode != ui_sidebar_mode::QueryBuilding) { // Not in a building's 'q' menu. return nullptr; } - + building_trapst *ts = virtual_cast(world->selected_building); if (!ts) { // Not a trap type of building. return nullptr; } - + if (ts->trap_type != df::trap_type::TrackStop) { // Not a trackstop. return nullptr; } - + if (ts->construction_stage < ts->getMaxBuildStage()) { // Not yet fully constructed. return nullptr; } - + for (auto it = ts->jobs.begin(); it != ts->jobs.end(); it++) { auto job = *it; if (job->job_type == df::job_type::DestroyBuilding) { @@ -72,20 +72,20 @@ struct trackstop_hook : public df::viewscreen_dwarfmodest { return nullptr; } } - + return ts; } - + bool handleInput(set *input) { building_trapst *ts = get_selected_trackstop(); if (!ts) { return false; } - + if (input->count(interface_key::BUILDING_TRACK_STOP_DUMP)) { // Change track stop dump direction. // There might be a more elegant way to do this. - + if (!ts->use_dump) { // No -> North ts->use_dump = 1; @@ -109,7 +109,7 @@ struct trackstop_hook : public df::viewscreen_dwarfmodest { ts->dump_x_shift = 0; ts->dump_y_shift = 0; } - + return true; } else if (input->count(interface_key::BUILDING_TRACK_STOP_FRICTION_UP)) { ts->friction = ( @@ -120,7 +120,7 @@ struct trackstop_hook : public df::viewscreen_dwarfmodest { (ts->friction < Friction::Highest)? Friction::Highest: ts->friction ); - + return true; } else if (input->count(interface_key::BUILDING_TRACK_STOP_FRICTION_DOWN)) { ts->friction = ( @@ -131,31 +131,31 @@ struct trackstop_hook : public df::viewscreen_dwarfmodest { (ts->friction > Friction::Lowest)? Friction::Lowest: ts->friction ); - + return true; } - + return false; } - + DEFINE_VMETHOD_INTERPOSE(void, feed, (set *input)) { if (!handleInput(input)) { INTERPOSE_NEXT(feed)(input); } } - + DEFINE_VMETHOD_INTERPOSE(void, render, ()) { INTERPOSE_NEXT(render)(); - + building_trapst *ts = get_selected_trackstop(); if (ts) { auto dims = Gui::getDwarfmodeViewDims(); int left_margin = dims.menu_x1 + 1; int x = left_margin; int y = dims.y1 + 1; - + OutputString(COLOR_WHITE, x, y, "Track Stop", true, left_margin); - + y += 3; OutputString(COLOR_WHITE, x, y, "Friction: ", false); OutputString(COLOR_WHITE, x, y, ( @@ -168,9 +168,9 @@ struct trackstop_hook : public df::viewscreen_dwarfmodest { OutputString(COLOR_LIGHTRED, x, y, Screen::getKeyDisplay(interface_key::BUILDING_TRACK_STOP_FRICTION_DOWN)); OutputString(COLOR_LIGHTRED, x, y, Screen::getKeyDisplay(interface_key::BUILDING_TRACK_STOP_FRICTION_UP)); OutputString(COLOR_WHITE, x, y, ": Change Friction", true, left_margin); - + y += 1; - + OutputString(COLOR_WHITE, x, y, "Dump on arrival: ", false); OutputString(COLOR_WHITE, x, y, ( (!ts->use_dump)? "No": @@ -188,7 +188,7 @@ struct trackstop_hook : public df::viewscreen_dwarfmodest { struct roller_hook : public df::viewscreen_dwarfmodest { typedef df::viewscreen_dwarfmodest interpose_base; - + enum Speed { Lowest = 10000, Low = 20000, @@ -196,24 +196,24 @@ struct roller_hook : public df::viewscreen_dwarfmodest { High = 40000, Highest = 50000 }; - + building_rollersst *get_selected_roller() { if (!Gui::dwarfmode_hotkey(Core::getTopViewscreen()) || ui->main.mode != ui_sidebar_mode::QueryBuilding) { // Not in a building's 'q' menu. return nullptr; } - + building_rollersst *roller = virtual_cast(world->selected_building); if (!roller) { // Not a roller. return nullptr; } - + if (roller->construction_stage < roller->getMaxBuildStage()) { // Not yet fully constructed. return nullptr; } - + for (auto it = roller->jobs.begin(); it != roller->jobs.end(); it++) { auto job = *it; if (job->job_type == df::job_type::DestroyBuilding) { @@ -221,16 +221,16 @@ struct roller_hook : public df::viewscreen_dwarfmodest { return nullptr; } } - + return roller; } - + bool handleInput(set *input) { building_rollersst *roller = get_selected_roller(); if (!roller) { return false; } - + if (input->count(interface_key::BUILDING_ORIENT_NONE)) { // Flip roller orientation. // Long rollers can only be oriented along their length. @@ -243,35 +243,35 @@ struct roller_hook : public df::viewscreen_dwarfmodest { if (roller->speed < Speed::Highest) { roller->speed += Speed::Lowest; } - + return true; } else if (input->count(interface_key::BUILDING_ROLLERS_SPEED_DOWN)) { if (roller->speed > Speed::Lowest) { roller->speed -= Speed::Lowest; } - + return true; } - + return false; } - + DEFINE_VMETHOD_INTERPOSE(void, feed, (set *input)) { if (!handleInput(input)) { INTERPOSE_NEXT(feed)(input); } } - + DEFINE_VMETHOD_INTERPOSE(void, render, ()) { INTERPOSE_NEXT(render)(); - + building_rollersst *roller = get_selected_roller(); if (roller) { auto dims = Gui::getDwarfmodeViewDims(); int left_margin = dims.menu_x1 + 1; int x = left_margin; int y = dims.y1 + 6; - + OutputString(COLOR_LIGHTRED, x, y, Screen::getKeyDisplay(interface_key::BUILDING_ORIENT_NONE)); OutputString(COLOR_WHITE, x, y, ": Rolls ", false); OutputString(COLOR_WHITE, x, y, ( @@ -281,7 +281,7 @@ struct roller_hook : public df::viewscreen_dwarfmodest { (roller->direction == df::screw_pump_direction::FromWest)? "Eastward": "" ), true, left_margin); - + OutputString(COLOR_LIGHTRED, x, y, Screen::getKeyDisplay(interface_key::BUILDING_ROLLERS_SPEED_DOWN)); OutputString(COLOR_LIGHTRED, x, y, Screen::getKeyDisplay(interface_key::BUILDING_ROLLERS_SPEED_UP)); OutputString(COLOR_WHITE, x, y, ": "); @@ -313,10 +313,10 @@ DFhackCExport command_result plugin_enable(color_ostream& out, bool enable) { out.printerr("Could not %s trackstop hooks!\n", enable? "insert": "remove"); return CR_FAILURE; } - + enabled = enable; } - + return CR_OK; } diff --git a/plugins/treefarm.cpp b/plugins/treefarm.cpp index 1578bf373..68429dd93 100644 --- a/plugins/treefarm.cpp +++ b/plugins/treefarm.cpp @@ -68,7 +68,7 @@ void checkFarms(color_ostream& out, void* ptr) { return; EventManager::registerTick(handler, frequency, plugin_self); CoreSuspender suspend; - + int32_t xOffset = world->map.region_x*3; int32_t yOffset = world->map.region_y*3; int32_t zOffset = world->map.region_z; @@ -77,19 +77,19 @@ void checkFarms(color_ostream& out, void* ptr) { df::burrow* burrow = df::burrow::get_vector()[a]; if ( !burrow || burrow->name.find("treefarm") == std::string::npos ) continue; - + if ( burrow->block_x.size() != burrow->block_y.size() || burrow->block_x.size() != burrow->block_z.size() ) continue; - + for ( size_t b = 0; b < burrow->block_x.size(); b++ ) { int32_t x=burrow->block_x[b] - xOffset; int32_t y=burrow->block_y[b] - yOffset; int32_t z=burrow->block_z[b] - zOffset; - + df::map_block* block = world->map.block_index[x][y][z]; if ( !block ) continue; - + df::block_burrow_link* link = &block->block_burrows; df::tile_bitmask mask; for ( ; link != NULL; link = link->next ) { @@ -102,7 +102,7 @@ void checkFarms(color_ostream& out, void* ptr) { } if ( link == NULL ) continue; - + for ( int32_t x = 0; x < 16; x++ ) { for ( int32_t y = 0; y < 16; y++ ) { if ( !mask.getassignment(x,y) ) @@ -123,7 +123,7 @@ void checkFarms(color_ostream& out, void* ptr) { if ( y == 15 && (block->map_pos.y/16) == world->map.y_count_block-1 ) continue; } - + block->designation[x][y].bits.dig = df::enums::tile_dig_designation::Default; } } @@ -134,7 +134,7 @@ void checkFarms(color_ostream& out, void* ptr) { command_result treefarm (color_ostream &out, std::vector & parameters) { EventManager::unregisterAll(plugin_self); - + if ( parameters.size() > 1 ) return CR_WRONG_USAGE; if ( parameters.size() == 1 ) { @@ -147,7 +147,7 @@ command_result treefarm (color_ostream &out, std::vector & paramet plugin_enable(out, true); frequency = i; } - + if ( enabled ) { EventManager::registerTick(handler, 1, plugin_self); out.print("treefarm enabled with update frequency %d ticks\n", frequency); diff --git a/plugins/uicommon.h b/plugins/uicommon.h index 733d29d61..82df61d61 100644 --- a/plugins/uicommon.h +++ b/plugins/uicommon.h @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include @@ -67,7 +67,7 @@ struct coord32_t y = other.y; z = other.z; } - + df::coord get_coord16() const { return df::coord(x, y, z); @@ -86,7 +86,7 @@ static void for_each_(map &v, Fn func) for_each(v.begin(), v.end(), func); } -template +template static void transform_(vector &src, vector &dst, Fn func) { transform(src.begin(), src.end(), back_inserter(dst), func); @@ -94,7 +94,7 @@ static void transform_(vector &src, vector &dst, Fn func) typedef int8_t UIColor; -static void OutputString(UIColor color, int &x, int &y, const std::string &text, +static void OutputString(UIColor color, int &x, int &y, const std::string &text, bool newline = false, int left_margin = 0, const UIColor bg_color = 0) { Screen::paintString(Screen::Pen(' ', color, bg_color), x, y, text); @@ -107,7 +107,7 @@ static void OutputString(UIColor color, int &x, int &y, const std::string &text, x += text.length(); } -static void OutputHotkeyString(int &x, int &y, const char *text, const char *hotkey, bool newline = false, +static void OutputHotkeyString(int &x, int &y, const char *text, const char *hotkey, bool newline = false, int left_margin = 0, int8_t text_color = COLOR_WHITE, int8_t hotkey_color = COLOR_LIGHTGREEN) { OutputString(hotkey_color, x, y, hotkey); @@ -116,7 +116,7 @@ static void OutputHotkeyString(int &x, int &y, const char *text, const char *hot OutputString(text_color, x, y, display, newline, left_margin); } -static void OutputLabelString(int &x, int &y, const char *text, const char *hotkey, const string &label, bool newline = false, +static void OutputLabelString(int &x, int &y, const char *text, const char *hotkey, const string &label, bool newline = false, int left_margin = 0, int8_t text_color = COLOR_WHITE, int8_t hotkey_color = COLOR_LIGHTGREEN) { OutputString(hotkey_color, x, y, hotkey); @@ -127,7 +127,7 @@ static void OutputLabelString(int &x, int &y, const char *text, const char *hotk OutputString(hotkey_color, x, y, label, newline, left_margin); } -static void OutputFilterString(int &x, int &y, const char *text, const char *hotkey, bool state, bool newline = false, +static void OutputFilterString(int &x, int &y, const char *text, const char *hotkey, bool state, bool newline = false, int left_margin = 0, int8_t hotkey_color = COLOR_LIGHTGREEN) { OutputString(hotkey_color, x, y, hotkey); @@ -273,9 +273,9 @@ static bool can_melt(df::item* item) if (!is_metal_item(item)) return false; - for (auto g = item->general_refs.begin(); g != item->general_refs.end(); g++) + for (auto g = item->general_refs.begin(); g != item->general_refs.end(); g++) { - switch ((*g)->getType()) + switch ((*g)->getType()) { case general_ref_type::CONTAINS_ITEM: case general_ref_type::UNIT_HOLDER: @@ -377,12 +377,12 @@ private: class PersistentStockpileInfo : public StockpileInfo { public: - PersistentStockpileInfo(df::building_stockpilest *sp, string persistence_key) : + PersistentStockpileInfo(df::building_stockpilest *sp, string persistence_key) : StockpileInfo(sp), persistence_key(persistence_key) { } - PersistentStockpileInfo(PersistentDataItem &config, string persistence_key) : + PersistentStockpileInfo(PersistentDataItem &config, string persistence_key) : config(config), persistence_key(persistence_key) { id = config.ival(1); @@ -433,7 +433,7 @@ public: bool selected; UIColor color; - ListEntry(const string text, const T elem, const string keywords = "", const UIColor color = COLOR_UNSELECTED) : + ListEntry(const string text, const T elem, const string keywords = "", const UIColor color = COLOR_UNSELECTED) : elem(elem), text(text), selected(false), keywords(keywords), color(color) { } @@ -529,7 +529,7 @@ public: ++y; UIColor fg_color = (display_list[i]->selected) ? COLOR_SELECTED : display_list[i]->color; UIColor bg_color = (is_selected_column && i == highlighted_index) ? COLOR_HIGHLIGHTED : COLOR_BLACK; - + string item_label = display_list[i]->text; if (text_clip_at > 0 && item_label.length() > text_clip_at) item_label.resize(text_clip_at); @@ -570,7 +570,7 @@ public: string item_string = toLower(list[i].text); for (auto si = search_tokens.begin(); si != search_tokens.end(); si++) { - if (!si->empty() && item_string.find(*si) == string::npos && + if (!si->empty() && item_string.find(*si) == string::npos && list[i].keywords.find(*si) == string::npos) { include_item = false; diff --git a/plugins/workNow.cpp b/plugins/workNow.cpp index b26428f8a..042914c44 100644 --- a/plugins/workNow.cpp +++ b/plugins/workNow.cpp @@ -39,7 +39,7 @@ DFhackCExport command_result plugin_init(color_ostream& out, std::vector& paramet return CR_WRONG_USAGE; } int32_t a = atoi(parameters[0].c_str()); - + if (a < 0 || a > 2) return CR_WRONG_USAGE; @@ -92,7 +92,7 @@ DFhackCExport command_result workNow(color_ostream& out, vector& paramet void jobCompletedHandler(color_ostream& out, void* ptr) { if ( mode < 2 ) return; - + *process_jobs = true; *process_dig = true; } diff --git a/plugins/workflow.cpp b/plugins/workflow.cpp index 3ee0097df..d5964da7b 100644 --- a/plugins/workflow.cpp +++ b/plugins/workflow.cpp @@ -741,7 +741,7 @@ static ItemConstraint *get_constraint(color_ostream &out, const std::string &str out.printerr("Cannot decode material mask: %s\n", maskstr.c_str()); return NULL; } - + if (mat_mask.whole != 0) weight += 100; diff --git a/scripts/add-thought.lua b/scripts/add-thought.lua index 3739f85c7..313647445 100644 --- a/scripts/add-thought.lua +++ b/scripts/add-thought.lua @@ -70,14 +70,14 @@ if args.gui then end) else local thought = args.thought or 180 - + local emotion = args.emotion or -1 - + local severity = args.severity or 0 - + local subthought = args.subthought or 0 - + local strength = args.strength or 0 - + addEmotionToUnit(unit,thought,emotion,severity,strength,subthought) end diff --git a/scripts/autofarm.rb b/scripts/autofarm.rb index 52e0245be..cc2f29dff 100644 --- a/scripts/autofarm.rb +++ b/scripts/autofarm.rb @@ -1,176 +1,176 @@ -class AutoFarm - - def initialize - @thresholds = Hash.new(50) - @lastcounts = Hash.new(0) - end - - def setthreshold(id, v) - list = df.world.raws.plants.all.find_all { |plt| plt.flags[:SEED] }.map { |plt| plt.id } - if tok = df.match_rawname(id, list) - @thresholds[tok] = v.to_i - else - puts "No plant with id #{id}, try one of " + - list.map { |w| w =~ /[^\w]/ ? w.inspect : w }.sort.join(' ') - end - end - - def setdefault(v) - @thresholds.default = v.to_i - end - - def is_plantable(plant) - has_seed = plant.flags[:SEED] - season = df.cur_season - harvest = df.cur_season_tick + plant.growdur * 10 - will_finish = harvest < 10080 - can_plant = has_seed && plant.flags[season] - can_plant = can_plant && (will_finish || plant.flags[(season+1)%4]) - can_plant - end - - def find_plantable_plants - plantable = {} - counts = Hash.new(0) - - df.world.items.other[:SEEDS].each { |i| - if (!i.flags.dump && !i.flags.forbid && !i.flags.garbage_collect && - !i.flags.hostile && !i.flags.on_fire && !i.flags.rotten && - !i.flags.trader && !i.flags.in_building && !i.flags.construction && - !i.flags.artifact) - counts[i.mat_index] += i.stack_size - end - } - - counts.keys.each { |i| - if df.ui.tasks.discovered_plants[i] - plant = df.world.raws.plants.all[i] - if is_plantable(plant) - plantable[i] = :Surface if (plant.underground_depth_min == 0 || plant.underground_depth_max == 0) - plantable[i] = :Underground if (plant.underground_depth_min > 0 || plant.underground_depth_max > 0) - end - end - } - - return plantable - end - - def set_farms(plants, farms) - return if farms.length == 0 - if plants.length == 0 - plants = [-1] - end - - season = df.cur_season - - farms.each_with_index { |f, idx| - f.plant_id[season] = plants[idx % plants.length] - } - end - - def process - plantable = find_plantable_plants - @lastcounts = Hash.new(0) - - df.world.items.other[:PLANT].each { |i| - if (!i.flags.dump && !i.flags.forbid && !i.flags.garbage_collect && - !i.flags.hostile && !i.flags.on_fire && !i.flags.rotten && - !i.flags.trader && !i.flags.in_building && !i.flags.construction && - !i.flags.artifact && plantable.has_key?(i.mat_index)) - id = df.world.raws.plants.all[i.mat_index].id - @lastcounts[id] += i.stack_size - end - } - - return unless @running - - plants_s = [] - plants_u = [] - - plantable.each_key { |k| - plant = df.world.raws.plants.all[k] - if (@lastcounts[plant.id] < @thresholds[plant.id]) - plants_s.push(k) if plantable[k] == :Surface - plants_u.push(k) if plantable[k] == :Underground - end - } - - farms_s = [] - farms_u = [] - df.world.buildings.other[:FARM_PLOT].each { |f| - if (f.flags.exists) - underground = df.map_designation_at(f.centerx,f.centery,f.z).subterranean - farms_s.push(f) unless underground - farms_u.push(f) if underground - end - } - - set_farms(plants_s, farms_s) - set_farms(plants_u, farms_u) - end - - def start - return if @running - @onupdate = df.onupdate_register('autofarm', 1200) { process } - @running = true - end - - def stop - df.onupdate_unregister(@onupdate) - @running = false - end - - def status - stat = @running ? "Running." : "Stopped." - @lastcounts.each { |k,v| - stat << "\n#{k} limit #{@thresholds.fetch(k, 'default')} current #{v}" - } - @thresholds.each { |k,v| - stat << "\n#{k} limit #{v} current 0" unless @lastcounts.has_key?(k) - } - stat << "\nDefault: #{@thresholds.default}" - stat - end - -end - -$AutoFarm ||= AutoFarm.new - -case $script_args[0] -when 'start', 'enable' - $AutoFarm.start - puts $AutoFarm.status - -when 'end', 'stop', 'disable' - $AutoFarm.stop - puts 'Stopped.' - -when 'default' - $AutoFarm.setdefault($script_args[1]) - -when 'threshold' - t = $script_args[1] - $script_args[2..-1].each {|i| - $AutoFarm.setthreshold(i, t) - } - -when 'delete' - $AutoFarm.stop - $AutoFarm = nil - -when 'help', '?' - puts < 0 || plant.underground_depth_max > 0) + end + end + } + + return plantable + end + + def set_farms(plants, farms) + return if farms.length == 0 + if plants.length == 0 + plants = [-1] + end + + season = df.cur_season + + farms.each_with_index { |f, idx| + f.plant_id[season] = plants[idx % plants.length] + } + end + + def process + plantable = find_plantable_plants + @lastcounts = Hash.new(0) + + df.world.items.other[:PLANT].each { |i| + if (!i.flags.dump && !i.flags.forbid && !i.flags.garbage_collect && + !i.flags.hostile && !i.flags.on_fire && !i.flags.rotten && + !i.flags.trader && !i.flags.in_building && !i.flags.construction && + !i.flags.artifact && plantable.has_key?(i.mat_index)) + id = df.world.raws.plants.all[i.mat_index].id + @lastcounts[id] += i.stack_size + end + } + + return unless @running + + plants_s = [] + plants_u = [] + + plantable.each_key { |k| + plant = df.world.raws.plants.all[k] + if (@lastcounts[plant.id] < @thresholds[plant.id]) + plants_s.push(k) if plantable[k] == :Surface + plants_u.push(k) if plantable[k] == :Underground + end + } + + farms_s = [] + farms_u = [] + df.world.buildings.other[:FARM_PLOT].each { |f| + if (f.flags.exists) + underground = df.map_designation_at(f.centerx,f.centery,f.z).subterranean + farms_s.push(f) unless underground + farms_u.push(f) if underground + end + } + + set_farms(plants_s, farms_s) + set_farms(plants_u, farms_u) + end + + def start + return if @running + @onupdate = df.onupdate_register('autofarm', 1200) { process } + @running = true + end + + def stop + df.onupdate_unregister(@onupdate) + @running = false + end + + def status + stat = @running ? "Running." : "Stopped." + @lastcounts.each { |k,v| + stat << "\n#{k} limit #{@thresholds.fetch(k, 'default')} current #{v}" + } + @thresholds.each { |k,v| + stat << "\n#{k} limit #{v} current 0" unless @lastcounts.has_key?(k) + } + stat << "\nDefault: #{@thresholds.default}" + stat + end + +end + +$AutoFarm ||= AutoFarm.new + +case $script_args[0] +when 'start', 'enable' + $AutoFarm.start + puts $AutoFarm.status + +when 'end', 'stop', 'disable' + $AutoFarm.stop + puts 'Stopped.' + +when 'default' + $AutoFarm.setdefault($script_args[1]) + +when 'threshold' + t = $script_args[1] + $script_args[2..-1].each {|i| + $AutoFarm.setthreshold(i, t) + } + +when 'delete' + $AutoFarm.stop + $AutoFarm = nil + +when 'help', '?' + puts < 0 - puts "Unsuspended #{count} job(s)." - df.process_jobs = true - end - end - - def start - @running = true - @onupdate = df.onupdate_register('autounsuspend', 5) { process if @running } - end - - def stop - @running = false - df.onupdate_unregister(@onupdate) - end -end - -case $script_args[0] -when 'start' - $AutoUnsuspend ||= AutoUnsuspend.new - $AutoUnsuspend.start - -when 'end', 'stop' - $AutoUnsuspend.stop - -else - puts $AutoUnsuspend && $AutoUnsuspend.running ? 'Running.' : 'Stopped.' -end +class AutoUnsuspend + attr_accessor :running + + def process + count = 0 + df.world.job_list.each { |job| + if job.job_type == :ConstructBuilding and job.flags.suspend and df.map_tile_at(job).designation.flow_size <= 1 + job.flags.suspend = false + count += 1 + end + } + if count > 0 + puts "Unsuspended #{count} job(s)." + df.process_jobs = true + end + end + + def start + @running = true + @onupdate = df.onupdate_register('autounsuspend', 5) { process if @running } + end + + def stop + @running = false + df.onupdate_unregister(@onupdate) + end +end + +case $script_args[0] +when 'start' + $AutoUnsuspend ||= AutoUnsuspend.new + $AutoUnsuspend.start + +when 'end', 'stop' + $AutoUnsuspend.stop + +else + puts $AutoUnsuspend && $AutoUnsuspend.running ? 'Running.' : 'Stopped.' +end diff --git a/scripts/create-items.rb b/scripts/create-items.rb index fb1b2d8c7..ea739f4e0 100644 --- a/scripts/create-items.rb +++ b/scripts/create-items.rb @@ -1,177 +1,177 @@ -# create first necessity items under cursor - -category = $script_args[0] || 'help' -mat_raw = $script_args[1] || 'list' -count = $script_args[2] - - -category = df.match_rawname(category, ['help', 'bars', 'boulders', 'plants', 'logs', 'webs', 'anvils']) || 'help' - -if category == 'help' - puts < 5 - df.curview.feed_keys(:CURSOR_DOWN_Z) - df.curview.feed_keys(:CURSOR_UP_Z) -else - df.curview.feed_keys(:CURSOR_UP_Z) - df.curview.feed_keys(:CURSOR_DOWN_Z) -end +# create first necessity items under cursor + +category = $script_args[0] || 'help' +mat_raw = $script_args[1] || 'list' +count = $script_args[2] + + +category = df.match_rawname(category, ['help', 'bars', 'boulders', 'plants', 'logs', 'webs', 'anvils']) || 'help' + +if category == 'help' + puts < 5 + df.curview.feed_keys(:CURSOR_DOWN_Z) + df.curview.feed_keys(:CURSOR_UP_Z) +else + df.curview.feed_keys(:CURSOR_UP_Z) + df.curview.feed_keys(:CURSOR_DOWN_Z) +end diff --git a/scripts/deathcause.rb b/scripts/deathcause.rb index 45e87daff..4ba3d2388 100644 --- a/scripts/deathcause.rb +++ b/scripts/deathcause.rb @@ -1,67 +1,67 @@ -# show death cause of a creature - -def display_death_event(e) - str = "The #{e.victim_hf_tg.race_tg.name[0]} #{e.victim_hf_tg.name} died in year #{e.year}" - str << " (cause: #{e.death_cause.to_s.downcase})," - str << " killed by the #{e.slayer_race_tg.name[0]} #{e.slayer_hf_tg.name}" if e.slayer_hf != -1 - str << " using a #{df.world.raws.itemdefs.weapons[e.weapon.item_subtype].name}" if e.weapon.item_type == :WEAPON - str << ", shot by a #{df.world.raws.itemdefs.weapons[e.weapon.shooter_item_subtype].name}" if e.weapon.shooter_item_type == :WEAPON - - puts str.chomp(',') + '.' -end - -def display_death_unit(u) - death_info = u.counters.death_tg - killer = death_info.killer_tg if death_info - - str = "The #{u.race_tg.name[0]}" - str << " #{u.name}" if u.name.has_name - str << " died" - str << " in year #{death_info.event_year}" if death_info - str << " (cause: #{u.counters.death_cause.to_s.downcase})," if u.counters.death_cause != -1 - str << " killed by the #{killer.race_tg.name[0]} #{killer.name}" if killer - - puts str.chomp(',') + '.' -end - -item = df.item_find(:selected) -unit = df.unit_find(:selected) - -if !item or !item.kind_of?(DFHack::ItemBodyComponent) - item = df.world.items.other[:ANY_CORPSE].find { |i| df.at_cursor?(i) } -end - -if item and item.kind_of?(DFHack::ItemBodyComponent) - hf = item.hist_figure_id -elsif unit - hf = unit.hist_figure_id -end - -if not hf - puts "Please select a corpse in the loo'k' menu, or an unit in the 'u'nitlist screen" - -elsif hf == -1 - if unit ||= item.unit_tg - display_death_unit(unit) - else - puts "Not a historical figure, cannot death find info" - end - -else - histfig = df.world.history.figures.binsearch(hf) - unit = histfig ? df.unit_find(histfig.unit_id) : nil - if unit and not unit.flags1.dead and not unit.flags3.ghostly - puts "#{unit.name} is not dead yet !" - - else - events = df.world.history.events - (0...events.length).reverse_each { |i| - e = events[i] - if e.kind_of?(DFHack::HistoryEventHistFigureDiedst) and e.victim_hf == hf - display_death_event(e) - break - end - } - end -end - +# show death cause of a creature + +def display_death_event(e) + str = "The #{e.victim_hf_tg.race_tg.name[0]} #{e.victim_hf_tg.name} died in year #{e.year}" + str << " (cause: #{e.death_cause.to_s.downcase})," + str << " killed by the #{e.slayer_race_tg.name[0]} #{e.slayer_hf_tg.name}" if e.slayer_hf != -1 + str << " using a #{df.world.raws.itemdefs.weapons[e.weapon.item_subtype].name}" if e.weapon.item_type == :WEAPON + str << ", shot by a #{df.world.raws.itemdefs.weapons[e.weapon.shooter_item_subtype].name}" if e.weapon.shooter_item_type == :WEAPON + + puts str.chomp(',') + '.' +end + +def display_death_unit(u) + death_info = u.counters.death_tg + killer = death_info.killer_tg if death_info + + str = "The #{u.race_tg.name[0]}" + str << " #{u.name}" if u.name.has_name + str << " died" + str << " in year #{death_info.event_year}" if death_info + str << " (cause: #{u.counters.death_cause.to_s.downcase})," if u.counters.death_cause != -1 + str << " killed by the #{killer.race_tg.name[0]} #{killer.name}" if killer + + puts str.chomp(',') + '.' +end + +item = df.item_find(:selected) +unit = df.unit_find(:selected) + +if !item or !item.kind_of?(DFHack::ItemBodyComponent) + item = df.world.items.other[:ANY_CORPSE].find { |i| df.at_cursor?(i) } +end + +if item and item.kind_of?(DFHack::ItemBodyComponent) + hf = item.hist_figure_id +elsif unit + hf = unit.hist_figure_id +end + +if not hf + puts "Please select a corpse in the loo'k' menu, or an unit in the 'u'nitlist screen" + +elsif hf == -1 + if unit ||= item.unit_tg + display_death_unit(unit) + else + puts "Not a historical figure, cannot death find info" + end + +else + histfig = df.world.history.figures.binsearch(hf) + unit = histfig ? df.unit_find(histfig.unit_id) : nil + if unit and not unit.flags1.dead and not unit.flags3.ghostly + puts "#{unit.name} is not dead yet !" + + else + events = df.world.history.events + (0...events.length).reverse_each { |i| + e = events[i] + if e.kind_of?(DFHack::HistoryEventHistFigureDiedst) and e.victim_hf == hf + display_death_event(e) + break + end + } + end +end + diff --git a/scripts/devel/light.lua b/scripts/devel/light.lua index 48324d797..111d12b46 100644 --- a/scripts/devel/light.lua +++ b/scripts/devel/light.lua @@ -9,367 +9,367 @@ local tile_attrs = df.tiletype.attrs local args={...} function setCell(x,y,cell) - cell=cell or {} - cell.fm=cell.fm or {r=1,g=1,b=1} - cell.bm=cell.bm or {r=1,g=1,b=1} - cell.fo=cell.fo or {r=0,g=0,b=0} - cell.bo=cell.bo or {r=0,g=0,b=0} - render.setCell(x,y,cell) + cell=cell or {} + cell.fm=cell.fm or {r=1,g=1,b=1} + cell.bm=cell.bm or {r=1,g=1,b=1} + cell.fo=cell.fo or {r=0,g=0,b=0} + cell.bo=cell.bo or {r=0,g=0,b=0} + render.setCell(x,y,cell) end function getCursorPos() - local g_cursor=df.global.cursor + local g_cursor=df.global.cursor if g_cursor.x ~= -30000 then return copyall(g_cursor) end end function falloff(color,sqDist,maxdist) - local v1=1/(sqDist/maxdist+1) - local v2=v1-1/(1+maxdist*maxdist) - local v=v2/(1-1/(1+maxdist*maxdist)) - return {r=v*color.r,g=v*color.g,b=v*color.b} + local v1=1/(sqDist/maxdist+1) + local v2=v1-1/(1+maxdist*maxdist) + local v=v2/(1-1/(1+maxdist*maxdist)) + return {r=v*color.r,g=v*color.g,b=v*color.b} end function blend(c1,c2) return {r=math.max(c1.r,c2.r), - g=math.max(c1.g,c2.g), - b=math.max(c1.b,c2.b)} + g=math.max(c1.g,c2.g), + b=math.max(c1.b,c2.b)} end LightOverlay=defclass(LightOverlay,guidm.DwarfOverlay) LightOverlay.ATTRS { lightMap={}, - dynamic=true, - dirty=false, + dynamic=true, + dirty=false, } function LightOverlay:init(args) - - self.tick=df.global.cur_year_tick_advmode + + self.tick=df.global.cur_year_tick_advmode end function lightPassable(shape) - if shape==df.tiletype_shape.WALL or - shape==df.tiletype_shape.BROOK_BED or - shape==df.tiletype_shape.TREE then - return false - else - return true - end + if shape==df.tiletype_shape.WALL or + shape==df.tiletype_shape.BROOK_BED or + shape==df.tiletype_shape.TREE then + return false + else + return true + end end function circle(xm, ym,r,plot) local x = -r local y = 0 - local err = 2-2*r -- /* II. Quadrant */ - repeat + local err = 2-2*r -- /* II. Quadrant */ + repeat plot(xm-x, ym+y);--/* I. Quadrant */ plot(xm-y, ym-x);--/* II. Quadrant */ plot(xm+x, ym-y);--/* III. Quadrant */ plot(xm+y, ym+x);--/* IV. Quadrant */ r = err; if (r <= y) then - y=y+1 - err =err+y*2+1; --/* e_xy+e_y < 0 */ - end + y=y+1 + err =err+y*2+1; --/* e_xy+e_y < 0 */ + end if (r > x or err > y) then - x=x+1 - err =err+x*2+1; --/* e_xy+e_x > 0 or no 2nd y-step */ - end + x=x+1 + err =err+x*2+1; --/* e_xy+e_x > 0 or no 2nd y-step */ + end until (x >= 0); end function line(x0, y0, x1, y1,plot) - local dx = math.abs(x1-x0) - local dy = math.abs(y1-y0) - local sx,sy - if x0 < x1 then sx = 1 else sx = -1 end - if y0 < y1 then sy = 1 else sy = -1 end - local err = dx-dy + local dx = math.abs(x1-x0) + local dy = math.abs(y1-y0) + local sx,sy + if x0 < x1 then sx = 1 else sx = -1 end + if y0 < y1 then sy = 1 else sy = -1 end + local err = dx-dy - while true do - if not plot(x0,y0) then - return - end - if x0 == x1 and y0 == y1 then - break - end - local e2 = 2*err - if e2 > -dy then - err = err - dy - x0 = x0 + sx - end - if x0 == x1 and y0 == y1 then - if not plot(x0,y0) then - return - end - break - end - if e2 < dx then - err = err + dx - y0 = y0 + sy - end - end + while true do + if not plot(x0,y0) then + return + end + if x0 == x1 and y0 == y1 then + break + end + local e2 = 2*err + if e2 > -dy then + err = err - dy + x0 = x0 + sx + end + if x0 == x1 and y0 == y1 then + if not plot(x0,y0) then + return + end + break + end + if e2 < dx then + err = err + dx + y0 = y0 + sy + end + end end function LightOverlay:calculateFovs() - self.fovs=self.fovs or {} - self.precalc=self.precalc or {} - for k,v in ipairs(self.fovs) do - self:calculateFov(v.pos,v.radius,v.color) - end + self.fovs=self.fovs or {} + self.precalc=self.precalc or {} + for k,v in ipairs(self.fovs) do + self:calculateFov(v.pos,v.radius,v.color) + end end function LightOverlay:calculateFov(pos,radius,color) - local vp=self:getViewport() - local map = self.df_layout.map - local ray=function(tx,ty) - local power=copyall(color) - local lx=pos.x - local ly=pos.y - local setTile=function(x,y) - if x>0 and y>0 and x<=map.width and y<=map.height then - local dtsq=(lx-x)*(lx-x)+(ly-y)*(ly-y) - local dt=math.sqrt(dtsq) - local tile=x+y*map.width - if self.precalc[tile] then - local tcol=blend(self.precalc[tile],power) - if tcol.r==self.precalc[tile].r and tcol.g==self.precalc[tile].g and self.precalc[tile].b==self.precalc[tile].b - and dtsq>0 then - return false - end - end - local ocol=self.lightMap[tile] or {r=0,g=0,b=0} - local ncol=blend(power,ocol) - - self.lightMap[tile]=ncol - local v=self.ocupancy[tile] - if dtsq>0 then - power.r=power.r*(v.r^dt) - power.g=power.g*(v.g^dt) - power.b=power.b*(v.b^dt) - end - lx=x - ly=y - local pwsq=power.r*power.r+power.g*power.g+power.b*power.b - return pwsq>levelDim*levelDim - end - return false - end - line(pos.x,pos.y,tx,ty,setTile) - end - circle(pos.x,pos.y,radius,ray) + local vp=self:getViewport() + local map = self.df_layout.map + local ray=function(tx,ty) + local power=copyall(color) + local lx=pos.x + local ly=pos.y + local setTile=function(x,y) + if x>0 and y>0 and x<=map.width and y<=map.height then + local dtsq=(lx-x)*(lx-x)+(ly-y)*(ly-y) + local dt=math.sqrt(dtsq) + local tile=x+y*map.width + if self.precalc[tile] then + local tcol=blend(self.precalc[tile],power) + if tcol.r==self.precalc[tile].r and tcol.g==self.precalc[tile].g and self.precalc[tile].b==self.precalc[tile].b + and dtsq>0 then + return false + end + end + local ocol=self.lightMap[tile] or {r=0,g=0,b=0} + local ncol=blend(power,ocol) + + self.lightMap[tile]=ncol + local v=self.ocupancy[tile] + if dtsq>0 then + power.r=power.r*(v.r^dt) + power.g=power.g*(v.g^dt) + power.b=power.b*(v.b^dt) + end + lx=x + ly=y + local pwsq=power.r*power.r+power.g*power.g+power.b*power.b + return pwsq>levelDim*levelDim + end + return false + end + line(pos.x,pos.y,tx,ty,setTile) + end + circle(pos.x,pos.y,radius,ray) end function LightOverlay:placeLightFov(pos,radius,color) - local map = self.df_layout.map - local tile=pos.x+pos.y*map.width - local ocol=self.precalc[tile] or {r=0,g=0,b=0} - local ncol=blend(color,ocol) - self.precalc[tile]=ncol - local ocol=self.lightMap[tile] or {r=0,g=0,b=0} - local ncol=blend(color,ocol) - self.lightMap[tile]=ncol - table.insert(self.fovs,{pos=pos,radius=radius,color=color}) + local map = self.df_layout.map + local tile=pos.x+pos.y*map.width + local ocol=self.precalc[tile] or {r=0,g=0,b=0} + local ncol=blend(color,ocol) + self.precalc[tile]=ncol + local ocol=self.lightMap[tile] or {r=0,g=0,b=0} + local ncol=blend(color,ocol) + self.lightMap[tile]=ncol + table.insert(self.fovs,{pos=pos,radius=radius,color=color}) end function LightOverlay:placeLightFov2(pos,radius,color,f,rays) - f=f or falloff - local raycount=rays or 25 - local vp=self:getViewport() - local map = self.df_layout.map - local off=math.random(0,math.pi) - local done={} - for d=0,math.pi*2,math.pi*2/raycount do - local dx,dy - dx=math.cos(d+off) - dy=math.sin(d+off) - local cx=0 - local cy=0 - - for dt=0,radius,0.01 do - if math.abs(math.floor(dt*dx)-cx)>0 or math.abs(math.floor(dt*dy)-cy)> 0then - local x=cx+pos.x - local y=cy+pos.y - - if x>0 and y>0 and x<=map.width and y<=map.height and not done[tile] then - local tile=x+y*map.width - done[tile]=true - local ncol=f(color,dt*dt,radius) - local ocol=self.lightMap[tile] or {r=0,g=0,b=0} - ncol=blend(ncol,ocol) - self.lightMap[tile]=ncol - - - if --(ncol.r==ocol.r and ncol.g==ocol.g and ncol.b==ocol.b) or - not self.ocupancy[tile] then - break - end - end - cx=math.floor(dt*dx) - cy=math.floor(dt*dy) - end - end - end + f=f or falloff + local raycount=rays or 25 + local vp=self:getViewport() + local map = self.df_layout.map + local off=math.random(0,math.pi) + local done={} + for d=0,math.pi*2,math.pi*2/raycount do + local dx,dy + dx=math.cos(d+off) + dy=math.sin(d+off) + local cx=0 + local cy=0 + + for dt=0,radius,0.01 do + if math.abs(math.floor(dt*dx)-cx)>0 or math.abs(math.floor(dt*dy)-cy)> 0then + local x=cx+pos.x + local y=cy+pos.y + + if x>0 and y>0 and x<=map.width and y<=map.height and not done[tile] then + local tile=x+y*map.width + done[tile]=true + local ncol=f(color,dt*dt,radius) + local ocol=self.lightMap[tile] or {r=0,g=0,b=0} + ncol=blend(ncol,ocol) + self.lightMap[tile]=ncol + + + if --(ncol.r==ocol.r and ncol.g==ocol.g and ncol.b==ocol.b) or + not self.ocupancy[tile] then + break + end + end + cx=math.floor(dt*dx) + cy=math.floor(dt*dy) + end + end + end end function LightOverlay:placeLight(pos,radius,color,f) - f=f or falloff - local vp=self:getViewport() - local map = self.df_layout.map + f=f or falloff + local vp=self:getViewport() + local map = self.df_layout.map - for i=-radius,radius do - for j=-radius,radius do - local x=pos.x+i+1 - local y=pos.y+j+1 - if x>0 and y>0 and x<=map.width and y<=map.height then - local tile=x+y*map.width - local ncol=f(color,(i*i+j*j),radius) - local ocol=self.lightMap[tile] or {r=0,g=0,b=0} - self.lightMap[tile]=blend(ncol,ocol) - end - end - end + for i=-radius,radius do + for j=-radius,radius do + local x=pos.x+i+1 + local y=pos.y+j+1 + if x>0 and y>0 and x<=map.width and y<=map.height then + local tile=x+y*map.width + local ncol=f(color,(i*i+j*j),radius) + local ocol=self.lightMap[tile] or {r=0,g=0,b=0} + self.lightMap[tile]=blend(ncol,ocol) + end + end + end end function LightOverlay:calculateLightLava() - local vp=self:getViewport() - local map = self.df_layout.map - for i=map.x1,map.x2 do - for j=map.y1,map.y2 do - local pos={x=i+vp.x1-1,y=j+vp.y1-1,z=vp.z} - local pos2={x=i+vp.x1-1,y=j+vp.y1-1,z=vp.z-1} - local t1=dfhack.maps.getTileFlags(pos) - local tt=dfhack.maps.getTileType(pos) - if tt then - local shape=tile_attrs[tt].shape - local t2=dfhack.maps.getTileFlags(pos2) - if (t1 and t1.liquid_type and t1.flow_size>0) or - (shape==df.tiletype_shape.EMPTY and t2 and t2.liquid_type and t2.flow_size>0) then - --self:placeLight({x=i,y=j},5,{r=0.8,g=0.2,b=0.2}) - self:placeLightFov({x=i,y=j},5,{r=0.8,g=0.2,b=0.2},nil) - end - end - end - end + local vp=self:getViewport() + local map = self.df_layout.map + for i=map.x1,map.x2 do + for j=map.y1,map.y2 do + local pos={x=i+vp.x1-1,y=j+vp.y1-1,z=vp.z} + local pos2={x=i+vp.x1-1,y=j+vp.y1-1,z=vp.z-1} + local t1=dfhack.maps.getTileFlags(pos) + local tt=dfhack.maps.getTileType(pos) + if tt then + local shape=tile_attrs[tt].shape + local t2=dfhack.maps.getTileFlags(pos2) + if (t1 and t1.liquid_type and t1.flow_size>0) or + (shape==df.tiletype_shape.EMPTY and t2 and t2.liquid_type and t2.flow_size>0) then + --self:placeLight({x=i,y=j},5,{r=0.8,g=0.2,b=0.2}) + self:placeLightFov({x=i,y=j},5,{r=0.8,g=0.2,b=0.2},nil) + end + end + end + end end function LightOverlay:calculateLightSun() - local vp=self:getViewport() - local map = self.df_layout.map - for i=map.x1,map.x2+1 do - for j=map.y1,map.y2+1 do - local pos={x=i+vp.x1-1,y=j+vp.y1-1,z=vp.z} - - local t1=dfhack.maps.getTileFlags(pos) - - if (t1 and t1.outside ) then - - self:placeLightFov({x=i,y=j},15,{r=1,g=1,b=1},nil) - end - end - end + local vp=self:getViewport() + local map = self.df_layout.map + for i=map.x1,map.x2+1 do + for j=map.y1,map.y2+1 do + local pos={x=i+vp.x1-1,y=j+vp.y1-1,z=vp.z} + + local t1=dfhack.maps.getTileFlags(pos) + + if (t1 and t1.outside ) then + + self:placeLightFov({x=i,y=j},15,{r=1,g=1,b=1},nil) + end + end + end end function LightOverlay:calculateLightCursor() - local c=getCursorPos() - - if c then - - local vp=self:getViewport() - local pos=vp:tileToScreen(c) - --self:placeLight(pos,11,{r=0.96,g=0.84,b=0.03}) - self:placeLightFov({x=pos.x+1,y=pos.y+1},11,{r=0.96,g=0.84,b=0.03}) - - end + local c=getCursorPos() + + if c then + + local vp=self:getViewport() + local pos=vp:tileToScreen(c) + --self:placeLight(pos,11,{r=0.96,g=0.84,b=0.03}) + self:placeLightFov({x=pos.x+1,y=pos.y+1},11,{r=0.96,g=0.84,b=0.03}) + + end end function LightOverlay:buildOcupancy() - self.ocupancy={} - local vp=self:getViewport() - local map = self.df_layout.map - for i=map.x1,map.x2+1 do - for j=map.y1,map.y2+1 do - local pos={x=i+vp.x1-1,y=j+vp.y1-1,z=vp.z} - local tile=i+j*map.width - local tt=dfhack.maps.getTileType(pos) - local t1=dfhack.maps.getTileFlags(pos) - if tt then - local shape=tile_attrs[tt].shape - if not lightPassable(shape) then - self.ocupancy[tile]={r=0,g=0,b=0} - else - if t1 and not t1.liquid_type and t1.flow_size>2 then - self.ocupancy[tile]={r=0.5,g=0.5,b=0.7} - else - self.ocupancy[tile]={r=0.8,g=0.8,b=0.8} - end - end - end - end - end + self.ocupancy={} + local vp=self:getViewport() + local map = self.df_layout.map + for i=map.x1,map.x2+1 do + for j=map.y1,map.y2+1 do + local pos={x=i+vp.x1-1,y=j+vp.y1-1,z=vp.z} + local tile=i+j*map.width + local tt=dfhack.maps.getTileType(pos) + local t1=dfhack.maps.getTileFlags(pos) + if tt then + local shape=tile_attrs[tt].shape + if not lightPassable(shape) then + self.ocupancy[tile]={r=0,g=0,b=0} + else + if t1 and not t1.liquid_type and t1.flow_size>2 then + self.ocupancy[tile]={r=0.5,g=0.5,b=0.7} + else + self.ocupancy[tile]={r=0.8,g=0.8,b=0.8} + end + end + end + end + end end function LightOverlay:changed() - if self.dirty or self.tick~=df.global.cur_year_tick_advmode then - self.dirty=false - self.tick=df.global.cur_year_tick_advmode - return true - end - return false + if self.dirty or self.tick~=df.global.cur_year_tick_advmode then + self.dirty=false + self.tick=df.global.cur_year_tick_advmode + return true + end + return false end function LightOverlay:makeLightMap() - if not self:changed() then - return - end - self.fovs={} - self.precalc={} - self.lightMap={} - - self:buildOcupancy() - self:calculateLightCursor() - self:calculateLightLava() - self:calculateLightSun() - - self:calculateFovs() + if not self:changed() then + return + end + self.fovs={} + self.precalc={} + self.lightMap={} + + self:buildOcupancy() + self:calculateLightCursor() + self:calculateLightLava() + self:calculateLightSun() + + self:calculateFovs() end function LightOverlay:onIdle() - self._native.parent:logic() + self._native.parent:logic() end function LightOverlay:render(dc) - if self.dynamic then - self:makeLightMap() - end - self:renderParent() - local vp=self:getViewport() - local map = self.df_layout.map - - self.lightMap=self.lightMap or {} - render.lockGrids() - render.invalidate({x=map.x1,y=map.y1,w=map.width,h=map.height}) - render.resetGrids() - for i=map.x1,map.x2 do - for j=map.y1,map.y2 do - local v=self.lightMap[i+j*map.width] - if v then - setCell(i,j,{fm=v,bm=v}) - else - local dimRgb={r=levelDim,g=levelDim,b=levelDim} - setCell(i,j,{fm=dimRgb,bm=dimRgb}) - end - end - end - render.unlockGrids() - + if self.dynamic then + self:makeLightMap() + end + self:renderParent() + local vp=self:getViewport() + local map = self.df_layout.map + + self.lightMap=self.lightMap or {} + render.lockGrids() + render.invalidate({x=map.x1,y=map.y1,w=map.width,h=map.height}) + render.resetGrids() + for i=map.x1,map.x2 do + for j=map.y1,map.y2 do + local v=self.lightMap[i+j*map.width] + if v then + setCell(i,j,{fm=v,bm=v}) + else + local dimRgb={r=levelDim,g=levelDim,b=levelDim} + setCell(i,j,{fm=dimRgb,bm=dimRgb}) + end + end + end + render.unlockGrids() + end function LightOverlay:onDismiss() - render.lockGrids() - render.resetGrids() - render.invalidate() - render.unlockGrids() - + render.lockGrids() + render.resetGrids() + render.invalidate() + render.unlockGrids() + end function LightOverlay:onInput(keys) - if keys.STRING_A096 then - self:dismiss() - else - self:sendInputToParent(keys) - - if keys.CHANGETAB then - self:updateLayout() - end - if keys.STRING_A126 and not self.dynamic then - self:makeLightMap() - end - self.dirty=true - end + if keys.STRING_A096 then + self:dismiss() + else + self:sendInputToParent(keys) + + if keys.CHANGETAB then + self:updateLayout() + end + if keys.STRING_A126 and not self.dynamic then + self:makeLightMap() + end + self.dirty=true + end end if not render.isEnabled() then - qerror("Lua rendermode not enabled!") + qerror("Lua rendermode not enabled!") end local dyn=true if #args>0 and args[1]=="static" then dyn=false end diff --git a/scripts/devel/scanitemother.rb b/scripts/devel/scanitemother.rb index e026f926b..00b093a28 100644 --- a/scripts/devel/scanitemother.rb +++ b/scripts/devel/scanitemother.rb @@ -6,5 +6,5 @@ raise 'select an item' if not tg o = df.world.items.other # discard ANY/BAD o._indexenum::ENUM.sort.transpose[1][1..-2].each { |k| - puts k if o[k].find { |i| i == tg } + puts k if o[k].find { |i| i == tg } } diff --git a/scripts/devel/spawn-unit-helper.rb b/scripts/devel/spawn-unit-helper.rb index 999fe7e45..a7d4f610d 100644 --- a/scripts/devel/spawn-unit-helper.rb +++ b/scripts/devel/spawn-unit-helper.rb @@ -4,10 +4,10 @@ df.world.arena_spawn.race.clear df.world.arena_spawn.caste.clear df.world.raws.creatures.all.length.times { |r_idx| - df.world.raws.creatures.all[r_idx].caste.length.times { |c_idx| - df.world.arena_spawn.race << r_idx - df.world.arena_spawn.caste << c_idx - } + df.world.raws.creatures.all[r_idx].caste.length.times { |c_idx| + df.world.arena_spawn.race << r_idx + df.world.arena_spawn.caste << c_idx + } } df.world.arena_spawn.creature_cnt[df.world.arena_spawn.race.length-1] = 0 diff --git a/scripts/digfort.rb b/scripts/digfort.rb index 0d41649b3..c12957500 100644 --- a/scripts/digfort.rb +++ b/scripts/digfort.rb @@ -1,65 +1,65 @@ -# designate an area for digging according to a plan in csv format - -fname = $script_args[0].to_s - -if not $script_args[0] then - puts " Usage: digfort " - throw :script_finished -end -if not fname[-4..-1] == ".csv" then - puts " The plan file must be in .csv format." - throw :script_finished -end -if not File.file?(fname) then - puts " The specified file does not exist." - throw :script_finished -end - -planfile = File.read(fname) - -if df.cursor.x == -30000 - puts "place the game cursor to the top-left corner of the design and retry" - throw :script_finished -end - -offset = [0, 0] -tiles = [] -planfile.each_line { |l| - if l =~ /#.*start\s*\(\s*(-?\d+)\s*[,;]\s*(-?\d+)/ - raise "Error: multiple start() comments" if offset != [0, 0] - offset = [$1.to_i, $2.to_i] - end - - l = l.chomp.sub(/#.*/, '') - next if l == '' - tiles << l.split(/[;,]/).map { |t| - t = t.strip - (t[0] == ?") ? t[1..-2] : t - } -} - -x = df.cursor.x - offset[0] -y = df.cursor.y - offset[1] -z = df.cursor.z - -tiles.each { |line| - next if line.empty? or line == [''] - line.each { |tile| - t = df.map_tile_at(x, y, z) - s = t.shape_basic - case tile - when 'd'; t.dig(:Default) if s == :Wall - when 'u'; t.dig(:UpStair) if s == :Wall - when 'j'; t.dig(:DownStair) if s == :Wall or s == :Floor - when 'i'; t.dig(:UpDownStair) if s == :Wall - when 'h'; t.dig(:Channel) if s == :Wall or s == :Floor - when 'r'; t.dig(:Ramp) if s == :Wall - when 'x'; t.dig(:No) - end - x += 1 - } - x = df.cursor.x - offset[0] - y += 1 -} - -puts ' done' +# designate an area for digging according to a plan in csv format + +fname = $script_args[0].to_s + +if not $script_args[0] then + puts " Usage: digfort " + throw :script_finished +end +if not fname[-4..-1] == ".csv" then + puts " The plan file must be in .csv format." + throw :script_finished +end +if not File.file?(fname) then + puts " The specified file does not exist." + throw :script_finished +end + +planfile = File.read(fname) + +if df.cursor.x == -30000 + puts "place the game cursor to the top-left corner of the design and retry" + throw :script_finished +end + +offset = [0, 0] +tiles = [] +planfile.each_line { |l| + if l =~ /#.*start\s*\(\s*(-?\d+)\s*[,;]\s*(-?\d+)/ + raise "Error: multiple start() comments" if offset != [0, 0] + offset = [$1.to_i, $2.to_i] + end + + l = l.chomp.sub(/#.*/, '') + next if l == '' + tiles << l.split(/[;,]/).map { |t| + t = t.strip + (t[0] == ?") ? t[1..-2] : t + } +} + +x = df.cursor.x - offset[0] +y = df.cursor.y - offset[1] +z = df.cursor.z + +tiles.each { |line| + next if line.empty? or line == [''] + line.each { |tile| + t = df.map_tile_at(x, y, z) + s = t.shape_basic + case tile + when 'd'; t.dig(:Default) if s == :Wall + when 'u'; t.dig(:UpStair) if s == :Wall + when 'j'; t.dig(:DownStair) if s == :Wall or s == :Floor + when 'i'; t.dig(:UpDownStair) if s == :Wall + when 'h'; t.dig(:Channel) if s == :Wall or s == :Floor + when 'r'; t.dig(:Ramp) if s == :Wall + when 'x'; t.dig(:No) + end + x += 1 + } + x = df.cursor.x - offset[0] + y += 1 +} + +puts ' done' diff --git a/scripts/drain-aquifer.lua b/scripts/drain-aquifer.lua index 0c153acaf..4f7fd1616 100644 --- a/scripts/drain-aquifer.lua +++ b/scripts/drain-aquifer.lua @@ -9,7 +9,7 @@ local function drain() if block.flags.has_aquifer then block.flags.has_aquifer = false block.flags.check_aquifer = false - + for x, row in ipairs(block.designation) do for y, tile in ipairs(row) do if tile.water_table then @@ -18,7 +18,7 @@ local function drain() end end end - + if not layers[block.map_pos.z] then layers[block.map_pos.z] = true layer_count = layer_count + 1 diff --git a/scripts/exterminate.rb b/scripts/exterminate.rb index 5dfc36a96..b2625428f 100644 --- a/scripts/exterminate.rb +++ b/scripts/exterminate.rb @@ -1,151 +1,151 @@ -# exterminate creatures - -# race = name of the race to eradicate, use 'him' to target only the selected creature -# use 'undead' to target all undeads -race = $script_args[0] - -# if the 2nd parameter is 'magma', magma rain for the targets instead of instant death -# if it is 'butcher' mark all units for butchering (wont work with hostiles) -kill_by = $script_args[1] - -case kill_by -when 'magma' - slain = 'burning' -when 'slaughter', 'butcher' - slain = 'marked for butcher' -when nil - slain = 'slain' -else - race = 'help' -end - -checkunit = lambda { |u| - (u.body.blood_count != 0 or u.body.blood_max == 0) and - not u.flags1.dead and - not u.flags1.caged and not u.flags1.chained and - #not u.flags1.hidden_in_ambush and - not df.map_designation_at(u).hidden -} - -slayit = lambda { |u| - case kill_by - when 'magma' - # it's getting hot around here - # !!WARNING!! do not call on a magma-safe creature - ouh = df.onupdate_register("exterminate ensure #{u.id}", 1) { - if u.flags1.dead - df.onupdate_unregister(ouh) - else - x, y, z = u.pos.x, u.pos.y, u.pos.z - z += 1 while tile = df.map_tile_at(x, y, z+1) and - tile.shape_passableflow and tile.shape_passablelow - df.map_tile_at(x, y, z).spawn_magma(7) - end - } - when 'butcher', 'slaughter' - # mark for slaughter at butcher's shop - u.flags2.slaughter = true - else - # just make them drop dead - u.body.blood_count = 0 - # some races dont mind having no blood, ensure they are still taken care of. - u.animal.vanish_countdown = 2 - end -} - -all_races = Hash.new(0) - -df.world.units.active.map { |u| - if checkunit[u] - if (u.enemy.undead or - (u.curse.add_tags1.OPPOSED_TO_LIFE and not - u.curse.rem_tags1.OPPOSED_TO_LIFE)) - all_races['Undead'] += 1 - else - all_races[u.race_tg.creature_id] += 1 - end - end -} - -case race -when nil - all_races.sort_by { |race, cnt| [cnt, race] }.each{ |race, cnt| puts " #{race} #{cnt}" } - -when 'help', '?' - puts < i2 - links.delete_at i2 - links.delete_at i1 - links << DFHack::HistfigEntityLinkMemberst.cpp_new(:entity_id => df.ui.civ_id, :link_strength => 100) - df.add_announcement "fixloyalty: #{unit.name} is now a member of #{df.ui.civ_tg.name} again" - end - - # check if the unit is a group renegade - if i1 = links.index { |l| - l.kind_of?(DFHack::HistfigEntityLinkFormerMemberst) and - l.entity_id == df.ui.group_id - } and i2 = links.index { |l| - l.kind_of?(DFHack::HistfigEntityLinkEnemyst) and - l.entity_id == df.ui.group_id - } - fixed = true - i1, i2 = i2, i1 if i1 > i2 - links.delete_at i2 - links.delete_at i1 - links << DFHack::HistfigEntityLinkMemberst.cpp_new(:entity_id => df.ui.group_id, :link_strength => 100) - df.add_announcement "fixloyalty: #{unit.name} is now a member of #{df.ui.group_tg.name} again" - end - - # fix the 'is an enemy' cache matrix (mark to be recalculated by the game when needed) - if fixed and unit.enemy.enemy_status_slot != -1 - i = unit.enemy.enemy_status_slot - unit.enemy.enemy_status_slot = -1 - cache = df.world.enemy_status_cache - cache.slot_used[i] = false - cache.rel_map[i].map! { -1 } - cache.rel_map.each { |a| a[i] = -1 } - cache.next_slot = i if cache.next_slot > i - end - - # return true if we actually fixed the unit - fixed -end - -count = 0 -df.unit_citizens.each { |u| - count += 1 if fixunit(u) -} - -if count > 0 - puts "loyalty cascade fixed (#{count} dwarves)" -else - puts "no loyalty cascade found" -end +# script to fix loyalty cascade, when you order your militia to kill friendly units + +def fixunit(unit) + return if unit.race != df.ui.race_id or unit.civ_id != df.ui.civ_id + links = unit.hist_figure_tg.entity_links + fixed = false + + # check if the unit is a civ renegade + if i1 = links.index { |l| + l.kind_of?(DFHack::HistfigEntityLinkFormerMemberst) and + l.entity_id == df.ui.civ_id + } and i2 = links.index { |l| + l.kind_of?(DFHack::HistfigEntityLinkEnemyst) and + l.entity_id == df.ui.civ_id + } + fixed = true + i1, i2 = i2, i1 if i1 > i2 + links.delete_at i2 + links.delete_at i1 + links << DFHack::HistfigEntityLinkMemberst.cpp_new(:entity_id => df.ui.civ_id, :link_strength => 100) + df.add_announcement "fixloyalty: #{unit.name} is now a member of #{df.ui.civ_tg.name} again" + end + + # check if the unit is a group renegade + if i1 = links.index { |l| + l.kind_of?(DFHack::HistfigEntityLinkFormerMemberst) and + l.entity_id == df.ui.group_id + } and i2 = links.index { |l| + l.kind_of?(DFHack::HistfigEntityLinkEnemyst) and + l.entity_id == df.ui.group_id + } + fixed = true + i1, i2 = i2, i1 if i1 > i2 + links.delete_at i2 + links.delete_at i1 + links << DFHack::HistfigEntityLinkMemberst.cpp_new(:entity_id => df.ui.group_id, :link_strength => 100) + df.add_announcement "fixloyalty: #{unit.name} is now a member of #{df.ui.group_tg.name} again" + end + + # fix the 'is an enemy' cache matrix (mark to be recalculated by the game when needed) + if fixed and unit.enemy.enemy_status_slot != -1 + i = unit.enemy.enemy_status_slot + unit.enemy.enemy_status_slot = -1 + cache = df.world.enemy_status_cache + cache.slot_used[i] = false + cache.rel_map[i].map! { -1 } + cache.rel_map.each { |a| a[i] = -1 } + cache.next_slot = i if cache.next_slot > i + end + + # return true if we actually fixed the unit + fixed +end + +count = 0 +df.unit_citizens.each { |u| + count += 1 if fixunit(u) +} + +if count > 0 + puts "loyalty cascade fixed (#{count} dwarves)" +else + puts "no loyalty cascade found" +end diff --git a/scripts/fix/stuckdoors.rb b/scripts/fix/stuckdoors.rb index 5c4adada1..249ed5810 100644 --- a/scripts/fix/stuckdoors.rb +++ b/scripts/fix/stuckdoors.rb @@ -1,25 +1,25 @@ -# fix doors that are frozen in 'open' state - -# this may happen after people mess with the game by (incorrectly) teleporting units or items -# a door may stick open if the map occupancy flags are wrong - -count = 0 -df.world.buildings.all.each { |bld| - # for all doors - next if bld._rtti_classname != :building_doorst - # check if it is open - next if bld.close_timer == 0 - # check if occupancy is set - occ = df.map_occupancy_at(bld.x1, bld.y1, bld.z) - if (occ.unit or occ.unit_grounded) and not - # check if an unit is present - df.world.units.active.find { |u| u.pos.x == bld.x1 and u.pos.y == bld.y1 and u.pos.z == bld.z } - count += 1 - occ.unit = occ.unit_grounded = false - end - if occ.item and not df.world.items.all.find { |i| i.pos.x == bld.x1 and i.pos.y == bld.y1 and i.pos.z == bld.z } - count += 1 - occ.item = false - end -} -puts "unstuck #{count} doors" +# fix doors that are frozen in 'open' state + +# this may happen after people mess with the game by (incorrectly) teleporting units or items +# a door may stick open if the map occupancy flags are wrong + +count = 0 +df.world.buildings.all.each { |bld| + # for all doors + next if bld._rtti_classname != :building_doorst + # check if it is open + next if bld.close_timer == 0 + # check if occupancy is set + occ = df.map_occupancy_at(bld.x1, bld.y1, bld.z) + if (occ.unit or occ.unit_grounded) and not + # check if an unit is present + df.world.units.active.find { |u| u.pos.x == bld.x1 and u.pos.y == bld.y1 and u.pos.z == bld.z } + count += 1 + occ.unit = occ.unit_grounded = false + end + if occ.item and not df.world.items.all.find { |i| i.pos.x == bld.x1 and i.pos.y == bld.y1 and i.pos.z == bld.z } + count += 1 + occ.item = false + end +} +puts "unstuck #{count} doors" diff --git a/scripts/forum-dwarves.lua b/scripts/forum-dwarves.lua index 805d8586a..eb12b3bae 100644 --- a/scripts/forum-dwarves.lua +++ b/scripts/forum-dwarves.lua @@ -8,35 +8,35 @@ local args = {...} if args[1] == 'help' then print([[ description: - This script will attempt to read the current df-screen, and if it is a - text-viewscreen (such as the dwarf 'thoughts' screen or an item - 'description') then append a marked-up version of this text to the - target file. Previous entries in the file are not overwritten, so you - may use the 'forumdwarves' command multiple times to create a single - document containing the text from multiple screens (eg: text screens - from several dwarves, or text screens from multiple artifacts/items, + This script will attempt to read the current df-screen, and if it is a + text-viewscreen (such as the dwarf 'thoughts' screen or an item + 'description') then append a marked-up version of this text to the + target file. Previous entries in the file are not overwritten, so you + may use the 'forumdwarves' command multiple times to create a single + document containing the text from multiple screens (eg: text screens + from several dwarves, or text screens from multiple artifacts/items, or some combination). known screens: - The screens which have been tested and known to function properly with + The screens which have been tested and known to function properly with this script are: 1: dwarf/unit 'thoughts' screen 2: item/art 'description' screen 3: individual 'historical item/figure' screens - There may be other screens to which the script applies. It should be - safe to attempt running the script with any screen active, with an + There may be other screens to which the script applies. It should be + safe to attempt running the script with any screen active, with an error message to inform you when the selected screen is not appropriate for this script. target file: The target file's name is 'forumdwarves.txt'. A remider to this effect will be displayed if the script is successful. character encoding: - The text will likely be using system-default encoding, and as such - will likely NOT display special characters (eg:È,ı,Á) correctly. To - fix this, you need to modify the character set that you are reading - the document with. 'Notepad++' is a freely available program which + The text will likely be using system-default encoding, and as such + will likely NOT display special characters (eg:È,ı,Á) correctly. To + fix this, you need to modify the character set that you are reading + the document with. 'Notepad++' is a freely available program which can do this using the following steps: 1: open the document in Notepad++ - 2: in the menu-bar, select + 2: in the menu-bar, select Encoding->Character Sets->Western European->OEM-US 3: copy the text normally to wherever you want to use it ]]) @@ -69,32 +69,32 @@ local flerb = dfhack.gui.getFocusString(scrn) local function format_for_forum(strin) local strout = strin - + local newline_idx = string.find(strout, '[P]', 1, true) while newline_idx ~= nil do strout = string.sub(strout,1, newline_idx-1)..'\n'..string.sub(strout,newline_idx+3) newline_idx = string.find(strout, '[P]', 1, true) end - + newline_idx = string.find(strout, '[B]', 1, true) while newline_idx ~= nil do strout = string.sub(strout,1, newline_idx-1)..'\n'..string.sub(strout,newline_idx+3) newline_idx = string.find(strout, '[B]', 1, true) end - + newline_idx = string.find(strout, '[R]', 1, true) while newline_idx ~= nil do strout = string.sub(strout,1, newline_idx-1)..'\n'..string.sub(strout,newline_idx+3) newline_idx = string.find(strout, '[R]', 1, true) end - + local color_idx = string.find(strout, '[C:', 1, true) while color_idx ~= nil do local colormatch = (string.byte(strout, color_idx+3)-48)+((string.byte(strout, color_idx+7)-48)*8) strout = string.sub(strout,1, color_idx-1)..'[/color][color='..colors_css[colormatch]..']'..string.sub(strout,color_idx+9) color_idx = string.find(strout, '[C:', 1, true) end - + return strout end @@ -103,7 +103,7 @@ if flerb == 'textviewer' then printall(scrn) local lines = scrn.src_text local line = "" - + if lines ~= nil then local log = io.open('forumdwarves.txt', 'a') log:write("[color=silver]") diff --git a/scripts/full-heal.lua b/scripts/full-heal.lua index 8de3f9eda..d7267118c 100644 --- a/scripts/full-heal.lua +++ b/scripts/full-heal.lua @@ -30,9 +30,9 @@ if args.help then end if(args.unit) then - unit = df.unit.find(args.unit) + unit = df.unit.find(args.unit) else - unit = dfhack.gui.getSelectedUnit() + unit = dfhack.gui.getSelectedUnit() end if not unit then @@ -51,7 +51,7 @@ if unit then unit.flags3.ghostly = false --unit.unk_100 = 3 end - + --print("Erasing wounds...") while #unit.body.wounds > 0 do unit.body.wounds:erase(#unit.body.wounds-1) @@ -96,7 +96,7 @@ if unit then unit.counters2.thirst_timer=0 unit.counters2.sleepiness_timer=0 unit.counters2.vomit_timeout=0 - + --print("Resetting body part status...") local v=unit.body.components for i=0,#v.nonsolid_remaining - 1,1 do @@ -111,7 +111,7 @@ if unit then v.layer_dent_fraction[i] = 0 -- 100*surface percentage of dents on the body part layer (Urist Da Vinci) v.layer_effect_fraction[i] = 0 -- 100*surface percentage of "effects" on the body part layer (Urist Da Vinci) end - + v=unit.body.components.body_part_status for i=0,#v-1,1 do v[i].on_fire = false @@ -126,7 +126,7 @@ if unit then v[i].motor_nerve_severed = false v[i].sensory_nerve_severed = false end - + if unit.job.current_job and unit.job.current_job.job_type == df.job_type.Rest then --print("Wake from rest -> clean self...") unit.job.current_job = df.job_type.CleanSelf diff --git a/scripts/gaydar.lua b/scripts/gaydar.lua index f4eb7d67f..1aca8cdbe 100644 --- a/scripts/gaydar.lua +++ b/scripts/gaydar.lua @@ -1,5 +1,5 @@ local utils = require('utils') - + validArgs = utils.invert({ 'all', 'citizens', @@ -12,7 +12,7 @@ validArgs = utils.invert({ 'help' }) - + local args = utils.processArgs({...}, validArgs) if args.help then @@ -40,7 +40,7 @@ orientation filters: shows only creatures who are strictly straight. -asexualOnly shows only creatures who are strictly asexual. - + No argument will show the orientation of the unit under the cursor. ]]) diff --git a/scripts/growcrops.rb b/scripts/growcrops.rb index ed370030e..c5ad717cc 100644 --- a/scripts/growcrops.rb +++ b/scripts/growcrops.rb @@ -1,49 +1,49 @@ -# grow crops in farm plots. ex: growcrops helmet_plump 20 - -material = $script_args[0] -count_max = $script_args[1].to_i -count_max = 100 if count_max == 0 - -# cache information from the raws -@raws_plant_name ||= {} -@raws_plant_growdur ||= {} -if @raws_plant_name.empty? - df.world.raws.plants.all.each_with_index { |p, idx| - @raws_plant_name[idx] = p.id - @raws_plant_growdur[idx] = p.growdur - } -end - -inventory = Hash.new(0) -df.world.items.other[:SEEDS].each { |seed| - next if not seed.flags.in_building - next if not seed.general_refs.find { |ref| ref._rtti_classname == :general_ref_building_holderst } - next if seed.grow_counter >= @raws_plant_growdur[seed.mat_index] - inventory[seed.mat_index] += 1 -} - -if !material or material == 'help' or material == 'list' - # show a list of available crop types - inventory.sort_by { |mat, c| c }.each { |mat, c| - name = df.world.raws.plants.all[mat].id - puts " #{name} #{c}" - } - -else - - mat = df.match_rawname(material, inventory.keys.map { |k| @raws_plant_name[k] }) - unless wantmat = @raws_plant_name.index(mat) - raise "invalid plant material #{material}" - end - - count = 0 - df.world.items.other[:SEEDS].each { |seed| - next if seed.mat_index != wantmat - next if not seed.flags.in_building - next if not seed.general_refs.find { |ref| ref._rtti_classname == :general_ref_building_holderst } - next if seed.grow_counter >= @raws_plant_growdur[seed.mat_index] - seed.grow_counter = @raws_plant_growdur[seed.mat_index] - count += 1 - } - puts "Grown #{count} #{mat}" -end +# grow crops in farm plots. ex: growcrops helmet_plump 20 + +material = $script_args[0] +count_max = $script_args[1].to_i +count_max = 100 if count_max == 0 + +# cache information from the raws +@raws_plant_name ||= {} +@raws_plant_growdur ||= {} +if @raws_plant_name.empty? + df.world.raws.plants.all.each_with_index { |p, idx| + @raws_plant_name[idx] = p.id + @raws_plant_growdur[idx] = p.growdur + } +end + +inventory = Hash.new(0) +df.world.items.other[:SEEDS].each { |seed| + next if not seed.flags.in_building + next if not seed.general_refs.find { |ref| ref._rtti_classname == :general_ref_building_holderst } + next if seed.grow_counter >= @raws_plant_growdur[seed.mat_index] + inventory[seed.mat_index] += 1 +} + +if !material or material == 'help' or material == 'list' + # show a list of available crop types + inventory.sort_by { |mat, c| c }.each { |mat, c| + name = df.world.raws.plants.all[mat].id + puts " #{name} #{c}" + } + +else + + mat = df.match_rawname(material, inventory.keys.map { |k| @raws_plant_name[k] }) + unless wantmat = @raws_plant_name.index(mat) + raise "invalid plant material #{material}" + end + + count = 0 + df.world.items.other[:SEEDS].each { |seed| + next if seed.mat_index != wantmat + next if not seed.flags.in_building + next if not seed.general_refs.find { |ref| ref._rtti_classname == :general_ref_building_holderst } + next if seed.grow_counter >= @raws_plant_growdur[seed.mat_index] + seed.grow_counter = @raws_plant_growdur[seed.mat_index] + count += 1 + } + puts "Grown #{count} #{mat}" +end diff --git a/scripts/gui/advfort.lua b/scripts/gui/advfort.lua index 17aef6a42..1c8713d02 100644 --- a/scripts/gui/advfort.lua +++ b/scripts/gui/advfort.lua @@ -30,13 +30,13 @@ prevJob={key="CUSTOM_SHIFT_R",desc="Previous job in the list"}, continue={key="A_WAIT",desc="Continue job if available"}, down_alt1={key="CUSTOM_CTRL_D",desc="Use job down"}, down_alt2={key="CURSOR_DOWN_Z_AUX",desc="Use job down"}, -up_alt1={key="CUSTOM_CTRL_E",desc="Use job up"}, +up_alt1={key="CUSTOM_CTRL_E",desc="Use job up"}, up_alt2={key="CURSOR_UP_Z_AUX",desc="Use job up"}, use_same={key="A_MOVE_SAME_SQUARE",desc="Use job at the tile you are standing"}, workshop={key="CHANGETAB",desc="Show building menu"}, } -- building filters -build_filter={ +build_filter={ forbid_all=false, --this forbits all except the "allow" allow={"MetalSmithsForge"}, --ignored if forbit_all=false forbid={} --ignored if forbit_all==true @@ -84,7 +84,7 @@ function deon_filter(name,type_id,subtype_id,custom_id, parent) else return not hasValue(race_filter.forbid,name) end - else + else if build_filter.forbid_all then return hasValue(build_filter.allow,name) else @@ -104,7 +104,7 @@ for k,v in ipairs({...}) do --setting parsing settings.df_assign=false else mode_name=v - + end end @@ -154,7 +154,7 @@ end function inSite() local tx,ty=advGlobalPos() --print(tx,ty) - + for k,v in pairs(df.global.world.world_data.sites) do local tp={v.pos.x,v.pos.y} if tx>=tp[1]*16+v.rgn_min_x and tx<=tp[1]*16+v.rgn_max_x and @@ -465,19 +465,19 @@ function chooseBuildingWidthHeightDir(args) --TODO nicer selection dialog if myneeds==nil then return end if args.width==nil and myneeds.w then --args.width=3 - dialog.showInputPrompt("Building size:", "Input building width:", nil, "1", + dialog.showInputPrompt("Building size:", "Input building width:", nil, "1", function(txt) args.width=tonumber(txt);BuildingChosen(args) end) return true end if args.height==nil and myneeds.h then --args.height=4 - dialog.showInputPrompt("Building size:", "Input building height:", nil, "1", + dialog.showInputPrompt("Building size:", "Input building height:", nil, "1", function(txt) args.height=tonumber(txt);BuildingChosen(args) end) return true end if args.direction==nil and myneeds.d then --args.direction=0--? - dialog.showInputPrompt("Building size:", "Input building direction:", nil, "0", + dialog.showInputPrompt("Building size:", "Input building direction:", nil, "0", function(txt) args.direction=tonumber(txt);BuildingChosen(args) end) return true end @@ -487,7 +487,7 @@ end CheckAndFinishBuilding=nil function BuildingChosen(inp_args,type_id,subtype_id,custom_id) local args=inp_args or {} - + args.type=type_id or args.type args.subtype=subtype_id or args.subtype args.custom=custom_id or args.custom_id @@ -497,9 +497,9 @@ function BuildingChosen(inp_args,type_id,subtype_id,custom_id) last_building.type=args.type last_building.subtype=args.subtype last_building.custom=args.custom - + if chooseBuildingWidthHeightDir(args) then - + return end --if settings.build_by_items then @@ -530,7 +530,7 @@ function isSuitableItem(job_item,item) --todo butcher test if job_item.item_type~=-1 then if item:getType()~= job_item.item_type then - + return false, "type" elseif job_item.item_subtype~=-1 then if item:getSubtype()~=job_item.item_subtype then @@ -538,7 +538,7 @@ function isSuitableItem(job_item,item) end end end - + if job_item.mat_type~=-1 then if item:getActualMaterial()~= job_item.mat_type then --unless we would want to make hist-fig specific reactions return false, "material" @@ -580,7 +580,7 @@ function isSuitableItem(job_item,item) print(v) end --]] - + return false,"matinfo" end -- some bonus checks: @@ -748,10 +748,10 @@ function AssignJobItems(args) local used_item_id={} for job_id, trg_job_item in ipairs(job.job_items) do item_suitability[job_id]={} - - for _,cur_item in pairs(its) do + + for _,cur_item in pairs(its) do if not used_item_id[cur_item.id] then - + local item_suitable,msg=isSuitableItem(trg_job_item,cur_item) if item_suitable or settings.build_by_items then table.insert(item_suitability[job_id],cur_item) @@ -787,7 +787,7 @@ function AssignJobItems(args) else print("Failed job, i'm confused...") end - + --end) return false,"Selecting items" else @@ -803,7 +803,7 @@ function AssignJobItems(args) return true end - + end @@ -815,7 +815,7 @@ CheckAndFinishBuilding=function (args,bld) break end end - + if args.job~=nil then args.pre_actions={AssignJobItems} else @@ -849,9 +849,9 @@ function BuildLast(args) return true end function CancelJob(unit) - local c_job=unit.job.current_job + local c_job=unit.job.current_job if c_job then - unit.job.current_job =nil --todo add real cancelation + unit.job.current_job =nil --todo add real cancelation for k,v in pairs(c_job.general_refs) do if df.general_ref_unit_workerst:is_instance(v) then v:delete() @@ -862,7 +862,7 @@ function CancelJob(unit) end end function ContinueJob(unit) - local c_job=unit.job.current_job + local c_job=unit.job.current_job --no job to continue if not c_job then return end --reset suspends... @@ -883,7 +883,7 @@ actions={ {"DetailWall" ,df.job_type.DetailWall,{IsWall,IsHardMaterial}}, {"DetailFloor" ,df.job_type.DetailFloor,{IsFloor,IsHardMaterial,SameSquare}}, {"CarveTrack" ,df.job_type.CarveTrack,{IsFloor,IsHardMaterial} - ,{SetCarveDir}}, + ,{SetCarveDir}}, {"Dig" ,df.job_type.Dig,{MakePredicateWieldsItem(df.job_skill.MINING),IsWall}}, {"CarveUpwardStaircase" ,df.job_type.CarveUpwardStaircase,{MakePredicateWieldsItem(df.job_skill.MINING),IsWall}}, {"CarveDownwardStaircase",df.job_type.CarveDownwardStaircase,{MakePredicateWieldsItem(df.job_skill.MINING)}}, @@ -894,7 +894,7 @@ actions={ {"Fish" ,df.job_type.Fish,{IsWater}}, --{"Diagnose Patient" ,df.job_type.DiagnosePatient,{IsUnit},{SetPatientRef}}, --{"Surgery" ,df.job_type.Surgery,{IsUnit},{SetPatientRef}}, - {"TameAnimal" ,df.job_type.TameAnimal,{IsUnit},{SetCreatureRef}}, + {"TameAnimal" ,df.job_type.TameAnimal,{IsUnit},{SetCreatureRef}}, {"GatherPlants" ,df.job_type.GatherPlants,{IsPlant,SameSquare}}, {"RemoveConstruction" ,df.job_type.RemoveConstruction,{IsConstruct}}, {"RemoveBuilding" ,RemoveBuilding,{IsBuilding}}, @@ -904,7 +904,7 @@ actions={ {"BuildLast" ,BuildLast,{NoConstructedBuilding}}, {"Clean" ,df.job_type.Clean,{}}, {"GatherWebs" ,df.job_type.CollectWebs,{--[[HasWeb]]},{SetWebRef}}, - + } for id,action in pairs(actions) do @@ -922,7 +922,7 @@ function usetool:getModeName() else return actions[(mode or 0)+1][1] or " " end - + end function usetool:init(args) @@ -933,7 +933,7 @@ function usetool:init(args) text={{key=keybinds.prevJob.key},{gap=1,text=self:callback("getModeName")},{gap=1,key=keybinds.nextJob.key}, } }, - + wid.Label{ view_id="shopLabel", @@ -942,7 +942,7 @@ function usetool:init(args) text={ {id="text1",gap=1,key=keybinds.workshop.key,key_sep="()", text="Workshop menu",pen=dfhack.pen.parse{fg=COLOR_YELLOW,bg=0}}} }, - + wid.Label{ view_id="siteLabel", frame = {t=1,xalign=-1,yalign=0}, @@ -1051,7 +1051,7 @@ function putItemToBuilding(building,item) end end function usetool:openPutWindow(building) - + local adv=df.global.world.units.active[0] local items=EnumItems{pos=adv.pos,unit=adv, inv={[df.unit_inventory_item.T_mode.Hauled]=true,--[df.unit_inventory_item.T_mode.Worn]=true, @@ -1106,7 +1106,7 @@ function usetool:openShopWindowButtoned(building,no_reset) --]] end building:fillSidebarMenu() - + local list={} for id,choice in pairs(wui.choices_visible) do table.insert(list,{text=utils.call_with_string(choice,"getLabel"),button=choice}) @@ -1122,7 +1122,7 @@ function usetool:openShopWindowButtoned(building,no_reset) end function usetool:openShopWindow(building) local adv=df.global.world.units.active[0] - + local filter_pile=workshopJobs.getJobs(building:getType(),building:getSubtype(),building:getCustomType()) if filter_pile then local state={unit=adv,from_pos={x=adv.pos.x,y=adv.pos.y, z=adv.pos.z},building=building @@ -1153,7 +1153,7 @@ function usetool:armCleanTrap(building) LoadStoneTrap, LoadWeaponTrap, ]] - if building.trap_type==df.trap_type.Lever then + if building.trap_type==df.trap_type.Lever then --link return end @@ -1190,7 +1190,7 @@ function usetool:hiveActions(building) --CollectHiveProducts, end function usetool:operatePump(building) - + local adv=df.global.world.units.active[0] makeJob{unit=adv,post_actions={AssignBuildingRef},pos=adv.pos,from_pos=adv.pos,job_type=df.job_type.OperatePump,screen=self} end @@ -1205,7 +1205,7 @@ function usetool:farmPlot(building) end end --check if there tile is without plantseeds,add job - + local args={unit=adv,pos=adv.pos,from_pos=adv.pos,screen=self} if do_harvest then args.job_type=df.job_type.HarvestPlants @@ -1294,7 +1294,7 @@ MODES={ input=usetool.chairActions, }, } -function usetool:shopMode(enable,mode,building) +function usetool:shopMode(enable,mode,building) self.subviews.shopLabel.visible=enable if mode then self.subviews.shopLabel:itemById("text1").text=mode.name @@ -1349,7 +1349,7 @@ function usetool:fieldInput(keys) break end end - + for _,p in pairs(cur_mode[3] or {}) do local ok,msg=p(state) if ok==false then @@ -1357,7 +1357,7 @@ function usetool:fieldInput(keys) failed=true end end - + if not failed then local ok,msg if type(cur_mode[2])=="function" then @@ -1365,9 +1365,9 @@ function usetool:fieldInput(keys) else makeJob(state) --(adv,moddedpos(adv.pos,MOVEMENT_KEYS[code]),cur_mode[2],adv.pos,cur_mode[4]) - + end - + if code=="SELECT" then self:sendInputToParent("LEAVESCREEN") end @@ -1381,11 +1381,11 @@ function usetool:fieldInput(keys) end end end - + end function usetool:onInput(keys) local adv=df.global.world.units.active[0] - + if keys.LEAVESCREEN then if df.global.cursor.x~=-30000 then self:sendInputToParent("LEAVESCREEN") @@ -1412,13 +1412,13 @@ function usetool:onInput(keys) if keys[keybinds.workshop.key] then self.mode.input(self,self.building) end - self:fieldInput(keys) + self:fieldInput(keys) else self:fieldInput(keys) end end local site=inSite() - + if site then self.subviews.siteLabel.visible=true self.subviews.siteLabel:itemById("site").text=dfhack.TranslateName(site.name) diff --git a/scripts/gui/advfort_items.lua b/scripts/gui/advfort_items.lua index e44e3857a..39a10367c 100644 --- a/scripts/gui/advfort_items.lua +++ b/scripts/gui/advfort_items.lua @@ -23,7 +23,7 @@ function update_slot_text(slot) items=items.."," end end - + slot.text=string.format("%02d. Filled(%d/%d):%s",slot.id+1,slot.filled_amount,slot.job_item.quantity,items) end --items-> table => key-> id of job.job_items, value-> table => key (num), value => item(ref) @@ -31,7 +31,7 @@ function jobitemEditor:init(args) --self.job=args.job if self.job==nil then qerror("This screen must have job target") end if self.items==nil then qerror("This screen must have item list") end - + self:addviews{ wid.Label{ view_id = 'label', diff --git a/scripts/gui/companion-order.lua b/scripts/gui/companion-order.lua index 68bc7ab39..bef1e0968 100644 --- a/scripts/gui/companion-order.lua +++ b/scripts/gui/companion-order.lua @@ -31,10 +31,10 @@ function CheckCursor(p) return true end function getxyz() -- this will return pointers x,y and z coordinates. - local x=df.global.cursor.x - local y=df.global.cursor.y - local z=df.global.cursor.z - return x,y,z -- return the coords + local x=df.global.cursor.x + local y=df.global.cursor.y + local z=df.global.cursor.z + return x,y,z -- return the coords end function GetCaste(race_id,caste_id) @@ -59,7 +59,7 @@ function ReadCurrentEquiped(body_equip,unit) local sb=v.item.subtype.props local trg=body_equip[bpid] local trg_layer=trg.layers[sb.layer] - + if trg_layer.permit==0 then trg_layer.permit=sb.layer_permit else @@ -94,7 +94,7 @@ function AddLayering(body_part,item) end function AddIfFits(body_equip,unit,item) --TODO shaped items - + local need_flag for k,v in pairs(permited_equips) do if k:is_instance(item) then @@ -106,7 +106,7 @@ function AddIfFits(body_equip,unit,item) return false end - + for k,bp in pairs(body_equip) do local handedness_ok=true if df.item_glovesst:is_instance(item) then @@ -153,7 +153,7 @@ end function GetBackpack(unit) for k,v in pairs(unit.inventory) do - + if df.item_backpackst:is_instance(v.item) then return v.item end @@ -223,7 +223,7 @@ end}, --todo make a table join function or sth... submit it to the lua list! AddBackpackItems(GetBackpack(unit),items) items=FilterByEquipable(items) - FilterBySize(items,unit.race) + FilterBySize(items,unit.race) local body_parts=EnumBodyEquipable(unit.race,unit.caste) ReadCurrentEquiped(body_parts,unit) for it_num,item in pairs(items) do @@ -239,7 +239,7 @@ end}, -- TODO sort with weapon/shield on top of list! --add to grasps, then add to backpack (sanely? i.e. weapons/shields into hands then stuff) --or add to backpack if have, only then check grasps (faster equiping) - while #grasps >0 and #items>0 do + while #grasps >0 and #items>0 do if(dfhack.items.moveToInventory(items[#items],v,1,grasps[#grasps])) then table.remove(grasps) end @@ -265,7 +265,7 @@ end}, return true end}, {name="unwield",f=function (unit_list) - + for k,v in pairs(unit_list) do local wep_count=0 for _,it in pairs(v.inventory) do @@ -279,7 +279,7 @@ end}, dfhack.items.moveToGround(it.item,v.pos) break end - end + end end end return true @@ -314,7 +314,7 @@ end}, local adv=df.global.world.units.active[0] local t_nem=dfhack.units.getNemesis(adv) for k,v in pairs(unit_list) do - + v.relations.group_leader_id=-1 local u_nem=dfhack.units.getNemesis(v) if u_nem then @@ -336,14 +336,14 @@ end}, local cheats={ {name="Patch up",f=function (unit_list) local dft=require("plugins.dfusion.tools") - for k,v in pairs(unit_list) do + for k,v in pairs(unit_list) do dft.healunit(v) - end - return true + end + return true end}, {name="Power up",f=function (unit_list) local dft=require("plugins.dfusion.tools") - for k,d in pairs(unit_list) do + for k,d in pairs(unit_list) do dft.powerup(d) end return true @@ -352,16 +352,16 @@ end}, if not CheckCursor(pos) then return false end - adv=df.global.world.units.active[0] - item=getItemsAtPos(getxyz())[1] - print(item.id) + adv=df.global.world.units.active[0] + item=getItemsAtPos(getxyz())[1] + print(item.id) for k,v in pairs(unit_list) do v.riding_item_id=item.id local ref=df.general_ref_unit_riderst:new() ref.unit_id=v.id item.general_refs:insert("#",ref) - end - return true + end + return true end}, } --[[ todo: add cheats...]]-- @@ -404,7 +404,7 @@ function CompanionUi:GetSelectedUnits() end function CompanionUi:onInput(keys) - + if keys.LEAVESCREEN then self:dismiss() elseif keys._STRING then @@ -412,13 +412,13 @@ function CompanionUi:onInput(keys) if s==string.byte('*') then local v=self.selected[1] or false for i=0,26 do - + self.selected[i]=not v end end if s>=string.byte('a') and s<=string.byte('z') then local idx=s-string.byte('a')+1 - if self.selected[idx] then + if self.selected[idx] then self.selected[idx]=false else self.selected[idx]=true diff --git a/scripts/gui/dfstatus.lua b/scripts/gui/dfstatus.lua index 0ebaa141d..f7dc4988c 100644 --- a/scripts/gui/dfstatus.lua +++ b/scripts/gui/dfstatus.lua @@ -30,19 +30,19 @@ function screen2:onRenderBody(dc) --local raw_fish = 0 --local plants = 0 local prepared_meals = 0 - + local fuel = 0 local pigiron = 0 local iron = 0 local steel = 0 - + local silver = 0 local copper = 0 local gold = 0 - + local tannedhides = 0 local cloth = 0 - + --print("------------------------------") for _,item in ipairs(df.global.world.items.all) do if(not item.flags.rotten and not item.flags.dump and not item.flags.forbid) then @@ -52,18 +52,18 @@ function screen2:onRenderBody(dc) if(item:getType() == df.item_type.DRINK)then --print(item:getType() .. ":" .. dfhack.items.getDescription(item,0)) end - + if (item:getType() == df.item_type.WOOD) then wood = wood + item:getStackSize() elseif (item:getType() == df.item_type.DRINK) then drink = drink + item:getStackSize() elseif (item:getType() == df.item_type.SKIN_TANNED) then tannedhides = tannedhides + item:getStackSize() elseif (item:getType() == df.item_type.CLOTH) then cloth = cloth + item:getStackSize() - --elseif (item:getType() == df.item_type.MEAT) then meat = meat + item:getStackSize() - --elseif (item:getType() == df.item_type.FISH_RAW) then raw_fish = raw_fish + item:getStackSize() - --elseif (item:getType() == df.item_type.PLANT) then plants = plants + item:getStackSize() - elseif (item:getType() == df.item_type.FOOD) then prepared_meals = prepared_meals + item:getStackSize() + --elseif (item:getType() == df.item_type.MEAT) then meat = meat + item:getStackSize() + --elseif (item:getType() == df.item_type.FISH_RAW) then raw_fish = raw_fish + item:getStackSize() + --elseif (item:getType() == df.item_type.PLANT) then plants = plants + item:getStackSize() + elseif (item:getType() == df.item_type.FOOD) then prepared_meals = prepared_meals + item:getStackSize() elseif (item:getType() == df.item_type.BAR) then for token in string.gmatch(dfhack.items.getDescription(item,0),"[^%s]+") do - if (token == "silver") then silver = silver + item:getStackSize() + if (token == "silver") then silver = silver + item:getStackSize() elseif (token == "charcoal" or token == "coke") then fuel = fuel + item:getStackSize() elseif (token == "iron") then iron = iron + item:getStackSize() elseif (token == "pig") then pigiron = pigiron + item:getStackSize() diff --git a/scripts/gui/gm-editor.lua b/scripts/gui/gm-editor.lua index 11fbdca99..4f7405121 100644 --- a/scripts/gui/gm-editor.lua +++ b/scripts/gui/gm-editor.lua @@ -46,7 +46,7 @@ GmEditorUi = defclass(GmEditorUi, gui.FramedScreen) GmEditorUi.ATTRS={ frame_style = gui.GREY_LINE_FRAME, frame_title = "GameMaster's editor", - } + } function GmEditorUi:onHelp() self.subviews.pages:setSelected(2) end @@ -76,7 +76,7 @@ function GmEditorUi:init(args) end table.insert(helptext,NEWLINE) Disclaimer(helptext) - + local helpPage=widgets.Panel{ subviews={widgets.Label{text=helptext,frame = {l=1,t=1,yalign=0}}}} local mainList=widgets.List{view_id="list_main",choices={},frame = {l=1,t=3,yalign=0},on_submit=self:callback("editSelected"), @@ -90,7 +90,7 @@ function GmEditorUi:init(args) --widgets.Label{text="BLAH2"} } ,view_id='page_main'} - + local pages=widgets.Pages{subviews={mainPage,helpPage},view_id="pages"} self:addviews{ pages @@ -104,20 +104,20 @@ function GmEditorUi:enable_input(enable) self.subviews.filter_input.active=enable end function GmEditorUi:find(test) - local trg=self:currentTarget() - + local trg=self:currentTarget() + if test== nil then dialog.showInputPrompt("Test function","Input function that tests(k,v as argument):",COLOR_WHITE,"",dfhack.curry(self.find,self)) return end - + local e,what=load("return function(k,v) return "..test.." end") if e==nil then dialog.showMessage("Error!","function failed to compile\n"..what,COLOR_RED) end - + if trg.target and trg.target._kind and trg.target._kind=="container" then - + for k,v in pairs(trg.target) do if e()(k,v)==true then self:pushTarget(v) @@ -146,13 +146,13 @@ function GmEditorUi:insertNew(typename) dialog.showMessage("Error!","Type '"..tp.." not found",COLOR_RED) return end - - local trg=self:currentTarget() + + local trg=self:currentTarget() if trg.target and trg.target._kind and trg.target._kind=="container" then local thing=ntype:new() dfhack.call_with_finalizer(1,false,df.delete,thing,function (tscreen,target,to_insert) target:insert("#",to_insert); tscreen:updateTarget(true,true);end,self,trg.target,thing) - + end end function GmEditorUi:deleteSelected(key) @@ -186,7 +186,7 @@ function GmEditorUi:editSelectedEnum(index,choice) self:updateTarget(true) end end) - + else qerror("not an enum") end @@ -211,7 +211,7 @@ function GmEditorUi:editSelected(index,choice) if trg_type=='number' or trg_type=='string' then --ugly TODO: add metatable get selected dialog.showInputPrompt(tostring(trg_key),"Enter new value:",COLOR_WHITE, tostring(trg.target[trg_key]),self:callback("commitEdit",trg_key)) - + elseif trg_type=='boolean' then trg.target[trg_key]= not trg.target[trg_key] self:updateTarget(true) @@ -235,8 +235,8 @@ function GmEditorUi:commitEdit(key,value) end function GmEditorUi:set(key,input) - local trg=self:currentTarget() - + local trg=self:currentTarget() + if input== nil then dialog.showInputPrompt("Set to what?","Lua code to set to (v cur target):",COLOR_WHITE,"",self:callback("set",key)) return @@ -281,7 +281,7 @@ function GmEditorUi:onInput(keys) self:insertNew() elseif keys[keybindings.delete.key] then --delete self:deleteSelected(self:getSelectedKey()) - elseif keys[keybindings.reinterpret.key] then + elseif keys[keybindings.reinterpret.key] then self:openReinterpret(self:getSelectedKey()) elseif keys[keybindings.start_filter.key] then self:enable_input(true) @@ -292,7 +292,7 @@ function GmEditorUi:onInput(keys) end function getStringValue(trg,field) local obj=trg.target - + local text=tostring(obj[field]) pcall(function() if obj._field ~= nil then @@ -326,7 +326,7 @@ function GmEditorUi:updateTarget(preserve_pos,reindex) self.subviews.lbl_current_item:itemById('name').text=tostring(trg.target) local t={} for k,v in pairs(trg.keys) do - table.insert(t,{text={{text=string.format("%-25s",tostring(v))},{gap=1,text=getStringValue(trg,v)}}}) + table.insert(t,{text={{text=string.format("%-25s",tostring(v))},{gap=1,text=getStringValue(trg,v)}}}) end local last_pos if preserve_pos then diff --git a/scripts/gui/hack-wish.lua b/scripts/gui/hack-wish.lua index 19e59bb52..e3c1f374c 100644 --- a/scripts/gui/hack-wish.lua +++ b/scripts/gui/hack-wish.lua @@ -3,7 +3,7 @@ -- author Putnam -- edited by expwnent - + function getGenderString(gender) local genderStr if gender==0 then @@ -15,7 +15,7 @@ function getGenderString(gender) end return string.char(40)..genderStr..string.char(41) end - + function getCreatureList() local crList={} for k,cr in ipairs(df.global.world.raws.creatures.alphabetic) do @@ -27,7 +27,7 @@ function getCreatureList() end return crList end - + function getMatFilter(itemtype) local itemTypes={ SEEDS=function(mat,parent,typ,idx) @@ -69,7 +69,7 @@ function getMatFilter(itemtype) } return itemTypes[df.item_type[itemtype]] or getRestrictiveMatFilter(itemtype) end - + function getRestrictiveMatFilter(itemType) if not args.restrictive then return nil end local itemTypes={ @@ -95,7 +95,7 @@ function getRestrictiveMatFilter(itemType) BAR=function(mat,parent,typ,idx) return (mat.flags.IS_METAL or mat.flags.SOAP or mat.id==COAL) end - + } for k,v in ipairs({'GOBLET','FLASK','TOY','RING','CROWN','SCEPTER','FIGURINE','TOOL'}) do itemTypes[v]=itemTypes.INSTRUMENT @@ -109,14 +109,14 @@ function getRestrictiveMatFilter(itemType) itemTypes.BOULDER=itemTypes.ROCK return itemTypes[df.item_type[itemType]] end - + function createItem(mat,itemType,quality,creator,description) - dfhack.items.createItem(itemType[1], itemType[2], mat[1], mat[2], creator) + dfhack.items.createItem(itemType[1], itemType[2], mat[1], mat[2], creator) if df.item_type[itemType[1]]=='SLAB' then item.description=description end end - + function qualityTable() return {{'None'}, {'-Well-crafted-'}, @@ -126,9 +126,9 @@ function qualityTable() {string.char(15)..'Masterwork'..string.char(15)} } end - + local script=require('gui.script') - + function showItemPrompt(text,item_filter,hide_none) require('gui.materials').ItemTypeDialog{ prompt=text, @@ -138,10 +138,10 @@ function showItemPrompt(text,item_filter,hide_none) on_cancel=script.mkresume(false), on_close=script.qresume(nil) }:show() - + return script.wait() end - + function showMaterialPrompt(title, prompt, filter, inorganic, creature, plant) --the one included with DFHack doesn't have a filter or the inorganic, creature, plant things available require('gui.materials').MaterialDialog{ frame_title = title, @@ -154,19 +154,19 @@ function showMaterialPrompt(title, prompt, filter, inorganic, creature, plant) - on_cancel = script.mkresume(false), on_close = script.qresume(nil) }:show() - + return script.wait() end - + function usesCreature(itemtype) typesThatUseCreatures={REMAINS=true,FISH=true,FISH_RAW=true,VERMIN=true,PET=true,EGG=true,CORPSE=true,CORPSEPIECE=true} return typesThatUseCreatures[df.item_type[itemtype]] end - + function getCreatureRaceAndCaste(caste) return df.global.world.raws.creatures.list_creature[caste.index],df.global.world.raws.creatures.list_caste[caste.index] end - + function hackWish(unit) script.start(function() local amountok, amount @@ -202,11 +202,11 @@ function hackWish(unit) else if mattype and itemtype then createItem({mattype,matindex},{itemtype,itemsubtype},quality,unit,description) - end + end end end) end - + scriptArgs={...} utils=require('utils') @@ -220,10 +220,10 @@ validArgs = validArgs or utils.invert({ }) args = utils.processArgs({...}, validArgs) - + eventful=require('plugins.eventful') -if not args.startup then +if not args.startup then local unit=args.unit and df.unit.find(args.unit) or dfhack.gui.getSelectedUnit(true) if unit then hackWish(unit) diff --git a/scripts/gui/mod-manager.lua b/scripts/gui/mod-manager.lua index a4f503868..2f2aa92ba 100644 --- a/scripts/gui/mod-manager.lua +++ b/scripts/gui/mod-manager.lua @@ -25,13 +25,13 @@ local mod_dir=dfhack.getDFPath().."/hack/mods" ]] function fileExists(filename) - local file=io.open(filename,"rb") - if file==nil then - return - else - file:close() - return true - end + local file=io.open(filename,"rb") + if file==nil then + return + else + file:close() + return true + end end if not fileExists(init_file) then local initFile=io.open(init_file,"a") @@ -47,10 +47,10 @@ function copyFile(from,to) --oh so primitive fileto:close() end function patchInit(initFileName,patch_guard,code) - local initFile=io.open(initFileName,"a") - initFile:write(string.format("\n%s\n%s\n%s",patch_guard[1], - code,patch_guard[2])) - initFile:close() + local initFile=io.open(initFileName,"a") + initFile:write(string.format("\n%s\n%s\n%s",patch_guard[1], + code,patch_guard[2])) + initFile:close() end function patchDofile( luaFileName,patch_guard,dofile_list,mod_path ) local luaFile=io.open(luaFileName,"a") @@ -64,10 +64,10 @@ function patchDofile( luaFileName,patch_guard,dofile_list,mod_path ) end function patchFile(file_name,patch_guard,after_string,code) local input_lines=patch_guard[1].."\n"..code.."\n"..patch_guard[2] - + local badchars="[%:%[%]]" local find_string=after_string:gsub(badchars,"%%%1") --escape some bad chars - + local entityFile=io.open(file_name,"r") local buf=entityFile:read("*all") entityFile:close() @@ -77,98 +77,98 @@ function patchFile(file_name,patch_guard,after_string,code) entityFile:close() end function findGuards(str,start,patch_guard) - local pStart=string.find(str,patch_guard[1],start) - if pStart==nil then return nil end - local pEnd=string.find(str,patch_guard[2],pStart) - if pEnd==nil then error("Start guard token found, but end was not found") end - return pStart-1,pEnd+#patch_guard[2]+1 + local pStart=string.find(str,patch_guard[1],start) + if pStart==nil then return nil end + local pEnd=string.find(str,patch_guard[2],pStart) + if pEnd==nil then error("Start guard token found, but end was not found") end + return pStart-1,pEnd+#patch_guard[2]+1 end function findGuardsFile(filename,patch_guard) - local file=io.open(filename,"r") - local buf=file:read("*all") - return findGuards(buf,1,patch_guard) + local file=io.open(filename,"r") + local buf=file:read("*all") + return findGuards(buf,1,patch_guard) end function unPatchFile(filename,patch_guard) - local file=io.open(filename,"r") - local buf=file:read("*all") - file:close() - - local newBuf="" - local pos=1 - local lastPos=1 - repeat - local endPos - pos,endPos=findGuards(buf,lastPos,patch_guard) - newBuf=newBuf..string.sub(buf,lastPos,pos) - if endPos~=nil then - lastPos=endPos - end - until pos==nil - - local file=io.open(filename,"w+") - file:write(newBuf) + local file=io.open(filename,"r") + local buf=file:read("*all") + file:close() + + local newBuf="" + local pos=1 + local lastPos=1 + repeat + local endPos + pos,endPos=findGuards(buf,lastPos,patch_guard) + newBuf=newBuf..string.sub(buf,lastPos,pos) + if endPos~=nil then + lastPos=endPos + end + until pos==nil + + local file=io.open(filename,"w+") + file:write(newBuf) file:close() end function checkInstalled(dfMod) --try to figure out if installed - if dfMod.checkInstalled then - return dfMod.checkInstalled() - else - if dfMod.raws_list then - for k,v in pairs(dfMod.raws_list) do - if fileExists(dfhack.getDFPath().."/raw/objects/"..v) then - return true,v - end - end - end - if dfMod.patch_entity then - if findGuardsFile(entity_file,dfMod.guard)~=nil then - return true,"entity_default.txt" - end - end + if dfMod.checkInstalled then + return dfMod.checkInstalled() + else + if dfMod.raws_list then + for k,v in pairs(dfMod.raws_list) do + if fileExists(dfhack.getDFPath().."/raw/objects/"..v) then + return true,v + end + end + end + if dfMod.patch_entity then + if findGuardsFile(entity_file,dfMod.guard)~=nil then + return true,"entity_default.txt" + end + end if dfMod.patch_files then for k,v in pairs(dfMod.patch_files) do if findGuardsFile(dfhack.getDFPath().."/raw/objects/"..v.filename,dfMod.guard)~=nil then return true,"v.filename" end end - end - if dfMod.patch_init then - if findGuardsFile(init_file,dfMod.guard_init)~=nil then - return true,"init.lua" - end - end - end + end + if dfMod.patch_init then + if findGuardsFile(init_file,dfMod.guard_init)~=nil then + return true,"init.lua" + end + end + end end manager=defclass(manager,gui.FramedScreen) function manager:init(args) self.mods={} local mods=self.mods - local mlist=dfhack.internal.getDir(mod_dir) + local mlist=dfhack.internal.getDir(mod_dir) if #mlist==0 then qerror("Mod directory not found! Are you sure it is in:"..mod_dir) end - for k,v in ipairs(mlist) do - if v~="." and v~=".." then - local f,modData=pcall(dofile,mod_dir.."/".. v .. "/init.lua") + for k,v in ipairs(mlist) do + if v~="." and v~=".." then + local f,modData=pcall(dofile,mod_dir.."/".. v .. "/init.lua") if f then mods[modData.name]=modData modData.guard=modData.guard or {">>"..modData.name.." patch","< 10 then hitCeiling = true end - if stairs == 1 and x == pos.x and y == pos.y then + if stairs == 1 and x == pos.x and y == pos.y then if block.tiletype[x%16][y%16] == 32 then - if z == pos.z then + if z == pos.z then block.tiletype[x%16][y%16] = 56 - else - block.tiletype[x%16][y%16] = 55 + else + block.tiletype[x%16][y%16] = 55 end - else - block.tiletype[x%16][y%16] = 57 + else + block.tiletype[x%16][y%16] = 57 end end end @@ -68,7 +68,7 @@ for x=pos.x-size,pos.x+size,1 do elseif x == pos.x+size and y == pos.y-size then if needsWall == true then block.tiletype[x%16][y%16]=323 end elseif x == pos.x-size or x == pos.x+size then if needsWall == true then block.tiletype[x%16][y%16]=324 end elseif y == pos.y-size or y == pos.y+size then if needsWall == true then block.tiletype[x%16][y%16]=325 end - elseif stairs == 1 and x == pos.x and y == pos.y then + elseif stairs == 1 and x == pos.x and y == pos.y then if z == pos.z then block.tiletype[x%16][y%16]=56 else block.tiletype[x%16][y%16]=55 end else block.tiletype[x%16][y%16]=32 diff --git a/scripts/lever.rb b/scripts/lever.rb index 4e2d399e5..18e4484cd 100644 --- a/scripts/lever.rb +++ b/scripts/lever.rb @@ -1,124 +1,124 @@ -# control your levers from the dfhack console - -def lever_pull_job(bld) - ref = DFHack::GeneralRefBuildingHolderst.cpp_new - ref.building_id = bld.id - - job = DFHack::Job.cpp_new - job.job_type = :PullLever - job.pos = [bld.centerx, bld.centery, bld.z] - job.general_refs << ref - bld.jobs << job - df.job_link job - - puts lever_descr(bld) -end - -def lever_pull_cheat(bld) - bld.linked_mechanisms.each { |i| - i.general_refs.grep(DFHack::GeneralRefBuildingHolderst).each { |r| - r.building_tg.setTriggerState(bld.state) - } - } - - bld.state = (bld.state == 0 ? 1 : 0) - - puts lever_descr(bld) -end - -def lever_descr(bld, idx=nil) - ret = [] - - # lever description - descr = '' - descr << "#{idx}: " if idx - descr << "lever ##{bld.id} @[#{bld.centerx}, #{bld.centery}, #{bld.z}] #{bld.state == 0 ? '\\' : '/'}" - bld.jobs.each { |j| - if j.job_type == :PullLever - flags = '' - flags << ', repeat' if j.flags.repeat - flags << ', suspended' if j.flags.suspend - descr << " (pull order#{flags})" - end - } - - bld.linked_mechanisms.map { |i| - i.general_refs.grep(DFHack::GeneralRefBuildingHolderst) - }.flatten.each { |r| - # linked building description - tg = r.building_tg - state = '' - if tg.respond_to?(:gate_flags) - state << (tg.gate_flags.closed ? 'closed' : 'opened') - state << ", closing (#{tg.timer})" if tg.gate_flags.closing - state << ", opening (#{tg.timer})" if tg.gate_flags.opening - end - - ret << (descr + " linked to #{tg._rtti_classname} ##{tg.id} @[#{tg.centerx}, #{tg.centery}, #{tg.z}] #{state}") - - # indent other links - descr = descr.gsub(/./, ' ') - } - - ret << descr if ret.empty? - - ret -end - -def lever_list - @lever_list = [] - df.world.buildings.other[:TRAP].find_all { |bld| - bld.trap_type == :Lever - }.sort_by { |bld| bld.id }.each { |bld| - puts lever_descr(bld, @lever_list.length) - @lever_list << bld.id - } -end - - -@lever_list ||= [] - -case $script_args[0] -when 'pull' - cheat = $script_args.delete('--cheat') || $script_args.delete('--now') - - id = $script_args[1].to_i - id = @lever_list[id] || id - bld = df.building_find(id) - raise 'invalid lever id' if not bld - - if cheat - lever_pull_cheat(bld) - else - lever_pull_job(bld) - end - -when 'list' - lever_list - -when /^\d+$/ - id = $script_args[0].to_i - id = @lever_list[id] || id - bld = df.building_find(id) - raise 'invalid lever id' if not bld - - puts lever_descr(bld) - -else - - puts < 0 and bx+dx < df.world.map.x_count-1 and by+dy > 0 and by+dy < df.world.map.y_count-1 - pos = [bx+dx, by+dy, bz] - end - } - } - } - } - df.center_viewscreen(*pos) - df.map_tile_at(*pos).dig - puts "Here is some #{df.world.raws.inorganics[found_mat].id}" - else - puts "Cannot find unmined #{mats.map { |mat| df.world.raws.inorganics[mat].id }.join(', ')}" - end - -else - puts "Available ores:", $ore_veins.sort_by { |mat, pos| pos.length }.map { |mat, pos| - ore = df.world.raws.inorganics[mat] - metals = ore.metal_ore.mat_index.map { |m| df.world.raws.inorganics[m] } - ' ' + ore.id.downcase + ' (' + metals.map { |m| m.id.downcase }.join(', ') + ')' - } - -end +# scan the map for ore veins + +target_ore = $script_args[0] + +def find_all_ore_veins + puts 'scanning map...' + $ore_veins = {} + seen_mat = {} + df.each_map_block { |block| + block.block_events.grep(DFHack::BlockSquareEventMineralst).each { |vein| + mat_index = vein.inorganic_mat + if not seen_mat[mat_index] or $ore_veins[mat_index] + seen_mat[mat_index] = true + if df.world.raws.inorganics[mat_index].flags[:METAL_ORE] + $ore_veins[mat_index] ||= [] + $ore_veins[mat_index] << [block.map_pos.x, block.map_pos.y, block.map_pos.z] + end + end + } + } + + df.onstatechange_register_once { |st| + if st == :MAP_LOADED + $ore_veins = nil # invalidate veins cache + true + end + } + + $ore_veins +end + +$ore_veins ||= find_all_ore_veins + +if not target_ore or target_ore == 'help' + puts < 0 and bx+dx < df.world.map.x_count-1 and by+dy > 0 and by+dy < df.world.map.y_count-1 + pos = [bx+dx, by+dy, bz] + end + } + } + } + } + df.center_viewscreen(*pos) + df.map_tile_at(*pos).dig + puts "Here is some #{df.world.raws.inorganics[found_mat].id}" + else + puts "Cannot find unmined #{mats.map { |mat| df.world.raws.inorganics[mat].id }.join(', ')}" + end + +else + puts "Available ores:", $ore_veins.sort_by { |mat, pos| pos.length }.map { |mat, pos| + ore = df.world.raws.inorganics[mat] + metals = ore.metal_ore.mat_index.map { |m| df.world.raws.inorganics[m] } + ' ' + ore.id.downcase + ' (' + metals.map { |m| m.id.downcase }.join(', ') + ')' + } + +end diff --git a/scripts/log-region.lua b/scripts/log-region.lua index 2da2da773..31cdaf782 100644 --- a/scripts/log-region.lua +++ b/scripts/log-region.lua @@ -29,7 +29,7 @@ else --site.name --fort_ent.name --civ_ent.name - + write_gamelog('Loaded '..world.cur_savegame.save_dir..', '..fullname(world.world_data).. ' at coordinates ('..site.pos.x..','..site.pos.y..')'..NEWLINE.. 'Loaded the fortress '..fullname(site).. diff --git a/scripts/make-monarch.lua b/scripts/make-monarch.lua index 253179680..967225589 100644 --- a/scripts/make-monarch.lua +++ b/scripts/make-monarch.lua @@ -17,7 +17,7 @@ for pos_id,v in pairs(my_entity.positions.assignments) do old_id=v.histfig v.histfig=newfig.id local oldfig=df.historical_figure.find(old_id) - + for k,v in pairs(oldfig.entity_links) do if df.histfig_entity_link_positionst:is_instance(v) and v.assignment_id==pos_id and v.entity_id==df.global.ui.civ_id then oldfig.entity_links:erase(k) diff --git a/scripts/markdown.lua b/scripts/markdown.lua index 957f18c10..7fb1dbee9 100644 --- a/scripts/markdown.lua +++ b/scripts/markdown.lua @@ -4,54 +4,54 @@ local args = {...} -if args[1] == 'help' then +if args[1] == 'help' then print([[ description: - This script will attempt to read the current df-screen, and if it is a + This script will attempt to read the current df-screen, and if it is a text-viewscreen (such as the dwarf 'thoughts' screen or an item / creature - 'description') or an announcement list screen (such as announcements and - combat reports) then append a marked-down version of this text to the + 'description') or an announcement list screen (such as announcements and + combat reports) then append a marked-down version of this text to the target file (for easy pasting on reddit for example). - Previous entries in the file are not overwritten, so you - may use the 'markdown' command multiple times to create a single - document containing the text from multiple screens (eg: text screens - from several dwarves, or text screens from multiple artifacts/items, - or some combination). - + Previous entries in the file are not overwritten, so you + may use the 'markdown' command multiple times to create a single + document containing the text from multiple screens (eg: text screens + from several dwarves, or text screens from multiple artifacts/items, + or some combination). + usage: markdown [/n] [filename] - + /n - overwrites contents of output file filename - if provided, the data will be saved in md_filename.md instead - of default md_export.md - + of default md_export.md + known screens: - The screens which have been tested and known to function properly with + The screens which have been tested and known to function properly with this script are: 1: dwarf/unit 'thoughts' screen 2: item/art 'description' screen 3: individual 'historical item/figure' screens - 4: manual + 4: manual 4: announements screen 5: combat reports screen 6: latest news (when meeting with liaison) - There may be other screens to which the script applies. It should be - safe to attempt running the script with any screen active, with an + There may be other screens to which the script applies. It should be + safe to attempt running the script with any screen active, with an error message to inform you when the selected screen is not appropriate for this script. - + target file: The default target file's name is 'md_export.md'. A remider to this effect - will be displayed if the script is successful. - + will be displayed if the script is successful. + character encoding: - The text will likely be using system-default encoding, and as such - will likely NOT display special characters (eg:,,) correctly. To - fix this, you need to modify the character set that you are reading - the document with. 'Notepad++' is a freely available program which + The text will likely be using system-default encoding, and as such + will likely NOT display special characters (eg:,,) correctly. To + fix this, you need to modify the character set that you are reading + the document with. 'Notepad++' is a freely available program which can do this using the following steps: 1: open the document in Notepad++ - 2: in the menu-bar, select + 2: in the menu-bar, select Encoding->Character Sets->Western European->OEM-US 3: copy the text normally to wherever you want to use it ]]) @@ -60,7 +60,7 @@ end local writemode = 'a' --- check if we want to append to an existing file (default) or overwrite previous contents +-- check if we want to append to an existing file (default) or overwrite previous contents if args[1] == '/n' then writemode = 'w' table.remove(args, 1) @@ -70,7 +70,7 @@ local filename if args[1] ~= nil then filename = 'md_' .. table.remove(args, 1) .. '.md' -else +else filename = 'md_export.md' end @@ -103,7 +103,7 @@ local function getFileHandle() return io.open(filename, writemode) end -local function closeFileHandle(handle) +local function closeFileHandle(handle) handle:write('\n***\n\n') handle:close() print ('Data exported to "' .. filename .. '"') @@ -111,35 +111,35 @@ end local function reformat(strin) local strout = strin - + -- [P] tags seem to indicate a new paragraph local newline_idx = string.find(strout, '[P]', 1, true) while newline_idx ~= nil do strout = string.sub(strout, 1, newline_idx - 1) .. '\n***\n\n' .. string.sub(strout, newline_idx + 3) newline_idx = string.find(strout, '[P]', 1, true) end - + -- [R] tags seem to indicate a new 'section'. Let's mark it with a horizontal line. newline_idx = string.find(strout, '[R]', 1, true) while newline_idx ~= nil do strout = string.sub(strout, 1, newline_idx - 1) .. '\n***\n\n' .. string.sub(strout,newline_idx + 3) newline_idx = string.find(strout, '[R]', 1, true) end - + -- No idea what [B] tags might indicate. Just removing them seems to work fine newline_idx = string.find(strout, '[B]', 1, true) while newline_idx ~= nil do strout = string.sub(strout, 1, newline_idx - 1) .. string.sub(strout,newline_idx + 3) newline_idx = string.find(strout, '[B]', 1, true) end - + -- Reddit doesn't support custom colors in markdown. We need to remove all color information :( local color_idx = string.find(strout, '[C:', 1, true) - while color_idx ~= nil do + while color_idx ~= nil do strout = string.sub(strout, 1, color_idx - 1) .. string.sub(strout, color_idx + 9) color_idx = string.find(strout, '[C:', 1, true) end - + return strout end @@ -147,18 +147,18 @@ local function formattime(year, ticks) -- Dwarf Mode month is 33600 ticks long local month = math.floor(ticks / 33600) local dayRemainder = ticks - month * 33600 - + -- Dwarf Mode day is 1200 ticks long local day = math.floor(dayRemainder / 1200) local timeRemainder = dayRemainder - day * 1200 - + -- Assuming a 24h day each Dwarf Mode tick corresponds to 72 seconds local seconds = timeRemainder * 72 - + local H = string.format("%02.f", math.floor(seconds / 3600)); local m = string.format("%02.f", math.floor(seconds / 60 - (H * 60))); local i = string.format("%02.f", math.floor(seconds - H * 3600 - m * 60)); - + day = day + 1 if (day == 1 or day == 21) then day = day .. 'st' @@ -167,37 +167,37 @@ local function formattime(year, ticks) else day = day .. 'th' end - + return (day .. " " .. months[month + 1] .. " " .. year .. " " .. H .. ":" .. m..":" .. i) end if flerb == 'textviewer' then - + local lines = scrn.src_text - + if lines ~= nil then - + local log = getFileHandle() log:write('### ' .. scrn.title .. '\n') print('Exporting ' .. scrn.title .. '\n') - + for n,x in ipairs(lines) do log:write(reformat(x.value).." ") --- debug output --- print(x.value) +-- debug output +-- print(x.value) end closeFileHandle(log) - end - + end + elseif flerb == 'announcelist' then local lines = scrn.reports - + if lines ~= nil then local log = getFileHandle() local lastTime = "" - + for n,x in ipairs(lines) do local currentTime = formattime(x.year, x.time) if (currentTime ~= lastTime) then @@ -205,22 +205,22 @@ elseif flerb == 'announcelist' then log:write('\n***\n\n') log:write('## ' .. currentTime .. '\n') end --- debug output +-- debug output -- print(x.text) log:write(x.text .. '\n') end closeFileHandle(log) end - - + + elseif flerb == 'topicmeeting' then local lines = scrn.text - + if lines ~= nil then local log = getFileHandle() - - for n,x in ipairs(lines) do --- debug output + + for n,x in ipairs(lines) do +-- debug output -- print(x.value) log:write(x.value .. '\n') end diff --git a/scripts/masspit.rb b/scripts/masspit.rb index b38f69d42..e391509fb 100644 --- a/scripts/masspit.rb +++ b/scripts/masspit.rb @@ -1,40 +1,40 @@ -# pit all caged creatures in a zone - -case $script_args[0] -when '?', 'help' - puts <= df.cursor.x and zone.y1 <= df.cursor.y and zone.y2 >= df.cursor.y - } - -end - -if not bld - puts "Please select a pit/pond zone" - throw :script_finished -end - -found = 0 -df.world.items.other[:CAGE].each { |cg| - next if not cg.flags.on_ground - next if cg.pos.z != bld.z or cg.pos.x < bld.x1 or cg.pos.x > bld.x2 or cg.pos.y < bld.y1 or cg.pos.y > bld.y2 - next if not uref = cg.general_refs.grep(DFHack::GeneralRefContainsUnitst).first - found += 1 - u = uref.unit_tg - puts "Pitting #{u.race_tg.name[0]} #{u.id} #{u.name}" - u.general_refs << DFHack::GeneralRefBuildingCivzoneAssignedst.cpp_new(:building_id => bld.id) - bld.assigned_units << u.id -} -puts "No creature available for pitting" if found == 0 +# pit all caged creatures in a zone + +case $script_args[0] +when '?', 'help' + puts <= df.cursor.x and zone.y1 <= df.cursor.y and zone.y2 >= df.cursor.y + } + +end + +if not bld + puts "Please select a pit/pond zone" + throw :script_finished +end + +found = 0 +df.world.items.other[:CAGE].each { |cg| + next if not cg.flags.on_ground + next if cg.pos.z != bld.z or cg.pos.x < bld.x1 or cg.pos.x > bld.x2 or cg.pos.y < bld.y1 or cg.pos.y > bld.y2 + next if not uref = cg.general_refs.grep(DFHack::GeneralRefContainsUnitst).first + found += 1 + u = uref.unit_tg + puts "Pitting #{u.race_tg.name[0]} #{u.id} #{u.name}" + u.general_refs << DFHack::GeneralRefBuildingCivzoneAssignedst.cpp_new(:building_id => bld.id) + bld.assigned_units << u.id +} +puts "No creature available for pitting" if found == 0 diff --git a/scripts/modtools/force.lua b/scripts/modtools/force.lua index 615b6b969..2930d2930 100644 --- a/scripts/modtools/force.lua +++ b/scripts/modtools/force.lua @@ -8,7 +8,7 @@ local utils = require 'utils' local function findCiv(arg) local entities = df.global.world.entities.all if tonumber(arg) then return arg end - if arg then + if arg then for eid,entity in ipairs(entities) do if entity.entity_raw.code == arg then return entity end end diff --git a/scripts/modtools/interaction-trigger.lua b/scripts/modtools/interaction-trigger.lua index 94e476b8f..10eca5d4e 100644 --- a/scripts/modtools/interaction-trigger.lua +++ b/scripts/modtools/interaction-trigger.lua @@ -69,7 +69,7 @@ eventful.onInteraction.interactionTrigger = function(attackVerb, defendVerb, att processTrigger(command) utils.unfillTable(command,extras) end - + local eraseReport = function(unit,report) for i,v in ipairs(unit.reports.log.Combat) do if v == report then diff --git a/scripts/modtools/item-trigger.lua b/scripts/modtools/item-trigger.lua index 4ad30315c..c7f9c6d18 100644 --- a/scripts/modtools/item-trigger.lua +++ b/scripts/modtools/item-trigger.lua @@ -62,7 +62,7 @@ function handler(table) local itemType = dfhack.items.getSubtypeDef(table.item:getType(),table.item:getSubtype()).id table.itemMat = itemMat table.itemType = itemType - + for _,command in ipairs(itemTriggers[itemType] or {}) do if command[table.mode] then utils.fillTable(command,table) @@ -78,7 +78,7 @@ function handler(table) utils.unfillTable(command,table) end end - + for _,contaminant in ipairs(table.item.contaminants or {}) do local contaminantMat = dfhack.matinfo.decode(contaminant.mat_type, contaminant.mat_index) local contaminantStr = contaminantMat:getToken() @@ -106,7 +106,7 @@ eventful.onInventoryChange.equipmentTrigger = function(unit, item, item_old, ite if item_old and item_new then return end - + local isEquip = item_new and not item_old equipHandler(unit,item,isEquip) end @@ -114,11 +114,11 @@ end eventful.onUnitAttack.attackTrigger = function(attacker,defender,wound) attacker = df.unit.find(attacker) defender = df.unit.find(defender) - + if not attacker then return end - + local attackerWeapon for _,item in ipairs(attacker.inventory) do if item.mode == df.unit_inventory_item.T_mode.Weapon then @@ -126,7 +126,7 @@ eventful.onUnitAttack.attackTrigger = function(attacker,defender,wound) break end end - + if not attackerWeapon then return end @@ -161,7 +161,7 @@ arguments: print this help message -clear clear all registered triggers - -checkAttackEvery n + -checkAttackEvery n check the attack event at least every n ticks -checkInventoryEvery n check inventory event at least every n ticks diff --git a/scripts/modtools/random-trigger.lua b/scripts/modtools/random-trigger.lua index 50d32b930..4ad6813c1 100644 --- a/scripts/modtools/random-trigger.lua +++ b/scripts/modtools/random-trigger.lua @@ -58,7 +58,7 @@ If you want multiple independent random events, call the script multiple times. 99% of the time, you won't need to worry about this, but just in case, you can specify a name of a list of outcomes to prevent interference from other scripts that call this one. That also permits situations where you don't know until runtime what outcomes you want. For example, you could make a reaction-trigger that registers the worker as a mayor candidate, then run this script to choose a random mayor from the list of units that did the mayor reaction. - + arguments: -help print this help message diff --git a/scripts/modtools/reaction-trigger.lua b/scripts/modtools/reaction-trigger.lua index 2e428c1d4..9d14ae608 100644 --- a/scripts/modtools/reaction-trigger.lua +++ b/scripts/modtools/reaction-trigger.lua @@ -76,12 +76,12 @@ eventful.onJobCompleted.reactionTrigger = function(job) if job.completion_timer > 0 then return end - + -- if job.job_type ~= df.job_type.CustomReaction then -- --TODO: support builtin reaction triggers if someone asks -- return -- end - + if not job.reaction_name or job.reaction_name == '' then return end @@ -89,7 +89,7 @@ eventful.onJobCompleted.reactionTrigger = function(job) if not job.reaction_name or not reactionHooks[job.reaction_name] then return end - + local worker,building = getWorkerAndBuilding(job) worker = df.unit.find(worker) building = df.building.find(building) @@ -98,7 +98,7 @@ eventful.onJobCompleted.reactionTrigger = function(job) --TODO: consider printing a warning once return end - + local function doAction(action) local didSomething if action.command then diff --git a/scripts/multicmd.rb b/scripts/multicmd.rb index d92e25cde..593b0fa72 100644 --- a/scripts/multicmd.rb +++ b/scripts/multicmd.rb @@ -1,4 +1,4 @@ -# run many dfhack commands separated by ; -# ex: multicmd locate-ore IRON ; digv ; digcircle 16 - -$script_args.join(' ').split(/\s*;\s*/).each { |cmd| df.dfhack_run cmd } +# run many dfhack commands separated by ; +# ex: multicmd locate-ore IRON ; digv ; digcircle 16 + +$script_args.join(' ').split(/\s*;\s*/).each { |cmd| df.dfhack_run cmd } diff --git a/scripts/position.lua b/scripts/position.lua index 8c3dbe72a..ea824e15f 100644 --- a/scripts/position.lua +++ b/scripts/position.lua @@ -1,7 +1,7 @@ --prints current time and position local months = { - 'Granite, in early Spring.', + 'Granite, in early Spring.', 'Slate, in mid Spring.', 'Felsite, in late Spring.', 'Hematite, in early Summer.', @@ -38,6 +38,6 @@ print('Place:') print(' The z-level is z='..df.global.window_z) print(' The cursor is at x='..df.global.cursor.x..', y='..df.global.cursor.y) print(' The window is '..df.global.gps.dimx..' tiles wide and '..df.global.gps.dimy..' tiles high') -if df.global.gps.mouse_x == -1 then print(' The mouse is not in the DF window') else +if df.global.gps.mouse_x == -1 then print(' The mouse is not in the DF window') else print(' The mouse is at x='..df.global.gps.mouse_x..', y='..df.global.gps.mouse_y..' within the window') end --TODO: print(' The fortress is at '..x, y..' on the world map ('..worldsize..' square)') diff --git a/scripts/show-unit-syndromes.rb b/scripts/show-unit-syndromes.rb index 54860b48c..f79a79e83 100644 --- a/scripts/show-unit-syndromes.rb +++ b/scripts/show-unit-syndromes.rb @@ -179,7 +179,7 @@ def get_effect_target(target) if(target.mode[i].to_s() != "") items = "" - + #case target.mode[i].to_s() #when "BY_TYPE" # item = "type(" @@ -188,12 +188,12 @@ def get_effect_target(target) #when "BY_CATEGORY" # item = "category(" #end - + if(target.key[i].to_s()!="") item = "#{item}#{target.key[i].to_s().capitalize()}" end - if target.tissue[i].to_s() != "ALL" + if target.tissue[i].to_s() != "ALL" if(target.key[i].to_s()!="" and target.tissue[i].to_s()!="") item = "#{item}:" end @@ -211,7 +211,7 @@ def get_effect_target(target) end if values.length == 0 or (values.length == 1 and values[0] == "All") - return "" + return "" else return ", target=" + values.join(", ") end @@ -272,7 +272,7 @@ def get_display_name(name, verb) if verb.length > 100 verb = verb.slice(0, 100).capitalize() end - + pos = verb.index(".") if pos == nil return verb.slice(0, verb.rindex(" ")).capitalize() @@ -563,28 +563,28 @@ def find_creature_name(id, casteid) end creature_name = creature.name[0].capitalize() - + if casteid == "DEFAULT" return creature_name, "" end - + caste = creature.caste.find{ |c| c.caste_id == casteid } - + if caste == nil return creature_name, casteid elsif creature.name[0].downcase() == caste.caste_name[0].downcase() return creature_name, "" else castename = caste.caste_name[0].downcase().chomp(creature.name[0].downcase()).strip() - + if castename.start_with?(creature.name[0]) castename = castename.slice(creature.name[0].length, castename.length - creature.name[0].length).strip() end if castename.start_with?("of the") castename = castename.slice("of the".length, castename.length - "of the".length).strip() - end - + end + return creature_name, castename.downcase() end end @@ -765,13 +765,13 @@ def get_effect(logger, ce, ticks, showdisplayeffects) end creature_name = find_creature_name(ce.race_str, ce.caste_str) - + if creature_name[1] == "" - desc = "#{creature_name[0]}#{chance}" + desc = "#{creature_name[0]}#{chance}" else - desc = "#{creature_name[0]}(#{creature_name[1]})#{chance}" + desc = "#{creature_name[0]}(#{creature_name[1]})#{chance}" end - + color = Output::BLUE when "PHYS_ATT_CHANGE" name = "Physical" @@ -793,7 +793,7 @@ def get_effect(logger, ce, ticks, showdisplayeffects) else color = Output::DEFAULT end - + if ce.mat_index >=0 mat = df.decode_mat(ce.mat_type, ce.mat_index ) elsif ce.mat_type >= 0 @@ -801,16 +801,16 @@ def get_effect(logger, ce, ticks, showdisplayeffects) else mat = nil end - + if mat!= nil token = mat.token if token.start_with?("INORGANIC:") token = token.slice("INORGANIC:".length, token.length - "INORGANIC:".length) end - + desc = "#{desc} vs #{token.capitalize()}" - end - + end + when "BODY_MAT_INTERACTION" # interactionId, SundromeTriggerType name = "Body material interaction" diff --git a/scripts/source.rb b/scripts/source.rb index 204afc70c..176cfbf2b 100644 --- a/scripts/source.rb +++ b/scripts/source.rb @@ -1,83 +1,83 @@ -# create an infinite magma/water source/drain at the cursor - -$sources ||= [] - -cur_source = { - :liquid => 'water', - :amount => 7, - :pos => [df.cursor.x, df.cursor.y, df.cursor.z] -} -cmd = 'help' - -$script_args.each { |a| - case a.downcase - when 'water', 'magma' - cur_source[:liquid] = a.downcase - when /^\d+$/ - cur_source[:amount] = a.to_i - when 'add', 'del', 'delete', 'clear', 'help', 'list' - cmd = a.downcase - else - puts "source: unhandled argument #{a}" - end -} - -case cmd -when 'add' - $sources_onupdate ||= df.onupdate_register('sources', 12) { - # called every 12 game ticks (100x a dwarf day) - $sources.each { |s| - if tile = df.map_tile_at(*s[:pos]) and tile.shape_passableflow - # XXX does not check current liquid_type - des = tile.designation - cur = des.flow_size - if cur != s[:amount] - tile.spawn_liquid((cur > s[:amount] ? cur-1 : cur+1), s[:liquid] == 'magma') - end - end - } - if $sources.empty? - df.onupdate_unregister($sources_onupdate) - $sources_onupdate = nil - end - } - - if cur_source[:pos][0] >= 0 - if tile = df.map_tile_at(*cur_source[:pos]) - if tile.shape_passableflow - $sources << cur_source - else - puts "Impassable tile: I'm afraid I can't do that, Dave" - end - else - puts "Unallocated map block - build something here first" - end - else - puts "Please put the game cursor where you want a source" - end - -when 'del', 'delete' - $sources.delete_if { |s| s[:pos] == cur_source[:pos] } - -when 'clear' - $sources.clear - -when 'list' - puts "Source list:", $sources.map { |s| - " #{s[:pos].inspect} #{s[:liquid]} #{s[:amount]}" - } - puts "Current cursor pos: #{[df.cursor.x, df.cursor.y, df.cursor.z].inspect}" if df.cursor.x >= 0 - -else - puts < 'water', + :amount => 7, + :pos => [df.cursor.x, df.cursor.y, df.cursor.z] +} +cmd = 'help' + +$script_args.each { |a| + case a.downcase + when 'water', 'magma' + cur_source[:liquid] = a.downcase + when /^\d+$/ + cur_source[:amount] = a.to_i + when 'add', 'del', 'delete', 'clear', 'help', 'list' + cmd = a.downcase + else + puts "source: unhandled argument #{a}" + end +} + +case cmd +when 'add' + $sources_onupdate ||= df.onupdate_register('sources', 12) { + # called every 12 game ticks (100x a dwarf day) + $sources.each { |s| + if tile = df.map_tile_at(*s[:pos]) and tile.shape_passableflow + # XXX does not check current liquid_type + des = tile.designation + cur = des.flow_size + if cur != s[:amount] + tile.spawn_liquid((cur > s[:amount] ? cur-1 : cur+1), s[:liquid] == 'magma') + end + end + } + if $sources.empty? + df.onupdate_unregister($sources_onupdate) + $sources_onupdate = nil + end + } + + if cur_source[:pos][0] >= 0 + if tile = df.map_tile_at(*cur_source[:pos]) + if tile.shape_passableflow + $sources << cur_source + else + puts "Impassable tile: I'm afraid I can't do that, Dave" + end + else + puts "Unallocated map block - build something here first" + end + else + puts "Please put the game cursor where you want a source" + end + +when 'del', 'delete' + $sources.delete_if { |s| s[:pos] == cur_source[:pos] } + +when 'clear' + $sources.clear + +when 'list' + puts "Source list:", $sources.map { |s| + " #{s[:pos].inspect} #{s[:liquid]} #{s[:amount]}" + } + puts "Current cursor pos: #{[df.cursor.x, df.cursor.y, df.cursor.z].inspect}" if df.cursor.x >= 0 + +else + puts < 1}" -end - -def cage_dump_items(list) - count = 0 - count_cage = 0 - list.each { |cage| - pre_count = count - cage.general_refs.each { |ref| - next unless ref.kind_of?(DFHack::GeneralRefContainsItemst) - next if ref.item_tg.flags.dump - count += 1 - ref.item_tg.flags.dump = true - } - count_cage += 1 if pre_count != count - } - - puts "Dumped #{plural(count, 'item')} in #{plural(count_cage, 'cage')}" -end - -def cage_dump_armor(list) - count = 0 - count_cage = 0 - list.each { |cage| - pre_count = count - cage.general_refs.each { |ref| - next unless ref.kind_of?(DFHack::GeneralRefContainsUnitst) - ref.unit_tg.inventory.each { |it| - next if it.mode != :Worn - next if it.item.flags.dump - count += 1 - it.item.flags.dump = true - } - } - count_cage += 1 if pre_count != count - } - - puts "Dumped #{plural(count, 'armor piece')} in #{plural(count_cage, 'cage')}" -end - -def cage_dump_weapons(list) - count = 0 - count_cage = 0 - list.each { |cage| - pre_count = count - cage.general_refs.each { |ref| - next unless ref.kind_of?(DFHack::GeneralRefContainsUnitst) - ref.unit_tg.inventory.each { |it| - next if it.mode != :Weapon - next if it.item.flags.dump - count += 1 - it.item.flags.dump = true - } - } - count_cage += 1 if pre_count != count - } - - puts "Dumped #{plural(count, 'weapon')} in #{plural(count_cage, 'cage')}" -end - -def cage_dump_all(list) - count = 0 - count_cage = 0 - list.each { |cage| - pre_count = count - cage.general_refs.each { |ref| - case ref - when DFHack::GeneralRefContainsItemst - next if ref.item_tg.flags.dump - count += 1 - ref.item_tg.flags.dump = true - when DFHack::GeneralRefContainsUnitst - ref.unit_tg.inventory.each { |it| - next if it.item.flags.dump - count += 1 - it.item.flags.dump = true - } - end - } - count_cage += 1 if pre_count != count - } - - puts "Dumped #{plural(count, 'item')} in #{plural(count_cage, 'cage')}" -end - - -def cage_dump_list(list) - count_total = Hash.new(0) - empty_cages = 0 - list.each { |cage| - count = Hash.new(0) - - cage.general_refs.each { |ref| - case ref - when DFHack::GeneralRefContainsItemst - count[ref.item_tg._rtti_classname] += 1 - when DFHack::GeneralRefContainsUnitst - ref.unit_tg.inventory.each { |it| - count[it.item._rtti_classname] += 1 - } - # TODO vermin ? - else - puts "unhandled ref #{ref.inspect}" if $DEBUG - end - } - - type = case cage - when DFHack::ItemCagest; 'Cage' - when DFHack::ItemAnimaltrapst; 'Animal trap' - else cage._rtti_classname - end - - if count.empty? - empty_cages += 1 - else - puts "#{type} ##{cage.id}: ", count.sort_by { |k, v| v }.map { |k, v| " #{v} #{k}" } - end - - count.each { |k, v| count_total[k] += v } - } - - if list.length > 2 - puts '', "Total: ", count_total.sort_by { |k, v| v }.map { |k, v| " #{v} #{k}" } - puts "with #{plural(empty_cages, 'empty cage')}" - end -end - - -# handle magic script arguments -here_only = $script_args.delete 'here' -if here_only - it = df.item_find - list = [it] - if not it.kind_of?(DFHack::ItemCagest) and not it.kind_of?(DFHack::ItemAnimaltrapst) - list = df.world.items.other[:ANY_CAGE_OR_TRAP].find_all { |i| df.at_cursor?(i) } - end - if list.empty? - puts 'Please select a cage' - throw :script_finished - end - -elsif ids = $script_args.find_all { |arg| arg =~ /^\d+$/ } and ids.first - list = [] - ids.each { |id| - $script_args.delete id - if not it = df.item_find(id.to_i) - puts "Invalid item id #{id}" - elsif not it.kind_of?(DFHack::ItemCagest) and not it.kind_of?(DFHack::ItemAnimaltrapst) - puts "Item ##{id} is not a cage" - list << it - else - list << it - end - } - if list.empty? - puts 'Please use a valid cage id' - throw :script_finished - end - -else - list = df.world.items.other[:ANY_CAGE_OR_TRAP] -end - - -# act -case $script_args[0] -when /^it/i - cage_dump_items(list) -when /^arm/i - cage_dump_armor(list) -when /^wea/i - cage_dump_weapons(list) -when 'all' - cage_dump_all(list) -when 'list' - cage_dump_list(list) -else - puts < 1}" +end + +def cage_dump_items(list) + count = 0 + count_cage = 0 + list.each { |cage| + pre_count = count + cage.general_refs.each { |ref| + next unless ref.kind_of?(DFHack::GeneralRefContainsItemst) + next if ref.item_tg.flags.dump + count += 1 + ref.item_tg.flags.dump = true + } + count_cage += 1 if pre_count != count + } + + puts "Dumped #{plural(count, 'item')} in #{plural(count_cage, 'cage')}" +end + +def cage_dump_armor(list) + count = 0 + count_cage = 0 + list.each { |cage| + pre_count = count + cage.general_refs.each { |ref| + next unless ref.kind_of?(DFHack::GeneralRefContainsUnitst) + ref.unit_tg.inventory.each { |it| + next if it.mode != :Worn + next if it.item.flags.dump + count += 1 + it.item.flags.dump = true + } + } + count_cage += 1 if pre_count != count + } + + puts "Dumped #{plural(count, 'armor piece')} in #{plural(count_cage, 'cage')}" +end + +def cage_dump_weapons(list) + count = 0 + count_cage = 0 + list.each { |cage| + pre_count = count + cage.general_refs.each { |ref| + next unless ref.kind_of?(DFHack::GeneralRefContainsUnitst) + ref.unit_tg.inventory.each { |it| + next if it.mode != :Weapon + next if it.item.flags.dump + count += 1 + it.item.flags.dump = true + } + } + count_cage += 1 if pre_count != count + } + + puts "Dumped #{plural(count, 'weapon')} in #{plural(count_cage, 'cage')}" +end + +def cage_dump_all(list) + count = 0 + count_cage = 0 + list.each { |cage| + pre_count = count + cage.general_refs.each { |ref| + case ref + when DFHack::GeneralRefContainsItemst + next if ref.item_tg.flags.dump + count += 1 + ref.item_tg.flags.dump = true + when DFHack::GeneralRefContainsUnitst + ref.unit_tg.inventory.each { |it| + next if it.item.flags.dump + count += 1 + it.item.flags.dump = true + } + end + } + count_cage += 1 if pre_count != count + } + + puts "Dumped #{plural(count, 'item')} in #{plural(count_cage, 'cage')}" +end + + +def cage_dump_list(list) + count_total = Hash.new(0) + empty_cages = 0 + list.each { |cage| + count = Hash.new(0) + + cage.general_refs.each { |ref| + case ref + when DFHack::GeneralRefContainsItemst + count[ref.item_tg._rtti_classname] += 1 + when DFHack::GeneralRefContainsUnitst + ref.unit_tg.inventory.each { |it| + count[it.item._rtti_classname] += 1 + } + # TODO vermin ? + else + puts "unhandled ref #{ref.inspect}" if $DEBUG + end + } + + type = case cage + when DFHack::ItemCagest; 'Cage' + when DFHack::ItemAnimaltrapst; 'Animal trap' + else cage._rtti_classname + end + + if count.empty? + empty_cages += 1 + else + puts "#{type} ##{cage.id}: ", count.sort_by { |k, v| v }.map { |k, v| " #{v} #{k}" } + end + + count.each { |k, v| count_total[k] += v } + } + + if list.length > 2 + puts '', "Total: ", count_total.sort_by { |k, v| v }.map { |k, v| " #{v} #{k}" } + puts "with #{plural(empty_cages, 'empty cage')}" + end +end + + +# handle magic script arguments +here_only = $script_args.delete 'here' +if here_only + it = df.item_find + list = [it] + if not it.kind_of?(DFHack::ItemCagest) and not it.kind_of?(DFHack::ItemAnimaltrapst) + list = df.world.items.other[:ANY_CAGE_OR_TRAP].find_all { |i| df.at_cursor?(i) } + end + if list.empty? + puts 'Please select a cage' + throw :script_finished + end + +elsif ids = $script_args.find_all { |arg| arg =~ /^\d+$/ } and ids.first + list = [] + ids.each { |id| + $script_args.delete id + if not it = df.item_find(id.to_i) + puts "Invalid item id #{id}" + elsif not it.kind_of?(DFHack::ItemCagest) and not it.kind_of?(DFHack::ItemAnimaltrapst) + puts "Item ##{id} is not a cage" + list << it + else + list << it + end + } + if list.empty? + puts 'Please use a valid cage id' + throw :script_finished + end + +else + list = df.world.items.other[:ANY_CAGE_OR_TRAP] +end + + +# act +case $script_args[0] +when /^it/i + cage_dump_items(list) +when /^arm/i + cage_dump_armor(list) +when /^wea/i + cage_dump_weapons(list) +when 'all' + cage_dump_all(list) +when 'list' + cage_dump_list(list) +else + puts < 10000 - u.counters2.sleepiness_timer = 1 - end - - # no break - if b = u.status.misc_traits.find { |t| t.id == :OnBreak } - b.value = 500_000 - end - else - $superdwarf_ids.delete id - end - } - end - } - else - puts "Select a creature using 'v'" - end - -when 'del' - if u = df.unit_find - $superdwarf_ids.delete u.id - else - puts "Select a creature using 'v'" - end - -when 'clear' - $superdwarf_ids.clear - -when 'list' - puts "current superdwarves:", $superdwarf_ids.map { |id| df.unit_find(id).name } - -else - puts "Usage:", - " - superdwarf add: give superspeed to currently selected creature", - " - superdwarf del: remove superspeed to current creature", - " - superdwarf clear: remove all superpowers", - " - superdwarf list: list super-dwarves" -end +# give super-dwarven speed to an unit + +$superdwarf_onupdate ||= nil +$superdwarf_ids ||= [] + +case $script_args[0] +when 'add' + if u = df.unit_find + $superdwarf_ids |= [u.id] + + $superdwarf_onupdate ||= df.onupdate_register('superdwarf', 1) { + if $superdwarf_ids.empty? + df.onupdate_unregister($superdwarf_onupdate) + $superdwarf_onupdate = nil + else + $superdwarf_ids.each { |id| + if u = df.unit_find(id) and not u.flags1.dead + u.actions.each { |a| + case a.type + when :Move + a.data.move.timer = 1 + when :Climb + a.data.climb.timer = 1 + when :Job + a.data.job.timer = 1 + when :Job2 + a.data.job2.timer = 1 + when :Attack + # Attack execution timer; fires when reaches zero. + a.data.attack.timer1 = 1 + # Attack completion timer: finishes action at zero. + # An action must complete before target re-seleciton + # occurs. + a.data.attack.timer2 = 0 + end + } + + # no sleep + if u.counters2.sleepiness_timer > 10000 + u.counters2.sleepiness_timer = 1 + end + + # no break + if b = u.status.misc_traits.find { |t| t.id == :OnBreak } + b.value = 500_000 + end + else + $superdwarf_ids.delete id + end + } + end + } + else + puts "Select a creature using 'v'" + end + +when 'del' + if u = df.unit_find + $superdwarf_ids.delete u.id + else + puts "Select a creature using 'v'" + end + +when 'clear' + $superdwarf_ids.clear + +when 'list' + puts "current superdwarves:", $superdwarf_ids.map { |id| df.unit_find(id).name } + +else + puts "Usage:", + " - superdwarf add: give superspeed to currently selected creature", + " - superdwarf del: remove superspeed to current creature", + " - superdwarf clear: remove all superpowers", + " - superdwarf list: list super-dwarves" +end diff --git a/scripts/undump-buildings.lua b/scripts/undump-buildings.lua index fc1511343..77e7fce5f 100644 --- a/scripts/undump-buildings.lua +++ b/scripts/undump-buildings.lua @@ -17,7 +17,7 @@ function undump_buildings() end end end - + if undumped > 0 then local s = "s" if undumped == 1 then s = "" end diff --git a/scripts/unsuspend.rb b/scripts/unsuspend.rb index 0d5a10be4..690ce6f03 100644 --- a/scripts/unsuspend.rb +++ b/scripts/unsuspend.rb @@ -1,17 +1,17 @@ -joblist = df.world.job_list.next -count = 0 - -while joblist - job = joblist.item - joblist = joblist.next - - if job.job_type == :ConstructBuilding - if (job.flags.suspend && job.items && job.items[0]) - item = job.items[0].item - job.flags.suspend = false - count += 1 - end - end -end - -puts "Unsuspended #{count} job(s)." +joblist = df.world.job_list.next +count = 0 + +while joblist + job = joblist.item + joblist = joblist.next + + if job.job_type == :ConstructBuilding + if (job.flags.suspend && job.items && job.items[0]) + item = job.items[0].item + job.flags.suspend = false + count += 1 + end + end +end + +puts "Unsuspended #{count} job(s)." From 9ef25f33a9a5b5e359542d531bd0464ddfda058c Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 14 Feb 2015 23:28:16 -0500 Subject: [PATCH 12/22] Update submodules (whitespace changes) --- plugins/df2mc | 2 +- plugins/isoworld | 2 +- plugins/stonesense | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/df2mc b/plugins/df2mc index a80abe848..5b167d2ba 160000 --- a/plugins/df2mc +++ b/plugins/df2mc @@ -1 +1 @@ -Subproject commit a80abe848e4886a210e7a5123192e9221dc85810 +Subproject commit 5b167d2ba89b877d80e0609feae8771aeaef356d diff --git a/plugins/isoworld b/plugins/isoworld index 07750ad7f..85dcde971 160000 --- a/plugins/isoworld +++ b/plugins/isoworld @@ -1 +1 @@ -Subproject commit 07750ad7f7ce7c2506e5198ffb80ca50a73e9c4e +Subproject commit 85dcde97197bdde1c1e97ccb536f2cc4cab6818f diff --git a/plugins/stonesense b/plugins/stonesense index 8270ef289..a8c5bd263 160000 --- a/plugins/stonesense +++ b/plugins/stonesense @@ -1 +1 @@ -Subproject commit 8270ef2892b640a2e5753844a5e917ba96523fbb +Subproject commit a8c5bd263306050ac1dc21140ce52719b0dd598b From 16a1e413310bc81e844d4d5491ad8d729fedaefe Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 14 Feb 2015 23:40:44 -0500 Subject: [PATCH 13/22] Set language to C++ in .travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 4653cf18c..b149c1140 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,2 +1,3 @@ +language: cpp script: - python travis/lint.py From 5223891984e07aba3c6a435f7a0d8e8a2649df39 Mon Sep 17 00:00:00 2001 From: PeridexisErrant Date: Sun, 15 Feb 2015 18:13:58 +1100 Subject: [PATCH 14/22] Update and clarify readme Fixed typos. Made hyperlinks inline. Some editorial changes for clarification. Updated and expanded introduction. Fixed a few formatting errors. --- Readme.rst | 222 +++++++++++++++++++++++++++-------------------------- 1 file changed, 115 insertions(+), 107 deletions(-) diff --git a/Readme.rst b/Readme.rst index 56678afc3..cf0cc45df 100644 --- a/Readme.rst +++ b/Readme.rst @@ -6,39 +6,56 @@ DFHack Readme Introduction ============ -DFHack is a Dwarf Fortress memory access library and a set of basic -tools that use it. Tools come in the form of plugins or (not yet) -external tools. It is an attempt to unite the various ways tools -access DF memory and allow for easier development of new tools. +DFHack is a Dwarf Fortress memory access library, distributed with scripts +and plugins implementing a wide variety of useful functions and tools. + +For users, it provides a significant suite of bugfixes and interface +enhancements by default, and more can be enabled. There are also many tools +(such as ``workflow`` or ``autodump``) which can make life easier. You can +even add third-party scripts and plugins to do almost anything! + +For modders, DFHack makes many things possible. Custom reactions, new +interactions, magic creature abilities, and more can be set through scripts +and custom raws. Non-standard DFHack scripts and inits can be stored in the +raw directory, making raws or saves fully self-contained for distribution - +or for coexistence in a single DF install, even with incompatible components. + +For developers, DFHack unites the various ways tools access DF memory and +allows easier development of new tools. As an open-source project under +various copyleft licences, contributions are welcome. .. contents:: ============== Getting DFHack ============== -The project is currently hosted on github_ -at http://github.com/DFHack/dfhack +The project is currently hosted at http://www.github.com/ + +Recent releases are available in source and binary formats `on the releases +page`_, while the binaries for releases 40.15-r1 to 34.11-r4 are on DFFD_. +Even older versions are available here_. -.. _github: http://www.github.com/ +.. _`on the releases page`: http://github.com/DFHack/dfhack/releases +.. _DFFD: http://dffd.bay12games.com/search.php?string=DFHack&id=15 +.. _here: http://dethware.org/dfhack/download -Older releases can be downloaded from here: http://dethware.org/dfhack/download +All new releases are announced in `the bay12 forums thread`_, which is also a +good place for discussion and questions. -All new releases are announced in the bay12 thread: -http://www.bay12forums.com/smf/index.php?topic=139553.0 +.. _`the bay12 forums thread`: http://www.bay12forums.com/smf/index.php?topic=139553 ============= Compatibility ============= -DFHack works on Windows XP, Vista, 7, any modern Linux distribution, or OS X -10.6.8-10.9. +DFHack is available for Windows (XP or later), Linux (any modern distribution), +or OS X (10.6.8 to 10.9). -Recent versions can be found on the releases_ page. Most releases only support -the version of DF mentioned in their title (e.g. DFHack 0.40.24-r2 only supports -DF 0.40.24), but some releases support earlier DF versions as well. +Most releases only support the version of DF mentioned in their title - for +example, DFHack 0.40.24-r2 only supports DF 0.40.24 - but some releases +support earlier DF versions as well. Wherever possible, use the latest version +built for the target version of DF. -.. _releases: http://github.com/DFHack/dfhack/releases - -On Windows, you have to use the SDL version of DF. +On Windows, DFHack is compatible with the SDL version of DF, but not the legacy version. It is also possible to use the Windows DFHack with Wine under Linux and OS X. @@ -95,7 +112,7 @@ DFHack basically extends what DF can do with something similar to the drop-down console found in Quake engine games. On Windows, this is a separate command line window. On linux, the terminal used to launch the dfhack script is taken over (so, make sure you start from a terminal). Basic interaction with dfhack -involves entering commands into the console. For some basic instroduction, +involves entering commands into the console. For some basic instructions, use the 'help' command. To list all possible commands, use the 'ls' command. Many commands have their own help or detailed description. You can use 'command help' or 'command ?' to show that. @@ -158,22 +175,28 @@ In this case, updating symbols.xml is not necessary. ============================= Something doesn't work, help! ============================= -First, don't panic :) Second, dfhack keeps a few log files in DF's folder -- stderr.log and stdout.log. You can look at those and possibly find out what's -happening. -If you found a bug, you can either report it in the bay12 DFHack thread, -the issues tracker on github, contact me (peterix@gmail.com) or visit the -#dfhack IRC channel on freenode. +First, don't panic :) + +Second, dfhack keeps a few log files in DF's folder (``stderr.log`` and +``stdout.log``). Looking at these might help you solve the problem. +If it doesn't, you can ask for help in the forum thread or on IRC. + +If you found a bug, you can report it in the Bay12 DFHack thread, the issues +tracker on github, or visit the #dfhack IRC channel on freenode. ============= The init file ============= -If your DF folder contains a file named ``dfhack.init``, its contents will be run -every time you start DF. This allows setting up keybindings. An example file -is provided as ``dfhack.init-example`` - you can tweak it and rename to dfhack.init -if you want to use this functionality. +If your DF folder contains a file named ``dfhack.init``, its contents will be +run every time you start DF. This allows keybindings and other settings to +persist across runs. An example file is provided as ``dfhack.init-example`` - +you can tweak it and rename to ``dfhack.init`` if you want to use this +functionality. If only the example init file is found, will be used and a +warning will be shown. -When a savegame is loaded, the ``onLoad.init`` file in its raw folder is run. It works the same way as ``dfhack.init``. It is recommended that modders use this to improve mobility of save games. +When a savegame is loaded, an ``onLoad.init`` file in its raw folder is run, +as a save-portable alternative to ``dfhack.init``. It is recommended that +modders use this to improve mobility of save games and compatibility of mods. Setting keybindings =================== @@ -252,10 +275,10 @@ If the first non-whitespace character is ``:``, the command is parsed in a speci alternative mode: first, non-whitespace characters immediately following the ``:`` are used as the command name; the remaining part of the line, starting with the first non-whitespace character *after* the command name, is used verbatim as the first argument. -The following two command lines are exactly equivalent: +The following two command lines are exactly equivalent:: -* ``:foo a b "c d" e f`` -* ``foo "a b \"c d\" e f"`` + :foo a b "c d" e f + foo "a b \"c d\" e f" This is intended for commands like ``rb_eval`` that evaluate script language statements. @@ -396,13 +419,14 @@ that pre-filled. rendermax --------- A collection of renderer replacing/enhancing filters. For better effect try changing the -black color in palette to non totally black. For more info see thread in forums: -http://www.bay12forums.com/smf/index.php?topic=128487.0 +black color in palette to non totally black. For more info see `the Bay12 forum thread`_. + +.. _`the Bay12 forum thread`: http://www.bay12forums.com/smf/index.php?topic=128487 Options: ``rendermax trippy`` - Randomizes each tiles color. Used for fun mainly. + Randomizes the color of each tiles. Used for fun, or testing. ``rendermax light`` Enable lighting engine. ``rendermax light reload`` @@ -467,8 +491,6 @@ care to exactly preserve the mineral counts reported by ``prospect all``. The amounts of different layer stones may slightly change in some cases if vein mass shifts between Z layers. -This command is very unlikely to work on maps generated before version 0.34.08. - Note that there is no undo option other than restoring from backup. changelayer @@ -609,8 +631,8 @@ Options: :building: Subsequent items will become part of the currently selected building. Best used for loading traps; do not use with workshops, or you will need to deconstruct the building to use the item. -deramp (by zilpin) ------------------- +deramp +------ Removes all ramps designated for removal from the map. This is useful for replicating the old channel digging designation. It also removes any and all 'down ramps' that can remain after a cave-in (you don't have to designate anything for that to happen). @@ -1006,9 +1028,9 @@ A permanent alias for 'digl x'. digexp ------ -This command can be used for exploratory mining. +This command is for `exploratory mining`_. -See: http://df.magmawiki.com/index.php/DF2010:Exploratory_mining +.. _`exploratory mining`: http://dwarffortresswiki.org/index.php/cv:Exploratory_mining There are two variables that can be set: pattern and filter. @@ -1207,16 +1229,11 @@ Cursor must be placed on a floor tile so the items can be dumped there. Options: :destroy: Destroy instead of dumping. Doesn't require a cursor. -:destroy-here: Destroy items only under the cursor. +:destroy-here: Destroy items only under the cursor. Alias ``autodump-destroy-here``, for keybindings. :visible: Only process items that are not hidden. :hidden: Only process hidden items. :forbidden: Only process forbidden items (default: only unforbidden). -autodump-destroy-here ---------------------- -Destroy items marked for dumping under cursor. Identical to autodump -destroy-here, but intended for use as keybinding. - autodump-destroy-item --------------------- Destroy the selected item. The item may be selected in the 'k' list, or inside @@ -1359,8 +1376,9 @@ armor stands, and in containers. Also, the default capacity of armor stands is way too low, so you may want to also apply the ``armorstand-capacity`` patch. Check out - http://www.bay12games.com/dwarves/mantisbt/view.php?id=1445 - for more information about the bugs. + `the bug report`_ for more information. + +.. _`the bug report`: http://www.bay12games.com/dwarves/mantisbt/view.php?id=1445 Note that the buildings in the armory are used as follows: @@ -1435,8 +1453,7 @@ produce undesirable results. There are a few good ones though. You just lost a fortress and gained an adventurer. You could also do this. You are in fort game mode, managing your fortress and paused at the esc menu. - You switch to the adventure game mode, then use Dfusion to *assume control of a creature* and then - save or retire. + You switch to the adventure game mode, assume control of a creature, then save or retire. You just created a returnable mountain home and gained an adventurer. @@ -1446,39 +1463,39 @@ I take no responsibility of anything that happens as a result of using this tool Visualizer and data export ========================== -ssense / stonesense -------------------- +stonesense +---------- An isometric visualizer that runs in a second window. This requires working graphics acceleration and at least a dual core CPU (otherwise it will slow -down DF). - -All the data resides in the 'stonesense' directory. For detailed instructions, -see stonesense/README.txt +down DF). Invoked with ``stonesense``, or alias ``ssense``. -Compatible with Windows > XP SP3 and most modern Linux distributions. +For detailed information, see the `stonesense readme`_, the `wiki page`_, +or the `Bay12 forum thread`_. -Older versions, support and extra graphics can be found in the bay12 forum -thread: http://www.bay12forums.com/smf/index.php?topic=43260.0 +.. _`stonesense readme`: https://github.com/DFHack/stonesense/blob/master/README.md +.. _`wiki page`: http://dwarffortresswiki.org/index.php/Utility:Stonesense +.. _`Bay12 forum thread`: http://www.bay12forums.com/smf/index.php?topic=43260 -Some additional resources: -http://df.magmawiki.com/index.php/Utility:Stonesense/Content_repository +Stonesense works on Windows XP SP3 or later, and most modern Linux distributions. +Each stonesense version is built for a particular version of DFHack, so +releases are now done through DFHack. mapexport --------- -Export the current loaded map as a file. This will be eventually usable -with visualizers. +Export the current loaded map as a file. This was used by visualizers for +DF 34.11, but is now basically obsolete. dwarfexport ----------- -Export dwarves to RuneSmith-compatible XML. +Export dwarves to RuneSmith-compatible XML; also unused by modern tools. exportlegends ------------- Controls legends mode to export data - especially useful to set-and-forget large worlds, or when you want a map of every site when there are several hundred. -The 'info' option exports more data than is possible in vanilla, to a -region-date-legends_plus.xml" file developed to extend the World +The 'info' option exports more data than is possible in vanilla, to a +``region-date-legends_plus.xml`` file developed to extend the World Viewer utility and potentially compatible with others. Options: @@ -1626,13 +1643,15 @@ in the game UI. Constraint format ~~~~~~~~~~~~~~~~~ -The contstraint spec consists of 4 parts, separated with '/' characters:: +The constraint spec consists of 4 parts, separated with '/' characters:: ITEM[:SUBTYPE]/[GENERIC_MAT,...]/[SPECIFIC_MAT:...]/[LOCAL,] The first part is mandatory and specifies the item type and subtype, using the raw tokens for items, in the same syntax you would e.g. use -for a custom reaction input. See this list for more info: http://dwarffortresswiki.org/index.php/Item_token +for a custom reaction input. See `this page`_ for more info. + +.. _`this page`: http://dwarffortresswiki.org/index.php/Material_token The subsequent parts are optional: @@ -1645,9 +1664,9 @@ The subsequent parts are optional: - A specific material spec chooses the material exactly, using the raw syntax for reaction input materials, e.g. INORGANIC:IRON, although for convenience it also allows just IRON, or ACACIA:WOOD etc. - See this page for more details on the unabbreviated raw syntax: + See `this page`_ for more details on the unabbreviated raw syntax. - http://dwarffortresswiki.org/index.php/Material_token + .. _`this page`: http://dwarffortresswiki.org/index.php/Material_token - A comma-separated list of miscellaneous flags, which currently can be used to ignore imported items or items below a certain quality. @@ -1975,15 +1994,11 @@ add some new races with 'watch'. If you simply want to stop it completely use Settings and watchlist are stored in the savegame, so that you can have different settings for each world. If you want to copy your watchlist to -another savegame you can use the command list_export: -:: - - Load savegame where you made the settings. - Start a CMD shell and navigate to the df directory. Type the following into the shell: - dfhack-run autobutcher list_export > autobutcher.bat - Load the savegame where you want to copy the settings to, run the batch file (from the shell): - autobutcher.bat +another savegame you can export and then import them with ``list_export``: +To export them, open a terminal in the DF directory, and run +``dfhack-run autobutcher list_export > autobutcher.bat`` (or ``.sh`` on OSX or +Linux). To import, load your new save and run the script you created. autochop --------- @@ -1994,7 +2009,7 @@ Open the dashboard by running:: getplants autochop -The plugin must be activated (with 'a') before it can be used. You can then set logging quotas +The plugin must be activated (with ``c``) before it can be used. You can then set logging quotas and restrict designations to specific burrows (with 'Enter') if desired. The plugin's activity cycle runs once every in game day. @@ -2055,16 +2070,16 @@ Other jobs are automatically assigned as described above. Each of these setting Jobs are rarely assigned to nobles with responsibilities for meeting diplomats or merchants, never to the chief medical dwarf, and less often to the bookeeper and manager. -Hunting is never assigned without a butchery, and fishing is nver assigned without a fishery. +Hunting is never assigned without a butchery, and fishing is never assigned without a fishery. For each labor a preference order is calculated based on skill, biased against masters of other trades and excluding those who can't do the job. The labor is then added to the best dwarves for that labor. We assign at least the minimum number of dwarfs, in order of preference, and then assign additional dwarfs that meet any of these conditions: - * The dwarf is idle and there are no idle dwarves assigned to this labor - * The dwarf has nonzero skill associated with the labor - * The labor is mining, hunting, or woodcutting and the dwarf currently has it enabled. +* The dwarf is idle and there are no idle dwarves assigned to this labor +* The dwarf has non-zero skill associated with the labor +* The labor is mining, hunting, or woodcutting and the dwarf currently has it enabled. We stop assigning dwarfs when we reach the maximum allowed. @@ -2078,18 +2093,10 @@ twice. dfusion ------- -This is the DFusion lua plugin system by Warmist, running as a DFHack plugin. There are two parts to this plugin: an interactive script that shows a text based menu and lua modules. Some of the functionality of is intentionaly left out of the menu: +This is the DFusion system (a DFHack precursor) by Warmist, running as a DFHack +plugin. For detail on this legacy system, see the `Bay12 forums thread`_. -:Friendship: a binary plugin that allows multi race forts (to use make a script that imports plugins.dfusion.friendship and use Friendship:install{table} table should contain list of race names.) -:Embark: a binary plugin that allows multi race embark (to use make a script that imports plugins.dfusion.embark and use Embark:install{table} table should contain list of race names or list of pairs (race-name, caste_id)). - -See the bay12 thread for details: http://www.bay12forums.com/smf/index.php?topic=93317.0 - - -.. note:: - - * Some of the DFusion plugins aren't completely ported yet. This can lead to crashes. - * The game will be suspended while you're using dfusion. Don't panic when it doesn't respond. +.. _`Bay12 forums thread`: http://www.bay12forums.com/smf/index.php?topic=93317 embark-tools ------------ @@ -2201,7 +2208,8 @@ Scripts in this subdirectory fix various bugs and issues, some of them obscure. * fix/growth-bug - Fixes locally born units such that they will grow larger than their birth size. Note that this bug was fixed in DF version 0.40.02. + Fixes locally born units such that they will grow larger than their birth size. + Note that this bug was fixed in DF version 0.40.02. * fix/item-occupancy @@ -2235,7 +2243,7 @@ directory. * gui/stockpiles Load and save stockpile settings from the 'q' menu. - Usage: + Usage:: gui/stockpiles -save to save the current stockpile gui/stockpiles -load to load settings into the current stockpile @@ -2317,11 +2325,11 @@ deathcause ========== Focus a body part ingame, and this script will display the cause of death of the creature. -Also works when selecting units from the 'u'nitlist viewscreen. +Also works when selecting units from the (``u``) unitlist viewscreen. dfstatus ======== -Show a quick overview of critical stock quantities, including food, dirnks, wood, and various bars. +Show a quick overview of critical stock quantities, including food, drinks, wood, and various bars. exterminate =========== @@ -2344,7 +2352,7 @@ such as vampires, it also sets animal.vanish_countdown to 2. An alternate mode is selected by adding a 2nd argument to the command, ``magma``. In this case, a column of 7/7 magma is generated on top of the targets until they die (Warning: do not call on magma-safe creatures. Also, -using this mode on birds is not recommanded.) +using this mode on birds is not recommended.) Will target any unit on a revealed tile of the map, including ambushers, but ignore caged/chained creatures. @@ -2381,7 +2389,7 @@ same line. The syntax of the file itself is similar to digfort or quickfort. At present, only buildings constructed of an item with the same name as the building -are supported. All other characters are ignored. For example: +are supported. All other characters are ignored. For example:: `,`,d,`,` `,f,`,t,` @@ -2424,7 +2432,7 @@ two-across pit with stairs but no walls. hotkey-notes ============ -Lists the key, name, and jump position of your hotkeys. +Lists the key, name, and jump position of your hotkeys in the DFHack console. lever ===== @@ -2916,11 +2924,11 @@ work again. The existing issues are: * Even if assigned by the script, **the game will unassign the racks again without a binary patch**. This patch is called ``weaponrack-unassign``, and can be applied via - the binpatch program, or the matching script. See this for more info - about the bug: - http://www.bay12games.com/dwarves/mantisbt/view.php?id=1445 + the binpatch program, or the matching script. See `the bug report`_ for more info. + +.. _`the bug report`: http://www.bay12games.com/dwarves/mantisbt/view.php?id=1445 -* Haulers still take equpment stored in the armory away to the stockpiles, +* Haulers still take equipment stored in the armory away to the stockpiles, unless the ``fix-armory`` plugin above is used. The script interface simply lets you designate one of the squads that From 3a5cd754dd51cfc7dd902b883c303a5da4f0d8fa Mon Sep 17 00:00:00 2001 From: lethosor Date: Sun, 15 Feb 2015 13:23:39 -0500 Subject: [PATCH 15/22] Verify that pull requests are based on develop --- .travis.yml | 1 + travis/pr-check-base.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 travis/pr-check-base.py diff --git a/.travis.yml b/.travis.yml index b149c1140..5e8077f9e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ language: cpp script: - python travis/lint.py +- python travis/pr-check-base.py diff --git a/travis/pr-check-base.py b/travis/pr-check-base.py new file mode 100644 index 000000000..e4e9ae910 --- /dev/null +++ b/travis/pr-check-base.py @@ -0,0 +1,29 @@ +import json, os, sys +if sys.version.startswith('2'): + from urllib2 import urlopen, HTTPError +else: + from urllib.request import urlopen + from urllib.error import HTTPError +try: + pr_id = int(os.environ.get('TRAVIS_PULL_REQUEST', 'false')) +except ValueError: + print('Not a pull request') + sys.exit(0) +print('Pull request %i' % pr_id) +res = {} +try: + res = json.loads(urlopen('https://api.github.com/repos/dfhack/dfhack/pulls/%i' % pr_id).read().decode('utf-8')) +except ValueError: + pass +except HTTPError: + print('Failed to retrieve PR information from API') + sys.exit(2) +if 'base' not in res or 'ref' not in res['base']: + print('Invalid JSON returned from API') + sys.exit(2) +if res['base']['ref'] != 'develop': + print('Not based on develop branch') + sys.exit(1) +else: + print('Ok') + sys.exit(0) From 81b67721c875446f38f8f498949fc2b1777b16a6 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sun, 15 Feb 2015 13:25:00 -0500 Subject: [PATCH 16/22] Disable travis email notifications --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 5e8077f9e..a12b9d853 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,3 +2,5 @@ language: cpp script: - python travis/lint.py - python travis/pr-check-base.py +notifications: + email: false From 944ee2f53aa4baf4a8cea0717df068227093e0c6 Mon Sep 17 00:00:00 2001 From: Peridexis Errant Date: Mon, 16 Feb 2015 18:04:48 +1100 Subject: [PATCH 17/22] More readme clarification Fix DF version numbers. Make newlines at headings consistent. Consistent 4-space indentation where practical. Fix indented blocks. Remove duplicate sections. Minor editorial fixes. --- Readme.rst | 227 +++++++++++++++-------------------------------------- 1 file changed, 64 insertions(+), 163 deletions(-) diff --git a/Readme.rst b/Readme.rst index cf0cc45df..bab2fc9ad 100644 --- a/Readme.rst +++ b/Readme.rst @@ -5,7 +5,6 @@ DFHack Readme ============ Introduction ============ - DFHack is a Dwarf Fortress memory access library, distributed with scripts and plugins implementing a wide variety of useful functions and tools. @@ -32,7 +31,7 @@ Getting DFHack The project is currently hosted at http://www.github.com/ Recent releases are available in source and binary formats `on the releases -page`_, while the binaries for releases 40.15-r1 to 34.11-r4 are on DFFD_. +page`_, while the binaries for releases 0.40.15-r1 to 0.34.11-r4 are on DFFD_. Even older versions are available here_. .. _`on the releases page`: http://github.com/DFHack/dfhack/releases @@ -81,7 +80,6 @@ file created in your DF folder. Getting started =============== - If DFHack is installed correctly, it will automatically pop up a console window once DF is started as usual on windows. Linux and Mac OS X require running the dfhack script from the terminal, and will use that terminal for @@ -107,7 +105,6 @@ For more information, refer to the rest of this document. ============ Using DFHack ============ - DFHack basically extends what DF can do with something similar to the drop-down console found in Quake engine games. On Windows, this is a separate command line window. On linux, the terminal used to launch the dfhack script is taken over @@ -137,7 +134,6 @@ Most of the commands come from plugins. Those reside in 'hack/plugins/'. Patched binaries ================ - On linux and OSX, users of patched binaries may have to find the relevant section in symbols.xml, and add a new line with the checksum of their executable:: @@ -162,16 +158,13 @@ system console: The patches are expected to be encoded in text format used by IDA. - Live patching ------------- - As an alternative, you can use the ``binpatch`` dfhack command to apply/remove patches live in memory during a DF session. In this case, updating symbols.xml is not necessary. - ============================= Something doesn't work, help! ============================= @@ -200,7 +193,6 @@ modders use this to improve mobility of save games and compatibility of mods. Setting keybindings =================== - To set keybindings, use the built-in ``keybinding`` command. Like any other command it can be used at any time from the console, but it is also meaningful in the DFHack init file. @@ -239,7 +231,6 @@ for context ``foo/bar/baz``, possible matches are any of ``@foo/bar/baz``, ``@fo Enabling plugins ================ - Many plugins can be in a distinct enabled or disabled state. Some of them activate and deactivate automatically depending on the contents of the world raws. Others store their state in world data. However a @@ -256,11 +247,9 @@ arguments for the command:: enable manipulator search - ======== Commands ======== - DFHack command syntax consists of a command name, followed by arguments separated by whitespace. To include whitespace in an argument, quote it in double quotes. To include a double quote character, use ``\"`` inside double quotes. @@ -286,7 +275,6 @@ Almost all the commands support using the 'help ' built-in command to retrieve further help without having to look at this document. Alternatively, some accept a 'help'/'?' option on their command line. - Game progress ============= @@ -339,41 +327,33 @@ Toggle between displaying/not displaying liquid depth as numbers. stockpile settings management ----------------------------- - Save and load stockpile settings. See the gui/stockpiles for an in-game GUI to this plugin. copystock ~~~~~~~~~ - Copies the parameters of the currently highlighted stockpile to the custom stockpile settings and switches to custom stockpile placement mode, effectively allowing you to copy/paste stockpiles easily. savestock ~~~~~~~~~ - Saves the currently highlighted stockpile's settings to a file in your Dwarf Fortress folder. This file can be used to copy settings between game saves or players. -example: +example:: -``` -savestock food_settings.dfstock -``` + savestock food_settings.dfstock loadstock ~~~~~~~~~ - Loads a saved stockpile settings file and applies it to the currently selected stockpile. -example: +example:: -``` -loadstock food_settings.dfstock -``` + loadstock food_settings.dfstock To use savestock and loadstock, use the 'q' command to highlight a stockpile. Then run savestock giving it a descriptive filename. Then, in a different (or @@ -387,7 +367,6 @@ there or in a subfolder for easy access. Filenames should not have spaces. **Limitations:** Generated materials, divine metals, etc are not saved as they are different in every world. - rename ------ Allows renaming various things. @@ -460,8 +439,7 @@ Usage: advtools -------- -A package of different adventure mode tools (currently just one) - +A package of different adventure mode tools. Usage: @@ -479,7 +457,6 @@ Map modification 3dveins ------- - Removes all existing veins from the map and generates new ones using 3D Perlin noise, in order to produce a layout that smoothly flows between Z levels. The vein distribution is based on the world seed, so running @@ -685,7 +662,6 @@ settings in liquids were made it paints a point of 7/7 magma by default). Intended to be used as keybinding. Requires an active in-game cursor. - tiletypes --------- Can be used for painting map tiles and is an interactive command, much like @@ -765,7 +741,7 @@ You can use several different brushes for painting tiles: Example:: - range 10 10 1 + range 10 10 1 This will change the brush to a rectangle spanning 10x10 tiles on one z-level. The range starts at the position of the cursor and goes to the east, south and @@ -842,7 +818,6 @@ Options: :rain: make it rain. :clear: clear the sky. - Map inspection ============== @@ -912,7 +887,6 @@ Options: Pre-embark estimate ~~~~~~~~~~~~~~~~~~~ - If prospect is called during the embark selection screen, it displays an estimate of layer stone availability. @@ -1094,7 +1068,6 @@ Examples: * 'digcircle filled 3' = Dig a filled circle with diameter = 3. * 'digcircle' = Do it again. - digtype ------- For every tile on the map of the same vein type as the selected tile, this command designates it to have the same designation as the selected tile. If the selected tile has no designation, they will be dig designated. @@ -1191,7 +1164,6 @@ Options: Specifying both -t and -s will have no effect. If no plant IDs are specified, all valid plant IDs will be listed. - Cleanup and garbage disposal ============================ @@ -1259,8 +1231,6 @@ Example: This will confiscate rotten and dropped food, garbage on the floors and any worn items with 'X' damage and above. - - Bugfixes ======== @@ -1273,9 +1243,8 @@ fixdiplomats Up to version 0.31.12, Elves only sent Diplomats to your fortress to propose tree cutting quotas due to a bug; once that bug was fixed, Elves stopped caring about excess tree cutting. This command adds a Diplomat position to all Elven -civilizations, allowing them to negotiate tree cutting quotas (and allowing you -to violate them and potentially start wars) in case you haven't already modified -your raws accordingly. +civilizations, allowing them to negotiate tree cutting quotas - and you to +violate them and start wars. fixmerchants ------------ @@ -1447,19 +1416,17 @@ produce undesirable results. There are a few good ones though. .. admonition:: Example - You are in fort game mode, managing your fortress and paused. - You switch to the arena game mode, *assume control of a creature* and then - switch to adventure game mode(1). - You just lost a fortress and gained an adventurer. - You could also do this. - You are in fort game mode, managing your fortress and paused at the esc menu. - You switch to the adventure game mode, assume control of a creature, then save or retire. - You just created a returnable mountain home and gained an adventurer. - + You are in fort game mode, managing your fortress and paused. + You switch to the arena game mode, *assume control of a creature* and then + switch to adventure game mode(1). + You just lost a fortress and gained an adventurer. + You could also do this. + You are in fort game mode, managing your fortress and paused at the esc menu. + You switch to the adventure game mode, assume control of a creature, then save or retire. + You just created a returnable mountain home and gained an adventurer. I take no responsibility of anything that happens as a result of using this tool - Visualizer and data export ========================== @@ -1483,7 +1450,7 @@ releases are now done through DFHack. mapexport --------- Export the current loaded map as a file. This was used by visualizers for -DF 34.11, but is now basically obsolete. +DF 0.34.11, but is now basically obsolete. dwarfexport ----------- @@ -1522,7 +1489,6 @@ Options: If only region and name are given, all exports are performed. - Job management ============== @@ -1642,7 +1608,6 @@ in the game UI. Constraint format ~~~~~~~~~~~~~~~~~ - The constraint spec consists of 4 parts, separated with '/' characters:: ITEM[:SUBTYPE]/[GENERIC_MAT,...]/[SPECIFIC_MAT:...]/[LOCAL,] @@ -1673,7 +1638,6 @@ The subsequent parts are optional: Constraint examples ~~~~~~~~~~~~~~~~~~~ - Keep metal bolts within 900-1000, and wood/bone within 150-200:: workflow amount AMMO:ITEM_AMMO_BOLTS/METAL 1000 100 @@ -1807,7 +1771,6 @@ Filters: Usage with single units ~~~~~~~~~~~~~~~~~~~~~~~ - One convenient way to use the zone tool is to bind the command 'zone assign' to a hotkey, maybe also the command 'zone set'. Place the in-game cursor over a pen/pasture or pit, use 'zone set' to mark it. Then you can select units @@ -1817,7 +1780,6 @@ own dwarves, by the way. Usage with filters ~~~~~~~~~~~~~~~~~~ - All filters can be used together with the 'assign' command. Restrictions: It's not possible to assign units who are inside built cages @@ -1839,7 +1801,6 @@ Most filters can be negated (e.g. 'not grazer' -> race is not a grazer). Mass-renaming ~~~~~~~~~~~~~ - Using the 'nick' command you can set the same nickname for multiple units. If used without 'assign', 'all' or 'count' it will rename all units in the current default target zone. Combined with 'assign', 'all' or 'count' (and @@ -1847,7 +1808,6 @@ further optional filters) it will rename units matching the filter conditions. Cage zones ~~~~~~~~~~ - Using the 'tocages' command you can assign units to a set of cages, for example a room next to your butcher shop(s). They will be spread evenly among available cages to optimize hauling to and butchering from them. For this to work you need @@ -1859,7 +1819,6 @@ the usual filters. Examples ~~~~~~~~ - ``zone assign all own ALPACA minage 3 maxage 10`` Assign all own alpacas who are between 3 and 10 years old to the selected pasture. @@ -1906,22 +1865,18 @@ autobutcher Assigns lifestock for slaughter once it reaches a specific count. Requires that you add the target race(s) to a watch list. Only tame units will be processed. -Named units will be completely ignored (to protect specific animals from -autobutcher you can give them nicknames with the tool 'rename unit' for single -units or with 'zone nick' to mass-rename units in pastures and cages). - -Creatures trained for war or hunting will be ignored as well. - -Creatures assigned to cages will be ignored if the cage is defined as a room -(to avoid butchering unnamed zoo animals). - -Creatures who will not reproduce (because they're not interested in the opposite -sex or have been gelded) have first priority for butchering. +Units will be ignored if they are: +* Nicknamed (for custom protection; you can use the ``rename unit`` tool + individually, or ``zone nick` for groups) +* Caged, if and only if the cage is defined as a room (to protect zoos) +* Trained for war or hunting -Once you have too much adults, the oldest will be butchered first. -Once you have too much kids, the youngest will be butchered first. -If you don't set any target count the following default will be used: -1 male kid, 5 female kids, 1 male adult, 5 female adults. +Creatures who will not reproduce (because they're not interested in the +opposite sex or have been gelded) will be butchered before those who will. +Older adults and younger children will be butchered first if the population +is above the target (default 1 male, 5 female kids and adults). Note that +you may need to set a target above 1 to have a reliable breeding population +due to asexuality etc. Options: @@ -1985,10 +1940,9 @@ settings so that you can use 'unwatch' without the need to enter the values again. Note: 'autobutcher unwatch all' works, but only makes sense if you want to keep the plugin running with the 'autowatch' feature or manually add some new races with 'watch'. If you simply want to stop it completely use -'autobutcher stop' instead. -:: +'autobutcher stop' instead.:: - autobutcher unwatch ALPACA CAT + autobutcher unwatch ALPACA CAT **Note:** @@ -2007,21 +1961,19 @@ quotas. Open the dashboard by running:: - getplants autochop + getplants autochop The plugin must be activated (with ``c``) before it can be used. You can then set logging quotas and restrict designations to specific burrows (with 'Enter') if desired. The plugin's activity cycle runs once every in game day. -If you add -:: +If you add:: - enable getplants + enable getplants to your dfhack.init there will be a hotkey to open the dashboard from the chop designation menu. - autolabor --------- Automatically manage dwarf labors to efficiently complete jobs. @@ -2116,8 +2068,15 @@ Tools: petcapRemover ------------- - -This plugin allows you to remove or raise the pet population cap. In vanilla DF, pets will not reproduce unless the population is below 50 and the number of children of that species is below a certain percentage. This plugin allows removing the second restriction and removing or raising the first. Pets still require PET or PET_EXOTIC tags in order to reproduce. Type help petcapRemover for exact usage. In order to make population more stable and avoid sudden population booms as you go below the raised population cap, this plugin counts pregnancies toward the new population cap. It can still go over, but only in the case of multiple births. +This plugin allows you to remove or raise the pet population cap. In vanilla +DF, pets will not reproduce unless the population is below 50 and the number of +children of that species is below a certain percentage. This plugin allows +removing the second restriction and removing or raising the first. Pets still +require PET or PET_EXOTIC tags in order to reproduce. Type help petcapRemover +for exact usage. In order to make population more stable and avoid sudden +population booms as you go below the raised population cap, this plugin counts +pregnancies toward the new population cap. It can still go over, but only in the +case of multiple births. `petcapRemover` cause pregnancies now and schedule the next check @@ -2159,12 +2118,10 @@ log-region ---------- When enabled in dfhack.init, each time a fort is loaded identifying information will be written to the gamelog. Assists in parsing the file if you switch between forts, and adds information for story-building. - ======= Scripts ======= - -Lua or ruby scripts placed in the hack/scripts/ directory are considered for +Lua or ruby scripts placed in the ``hack/scripts/`` directory are considered for execution as if they were native DFHack commands. They are listed at the end of the 'ls' command output. @@ -2172,11 +2129,10 @@ Note: scripts in subdirectories of hack/scripts/ can still be called, but will only be listed by ls if called as 'ls -a'. This is intended as a way to hide scripts that are obscure, developer-oriented, or should be used as keybindings. -Some notable scripts: +The following scripts are distibuted with DFHack: fix/* ===== - Scripts in this subdirectory fix various bugs and issues, some of them obscure. * fix/blood-del @@ -2232,7 +2188,6 @@ Scripts in this subdirectory fix various bugs and issues, some of them obscure. gui/* ===== - Scripts that implement dialogs inserted into the main game window are put in this directory. @@ -2255,7 +2210,6 @@ the DF folder before trying to use this plugin. binpatch ======== - Checks, applies or removes binary patches directly in memory at runtime:: binpatch check/apply/remove @@ -2377,7 +2331,7 @@ Usage: fortplan [filename] Designates furniture for building according to a .csv file with quickfort-style syntax. Companion to digfort. -The first line of the file must contain the following: +The first line of the file must contain the following:: #build start(X; Y; ) @@ -2422,7 +2376,7 @@ Creates a pit to the underworld at the cursor. Takes three arguments: diameter of the pit in tiles, whether to wall off the pit, and whether to insert stairs. If no arguments are given, the default -is "hfs-pit 1 0 0", ie single-tile wide with no walls or stairs. +is "hfs-pit 1 0 0", ie single-tile wide with no walls or stairs.:: hfs-pit 4 0 1 hfs-pit 2 1 0 @@ -2466,7 +2420,6 @@ Examples:: lua === - There are the following ways to invoke this command: 1. ``lua`` (without any parameters) @@ -2516,7 +2469,6 @@ or '--all' for all items. quicksave ========= - If called in dwarf mode, makes DF immediately auto-save the game by setting a flag normally used in seasonal auto-save. @@ -2526,13 +2478,11 @@ Sets stress to -1,000,000; the normal range is 0 to 500,000 with very stable or setfps ====== - Run ``setfps `` to set the FPS cap at runtime, in case you want to watch combat in slow motion or something :) siren ===== - Wakes up sleeping units, cancels breaks and stops parties either everywhere, or in the burrows given as arguments. In return, adds bad thoughts about noise, tiredness and lack of protection. Also, the units with interrupted @@ -2541,7 +2491,6 @@ emergencies, e.g. when a siege appears, and all your military is partying. soundsense-season ================= - It is a well known issue that Soundsense cannot detect the correct current season when a savegame is loaded and has to play random season music until a season switch occurs. @@ -2626,8 +2575,18 @@ Undesignates building base materials for dumping. ======== modtools ======== - -These scripts are mostly useful for raw modders and scripters. They all have standard arguments: arguments are of the form ``tool -argName1 argVal1 -argName2 argVal2``. This is equivalent to ``tool -argName2 argVal2 -argName1 argVal1``. It is not necessary to provide a value to an argument name: ``tool -argName3`` is fine. Supplying the same argument name multiple times will result in an error. Argument names are preceded with a dash. The ``-help`` argument will print a descriptive usage string describing the nature of the arguments. For multiple word argument values, brackets must be used: ``tool -argName4 [ sadf1 sadf2 sadf3 ]``. In order to allow passing literal braces as part of the argument, backslashes are used: ``tool -argName4 [ \] asdf \foo ]`` sets ``argName4`` to ``\] asdf foo``. The ``*-trigger`` scripts have a similar policy with backslashes. +These scripts are mostly useful for raw modders and scripters. They all have +standard arguments: arguments are of the form ``tool -argName1 argVal1 +-argName2 argVal2``. This is equivalent to ``tool -argName2 argVal2 -argName1 +argVal1``. It is not necessary to provide a value to an argument name: ``tool +-argName3`` is fine. Supplying the same argument name multiple times will +result in an error. Argument names are preceded with a dash. The ``-help`` +argument will print a descriptive usage string describing the nature of the +arguments. For multiple word argument values, brackets must be used: ``tool +-argName4 [ sadf1 sadf2 sadf3 ]``. In order to allow passing literal braces as +part of the argument, backslashes are used: ``tool -argName4 [ \] asdf \foo ]`` +sets ``argName4`` to ``\] asdf foo``. The ``*-trigger`` scripts have a similar +policy with backslashes. * add-syndrome @@ -2704,7 +2663,6 @@ These scripts are mostly useful for raw modders and scripters. They all have sta ======================= In-game interface tools ======================= - These tools work by displaying dialogs or overlays in the game window, and are mostly implemented by lua scripts. @@ -2722,10 +2680,8 @@ are mostly implemented by lua scripts. All of these tools are disabled by default - in order to make them available, you must enable the plugins which provide them. - Dwarf Manipulator ================= - Implemented by the 'manipulator' plugin. To activate, open the unit screen and press 'l'. @@ -2778,10 +2734,8 @@ The following mouse shortcuts are also available: Pressing ESC normally returns to the unit screen, but Shift-ESC would exit directly to the main dwarf mode screen. - Search ====== - Implemented by the 'search' plugin. The search plugin adds search to the Stocks, Animals, Trading, Stockpile, @@ -2820,10 +2774,8 @@ on items actually shown in the rightmost list, so it is possible to select only fat or tallow by forbidding fats, then searching for fat/tallow, and using Permit Fats again while the list is filtered. - AutoMaterial ============ - Implemented by the 'automaterial' plugin. This makes building constructions (walls, floors, fortifications, etc) a little bit @@ -2871,7 +2823,6 @@ When autotrade is enabled for a stockpile, any items placed in it will be design Track Stop Menu =============== - The `q` menu of track stops is completely blank by default. To enable one:: enable trackstop @@ -2885,7 +2836,6 @@ It re-uses the keybindings from the track stop building interface: gui/advfort =========== - This script allows to perform jobs in adventure mode. For more complete help press '?' while script is running. It's most confortable to use this as a keybinding. (e.g. keybinding set Ctrl-T gui/advfort). Possible arguments: @@ -2909,7 +2859,6 @@ An example of player digging in adventure mode: gui/assign-rack =============== - Bind to a key (the example config uses P), and activate when viewing a weapon rack in the 'q' mode. @@ -2938,7 +2887,6 @@ of currently assigned racks for every valid squad. gui/choose-weapons ================== - Bind to a key (the example config uses Ctrl-W), and activate in the Equip->View/Customize page of the military screen. @@ -2952,7 +2900,6 @@ and may lead to inappropriate weapons being selected. gui/clone-uniform ================= - Bind to a key (the example config uses Ctrl-C), and activate in the Uniforms page of the military screen with the cursor in the leftmost list. @@ -2961,7 +2908,6 @@ and selects the newly created copy. gui/companion-order =================== - A script to issue orders for companions. Select companions with lower case chars, issue orders with upper case. Must be in look or talk mode to issue command on tile. @@ -2978,7 +2924,6 @@ case. Must be in look or talk mode to issue command on tile. gui/gm-editor ============= - There are three ways to open this editor: * using gui/gm-editor command/keybinding - opens editor on what is selected @@ -2997,7 +2942,6 @@ in-game help. Hotkeys ======= - Opens an in-game screen showing DFHack keybindings that are valid in the current mode. .. image:: images/hotkeys.png @@ -3007,19 +2951,6 @@ globally active hotkey in dfhack.init, e.g.:: keybinding add Ctrl-F1 hotkeys -Hotkeys -======= - -Opens an in-game screen showing DFHack keybindings that are valid in the current mode. - -.. image:: images/hotkeys.png - -Type ``hotkeys`` into the DFHack console to open the screen, or bind the command to a -globally active hotkey in dfhack.init, e.g.: - - ``keybinding add Ctrl-F1 hotkeys`` - - Stockpile Automation ==================== Enable the autodump plugin in your dfhack.init with @@ -3028,18 +2959,8 @@ Enable the autodump plugin in your dfhack.init with When querying a stockpile an option will appear to toggle autodump for this stockpile. Any items placed in this stockpile will be designated to be dumped. -Stockpile Automation -==================== -Enable the automelt plugin in your dfhack.init with - ``enable automelt`` - -When querying a stockpile an option will appear to toggle automelt for this stockpile. -Any items placed in this stockpile will be designated to be melted. - - gui/liquids =========== - To use, bind to a key (the example config uses Alt-L) and activate in the 'k' mode. .. image:: images/liquids.png @@ -3066,7 +2987,6 @@ After setting up the desired operations using the described keys, use ``Enter`` gui/mechanisms ============== - To use, bind to a key (the example config uses Ctrl-M) and activate in the 'q' mode. .. image:: images/mechanisms.png @@ -3080,15 +3000,17 @@ re-entering the mechanisms ui. gui/mod-manager =============== +A simple way to install and remove small mods. -A way to simply install and remove small mods. It looks for specially formatted mods in -df subfolder 'mods'. Mods are not included, for example mods see: `github mini mod repository `_ +It looks for specially formatted mods in df subfolder 'mods'. Mods are not +included, but some examples are `available here`_. + +.. _`available here`: https://github.com/warmist/df-mini-mods .. image:: images/mod-manager.png gui/rename ========== - Backed by the rename plugin, this script allows entering the desired name via a simple dialog in the game ui. @@ -3117,7 +3039,6 @@ unit profession change to Ctrl-Shift-T. gui/room-list ============= - To use, bind to a key (the example config uses Alt-R) and activate in the 'q' mode, either immediately or after opening the assign owner page. @@ -3126,10 +3047,8 @@ either immediately or after opening the assign owner page. The script lists other rooms owned by the same owner, or by the unit selected in the assign list, and allows unassigning them. - gui/guide-path ============== - Bind to a key (the example config uses Alt-P), and activate in the Hauling menu with the cursor over a Guide order. @@ -3140,7 +3059,6 @@ computes it when the order is executed for the first time. gui/workflow ============ - Bind to a key (the example config uses Alt-W), and activate with a job selected in a workshop in the 'q' mode. @@ -3202,7 +3120,6 @@ limit (maximum) and the dark green line is that minus the gap (minimum). gui/workshop-job ================ - Bind to a key (the example config uses Alt-A), and activate with a job selected in a workshop in the 'q' mode. @@ -3250,7 +3167,6 @@ you have to unset the material first. ============= Behavior Mods ============= - These plugins, when activated via configuration UI or by detecting certain structures in RAWs, modify the game engine behavior concerning the target objects to add features not otherwise present. @@ -3263,7 +3179,6 @@ objects to add features not otherwise present. Siege Engine ============ - The siege-engine plugin enables siege engines to be linked to stockpiles, and aimed at an arbitrary rectangular area across Z levels, instead of the original four directions. Also, catapults can be ordered to load arbitrary objects, not @@ -3271,7 +3186,6 @@ just stones. Rationale --------- - Siege engines are a very interesting feature, but sadly almost useless in the current state because they haven't been updated since 2D and can only aim in four directions. This is an attempt to bring them more up to date until Toady has time to work on it. Actual improvements, @@ -3279,7 +3193,6 @@ e.g. like making siegers bring their own, are something only Toady can do. Configuration UI ---------------- - The configuration front-end to the plugin is implemented by the gui/siege-engine script. Bind it to a key (the example config uses Alt-A) and activate after selecting a siege engine in 'q' mode. @@ -3306,10 +3219,8 @@ Exiting from the siege engine script via ESC reverts the view to the state prior the script. Shift-ESC retains the current viewport, and also exits from the 'q' mode to main menu. - Power Meter =========== - The power-meter plugin implements a modified pressure plate that detects power being supplied to gear boxes built in the four adjacent N/S/W/E tiles. @@ -3322,16 +3233,13 @@ in the build menu. The script follows the general look and feel of the regular pressure plate build configuration page, but configures parameters relevant to the modded power meter building. - Steam Engine ============ - The steam-engine plugin detects custom workshops with STEAM_ENGINE in their token, and turns them into real steam engines. Rationale --------- - The vanilla game contains only water wheels and windmills as sources of power, but windmills give relatively little power, and water wheels require flowing water, which must either be a real river and thus immovable and @@ -3344,7 +3252,6 @@ in a new way with some glue code and a bit of custom logic. Construction ------------ - The workshop needs water as its input, which it takes via a passable floor tile below it, like usual magma workshops do. The magma version also needs magma. @@ -3370,7 +3277,6 @@ is extracted from the workshop raws. Operation --------- - In order to operate the engine, queue the Stoke Boiler job (optionally on repeat). A furnace operator will come, possibly bringing a bar of fuel, and perform it. As a result, a "boiling water" item will appear @@ -3405,7 +3311,6 @@ use rate by 10%. Explosions ---------- - The engine must be constructed using barrel, pipe and piston from fire-safe, or in the magma version magma-safe metals. @@ -3416,7 +3321,6 @@ tantruming dwarf. Save files ---------- - It should be safe to load and view engine-using fortresses from a DF version without DFHack installed, except that in such case the engines won't work. However actually making modifications @@ -3425,10 +3329,8 @@ can easily result in inconsistent state once this plugin is available again. The effects may be as weird as negative power being generated. - Add Spatter =========== - This plugin makes reactions with names starting with ``SPATTER_ADD_`` produce contaminants on the items instead of improvements. The produced contaminants are immune to being washed away by water or destroyed by @@ -3439,4 +3341,3 @@ be bought from caravans. :) To be really useful this needs patches from bug 808, ``tweak fix-dimensions`` and ``tweak advmode-contained``. - From 7972aa2fbca0a764b26bf28139452655aea39ec0 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 16 Feb 2015 09:56:34 -0500 Subject: [PATCH 18/22] Fix syntax errors in Readme.rst --- Readme.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Readme.rst b/Readme.rst index bab2fc9ad..22b147944 100644 --- a/Readme.rst +++ b/Readme.rst @@ -1866,8 +1866,9 @@ Assigns lifestock for slaughter once it reaches a specific count. Requires that you add the target race(s) to a watch list. Only tame units will be processed. Units will be ignored if they are: + * Nicknamed (for custom protection; you can use the ``rename unit`` tool - individually, or ``zone nick` for groups) + individually, or ``zone nick`` for groups) * Caged, if and only if the cage is defined as a room (to protect zoos) * Trained for war or hunting @@ -3000,7 +3001,7 @@ re-entering the mechanisms ui. gui/mod-manager =============== -A simple way to install and remove small mods. +A simple way to install and remove small mods. It looks for specially formatted mods in df subfolder 'mods'. Mods are not included, but some examples are `available here`_. From d14a8b4308799bba63d27527da756081b63fdb3e Mon Sep 17 00:00:00 2001 From: Lethosor Date: Mon, 16 Feb 2015 13:55:19 -0500 Subject: [PATCH 19/22] Convert TranslateName output to UTF-8 --- scripts/exportlegends.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/exportlegends.lua b/scripts/exportlegends.lua index 9aa83a056..7c8c539fb 100644 --- a/scripts/exportlegends.lua +++ b/scripts/exportlegends.lua @@ -77,8 +77,8 @@ function export_more_legends_xml() io.write ("".."\n") io.write ("".."\n") - io.write (""..dfhack.TranslateName(df.global.world.world_data.name).."".."\n") - io.write (""..dfhack.TranslateName(df.global.world.world_data.name,1).."".."\n") + io.write (""..dfhack.df2utf(dfhack.TranslateName(df.global.world.world_data.name)).."".."\n") + io.write (""..dfhack.df2utf(dfhack.TranslateName(df.global.world.world_data.name,1)).."".."\n") io.write ("".."\n") for regionK, regionV in ipairs(df.global.world.world_data.regions) do @@ -120,8 +120,8 @@ function export_more_legends_xml() io.write ("\t\t\t\t"..""..buildingV.id.."".."\n") io.write ("\t\t\t\t"..""..df.abstract_building_type[buildingV:getType()]:lower().."".."\n") if (df.abstract_building_type[buildingV:getType()]:lower() ~= "underworld_spire") then - io.write ("\t\t\t\t"..""..dfhack.TranslateName(buildingV.name, 1).."".."\n") - io.write ("\t\t\t\t"..""..dfhack.TranslateName(buildingV.name).."".."\n") + io.write ("\t\t\t\t"..""..dfhack.df2utf(dfhack.TranslateName(buildingV.name, 1)).."".."\n") + io.write ("\t\t\t\t"..""..dfhack.df2utf(dfhack.TranslateName(buildingV.name)).."".."\n") end io.write ("\t\t\t".."".."\n") end @@ -137,7 +137,7 @@ function export_more_legends_xml() for wcK, wcV in ipairs(df.global.world.world_data.constructions.list) do io.write ("\t".."".."\n") io.write ("\t\t"..""..wcV.id.."".."\n") - io.write ("\t\t"..""..dfhack.TranslateName(wcV.name,1).."".."\n") + io.write ("\t\t"..""..dfhack.df2utf(dfhack.TranslateName(wcV.name,1)).."".."\n") io.write ("\t\t"..""..(df.world_construction_type[wcV:getType()]):lower().."".."\n") io.write ("\t\t".."") for xK, xVal in ipairs(wcV.square_pos.x) do From b7f15ef2d6fe11e80b99871adedfe2a5ca42e583 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 16 Feb 2015 19:10:15 -0500 Subject: [PATCH 20/22] Update xml, stonesense for 0.40 ui_advmode_menu changes Closes #552 --- library/xml | 2 +- plugins/stonesense | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/xml b/library/xml index e1151e8d6..7ff793882 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit e1151e8d6401c286f1d7df45abbd14562bedc7e9 +Subproject commit 7ff793882032374e8f9819978aa7a29d5236798c diff --git a/plugins/stonesense b/plugins/stonesense index a8c5bd263..9e87d3e8d 160000 --- a/plugins/stonesense +++ b/plugins/stonesense @@ -1 +1 @@ -Subproject commit a8c5bd263306050ac1dc21140ce52719b0dd598b +Subproject commit 9e87d3e8dc2a3b897c92fe2ee8cd57249a262779 From c399377f081e5d000f40294c498e507e058c2fd5 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 16 Feb 2015 20:17:47 -0500 Subject: [PATCH 21/22] Ensure that command usage information always ends with a newline --- library/include/PluginManager.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/include/PluginManager.h b/library/include/PluginManager.h index 663dde90a..3075844da 100644 --- a/library/include/PluginManager.h +++ b/library/include/PluginManager.h @@ -98,6 +98,7 @@ namespace DFHack function(function_), interactive(interactive_), guard(NULL), usage(usage_) { + fix_usage(); } PluginCommand(const char * _name, @@ -109,6 +110,13 @@ namespace DFHack function(function_), interactive(false), guard(guard_), usage(usage_) { + fix_usage(); + } + + void fix_usage() + { + if (usage.size() && usage[usage.size() - 1] != '\n') + usage.push_back('\n'); } bool isHotkeyCommand() const { return guard != NULL; } From 89197bc931c62902d34b08b65694176ae22069a5 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 16 Feb 2015 21:54:22 -0500 Subject: [PATCH 22/22] Use table in Contributors.rst --- Contributors.rst | 163 +++++++++++++++++++++++++---------------------- 1 file changed, 88 insertions(+), 75 deletions(-) diff --git a/Contributors.rst b/Contributors.rst index 6f079f4ed..591b9f173 100644 --- a/Contributors.rst +++ b/Contributors.rst @@ -4,80 +4,93 @@ If you belong here and are missing, please add yourself and send me (peterix) a The following is a list of people who have contributed to **DFHack**. -- Petr Mrázek -- Alexander Gavrilov -- doomchild -- Quietust -- jj -- Warmist -- Robert Heinrich -- simon -- Kelly Martin -- mizipzor -- Simon Jackson -- belal -- RusAnon -- Raoul XQ -- Matthew Cline -- Mike Stewart -- Timothy Collett -- RossM -- Tom Prince -- Jared Adams -- expwnent -- Erik Youngren -- Espen Wiborg -- Tim Walberg -- Mikko Juola -- rampaging-poet -- U-glouglou\\simon -- Clayton Hughes -- zilpin -- Will Rogers -- NMLittle -- root -- reverb -- Zhentar -- Valentin Ochs -- Priit Laes -- kmartin -- Neil Little -- rout -- rofl0r -- harlanplayford -- gsvslto -- sami -- potato -- playfordh -- feng1st -- comestible -- Rumrusher -- Rinin -- Raoul van Putten -- John Shade -- John Beisley -- Feng -- Donald Ruegsegger -- Caldfir -- Antalia -- Angus Mezick -- PeridexisErrant -- Putnam -- Danaris -- Lethosor -- Eswald -- Ramblurr -- MithrilTuxedo -- AndreasPK -- cdombroski +======================= ==================== =========================== +Name Github Email +======================= ==================== =========================== +Petr Mrázek peterix peterix@gmail.com +Alexander Gavrilov angavrilov angavrilov@gmail.com +doomchild doomchild lee.crabtree@gmail.com +Quietust quietust quietust@gmail.com +jj jjyg john-git@ofjj.net +Warmist warmist warmist@gmail.com +Robert Heinrich rh73 robertheinrich73@googlemail.com +simon simon@banquise.net +Kelly Martin ab9rf kelly.lynn.martin@gmail.com +mizipzor mizipzor mizipzor@gmail.com +Simon Jackson sizeak sizeak@hotmail.com +belal jimhester jimbelal@gmail.com +RusAnon RusAnon rusanon@dollchan.ru +Raoul XQ raoulxq raoulxq@gmail.com +Matthew Cline zelgadis@sourceforge.net +Mike Stewart thewonderidiot thewonderidiot@gmail.com +Timothy Collett danaris tcollett+github@topazgryphon.org +RossM Ross@Gnome +Tom Prince tom.prince@ualberta.net +Jared Adams jaxad0127@gmail.com +expwnent expwnent +Erik Youngren Artanis artanis.00@gmail.com +Espen Wiborg espen.wiborg@telio.no +Tim Walberg twalberg twalberg@comcast.net +Mikko Juola Noeda mikko.juola@kolumbus.fi +rampaging-poet yrudoingthis@hotmail.com +U-glouglou\\simon simon@glouglou +Clayton Hughes clayton.hughes@gmail.com +zilpin zilpin ziLpin@gmail.com +Will Rogers wjrogers wjrogers@gmail.com +NMLittle nmlittle nmlittle@gmail.com +root +reverb +Zhentar Zhentar Zhentar@gmail.com +Valentin Ochs Cat-Ion a@0au.de +Priit Laes plaes plaes@plaes.org +kmartin +Neil Little +rout rout.mail+github@gmail.com +rofl0r rofl0r retnyg@gmx.net +harlanplayford playfordh harlanplayford@gmail.com +John Shade gsvslto gsvslto@gmail.com +sami +potato +feng1st nf_xp@hotmail.com +comestible nickrart nickolas.g.russell@gmail.com +Rumrusher rumrusher Anuleakage@yahoo.com +Rinin Rinin RininS@Gmail.com +Raoul van Putten +John Beisley huin greatred@gmail.com +Feng nf_xp@hotmail.com +Donald Ruegsegger hashaash druegsegger@gmail.com +Caldfir caldfir caldfir@hotmail.com +Antalia tamarakorr tamarakorr@gmail.com +Angus Mezick amezick amezick@gmail.com +Japa JapaMala japa.mala.illo@gmail.com +Putnam Putnam3145 +Lethosor lethosor +PeridexisErrant PeridexisErrant PeridexisErrant@gmail.com +Eswald eswald +Ramblurr Ramblurr +MithrilTuxedo MithrilTuxedo +AndreasPK AndreasPK +Chris Dombroski cdombroski +Ben Lubar BenLubar +miffedmap miffedmap +scamtank scamtank +Mason11987 Mason11987 +======================= ==================== =========================== -And those are the cool people who made **stonesense**. +And these are the cool people who made **Stonesense**. -- Kris Parker -- Japa -- Jonas Ask -- Petr Mrázek -- Caldfir -- 8Z -- Alexander Gavrilov -- Timothy Collett +======================= ==================== =========================== +Name Github Email +======================= ==================== =========================== +Kris Parker kaypy +Japa JapaMala japa.mala.illo@gmail.com +Jonas Ask jonask84@gmail.com +Petr Mrázek peterix peterix@gmail.com> +Caldfir caldfir aitken.tim@gmail.com +8Z 8Z git8z@ya.ru +Alexander Gavrilov angavrilov angavrilov@gmail.com +Timothy Collett danaris tcollett+github@topazgryphon.org +Lethosor lethosor +Eswald eswald +PeridexisErrant PeridexisErrant PeridexisErrant@gmail.com +======================= ==================== ===========================