From 27bdc9f2df02ccd566eddc5fe1ffa2a09d7e6143 Mon Sep 17 00:00:00 2001
From: Warmist
Date: Thu, 23 Aug 2012 21:38:38 +0300
Subject: [PATCH 001/158] Start gutting dfusion.
---
plugins/Dfusion/readme.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/plugins/Dfusion/readme.txt b/plugins/Dfusion/readme.txt
index c40ac3707..df3b85b1f 100644
--- a/plugins/Dfusion/readme.txt
+++ b/plugins/Dfusion/readme.txt
@@ -10,3 +10,5 @@ Similar to dfusion but not interactive. To be used with hotkeys (later will have
Also dfuse/dfusion runs an init script located at 'save directory/dfusion/init.lua'. And 'initcustom.lua' if it exists
More info http://dwarffortresswiki.org/index.php/Utility:DFusion
+
+a
\ No newline at end of file
From 90021b4e5e8451e1505f1344b4862a05cbe9711a Mon Sep 17 00:00:00 2001
From: Warmist
Date: Thu, 30 Aug 2012 20:41:10 +0300
Subject: [PATCH 002/158] simple_embark/plugin.lua sanitized
---
plugins/Dfusion/luafiles/init.lua | 11 +++--------
.../Dfusion/luafiles/simple_embark/plugin.lua | 16 ++++++++++++----
plugins/Dfusion/readme.txt | 2 --
3 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/plugins/Dfusion/luafiles/init.lua b/plugins/Dfusion/luafiles/init.lua
index 19f63d603..c8eebcd23 100644
--- a/plugins/Dfusion/luafiles/init.lua
+++ b/plugins/Dfusion/luafiles/init.lua
@@ -1,11 +1,7 @@
-function err(msg) --make local maybe...
- print(msg)
- print(debug.traceback())
-end
function dofile(filename) --safer dofile, with traceback (very usefull)
f,perr=loadfile(filename)
if f~=nil then
- return xpcall(f,err)
+ return safecall(f)
else
print(perr)
end
@@ -13,7 +9,7 @@ end
function dofile_silent(filename) --safer dofile, with traceback, no file not found error
f,perr=loadfile(filename)
if f~=nil then
- return xpcall(f,err)
+ return safecall(f)
else
if(string.sub(perr,1,11)~="cannot open") then --ugly hack
print(perr)
@@ -26,7 +22,6 @@ function loadall(t1) --loads all non interactive plugin parts, so that later the
end
end
function mainmenu(t1)
-
while true do
print("No. Name Desc")
for k,v in pairs(t1) do
@@ -58,7 +53,7 @@ dofile("dfusion/common.lua")
dofile("dfusion/utils.lua")
dofile("dfusion/offsets_misc.lua")
dofile("dfusion/editor.lua")
---dofile("dfusion/xml_struct.lua")
+
unlockDF()
plugins={}
table.insert(plugins,{"simple_embark","A simple embark dwarf count editor"})
diff --git a/plugins/Dfusion/luafiles/simple_embark/plugin.lua b/plugins/Dfusion/luafiles/simple_embark/plugin.lua
index c64aa7e68..f4f594e8d 100644
--- a/plugins/Dfusion/luafiles/simple_embark/plugin.lua
+++ b/plugins/Dfusion/luafiles/simple_embark/plugin.lua
@@ -1,10 +1,18 @@
function simple_embark(num)
-stoff=VersionInfo.getAddress('start_dwarf_count')
-print("Starting dwarves found:"..engine.peekd(stoff))
-engine.poked(stoff,num)
+ local stoff=dfhack.internal.getAddress('start_dwarf_count')
+ print("Starting dwarves found:"..df.reinterpret_cast('int32_t', stoff).value)
+ local tmp_val=df.new('int32_t')
+ local size,pos=tmp_val:sizeof()
+ tmp_val.value=num
+ local ret=dfhack.internal.patchMemory(stoff,tmp_val,size)
+ if ret then
+ print("Success!")
+ else
+ qerror("Failed to patch in number")
+ end
end
if not(FILE) then
-print("Type in new ammount:")
+print("Type in new ammount (more than 6, less than 15000):")
repeat
ans=tonumber(io.read())
if ans==nil or not(ans<=15000 and ans>0) then
diff --git a/plugins/Dfusion/readme.txt b/plugins/Dfusion/readme.txt
index df3b85b1f..c40ac3707 100644
--- a/plugins/Dfusion/readme.txt
+++ b/plugins/Dfusion/readme.txt
@@ -10,5 +10,3 @@ Similar to dfusion but not interactive. To be used with hotkeys (later will have
Also dfuse/dfusion runs an init script located at 'save directory/dfusion/init.lua'. And 'initcustom.lua' if it exists
More info http://dwarffortresswiki.org/index.php/Utility:DFusion
-
-a
\ No newline at end of file
From f8744e2ec259cdb72c77e6095cf2e7e329ba081d Mon Sep 17 00:00:00 2001
From: Warmist
Date: Fri, 31 Aug 2012 23:46:33 +0300
Subject: [PATCH 003/158] Experimental stuff editor (can and will crash DF )
---
scripts/gui/gm-Items.lua | 181 +++++++++++++++++++++++++++++++++++++++
1 file changed, 181 insertions(+)
create mode 100644 scripts/gui/gm-Items.lua
diff --git a/scripts/gui/gm-Items.lua b/scripts/gui/gm-Items.lua
new file mode 100644
index 000000000..82a1da154
--- /dev/null
+++ b/scripts/gui/gm-Items.lua
@@ -0,0 +1,181 @@
+-- Interface powered item editor.
+-- TODO use this: MechanismList = defclass(MechanismList, guidm.MenuOverlay)
+local gui = require 'gui'
+
+if dfhack.gui.getCurFocus() ~= 'item' then
+ qerror("This script requires the item view.")
+end
+
+TextInputDialog = defclass(TextInputDialog, gui.FramedScreen)
+
+function TextInputDialog:init(prompt)
+ self.frame_style=GREY_LINE_FRAME
+ self.frame_title=prompt
+ self.input=""
+ return self
+end
+function TextInputDialog:onRenderBody(dc)
+ dc:seek(1,1):string(self.input, COLOR_WHITE):newline()
+end
+
+local MODE_BROWSE=0
+local MODE_EDIT=1
+local item_screen={
+ frame_style = gui.GREY_LINE_FRAME,
+ frame_title = "GameMaster's editor",
+ stack={},
+ item_count=0,
+ mode=MODE_BROWSE,
+
+ keys={},
+ insertNew=function(self)
+ --[=[local trg=self:currentTarget() -- not sure if possible...
+ if trg.target and trg.target._kind and trg.target._kind=="container" then
+ local thing=df.new('general_ref_contained_itemst')
+ trg.target:insert('#',trg.keys[trg.selected])
+ end]=]
+ end,
+ deleteSelected=function(self)
+ local trg=self:currentTarget()
+ if trg.target and trg.target._kind and trg.target._kind=="container" then
+ trg.target:erase(trg.keys[trg.selected])
+ end
+ end,
+ currentTarget=function(self)
+ return self.stack[#self.stack]
+ end,
+ changeSelected = function (self,delta)
+ local trg=self:currentTarget()
+ if trg.item_count <= 1 then return end
+ trg.selected = 1 + (trg.selected + delta - 1) % trg.item_count
+ end,
+ editSelected = function(self)
+ local trg=self:currentTarget()
+ if trg.target and trg.target._kind and trg.target._kind=="bitfield" then
+ trg.target[trg.keys[trg.selected]]= not trg.target[trg.keys[trg.selected]]
+ else
+ --print(type(trg.target[trg.keys[trg.selected]]),trg.target[trg.keys[trg.selected]]._kind or "")
+ local trg_type=type(trg.target[trg.keys[trg.selected]])
+ if trg_type=='number' or trg_type=='string' then --ugly TODO: add metatable get selected
+ self.mode=MODE_EDIT
+ self.input=tostring(trg.target[trg.keys[trg.selected]])
+ elseif trg_type=='userdata' then
+ self:pushTarget(trg.target[trg.keys[trg.selected]])
+ --local screen = mkinstance(gui.FramedScreen,item_screen):init(trg.target[trg.keys[trg.selected]]) -- does not work
+ --screen:show()
+ else
+ print("Unknow type:"..trg_type)
+ print("Subtype:"..tostring(trg.target[trg.keys[trg.selected]]._kind))
+ end
+ end
+ end,
+ cancelEdit = function(self)
+ self.mode=MODE_BROWSE
+ self.input=""
+ end,
+ commitEdit = function(self)
+ local trg=self:currentTarget()
+ self.mode=MODE_BROWSE
+ if type(trg.target[trg.keys[trg.selected]])=='number' then
+ trg.target[trg.keys[trg.selected]]=tonumber(self.input)
+ elseif type(trg.target[trg.keys[trg.selected]])=='string' then
+ trg.target[trg.keys[trg.selected]]=self.input
+ end
+ end,
+ onRenderBody = function(self, dc)
+ local trg=self:currentTarget()
+ dc:seek(2,1):string(tostring(trg.target), COLOR_RED)
+ local offset=2
+ local page_offset=0
+ local current_item=1
+ local t_col
+ if math.floor(trg.selected / (self.frame_height-offset-2)) >0 then
+ page_offset=math.floor(trg.selected / (self.frame_height-offset-2))*(self.frame_height-offset-2)-1
+ end
+ for k,v in pairs(trg.target) do
+
+ if current_item==trg.selected then
+ t_col=COLOR_LIGHTGREEN
+ else
+ t_col=COLOR_GRAY
+ end
+
+ if current_item-page_offset > 0 then
+ local y_pos=current_item-page_offset+offset
+ dc:seek(2,y_pos):string(tostring(k),t_col)
+
+ if self.mode==MODE_EDIT and current_item==trg.selected then
+ dc:seek(20,y_pos):string(self.input..'_',COLOR_GREEN)
+ else
+ dc:seek(20,y_pos):string(tostring(v),t_col)
+ end
+ end
+ current_item=current_item+1
+ end
+ end,
+
+ onInput = function(self,keys)
+ if self.mode==MODE_BROWSE then
+ if keys.LEAVESCREEN then
+ self:popTarget()
+ elseif keys.CURSOR_UP then
+ self:changeSelected(-1)
+ elseif keys.CURSOR_DOWN then
+ self:changeSelected(1)
+ elseif keys.CURSOR_UP_FAST then
+ self:changeSelected(-10)
+ elseif keys.CURSOR_DOWN_FAST then
+ self:changeSelected(10)
+ elseif keys.SELECT then
+ self:editSelected()
+ elseif keys.CUSTOM_ALT_E then
+ --self:specialEditor()
+ local screen = mkinstance(TextInputDialog):init("Input new coordinates")
+ screen:show()
+ elseif keys.CUSTOM_ALT_I then --insert
+ self:insertNew()
+ elseif keys.CUSTOM_ALT_D then --delete
+ self:deleteSelected()
+ end
+ elseif self.mode==MODE_EDIT then
+ if keys.LEAVESCREEN then
+ self:cancelEdit()
+ elseif keys.SELECT then
+ self:commitEdit()
+ elseif keys._STRING then
+ if keys._STRING==0 then
+ self.input=string.sub(self.input,1,-2)
+ else
+ self.input=self.input.. string.char(keys._STRING)
+ end
+ end
+ end
+ end,
+ pushTarget=function(self,target_to_push)
+ local new_tbl={}
+ new_tbl.target=target_to_push
+ new_tbl.keys={}
+ new_tbl.selected=1
+ for k,v in pairs(target_to_push) do
+ table.insert(new_tbl.keys,k)
+ end
+ new_tbl.item_count=#new_tbl.keys
+ table.insert(self.stack,new_tbl)
+ end,
+ popTarget=function(self)
+ table.remove(self.stack) --removes last element
+ if #self.stack==0 then
+ self:dismiss()
+ end
+ end,
+ init = function(self,item_to_edit)
+ self:pushTarget(item_to_edit)
+ self.frame_width,self.frame_height=dfhack.screen.getWindowSize()
+ return self
+ end
+ }
+
+
+
+local screen = mkinstance(gui.FramedScreen,item_screen):init(dfhack.gui.getCurViewscreen().item)
+screen:show()
\ No newline at end of file
From af155db3beca208cf1f842246db342db09bdc5cc Mon Sep 17 00:00:00 2001
From: Warmist
Date: Sat, 1 Sep 2012 01:22:51 +0300
Subject: [PATCH 004/158] Added whole bunch of editable things (units, jobs,
flows)
---
scripts/gui/gm-Items.lua | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/scripts/gui/gm-Items.lua b/scripts/gui/gm-Items.lua
index 82a1da154..839d3158a 100644
--- a/scripts/gui/gm-Items.lua
+++ b/scripts/gui/gm-Items.lua
@@ -2,8 +2,27 @@
-- TODO use this: MechanismList = defclass(MechanismList, guidm.MenuOverlay)
local gui = require 'gui'
-if dfhack.gui.getCurFocus() ~= 'item' then
- qerror("This script requires the item view.")
+local my_trg
+if dfhack.gui.getCurFocus() == 'item' then
+ my_trg=dfhack.gui.getCurViewscreen().item
+elseif dfhack.gui.getCurFocus() == 'joblist' then
+ local t_screen=dfhack.gui.getCurViewscreen()
+ my_trg=t_screen.jobs[t_screen.cursor_pos]
+elseif dfhack.gui.getCurFocus() == 'createquota' then
+ local t_screen=dfhack.gui.getCurViewscreen()
+ my_trg=t_screen.orders[t_screen.sel_idx]
+elseif dfhack.gui.getCurFocus() == 'dwarfmode/LookAround/Flow' then
+ local t_look=df.global.ui_look_list.items[df.global.ui_look_cursor]
+ my_trg=t_look.flow
+
+elseif dfhack.gui.getSelectedUnit(true) then
+ my_trg=dfhack.gui.getSelectedUnit(true)
+elseif dfhack.gui.getSelectedItem(true) then
+ my_trg=dfhack.gui.getSelectedItem(true)
+elseif dfhack.gui.getSelectedJob(true) then
+ my_trg=dfhack.gui.getSelectedJob(true)
+else
+ qerror("No valid target found")
end
TextInputDialog = defclass(TextInputDialog, gui.FramedScreen)
@@ -177,5 +196,5 @@ local item_screen={
-local screen = mkinstance(gui.FramedScreen,item_screen):init(dfhack.gui.getCurViewscreen().item)
+local screen = mkinstance(gui.FramedScreen,item_screen):init(my_trg)
screen:show()
\ No newline at end of file
From c9c587af9aeae439313f64b23d40a862672726e2 Mon Sep 17 00:00:00 2001
From: Warmist
Date: Sat, 1 Sep 2012 01:27:01 +0300
Subject: [PATCH 005/158] small fix for boolean values
---
scripts/gui/gm-Items.lua | 2 ++
1 file changed, 2 insertions(+)
diff --git a/scripts/gui/gm-Items.lua b/scripts/gui/gm-Items.lua
index 839d3158a..34e744ee2 100644
--- a/scripts/gui/gm-Items.lua
+++ b/scripts/gui/gm-Items.lua
@@ -78,6 +78,8 @@ local item_screen={
if trg_type=='number' or trg_type=='string' then --ugly TODO: add metatable get selected
self.mode=MODE_EDIT
self.input=tostring(trg.target[trg.keys[trg.selected]])
+ elseif trg_type=='boolean' then
+ trg.target[trg.keys[trg.selected]]= not trg.target[trg.keys[trg.selected]]
elseif trg_type=='userdata' then
self:pushTarget(trg.target[trg.keys[trg.selected]])
--local screen = mkinstance(gui.FramedScreen,item_screen):init(trg.target[trg.keys[trg.selected]]) -- does not work
From d784d4bc40e2b0b0d91513a22a3c22f5e042d59c Mon Sep 17 00:00:00 2001
From: Warmist
Date: Sat, 1 Sep 2012 10:05:31 +0300
Subject: [PATCH 006/158] Static code segment search for memscan.lua
---
library/lua/memscan.lua | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/library/lua/memscan.lua b/library/lua/memscan.lua
index 970f821c2..521f7c7e8 100644
--- a/library/lua/memscan.lua
+++ b/library/lua/memscan.lua
@@ -195,6 +195,36 @@ function MemoryArea:delete()
for k,v in pairs(self) do self[k] = nil end
end
+-- Static code segment search
+local function find_code_segment()
+ local code_start, code_end
+
+ for i,mem in ipairs(dfhack.internal.getMemRanges()) do
+ if code_end then
+ if mem.start_addr == code_end and mem.read and not mem.write then
+ code_end = mem.end_addr
+ else
+ break
+ end
+ elseif mem.read and not mem.write
+ and (string.match(mem.name,'/dwarfort%.exe$')
+ or string.match(mem.name,'/Dwarf_Fortress$')
+ or string.match(mem.name,'Dwarf Fortress%.exe'))
+ then
+ code_start = mem.start_addr
+ code_end = mem.end_addr
+ end
+ end
+
+ return code_start,code_end
+end
+
+function get_code_segment()
+ local s, e = find_code_segment()
+ if s and e then
+ return ms.MemoryArea.new(s, e)
+ end
+end
-- Static data segment search
local function find_data_segment()
From 7cabf1b8435779c74ed498745920b8edbbacdd15 Mon Sep 17 00:00:00 2001
From: Warmist
Date: Sat, 1 Sep 2012 10:13:08 +0300
Subject: [PATCH 007/158] Small bug fix
---
library/lua/memscan.lua | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/library/lua/memscan.lua b/library/lua/memscan.lua
index 521f7c7e8..af2fe7435 100644
--- a/library/lua/memscan.lua
+++ b/library/lua/memscan.lua
@@ -222,7 +222,7 @@ end
function get_code_segment()
local s, e = find_code_segment()
if s and e then
- return ms.MemoryArea.new(s, e)
+ return MemoryArea.new(s, e)
end
end
-- Static data segment search
From 532839a4d5fd37fdbd52edd9cf5f7661f8232bdb Mon Sep 17 00:00:00 2001
From: Warmist
Date: Sat, 1 Sep 2012 10:54:45 +0300
Subject: [PATCH 008/158] Embark anywhere ported
---
library/lua/memscan.lua | 13 +++++++++++++
plugins/Dfusion/luafiles/simple_embark/plugin.lua | 2 +-
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/library/lua/memscan.lua b/library/lua/memscan.lua
index af2fe7435..85ed5624a 100644
--- a/library/lua/memscan.lua
+++ b/library/lua/memscan.lua
@@ -225,6 +225,19 @@ function get_code_segment()
return MemoryArea.new(s, e)
end
end
+function get_code_segments()
+ local ret={}
+ for i,mem in ipairs(dfhack.internal.getMemRanges()) do
+ if mem.read and not mem.write
+ and (string.match(mem.name,'/dwarfort%.exe$')
+ or string.match(mem.name,'/Dwarf_Fortress$')
+ or string.match(mem.name,'Dwarf Fortress%.exe'))
+ then
+ table.insert(ret,MemoryArea.new(mem.start_addr,mem.end_addr))
+ end
+ end
+ return ret
+end
-- Static data segment search
local function find_data_segment()
diff --git a/plugins/Dfusion/luafiles/simple_embark/plugin.lua b/plugins/Dfusion/luafiles/simple_embark/plugin.lua
index f4f594e8d..abc3530c2 100644
--- a/plugins/Dfusion/luafiles/simple_embark/plugin.lua
+++ b/plugins/Dfusion/luafiles/simple_embark/plugin.lua
@@ -12,7 +12,7 @@ function simple_embark(num)
end
end
if not(FILE) then
-print("Type in new ammount (more than 6, less than 15000):")
+print("Type in new amount (more than 6, less than 15000):")
repeat
ans=tonumber(io.read())
if ans==nil or not(ans<=15000 and ans>0) then
From 5b60dc296a1e039c0fb0084f63f07a3825ab0ad8 Mon Sep 17 00:00:00 2001
From: Warmist
Date: Sat, 1 Sep 2012 21:53:52 +0300
Subject: [PATCH 009/158] Renamed editor and added example keybinding
---
dfhack.init-example | 3 +++
scripts/gui/{gm-Items.lua => gm-editor.lua} | 0
2 files changed, 3 insertions(+)
rename scripts/gui/{gm-Items.lua => gm-editor.lua} (100%)
diff --git a/dfhack.init-example b/dfhack.init-example
index d3a28b9b0..a9de146c2 100644
--- a/dfhack.init-example
+++ b/dfhack.init-example
@@ -52,6 +52,9 @@ keybinding add Alt-R@dwarfmode/QueryBuilding/Some gui/room-list.work
# interface for the liquids plugin
keybinding add Alt-L@dwarfmode/LookAround gui/liquids
+# interface for universal game master's editor
+keybinding add Alt-Shift-E gui/gm-editor
+
###################
# UI logic tweaks #
###################
diff --git a/scripts/gui/gm-Items.lua b/scripts/gui/gm-editor.lua
similarity index 100%
rename from scripts/gui/gm-Items.lua
rename to scripts/gui/gm-editor.lua
From 2574bb1e3d277627f1855ec78e59c4a4ace5e7dd Mon Sep 17 00:00:00 2001
From: Warmist
Date: Sat, 1 Sep 2012 21:58:01 +0300
Subject: [PATCH 010/158] embark anywhere upgrade.
---
plugins/Dfusion/luafiles/tools/init.lua | 32 +++++++++++++++++++------
1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/plugins/Dfusion/luafiles/tools/init.lua b/plugins/Dfusion/luafiles/tools/init.lua
index e3a4607cf..b9978d020 100644
--- a/plugins/Dfusion/luafiles/tools/init.lua
+++ b/plugins/Dfusion/luafiles/tools/init.lua
@@ -1,3 +1,4 @@
+local ms=require "memscan"
tools={}
tools.menu=MakeMenu()
function tools.setrace(name)
@@ -60,14 +61,31 @@ function tools.GiveSentience(names)
end
end
tools.menu:add("Give Sentience",tools.GiveSentience)
-function tools.embark()
- off=offsets.find(0,0x66, 0x83, 0x7F ,0x1A ,0xFF,0x74,0x04)
- if off~=0 then
- engine.pokeb(off+5,0x90)
- engine.pokeb(off+6,0x90)
- print("Found and patched")
+function embark() --windows only?
+ local seg=ms.get_code_segments()
+ printall(seg)
+ local idx,off
+ for k,v in ipairs(seg) do
+ idx,off=v.uint8_t:find_one{0x66, 0x83, 0x7F ,0x1A ,0xFF,0x74,0x04}
+ if idx then
+ break
+ end
+ end
+
+ if idx then
+ local tmp_val=df.new('uint8_t',2)
+ tmp_val[0]=0x90
+ tmp_val[1]=0x90
+ local size,pos=tmp_val:sizeof()
+ local ret=dfhack.internal.patchMemory(off+5,pos,size*2)
+ if ret then
+ print("Found and patched:",off+5)
+ else
+ print("Patching failed at:",off+5)
+ end
+ tmp_val:delete()
else
- print("not found")
+ qerror("Offset for embark patch not found!")
end
end
tools.menu:add("Embark anywhere",tools.embark)
From 6fc10fc2683e82dc6c0552507f1700214019a514 Mon Sep 17 00:00:00 2001
From: Warmist
Date: Wed, 5 Sep 2012 21:52:54 +0300
Subject: [PATCH 011/158] Fixed embark anywhere to use more sane code segment
search
---
library/lua/memscan.lua | 41 ++++++-------------------
plugins/Dfusion/luafiles/tools/init.lua | 12 ++------
2 files changed, 12 insertions(+), 41 deletions(-)
diff --git a/library/lua/memscan.lua b/library/lua/memscan.lua
index 85ed5624a..ba3efd708 100644
--- a/library/lua/memscan.lua
+++ b/library/lua/memscan.lua
@@ -196,48 +196,25 @@ function MemoryArea:delete()
end
-- Static code segment search
-local function find_code_segment()
- local code_start, code_end
+
+function get_code_segment()
+ local cstart, cend
for i,mem in ipairs(dfhack.internal.getMemRanges()) do
- if code_end then
- if mem.start_addr == code_end and mem.read and not mem.write then
- code_end = mem.end_addr
- else
- break
- end
- elseif mem.read and not mem.write
+ if mem.read and mem.execute
and (string.match(mem.name,'/dwarfort%.exe$')
or string.match(mem.name,'/Dwarf_Fortress$')
or string.match(mem.name,'Dwarf Fortress%.exe'))
then
- code_start = mem.start_addr
- code_end = mem.end_addr
+ cstart = mem.start_addr
+ cend = mem.end_addr
end
end
-
- return code_start,code_end
-end
-
-function get_code_segment()
- local s, e = find_code_segment()
- if s and e then
- return MemoryArea.new(s, e)
+ if cstart and cend then
+ return MemoryArea.new(cstart, cend)
end
end
-function get_code_segments()
- local ret={}
- for i,mem in ipairs(dfhack.internal.getMemRanges()) do
- if mem.read and not mem.write
- and (string.match(mem.name,'/dwarfort%.exe$')
- or string.match(mem.name,'/Dwarf_Fortress$')
- or string.match(mem.name,'Dwarf Fortress%.exe'))
- then
- table.insert(ret,MemoryArea.new(mem.start_addr,mem.end_addr))
- end
- end
- return ret
-end
+
-- Static data segment search
local function find_data_segment()
diff --git a/plugins/Dfusion/luafiles/tools/init.lua b/plugins/Dfusion/luafiles/tools/init.lua
index b9978d020..7052715bc 100644
--- a/plugins/Dfusion/luafiles/tools/init.lua
+++ b/plugins/Dfusion/luafiles/tools/init.lua
@@ -61,17 +61,11 @@ function tools.GiveSentience(names)
end
end
tools.menu:add("Give Sentience",tools.GiveSentience)
-function embark() --windows only?
- local seg=ms.get_code_segments()
- printall(seg)
+function tools.embark() --windows only?
+ local seg=ms.get_code_segment()
local idx,off
- for k,v in ipairs(seg) do
- idx,off=v.uint8_t:find_one{0x66, 0x83, 0x7F ,0x1A ,0xFF,0x74,0x04}
- if idx then
- break
- end
- end
+ idx,off=seg.uint8_t:find_one{0x66, 0x83, 0x7F ,0x1A ,0xFF,0x74,0x04}
if idx then
local tmp_val=df.new('uint8_t',2)
tmp_val[0]=0x90
From 85fc3384dd82f959be5fa0a8bedca995f674c67e Mon Sep 17 00:00:00 2001
From: Warmist
Date: Fri, 7 Sep 2012 17:25:39 +0300
Subject: [PATCH 012/158] Little cleanup and update to gm-editor
---
.../luafiles/patterns/supplementary.xml | 7 ---
.../luafiles/patterns/xml_angavrilov.lua | 55 -------------------
scripts/gui/gm-editor.lua | 24 ++++++--
3 files changed, 19 insertions(+), 67 deletions(-)
delete mode 100644 plugins/Dfusion/luafiles/patterns/supplementary.xml
delete mode 100644 plugins/Dfusion/luafiles/patterns/xml_angavrilov.lua
diff --git a/plugins/Dfusion/luafiles/patterns/supplementary.xml b/plugins/Dfusion/luafiles/patterns/supplementary.xml
deleted file mode 100644
index e341a1368..000000000
--- a/plugins/Dfusion/luafiles/patterns/supplementary.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/patterns/xml_angavrilov.lua b/plugins/Dfusion/luafiles/patterns/xml_angavrilov.lua
deleted file mode 100644
index dbd3ad692..000000000
--- a/plugins/Dfusion/luafiles/patterns/xml_angavrilov.lua
+++ /dev/null
@@ -1,55 +0,0 @@
-
-function parseargs(s)
- local arg = {}
- string.gsub(s, "([%w%-]+)=([\"'])(.-)%2", function (w, _, a)
- arg[w] = a
- end)
- return arg
-end
-
-function collect(s)
- local stack = {}
- local top = {}
- table.insert(stack, top)
- local ni,c,label,xarg, empty
- local i, j = 1, 1
- while true do
- ni,j,c,label,xarg, empty = string.find(s, "<(%/?)([%w:%-]+)(.-)(%/?)>", i)
- if not ni then break end
- local text = string.sub(s, i, ni-1)
- if not string.find(text, "^%s*$") then
- table.insert(top, text)
- end
- if empty == "/" then -- empty element tag
- table.insert(top, {label=label, xarg=parseargs(xarg), empty=1})
- elseif c == "" then -- start tag
- top = {label=label, xarg=parseargs(xarg)}
- table.insert(stack, top) -- new level
- else -- end tag
- local toclose = table.remove(stack) -- remove top
- top = stack[#stack]
- if #stack < 1 then
- error("nothing to close with "..label)
- end
- if toclose.label ~= label then
- error("trying to close "..toclose.label.." with "..label)
- end
- table.insert(top, toclose)
- end
- i = j+1
- end
- local text = string.sub(s, i)
- if not string.find(text, "^%s*$") then
- table.insert(stack[#stack], text)
- end
- if #stack > 1 then
- error("unclosed "..stack[#stack].label)
- end
- return stack[1]
-end
-
-function parseXmlFile(path)
- local f, e = io.open(path, "r")
- local xml = f:read("*a")
- return collect(xml)
-end
\ No newline at end of file
diff --git a/scripts/gui/gm-editor.lua b/scripts/gui/gm-editor.lua
index 34e744ee2..d95cb652b 100644
--- a/scripts/gui/gm-editor.lua
+++ b/scripts/gui/gm-editor.lua
@@ -1,6 +1,7 @@
-- Interface powered item editor.
-- TODO use this: MechanismList = defclass(MechanismList, guidm.MenuOverlay)
local gui = require 'gui'
+local dialog = require 'gui.dialogs'
local my_trg
if dfhack.gui.getCurFocus() == 'item' then
@@ -47,12 +48,25 @@ local item_screen={
mode=MODE_BROWSE,
keys={},
- insertNew=function(self)
- --[=[local trg=self:currentTarget() -- not sure if possible...
+
+ insertNew=function(self,typename)
+ local tp=typename
+ if typename== nil then
+ dialog.showInputPrompt("Class type","Input class type\n:",COLOR_WHITE,"",dfhack.curry(self.insertNew,self))
+ return
+ end
+ local ntype=df[tp]
+ if ntype== nil then
+ dialog.showMessage("Error!","Type '"..tp.." not found",COLOR_RED)
+ return
+ end
+
+ local trg=self:currentTarget()
if trg.target and trg.target._kind and trg.target._kind=="container" then
- local thing=df.new('general_ref_contained_itemst')
- trg.target:insert('#',trg.keys[trg.selected])
- end]=]
+ local thing=ntype:new()
+ dfhack.call_with_finalizer(1,false,df.delete,thing,trg.target.insert,trg.target,'#',thing)
+
+ end
end,
deleteSelected=function(self)
local trg=self:currentTarget()
From 4f9732bfdae5e09ab0f7d3f2825e77e4c76c2dab Mon Sep 17 00:00:00 2001
From: Warmist
Date: Sat, 15 Sep 2012 15:44:15 +0300
Subject: [PATCH 013/158] Useless files removed, small bugfix
---
plugins/Dfusion/luafiles/adv_tools/init.lua | 6 +-
plugins/Dfusion/luafiles/buildingpatterns.lua | 24 -
plugins/Dfusion/luafiles/editor.lua | 150 ----
plugins/Dfusion/luafiles/itempatterns.lua | 62 --
plugins/Dfusion/luafiles/patterns.lua | 248 ------
plugins/Dfusion/luafiles/patterns2.lua | 29 -
plugins/Dfusion/luafiles/xml_struct.lua | 151 ----
plugins/Dfusion/luafiles/xml_types.lua | 734 ------------------
.../Dfusion/luafiles/xml_types_windows.lua | 159 ----
9 files changed, 3 insertions(+), 1560 deletions(-)
delete mode 100644 plugins/Dfusion/luafiles/buildingpatterns.lua
delete mode 100644 plugins/Dfusion/luafiles/editor.lua
delete mode 100644 plugins/Dfusion/luafiles/itempatterns.lua
delete mode 100644 plugins/Dfusion/luafiles/patterns.lua
delete mode 100644 plugins/Dfusion/luafiles/patterns2.lua
delete mode 100644 plugins/Dfusion/luafiles/xml_struct.lua
delete mode 100644 plugins/Dfusion/luafiles/xml_types.lua
delete mode 100644 plugins/Dfusion/luafiles/xml_types_windows.lua
diff --git a/plugins/Dfusion/luafiles/adv_tools/init.lua b/plugins/Dfusion/luafiles/adv_tools/init.lua
index 5504f32bc..566484f01 100644
--- a/plugins/Dfusion/luafiles/adv_tools/init.lua
+++ b/plugins/Dfusion/luafiles/adv_tools/init.lua
@@ -18,7 +18,7 @@ function adv_tools.reincarnate(swap_soul) --only for adventurer i guess
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].hfid==hist_fig.id then
+ if events[i].victim==hist_fig.id then
--print("Is same id:"..i)
trg_hist_fig=events[i].slayer
if trg_hist_fig then
@@ -29,12 +29,12 @@ function adv_tools.reincarnate(swap_soul) --only for adventurer i guess
end
end
if trg_hist_fig ==nil then
- error("Slayer not found")
+ qerror("Slayer not found")
end
local trg_unit=trg_hist_fig.unit_id
if trg_unit==nil then
- error("Unit id not found!")
+ qerror("Unit id not found!")
end
local trg_unit_final=df.unit.find(trg_unit)
diff --git a/plugins/Dfusion/luafiles/buildingpatterns.lua b/plugins/Dfusion/luafiles/buildingpatterns.lua
deleted file mode 100644
index 310c543cb..000000000
--- a/plugins/Dfusion/luafiles/buildingpatterns.lua
+++ /dev/null
@@ -1,24 +0,0 @@
-ptr_building={}
-ptr_building.RTI={off=0,rtype=DWORD}
-ptr_building.xs={off=4,rtype=DWORD}
-ptr_building.ys={off=6,rtype=DWORD}
-ptr_building.zs={off=8,rtype=DWORD}
-ptr_building.xe={off=12,rtype=DWORD}
-ptr_building.ye={off=16,rtype=DWORD}
-ptr_building.ze={off=20,rtype=DWORD}
-ptr_building.flags={off=24,rtype=ptt_dfflag.new(4)}
-ptr_building.materials={off=28,rtype=DWORD}
-ptr_building.builditems={off=228,rtype=ptr_vector}
-function ptr_building.getname(self,RTI)
- if RTI == nil then
- return string.sub(RTTI_GetName(self.RTI),5,-3)
- else
- return string.sub(RTTI_GetName(RTI),5,-3)
- end
-end
-ptr_subbuilding={}
-ptr_subbuilding["building_trapst"]={}
-ptr_subbuilding["building_trapst"].state={off=250,rtype=DWORD} -- atleast lever has this
-ptr_subbuilding["building_doorst"]={}
-ptr_subbuilding["building_doorst"].flg={off=248,rtype=WORD} --maybe flags?
-ptr_subbuilding["building_doorst"].state={off=250,rtype=DWORD}
diff --git a/plugins/Dfusion/luafiles/editor.lua b/plugins/Dfusion/luafiles/editor.lua
deleted file mode 100644
index 06b07ce5e..000000000
--- a/plugins/Dfusion/luafiles/editor.lua
+++ /dev/null
@@ -1,150 +0,0 @@
-function getTypename(object)
- local tbl
- local ret={}
- if getmetatable(object)~=nil then
- local tbl=getmetatable(object)
- for k,v in pairs(xtypes) do
- if v==tbl then
- return k
- end
- end
- for k,v in pairs(xtypes.containers) do
- if v==tbl then
- return k
- end
- end
- end
- if object.name~= nil then
- return object.name
- end
- return "?"
-end
-function getFields(object)
- local tbl
- local ret={}
- if getmetatable(object)==xtypes["struct-type"].wrap then
- tbl=rawget(object,"mtype")
- elseif getmetatable(object)==xtypes["struct-type"] then
- tbl=object
- else
- error("Not an class_type or a class_object")
- end
- for k,v in pairs(tbl.types) do
- table.insert(ret,{k,v[2],getTypename(v[1])})
- --ret[v[2]]=k
- --print(string.format("%s %x",k,v[2]))
- end
- table.sort(ret,function (a,b) return a[2]>b[2] end)
- return ret
-end
-function editField(tbl,field,typename)
- if EditType[typename] ~= nil then
- EditType[typename](tbl[field])
- else
- print("Cur value:"..tostring(tbl[field]))
- val=getline("Enter newvalue:")
- tbl[field]=val
- end
-end
-EditType={}
-EditType["df-flagarray"]=function(trg)
- local fields=rawget(trg,"mtype").index.names
- print("Flag count:"..trg.size)
- print("Name count:"..#fields)
- for i=0,#fields do
- print(string.format("%3d %20s %s",i,fields[i],tostring(trg[i-1])))
- end
- number=getline("enter flag id to flip:")
- number=tonumber(number)
- if number then
- trg[fields[number]]= not trg[fields[number]]
- end
-end
-EditType["enum-type"]=function(trg)
- local fields=rawget(trg,"mtype").names
- local typename=getTypename(rawget(trg,"mtype").etype)
- for k,v in pairs(fields) do
- print(string.format("%3d %s",k,v))
- end
- local cval=trg:get()
- if fields[cval]~= nil then
- print(string.format("Current value:%d (%s)",cval,fields[cval]))
- else
- print(string.format("Current value:%d",cval))
- end
- number=getline("enter new value:")
- number=tonumber(number)
- if number then
- trg:set(number)
- end
-end
-EditType["static-array"]=function(trg)
- local item_type=rawget(trg,"mtype").item_type
- local typename=getTypename(item_type)
- number=getline(string.format("Select item (max %d, item-type '%s'):",trg.size,typename))
- number=tonumber(number)
- if number then
- EditType[typename](trg[number])
- end
-end
-EditType["stl-vector"]=EditType["static-array"]
-EditType["df-array"]=EditType["static-array"]
-EditType["struct-type"]=function(trg)
- local mtype=rawget(trg,"mtype")
- local fields=getFields(trg)
- for k,v in pairs(fields) do
- print(string.format("%4d %25s %s",k,v[1],v[3]))
- end
- number=getline("Choose field to edit:")
- number=tonumber(number)
- if number then
- local v=fields[number]
- editField(trg,v[1],v[3])
- end
-end
-EditType["pointer"]=function(trg)
- local mtype=rawget(trg,"mtype").ptype
- local typename=getTypename(mtype)
- if(trg:tonumber()==0) then
- print("pointer points to nowhere!")
- return
- end
- print("Auto dereferencing pointer! type:"..typename)
- if EditType[typename] ~= nil then
- EditType[typename](trg:deref())
- else
- print("Cur value:"..tostring(trg:deref()))
- val=getline("Enter newvalue:")
- trg:setref(val)
- end
-end
-
-function EditDF()
- local i=1
- local tbl={}
- for k,v in pairs(rawget(df,"types")) do
- print(string.format("%4d %25s %s",i,k,getTypename(v)))
- tbl[i]={k,getTypename(v)}
- i=i+1
- end
- number=dfhack.lineedit("select item to edit (q to quit):")
- if number and tonumber(number) then
- local entry=tbl[tonumber(number)]
- if entry==nil then
- return
- end
- editField(df,entry[1],entry[2])
- --[=[
- if EditType[entry[2]] ~= nil then
- EditType[entry[2]](df[entry[1]])
- else
- print("Cur value:"..tostring(df[entry[1]]))
- val=getline("Enter newvalue:")
- df[entry[1]]=val
- end
- --]=]
- end
-end
-function EditObject(obj)
- EditType[getTypename(obj)](obj)
-end
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/itempatterns.lua b/plugins/Dfusion/luafiles/itempatterns.lua
deleted file mode 100644
index da62c26d2..000000000
--- a/plugins/Dfusion/luafiles/itempatterns.lua
+++ /dev/null
@@ -1,62 +0,0 @@
---dofile("patterns2.lua") moved to common.lua
-ptr_item={}
-ptr_item.RTI={off=0,rtype=DWORD}
-ptr_item.x={off=4,rtype=WORD}
-ptr_item.y={off=6,rtype=WORD}
-ptr_item.z={off=8,rtype=WORD}
-ptr_item.ref={off=0x28,rtype=ptr_vector}
-
-ptr_item.mat={off=0x78,rtype=WORD}
-ptr_item.submat={off=0x7A,rtype=WORD}
-ptr_item.submat2={off=0x7C,rtype=DWORD}
-ptr_item.legendid={off=0x80,rtype=DWORD} -- i don't remember writing this...
-ptr_item.decorations={off=0x90,rtype=ptr_vector}
-ptr_item.flags={off=0xC,rtype=ptt_dfflag.new(8)}
-ptr_item.ptr_covering={off=0x64,rtype=DWORD}
-ptr_item.stack={off=0x58,rtype=WORD}
-function ptr_item.getname(self,RTI)
- if RTI == nil then
- return string.sub(RTTI_GetName(self.RTI),5,-3)
- else
- return string.sub(RTTI_GetName(RTI),5,-3)
- end
-end
-ptr_subitems={}
-ptr_subitems["item_slabst"]={}
-ptr_subitems["item_slabst"].msgptr={off=0xA0,rtype=ptt_dfstring}
-ptr_subitems["item_slabst"].signtype={off=0xC0,rtype=DWORD}
-
-ptr_subitems["item_fisthst"]={}
-ptr_subitems["item_fisthst"].fisthtype={off=0x78,rtype=WORD}
-
-ptr_subitems["item_eggst"]={}
-ptr_subitems["item_eggst"].race={off=0x78,rtype=DWORD}
-ptr_subitems["item_eggst"].isfertile={off=0xa0,rtype=DWORD} --0 or 1
-ptr_subitems["item_eggst"].hatchtime={off=0xa4,rtype=DWORD}
-
-ptr_decoration_gen={}
-ptr_decoration_gen.RTI={off=0,rtype=DWORD}
-ptr_decoration_gen.material={off=0x04,rtype=WORD} -- same for all?
-ptr_decoration_gen.submat={off=0x08,rtype=DWORD}
-function ptr_decoration_gen.getname(self,RTI)
- if RTI == nil then
- return string.sub(RTTI_GetName(self.RTI),21,-5)
- else
- return string.sub(RTTI_GetName(RTI),21,-5)
- end
-end
-ptr_decoration={}
-ptr_decoration["covered"]={}
-ptr_decoration["covered"].material={off=0x04,rtype=WORD}
-ptr_decoration["covered"].submat={off=0x08,rtype=DWORD}
-ptr_decoration["art_image"]={}
-ptr_decoration["art_image"].material={off=0x04,rtype=WORD}
-ptr_decoration["art_image"].submat={off=0x08,rtype=DWORD}
-ptr_decoration["art_image"].image={off=0x24,rtype=DWORD}
-ptr_decoration["bands"]={}
-ptr_decoration["bands"].material={off=0x04,rtype=WORD}
-ptr_decoration["bands"].submat={off=0x08,rtype=DWORD}
-ptr_cover={} --covering of various types (blood, water, etc)
-ptr_cover.mat={off=0,rtype=WORD}
-ptr_cover.submat={off=4,rtype=DWORD}
-ptr_cover.state={off=8,rtype=WORD}
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/patterns.lua b/plugins/Dfusion/luafiles/patterns.lua
deleted file mode 100644
index 34aa0c274..000000000
--- a/plugins/Dfusion/luafiles/patterns.lua
+++ /dev/null
@@ -1,248 +0,0 @@
-ptt_dfstring={}
-if WINDOWS then
- ptt_dfstring.ptr={off=0,rtype=DWORD}
- ptt_dfstring.size={off=16,rtype=DWORD}
- ptt_dfstring.alloc={off=20,rtype=DWORD}
-
- function ptt_dfstring:getval()
- --print(string.format("GETTING FROM:%x",self.__offset))
- if self.size<16 then
- --print(string.format("GETTING FROM:%x",self.__offset))
- return string.sub(engine.peekstr(self.__offset),1,self.size)
- else
- --print(string.format("GETTING FROM:%x",self.ptr))
- return string.sub(engine.peekstr(self.ptr),1,self.size)
- end
- end
- function ptt_dfstring:setval(newstring)
- local offset=self.__offset
- local strl=string.len(newstring)
- if strl<16 then
- --print(string.format("GETTING FROM:%x",self.__offset))
-
- engine.poked(offset+ptt_dfstring.size.off,strl)
- engine.poked(offset+ptt_dfstring.alloc.off,15)
- engine.pokestr(offset,newstring)
-
- else
- local loc
- if engine.peekd(offset+ptt_dfstring.alloc.off) > strl then
- loc=engine.peekd(offset)
- print("Will fit:"..loc.." len:"..strl)
- else
- loc=Allocate(strl+1)
- engine.poked(offset+ptt_dfstring.alloc.off,strl)
- print("Will not fit:"..loc.." len:"..strl)
- end
- --print(string.format("GETTING FROM:%x",self.ptr))
- engine.poked(self.__offset+ptt_dfstring.size.off,strl)
- engine.pokestr(loc,newstring)
- engine.poked(self.__offset,loc)
- end
- end
-else
- --ptt_dfstring.ptr={off=0,rtype=DWORD}
- function ptt_dfstring:getval()
- return engine.peekstr_stl(self.__offset)
- end
-end
---if(COMPATMODE) then
---ptr_vector={}
---ptr_vector.st={off=4,rtype=DWORD}
---ptr_vector.en={off=8,rtype=DWORD}
---else
-ptr_vector={}
-ptr_vector.st={off=0,rtype=DWORD}
-ptr_vector.en={off=4,rtype=DWORD}
-ptr_vector.alloc={off=8,rtype=DWORD}
---end
-function ptr_vector:clone(settype)
- local ret={}
- for k,v in pairs(self) do
- ret[k]=v
- end
- ret.type=settype
- return ret
-end
-function ptr_vector:size()
- return (self.en-self.st)/engine.sizeof(self.type)
-end
-ptr_vector.type=DWORD
-function ptr_vector:getval(num)
- if self.st==0 then return error("Vector empty.") end
- --print("Wants:"..num.." size:"..self:size())
- if num>=self:size() then error("Index out of bounds in vector.") end
- return engine.peek(self.st+engine.sizeof(self.type)*num,self.type)
-end
-function ptr_vector:setval(num,val)
- return engine.poke(self.st+engine.sizeof(self.type)*num,self.type,val)
-end
-function ptr_vector:append(val)
- if self.alloc - self.en > 0 then
- local num=self:size()
- self.en=self.en+engine.sizeof(self.type)
- self:setval(val,num)
- else
- error("larger than allocated arrays not implemented yet")
- local num=self:size()
- local ptr=Allocate(num*2)
-
- end
-end
-ptt_dfflag={}
-function ptt_dfflag.flip(self,num) --flip one bit in flags
- local of=math.floor (num/8);
-
- self[of]=bit.bxor(self[of],bit.lshift(1,num%8))
-end
-
-function ptt_dfflag.get(self,num) -- get one bit in flags
- local of=math.floor (num/8);
-
- if bit.band(self[of],bit.lshift(1,num%8))~=0 then
- return true
- else
- return false
- end
-end
-function ptt_dfflag.set(self,num,val) --set to on or off one bit in flags
- if (self:get(num)~=val) then
- self:flip(num)
- end
-end
-function ptt_dfflag.new(size) -- create new flag pattern of size(in bytes)
- local ret={}
- for i=0,size-1 do
- ret[i]={off=i,rtype=BYTE};
- end
- ret.flip=ptt_dfflag.flip --change to metatable stuff...
- ret.get=ptt_dfflag.get
- ret.set=ptt_dfflag.set
- return ret;
-end
---[[
- Creature:
- 0 name (df_string) 28
- 28 nick (df_string) 56
- 56 surname- namearray(7*dword(4)) 84 ...
- 140 race (dword) 144
- 224 flags
- 264 civ (dword)
- 252 ID
- 592 following ID
- 904 bleed vector? hurt vector or sth...
- 0x790 legends id?
- 2128 known names? or knowledge?
- flags:
- 0 Can the dwarf move or are they waiting for their movement timer
- 1 Dead (might also be set for incoming/leaving critters that are alive)
- 2 Currently in mood
- 3 Had a mood
- 4 "marauder" -- wide class of invader/inside creature attackers
- 5 Drowning
- 6 Active merchant
- 7 "forest" (used for units no longer linked to merchant/diplomacy, they just try to leave mostly)
- 8 Left (left the map)
- 9 Rider
- 10 Incoming
- 11 Diplomat
- 12 Zombie
- 13 Skeleton
- 14 Can swap tiles during movement (prevents multiple swaps)
- 15 On the ground (can be conscious)
- 16 Projectile
- 17 Active invader (for organized ones)
- 18 Hidden in ambush
- 19 Invader origin (could be inactive and fleeing)
- 20 Will flee if invasion turns around
- 21 Active marauder/invader moving inward
- 22 Marauder resident/invader moving in all the way
- 23 Check against flows next time you get a chance
- 24 Ridden
- 25 Caged
- 26 Tame
- 27 Chained
- 28 Royal guard
- 29 Fortress guard
- 30 Suppress wield for beatings/etc
- 31 Is an important historical figure
- 32 swiming
-
-]]--
-ptr_Creature={}
-local posoff=0 --VersionInfo.getGroup("Creatures"):getGroup("creature"):getOffset("position")
-ptr_Creature.x={off=posoff,rtype=WORD} --ok
-ptr_Creature.y={off=posoff+2,rtype=WORD} --ok
-ptr_Creature.z={off=posoff+4,rtype=WORD} --ok
-ptr_Creature.flags={off=0,rtype=ptt_dfflag.new(10)}
-ptr_Creature.name={off=0,rtype=ptt_dfstring}
-ptr_Creature.ID={off=252,rtype=DWORD} --ok i guess
-ptr_Creature.followID={off=592,rtype=DWORD} --ok
-ptr_Creature.race={off=140,rtype=DWORD} --ok
-ptr_Creature.civ={off=264,rtype=DWORD}
-ptr_Creature.legends={off=344,rtype=ptr_vector} --ok
-ptr_Creature.hurt1={off=0x308,rtype=ptr_vector:clone(BYTE)} --byte vector...
-ptr_Creature.hurt2={off=0x338,rtype=ptr_vector}
-ptr_Creature.wounds={off=0x388,rtype=ptr_vector}
-ptr_Creature.itemlist1={off=0x1D0,rtype=ptr_vector}
-ptr_Creature.itemlist2={off=0x288,rtype=ptr_vector}
-ptr_Creature.bloodlvl={off=0x490,rtype=DWORD}
-ptr_Creature.bleedlvl={off=0x494,rtype=DWORD}
-
-ptr_CrGloss={}
-ptr_CrGloss.token={off=0,rtype=ptt_dfstring}
-ptr_CrGloss.castes={off=296,rtype=ptr_vector}
-
-ptr_CrCaste={}
-ptr_CrCaste.name={off=0,rtype=ptt_dfstring}
-ptr_CrCaste.flags_ptr={off=0x5A0,rtype=DWORD} --size 17?
---[=[
- Flags:
- 57 - is sentient (allows setting labours)
---]=]
-ptr_LEntry={} -- all size 256
-ptr_LEntry.name={off=36,rtype=ptt_dfstring}
-ptr_LEntry.id1={off=160,rtype=DWORD}
-ptr_LEntry.id2={off=164,rtype=DWORD}
-ptr_LEntry.somlist={off=220,rtype=DWORD}
-
-ptr_dfname={}
-for i=0,6 do
-ptr_dfname[i]={off=i*4,rtype=DWORD}
-end
---[[
- Site docs:
- 0x38 name struct todo...
- 0x78 type:
- 0 - mountain halls (yours)
- 1 - dark fort
- 2 - cave
- 3 - mountain hall (other)
- 4 - forest
- 5 - hamlet
- 6 - imp location
- 7 - lair
- 8 - fort
- 9 - camp
- 0x7a some sort of id?
- 0x84 some vec (ids)
- 0x94 some other vec (ids)
- 0xa4 some vec (prts)
- 0x118 ptr to sth
-
- 0x14c ptr to mapdata
-]]--
-
-
-ptr_site={}
-ptr_site.type={off=0x78,rtype=WORD}
-ptr_site.id={off=0x7a,rtype=DWORD}
-ptr_site.name={off=0x38,rtype=ptr_dfname}
-ptr_site.flagptr={off=0x118,rtype=DWORD}
-
-ptr_legends2={}
-ptr_legends2.id={off=0,rtype=DWORD}
-ptr_legends2.follow={off=0x18,rtype=DWORD}
-
-ptr_material={}
-ptr_material.token={off=0,rtype=ptt_dfstring}
diff --git a/plugins/Dfusion/luafiles/patterns2.lua b/plugins/Dfusion/luafiles/patterns2.lua
deleted file mode 100644
index 09a3b0db8..000000000
--- a/plugins/Dfusion/luafiles/patterns2.lua
+++ /dev/null
@@ -1,29 +0,0 @@
-ptr_COL={} -- complete object locator...
-ptr_COL.sig={off=0,rtype=DWORD}
-ptr_COL.offset={off=4,rtype=DWORD} --offset of this vtable in the complete class
-ptr_COL.cdoffset={off=8,rtype=DWORD} -- constructor displacement
-ptr_COL.typePointer={off=12,rtype=DWORD}
-ptr_COL.hierarchyPointer={off=16,rtype=DWORD}
-
-ptr_RTTI_Type={}
-ptr_RTTI_Type.vftPointer={off=0,rtype=DWORD}
-ptr_RTTI_Type.name={off=8,rtype=STD_STRING}
-
-function RTTI_GetName(vtable)
- local COLoff=engine.peek(vtable-4,DWORD)
- --print(string.format("Look:%x vtable:%x",vtable,engine.peek(vtable-4,DWORD)))
- COL=engine.peek(COLoff,ptr_COL)
- --print(string.format("COL:%x Typeptr:%x Type:%s",COLoff,COL.typePointer,engine.peek(COL.typePointer,ptr_RTTI_Type.name)))
- return engine.peek(COL.typePointer,ptr_RTTI_Type.name)
-end
-ptr_RTTI_Hierarchy={}
-ptr_RTTI_Hierarchy.sig={off=0,rtype=DWORD}
-ptr_RTTI_Hierarchy.attributes={off=4,rtype=DWORD}
-ptr_RTTI_Hierarchy.numBaseClasses={off=8,rtype=DWORD}
-ptr_RTTI_Hierarchy.ptrBases={off=12,rtype=DWORD}
-
-ptr_RTTI_BaseClass={}
-ptr_RTTI_BaseClass.typePointer={off=0,rtype=DWORD}
-ptr_RTTI_BaseClass.numContained={off=4,rtype=DWORD}
---todo PMD
---todo flags
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/xml_struct.lua b/plugins/Dfusion/luafiles/xml_struct.lua
deleted file mode 100644
index 8d0801be3..000000000
--- a/plugins/Dfusion/luafiles/xml_struct.lua
+++ /dev/null
@@ -1,151 +0,0 @@
-if types ~= nil then
- return
-end
-dofile("dfusion/xml_types.lua")
-
-function parseTree(t)
- for k,v in ipairs(t) do
- if v.xarg~=nil and v.xarg["type-name"]~=nil and v.label=="ld:global-type" then
- local name=v.xarg["type-name"];
- if(types[name]==nil) then
-
- --for kk,vv in pairs(v.xarg) do
- -- print("\t"..kk.." "..tostring(vv))
- --end
- types[name]=makeType(v)
- --print("found "..name.." or type:"..v.xarg.meta or v.xarg.base)
-
- else
- types[name]=makeType(v,types[name])
- end
- end
- end
-end
-function parseTreeGlobals(t)
- local glob={}
- --print("Parsing global-objects")
- for k,v in ipairs(t) do
- if v.xarg~=nil and v.label=="ld:global-object" then
- local name=v.xarg["name"];
- --print("Parsing:"..name)
- local subitem=v[1]
- if subitem==nil then
- error("Global-object subitem is nil:"..name)
- end
- local ret=makeType(subitem)
- if ret==nil then
- error("Make global returned nil!")
- end
- glob[name]=ret
- end
- end
- --print("Printing globals:")
- --for k,v in pairs(glob) do
- -- print(k)
- --end
- return glob
-end
-function findAndParse(tname)
- --if types[tname]==nil then types[tname]={} end
- -- [=[
- for k,v in ipairs(main_tree) do
- local name=v.xarg["type-name"];
- if v.xarg~=nil and v.xarg["type-name"]~=nil and v.label=="ld:global-type" then
-
- if(name ==tname) then
- --print("Parsing:"..name)
- --for kk,vv in pairs(v.xarg) do
- -- print("\t"..kk.." "..tostring(vv))
- --end
- types[name]=makeType(v,types[name])
- end
- --print("found "..name.." or type:"..v.xarg.meta or v.xarg.base)
- end
- end
- --]=]
-end
-df={}
-df.types=rawget(df,"types") or {} --temporary measure for debug
-local df_meta={}
-function df_meta:__index(key)
- local addr=VersionInfo.getAddress(key)
- local vartype=rawget(df,"types")[key];
- if addr==0 then
- error("No such global address exist")
- elseif vartype==nil then
- error("No such global type exist")
- else
- return type_read(vartype,addr)
- end
-end
-function df_meta:__newindex(key,val)
- local addr=VersionInfo.getAddress(key)
- local vartype=rawget(df,"types")[key];
- if addr==0 then
- error("No such global address exist")
- elseif vartype==nil then
- error("No such global type exist")
- else
- return type_write(vartype,addr,val)
- end
-end
-setmetatable(df,df_meta)
---------------------------------
-types=types or {}
-dofile("dfusion/patterns/xml_angavrilov.lua")
--- [=[
-main_tree=parseXmlFile("dfusion/patterns/supplementary.xml")[1]
-parseTree(main_tree)
-main_tree=parseXmlFile("dfusion/patterns/codegen.out.xml")[1]
-parseTree(main_tree)
-rawset(df,"types",parseTreeGlobals(main_tree))
---]=]
---[=[labels={}
-for k,v in ipairs(t) do
- labels[v.label]=labels[v.label] or {meta={}}
- if v.label=="ld:global-type" and v.xarg~=nil and v.xarg.meta ~=nil then
- labels[v.label].meta[v.xarg.meta]=1
- end
-end
-for k,v in pairs(labels) do
- print(k)
- if v.meta~=nil then
- for kk,vv in pairs(v.meta) do
- print("=="..kk)
- end
- end
-end--]=]
-function addressOf(var,key)
- if key== nil then
- local addr=rawget(var,"ptr")
- return addr
- else
- local meta=getmetatable(var)
- if meta== nil then
- error("Failed to get address, no metatable")
- end
- if meta.__address == nil then
- error("Failed to get address, no __address function")
- end
- return meta.__address(var,key)
- end
-end
-function printGlobals()
- print("Globals:")
- for k,v in pairs(rawget(df,"types")) do
- print(k)
- end
-end
-function printFields(object)
- local tbl
- if getmetatable(object)==xtypes["struct-type"].wrap then
- tbl=rawget(object,"mtype")
- elseif getmetatable(object)==xtypes["struct-type"] then
- tbl=object
- else
- error("Not an class_type or a class_object")
- end
- for k,v in pairs(tbl.types) do
- print(string.format("%s %x",k,v[2]))
- end
-end
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/xml_types.lua b/plugins/Dfusion/luafiles/xml_types.lua
deleted file mode 100644
index cced4be2c..000000000
--- a/plugins/Dfusion/luafiles/xml_types.lua
+++ /dev/null
@@ -1,734 +0,0 @@
--- otherwise you just maintain alignment granularity in addition to size for all fields,
--- round up current offset to field alignment,
--- assign structs the max alignment of any field, and round up struct size to its alignment
-function type_read(valtype,address)
- if valtype.issimple then
- --print("Simple read:"..tostring(valtype.ctype))
- return engine.peek(address,valtype.ctype)
- else
- return valtype:makewrap(address)
- end
-end
-function type_write(valtype,address,val)
- if valtype.issimple then
- engine.poke(address,valtype.ctype,val)
- else
- engine.poke(address,DWORD,rawget(val,"ptr"))
- end
-end
-function first_of_type(node,labelname)
- for k,v in ipairs(node) do
- if type(v)=="table" and v.label==labelname then
- return v
- end
- end
-end
-xtypes={} -- list of all types prototypes (e.g. enum-type -> announcement_type)
--- type must have size, new and makewrap (that makes a wrapper around ptr)
-if WINDOWS then
- dofile("dfusion/xml_types_windows.lua")
-elseif LINUX then
- dofile("dfusion/xml_types_linux.lua")
-end
-
-function padAddress(curoff,typetoadd) --return new offset to place things... Maybe linux is different?
- --windows -> sizeof(x)==alignof(x)
- --[=[
-
- if sizetoadd>8 then sizetoadd=8 end
- if(math.mod(curoff,sizetoadd)==0) then
- return curoff
- else
- return curoff+(sizetoadd-math.mod(curoff,sizetoadd))
- end
- --]=]
- if typetoadd==nil or typetoadd.__align==nil then
- return curoff
- else
-
- if(math.mod(curoff,typetoadd.__align)==0) then
- return curoff
- else
- if PRINT_PADS then
- print("padding off:"..curoff.." with align:"..typetoadd.__align.." pad="..(typetoadd.__align-math.mod(curoff,typetoadd.__align)))
- end
- return curoff+(typetoadd.__align-math.mod(curoff,typetoadd.__align))
- end
- end
-end
-
-
-local sarr={}
-sarr.__index=sarr
-function sarr.new(node,obj)
- local o=obj or {}
- setmetatable(o,sarr)
- --print("Making array.")
- o.count=tonumber(node.xarg.count)
- --print("got count:"..o.count)
- o.item_type=makeType(first_of_type(node,"ld:item"))
- o.__align=o.item_type.__align or 4
- o.size=o.count*o.item_type.size
- --print("got subtypesize:"..o.item_type.size)
- return o
-end
-function sarr:makewrap(address)
- local o={}
- o.mtype=self
- o.ptr=address
- setmetatable(o,self.wrap)
- return o
-end
-sarr.wrap={}
-function sarr.wrap:__index(key)
- if key=="size" then
- return rawget(self,"mtype").count
- end
- local num=tonumber(key)
- local mtype=rawget(self,"mtype")
- if num~=nil and num"..v.xarg.meta.." ttype:"..v.label)
- local ttype=makeType(v)
- if ttype.size==0 then error("Field with 0 size! type="..node.xarg["type-name"].."."..name) end
- if ttype.size-math.ceil(ttype.size) ~= 0 then error("Field with real offset! type="..node.xarg["type-name"].."."..name) end
- --for k,v in pairs(ttype) do
- -- print(k..tostring(v))
- --end
-
- local off=padAddress(o.size,ttype)
- --[=[if PRINT_PADS then
-
- if ttype.__align then
- print(name.." "..ttype.__align .. " off:"..off.." "..math.mod(off,ttype.__align))
-
- end
- if off~=o.size then
- print("var:"..name.." size:"..ttype.size)
- end
- end]=]
- --print("var:"..name.." ->"..tostring(off).. " :"..ttype.size)
- if isunion then
- if ttype.size > o.size then
- o.size=ttype.size
- end
- o.types[name]={ttype,0}
- else
- o.size=off
- o.types[name]={ttype,o.size}--+o.baseoffset
- o.size=o.size+ttype.size
- end
- if firsttype== nil then
- firsttype=o.types[name][1]
- end
-
- end
- end
- if isunion then
- o.__align=0
- for k,v in pairs(o.types) do
- if v[1].__align~= nil and v[1].__align>o.__align then
- o.__align=v[1].__align
- end
- end
- else
- if o.base[1]~= nil then
- o.__align=o.base[1].__align
- elseif firsttype~= nil then
- o.__align=firsttype.__align
- --if o.__align~=nil then
- --print("\t\t setting align to:"..(o.__align or ""))
- --else
- --o.__align=4
- --print("\t\t NIL ALIGNMENT!")
- --end
- end
- end
-
- return o
-end
-
-type_class.wrap={}
-function type_class.wrap:__address(key)
- local myptr=rawget(self,"ptr")
- local mytype=rawget(self,"mtype")
- if mytype.types[key] ~= nil then
- return myptr+mytype.types[key][2]
- else
- error("No such field exists")
- end
-end
-function type_class.wrap:__index(key)
- local myptr=rawget(self,"ptr")
- local mytype=rawget(self,"mtype")
- if mytype.types[key] ~= nil then
- return type_read(mytype.types[key][1],myptr+mytype.types[key][2])
- else
- error("No such field exists")
- end
-end
-function type_class.wrap:__newindex(key,value)
- local myptr=rawget(self,"ptr")
- local mytype=rawget(self,"mtype")
- if mytype.types[key] ~= nil then
- return type_write(mytype.types[key][1],myptr+mytype.types[key][2],value)
- else
- error("No such field exists")
- end
-end
-function type_class:makewrap(ptr)
- local o={}
- o.ptr=ptr
- o.mtype=self
- setmetatable(o,self.wrap)
- return o
-end
-xtypes["struct-type"]=type_class
-xtypes["class-type"]=type_class
-local type_pointer={}
-type_pointer.__index=type_pointer
-function type_pointer.new(node,obj)
- local o=obj or {}
- setmetatable(o,type_pointer)
- local subnode=first_of_type(node,"ld:item")
- if subnode~=nil then
- o.ptype=makeType(subnode,nil,true)
- end
-
- o.size=4
- o.__align=4
- return o
-end
-type_pointer.wrap={}
-type_pointer.wrap.__index=type_pointer.wrap
-function type_pointer.wrap:tonumber()
- local myptr=rawget(self,"ptr")
- return engine.peekd(myptr)--type_read(DWORD,myptr)
-end
-function type_pointer.wrap:__setup(trg)
- if trg~= nil then
- self:fromnumber(trg)
- else
- self:fromnumber(0)
- end
-end
-function type_pointer.wrap:fromnumber(num)
- local myptr=rawget(self,"ptr")
- return engine.poked(myptr,num)--type_write(DWORD,myptr,num)
-end
-function type_pointer.wrap:deref()
- local myptr=rawget(self,"ptr")
- local mytype=rawget(self,"mtype")
- return type_read(mytype.ptype,engine.peekd(myptr))
-end
-function type_pointer.wrap:setref(val)
- local myptr=rawget(self,"ptr")
- local mytype=rawget(self,"mtype")
- return type_write(mytype.ptype,engine.peekd(myptr),val)
-end
-function type_pointer.wrap:newref(val)
- local myptr=rawget(self,"ptr")
- local mytype=rawget(self,"mtype")
- local ptr=engine.alloc(mytype.ptype.size)
- self:fromnumber(ptr)
- return ptr
-end
-function type_pointer:makewrap(ptr)
- local o={}
- o.ptr=ptr
- o.mtype=self
- setmetatable(o,self.wrap)
- return o
-end
-xtypes["pointer"]=type_pointer
---------------------------------------------
---stl-vector (beginptr,endptr,allocptr)
---df-flagarray (ptr,size)
-xtypes.containers=xtypes.containers or {}
-local dfarr={}
-dfarr.__index=dfarr
-function dfarr.new(node,obj)
- local o=obj or {}
- setmetatable(o,dfarr)
- o.size=8
- o.__align=4
- o.item_type=makeType(first_of_type(node,"ld:item"))
- return o
-end
-function dfarr:makewrap(address)
- local o={}
- o.mtype=self
- o.ptr=address
- setmetatable(o,self.wrap)
- return o
-end
-dfarr.wrap={}
-function dfarr.wrap:__setup(size)
- local mtype=rawget(self,"mtype")
- engine.pokew(rawget(self,"ptr")+4,size)
- local newptr=engine.alloc(size*mtype.item_type.size)
- engine.poked(rawget(self,"ptr"),newptr)
-end
-function dfarr.wrap:__index(key)
- local num=tonumber(key)
- local mtype=rawget(self,"mtype")
- local size=engine.peekw(rawget(self,"ptr")+4)
- if key=="size" then
- return size
- end
- local item_start=engine.peekd(rawget(self,"ptr"))
- if num~=nil and num"..tostring(v))
- end
- error("Node parser not found: "..label)
- end
- --[=[
- if getSimpleType(node)~=nil then
- return getSimpleType(node)
- end
- print("Trying to make:"..node.xarg.meta)
- if xtypes[node.xarg.meta]~=nil then
- return xtypes[node.xarg.meta].new(node,obj)
- end
-
- if node.xarg.meta=="global" then
- --print(node.xarg["type-name"])
-
- if types[node.xarg["type-name"]]== nil then
- error("type:"..node.xarg["type-name"].." should already be ready")
- end
- return types[node.xarg["type-name"]]
- end
- ]=]
- --[=[for k,v in pairs(node) do
- print(k.."=>"..tostring(v))
- if type(v)=="table" then
- for kk,vv in pairs(v) do
- print("\t"..kk.."=>"..tostring(vv))
- end
- end
- end]=]
-
-end
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/xml_types_windows.lua b/plugins/Dfusion/luafiles/xml_types_windows.lua
deleted file mode 100644
index 90bc80312..000000000
--- a/plugins/Dfusion/luafiles/xml_types_windows.lua
+++ /dev/null
@@ -1,159 +0,0 @@
-xtypes.containers=xtypes.containers or {}
-local stl_vec={}
---[=[
- (make-instance 'pointer :name $start)
- (make-instance 'pointer :name $end)
- (make-instance 'pointer :name $block-end)
- (make-instance 'padding :name $pad :size 4 :alignment 4)
---]=]
-stl_vec.__index=stl_vec
-
-function stl_vec.new(node,obj)
- local o=obj or {}
-
- o.size=16
- o.__align=4
- local titem=first_of_type(node,"ld:item")
- if titem~=nil then
- o.item_type=makeType(titem)
- else
- o.item_type=getSimpleType("uint32_t")
- end
- setmetatable(o,stl_vec)
- return o
-end
-function stl_vec:makewrap(address)
- local o=obj or {}
- o.mtype=self
- o.ptr=address
- setmetatable(o,self.wrap)
- return o
-end
-stl_vec.wrap={}
-function stl_vec.wrap:__index(key)
- local num=tonumber(key)
- local mtype=rawget(self,"mtype")
- local ptr=rawget(self,"ptr")
- local p_begin=engine.peek(ptr,DWORD)
- local p_end=engine.peek(ptr+4,DWORD)
- local size=(p_end-p_begin)/mtype.item_type.size
- if key=="size" then
- return size
- end
-
- --allocend=type_read(ptr+8,DWORD)
- if num~=nil and num
Date: Sat, 15 Sep 2012 18:05:53 +0300
Subject: [PATCH 014/158] Removed unused triggers folder
---
plugins/Dfusion/luafiles/triggers/compile.bat | 1 -
.../Dfusion/luafiles/triggers/functions.lua | 20 ----
.../luafiles/triggers/functions_menu.lua | 12 --
plugins/Dfusion/luafiles/triggers/plugin.lua | 107 ------------------
.../Dfusion/luafiles/triggers/triggers.asm | 68 -----------
plugins/Dfusion/luafiles/triggers/triggers.o | Bin 720 -> 0 bytes
.../luafiles/triggers/universalfunc.asm | 14 ---
7 files changed, 222 deletions(-)
delete mode 100644 plugins/Dfusion/luafiles/triggers/compile.bat
delete mode 100644 plugins/Dfusion/luafiles/triggers/functions.lua
delete mode 100644 plugins/Dfusion/luafiles/triggers/functions_menu.lua
delete mode 100644 plugins/Dfusion/luafiles/triggers/plugin.lua
delete mode 100644 plugins/Dfusion/luafiles/triggers/triggers.asm
delete mode 100644 plugins/Dfusion/luafiles/triggers/triggers.o
delete mode 100644 plugins/Dfusion/luafiles/triggers/universalfunc.asm
diff --git a/plugins/Dfusion/luafiles/triggers/compile.bat b/plugins/Dfusion/luafiles/triggers/compile.bat
deleted file mode 100644
index 3b0fec1a2..000000000
--- a/plugins/Dfusion/luafiles/triggers/compile.bat
+++ /dev/null
@@ -1 +0,0 @@
-as -anl --32 -o triggers.o triggers.asm
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/triggers/functions.lua b/plugins/Dfusion/luafiles/triggers/functions.lua
deleted file mode 100644
index e6c3a62c9..000000000
--- a/plugins/Dfusion/luafiles/triggers/functions.lua
+++ /dev/null
@@ -1,20 +0,0 @@
-function func.Find_Print()
- pos=offsets.find(offsets.base(),0x73,0x02,0x8b,0xce,0x53,0x6a,0x01,0x6a,0x06,CALL) -- a hack for now...
- return engine.peekd(pos+10)+pos+14-offsets.base()
-end
-function func.PrintMessage(msg,color1,color2)
- func.f_print_pos= func.f_print_pos or func.Find_Print()
- print(string.format("Print @:%x",func.f_print_pos))
- debuger.suspend()
- d=NewCallTable() -- make a call table
- t=Allocate(string.len(msg))
- engine.pokestr(t,msg)
- --print(string.format("Message location:%x",t))
- d["ECX"]=t --set ecx to message location
- d["STACK5"]=color1 -- push to stack color1
- d["STACK4"]=color2 -- push to stack color2
- d["STACK3"]=0 -- this is usually 0 maybe a struct pointing to location of this message?
- PushFunction(func.f_print_pos+offsets.base(),d) -- prep to call function
- -- was 0x27F030
- debuger.resume()
-end
diff --git a/plugins/Dfusion/luafiles/triggers/functions_menu.lua b/plugins/Dfusion/luafiles/triggers/functions_menu.lua
deleted file mode 100644
index 3256c6117..000000000
--- a/plugins/Dfusion/luafiles/triggers/functions_menu.lua
+++ /dev/null
@@ -1,12 +0,0 @@
-func={}
-dofile("dfusion/triggers/functions.lua")
-func.menu=MakeMenu()
-function func.PrintMessage_()
- print("Type a message:")
- msg=io.stdin:read()
- func.PrintMessage(msg,6,1)
-end
-if not(FILE) then -- if not in script mode
- func.menu:add("Print message",func.PrintMessage_)
- func.menu:display()
-end
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/triggers/plugin.lua b/plugins/Dfusion/luafiles/triggers/plugin.lua
deleted file mode 100644
index e8f31eac1..000000000
--- a/plugins/Dfusion/luafiles/triggers/plugin.lua
+++ /dev/null
@@ -1,107 +0,0 @@
-if FILE then
- return
-end
-callinfo={}
-callinfo.regs={}
-callinfo.regs["EAX"]=0
-callinfo.regs["EBX"]=1
-callinfo.regs["ECX"]=2
-callinfo.regs["EDX"]=3
-callinfo.regs["ESI"]=4
-callinfo.regs["EDI"]=5
-callinfo.regs["STACK1"]=6
-callinfo.regs["STACK2"]=7
-callinfo.regs["STACK3"]=8
-callinfo.regs["STACK4"]=9
-callinfo.regs["STACK5"]=10
-
-mypos=engine.getmod("triggers_main")
-
-function GetCount()
- return engine.peek(0,triggers.count)
-end
-function SetCount(val)
- engine.poke(0,triggers.count,val)
-end
-function NewCallTable(tbl)
- ret=tbl or {}
- for k,v in pairs(callinfo.regs) do
- ret[k]=0
- end
- return ret
-end
-function PushFunction(off,data)
- local i=GetCount()
- engine.poked(triggers.table.off+i*44,off) -- add function to table
- engine.poked(triggers.data.off+0,data["EAX"]) --set register data...
- engine.poked(triggers.data.off+4,data["EBX"])
- engine.poked(triggers.data.off+8,data["ECX"])
- engine.poked(triggers.data.off+12,data["EDX"])
- engine.poked(triggers.data.off+16,data["ESI"])
- engine.poked(triggers.data.off+20,data["EDI"])
- engine.poked(triggers.data.off+24,data["STACK1"])
- engine.poked(triggers.data.off+28,data["STACK2"])
- engine.poked(triggers.data.off+32,data["STACK3"])
- engine.poked(triggers.data.off+36,data["STACK4"])
- engine.poked(triggers.data.off+40,data["STACK5"])
- SetCount(i+1)
-end
-function loadTriggers()
- if triggers then return end
- triggers={}
- p=engine.getmod("triggerdata")
- triggers.count={off=engine.peekd(p),rtype=DWORD}
- triggers.table={off=engine.peekd(p+4),rtype=DWORD}
- triggers.ret={off=engine.peekd(p+8),rtype=DWORD}
- triggers.data={off=engine.peekd(p+12),rtype=DWORD}
-end
-if mypos then
- loadTriggers()
- dofile("dfusion/triggers/functions_menu.lua")
- --return
-else
- triggers={}
-
- off=0x56D345+offsets.base()
- print(string.format("Function start %x",off))
- ModData=engine.installMod("dfusion/triggers/triggers.o","triggers_main")
- print("installed")
- modpos=ModData.pos
- modsize=ModData.size
- fdata=engine.newmod("function_body",256)
-
-
- engine.poked(modpos+engine.FindMarker(ModData,"trigercount"),modpos+modsize) -- count of functions
- engine.poked(modpos+engine.FindMarker(ModData,"f_loc"),modpos+modsize+4) -- function table start
- engine.poked(modpos+engine.FindMarker(ModData,"f_data"),fdata) -- function data start
-
- engine.poked(modpos+engine.FindMarker(ModData,"saveplace31"),modpos+modsize+260) -- save function loc
- engine.poked(modpos+engine.FindMarker(ModData,"saveplace32"),modpos+modsize+260) -- save function loc
- engine.poked(modpos+engine.FindMarker(ModData,"saveplace33"),modpos+modsize+260) -- save function loc
- engine.poked(modpos+engine.FindMarker(ModData,"saveplace"),modpos+modsize+256) -- save function loc
- engine.poked(modpos+engine.FindMarker(ModData,"trigcount2"),modpos+modsize) -- count of functions (for zeroing)
- engine.poked(modpos+engine.FindMarker(ModData,"saveplace2"),modpos+modsize+256) -- save function loc
- engine.poked(modpos+engine.FindMarker(ModData,"results"),modpos+modsize+256) --overwrite function call with results
-
- triggers.count={off=modpos+modsize,rtype=DWORD}
- triggers.table={off=modpos+modsize+4,rtype=DWORD}
- triggers.ret={off=modpos+modsize+256,rtype=DWORD}
- triggers.data={off=fdata,rtype=DWORD}
- pp=Allocate(4*4)
- engine.poked(pp,triggers.count.off)
- engine.poked(pp+4,triggers.table.off)
- engine.poked(pp+8,triggers.ret.off)
- engine.poked(pp+12,triggers.data.off)
- engine.newmod("triggerdata",0,pp)
- function pokeCall(off)
- engine.pokeb(off,0xe8)
- --b=engine.peekb(off+1)
- engine.poked(off+1,modpos-off-5)
- --engine.pokeb(off+5,b)
- end
- print(string.format("Mod @:%x",modpos))
- dat=engine.peekarb(off,5)
- engine.pokearb(modpos,dat,5)
- pokeCall(off)
-end
-
diff --git a/plugins/Dfusion/luafiles/triggers/triggers.asm b/plugins/Dfusion/luafiles/triggers/triggers.asm
deleted file mode 100644
index 58b9e5f61..000000000
--- a/plugins/Dfusion/luafiles/triggers/triggers.asm
+++ /dev/null
@@ -1,68 +0,0 @@
-.intel_syntax
-nop #5 nops for instruction thats replaced by call
-nop
-nop
-nop
-nop
-pushad
-pushfd
-saveplace31:
-mov [0xDEADBEEF], esp
-trigercount:
-mov eax, [0xDEADBEEF] #mov count of triggers.
-f_loc:
-mov esi, 0xdeadbeef #mov location of functions.
-f_data:
-mov ebx, 0xDEADBEEF #mov a start of function data
-test eax,eax
-jz lend
-lstart:
-dec eax
-push ebx
-push eax
-
-mov eax,[esi+eax*4]
-saveplace:
-mov [0xDEADBEEF],eax #save function for later
-pop eax
-push eax
-mov edx,44
-mul edx
-add eax,ebx
-#stack preparation
-mov ebx,[eax+24]
-push ebx
-mov ebx,[eax+28]
-push ebx
-mov ebx,[eax+32]
-push ebx
-mov ebx,[eax+36]
-push ebx
-mov ebx,[eax+40]
-push ebx
-mov ebx,[eax+4]
-mov ecx,[eax+8]
-mov edx,[eax+12]
-mov esi,[eax+16]
-mov edi,[eax+20]
-mov eax,[eax]
-saveplace2:
-call [0xdeadbeef] #same save loc
-results:
-mov [0xDEADBEEF],eax #get result
-saveplace33:
-mov esp, [0xDEADBEEF]
-add esp, -8
-pop eax
-pop ebx
-cmp eax,0
-jnz lstart
-lend:
-xor eax,eax
-trigcount2:
-mov dword ptr [0xDEADBEEF], eax # zero triggers
-saveplace32:
-mov esp, [0xDEADBEEF]
-popfd
-popad
-ret
diff --git a/plugins/Dfusion/luafiles/triggers/triggers.o b/plugins/Dfusion/luafiles/triggers/triggers.o
deleted file mode 100644
index 5a47daa69bb4ac4f86773a23f66d5a73c8b6d7b0..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 720
zcmeZaWM%*X5k?>evsfARN>VFIz-$Q70i=46_#mbNgF%8`N@7VOnm9Vwfx+N_UQ%%}
zx;Q$&0jO>Q2qetuRDHj1?Y)H{Vjqau4I)|(l!SQ%2XwQvEe3HT0(R*DjrjhE@kV!q
zL~wV63=k^-u?i4t05MCq2S;}RPj`VpcZEnd!+%kbF0j^au<^}Dendn!|6nLxWq1Hd
zcy8k12@~|vGILU)4*d6@fgznSEioG=faGu%Ae$YCfkDT>1{N0plDu${wD_F-WFSun
zNdyvP;&73i)VvfRhoKB1Qe2W)1Pp!!xCoHJAOpl|C?X(UG+d-8wYW5=q?iE|9|-pt
z0(ogDBDO$Y1&W9VkXH*AL5_QnIn0c0KoS)o$2${HiW#I34IsxkD1~8D69N=3PAp3;
n$Vp62H8x}@DauSwElSQW%_~8OBUnZVrm-
Date: Sun, 16 Sep 2012 13:20:55 +0300
Subject: [PATCH 015/158] More useless stuff removed
---
plugins/Dfusion/luafiles/items/plugin.lua | 212 ----------------------
plugins/Dfusion/luafiles/tools/init.lua | 2 +
2 files changed, 2 insertions(+), 212 deletions(-)
delete mode 100644 plugins/Dfusion/luafiles/items/plugin.lua
diff --git a/plugins/Dfusion/luafiles/items/plugin.lua b/plugins/Dfusion/luafiles/items/plugin.lua
deleted file mode 100644
index 8b92785bd..000000000
--- a/plugins/Dfusion/luafiles/items/plugin.lua
+++ /dev/null
@@ -1,212 +0,0 @@
-items={} --> first lets make a menu table
-items.menu=MakeMenu()
-
-
-function items.dest()
- myoff=offsets.getEx("Items") -- first find out where "item vector" is
- vector=engine.peek(myoff,ptr_vector) -- get list of items
- for i=0,vector:size()-1 do --look at each item
- flg=engine.peek(vector:getval(i),ptr_item.flags)
- flg:set(17,1)
- engine.poke(vector:getval(i),ptr_item.flags,flg)
- end
-end
-function items.eggs()
- myoff=offsets.getEx("Items") -- first find out where "item vector" is
- vector=engine.peek(myoff,ptr_vector) -- get list of items
- for i=0,vector:size()-1 do --look at each item
- rti=engine.peek(vector:getval(i),ptr_item.RTI)
- if ptr_item.getname(nil,rti)=="item_eggst" then
- egg=engine.peek(vector:getval(i),ptr_subitems["item_eggst"])
- egg.isfertile=1
- egg.hatchtime=0xffffff
- --egg.race=123 -- change race for fun times
- engine.poke(vector:getval(i),ptr_subitems["item_eggst"],egg)
- end
- end
-end
-function editFlags(offset)
- while true do
- flags=engine.peek(offset,ptr_item.flags)
- for i=0,8*8-1 do
- if flags:get(i) then
- print(i.." is true")
- else
- print(i.." is false")
- end
- end
- print(" enter number to switch flag or not a number to quit:")
- q=tonumber(io.stdin:read())
- if q==nil then return end
- flags:flip(q)
- engine.poke(offset,ptr_item.flags,flags)
- end
-end
-function editCovering(offset)
- off=engine.peek(offset,ptr_item.ptr_covering)
- if off == 0 then
- print("No coverings found.")
- end
- vec=engine.peek(off,ptr_vector)
- print("Covering list:")
- for i=0,vec:size()-1 do
- cov=engine.peek(vec:getval(i),ptr_cover)
- print(string.format("%d. mat=%d submat=%d state=%d",i,cov.mat,cov.submat,cov.state))
- end
- print("To edit type number:")
- q=tonumber(io.stdin:read())
- if q==nil then return end
- if q>=vec:size() or q<0 then return end
- off=vec:getval(q)
- cov=engine.peek(off,ptr_cover)
- print("Enter mat:")
- q=tonumber(io.stdin:read())
- if q==nil then q=0xffff end
- print("Enter submat:")
- v=tonumber(io.stdin:read())
- if v==nil then v=0xffff end
- print("Enter state:")
- y=tonumber(io.stdin:read())
- if y==nil then y=0 end
- cov.mat=q
- cov.submat=v
- cov.state=y
- engine.poke(off,ptr_cover,cov)
-end
-function editMaterial(offset)
- print("Mat id 0 to 18 is in normal materials (inorganic, amber etc...) after that creature mat (with submat2 being race)")
- print("from 219 with submat2=0xffffffff (type not a number) it reads legends id, from 419 submat2 means plant id")
- print("Probably submat is not used :? ")
- mat=engine.peek(offset,ptr_item.mat)
- submat=engine.peek(offset,ptr_item.submat)
- submat2=engine.peek(offset,ptr_item.submat2)
- lid=engine.peek(offset,ptr_item.legendid)
- print(string.format("Now is mat=%d, submat=%d submat2=%d legend id=%d",mat,submat,submat2,lid))
- print("Enter mat:")
- q=tonumber(io.stdin:read())
- if q==nil then return end
- print("Enter submat:")
- v=tonumber(io.stdin:read())
- if v==nil then v=0xffff end
- print("Enter submat2:")
- z=tonumber(io.stdin:read())
- if z==nil then z=0xffffffff end
- print("Enter legendid:")
- y=tonumber(io.stdin:read())
- if y==nil then y=0xffffffff end
- engine.poke(offset,ptr_item.mat,q)
- engine.poke(offset,ptr_item.submat,v)
- engine.poke(offset,ptr_item.legendid,y)
- engine.poke(offset,ptr_item.submat2,z)
- print("Done")
-end
-function items.select()
- myoff=offsets.getEx("Items")
- vector=engine.peek(myoff,ptr_vector)
- tx,ty,tz=getxyz()
- T={}
- for i=0,vector:size()-1 do --this finds all item offsets that are on pointer
- itoff=vector:getval(i)
- x=engine.peek(itoff,ptr_item.x)
- y=engine.peek(itoff,ptr_item.y)
- z=engine.peek(itoff,ptr_item.z)
- if x==tx and y==ty and z==tz then
- table.insert(T,itoff)
- end
- end
- print("Items under cursor:")
- i=1
- for _,v in pairs(T) do
- RTI=engine.peek(v,ptr_item.RTI)
- print(i..". "..ptr_item.getname(nil,RTI))
- i=i+1
- end
- print("Type number to edit or 'q' to exit")
- while true do
- q=io.stdin:read()
- if q=='q' then return end
- if tonumber(q) ~=nil and tonumber(q)
Date: Sun, 23 Sep 2012 23:22:14 +0300
Subject: [PATCH 016/158] gm-editor fixes and improvements
---
scripts/gui/gm-editor.lua | 341 +++++++++++++++++++-------------------
1 file changed, 172 insertions(+), 169 deletions(-)
diff --git a/scripts/gui/gm-editor.lua b/scripts/gui/gm-editor.lua
index d95cb652b..44345b3e8 100644
--- a/scripts/gui/gm-editor.lua
+++ b/scripts/gui/gm-editor.lua
@@ -1,5 +1,4 @@
-- Interface powered item editor.
--- TODO use this: MechanismList = defclass(MechanismList, guidm.MenuOverlay)
local gui = require 'gui'
local dialog = require 'gui.dialogs'
@@ -40,177 +39,181 @@ end
local MODE_BROWSE=0
local MODE_EDIT=1
-local item_screen={
+GmEditorUi = defclass(GmEditorUi, gui.FramedScreen)
+GmEditorUi.ATTRS={
frame_style = gui.GREY_LINE_FRAME,
frame_title = "GameMaster's editor",
- stack={},
- item_count=0,
- mode=MODE_BROWSE,
-
- keys={},
-
- insertNew=function(self,typename)
- local tp=typename
- if typename== nil then
- dialog.showInputPrompt("Class type","Input class type\n:",COLOR_WHITE,"",dfhack.curry(self.insertNew,self))
- return
- end
- local ntype=df[tp]
- if ntype== nil then
- dialog.showMessage("Error!","Type '"..tp.." not found",COLOR_RED)
- return
- end
-
- 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,trg.target.insert,trg.target,'#',thing)
-
- end
- end,
- deleteSelected=function(self)
- local trg=self:currentTarget()
- if trg.target and trg.target._kind and trg.target._kind=="container" then
- trg.target:erase(trg.keys[trg.selected])
- end
- end,
- currentTarget=function(self)
- return self.stack[#self.stack]
- end,
- changeSelected = function (self,delta)
- local trg=self:currentTarget()
- if trg.item_count <= 1 then return end
- trg.selected = 1 + (trg.selected + delta - 1) % trg.item_count
- end,
- editSelected = function(self)
- local trg=self:currentTarget()
- if trg.target and trg.target._kind and trg.target._kind=="bitfield" then
- trg.target[trg.keys[trg.selected]]= not trg.target[trg.keys[trg.selected]]
- else
- --print(type(trg.target[trg.keys[trg.selected]]),trg.target[trg.keys[trg.selected]]._kind or "")
- local trg_type=type(trg.target[trg.keys[trg.selected]])
- if trg_type=='number' or trg_type=='string' then --ugly TODO: add metatable get selected
- self.mode=MODE_EDIT
- self.input=tostring(trg.target[trg.keys[trg.selected]])
- elseif trg_type=='boolean' then
- trg.target[trg.keys[trg.selected]]= not trg.target[trg.keys[trg.selected]]
- elseif trg_type=='userdata' then
- self:pushTarget(trg.target[trg.keys[trg.selected]])
- --local screen = mkinstance(gui.FramedScreen,item_screen):init(trg.target[trg.keys[trg.selected]]) -- does not work
- --screen:show()
- else
- print("Unknow type:"..trg_type)
- print("Subtype:"..tostring(trg.target[trg.keys[trg.selected]]._kind))
- end
- end
- end,
- cancelEdit = function(self)
- self.mode=MODE_BROWSE
- self.input=""
- end,
- commitEdit = function(self)
- local trg=self:currentTarget()
- self.mode=MODE_BROWSE
- if type(trg.target[trg.keys[trg.selected]])=='number' then
- trg.target[trg.keys[trg.selected]]=tonumber(self.input)
- elseif type(trg.target[trg.keys[trg.selected]])=='string' then
- trg.target[trg.keys[trg.selected]]=self.input
- end
- end,
- onRenderBody = function(self, dc)
- local trg=self:currentTarget()
- dc:seek(2,1):string(tostring(trg.target), COLOR_RED)
- local offset=2
- local page_offset=0
- local current_item=1
- local t_col
- if math.floor(trg.selected / (self.frame_height-offset-2)) >0 then
- page_offset=math.floor(trg.selected / (self.frame_height-offset-2))*(self.frame_height-offset-2)-1
- end
- for k,v in pairs(trg.target) do
-
- if current_item==trg.selected then
- t_col=COLOR_LIGHTGREEN
- else
- t_col=COLOR_GRAY
- end
-
- if current_item-page_offset > 0 then
- local y_pos=current_item-page_offset+offset
- dc:seek(2,y_pos):string(tostring(k),t_col)
-
- if self.mode==MODE_EDIT and current_item==trg.selected then
- dc:seek(20,y_pos):string(self.input..'_',COLOR_GREEN)
- else
- dc:seek(20,y_pos):string(tostring(v),t_col)
- end
- end
- current_item=current_item+1
- end
- end,
-
- onInput = function(self,keys)
- if self.mode==MODE_BROWSE then
- if keys.LEAVESCREEN then
- self:popTarget()
- elseif keys.CURSOR_UP then
- self:changeSelected(-1)
- elseif keys.CURSOR_DOWN then
- self:changeSelected(1)
- elseif keys.CURSOR_UP_FAST then
- self:changeSelected(-10)
- elseif keys.CURSOR_DOWN_FAST then
- self:changeSelected(10)
- elseif keys.SELECT then
- self:editSelected()
- elseif keys.CUSTOM_ALT_E then
- --self:specialEditor()
- local screen = mkinstance(TextInputDialog):init("Input new coordinates")
- screen:show()
- elseif keys.CUSTOM_ALT_I then --insert
- self:insertNew()
- elseif keys.CUSTOM_ALT_D then --delete
- self:deleteSelected()
- end
- elseif self.mode==MODE_EDIT then
- if keys.LEAVESCREEN then
- self:cancelEdit()
- elseif keys.SELECT then
- self:commitEdit()
- elseif keys._STRING then
- if keys._STRING==0 then
- self.input=string.sub(self.input,1,-2)
- else
- self.input=self.input.. string.char(keys._STRING)
- end
- end
- end
- end,
- pushTarget=function(self,target_to_push)
- local new_tbl={}
- new_tbl.target=target_to_push
- new_tbl.keys={}
- new_tbl.selected=1
- for k,v in pairs(target_to_push) do
- table.insert(new_tbl.keys,k)
- end
- new_tbl.item_count=#new_tbl.keys
- table.insert(self.stack,new_tbl)
- end,
- popTarget=function(self)
- table.remove(self.stack) --removes last element
- if #self.stack==0 then
- self:dismiss()
- end
- end,
- init = function(self,item_to_edit)
- self:pushTarget(item_to_edit)
- self.frame_width,self.frame_height=dfhack.screen.getWindowSize()
- return self
- end
}
+function GmEditorUi:init(args)
+ self.stack={}
+ self.item_count=0
+ self.mode=MODE_BROWSE
+ self.keys={}
+ self:pushTarget(args.target)
+
+ return self
+end
+function GmEditorUi:insertNew(typename)
+ local tp=typename
+ if typename== nil then
+ dialog.showInputPrompt("Class type","Input class type:",COLOR_WHITE,"",dfhack.curry(self.insertNew,self))
+ return
+ end
+ local ntype=df[tp]
+ if ntype== nil then
+ dialog.showMessage("Error!","Type '"..tp.." not found",COLOR_RED)
+ return
+ end
+
+ 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,trg.target.insert,trg.target,'#',thing)
+
+ end
+end
+function GmEditorUi:deleteSelected()
+ local trg=self:currentTarget()
+ if trg.target and trg.target._kind and trg.target._kind=="container" then
+ trg.target:erase(trg.keys[trg.selected])
+ end
+end
+function GmEditorUi:currentTarget()
+ return self.stack[#self.stack]
+end
+function GmEditorUi:changeSelected(delta)
+ local trg=self:currentTarget()
+ if trg.item_count <= 1 then return end
+ trg.selected = 1 + (trg.selected + delta - 1) % trg.item_count
+end
+function GmEditorUi:editSelected()
+ local trg=self:currentTarget()
+ if trg.target and trg.target._kind and trg.target._kind=="bitfield" then
+ trg.target[trg.keys[trg.selected]]= not trg.target[trg.keys[trg.selected]]
+ else
+ --print(type(trg.target[trg.keys[trg.selected]]),trg.target[trg.keys[trg.selected]]._kind or "")
+ local trg_type=type(trg.target[trg.keys[trg.selected]])
+ if trg_type=='number' or trg_type=='string' then --ugly TODO: add metatable get selected
+ self.mode=MODE_EDIT
+ self.input=tostring(trg.target[trg.keys[trg.selected]])
+ elseif trg_type=='boolean' then
+ trg.target[trg.keys[trg.selected]]= not trg.target[trg.keys[trg.selected]]
+ elseif trg_type=='userdata' then
+ self:pushTarget(trg.target[trg.keys[trg.selected]])
+ --local screen = mkinstance(gui.FramedScreen,GmEditorUi):init(trg.target[trg.keys[trg.selected]]) -- does not work
+ --screen:show()
+ else
+ print("Unknow type:"..trg_type)
+ print("Subtype:"..tostring(trg.target[trg.keys[trg.selected]]._kind))
+ end
+ end
+end
+function GmEditorUi:cancelEdit()
+ self.mode=MODE_BROWSE
+ self.input=""
+end
+function GmEditorUi:commitEdit()
+ local trg=self:currentTarget()
+ self.mode=MODE_BROWSE
+ if type(trg.target[trg.keys[trg.selected]])=='number' then
+ trg.target[trg.keys[trg.selected]]=tonumber(self.input)
+ elseif type(trg.target[trg.keys[trg.selected]])=='string' then
+ trg.target[trg.keys[trg.selected]]=self.input
+ end
+end
+function GmEditorUi:onRenderBody( dc)
+ local trg=self:currentTarget()
+ dc:seek(2,1):string(tostring(trg.target), COLOR_RED)
+ local offset=2
+ local page_offset=0
+ local current_item=1
+ local t_col
+ local width,height=self:getWindowSize()
+ local window_height=height-offset-2
+ local cursor_window=math.floor(trg.selected / window_height)
+ if cursor_window>0 then
+ page_offset=cursor_window*window_height-1
+ end
+ for k,v in pairs(trg.target) do
+
+ if current_item==trg.selected then
+ t_col=COLOR_LIGHTGREEN
+ else
+ t_col=COLOR_GRAY
+ end
+
+ if current_item-page_offset > 0 then
+ local y_pos=current_item-page_offset+offset
+ dc:seek(2,y_pos):string(tostring(k),t_col)
+
+ if self.mode==MODE_EDIT and current_item==trg.selected then
+ dc:seek(20,y_pos):string(self.input..'_',COLOR_GREEN)
+ else
+ dc:seek(20,y_pos):string(tostring(v),t_col)
+ end
+ if y_pos+3>height then
+ break
+ end
+ end
+ current_item=current_item+1
+
+ end
+end
+ function GmEditorUi:onInput(keys)
+ if self.mode==MODE_BROWSE then
+ if keys.LEAVESCREEN then
+ self:popTarget()
+ elseif keys.CURSOR_UP then
+ self:changeSelected(-1)
+ elseif keys.CURSOR_DOWN then
+ self:changeSelected(1)
+ elseif keys.CURSOR_UP_FAST then
+ self:changeSelected(-10)
+ elseif keys.CURSOR_DOWN_FAST then
+ self:changeSelected(10)
+ elseif keys.SELECT then
+ self:editSelected()
+ elseif keys.CUSTOM_ALT_E then
+ --self:specialEditor()
+ local screen = mkinstance(TextInputDialog):init("Input new coordinates")
+ screen:show()
+ elseif keys.CUSTOM_ALT_I then --insert
+ self:insertNew()
+ elseif keys.CUSTOM_ALT_D then --delete
+ self:deleteSelected()
+ end
+ elseif self.mode==MODE_EDIT then
+ if keys.LEAVESCREEN then
+ self:cancelEdit()
+ elseif keys.SELECT then
+ self:commitEdit()
+ elseif keys._STRING then
+ if keys._STRING==0 then
+ self.input=string.sub(self.input,1,-2)
+ else
+ self.input=self.input.. string.char(keys._STRING)
+ end
+ end
+ end
+end
+function GmEditorUi:pushTarget(target_to_push)
+ local new_tbl={}
+ new_tbl.target=target_to_push
+ new_tbl.keys={}
+ new_tbl.selected=1
+ for k,v in pairs(target_to_push) do
+ table.insert(new_tbl.keys,k)
+ end
+ new_tbl.item_count=#new_tbl.keys
+ table.insert(self.stack,new_tbl)
+end
+function GmEditorUi:popTarget()
+ table.remove(self.stack) --removes last element
+ if #self.stack==0 then
+ self:dismiss()
+ end
+end
+local screen = GmEditorUi{target=my_trg}
-
-local screen = mkinstance(gui.FramedScreen,item_screen):init(my_trg)
screen:show()
\ No newline at end of file
From 39df1e0eceef0e6eafcb47f6274b26557f02ef61 Mon Sep 17 00:00:00 2001
From: Warmist
Date: Sun, 23 Sep 2012 23:23:12 +0300
Subject: [PATCH 017/158] Removed unused stuff from editor
---
scripts/gui/gm-editor.lua | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/scripts/gui/gm-editor.lua b/scripts/gui/gm-editor.lua
index 44345b3e8..a86a9f4a8 100644
--- a/scripts/gui/gm-editor.lua
+++ b/scripts/gui/gm-editor.lua
@@ -25,18 +25,6 @@ else
qerror("No valid target found")
end
-TextInputDialog = defclass(TextInputDialog, gui.FramedScreen)
-
-function TextInputDialog:init(prompt)
- self.frame_style=GREY_LINE_FRAME
- self.frame_title=prompt
- self.input=""
- return self
-end
-function TextInputDialog:onRenderBody(dc)
- dc:seek(1,1):string(self.input, COLOR_WHITE):newline()
-end
-
local MODE_BROWSE=0
local MODE_EDIT=1
GmEditorUi = defclass(GmEditorUi, gui.FramedScreen)
@@ -175,8 +163,6 @@ end
self:editSelected()
elseif keys.CUSTOM_ALT_E then
--self:specialEditor()
- local screen = mkinstance(TextInputDialog):init("Input new coordinates")
- screen:show()
elseif keys.CUSTOM_ALT_I then --insert
self:insertNew()
elseif keys.CUSTOM_ALT_D then --delete
From 28354715fff082194499fabe7a02a37b72a53d71 Mon Sep 17 00:00:00 2001
From: Warmist
Date: Sun, 23 Sep 2012 23:45:19 +0300
Subject: [PATCH 018/158] Editor with dialog mode (no without switching from/to
console to edit anything!)
---
scripts/gui/gm-editor.lua | 67 +++++++++++++++++++++++++--------------
1 file changed, 43 insertions(+), 24 deletions(-)
diff --git a/scripts/gui/gm-editor.lua b/scripts/gui/gm-editor.lua
index a86a9f4a8..309663bdf 100644
--- a/scripts/gui/gm-editor.lua
+++ b/scripts/gui/gm-editor.lua
@@ -1,30 +1,34 @@
-- Interface powered item editor.
local gui = require 'gui'
local dialog = require 'gui.dialogs'
+local args={...}
+function getTargetFromScreens()
+ local my_trg
+ if dfhack.gui.getCurFocus() == 'item' then
+ my_trg=dfhack.gui.getCurViewscreen().item
+ elseif dfhack.gui.getCurFocus() == 'joblist' then
+ local t_screen=dfhack.gui.getCurViewscreen()
+ my_trg=t_screen.jobs[t_screen.cursor_pos]
+ elseif dfhack.gui.getCurFocus() == 'createquota' then
+ local t_screen=dfhack.gui.getCurViewscreen()
+ my_trg=t_screen.orders[t_screen.sel_idx]
+ elseif dfhack.gui.getCurFocus() == 'dwarfmode/LookAround/Flow' then
+ local t_look=df.global.ui_look_list.items[df.global.ui_look_cursor]
+ my_trg=t_look.flow
-local my_trg
-if dfhack.gui.getCurFocus() == 'item' then
- my_trg=dfhack.gui.getCurViewscreen().item
-elseif dfhack.gui.getCurFocus() == 'joblist' then
- local t_screen=dfhack.gui.getCurViewscreen()
- my_trg=t_screen.jobs[t_screen.cursor_pos]
-elseif dfhack.gui.getCurFocus() == 'createquota' then
- local t_screen=dfhack.gui.getCurViewscreen()
- my_trg=t_screen.orders[t_screen.sel_idx]
-elseif dfhack.gui.getCurFocus() == 'dwarfmode/LookAround/Flow' then
- local t_look=df.global.ui_look_list.items[df.global.ui_look_cursor]
- my_trg=t_look.flow
-
-elseif dfhack.gui.getSelectedUnit(true) then
- my_trg=dfhack.gui.getSelectedUnit(true)
-elseif dfhack.gui.getSelectedItem(true) then
- my_trg=dfhack.gui.getSelectedItem(true)
-elseif dfhack.gui.getSelectedJob(true) then
- my_trg=dfhack.gui.getSelectedJob(true)
-else
- qerror("No valid target found")
+ elseif dfhack.gui.getSelectedUnit(true) then
+ my_trg=dfhack.gui.getSelectedUnit(true)
+ elseif dfhack.gui.getSelectedItem(true) then
+ my_trg=dfhack.gui.getSelectedItem(true)
+ elseif dfhack.gui.getSelectedJob(true) then
+ my_trg=dfhack.gui.getSelectedJob(true)
+ else
+ qerror("No valid target found")
+ end
+ return my_trg
end
+
local MODE_BROWSE=0
local MODE_EDIT=1
GmEditorUi = defclass(GmEditorUi, gui.FramedScreen)
@@ -199,7 +203,22 @@ function GmEditorUi:popTarget()
self:dismiss()
end
end
+function show_editor(trg)
+ local screen = GmEditorUi{target=trg}
+ screen:show()
+end
+if #args~=0 then
+ if args[1]=="dialog" then
+ function thunk(entry)
+ local t=load("return "..entry)()
+ show_editor(t)
+ end
+ dialog.showInputPrompt("Gm Editor", "Object to edit:", COLOR_GRAY, "",thunk)
+ else
+ local t=load("return "..args[1])()
+ show_editor(t)
+ end
+else
+ show_editor(getTargetFromScreens())
+end
-local screen = GmEditorUi{target=my_trg}
-
-screen:show()
\ No newline at end of file
From bd2f3a9998c72d85d663da44fbdb30702b3e0c6d Mon Sep 17 00:00:00 2001
From: Warmist
Date: Tue, 25 Sep 2012 00:24:37 +0300
Subject: [PATCH 019/158] Moved lua out of dfusion. Now lua is a script.
supports --file (or -f) flag, usage: lua or lua --file
or just "lua" for interactive interpreter.
---
plugins/Dfusion/dfusion.cpp | 62 -------------------------------------
scripts/lua.lua | 10 ++++++
2 files changed, 10 insertions(+), 62 deletions(-)
create mode 100644 scripts/lua.lua
diff --git a/plugins/Dfusion/dfusion.cpp b/plugins/Dfusion/dfusion.cpp
index 78c3fa8d1..6c698f58a 100644
--- a/plugins/Dfusion/dfusion.cpp
+++ b/plugins/Dfusion/dfusion.cpp
@@ -33,8 +33,6 @@ DFHACK_PLUGIN("dfusion")
command_result dfusion (color_ostream &out, std::vector ¶meters);
command_result dfuse (color_ostream &out, std::vector ¶meters);
-command_result lua_run (color_ostream &out, std::vector ¶meters);
-command_result lua_run_file (color_ostream &out, std::vector ¶meters);
DFhackCExport const char * plugin_name ( void )
{
@@ -65,8 +63,6 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector ' to run instead.",lua_run,true));
- commands.push_back(PluginCommand("runlua", "Run non-interactive interpreter. Use 'runlua ' to run .",lua_run_file,false));
mymutex=new tthread::mutex;
return CR_OK;
}
@@ -107,64 +103,6 @@ DFhackCExport command_result plugin_onupdate_DISABLED ( Core * c )
mymutex->unlock();
return CR_OK;
}
-command_result lua_run_file (color_ostream &out, std::vector ¶meters)
-{
- if(parameters.size()==0)
- {
- out.printerr("runlua without file to run!");
- return CR_FAILURE;
- }
- return lua_run(out,parameters);
-}
-command_result lua_run (color_ostream &out, std::vector ¶meters)
-{
- if (!parameters.empty())
- {
- if (parameters[0] == "--core-context")
- {
- Lua::InterpreterLoop(out, Lua::Core::State, "core lua");
- return CR_OK;
- }
- else if (parameters[0] == "--core-reload")
- {
- CoreSuspender suspend;
-
- for (size_t i = 1; i < parameters.size(); i++)
- {
- lua_getglobal(Lua::Core::State, "reload");
- lua_pushstring(Lua::Core::State, parameters[i].c_str());
- Lua::SafeCall(out, Lua::Core::State, 1, 0);
- }
-
- return CR_OK;
- }
- }
-
- mymutex->lock();
- lua::state s=lua::glua::Get();
-
- if(parameters.size()>0)
- {
- try{
- s.loadfile(parameters[0]); //load file
- for(size_t i=1;iunlock();
- return CR_OK;
-}
void RunDfusion(color_ostream &out, std::vector ¶meters)
{
mymutex->lock();
diff --git a/scripts/lua.lua b/scripts/lua.lua
new file mode 100644
index 000000000..c2033b7e6
--- /dev/null
+++ b/scripts/lua.lua
@@ -0,0 +1,10 @@
+local args={...}
+if args[1]=="--file" or args[1]=="-f" then
+ local f=loadfile (args[2])
+ dfhack.pcall(f,table.unpack(args,3))
+elseif args[1]~=nil then
+ local f=load(args[1],'=(lua command)', 't',)
+ dfhack.pcall(f,table.unpack(args,2))
+else
+ dfhack.interpreter("lua","lua.history")
+end
\ No newline at end of file
From cc5df57e53bf89b8cce51353c0a8b4f048d23679 Mon Sep 17 00:00:00 2001
From: Warmist
Date: Tue, 25 Sep 2012 10:24:45 +0300
Subject: [PATCH 020/158] Little error fixed in lua script
---
scripts/lua.lua | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/lua.lua b/scripts/lua.lua
index c2033b7e6..497498e86 100644
--- a/scripts/lua.lua
+++ b/scripts/lua.lua
@@ -3,7 +3,7 @@ if args[1]=="--file" or args[1]=="-f" then
local f=loadfile (args[2])
dfhack.pcall(f,table.unpack(args,3))
elseif args[1]~=nil then
- local f=load(args[1],'=(lua command)', 't',)
+ local f=load(args[1],'=(lua command)', 't')
dfhack.pcall(f,table.unpack(args,2))
else
dfhack.interpreter("lua","lua.history")
From 0bee8c360e1ad76ea68352e5d1806f79f910cd66 Mon Sep 17 00:00:00 2001
From: Warmist
Date: Tue, 25 Sep 2012 10:25:47 +0300
Subject: [PATCH 021/158] Reaction hooks experimentation.
---
plugins/CMakeLists.txt | 1 +
plugins/lua/reactionhooks.lua | 13 ++
plugins/reactionhooks.cpp | 319 ++++++++++++++++++++++++++++++++++
3 files changed, 333 insertions(+)
create mode 100644 plugins/lua/reactionhooks.lua
create mode 100644 plugins/reactionhooks.cpp
diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
index 0b0ad0461..4d4f7493f 100644
--- a/plugins/CMakeLists.txt
+++ b/plugins/CMakeLists.txt
@@ -123,6 +123,7 @@ if (BUILD_SUPPORTED)
DFHACK_PLUGIN(steam-engine steam-engine.cpp)
DFHACK_PLUGIN(power-meter power-meter.cpp LINK_LIBRARIES lua)
DFHACK_PLUGIN(siege-engine siege-engine.cpp LINK_LIBRARIES lua)
+ DFHACK_PLUGIN(reactionhooks reactionhooks.cpp LINK_LIBRARIES lua)
DFHACK_PLUGIN(add-spatter add-spatter.cpp)
# not yet. busy with other crud again...
#DFHACK_PLUGIN(versionosd versionosd.cpp)
diff --git a/plugins/lua/reactionhooks.lua b/plugins/lua/reactionhooks.lua
new file mode 100644
index 000000000..5f3622e2f
--- /dev/null
+++ b/plugins/lua/reactionhooks.lua
@@ -0,0 +1,13 @@
+local _ENV = mkmodule('plugins.reactionhooks')
+
+--[[
+
+ Native events:
+
+ * onReactionComplete(burrow)
+
+--]]
+
+rawset_default(_ENV, dfhack.reactionhooks)
+
+return _ENV
\ No newline at end of file
diff --git a/plugins/reactionhooks.cpp b/plugins/reactionhooks.cpp
new file mode 100644
index 000000000..4041b99a5
--- /dev/null
+++ b/plugins/reactionhooks.cpp
@@ -0,0 +1,319 @@
+#include "Core.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include "df/item_liquid_miscst.h"
+#include "df/item_constructed.h"
+#include "df/builtin_mats.h"
+#include "df/world.h"
+#include "df/job.h"
+#include "df/job_item.h"
+#include "df/job_item_ref.h"
+#include "df/ui.h"
+#include "df/report.h"
+#include "df/reaction.h"
+#include "df/reaction_reagent_itemst.h"
+#include "df/reaction_product_itemst.h"
+#include "df/matter_state.h"
+#include "df/contaminant.h"
+
+#include "MiscUtils.h"
+#include "LuaTools.h"
+
+using std::vector;
+using std::string;
+using std::stack;
+using namespace DFHack;
+using namespace df::enums;
+
+using df::global::gps;
+using df::global::world;
+using df::global::ui;
+
+typedef df::reaction_product_itemst item_product;
+
+DFHACK_PLUGIN("reactionhooks");
+
+struct ReagentSource {
+ int idx;
+ df::reaction_reagent *reagent;
+
+ ReagentSource() : idx(-1), reagent(NULL) {}
+};
+
+struct MaterialSource : ReagentSource {
+ bool product;
+ std::string product_name;
+
+ int mat_type, mat_index;
+
+ MaterialSource() : product(false), mat_type(-1), mat_index(-1) {}
+};
+
+struct ProductInfo {
+ df::reaction *react;
+ item_product *product;
+
+ MaterialSource material;
+
+ bool isValid() {
+ return (material.mat_type >= 0 || material.reagent);
+ }
+};
+
+struct ReactionInfo {
+ df::reaction *react;
+
+ std::vector products;
+};
+
+static std::map reactions;
+static std::map products;
+
+static ReactionInfo *find_reaction(const std::string &name)
+{
+ auto it = reactions.find(name);
+ return (it != reactions.end()) ? &it->second : NULL;
+}
+
+static bool is_lua_hook(const std::string &name)
+{
+ return name.size() > 9 && memcmp(name.data(), "LUA_HOOK_", 9) == 0;
+}
+
+static void find_material(int *type, int *index, df::item *input, MaterialSource &mat)
+{
+ if (input && mat.reagent)
+ {
+ MaterialInfo info(input);
+
+ if (mat.product)
+ {
+ if (!info.findProduct(info, mat.product_name))
+ {
+ color_ostream_proxy out(Core::getInstance().getConsole());
+ out.printerr("Cannot find product '%s'\n", mat.product_name.c_str());
+ }
+ }
+
+ *type = info.type;
+ *index = info.index;
+ }
+ else
+ {
+ *type = mat.mat_type;
+ *index = mat.mat_index;
+ }
+}
+
+
+/*
+ * Hooks
+ */
+
+typedef std::map > item_table;
+
+static void index_items(item_table &table, df::job *job, ReactionInfo *info)
+{
+ for (int i = job->items.size()-1; i >= 0; i--)
+ {
+ auto iref = job->items[i];
+ if (iref->job_item_idx < 0) continue;
+ auto iitem = job->job_items[iref->job_item_idx];
+
+ if (iitem->contains.empty())
+ {
+ table[iitem->reagent_index].push_back(iref->item);
+ }
+ else
+ {
+ std::vector contents;
+ Items::getContainedItems(iref->item, &contents);
+
+ for (int j = contents.size()-1; j >= 0; j--)
+ {
+ for (int k = iitem->contains.size()-1; k >= 0; k--)
+ {
+ int ridx = iitem->contains[k];
+ auto reag = info->react->reagents[ridx];
+
+ if (reag->matchesChild(contents[j], info->react, iitem->reaction_id))
+ table[ridx].push_back(contents[j]);
+ }
+ }
+ }
+ }
+}
+
+df::item* find_item(ReagentSource &info, item_table &table)
+{
+ if (!info.reagent)
+ return NULL;
+ if (table[info.idx].empty())
+ return NULL;
+ return table[info.idx].back();
+}
+
+
+
+df::item* find_item(
+ ReagentSource &info,
+ std::vector *in_reag,
+ std::vector *in_items
+) {
+ if (!info.reagent)
+ return NULL;
+ for (int i = in_items->size(); i >= 0; i--)
+ if ((*in_reag)[i] == info.reagent)
+ return (*in_items)[i];
+ return NULL;
+}
+
+static void handle_reaction_done(color_ostream &out, df::unit *unit, std::vector *in_items, std::vector *out_items,bool *call_native){};
+
+DEFINE_LUA_EVENT_4(onReactionComplete, handle_reaction_done, df::unit *, std::vector *,std::vector *,bool *);
+
+
+DFHACK_PLUGIN_LUA_EVENTS {
+ DFHACK_LUA_EVENT(onReactionComplete),
+ DFHACK_LUA_END
+};
+
+struct product_hook : item_product {
+ typedef item_product interpose_base;
+
+ DEFINE_VMETHOD_INTERPOSE(
+ void, produce,
+ (df::unit *unit, std::vector *out_items,
+ std::vector *in_reag,
+ std::vector *in_items,
+ int32_t quantity, int16_t skill,
+ df::historical_entity *entity, df::world_site *site)
+ ) {
+ if (auto product = products[this])
+ {
+ color_ostream_proxy out(Core::getInstance().getConsole());
+ bool call_native=true;
+ onReactionComplete(out,unit,in_items,out_items,&call_native);
+ if(!call_native)
+ return;
+ }
+
+ INTERPOSE_NEXT(produce)(unit, out_items, in_reag, in_items, quantity, skill, entity, site);
+ }
+};
+
+IMPLEMENT_VMETHOD_INTERPOSE(product_hook, produce);
+
+
+
+
+
+/*
+ * Scan raws for matching reactions.
+ */
+
+
+static void parse_product(
+ color_ostream &out, ProductInfo &info, df::reaction *react, item_product *prod
+ ) {
+ info.react = react;
+ info.product = prod;
+ info.material.mat_type = prod->mat_type;
+ info.material.mat_index = prod->mat_index;
+}
+
+static bool find_reactions(color_ostream &out)
+{
+ reactions.clear();
+
+ auto &rlist = world->raws.reactions;
+
+ for (size_t i = 0; i < rlist.size(); i++)
+ {
+ if (!is_lua_hook(rlist[i]->code))
+ continue;
+ reactions[rlist[i]->code].react = rlist[i];
+ }
+
+ for (auto it = reactions.begin(); it != reactions.end(); ++it)
+ {
+ auto &prod = it->second.react->products;
+ auto &out_prod = it->second.products;
+
+ for (size_t i = 0; i < prod.size(); i++)
+ {
+ auto itprod = strict_virtual_cast(prod[i]);
+ if (!itprod) continue;
+
+ out_prod.push_back(ProductInfo());
+ parse_product(out, out_prod.back(), it->second.react, itprod);
+ }
+
+ for (size_t i = 0; i < prod.size(); i++)
+ {
+ if (out_prod[i].isValid())
+ products[out_prod[i].product] = &out_prod[i];
+ }
+ }
+
+ return !products.empty();
+}
+
+static void enable_hooks(bool enable)
+{
+ INTERPOSE_HOOK(product_hook, produce).apply(enable);
+}
+
+DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event)
+{
+ switch (event) {
+ case SC_WORLD_LOADED:
+ if (find_reactions(out))
+ {
+ out.print("Detected reaction hooks - enabling plugin.\n");
+ enable_hooks(true);
+ }
+ else
+ enable_hooks(false);
+ break;
+ case SC_WORLD_UNLOADED:
+ enable_hooks(false);
+ reactions.clear();
+ products.clear();
+ break;
+ default:
+ break;
+ }
+
+ return CR_OK;
+}
+
+DFhackCExport command_result plugin_init ( color_ostream &out, std::vector &commands)
+{
+ if (Core::getInstance().isWorldLoaded())
+ plugin_onstatechange(out, SC_WORLD_LOADED);
+
+ return CR_OK;
+}
+
+DFhackCExport command_result plugin_shutdown ( color_ostream &out )
+{
+ enable_hooks(false);
+ return CR_OK;
+}
From ddc83a0a72edb7c23abe8f08daa4750ead3dc5ea Mon Sep 17 00:00:00 2001
From: Warmist
Date: Tue, 25 Sep 2012 11:30:38 +0300
Subject: [PATCH 022/158] Another dfusion nuking (not much left :) )
---
plugins/Dfusion/dfusion.cpp | 11 +-
plugins/Dfusion/include/functioncall.h | 26 ---
plugins/Dfusion/include/lua_FunctionCall.h | 14 --
plugins/Dfusion/include/lua_Misc.h | 1 -
plugins/Dfusion/include/lua_Offsets.h | 13 --
plugins/Dfusion/include/lua_VersionInfo.h | 12 --
plugins/Dfusion/src/functioncall.cpp | 121 -------------
plugins/Dfusion/src/lua_FunctionCall.cpp | 39 -----
plugins/Dfusion/src/lua_Misc.cpp | 99 +----------
plugins/Dfusion/src/lua_Offsets.cpp | 190 ---------------------
plugins/Dfusion/src/lua_VersionInfo.cpp | 115 -------------
11 files changed, 5 insertions(+), 636 deletions(-)
delete mode 100644 plugins/Dfusion/include/functioncall.h
delete mode 100644 plugins/Dfusion/include/lua_FunctionCall.h
delete mode 100644 plugins/Dfusion/include/lua_Offsets.h
delete mode 100644 plugins/Dfusion/include/lua_VersionInfo.h
delete mode 100644 plugins/Dfusion/src/functioncall.cpp
delete mode 100644 plugins/Dfusion/src/lua_FunctionCall.cpp
delete mode 100644 plugins/Dfusion/src/lua_Offsets.cpp
delete mode 100644 plugins/Dfusion/src/lua_VersionInfo.cpp
diff --git a/plugins/Dfusion/dfusion.cpp b/plugins/Dfusion/dfusion.cpp
index 6c698f58a..0f49e860d 100644
--- a/plugins/Dfusion/dfusion.cpp
+++ b/plugins/Dfusion/dfusion.cpp
@@ -14,10 +14,8 @@
#include "lua_Process.h"
#include "lua_Hexsearch.h"
#include "lua_Misc.h"
-#include "lua_VersionInfo.h"
-#include "functioncall.h"
-#include "lua_FunctionCall.h"
-#include "lua_Offsets.h"
+
+
#include "DataDefs.h"
#include "LuaTools.h"
@@ -43,15 +41,12 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector
-using std::vector;
-using std::size_t;
-class FunctionCaller
-{
-public:
- enum callconv
- {
- STD_CALL, //__stdcall - all in stack
- FAST_CALL, //__fastcall - as much in registers as fits
- THIS_CALL, //__thiscall - eax ptr to this, rest in stack
- CDECL_CALL //__cdecl - same as stdcall but no stack realign
- };
-
- FunctionCaller(size_t base):base_(base){};
-
- int CallFunction(size_t func_ptr,callconv conv,const vector &arguments);
-
-private:
- int CallF(size_t count,callconv conv,void* f,const vector &arguments);
- size_t base_;
-};
-
-#endif //FUNCTIONCALL__H
\ No newline at end of file
diff --git a/plugins/Dfusion/include/lua_FunctionCall.h b/plugins/Dfusion/include/lua_FunctionCall.h
deleted file mode 100644
index bc1af5685..000000000
--- a/plugins/Dfusion/include/lua_FunctionCall.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef LUA_FUNCTIONCALL__H
-#define LUA_FUNCTIONCALL__H
-
-#include "luamain.h"
-#include "functioncall.h"
-
-namespace lua
-{
-
-
-void RegisterFunctionCall(lua::state &st);
-
-}
-#endif
\ No newline at end of file
diff --git a/plugins/Dfusion/include/lua_Misc.h b/plugins/Dfusion/include/lua_Misc.h
index b39d60214..ff4611456 100644
--- a/plugins/Dfusion/include/lua_Misc.h
+++ b/plugins/Dfusion/include/lua_Misc.h
@@ -7,7 +7,6 @@
#include
#include "luamain.h"
#include "OutFile.h"
-#include "functioncall.h"
#include "LuaTools.h"
namespace lua
diff --git a/plugins/Dfusion/include/lua_Offsets.h b/plugins/Dfusion/include/lua_Offsets.h
deleted file mode 100644
index 8d6a94b95..000000000
--- a/plugins/Dfusion/include/lua_Offsets.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef LUA_OFFSETS_H
-#define LUA_OFFSETS_H
-#include "luamain.h"
-
-namespace lua
-{
-
-void RegisterEngine(lua::state &st);
-
-}
-
-
-#endif
\ No newline at end of file
diff --git a/plugins/Dfusion/include/lua_VersionInfo.h b/plugins/Dfusion/include/lua_VersionInfo.h
deleted file mode 100644
index a4d7ed658..000000000
--- a/plugins/Dfusion/include/lua_VersionInfo.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef LUA_VERSIONINFO_H
-#define LUA_VERSIONINFO_H
-#include "Core.h"
-#include
-#include "luamain.h"
-namespace lua
-{
-
-void RegisterVersionInfo(lua::state &st);
-
-}
-#endif
diff --git a/plugins/Dfusion/src/functioncall.cpp b/plugins/Dfusion/src/functioncall.cpp
deleted file mode 100644
index b6c38c928..000000000
--- a/plugins/Dfusion/src/functioncall.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-#include "functioncall.h"
-
-#ifdef LINUX_BUILD
-#define __F_TDEF(CONV,CONV_,tag) typedef int(__attribute__ ( (CONV_) ) *F_TYPE##CONV##tag)
-#else
-#define __F_TDEF(CONV,CONV_,tag) typedef int(__ ## CONV_ *F_TYPE##CONV##tag)
-#endif
-
-#define __F_T(CONV,tag) F_TYPE##CONV##tag
-#define __F_TYPEDEFS(CONV,CONV_) __F_TDEF(CONV,CONV_,1)(int);\
- __F_TDEF(CONV,CONV_,2)(int,int);\
- __F_TDEF(CONV,CONV_,3)(int,int,int);\
- __F_TDEF(CONV,CONV_,4)(int,int,int,int);\
- __F_TDEF(CONV,CONV_,5)(int,int,int,int,int);\
- __F_TDEF(CONV,CONV_,6)(int,int,int,int,int,int);\
- __F_TDEF(CONV,CONV_,7)(int,int,int,int,int,int,int)
-
-
-#define __FCALL(CONV,CONV_) if(conv==CONV)\
- { \
- if(count==1)\
- ret= (reinterpret_cast<__F_T(CONV,1)>(f))\
- (arguments[0]);\
- else if(count==2)\
- ret= (reinterpret_cast<__F_T(CONV,2)>(f))\
- (arguments[0],arguments[1]);\
- else if(count==3)\
- ret= (reinterpret_cast<__F_T(CONV,3)>(f))\
- (arguments[0],arguments[1],arguments[2]);\
- else if(count==4)\
- ret= (reinterpret_cast<__F_T(CONV,4)>(f))\
- (arguments[0],arguments[1],arguments[2],arguments[3]);\
- else if(count==5)\
- ret= (reinterpret_cast<__F_T(CONV,5)>(f))\
- (arguments[0],arguments[1],arguments[2],arguments[3],arguments[4]);\
- else if(count==6)\
- ret= (reinterpret_cast<__F_T(CONV,6)>(f))\
- (arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]);\
- else if(count==7)\
- ret= (reinterpret_cast<__F_T(CONV,7)>(f))\
- (arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6]);\
- }
-
-#define __FCALLEX(CONV,CONV_) if(conv==CONV)\
- { if(count==1) {__F_T(CONV,1) tmp_F=reinterpret_cast<__F_T(CONV,1)>(f); return tmp_F(arguments[0]);}\
- else if(count==2){__F_T(CONV,2) tmp_F=reinterpret_cast<__F_T(CONV,2)>(f); return tmp_F(arguments[0],arguments[1]);}\
- else if(count==3){__F_T(CONV,3) tmp_F=reinterpret_cast<__F_T(CONV,3)>(f); return tmp_F(arguments[0],arguments[1],arguments[2]);}\
- else if(count==4){__F_T(CONV,4) tmp_F=reinterpret_cast<__F_T(CONV,4)>(f); return tmp_F(arguments[0],arguments[1],arguments[2],arguments[3]);}\
- else if(count==5){__F_T(CONV,5) tmp_F=reinterpret_cast<__F_T(CONV,5)>(f); return tmp_F(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4]);}\
- else if(count==6){__F_T(CONV,6) tmp_F=reinterpret_cast<__F_T(CONV,6)>(f); return tmp_F(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]);}\
- else if(count==7){__F_T(CONV,7) tmp_F=reinterpret_cast<__F_T(CONV,7)>(f); return tmp_F(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6]);}\
- }
- /*else if(count==8)\
- ret= (reinterpret_cast<__F_T(CONV,8)>(f))\
- (arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6],arguments[7]);\
- else if(count==9)\
- ret= (reinterpret_cast(f))\
- (arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6],arguments[7],arguments[8]);\
- else if(count==10)\
- ret= (reinterpret_cast(f))\
- (arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6],arguments[7],arguments[8],arguments[9]);}*/
-
-
-/*int FunctionCaller::CallF(size_t count,callconv conv,void* f,const vector &arguments)//more complex but not more error safe
-{
- __F_TYPEDEFS(STD_CALL,__stdcall);
- __F_TYPEDEFS(FAST_CALL,__fastcall);
- __F_TYPEDEFS(THIS_CALL,__thiscall);
- __F_TYPEDEFS(CDECL_CALL,__cdecl);
- {
- __FCALLEX(STD_CALL,__stdcall);
- __FCALLEX(FAST_CALL,__fastcall);
- __FCALLEX(THIS_CALL,__thiscall);
- __FCALLEX(CDECL_CALL,__cdecl);
- }
-}*/
-int FunctionCaller::CallFunction(size_t func_ptr,callconv conv,const vector &arguments)
-{
- //nasty nasty code...
-#ifdef LINUX_BUILD //quick fix
- if(conv==THIS_CALL)
- conv=STD_CALL;
-#endif
- void* f= reinterpret_cast(func_ptr+base_);
- size_t count=arguments.size();
- if(count==0)
- return (reinterpret_cast(f))(); //does not matter how we call it...
- int ret=0;
- //typedefs
- __F_TYPEDEFS(STD_CALL,stdcall);
- __F_TYPEDEFS(FAST_CALL,fastcall);
- __F_TYPEDEFS(THIS_CALL,thiscall);
- __F_TYPEDEFS(CDECL_CALL,cdecl);
- //calls
- __FCALL(STD_CALL,stdcall);
- __FCALL(FAST_CALL,fastcall);
- __FCALL(THIS_CALL,thiscall);
- __FCALL(CDECL_CALL,cdecl);
- return -1; //incorect type. Should probably throw...
- //return CallF(count,conv,f,arguments);
- /*//testing part{ worked some time ago..., put where DFHack::Core is accesible
- c->Suspend();
- FunctionCaller caller(c->p->getBase());
- std::vector args;
- args.push_back((size_t)"Hello world");
- args.push_back(4);
- args.push_back(4);
- args.push_back(0);
- dfprint mprint=(dfprint)(0x27F030+c->p->getBase());
- mprint("Hello world",4,4,0);
- //caller.CallFunction((0x27F030),FunctionCaller::THIS_CALL,args);
- c->Resume();
- return CR_OK;
- //}end testing*/
-}
-#undef __FCALL
-#undef __FCALLEX
-#undef __F_TYPEDEFS
-#undef __F_T
diff --git a/plugins/Dfusion/src/lua_FunctionCall.cpp b/plugins/Dfusion/src/lua_FunctionCall.cpp
deleted file mode 100644
index a537edbb5..000000000
--- a/plugins/Dfusion/src/lua_FunctionCall.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "lua_FunctionCall.h"
-using namespace lua;
-int lua_FunctionCall(lua_State *L)
-{
- lua::state st(L);
- FunctionCaller cl(0);
- size_t ptr=st.as(1);
- int callconv=st.as(2);
- vector arguments;
- for(int i=3;i(i));
- int ret=cl.CallFunction(ptr,(FunctionCaller::callconv)callconv,arguments);
- st.push(ret);
- return 1;// dunno if len is needed...
-}
-
-const luaL_Reg lua_functioncall_func[]=
-{
- {"call",lua_FunctionCall},
- {NULL,NULL}
-};
-
-#define __ADDCONST(name) st.push(::FunctionCaller:: name); st.setglobal(#name)
-void lua::RegisterFunctionCall(lua::state &st)
-{
- st.getglobal("FunctionCall");
- if(st.is())
- {
- st.pop();
- st.newtable();
- }
- __ADDCONST(STD_CALL);
- __ADDCONST(FAST_CALL);
- __ADDCONST(THIS_CALL);
- __ADDCONST(CDECL_CALL);
- lua::RegFunctionsLocal(st, lua_functioncall_func);
- st.setglobal("FunctionCall");
-}
-#undef __ADDCONST
\ No newline at end of file
diff --git a/plugins/Dfusion/src/lua_Misc.cpp b/plugins/Dfusion/src/lua_Misc.cpp
index b58efc7ac..6a06781fd 100644
--- a/plugins/Dfusion/src/lua_Misc.cpp
+++ b/plugins/Dfusion/src/lua_Misc.cpp
@@ -129,111 +129,16 @@ static int GetMod(lua_State *L)
st.push(pos);
return 1;
}
-static int lua_malloc(lua_State *L)
-{
- lua::state st(L);
- size_t size=st.as(1);
- size_t pos=reinterpret_cast(malloc(size));
- st.push(pos);
- return 1;
-}
-static int lua_malloc_free(lua_State *L)
-{
- lua::state st(L);
- size_t ptr=st.as(1);
- free(reinterpret_cast(ptr));
- return 0;
-}
-#ifdef LINUX_BUILD
-static size_t __attribute__((stdcall)) PushValue(size_t ret,uint32_t eax,uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t edi,uint32_t esi,uint32_t esp,uint32_t ebp)
-#else
-static size_t __stdcall PushValue(size_t ret,uint32_t eax,uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t edi,uint32_t esi,uint32_t esp,uint32_t ebp)
-#endif
-{
- lua::state st=lua::glua::Get();
- st.getglobal("OnFunction");
- if(st.is())
- return 0;
- st.newtable();
- st.push(eax);
- st.setfield("eax");
- st.push(ebx);
- st.setfield("ebx");
- st.push(ecx);
- st.setfield("ecx");
- st.push(edx);
- st.setfield("edx");
- st.push(edi);
- st.setfield("edi");
- st.push(esi);
- st.setfield("esi");
- st.push(esp+12);
- st.setfield("esp");
- st.push(ebp);
- st.setfield("ebp");
- st.push(ret);
- st.setfield("ret");
- DFHack::Lua::SafeCall(DFHack::Core::getInstance().getConsole(),st,1,1);
- return st.as();
-}
-static int Get_PushValue(lua_State *L)
-{
- lua::state st(L);
- st.push((uint32_t)&PushValue);
- return 1;
-}
-static int Call_Df(lua_State *L)
-{
- lua::state st(L);
- FunctionCaller f(0);
- std::vector args;
- size_t ptr;
- FunctionCaller::callconv conv;
- ptr=st.as(1);
- conv=(FunctionCaller::callconv)st.as(2);
- for(size_t j=3;j<=st.gettop();j++)
- args.push_back(st.as(j));
- st.push(f.CallFunction(ptr,conv,args));
- return 1;
-}
-static int Suspend_Df(lua_State *L)
-{
- lua::state st(L);
- DFHack::Core::getInstance().Suspend();
- return 0;
-}
-static int Resume_Df(lua_State *L)
-{
- lua::state st(L);
- DFHack::Core::getInstance().Resume();
- return 0;
-}
-static int Cast(lua_State *L)
-{
- lua::state st(L);
- if(DFHack::Lua::IsDFObject(st,1)!=DFHack::Lua::OBJ_TYPE)
- st.error("First argument must be df type!");
- if(!st.is(2)) //todo maybe lightuserdata?
- st.error("Second argument must be pointer as a number!");
- st.getfield("_identity",1);
- DFHack::Lua::PushDFObject(st,(DFHack::type_identity*)lua_touserdata(st,-1),(void*)st.as(2));
- return 1;
-}
+
+
const luaL_Reg lua_misc_func[]=
{
- {"alloc",lua_malloc},
- {"free",lua_malloc_free},
{"loadmod",LoadMod},
{"getmod",GetMod},
{"loadobj",LoadObj},
{"loadobjsymbols",LoadObjSymbols},
{"findmarker",FindMarker},
{"newmod",NewMod},
- {"getpushvalue",Get_PushValue},
- {"calldf",Call_Df},
- {"suspend",Suspend_Df},
- {"resume",Resume_Df},
- {"cast",Cast},
{NULL,NULL}
};
void lua::RegisterMisc(lua::state &st)
diff --git a/plugins/Dfusion/src/lua_Offsets.cpp b/plugins/Dfusion/src/lua_Offsets.cpp
deleted file mode 100644
index 4d66e67e7..000000000
--- a/plugins/Dfusion/src/lua_Offsets.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-#include "lua_Offsets.h"
-#include
-#include
-//TODO make a seperate module with peeks/pokes and page permisions (linux/windows spec)
-//TODO maybe remove alltogether- use DFHack::Process instead?
-template
-T engine_peek(size_t offset)
-{
- return *(reinterpret_cast(offset));
-}
-template
-void engine_poke(size_t offset,T val)
-{
- *(reinterpret_cast(offset))=val;
-}
-
-void peekarb(size_t offset, void *mem,size_t size)
-{
- memcpy(mem,(void*)offset,size);
-}
-void peekstr(size_t offset, char* buf, size_t maxsize)
-{
- strncpy(buf,(char*)offset,maxsize);
-}
-void pokearb(size_t offset, void *mem,size_t size)
-{
- memcpy((void*)offset,mem,size);
-}
-void pokestr(size_t offset, char* buf, size_t maxsize)
-{
- strncpy((char*)offset,buf,maxsize);
-}
-
-//// lua stuff here
-static int lua_peekb(lua_State *L)
-{
- lua::state st(L);
- st.push(engine_peek(st.as(1)));
- return 1;
-}
-static int lua_peekw(lua_State *L)
-{
- lua::state st(L);
- st.push(engine_peek(st.as(1)));
- return 1;
-}
-static int lua_peekd(lua_State *L)
-{
- lua::state st(L);
- st.push(engine_peek(st.as(1)));
- return 1;
-}
-static int lua_peekq(lua_State *L)
-{
- lua::state st(L);
- st.push(engine_peek(st.as(1)));
- return 1;
-}
-static int lua_peekfloat(lua_State *L)
-{
- lua::state st(L);
- st.push(engine_peek(st.as(1)));
- return 1;
-}
-static int lua_peekdouble(lua_State *L)
-{
- lua::state st(L);
- st.push(engine_peek(st.as(1)));
- return 1;
-}
-static int lua_peekarb(lua_State *L)
-{
- lua::state st(L);
- size_t size=st.as(2);
- void *p=st.newuserdata(size);
- peekarb(st.as(1),p,size);
- return 1;
-}
-static int lua_peekstr(lua_State *L)
-{
- lua::state st(L);
- char *buf;
- buf=new char[256];
- peekstr(st.as(1),buf,256);
- std::string tstr(buf);
- st.push(tstr);
- delete [] buf;
- return 1;
-}
-static int lua_peekstr2(lua_State *L)
-{
- lua::state st(L);
- st.push(engine_peek(st.as(1)));
- return 1;
-}
-static int lua_pokeb(lua_State *L)
-{
- lua::state st(L);
- engine_poke(st.as(1),st.as(2));
- return 0;
-}
-static int lua_pokew(lua_State *L)
-{
- lua::state st(L);
- engine_poke(st.as(1),st.as(2));
- return 0;
-}
-static int lua_poked(lua_State *L)
-{
- lua::state st(L);
- engine_poke(st.as(1),st.as(2));
- return 0;
-}
-static int lua_pokeq(lua_State *L)
-{
- lua::state st(L);
- engine_poke(st.as(1),st.as(2));
- return 0;
-}
-static int lua_pokefloat(lua_State *L)
-{
- lua::state st(L);
- engine_poke(st.as(1),st.as(2));
- return 0;
-}
-static int lua_pokedouble(lua_State *L)
-{
- lua::state st(L);
- engine_poke(st.as(1),st.as(2));
- return 0;
-}
-static int lua_pokearb(lua_State *L)
-{
- lua::state st(L);
- void *p=(void *)lua_touserdata(L, 2);//st.as(2);
- size_t size=st.as(3);
- pokearb(st.as(1),p,size);
- return 0;
-}
-static int lua_pokestr(lua_State *L)
-{
- lua::state st(L);
- std::string trg=st.as(2);
- pokestr(st.as(1),(char*)trg.c_str(),trg.size());
- return 0;
-}
-static int lua_pokestr2(lua_State *L)
-{
- lua::state st(L);
- std::string trg=st.as(2);
- engine_poke(st.as(1),trg);
- return 0;
-}
-const luaL_Reg lua_engine_func[]=
-{
- {"peekb",lua_peekb},
- {"peekw",lua_peekw},
- {"peekd",lua_peekd},
- {"peekq",lua_peekq},
- {"peekfloat",lua_peekfloat},
- {"peekdouble",lua_peekdouble},
-
- {"peekarb",lua_peekarb},
- {"peekstr",lua_peekstr},
- {"peekstr2",lua_peekstr2},
-
- {"pokeb",lua_pokeb},
- {"pokew",lua_pokew},
- {"poked",lua_poked},
- {"pokeq",lua_pokeq},
- {"pokefloat",lua_pokefloat},
- {"pokedouble",lua_pokedouble},
-
- {"pokearb",lua_pokearb},
- {"pokestr",lua_pokestr},
- {"pokestr2",lua_pokestr2},
- {NULL,NULL}
-};
-
-void lua::RegisterEngine(lua::state &st)
-{
- st.getglobal("engine");
- if(st.is())
- {
- st.pop();
- st.newtable();
- }
- lua::RegFunctionsLocal(st,lua_engine_func);
- st.setglobal("engine");
-}
diff --git a/plugins/Dfusion/src/lua_VersionInfo.cpp b/plugins/Dfusion/src/lua_VersionInfo.cpp
deleted file mode 100644
index 9f5cd17e7..000000000
--- a/plugins/Dfusion/src/lua_VersionInfo.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-#include "lua_VersionInfo.h"
-
-#define VI_FUNC(name) int lua_VI_ ## name (lua_State *L){\
- lua::state s(L);\
- DFHack::VersionInfo* vif=DFHack::Core::getInstance().vinfo;
-#define END_VI_FUNC }
-
-VI_FUNC(getBase)
-//int lua_VI_getBase(lua_State *L)
- s.push(vif->getBase());
- return 1;
-END_VI_FUNC
-
-VI_FUNC(setBase)
- uint32_t val=s.as(1);
- vif->setBase(val);
- return 0;
-END_VI_FUNC
-VI_FUNC(rebaseTo)
- uint32_t val=s.as(1);
- vif->rebaseTo(val);
- return 0;
-END_VI_FUNC
-VI_FUNC(addMD5)
- std::string val=s.as(1);
- vif->addMD5(val);
- return 0;
-END_VI_FUNC
-VI_FUNC(hasMD5)
- std::string val=s.as(1);
- s.push(vif->hasMD5(val));
- return 1;
-END_VI_FUNC
-
-VI_FUNC(addPE)
- uint32_t val=s.as(1);
- vif->addPE(val);
- return 0;
-END_VI_FUNC
-
-VI_FUNC(hasPE)
- uint32_t val=s.as(1);
- s.push(vif->hasPE(val));
- return 1;
-END_VI_FUNC
-
-VI_FUNC(setVersion)
- std::string val=s.as(1);
- vif->setVersion(val);
- return 0;
-END_VI_FUNC
-
-VI_FUNC(getVersion)
- s.push(vif->getVersion());
- return 1;
-END_VI_FUNC
-
-VI_FUNC(setAddress)
- std::string key=s.as(1);
- uint32_t val=s.as(2);
- vif->setAddress(key,val);
- return 0;
-END_VI_FUNC
-
-VI_FUNC(getAddress)
- std::string key=s.as(1);
-
- s.push(vif->getAddress(key));
- return 1;
-END_VI_FUNC
-
-VI_FUNC(setOS)
- unsigned os=s.as(1);
- vif->setOS((DFHack::OSType)os);
- return 0;
-END_VI_FUNC
-
-VI_FUNC(getOS)
- s.push(vif->getOS());
- return 1;
-END_VI_FUNC
-#undef VI_FUNC
-#undef END_VI_FUNC
-#define VI_FUNC(name) {#name,lua_VI_ ## name}
-const luaL_Reg lua_vinfo_func[]=
-{
- VI_FUNC(getBase),
- VI_FUNC(setBase),
- VI_FUNC(rebaseTo),
- VI_FUNC(addMD5),
- VI_FUNC(hasMD5),
- VI_FUNC(addPE),
- VI_FUNC(hasPE),
- VI_FUNC(setVersion),
- VI_FUNC(getVersion),
- VI_FUNC(setAddress),
- VI_FUNC(getAddress),
- VI_FUNC(setOS),
- VI_FUNC(getOS),
- {NULL,NULL}
-};
-#undef VI_FUNC
-void lua::RegisterVersionInfo(lua::state &st)
-{
-
- st.getglobal("VersionInfo");
- if(st.is())
- {
- st.pop();
- st.newtable();
- }
-
- lua::RegFunctionsLocal(st, lua_vinfo_func);
- st.setglobal("VersionInfo");
-}
From 923ea3f4b0a2c435399dd967d4736e2ec626344f Mon Sep 17 00:00:00 2001
From: Warmist
Date: Sun, 7 Oct 2012 20:44:18 +0300
Subject: [PATCH 023/158] Reactionhooks more usefull and gm-editor minor tweaks
(e.g. search in containers)
---
library/include/LuaTools.h | 15 +++++++++++++++
plugins/reactionhooks.cpp | 9 ++++++---
scripts/gui/gm-editor.lua | 21 +++++++++++++++++++++
3 files changed, 42 insertions(+), 3 deletions(-)
diff --git a/library/include/LuaTools.h b/library/include/LuaTools.h
index 3330e23e7..e956a65d5 100644
--- a/library/include/LuaTools.h
+++ b/library/include/LuaTools.h
@@ -472,3 +472,18 @@ namespace DFHack {namespace Lua {
name##_event.invoke(out, 5); \
} \
}
+
+#define DEFINE_LUA_EVENT_6(name, handler, arg_type1, arg_type2, arg_type3, arg_type4, arg_type5,arg_type6) \
+ static DFHack::Lua::Notification name##_event(df::wrap_function(handler, true)); \
+ void name(color_ostream &out, arg_type1 arg1, arg_type2 arg2, arg_type3 arg3, arg_type4 arg4,arg_type5 arg5, arg_type6 arg6) { \
+ handler(out, arg1, arg2, arg3, arg4, arg5, arg6); \
+ if (auto state = name##_event.state_if_count()) { \
+ DFHack::Lua::Push(state, arg1); \
+ DFHack::Lua::Push(state, arg2); \
+ DFHack::Lua::Push(state, arg3); \
+ DFHack::Lua::Push(state, arg4); \
+ DFHack::Lua::Push(state, arg5); \
+ DFHack::Lua::Push(state, arg6); \
+ name##_event.invoke(out, 6); \
+ } \
+}
\ No newline at end of file
diff --git a/plugins/reactionhooks.cpp b/plugins/reactionhooks.cpp
index 4041b99a5..d70fb9ea1 100644
--- a/plugins/reactionhooks.cpp
+++ b/plugins/reactionhooks.cpp
@@ -184,9 +184,10 @@ df::item* find_item(
return NULL;
}
-static void handle_reaction_done(color_ostream &out, df::unit *unit, std::vector *in_items, std::vector *out_items,bool *call_native){};
+static void handle_reaction_done(color_ostream &out,df::reaction*, df::unit *unit, std::vector *in_items,std::vector *in_reag
+ , std::vector *out_items,bool *call_native){};
-DEFINE_LUA_EVENT_4(onReactionComplete, handle_reaction_done, df::unit *, std::vector *,std::vector *,bool *);
+DEFINE_LUA_EVENT_6(onReactionComplete, handle_reaction_done,df::reaction*, df::unit *, std::vector *,std::vector *,std::vector *,bool *);
DFHACK_PLUGIN_LUA_EVENTS {
@@ -207,9 +208,11 @@ struct product_hook : item_product {
) {
if (auto product = products[this])
{
+ df::reaction* this_reaction=product->react;
+ CoreSuspendClaimer suspend;
color_ostream_proxy out(Core::getInstance().getConsole());
bool call_native=true;
- onReactionComplete(out,unit,in_items,out_items,&call_native);
+ onReactionComplete(out,this_reaction,unit,in_items,in_reag,out_items,&call_native);
if(!call_native)
return;
}
diff --git a/scripts/gui/gm-editor.lua b/scripts/gui/gm-editor.lua
index 309663bdf..6999f1d8c 100644
--- a/scripts/gui/gm-editor.lua
+++ b/scripts/gui/gm-editor.lua
@@ -45,6 +45,25 @@ function GmEditorUi:init(args)
return self
end
+function GmEditorUi:find(test)
+ local trg=self:currentTarget()
+ if trg.target and trg.target._kind and trg.target._kind=="container" then
+ 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
+ for k,v in pairs(trg.target) do
+ if e()(k,v)==true then
+ self:pushTarget(v)
+ return
+ end
+ end
+ end
+end
function GmEditorUi:insertNew(typename)
local tp=typename
if typename== nil then
@@ -165,6 +184,8 @@ end
self:changeSelected(10)
elseif keys.SELECT then
self:editSelected()
+ elseif keys.CUSTOM_ALT_F then
+ self:find()
elseif keys.CUSTOM_ALT_E then
--self:specialEditor()
elseif keys.CUSTOM_ALT_I then --insert
From 49476818c466118508d2fe37bd8820a766e5a6c5 Mon Sep 17 00:00:00 2001
From: Warmist
Date: Sun, 7 Oct 2012 20:45:14 +0300
Subject: [PATCH 024/158] Dfusion rebuild start (lua script side plugins)
---
library/xml | 2 +-
plugins/Dfusion/CMakeLists.txt | 2 +-
plugins/Dfusion/dfusion.cpp | 148 ++++++---------------
plugins/Dfusion/luafiles/common.lua | 6 +-
plugins/Dfusion/luafiles/embark/a.out | 0
plugins/Dfusion/luafiles/embark/embark.asm | 6 +-
plugins/Dfusion/luafiles/embark/embark.o | Bin 348 -> 369 bytes
plugins/Dfusion/src/OutFile.cpp | 18 +--
8 files changed, 57 insertions(+), 125 deletions(-)
delete mode 100644 plugins/Dfusion/luafiles/embark/a.out
diff --git a/library/xml b/library/xml
index a914f3b75..8a78bfa21 160000
--- a/library/xml
+++ b/library/xml
@@ -1 +1 @@
-Subproject commit a914f3b7558335d53c0ac93f6e7267906a33cd29
+Subproject commit 8a78bfa218817765b0a80431e0cf25435ffb2179
diff --git a/plugins/Dfusion/CMakeLists.txt b/plugins/Dfusion/CMakeLists.txt
index 65587201b..51f2e3bee 100644
--- a/plugins/Dfusion/CMakeLists.txt
+++ b/plugins/Dfusion/CMakeLists.txt
@@ -1,5 +1,5 @@
include_directories(include)
-include_directories("${dfhack_SOURCE_DIR}/library/depends/tthread")
+
FILE(GLOB DFUSION_CPPS src/*.c*)
set(
DFUSION_CPPS_ALL
diff --git a/plugins/Dfusion/dfusion.cpp b/plugins/Dfusion/dfusion.cpp
index 0f49e860d..daacc0b26 100644
--- a/plugins/Dfusion/dfusion.cpp
+++ b/plugins/Dfusion/dfusion.cpp
@@ -6,16 +6,11 @@
#include
#include
-
-#include "tinythread.h"
-
-
#include "luamain.h"
#include "lua_Process.h"
#include "lua_Hexsearch.h"
#include "lua_Misc.h"
-
#include "DataDefs.h"
#include "LuaTools.h"
@@ -23,112 +18,51 @@ using std::vector;
using std::string;
using namespace DFHack;
-static tthread::mutex* mymutex=0;
-static tthread::thread* thread_dfusion=0;
-uint64_t timeLast=0;
-DFHACK_PLUGIN("dfusion")
-command_result dfusion (color_ostream &out, std::vector ¶meters);
-command_result dfuse (color_ostream &out, std::vector ¶meters);
+DFHACK_PLUGIN("dfusion")
-DFhackCExport const char * plugin_name ( void )
+static int loadObjectFile(lua_State* L)
{
- return "dfusion";
+ std::string path;
+
+ path=luaL_checkstring(L,1);
+
+ OutFile::File f(path);
+ lua_newtable(L);
+ int table_pos=lua_gettop(L);
+ size_t size=f.GetTextSize();
+ Lua::Push(L,size);
+ 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);
+ lua_setfield(L,table_pos,"data");
+ OutFile::vSymbol& symbols=f.GetSymbols();
+ lua_newtable(L);
+ for(size_t i=0;i &commands)
+DFHACK_PLUGIN_LUA_COMMANDS {
+ DFHACK_LUA_COMMAND(loadObjectFile),
+ DFHACK_LUA_END
+};
+DFhackCExport command_result plugin_init ( color_ostream &out, std::vector &commands)
{
- lua::state st=lua::glua::Get();
-
- //maybe remake it to run automatically
- Lua::Open(out, st);
-
- lua::RegisterProcess(st);
- lua::RegisterHexsearch(st);
- lua::RegisterMisc(st);
-
- #ifdef LINUX_BUILD
- st.push(1);
- st.setglobal("LINUX");
- #else
- st.push(1);
- st.setglobal("WINDOWS");
- #endif
-
- commands.push_back(PluginCommand("dfusion","Run dfusion system (interactive i.e. can input further commands).",dfusion,true));
- commands.push_back(PluginCommand("dfuse","Init dfusion system (not interactive).",dfuse,false));
- mymutex=new tthread::mutex;
return CR_OK;
-}
-
-DFhackCExport command_result plugin_shutdown ( Core * c )
-{
-
-// shutdown stuff
- if(thread_dfusion)
- delete thread_dfusion;
- delete mymutex;
- return CR_OK;
-}
-
-DFhackCExport command_result plugin_onupdate_DISABLED ( Core * c )
-{
- uint64_t time2 = GetTimeMs64();
- uint64_t delta = time2-timeLast;
- if(delta<100)
- return CR_OK;
- timeLast = time2;
- mymutex->lock();
- lua::state s=lua::glua::Get();
- s.getglobal("OnTick");
- if(s.is())
- {
- try{
- s.pcall();
- }
- catch(lua::exception &e)
- {
- c->getConsole().printerr("Error OnTick:%s\n",e.what());
- c->getConsole().printerr("%s\n",lua::DebugDump(lua::glua::Get()).c_str());
- c->getConsole().msleep(1000);
- }
- }
- s.settop(0);
- mymutex->unlock();
- return CR_OK;
-}
-void RunDfusion(color_ostream &out, std::vector ¶meters)
-{
- mymutex->lock();
- lua::state s=lua::glua::Get();
- try{
- s.loadfile("dfusion/init.lua"); //load script
- for(size_t i=0;iunlock();
-}
-command_result dfuse(color_ostream &out, std::vector ¶meters)
-{
- lua::state s=lua::glua::Get();
- s.push(1);
- s.setglobal("INIT");
- RunDfusion(out,parameters);
- return CR_OK;
-}
-command_result dfusion (color_ostream &out, std::vector ¶meters)
-{
- lua::state s=lua::glua::Get();
- s.push();
- s.setglobal("INIT");
- RunDfusion(out,parameters);
- return CR_OK;
-}
+}
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/common.lua b/plugins/Dfusion/luafiles/common.lua
index 7e621c4ea..a6781b385 100644
--- a/plugins/Dfusion/luafiles/common.lua
+++ b/plugins/Dfusion/luafiles/common.lua
@@ -541,8 +541,4 @@ function Allocate(size)
curptr=curptr+size
engine.poked(ptr,curptr)
return curptr-size+ptr
-end
-dofile("dfusion/patterns.lua")
-dofile("dfusion/patterns2.lua")
-dofile("dfusion/itempatterns.lua")
-dofile("dfusion/buildingpatterns.lua")
\ No newline at end of file
+end
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/embark/a.out b/plugins/Dfusion/luafiles/embark/a.out
deleted file mode 100644
index e69de29bb..000000000
diff --git a/plugins/Dfusion/luafiles/embark/embark.asm b/plugins/Dfusion/luafiles/embark/embark.asm
index 644459ce5..d2fa91081 100644
--- a/plugins/Dfusion/luafiles/embark/embark.asm
+++ b/plugins/Dfusion/luafiles/embark/embark.asm
@@ -1,7 +1,7 @@
.intel_syntax
-mov eax , [esp+0x1C]
-caste:
+mov eax , [esp+0x1C] # loop counter
+mark_caste:
movsx ecx, word ptr[eax*2+0xdeadbeef]
-race:
+mark_race:
movzx eax,word ptr [eax*2+0xDEADBEEF]
ret
diff --git a/plugins/Dfusion/luafiles/embark/embark.o b/plugins/Dfusion/luafiles/embark/embark.o
index 1c9c837c840eead962d5364f774aa47869b08db2..87f5bbd68f5c8d0aaf6f81485f653a440145a952 100644
GIT binary patch
delta 59
ycmcb^^pR=832_D>V1Z&rAk796VBnv4zfw{X$jD7B%8pM?EG|ifFpCnCQyBnH+YLDY
delta 38
ocmey!bcboe3Gw8_;*wMb1_l-&W&~n3hN8seRECN7D_KB70MFV8=l}o!
diff --git a/plugins/Dfusion/src/OutFile.cpp b/plugins/Dfusion/src/OutFile.cpp
index 2d8399b03..5617175f8 100644
--- a/plugins/Dfusion/src/OutFile.cpp
+++ b/plugins/Dfusion/src/OutFile.cpp
@@ -1,19 +1,21 @@
#include "OutFile.h"
+#include
using namespace OutFile;
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);
- mystream.read((char*)&myhead,sizeof(myhead));
- for(unsigned i=0;i
Date: Wed, 17 Oct 2012 19:33:20 +0300
Subject: [PATCH 025/158] Just companion orders tool
---
scripts/gui/companion-order.lua | 398 ++++++++++++++++++++++++++++++++
1 file changed, 398 insertions(+)
create mode 100644 scripts/gui/companion-order.lua
diff --git a/scripts/gui/companion-order.lua b/scripts/gui/companion-order.lua
new file mode 100644
index 000000000..6b6a79aa2
--- /dev/null
+++ b/scripts/gui/companion-order.lua
@@ -0,0 +1,398 @@
+
+local gui = require 'gui'
+local dlg = require 'gui.dialogs'
+
+local cursor=xyz2pos(df.global.cursor.x,df.global.cursor.y,df.global.cursor.z)
+local permited_equips={}
+
+permited_equips[df.item_backpackst]="UPPERBODY"
+permited_equips[df.item_flaskst]="UPPERBODY"
+permited_equips[df.item_armorst]="UPPERBODY"
+permited_equips[df.item_shoesst]="STANCE"
+permited_equips[df.item_glovesst]="GRASP"
+permited_equips[df.item_helmst]="HEAD"
+permited_equips[df.item_pantsst]="LOWERBODY"
+function DoesHaveSubtype(item)
+ if df.item_backpackst:is_instance(item) or df.item_flaskst:is_instance(item) then
+ return false
+ end
+ return true
+end
+function CheckCursor(p)
+ if p.x==-30000 then
+ dlg.showMessage(
+ 'Companion orders',
+ 'You must have a cursor on some tile!', COLOR_LIGHTRED
+ )
+ return false
+ end
+ return true
+end
+function GetCaste(race_id,caste_id)
+ local race=df.creature_raw.find(race_id)
+ return race.caste[caste_id]
+end
+
+function EnumBodyEquipable(race_id,caste_id)
+ local caste=GetCaste(race_id,caste_id)
+ local bps=caste.body_info.body_parts
+ local ret={}
+ for k,v in pairs(bps) do
+ ret[k]={bp=v,layers={[0]={size=0,permit=0},[1]={size=0,permit=0},[2]={size=0,permit=0},[3]={size=0,permit=0} } }
+ end
+ return ret
+end
+function ReadCurrentEquiped(body_equip,unit)
+ for k,v in pairs(unit.inventory) do
+ if v.mode==2 then
+ local bpid=v.body_part_id
+ if DoesHaveSubtype(v.item) then
+ 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
+ if trg_layer.permit>sb.layer_permit then
+ trg_layer.permit=sb.layer_permit
+ end
+ end
+ trg_layer.size=trg_layer.size+sb.layer_size
+ end
+ end
+ end
+end
+function LayeringPermits(body_part,item)
+ if not DoesHaveSubtype(item) then
+ return true
+ end
+ local sb=item.subtype.props
+ local trg_layer=body_part.layers[sb.layer]
+ if math.min(trg_layer.permit ,sb.layer_permit)0 and #items>0 do
+ if(dfhack.items.moveToInventory(items[#items],v,1,grasps[#grasps])) then
+ table.remove(grasps)
+ end
+ table.remove(items)
+ end
+ local backpack=GetBackpack(v)
+ if backpack then
+ while #items>0 do
+ dfhack.items.moveToContainer(items[#items],backpack)
+ table.remove(items)
+ end
+ end
+ end
+ return true
+end},
+{name="unequip",f=function (unit_list)
+ --remove and drop all the stuff (todo maybe a gui too?)
+ for k,v in pairs(unit_list) do
+ while #v.inventory ~=0 do
+ dfhack.items.moveToGround(v.inventory[0].item,v.pos)
+ end
+ end
+ return true
+end},
+--[=[
+{name="roam not working :<",f=function (unit_list,pos,dist) --does not work
+ if not CheckCursor(pos) then
+ return false
+ end
+ dist=dist or 5
+ for k,v in pairs(unit_list) do
+ v.idle_area:assign(pos)
+ v.idle_area_threshold=dist
+ end
+ return true
+end},
+--]=]
+{name="wait",f=function (unit_list)
+ for k,v in pairs(unit_list) do
+ v.relations.group_leader_id=-1
+ end
+ return true
+end},
+{name="follow",f=function (unit_list)
+ local adv=df.global.world.units.active[0]
+ for k,v in pairs(unit_list) do
+ v.relations.group_leader_id=adv.id
+ end
+ return true
+end},
+{name="leave",f=function (unit_list)
+ 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
+ u_nem.group_leader_id=-1
+ end
+ if t_nem and u_nem then
+ for k,v in pairs(t_nem.companions) do
+ if v==u_nem.id then
+ t_nem.companions:erase(k)
+ break
+ end
+ end
+ end
+ end
+ return true
+end},
+}
+local cheats={}
+--[[ todo: add cheats...]]--
+function getCompanions(unit)
+ unit=unit or df.global.world.units.active[0]
+ local t_nem=dfhack.units.getNemesis(unit)
+ if t_nem==nil then
+ qerror("Invalid unit! No nemesis record")
+ end
+ local ret={}
+ for k,v in pairs(t_nem.companions) do
+ local u=df.nemesis_record.find(v)
+ if u.unit then
+ table.insert(ret,u.unit)
+ end
+ end
+ return ret
+end
+
+
+CompanionUi=defclass(CompanionUi,gui.FramedScreen)
+CompanionUi.ATTRS{
+ frame_title = "Companions",
+}
+function CompanionUi:init(args)
+ self.unit_list=args.unit_list
+ self.selected={}
+ for i=0,26 do
+ self.selected[i]=true
+ end
+end
+function CompanionUi:GetSelectedUnits()
+ local ret={}
+ for k,v in pairs(self.unit_list) do
+ if self.selected[k] then
+ table.insert(ret,v)
+ end
+ end
+ return ret
+end
+function CompanionUi:onInput(keys)
+
+
+ if keys.LEAVESCREEN then
+ self:dismiss()
+ elseif keys._STRING then
+ local s=keys._STRING
+ 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
+ self.selected[idx]=false
+ else
+ self.selected[idx]=true
+ end
+ end
+ if s>=string.byte('A') and s<=string.byte('Z') then
+ local idx=s-string.byte('A')+1
+ if orders[idx] and orders[idx].f then
+ if orders[idx].f(self:GetSelectedUnits(),cursor) then
+ self:dismiss()
+ end
+ end
+ --do order
+ end
+ end
+end
+function CompanionUi:onRenderBody( dc)
+ --list widget goes here...
+ local char_a=string.byte('a')-1
+ dc:newline(1):string("*. All")
+ for k,v in ipairs(self.unit_list) do
+ if self.selected[k] then
+ dc:pen(COLOR_GREEN)
+ else
+ dc:pen(COLOR_GREY)
+ end
+ dc:newline(1):string(string.char(k+char_a)..". "):string(dfhack.TranslateName(v.name));
+ end
+ dc:pen(COLOR_GREY)
+ local w,h=self:getWindowSize()
+ local char_A=string.byte('A')-1
+ for k,v in ipairs(orders) do
+ dc:seek(w/2,k):string(string.char(k+char_A)..". "):string(v.name);
+ end
+end
+local screen=CompanionUi{unit_list=getCompanions()}
+screen:show()
\ No newline at end of file
From da92fb9a1c8dfd373ac9c0781729fe722009fdcb Mon Sep 17 00:00:00 2001
From: Warmist
Date: Wed, 17 Oct 2012 21:43:44 +0300
Subject: [PATCH 026/158] Start of dfusion module. Fixed small error in
memscan.lua and start of custom embark command.
---
library/lua/memscan.lua | 2 +-
plugins/Dfusion/luafiles/embark/init.lua | 25 ++++
plugins/lua/dfusion.lua | 163 +++++++++++++++++++++++
3 files changed, 189 insertions(+), 1 deletion(-)
create mode 100644 plugins/lua/dfusion.lua
diff --git a/library/lua/memscan.lua b/library/lua/memscan.lua
index ba3efd708..6796b3563 100644
--- a/library/lua/memscan.lua
+++ b/library/lua/memscan.lua
@@ -24,7 +24,7 @@ function CheckedArray:__len()
return self.count
end
function CheckedArray:__index(idx)
- if type(idx) == number then
+ if type(idx) == "number" then
if idx >= self.count then
error('Index out of bounds: '..tostring(idx))
end
diff --git a/plugins/Dfusion/luafiles/embark/init.lua b/plugins/Dfusion/luafiles/embark/init.lua
index 529c2d1e5..aa8f2822d 100644
--- a/plugins/Dfusion/luafiles/embark/init.lua
+++ b/plugins/Dfusion/luafiles/embark/init.lua
@@ -1,3 +1,28 @@
+local dfu=require("dfusion")
+local ms=require("memscan")
+
+CustomEmbark=defclass(CustomEmbark,dfu.BinaryPlugin)
+CustomEmbark.ATTRS{filename="dfusion/embark/embark.o",name="CustomEmbark",race_caste_data=DEFAULT_NIL}
+function CustomEmbark:install()
+ local stoff=dfhack.internal.getAddress('start_dwarf_count')
+ if stoff==nil then
+ error("address for start_dwarf_count not found!")
+ end
+ local _,race_id_offset=df.sizeof(df.global.ui:_field("race_id"))
+ local needle={0x0f,0xb7,0x0d} --movzx,...
+ add_dword(needle,race_id_offset) -- ...word ptr[]
+ local mem=ms.get_code_segment()
+ local trg_offset=mem.uint8_t.find(needle,stoff)--maybe endoff=stoff+bignumber
+ if trg_offset==nil then
+ error("address for race_load not found")
+ end
+ needle={0x83,0xc8,0xff} -- or eax, 0xFF
+ local caste_offset=mem.uint8_t.find(needle,trg_offset)
+ if caste_offset==nil or caste_offset-stoff>1000 then
+ error("Caste change code not found or found too far!")
+ end
+
+end
function MakeTable(modpos,modsize,names)
count=0
castes={}
diff --git a/plugins/lua/dfusion.lua b/plugins/lua/dfusion.lua
new file mode 100644
index 000000000..06128d29b
--- /dev/null
+++ b/plugins/lua/dfusion.lua
@@ -0,0 +1,163 @@
+-- Stuff used by dfusion
+local _ENV = mkmodule('plugins.dfusion')
+
+local ms=require("memscan")
+
+local marker={0xDE,0xAD,0xBE,0xEF}
+patches={}
+-- A reversable binary patch
+BinaryPatch=defclass(BinaryPatch)
+BinaryPatch.ATTRS {pre_data=DEFAULT_NIL,data=DEFAULT_NIL,address=DEFAULT_NIL,name=DEFAULT_NIL}
+function BinaryPatch:init(args)
+ self.is_applied=false
+ if args.pre_data==nil or args.data==nil or args.address==nil or args.name==nil then
+ error("Invalid parameters to binary patch")
+ end
+ if patches[self.name]~=nil then
+ error("Patch already exist")
+ end
+ self.max_val=0
+ for k,v in pairs(args.pre_data) do
+ if type(k)~="number" then
+ error("non number key in pre_data")
+ end
+ if self.max_val
Date: Sun, 21 Oct 2012 13:42:55 +0300
Subject: [PATCH 027/158] More work on dfusion. Embark anywhere script
separated.
---
plugins/Dfusion/dfusion.cpp | 20 ++++
plugins/Dfusion/luafiles/embark/init.lua | 137 ++++++++---------------
plugins/devel/CMakeLists.txt | 1 -
plugins/lua/dfusion.lua | 113 ++++++++++++-------
scripts/dfusion.lua | 2 +
scripts/embark.lua | 53 +++++++++
6 files changed, 196 insertions(+), 130 deletions(-)
create mode 100644 scripts/dfusion.lua
create mode 100644 scripts/embark.lua
diff --git a/plugins/Dfusion/dfusion.cpp b/plugins/Dfusion/dfusion.cpp
index daacc0b26..4507f9a15 100644
--- a/plugins/Dfusion/dfusion.cpp
+++ b/plugins/Dfusion/dfusion.cpp
@@ -58,8 +58,28 @@ static int loadObjectFile(lua_State* L)
lua_setfield(L,table_pos,"symbols");
return 1;
}
+static int markAsExecutable(lua_State* L)
+{
+ unsigned addr=luaL_checkunsigned(L,1);
+ std::vector ranges;
+ DFHack::Core::getInstance().p->getMemRanges(ranges);
+ for(size_t i=0;isetPermisions(ranges[i],newperm);
+ return 0;
+ }
+ }
+ lua_pushlstring(L,"Memory range not found",23);
+ lua_error(L);
+ return 0;
+}
DFHACK_PLUGIN_LUA_COMMANDS {
DFHACK_LUA_COMMAND(loadObjectFile),
+ DFHACK_LUA_COMMAND(markAsExecutable),
DFHACK_LUA_END
};
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector &commands)
diff --git a/plugins/Dfusion/luafiles/embark/init.lua b/plugins/Dfusion/luafiles/embark/init.lua
index aa8f2822d..76be00c72 100644
--- a/plugins/Dfusion/luafiles/embark/init.lua
+++ b/plugins/Dfusion/luafiles/embark/init.lua
@@ -1,108 +1,69 @@
-local dfu=require("dfusion")
+local dfu=require("plugins.dfusion")
local ms=require("memscan")
-
+local MAX_RACES=100
CustomEmbark=defclass(CustomEmbark,dfu.BinaryPlugin)
CustomEmbark.ATTRS{filename="dfusion/embark/embark.o",name="CustomEmbark",race_caste_data=DEFAULT_NIL}
function CustomEmbark:install()
local stoff=dfhack.internal.getAddress('start_dwarf_count')
+ if #self.race_caste_data<7 then
+ error("caste and race count must be bigger than 6")
+ end
+ if #self.race_caste_data>MAX_RACES then
+ error("caste and race count must be less then "..MAX_RACES)
+ end
if stoff==nil then
error("address for start_dwarf_count not found!")
end
local _,race_id_offset=df.sizeof(df.global.ui:_field("race_id"))
- local needle={0x0f,0xb7,0x0d} --movzx,...
- add_dword(needle,race_id_offset) -- ...word ptr[]
+ print(string.format("start=%08x",stoff))
+ local needle={0x0f,0xb7,0x0d} --movzx eax,dword ptr [race_id]
+ local tmp_table=dfu.dwordToTable(race_id_offset)
+ for k,v in ipairs(tmp_table) do
+ table.insert(needle,v)
+ end
+
local mem=ms.get_code_segment()
- local trg_offset=mem.uint8_t.find(needle,stoff)--maybe endoff=stoff+bignumber
+ 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
if trg_offset==nil then
error("address for race_load not found")
end
+ local call_data={0x90,0x90}
+ local _,data_offset=df.sizeof(self.data)
+ dfu.concatTables(call_data,dfu.makeCall(trg_offset+2,data_offset))
+ self.call_patch=dfu.BinaryPatch{pre_data=needle,data=call_data,address=trg_offset,name="custom_embark_call_patch"}
needle={0x83,0xc8,0xff} -- or eax, 0xFF
- local caste_offset=mem.uint8_t.find(needle,trg_offset)
+ local _,caste_offset=mem.uint8_t:find(needle,mem.uint8_t:addr2idx(trg_offset),nil)
if caste_offset==nil or caste_offset-stoff>1000 then
error("Caste change code not found or found too far!")
end
+ self.disable_castes=dfu.BinaryPatch{pre_data={0x83,0xc8,0xff},data={0x90,0x90,0x90},address=caste_offset,name="custom_embark_caste_disable"}
+ self.disable_castes:apply()
+ 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()
+ local caste_array=self:allocate("caste_array","uint16_t",#self.race_caste_data)
+ local race_array=self:allocate("race_array","uint16_t",#self.race_caste_data)
+ for k,v in ipairs(self.race_caste_data) do
+ caste_array[k-1]=v[2]
+ race_array[k-1]=v[1]
+ end
+ 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 MakeTable(modpos,modsize,names)
- count=0
- castes={}
- --print("Making table")
- for _,line in pairs(names) do
- --print("Line:"..line)
- tpos=string.find(line,":")
- if tpos~=nil then
- --print("Was line:"..line)
- table.insert(castes,tonumber(string.sub(line,tpos+1)))
- line=string.sub(line,1,tpos-1)
- --print("IS line:"..line)
- else
- table.insert(castes,-1)
- end
- if RaceTable[line] == nil then
- error("Failure, "..line.." not found!")
- end
- --print("adding:"..line.." id:"..RaceTable[line])
- engine.pokew(modpos+modsize+count*2,RaceTable[line]) -- add race
- count = count + 1
- end
- i=0
- for _,caste in pairs(castes) do
-
- engine.pokew(modpos+modsize+count*2+i*2,caste) -- add caste
- i= i+1
- end
-
- engine.poked(stoff,count)
- return count
-end
-function embark(names)
- RaceTable=RaceTable or BuildNameTable()
- mypos=engine.getmod('Embark')
- stoff=VersionInfo.getAddress('start_dwarf_count')
- if mypos then --if mod already loaded
- print("Mod already loaded @:"..mypos.." just updating")
- modpos=mypos
- _,modsize=engine.loadobj('dfusion/embark/embark.o')
-
- count=MakeTable(modpos,modsize,names) --just remake tables
- else
-
- _,tofind=df.sizeof(df.global.ui:_field("race_id"))
-
- loc=offsets.find(stoff,0x0f,0xb7,0x0d,DWORD_,tofind) --MOVZX ECX,WORD PTR[]
-
- print(string.format("found:%x",loc))
- if((loc~=0)and(loc-stoff<1000)) then
- loc2=offsets.find(loc,0x83,0xc8,0xff) -- or eax, ffffff (for caste)
- if loc2== 0 then
- error ("Location for caste nulling not found!")
- end
- engine.pokeb(loc2,0x90)
- engine.pokeb(loc2+1,0x90)
- engine.pokeb(loc2+2,0x90)
- ModData=engine.installMod("dfusion/embark/embark.o","Embark",256)
- modpos=ModData.pos
- modsize=ModData.size
- local castepos=modpos+engine.FindMarker(ModData,"caste")
- local racepos=modpos+engine.FindMarker(ModData,"race")
- count=MakeTable(modpos,modsize,names)
- engine.poked(castepos,modpos+modsize) --fix array start for race
- engine.poked(racepos,modpos+modsize+count*2) --fix array start for caste
- print("sucess loading mod @:"..modpos)
- -- build race vector after module.
-
-
- --finaly poke in the call!
- engine.pokeb(loc,0x90)
- engine.pokeb(loc+1,0x90)
- engine.pokeb(loc+2,0xe8)
- engine.poked(loc+3,modpos-loc-7)
- --engine.pokeb(loc+5,0x90)
-
- SetExecute(modpos)
- else
- error("did not find patch location, failing...")
- end
-
- end
+function CustomEmbark:uninstall()
+ if self.installed then
+ self.call_patch:remove()
+ self.disable_castes:remove()
+ self.dwarfcount:remove()
+ end
end
\ No newline at end of file
diff --git a/plugins/devel/CMakeLists.txt b/plugins/devel/CMakeLists.txt
index f126ae53b..134d5cb67 100644
--- a/plugins/devel/CMakeLists.txt
+++ b/plugins/devel/CMakeLists.txt
@@ -18,7 +18,6 @@ DFHACK_PLUGIN(stripcaged stripcaged.cpp)
DFHACK_PLUGIN(rprobe rprobe.cpp)
DFHACK_PLUGIN(nestboxes nestboxes.cpp)
DFHACK_PLUGIN(vshook vshook.cpp)
-DFHACK_PLUGIN(steam-engine steam-engine.cpp)
IF(UNIX)
DFHACK_PLUGIN(ref-index ref-index.cpp)
ENDIF()
diff --git a/plugins/lua/dfusion.lua b/plugins/lua/dfusion.lua
index 06128d29b..46f28f78e 100644
--- a/plugins/lua/dfusion.lua
+++ b/plugins/lua/dfusion.lua
@@ -4,8 +4,23 @@ local _ENV = mkmodule('plugins.dfusion')
local ms=require("memscan")
local marker={0xDE,0xAD,0xBE,0xEF}
-patches={}
+--utility functions
+function dwordToTable(dword)
+ local b={bit32.extract(dword,0,8),bit32.extract(dword,8,8),bit32.extract(dword,16,8),bit32.extract(dword,24,8)}
+ return b
+end
+function concatTables(t1,t2)
+ for k,v in pairs(t2) do
+ table.insert(t1,v)
+ end
+end
+function makeCall(from,to)
+ local ret={0xe8}
+ concatTables(ret,dwordToTable(to-from-5))
+ return ret
+end
-- A reversable binary patch
+patches={}
BinaryPatch=defclass(BinaryPatch)
BinaryPatch.ATTRS {pre_data=DEFAULT_NIL,data=DEFAULT_NIL,address=DEFAULT_NIL,name=DEFAULT_NIL}
function BinaryPatch:init(args)
@@ -16,19 +31,8 @@ function BinaryPatch:init(args)
if patches[self.name]~=nil then
error("Patch already exist")
end
- self.max_val=0
- for k,v in pairs(args.pre_data) do
- if type(k)~="number" then
- error("non number key in pre_data")
- end
- if self.max_val
Date: Sun, 21 Oct 2012 13:46:12 +0300
Subject: [PATCH 028/158] Small error fix
---
plugins/lua/dfusion.lua | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plugins/lua/dfusion.lua b/plugins/lua/dfusion.lua
index 46f28f78e..ac9a20868 100644
--- a/plugins/lua/dfusion.lua
+++ b/plugins/lua/dfusion.lua
@@ -52,7 +52,7 @@ function BinaryPatch:test()
end
function BinaryPatch:apply()
if not self:test() then
- error(string.format("pre-data for binary patch does not match expected")
+ error(string.format("pre-data for binary patch does not match expected"))
end
local post_buf=df.new('uint8_t',#self.pre_data)
From dfa3a520fd2e7243413d5dc38d253fd17e072c1e Mon Sep 17 00:00:00 2001
From: Kelly Martin
Date: Sun, 21 Oct 2012 16:34:13 -0500
Subject: [PATCH 029/158] sync structures
---
library/xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/library/xml b/library/xml
index b9b2e8c6d..e06438924 160000
--- a/library/xml
+++ b/library/xml
@@ -1 +1 @@
-Subproject commit b9b2e8c6d2141f13966ed965b3f3ffe924e527db
+Subproject commit e06438924929a8ecab751c0c233dad5767e91f7e
From 209d593f2173e70085fe287d7635c03d66b94cd2 Mon Sep 17 00:00:00 2001
From: Warmist
Date: Thu, 1 Nov 2012 16:00:00 +0200
Subject: [PATCH 030/158] Another day, another commit.
---
plugins/Dfusion/luafiles/embark/init.lua | 146 +++++++++++++---------
plugins/lua/dfusion.lua | 19 ++-
plugins/lua/dfusion/embark.lua | 148 +++++++++++++++++++++++
plugins/lua/dfusion/embark.o | Bin 0 -> 369 bytes
scripts/dfusion.lua | 40 ++++++
5 files changed, 289 insertions(+), 64 deletions(-)
create mode 100644 plugins/lua/dfusion/embark.lua
create mode 100644 plugins/lua/dfusion/embark.o
diff --git a/plugins/Dfusion/luafiles/embark/init.lua b/plugins/Dfusion/luafiles/embark/init.lua
index 76be00c72..b7795d049 100644
--- a/plugins/Dfusion/luafiles/embark/init.lua
+++ b/plugins/Dfusion/luafiles/embark/init.lua
@@ -2,68 +2,94 @@ local dfu=require("plugins.dfusion")
local ms=require("memscan")
local MAX_RACES=100
CustomEmbark=defclass(CustomEmbark,dfu.BinaryPlugin)
-CustomEmbark.ATTRS{filename="dfusion/embark/embark.o",name="CustomEmbark",race_caste_data=DEFAULT_NIL}
-function CustomEmbark:install()
- local stoff=dfhack.internal.getAddress('start_dwarf_count')
- if #self.race_caste_data<7 then
- error("caste and race count must be bigger than 6")
+local myos=dfhack.getOSType()
+if myos=="windows" then
+
+ CustomEmbark.ATTRS{filename="dfusion/embark/embark.o",name="CustomEmbark",race_caste_data=DEFAULT_NIL}
+ CustomEmbark.class_status="valid, not installed"
+ function CustomEmbark:install()
+ local stoff=dfhack.internal.getAddress('start_dwarf_count')
+
+ if #self.race_caste_data<7 then
+ error("caste and race count must be bigger than 6")
+ end
+ if #self.race_caste_data>MAX_RACES then
+ error("caste and race count must be less then "..MAX_RACES)
+ end
+ if stoff==nil then
+ error("address for start_dwarf_count not found!")
+ end
+ local _,race_id_offset=df.sizeof(df.global.ui:_field("race_id"))
+ print(string.format("start=%08x",stoff))
+ local needle={0x0f,0xb7,0x0d} --movzx eax,dword ptr [race_id]
+ local tmp_table=dfu.dwordToTable(race_id_offset)
+ for k,v in ipairs(tmp_table) do
+ table.insert(needle,v)
+ end
+
+ 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
+ if trg_offset==nil then
+ error("address for race_load not found")
+ end
+ local call_data={0x90,0x90}
+ local _,data_offset=df.sizeof(self.data)
+ dfu.concatTables(call_data,dfu.makeCall(trg_offset+2,data_offset))
+ self.call_patch=dfu.BinaryPatch{pre_data=needle,data=call_data,address=trg_offset,name="custom_embark_call_patch"}
+ needle={0x83,0xc8,0xff} -- or eax, 0xFF
+ local _,caste_offset=mem.uint8_t:find(needle,mem.uint8_t:addr2idx(trg_offset),nil)
+ if caste_offset==nil or caste_offset-stoff>1000 then
+ error("Caste change code not found or found too far!")
+ end
+
+ self.disable_castes=dfu.BinaryPatch{pre_data={0x83,0xc8,0xff},data={0x90,0x90,0x90},address=caste_offset,name="custom_embark_caste_disable"}
+ self.disable_castes:apply()
+ 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()
+ local caste_array=self:allocate("caste_array","uint16_t",#self.race_caste_data)
+ local race_array=self:allocate("race_array","uint16_t",#self.race_caste_data)
+ self:setEmbarkParty(self.race_caste_data)
+ for k,v in ipairs(self.race_caste_data) do
+ caste_array[k-1]=v[2]
+ race_array[k-1]=v[1]
+ end
+ 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
- if #self.race_caste_data>MAX_RACES then
- error("caste and race count must be less then "..MAX_RACES)
+ function CustomEmbark:setEmbarkParty(racesAndCastes)
+ self.race_caste_data=racesAndCastes
+ 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()
+ else
+ self.dwarfcount:repatch(dfu.dwordToTable(#self.race_caste_data))
+ end
+
end
- if stoff==nil then
- error("address for start_dwarf_count not found!")
+ function CustomEmbark:status()
+ if self.installed then
+ return "valid, installed"
+ else
+ return "valid, not installed"
+ end
end
- local _,race_id_offset=df.sizeof(df.global.ui:_field("race_id"))
- print(string.format("start=%08x",stoff))
- local needle={0x0f,0xb7,0x0d} --movzx eax,dword ptr [race_id]
- local tmp_table=dfu.dwordToTable(race_id_offset)
- for k,v in ipairs(tmp_table) do
- table.insert(needle,v)
- end
-
- 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
- if trg_offset==nil then
- error("address for race_load not found")
- end
- local call_data={0x90,0x90}
- local _,data_offset=df.sizeof(self.data)
- dfu.concatTables(call_data,dfu.makeCall(trg_offset+2,data_offset))
- self.call_patch=dfu.BinaryPatch{pre_data=needle,data=call_data,address=trg_offset,name="custom_embark_call_patch"}
- needle={0x83,0xc8,0xff} -- or eax, 0xFF
- local _,caste_offset=mem.uint8_t:find(needle,mem.uint8_t:addr2idx(trg_offset),nil)
- if caste_offset==nil or caste_offset-stoff>1000 then
- error("Caste change code not found or found too far!")
- end
-
- self.disable_castes=dfu.BinaryPatch{pre_data={0x83,0xc8,0xff},data={0x90,0x90,0x90},address=caste_offset,name="custom_embark_caste_disable"}
- self.disable_castes:apply()
- 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()
- local caste_array=self:allocate("caste_array","uint16_t",#self.race_caste_data)
- local race_array=self:allocate("race_array","uint16_t",#self.race_caste_data)
- for k,v in ipairs(self.race_caste_data) do
- caste_array[k-1]=v[2]
- race_array[k-1]=v[1]
- end
- 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:uninstall()
- if self.installed then
- self.call_patch:remove()
- self.disable_castes:remove()
- self.dwarfcount:remove()
+ function CustomEmbark:uninstall()
+ if self.installed then
+ self.call_patch:remove()
+ self.disable_castes:remove()
+ self.dwarfcount:remove()
+ end
end
+else
+ CustomEmbark.class_status="invalid, os not supported"
end
\ No newline at end of file
diff --git a/plugins/lua/dfusion.lua b/plugins/lua/dfusion.lua
index ac9a20868..053c486cf 100644
--- a/plugins/lua/dfusion.lua
+++ b/plugins/lua/dfusion.lua
@@ -107,6 +107,7 @@ end
-- A binary hack (obj file) loader/manager
-- has to have: a way to get offsets for marked areas (for post load modification) or some way to do that pre-load
-- page managing (including excecute/write flags for DEP and the like)
+-- TODO plugin state enum, a way to modify post install (could include repatching code...)
plugins=plugins or {}
BinaryPlugin=defclass(BinaryPlugin)
BinaryPlugin.ATTRS {filename=DEFAULT_NIL,reloc_table={},name=DEFAULT_NIL}
@@ -115,14 +116,21 @@ function BinaryPlugin:init(args)
end
function BinaryPlugin:postinit(args)
if self.name==nil then error("Not a valid plugin name!") end
- --if plugins[args.name]==nil then
+ if plugins[args.name]==nil then
plugins[self.name]=self
- --else
- -- error("Trying to create a same plugin")
- --end
+ else
+ error("Trying to create a same plugin")
+ end
self.allocated_object={}
self:load()
end
+function BinaryPlugin:get_or_alloc(name,typename,arrsize)
+ if self.allocated_object[name]~=nil then
+ return self.allocated_object[name]
+ else
+ return self:allocate(name,typename,arrsize)
+ end
+end
function BinaryPlugin:allocate(name,typename,arrsize)
local trg
if df[typename]==nil then
@@ -182,6 +190,9 @@ function BinaryPlugin:print_data()
end
print(out)
end
+function BinaryPlugin:status()
+ return "invalid, base class only!"
+end
function BinaryPlugin:__gc()
for k,v in pairs(self.allocated_object) do
df.delete(v)
diff --git a/plugins/lua/dfusion/embark.lua b/plugins/lua/dfusion/embark.lua
new file mode 100644
index 000000000..a674a96d3
--- /dev/null
+++ b/plugins/lua/dfusion/embark.lua
@@ -0,0 +1,148 @@
+local _ENV = mkmodule('plugins.dfusion.embark')
+local dfu=require("plugins.dfusion")
+local ms=require("memscan")
+local MAX_RACES=100
+CustomEmbark=defclass(CustomEmbark,dfu.BinaryPlugin)
+CustomEmbark.name="CustomEmbark"
+local myos=dfhack.getOSType()
+if myos=="windows" then
+ CustomEmbark.ATTRS{filename="hack/lua/plugins/dfusion/embark.o",name="CustomEmbark",race_caste_data=DEFAULT_NIL}
+ CustomEmbark.class_status="valid, not installed"
+ function CustomEmbark:install()
+ local stoff=dfhack.internal.getAddress('start_dwarf_count')
+
+ if #self.race_caste_data<7 then
+ error("caste and race count must be bigger than 6")
+ end
+ if #self.race_caste_data>MAX_RACES then
+ error("caste and race count must be less then "..MAX_RACES)
+ end
+ if stoff==nil then
+ error("address for start_dwarf_count not found!")
+ end
+ local _,race_id_offset=df.sizeof(df.global.ui:_field("race_id"))
+ print(string.format("start=%08x",stoff))
+ local needle={0x0f,0xb7,0x0d} --movzx eax,dword ptr [race_id]
+ local tmp_table=dfu.dwordToTable(race_id_offset)
+ for k,v in ipairs(tmp_table) do
+ table.insert(needle,v)
+ end
+
+ 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
+ if trg_offset==nil then
+ error("address for race_load not found")
+ end
+ local call_data={0x90,0x90}
+ local _,data_offset=df.sizeof(self.data)
+ dfu.concatTables(call_data,dfu.makeCall(trg_offset+2,data_offset))
+ self.call_patch=dfu.BinaryPatch{pre_data=needle,data=call_data,address=trg_offset,name="custom_embark_call_patch"}
+ needle={0x83,0xc8,0xff} -- or eax, 0xFF
+ local _,caste_offset=mem.uint8_t:find(needle,mem.uint8_t:addr2idx(trg_offset),nil)
+ if caste_offset==nil or caste_offset-stoff>1000 then
+ error("Caste change code not found or found too far!")
+ end
+
+ self.disable_castes=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 #racesAndCastes<7 then
+ error("caste and race count must be bigger than 6")
+ end
+ if #racesAndCastes>MAX_RACES then
+ error("caste and race count must be less then "..MAX_RACES)
+ end
+
+ self.race_caste_data=racesAndCastes
+ 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()
+ else
+ self.dwarfcount:repatch(dfu.dwordToTable(#self.race_caste_data))
+ 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]
+ race_array[k-1]=v[1]
+ end
+ end
+ function CustomEmbark:status()
+ if self.installed then
+ return "valid, installed"
+ else
+ return "valid, not installed"
+ end
+ end
+ function CustomEmbark:uninstall()
+ if self.installed then
+ self.call_patch:remove()
+ self.disable_castes:remove()
+ self.dwarfcount:remove()
+ end
+ end
+ function CustomEmbark:edit()
+ local data=self.race_caste_data or {}
+ print(string.format("Old race count:%d",#data))
+ local endthis=false
+ print("current:")
+ while(not endthis) do
+ print(" # RaceId Race name Caste num")
+ for k,v in pairs(data) do
+ local name=df.creature_raw.find(v[1]).creature_id or ""
+ print(string.format("%3d. %6d %20s %d",k,v[1],name,v[2]))
+ end
+ print("a- add, r-remove, c-cancel, s-save and update")
+ local choice=io.stdin:read()
+ if choice=='a' then
+ print("Enter new race then caste ids:")
+ local race=tonumber(io.stdin:read())
+ local caste=tonumber(io.stdin:read())
+ if race and caste then
+ table.insert(data,{race,caste})
+ else
+ print("input parse error")
+ end
+ elseif choice=='r' then
+ print("enter number to remove:")
+ local num_rem=tonumber(io.stdin:read())
+ if num_rem~=nil then
+ table.remove(data,num_rem)
+ end
+ elseif choice=='c' then
+ endthis=true
+ elseif choice=='s' then
+ endthis=true
+ if self.installed then
+ self:setEmbarkParty(data)
+ else
+ self.race_caste_data=data
+ self:install()
+ end
+ end
+ end
+ end
+else
+ CustomEmbark.class_status="invalid, os not supported"
+end
+return _ENV
\ No newline at end of file
diff --git a/plugins/lua/dfusion/embark.o b/plugins/lua/dfusion/embark.o
new file mode 100644
index 0000000000000000000000000000000000000000..87f5bbd68f5c8d0aaf6f81485f653a440145a952
GIT binary patch
literal 369
zcmeZaWM%+?B|yvtX0bBrm84dbfY}g20!Z~B@j*-l27?5>l*E!mG;wsU1B1Z
Date: Fri, 2 Nov 2012 00:28:16 +0200
Subject: [PATCH 031/158] New way of doing things! Now using a class for menus,
also no (non script) way to use bin-plugins.
---
plugins/Dfusion/luafiles/adv_tools/init.lua | 133 --------------------
plugins/Dfusion/luafiles/common.lua | 32 +----
plugins/lua/dfusion.lua | 35 ++++++
plugins/lua/dfusion/adv_tools.lua | 52 ++++++++
scripts/dfusion.lua | 47 ++-----
5 files changed, 96 insertions(+), 203 deletions(-)
delete mode 100644 plugins/Dfusion/luafiles/adv_tools/init.lua
create mode 100644 plugins/lua/dfusion/adv_tools.lua
diff --git a/plugins/Dfusion/luafiles/adv_tools/init.lua b/plugins/Dfusion/luafiles/adv_tools/init.lua
deleted file mode 100644
index 566484f01..000000000
--- a/plugins/Dfusion/luafiles/adv_tools/init.lua
+++ /dev/null
@@ -1,133 +0,0 @@
-adv_tools= {}
-adv_tools.menu=MakeMenu()
---TODO make every tool generic (work for both modes)
-function adv_tools.reincarnate(swap_soul) --only for adventurer i guess
- if swap_soul==nil then
- swap_soul=true
- end
- local adv=df.global.world.units.active[0]
- if adv.flags1.dead==false then
- error("You are not dead (yet)!")
- end
- local hist_fig=getNemesis(adv).figure
- if hist_fig==nil then
- error("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==hist_fig.id then
- --print("Is same id:"..i)
- trg_hist_fig=events[i].slayer
- 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)
-
- tools.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
-adv_tools.menu:add("Reincarnate",adv_tools.reincarnate)
-function adv_tools.ressurect()
-
- v2=engine.peek(vector:getval(indx),ptr_Creature.hurt1)
- for i=0,v2:size()-1 do
- v2:setval(i,0)
- end
- v2=engine.peek(vector:getval(indx),ptr_Creature.hurt2)
- v2.type=DWORD
- for i=0,v2:size()-1 do
- v2:setval(i,0)
- end
- engine.poke(vector:getval(indx),ptr_Creature.bloodlvl,60000) --give blood
- engine.poke(vector:getval(indx),ptr_Creature.bleedlvl,0) --stop some bleeding...
- local flg=engine.peek(vector:getval(indx),ptr_Creature.flags)
- flg:set(1,false) --ALIVE
- flg:set(39,false) -- leave body yet again
- flg:set(37,false) -- something todo with wounds- lets you walk again.
- flg:set(58,true) -- makes them able to breathe
- flg:set(61,true) -- gives them sight
- engine.poke(vector:getval(indx),ptr_Creature.flags,flg)
-end
-
-function adv_tools.wagonmode() --by rumrusher
- --first three lines same as before (because we will need an offset of creature at location x,y,z)
- myoff=offsets.getEx("AdvCreatureVec")
- vector=engine.peek(myoff,ptr_vector)
- indx=GetCreatureAtPos(getxyz())
- --indx=0
- --print(string.format("%x",vector:getval(indx)))
- flg=engine.peek(vector:getval(indx),ptr_Creature.flags) --get flags
- flg:set(1,false)
- flg:set(74,false)
- engine.poke(vector:getval(indx),ptr_Creature.flags,flg)
- print("To stay normal press y, else hit Enter turn Wagon mode on.")
- r=io.stdin:read() -- repeat for it too work... also creature will be dead.
- if r== "y" then
- flg=engine.peek(vector:getval(indx),ptr_Creature.flags)
- flg:set(1,false)
- engine.poke(vector:getval(indx),ptr_Creature.flags,flg)
- else
- flg=engine.peek(vector:getval(indx),ptr_Creature.flags)
- flg:set(1,false)
- flg:flip(74)
- engine.poke(vector:getval(indx),ptr_Creature.flags,flg)
- end
-end
-function selectall()
- local retvec={} --return vector (or a list)
- myoff=offsets.getEx("AdvCreatureVec")
- vector=engine.peek(myoff,ptr_vector) --standart start
- for i=0,vector:size()-1 do --check all creatures
- local off
- off=vector:getval(i)
- local flags=engine.peek(off,ptr_Creature.flags)
- if flags:get(1)==true then --if dead ...
- table.insert(retvec,off)--... add it to return vector
- end
- end
- return retvec --return the "return vector" :)
-end
-function adv_tools.hostilate()
- vector=engine.peek(offsets.getEx("AdvCreatureVec"),ptr_vector)
- id=GetCreatureAtPos(getxyz())
- print(string.format("Vec:%d cr:%d",vector:size(),id))
- off=vector:getval(id)
- crciv=engine.peek(vector:getval(id),ptr_Creature.civ)
- curciv=engine.peek(vector:getval(0),ptr_Creature.civ)
-
- if curciv==crciv then
- print("Friendly-making enemy")
- engine.poke(off,ptr_Creature.civ,-1)
- flg=engine.peek(off,ptr_Creature.flags)
- flg:set(17,true)
- engine.poke(off,ptr_Creature.flags,flg)
- else
- print("Enemy- making friendly")
- engine.poke(off,ptr_Creature.civ,curciv)
- flg=engine.peek(off,ptr_Creature.flags)
- flg:set(17,false)
- flg:set(19,false)
- engine.poke(off,ptr_Creature.flags,flg)
- end
-end
diff --git a/plugins/Dfusion/luafiles/common.lua b/plugins/Dfusion/luafiles/common.lua
index a6781b385..bdf3a2bc8 100644
--- a/plugins/Dfusion/luafiles/common.lua
+++ b/plugins/Dfusion/luafiles/common.lua
@@ -242,37 +242,7 @@ function engine.installMod(file,name,bonussize)
return T
end
-it_menu={}
-it_menu.__index=it_menu
-function it_menu:add(name,func)
- table.insert(self.items,{func,name})
-end
-function it_menu: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=getline("")
- 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("incorrect choice")
- end
-
- until ans~=nil and (ans<=#self.items and ans>0)
- self.items[ans][1]()
-end
-function MakeMenu()
- local ret={}
- ret.items={}
- setmetatable(ret,it_menu)
- return ret
-end
+
function PrintPattern(loadedpattern)
for k,v in pairs(loadedpattern) do
diff --git a/plugins/lua/dfusion.lua b/plugins/lua/dfusion.lua
index 053c486cf..c7bd9bef3 100644
--- a/plugins/lua/dfusion.lua
+++ b/plugins/lua/dfusion.lua
@@ -202,4 +202,39 @@ function BinaryPlugin:__gc()
end
self.data:delete()
end
+-- a Menu for some stuff. Maybe add a posibility of it working as a gui, or a gui adaptor?
+-- Todo add hints, and parse them to make a "smart" choice of parameters to pass
+SimpleMenu=defclass(SimpleMenu)
+SimpleMenu.ATTRS{title=DEFAULT_NIL}
+function SimpleMenu:init(args)
+ self.items={}
+end
+function SimpleMenu:add(name,entry,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=io.stdin:read()
+ 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
+ self.items[ans][1]:display()
+ end
+end
+
return _ENV
\ No newline at end of file
diff --git a/plugins/lua/dfusion/adv_tools.lua b/plugins/lua/dfusion/adv_tools.lua
new file mode 100644
index 000000000..4440a4b2f
--- /dev/null
+++ b/plugins/lua/dfusion/adv_tools.lua
@@ -0,0 +1,52 @@
+local _ENV = mkmodule('plugins.dfusion.adv_tools')
+local dfu=require("plugins.dfusion")
+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=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==hist_fig.id then
+ --print("Is same id:"..i)
+ trg_hist_fig=events[i].slayer
+ 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)
+
+ tools.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
+
+return _ENV
\ No newline at end of file
diff --git a/scripts/dfusion.lua b/scripts/dfusion.lua
index 63a530454..4fee0438e 100644
--- a/scripts/dfusion.lua
+++ b/scripts/dfusion.lua
@@ -1,42 +1,11 @@
--- a binary hack/plugin collection for df
+-- a collection of misc lua scripts
local dfu=require("plugins.dfusion")
local myos=dfhack.getOSType()
-
---some imports go here
-local plugins={
- require("plugins.dfusion.embark").CustomEmbark
-}
---show a table of all the statuses
-function status(plug)
- if dfu.plugins[plug.name]==nil then
- return plug.class_status
- else
- return dfu.plugins[plug.name]:status()
- end
+args={...}
+mainmenu=dfu.SimpleMenu()
+function runsave()
+ print("doing file:"..df.global.world.cur_savegame.save_dir)
end
-function printPlugs()
- local endthis=false
- print("current:")
- while(not endthis) do
- for k,v in pairs(plugins) do
- if v then
- print(string.format("%2d. %15s-%s",k,v.name,status(v)))
- end
- end
- print("e-edit and load, u-unload,c-cancel and then number to manipulate:")
- local choice=io.stdin:read()
- local num=tonumber(io.stdin:read())
- if num then
- local plg=dfu.plugins[plugins[num].name] or plugins[num]()
- if choice=='e' then
- plg:edit()
- elseif choice=='u' then
- plg:uninstall()
- elseif choice=='c' then
- endthis=true
- end
- end
- end
-end
-
-printPlugs()
\ No newline at end of file
+mainmenu:add("Run save script",runsave)
+mainmenu:add("Adventurer tools",require("plugins.dfusion.adv_tools").menu)
+mainmenu:display()
\ No newline at end of file
From 296d1cf090745c9bb667ddb8d30395ad431d13ef Mon Sep 17 00:00:00 2001
From: Warmist
Date: Fri, 2 Nov 2012 00:50:20 +0200
Subject: [PATCH 032/158] More scripts for dfusion. Only fixes left, and
updating bin-plugins (friendship and migrants(??))
---
plugins/lua/dfusion/adv_tools.lua | 68 ++++++++++++-
plugins/lua/dfusion/tools.lua | 164 ++++++++++++++++++++++++++++++
scripts/dfusion.lua | 5 +-
3 files changed, 234 insertions(+), 3 deletions(-)
create mode 100644 plugins/lua/dfusion/tools.lua
diff --git a/plugins/lua/dfusion/adv_tools.lua b/plugins/lua/dfusion/adv_tools.lua
index 4440a4b2f..31e83b234 100644
--- a/plugins/lua/dfusion/adv_tools.lua
+++ b/plugins/lua/dfusion/adv_tools.lua
@@ -48,5 +48,69 @@ function Reincarnate(trg_unit,swap_soul) --only for adventurer i guess
end
end
menu:add("Reincarnate",Reincarnate,{{df.unit,"optional"}})-- bool, optional
-
-return _ENV
\ No newline at end of file
+function change_adv(unit,nemesis)
+ if nemesis==nil then
+ nemesis=true --default value is nemesis switch too.
+ end
+ if unit==nil then
+ unit=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=getNemesis(unit)
+ local other_nem=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
+ error("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}
+ local pos={x=sub_pos.x+region_pos.x*48,y=sub_pos.y+region_pos.y*48,z=sub_pos.z+region_pos.z}
+ local state
+ if adv.flags1.dead then
+ state="dead"
+ else
+ state="live n kicking"
+ end
+ local message=string.format("%s %s at pos={%d,%d,%d} region={%d,%d,%d}",dfhack.TranslateName(adv.name),state,pos.x,pos.y,pos.z,region_pos.x,region_pos.y,region_pos.z)
+ print(message)
+ local path="deaths_"..df.global.world.cur_savegame.save_dir..".txt"
+ local f=io.open(path,"a")
+ f:write(message)
+ f:close()
+end
+menu:add("Log adventurers position",log_pos)
+return _ENV
diff --git a/plugins/lua/dfusion/tools.lua b/plugins/lua/dfusion/tools.lua
new file mode 100644
index 000000000..9ddfb8e45
--- /dev/null
+++ b/plugins/lua/dfusion/tools.lua
@@ -0,0 +1,164 @@
+local _ENV = mkmodule('plugins.dfusion.tools')
+local dfu=require("plugins.dfusion")
+local ms=require "memscan"
+menu=dfu.SimpleMenu()
+function setrace(name) --TODO FIX
+ RaceTable=BuildNameTable()
+ print("Your current race is:"..GetRaceToken(df.global.ui.race_id))
+ local id
+ if name == nil then
+ print("Type new race's token name in full caps (q to quit):")
+ repeat
+ entry=getline()
+ 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) --TODO FIX
+ RaceTable=RaceTable or BuildNameTable() --slow.If loaded don't load again
+ if names ==nil then
+ ids={}
+ print("Type race's token name in full caps to give sentience to:")
+ repeat
+ entry=getline()
+ id=RaceTable[entry]
+ until id~=nil
+ table.insert(ids,id)
+ 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.size))
+ 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=getNemesis(unit)
+ local t_nem=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.refs:insert(#unit.refs,proj_ref)
+ unit.flags1.projectile=true
+end
+function empregnate(unit)
+ if unit==nil then
+ unit=getSelectedUnit()
+ end
+
+ if unit==nil then
+ unit=getCreatureAtPos(getxyz())
+ 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_ptr == nil then
+ print("creating preg ptr.")
+ if false then
+ print(string.format("%x %x",df.sizeof(unit.relations:_field("pregnancy_ptr"))))
+ return
+ end
+ unit.relations.pregnancy_ptr = { new = true, assign = genes }
+ end
+ local ngenes = unit.relations.pregnancy_ptr
+ 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_mystery=1
+end
+menu:add("Empregnate",empregnate)
+return _ENV
\ No newline at end of file
diff --git a/scripts/dfusion.lua b/scripts/dfusion.lua
index 4fee0438e..79f9fd953 100644
--- a/scripts/dfusion.lua
+++ b/scripts/dfusion.lua
@@ -4,8 +4,11 @@ local myos=dfhack.getOSType()
args={...}
mainmenu=dfu.SimpleMenu()
function runsave()
- print("doing file:"..df.global.world.cur_savegame.save_dir)
+ local path=string.format("data/save/%s/dfhack.lua",df.global.world.cur_savegame.save_dir)
+ print("doing file:"..path)
+ loadfile(path)()
end
mainmenu:add("Run save script",runsave)
mainmenu:add("Adventurer tools",require("plugins.dfusion.adv_tools").menu)
+mainmenu:add("Misc tools",require("plugins.dfusion.tools").menu)
mainmenu:display()
\ No newline at end of file
From 5295be5fdbe4ef7e40e174ddfab86253d6d154bd Mon Sep 17 00:00:00 2001
From: Warmist
Date: Fri, 2 Nov 2012 20:28:08 +0200
Subject: [PATCH 033/158] More work done. Only bin-plugs left (and docs)
---
plugins/lua/dfusion/adv_tools.lua | 2 +-
plugins/lua/dfusion/tools.lua | 41 +++++++++++++++++++++++--------
2 files changed, 32 insertions(+), 11 deletions(-)
diff --git a/plugins/lua/dfusion/adv_tools.lua b/plugins/lua/dfusion/adv_tools.lua
index 31e83b234..6e95d2117 100644
--- a/plugins/lua/dfusion/adv_tools.lua
+++ b/plugins/lua/dfusion/adv_tools.lua
@@ -87,7 +87,7 @@ function change_adv(unit,nemesis)
end
end
else
- error("Current unit does not have nemesis record, further working not guaranteed")
+ qerror("Current unit does not have nemesis record, further working not guaranteed")
end
end
end
diff --git a/plugins/lua/dfusion/tools.lua b/plugins/lua/dfusion/tools.lua
index 9ddfb8e45..e577a9418 100644
--- a/plugins/lua/dfusion/tools.lua
+++ b/plugins/lua/dfusion/tools.lua
@@ -2,14 +2,31 @@ local _ENV = mkmodule('plugins.dfusion.tools')
local dfu=require("plugins.dfusion")
local ms=require "memscan"
menu=dfu.SimpleMenu()
-function setrace(name) --TODO FIX
- RaceTable=BuildNameTable()
- print("Your current race is:"..GetRaceToken(df.global.ui.race_id))
+RaceNames={}
+function build_race_names()
+ if #RaceNames~=0 then
+ return RaceNames
+ else
+ for k,v in pairs(df.global.world.raws.creatures.all) do
+ RaceNames[v.creature_id]=k
+ end
+ dfhack.onStateChange.invalidate_races=function(change_id) --todo does this work?
+ if change_id==SC_WORLD_UNLOADED then
+ dfhack.onStateChange.invalidate_races=nil
+ RaceNames={}
+ end
+ end
+ 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
- entry=getline()
+ local entry=io.stdin:read()
if entry=="q" then
return
end
@@ -24,16 +41,20 @@ function setrace(name) --TODO FIX
df.global.ui.race_id=id
end
menu:add("Set current race",setrace)
-function GiveSentience(names) --TODO FIX
- RaceTable=RaceTable or BuildNameTable() --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
- entry=getline()
+ id=io.stdin:read()
id=RaceTable[entry]
- until id~=nil
- table.insert(ids,id)
+ if id~=nil then
+ table.insert(ids,id)
+ end
+ until id==nil
+
else
ids={}
for _,name in pairs(names) do
@@ -45,7 +66,7 @@ function GiveSentience(names) --TODO FIX
local races=df.global.world.raws.creatures.all
local castes=races[id].caste
- print(string.format("Caste count:%i",castes.size))
+ print(string.format("Caste count:%i",#castes))
for i =0,#castes-1 do
print("Caste name:"..castes[i].caste_id.."...")
From 86e4a42bdda70a47338969aba2b8ade42800294f Mon Sep 17 00:00:00 2001
From: Warmist
Date: Fri, 2 Nov 2012 20:59:05 +0200
Subject: [PATCH 034/158] Small fix due to vmethod change
---
plugins/reactionhooks.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plugins/reactionhooks.cpp b/plugins/reactionhooks.cpp
index d70fb9ea1..ba0f8742d 100644
--- a/plugins/reactionhooks.cpp
+++ b/plugins/reactionhooks.cpp
@@ -203,7 +203,7 @@ struct product_hook : item_product {
(df::unit *unit, std::vector *out_items,
std::vector *in_reag,
std::vector *in_items,
- int32_t quantity, int16_t skill,
+ int32_t quantity, df::job_skill skill,
df::historical_entity *entity, df::world_site *site)
) {
if (auto product = products[this])
From e887c60e93c819dc3b803457dbb6b3c3c7300731 Mon Sep 17 00:00:00 2001
From: Warmist
Date: Fri, 2 Nov 2012 21:00:35 +0200
Subject: [PATCH 035/158] Removed unused buffers.
---
plugins/devel/memview.cpp | 2 --
1 file changed, 2 deletions(-)
diff --git a/plugins/devel/memview.cpp b/plugins/devel/memview.cpp
index 757b475dd..29b8403f8 100644
--- a/plugins/devel/memview.cpp
+++ b/plugins/devel/memview.cpp
@@ -168,8 +168,6 @@ command_result memview (color_ostream &out, vector & parameters)
else
memdata.refresh=0;
-
- uint8_t *buf,*lbuf;
memdata.buf=new uint8_t[memdata.len];
memdata.lbuf=new uint8_t[memdata.len];
Core::getInstance().p->getMemRanges(memdata.ranges);
From a7bf526f41216f6e43c942c21907dbd46fe8f44f Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Thu, 8 Nov 2012 21:27:56 +0400
Subject: [PATCH 036/158] Make workflow consider squad-assigned items busy.
---
NEWS | 1 +
plugins/workflow.cpp | 10 +++++++++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/NEWS b/NEWS
index f2237cab9..32181f16a 100644
--- a/NEWS
+++ b/NEWS
@@ -21,6 +21,7 @@ DFHack future
- properly considers minecarts assigned to routes busy.
- code for deducing job outputs rewritten in lua for flexibility.
- logic fix: collecting webs produces silk, and ungathered webs are not thread.
+ - items assigned to squads are considered busy, even if not in inventory.
New Fix Armory plugin:
Together with a couple of binary patches and the gui/assign-rack script,
this plugin makes weapon racks, armor stands, chests and cabinets in
diff --git a/plugins/workflow.cpp b/plugins/workflow.cpp
index d46daed44..5347d4671 100644
--- a/plugins/workflow.cpp
+++ b/plugins/workflow.cpp
@@ -1004,6 +1004,12 @@ static bool isRouteVehicle(df::item *item)
return vehicle && vehicle->route_id >= 0;
}
+static bool isAssignedSquad(df::item *item)
+{
+ auto &vec = ui->equipment.items_assigned[item->getType()];
+ return binsearch_index(vec, &df::item::id, item->id) >= 0;
+}
+
static void map_job_items(color_ostream &out)
{
for (size_t i = 0; i < constraints.size(); i++)
@@ -1117,8 +1123,10 @@ static void map_job_items(color_ostream &out)
item->isAssignedToStockpile() ||
isRouteVehicle(item) ||
itemInRealJob(item) ||
- itemBusy(item))
+ itemBusy(item) ||
+ isAssignedSquad(item))
{
+ is_invalid = true;
cv->item_inuse++;
}
else
From eb936c4ce07bb16684de0157a2ab5bbdf74fc4ca Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Sat, 10 Nov 2012 17:06:54 +0400
Subject: [PATCH 037/158] Support milking and shearing in workflow.
---
NEWS | 1 +
library/modules/Job.cpp | 2 +-
library/modules/Materials.cpp | 2 ++
library/xml | 2 +-
plugins/lua/workflow.lua | 23 +++++++++++++++++------
plugins/workflow.cpp | 4 +++-
scripts/gui/workflow.lua | 2 +-
7 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/NEWS b/NEWS
index 32181f16a..51321be95 100644
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,7 @@ DFHack future
- code for deducing job outputs rewritten in lua for flexibility.
- logic fix: collecting webs produces silk, and ungathered webs are not thread.
- items assigned to squads are considered busy, even if not in inventory.
+ - shearing and milking jobs are supported, but only with generic MILK or YARN outputs.
New Fix Armory plugin:
Together with a couple of binary patches and the gui/assign-rack script,
this plugin makes weapon racks, armor stands, chests and cabinets in
diff --git a/library/modules/Job.cpp b/library/modules/Job.cpp
index def3b4192..757000885 100644
--- a/library/modules/Job.cpp
+++ b/library/modules/Job.cpp
@@ -75,7 +75,7 @@ df::job *DFHack::Job::cloneJobStruct(df::job *job)
{
df::general_ref *ref = pnew->references[i];
- if (virtual_cast(ref))
+ if (virtual_cast(ref))
vector_erase_at(pnew->references, i);
else
pnew->references[i] = ref->clone();
diff --git a/library/modules/Materials.cpp b/library/modules/Materials.cpp
index 7c06aeb4c..4da484ade 100644
--- a/library/modules/Materials.cpp
+++ b/library/modules/Materials.cpp
@@ -425,6 +425,8 @@ bool MaterialInfo::matches(const df::dfhack_material_category &cat)
TEST(glass, IS_GLASS);
if (cat.bits.clay && linear_index(material->reaction_product.id, std::string("FIRED_MAT")) >= 0)
return true;
+ if (cat.bits.milk && linear_index(material->reaction_product.id, std::string("CHEESE_MAT")) >= 0)
+ return true;
return false;
}
diff --git a/library/xml b/library/xml
index 4ab899319..02e0e0d7b 160000
--- a/library/xml
+++ b/library/xml
@@ -1 +1 @@
-Subproject commit 4ab899319014d950214714a48cd3049a4beb5eb5
+Subproject commit 02e0e0d7b9a7ef708a621ef5511a24bf8657b4a2
diff --git a/plugins/lua/workflow.lua b/plugins/lua/workflow.lua
index 4c011b24c..c3dbe20d9 100644
--- a/plugins/lua/workflow.lua
+++ b/plugins/lua/workflow.lua
@@ -301,15 +301,26 @@ function listWeakenedConstraints(outputs)
local mask = cons.mat_mask
if (cons.mat_type or -1) >= 0 then
cons.mat_mask = nil
+ local info = dfhack.matinfo.decode(cons)
+ if info then
+ for i,flag in ipairs(df.dfhack_material_category) do
+ if flag and flag ~= 'wood2' and info:matches{[flag]=true} then
+ mask = mask or {}
+ mask[flag] = true
+ end
+ end
+ end
end
register(cons)
if mask then
- table.insert(generic, {
- item_type = cons.item_type,
- item_subtype = cons.item_subtype,
- is_craft = cons.is_craft,
- mat_mask = mask
- })
+ for k,v in pairs(mask) do
+ table.insert(generic, {
+ item_type = cons.item_type,
+ item_subtype = cons.item_subtype,
+ is_craft = cons.is_craft,
+ mat_mask = { [k] = v }
+ })
+ end
end
table.insert(anymat, {
item_type = cons.item_type,
diff --git a/plugins/workflow.cpp b/plugins/workflow.cpp
index 5347d4671..c89d87333 100644
--- a/plugins/workflow.cpp
+++ b/plugins/workflow.cpp
@@ -377,7 +377,9 @@ static bool isSupportedJob(df::job *job)
Job::getHolder(job) &&
(!job->job_items.empty() ||
job->job_type == job_type::CollectClay ||
- job->job_type == job_type::CollectSand);
+ job->job_type == job_type::CollectSand ||
+ job->job_type == job_type::MilkCreature ||
+ job->job_type == job_type::ShearCreature);
}
static bool isOptionEnabled(unsigned flag)
diff --git a/scripts/gui/workflow.lua b/scripts/gui/workflow.lua
index 8dc958062..366e3ec91 100644
--- a/scripts/gui/workflow.lua
+++ b/scripts/gui/workflow.lua
@@ -306,7 +306,7 @@ function JobConstraints:onNewConstraint()
end
dlg.showListPrompt(
- 'Job Outputs',
+ 'New limit',
'Select one of the possible outputs:',
COLOR_WHITE,
choices,
From 56ef33ea0e5c6236239b4af43f00cb182c181987 Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Sat, 10 Nov 2012 17:33:05 +0400
Subject: [PATCH 038/158] Support building steam engines on top of brooks
without any down stairs.
---
library/include/TileTypes.h | 6 ++++++
library/xml | 2 +-
plugins/steam-engine.cpp | 8 +++++---
3 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/library/include/TileTypes.h b/library/include/TileTypes.h
index d21fb3c17..48c10146a 100644
--- a/library/include/TileTypes.h
+++ b/library/include/TileTypes.h
@@ -203,6 +203,12 @@ namespace DFHack
return ENUM_ATTR(tiletype_shape, passable_flow, tileShape(tiletype));
}
+ inline
+ bool FlowPassableDown(df::tiletype tiletype)
+ {
+ return ENUM_ATTR(tiletype_shape, passable_flow_down, tileShape(tiletype));
+ }
+
inline
bool isWalkable(df::tiletype tiletype)
{
diff --git a/library/xml b/library/xml
index 02e0e0d7b..4b2124957 160000
--- a/library/xml
+++ b/library/xml
@@ -1 +1 @@
-Subproject commit 02e0e0d7b9a7ef708a621ef5511a24bf8657b4a2
+Subproject commit 4b2124957e282683480eaf05922e63c353364ec1
diff --git a/plugins/steam-engine.cpp b/plugins/steam-engine.cpp
index d884191e5..60f38ef83 100644
--- a/plugins/steam-engine.cpp
+++ b/plugins/steam-engine.cpp
@@ -320,7 +320,7 @@ struct workshop_hook : df::building_workshopst {
for (int y = y1; y <= y2; y++)
{
auto ptile = Maps::getTileType(x,y,z);
- if (!ptile || !LowPassable(*ptile))
+ if (!ptile || !FlowPassableDown(*ptile))
continue;
auto pltile = Maps::getTileType(x,y,z-1);
@@ -891,7 +891,7 @@ IMPLEMENT_VMETHOD_INTERPOSE(dwarfmode_hook, feed);
* Scan raws for matching workshop buildings.
*/
-static bool find_engines()
+static bool find_engines(color_ostream &out)
{
engines.clear();
@@ -943,6 +943,8 @@ static bool find_engines()
if (!ws.gear_tiles.empty())
engines.push_back(ws);
+ else
+ out.printerr("%s has no gear tiles - ignoring.\n", wslist[i]->code.c_str());
}
return !engines.empty();
@@ -973,7 +975,7 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan
{
switch (event) {
case SC_WORLD_LOADED:
- if (find_engines())
+ if (find_engines(out))
{
out.print("Detected steam engine workshops - enabling plugin.\n");
enable_hooks(true);
From f86371cfc3114dc08963cb3d0a521ca3660ac5ad Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Sat, 10 Nov 2012 18:06:41 +0400
Subject: [PATCH 039/158] Try blocking any use of stockpiles for squad stuff in
fix-armory.
---
plugins/fix-armory.cpp | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/plugins/fix-armory.cpp b/plugins/fix-armory.cpp
index b937d40e8..99e5fd500 100644
--- a/plugins/fix-armory.cpp
+++ b/plugins/fix-armory.cpp
@@ -132,6 +132,9 @@ DFhackCExport command_result plugin_shutdown (color_ostream &out)
* grace period during which the items can be instantly picked up again.
*/
+// Completely block the use of stockpiles
+#define NO_STOCKPILES
+
// Check if the item is assigned to any use controlled by the military tab
static bool is_assigned_item(df::item *item)
{
@@ -143,19 +146,6 @@ static bool is_assigned_item(df::item *item)
if (idx < 0)
return false;
- // Exclude weapons used by miners, wood cutters etc
- switch (type) {
- case item_type::WEAPON:
- // the game code also checks this for ammo, funnily enough
- // maybe it's not just for weapons?..
- if (binsearch_index(ui->equipment.work_weapons, item->id) >= 0)
- return false;
- break;
-
- default:
- break;
- }
-
return true;
}
@@ -328,6 +318,16 @@ template struct armory_hook : Item {
*/
DEFINE_VMETHOD_INTERPOSE(bool, isCollected, ())
{
+#ifdef NO_STOCKPILES
+ /*
+ * Completely block any items assigned to a squad from being stored
+ * in stockpiles. The reason is that I still observe haulers running
+ * around with bins to pick them up for some reason. There could be
+ * some unaccounted race conditions involved.
+ */
+ if (is_assigned_item(this))
+ return false;
+#else
// Block stockpiling of items in the armory.
if (is_in_armory(this))
return false;
@@ -354,6 +354,7 @@ template struct armory_hook : Item {
return false;
}
}
+#endif
// Call the original vmethod
return INTERPOSE_NEXT(isCollected)();
From f1d4eac70016ced41cb5e383e65763187a84b191 Mon Sep 17 00:00:00 2001
From: Warmist
Date: Sun, 11 Nov 2012 11:58:43 +0200
Subject: [PATCH 040/158] Pre-class remove
---
.../luafiles/friendship/friendship.asm | 10 +-
.../Dfusion/luafiles/friendship/friendship.o | Bin 722 -> 854 bytes
plugins/lua/dfusion/embark.lua | 2 +
plugins/lua/dfusion/friendship.lua | 111 ++++++++++++++++++
plugins/lua/dfusion/friendship.o | Bin 0 -> 854 bytes
plugins/lua/dfusion/srcs/compile.bat | 1 +
plugins/lua/dfusion/srcs/embark.asm | 7 ++
plugins/lua/dfusion/srcs/friendship.asm | 106 +++++++++++++++++
8 files changed, 234 insertions(+), 3 deletions(-)
create mode 100644 plugins/lua/dfusion/friendship.lua
create mode 100644 plugins/lua/dfusion/friendship.o
create mode 100644 plugins/lua/dfusion/srcs/compile.bat
create mode 100644 plugins/lua/dfusion/srcs/embark.asm
create mode 100644 plugins/lua/dfusion/srcs/friendship.asm
diff --git a/plugins/Dfusion/luafiles/friendship/friendship.asm b/plugins/Dfusion/luafiles/friendship/friendship.asm
index e56fe7f49..b649e38de 100644
--- a/plugins/Dfusion/luafiles/friendship/friendship.asm
+++ b/plugins/Dfusion/luafiles/friendship/friendship.asm
@@ -66,8 +66,10 @@ mov eax, [edi+0x8c]
#jmp compare
compare:
push ecx
+mark_racepointer:
mov ebx,0xDEADBEEF #write a pointer to the list of allowed races
-mov ecx,2000 #write a number of allowed races
+mark_racecount:
+mov ecx,0xDEADBEEF #write a number of allowed races
loop1:
cmp word[ebx+ecx*2],ax
jz endok
@@ -92,11 +94,13 @@ endfinal:
pop ebx
pop eax
-mov [0xFEEDBEEF],eax #write a pointer to safe location (usually after this)
+mark_safeloc1:
+mov [0xDEADBEEF],eax #write a pointer to safe location (usually after this)
pop eax
pushfd
inc eax #skip one instruction
popfd
push eax
-mov eax,[0xFEEDBEEF] #write a pointer to safe location (same as above)
+mark_safeloc2:
+mov eax,[0xDEADBEEF] #write a pointer to safe location (same as above)
ret
diff --git a/plugins/Dfusion/luafiles/friendship/friendship.o b/plugins/Dfusion/luafiles/friendship/friendship.o
index f956de3e0a6fce74f63feb2c41a1d07b7a441ec4..c801562dbc1bc9ab11c74929ef422aff7629dcb5 100644
GIT binary patch
delta 177
zcmcb_dX0_Ohmn~91VR`Y7$i6H3Ny02-?#SOWEDnbp0)QP<~Ym^SO^vfX1pm4QpWMtiq_w^Y&lF9EZ693*Ya1`)_hEMAX_RACES then
+ error("race count must be less then "..MAX_RACES)
+ end
+ local rarr=self:allocate("race_array",'uint16_t',MAX_RACES)
+ local _,rarr_offset=df.sizeof(rarr)
+ self:set_marker_dword("racepointer",rarr_offset)
+ self:set_races(rarr)
+ self:set_marker_dword("racecount",#self.race_data)
+ local safe_loc=self:allocate("safe_loc",'uint32_t',1)
+ local _1,safe_loc_offset=df.sizeof(safe_loc)
+ self:set_marker_dword("safeloc1",safe_loc_offset)
+ self:set_marker_dword("safeloc2",safe_loc_offset)
+ local addr=self:move_to_df()
+ self:patchCalls(addr)
+ self.installed=true
+ end
+return _ENV
\ No newline at end of file
diff --git a/plugins/lua/dfusion/friendship.o b/plugins/lua/dfusion/friendship.o
new file mode 100644
index 0000000000000000000000000000000000000000..c801562dbc1bc9ab11c74929ef422aff7629dcb5
GIT binary patch
literal 854
zcmeZaWM%+?5JmI3a0tG+rTticRPp<-2Hyv+Iu@eM4F|GH&Y3hXYaMV#5$~(mYI_Z_29q%3=HXvX^Gh|0jPLZZb3;>4g&)x
zkPi%c1~!JG)O2T%WIVEn3rHj%S;Pq>l8z!00OXY;i?{}RGBDJmh`0bn+L1*ZfgFZl
zxJX)JCeSqu4C~<{$@#ejiAAXly>JnbJPQ!_p@@hAd6VHHIr;eohCtp7xJYVVN`5ww
zw-Q+-Ei*4MXB%7u$Y4+b;vFa=MnK*nxCnBp1cewgBPd;>0^}6Q1e9V1DMSOvsS%X+
uv8izYisvR4WycpKCZ`tUXXcfp79j+Z^GoweAl%}_wA7sZWJ4655d#3LE~Ebd
literal 0
HcmV?d00001
diff --git a/plugins/lua/dfusion/srcs/compile.bat b/plugins/lua/dfusion/srcs/compile.bat
new file mode 100644
index 000000000..e084949f4
--- /dev/null
+++ b/plugins/lua/dfusion/srcs/compile.bat
@@ -0,0 +1 @@
+as -anl --32 -o friendship.o friendship.asm
\ No newline at end of file
diff --git a/plugins/lua/dfusion/srcs/embark.asm b/plugins/lua/dfusion/srcs/embark.asm
new file mode 100644
index 000000000..d2fa91081
--- /dev/null
+++ b/plugins/lua/dfusion/srcs/embark.asm
@@ -0,0 +1,7 @@
+.intel_syntax
+mov eax , [esp+0x1C] # loop counter
+mark_caste:
+movsx ecx, word ptr[eax*2+0xdeadbeef]
+mark_race:
+movzx eax,word ptr [eax*2+0xDEADBEEF]
+ret
diff --git a/plugins/lua/dfusion/srcs/friendship.asm b/plugins/lua/dfusion/srcs/friendship.asm
new file mode 100644
index 000000000..b649e38de
--- /dev/null
+++ b/plugins/lua/dfusion/srcs/friendship.asm
@@ -0,0 +1,106 @@
+.intel_syntax
+push eax
+mov eax,[esp+0x04]
+push ebx
+pushfd
+mov eax,[eax] # get a byte after the call this procedure to analyze what register holds cr ptr
+jmptbl:
+cmp al,0x81
+jz regC
+cmp al,0x82
+jz regD
+cmp al,0x83
+jz regB
+cmp al,0x85
+jz regBP
+cmp al,0x86
+jz regESI
+cmp al,0x87
+jz regEDI
+cmp al,0x88
+jz regA
+cmp al,0x8A
+jz regD
+cmp al,0x8B
+jz regB
+cmp al,0x8D
+jz regBP
+cmp al,0x8E
+jz regESI
+cmp al,0x8F
+jz regEDI
+cmp al,0x90
+jz regA
+cmp al,0x91
+jz regC
+cmp al,0x93
+jz regB
+cmp al,0x95
+jz regBP
+cmp al,0x96
+jz regESI
+cmp al,0x97
+jz regEDI
+jmp fail
+regA:
+mov eax, [esp+0x8]
+mov eax, [eax+0x8c]
+jmp compare
+regC:
+mov eax, [ecx+0x8c]
+jmp compare
+regB:
+mov eax, [ebx+0x8c]
+jmp compare
+regD:
+mov eax, [edx+0x8c]
+jmp compare
+regBP:
+mov eax, [ebp+0x8c]
+jmp compare
+regESI:
+mov eax, [esi+0x8c]
+jmp compare
+regEDI:
+mov eax, [edi+0x8c]
+#jmp compare
+compare:
+push ecx
+mark_racepointer:
+mov ebx,0xDEADBEEF #write a pointer to the list of allowed races
+mark_racecount:
+mov ecx,0xDEADBEEF #write a number of allowed races
+loop1:
+cmp word[ebx+ecx*2],ax
+jz endok
+dec ecx
+cmp ecx ,-1
+jnz loop1
+pop ecx
+popfd
+jmp fail
+endok:
+pop ecx
+popfd
+cmp eax,eax
+jmp endfinal
+fail:
+
+xor ebx,ebx
+xor eax,eax
+inc eax
+cmp eax,ebx
+endfinal:
+
+pop ebx
+pop eax
+mark_safeloc1:
+mov [0xDEADBEEF],eax #write a pointer to safe location (usually after this)
+pop eax
+pushfd
+inc eax #skip one instruction
+popfd
+push eax
+mark_safeloc2:
+mov eax,[0xDEADBEEF] #write a pointer to safe location (same as above)
+ret
From 33f674eee2ce40b5528b5ef6b4f4681867299829 Mon Sep 17 00:00:00 2001
From: Warmist
Date: Sun, 11 Nov 2012 12:33:54 +0200
Subject: [PATCH 041/158] Removed dfusion lua files. Updated plugins.
---
plugins/Dfusion/CMakeLists.txt | 3 -
plugins/Dfusion/luafiles/adv_tools/plugin.lua | 3 -
plugins/Dfusion/luafiles/common.lua | 514 ------------------
plugins/Dfusion/luafiles/embark/build.bat | 1 -
plugins/Dfusion/luafiles/embark/embark.asm | 7 -
plugins/Dfusion/luafiles/embark/embark.o | Bin 369 -> 0 bytes
plugins/Dfusion/luafiles/embark/init.lua | 95 ----
plugins/Dfusion/luafiles/embark/plugin.lua | 5 -
plugins/Dfusion/luafiles/embark/races.txt | 9 -
.../Dfusion/luafiles/friendship/compile.bat | 1 -
.../luafiles/friendship/friendship.asm | 106 ----
.../Dfusion/luafiles/friendship/friendship.o | Bin 854 -> 0 bytes
plugins/Dfusion/luafiles/friendship/init.lua | 45 --
.../Dfusion/luafiles/friendship/install.lua | 35 --
plugins/Dfusion/luafiles/friendship/patch.lua | 57 --
.../Dfusion/luafiles/friendship/plugin.lua | 18 -
plugins/Dfusion/luafiles/friendship/races.txt | 8 -
.../luafiles/friendship_civ/compile.bat | 1 -
.../luafiles/friendship_civ/friendship_c.asm | 41 --
.../luafiles/friendship_civ/friendship_c.o | Bin 462 -> 0 bytes
.../Dfusion/luafiles/friendship_civ/init.lua | 89 ---
.../luafiles/friendship_civ/plugin.lua | 57 --
plugins/Dfusion/luafiles/init.lua | 92 ----
plugins/Dfusion/luafiles/migrants/compile.bat | 1 -
plugins/Dfusion/luafiles/migrants/init.lua | 62 ---
.../Dfusion/luafiles/migrants/migrants.asm | 20 -
plugins/Dfusion/luafiles/migrants/migrants.o | Bin 336 -> 0 bytes
plugins/Dfusion/luafiles/migrants/plugin.lua | 5 -
plugins/Dfusion/luafiles/migrants/races.txt | 29 -
plugins/Dfusion/luafiles/offsets/plugin.lua | 2 -
plugins/Dfusion/luafiles/offsets_misc.lua | 48 --
.../Dfusion/luafiles/simple_embark/plugin.lua | 23 -
plugins/Dfusion/luafiles/tools/init.lua | 511 -----------------
plugins/Dfusion/luafiles/tools/plugin.lua | 8 -
plugins/Dfusion/luafiles/utils.lua | 1 -
plugins/lua/dfusion/embark.lua | 92 ++--
plugins/lua/dfusion/friendship.lua | 5 +-
37 files changed, 36 insertions(+), 1958 deletions(-)
delete mode 100644 plugins/Dfusion/luafiles/adv_tools/plugin.lua
delete mode 100644 plugins/Dfusion/luafiles/common.lua
delete mode 100644 plugins/Dfusion/luafiles/embark/build.bat
delete mode 100644 plugins/Dfusion/luafiles/embark/embark.asm
delete mode 100644 plugins/Dfusion/luafiles/embark/embark.o
delete mode 100644 plugins/Dfusion/luafiles/embark/init.lua
delete mode 100644 plugins/Dfusion/luafiles/embark/plugin.lua
delete mode 100644 plugins/Dfusion/luafiles/embark/races.txt
delete mode 100644 plugins/Dfusion/luafiles/friendship/compile.bat
delete mode 100644 plugins/Dfusion/luafiles/friendship/friendship.asm
delete mode 100644 plugins/Dfusion/luafiles/friendship/friendship.o
delete mode 100644 plugins/Dfusion/luafiles/friendship/init.lua
delete mode 100644 plugins/Dfusion/luafiles/friendship/install.lua
delete mode 100644 plugins/Dfusion/luafiles/friendship/patch.lua
delete mode 100644 plugins/Dfusion/luafiles/friendship/plugin.lua
delete mode 100644 plugins/Dfusion/luafiles/friendship/races.txt
delete mode 100644 plugins/Dfusion/luafiles/friendship_civ/compile.bat
delete mode 100644 plugins/Dfusion/luafiles/friendship_civ/friendship_c.asm
delete mode 100644 plugins/Dfusion/luafiles/friendship_civ/friendship_c.o
delete mode 100644 plugins/Dfusion/luafiles/friendship_civ/init.lua
delete mode 100644 plugins/Dfusion/luafiles/friendship_civ/plugin.lua
delete mode 100644 plugins/Dfusion/luafiles/init.lua
delete mode 100644 plugins/Dfusion/luafiles/migrants/compile.bat
delete mode 100644 plugins/Dfusion/luafiles/migrants/init.lua
delete mode 100644 plugins/Dfusion/luafiles/migrants/migrants.asm
delete mode 100644 plugins/Dfusion/luafiles/migrants/migrants.o
delete mode 100644 plugins/Dfusion/luafiles/migrants/plugin.lua
delete mode 100644 plugins/Dfusion/luafiles/migrants/races.txt
delete mode 100644 plugins/Dfusion/luafiles/offsets/plugin.lua
delete mode 100644 plugins/Dfusion/luafiles/offsets_misc.lua
delete mode 100644 plugins/Dfusion/luafiles/simple_embark/plugin.lua
delete mode 100644 plugins/Dfusion/luafiles/tools/init.lua
delete mode 100644 plugins/Dfusion/luafiles/tools/plugin.lua
delete mode 100644 plugins/Dfusion/luafiles/utils.lua
diff --git a/plugins/Dfusion/CMakeLists.txt b/plugins/Dfusion/CMakeLists.txt
index 51f2e3bee..6cfe9eb40 100644
--- a/plugins/Dfusion/CMakeLists.txt
+++ b/plugins/Dfusion/CMakeLists.txt
@@ -9,6 +9,3 @@ set(
FILE(GLOB DFUSION_HS include/*)
SET_SOURCE_FILES_PROPERTIES( ${DFUSION_HS} PROPERTIES HEADER_FILE_ONLY TRUE )
DFHACK_PLUGIN(dfusion ${DFUSION_CPPS_ALL} ${DFUSION_HS} LINK_LIBRARIES lua dfhack-tinythread)
-
-# installs into DF root
-install(DIRECTORY luafiles/ DESTINATION dfusion)
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/adv_tools/plugin.lua b/plugins/Dfusion/luafiles/adv_tools/plugin.lua
deleted file mode 100644
index cdd81e06f..000000000
--- a/plugins/Dfusion/luafiles/adv_tools/plugin.lua
+++ /dev/null
@@ -1,3 +0,0 @@
-if not(FILE) then
- adv_tools.menu:display()
-end
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/common.lua b/plugins/Dfusion/luafiles/common.lua
deleted file mode 100644
index bdf3a2bc8..000000000
--- a/plugins/Dfusion/luafiles/common.lua
+++ /dev/null
@@ -1,514 +0,0 @@
-dofile("dfusion/offsets_misc.lua")
-STD_STRING=0
-DWORD=1
-WORD=2
-BYTE=3
-QWORD=4
-DOUBLE=5
-FLOAT=6
-
-getline=function (inp)
-return dfhack.lineedit(inp or "")
-end
-io.stdin=nil
-
-function printd(...)
- if DEBUG then
- print(...)
- end
-end
-function GetTextRegion()
- if __TEXT ~=nil then --Chache this, not going to change.
- return __TEXT
- end
-
- ranges__=Process.getMemRanges()
- --print("Ranges:"..#ranges__)
- for k,v in pairs(ranges__) do
- for k2,v2 in pairs(v) do
- --print(string.format("%d %s->%s",k,tostring(k2),tostring(v2)))
- end
- --local num
- --flgs=""
- --if(v["read"])then flgs=flgs..'r' end
- --if(v["write"])then flgs=flgs..'w' end
- --if(v["execute"]) then flgs=flgs..'e' end
- --if num>=100 then
- --print(string.format("%d %x->%x %s %s",k,v["start"],v["end"],v.name or "",flgs))
- --end
- local pos=string.find(v.name,"Dwarf Fortress.exe") or string.find(v.name,"libs/Dwarf_Fortress")
- if(pos~=nil) and v["execute"] then
- __TEXT=v;
- return v;
- end
- end
- error(".Text region not found!")
-end
-function UpdateRanges()
- ranges__=Process.getMemRanges()
-end
-function GetRegionIn(pos)
- ranges__=ranges__ or Process.getMemRanges()
- for k,v in pairs(ranges__) do
- if pos>=v.start and pos%s",k,tostring(k2),tostring(v2)))
- --end
- --local num
- --num=0
- --if(v["read"])then num=num+1 end
- --if(v["write"])then num=num+10 end
- --if(v["execute"]) then num=num+100 end
- --print(string.format("%d %x->%x %s %x",k,v["start"],v["end"],v.name,pos))
- if pos>=v.start then --This is a hack to counter .text region suddenly shrinking.
- if cr~=nil then
- if v.start < cr.start then -- find region that start is closest
- cr=v
- end
- else
- cr=v
- end
- end
- end
- return cr
-end
-function ValidOffset(pos)
- ranges__=ranges__ or Process.getMemRanges()
- return GetRegionIn(pos)~=nil
-end
-function unlockDF()
- local reg=GetTextRegion()
- reg["write"]=true
- Process.setPermisions(reg,reg)
-end
-function lockDF()
- local reg=GetTextRegion()
- reg["write"]=false
- Process.setPermisions(reg,reg)
-end
-function SetExecute(pos)
- UpdateRanges()
- local reg=GetRegionIn(pos)
- reg.execute=true
- reg["write"]=true
- Process.setPermisions(reg,reg) -- TODO maybe make a page with only execute permisions or sth
-end
--- engine bindings
-engine=engine or {}
---[=[ use default peek/pokes for now
-engine.peekd=Process.readDWord
-engine.poked=Process.writeDWord
-engine.peekb=Process.readByte
-engine.pokeb=Process.writeByte
-engine.peekw=Process.readWord
-engine.pokew=Process.writeWord
-engine.peekstr_stl=Process.readSTLString
-engine.pokestr_stl=Process.writeSTLString
-engine.peekstr=Process.readCString
---engine.pokestr=Process.readCString
-engine.peekarb=Process.read
-engine.pokearb=Process.write
---]=]
-
-function engine.peek(offset,rtype)
- if type(rtype)=="table" then
- if rtype.off ==nil then
- return engine.peekpattern(offset,rtype)
- else
- return engine.peek(rtype.off+offset,rtype.rtype)
- end
- end
- if rtype==STD_STRING then
- return engine.peekstr2(offset)
- elseif rtype==DWORD then
- return engine.peekd(offset)
- elseif rtype==WORD then
- return engine.peekw(offset)
- elseif rtype==BYTE then
- return engine.peekb(offset)
- elseif rtype==QWORD then
- return engine.peekq(offset)
- elseif rtype==FLOAT then
- return engine.peekfloat(offset)
- elseif rtype==DOUBLE then
- return engine.peekdouble(offset)
- else
- error("Invalid peek type")
- return
- end
-end
-function engine.poke(offset,rtype,val)
- if type(rtype)=="table" then
- if rtype.off ==nil then
- return engine.pokepattern(offset,rtype,val)
- else
- return engine.poke(rtype.off+offset,rtype.rtype,val)
- end
- end
- if rtype==STD_STRING then
- return engine.pokestr2(offset,val)
- elseif rtype==DWORD then
- return engine.poked(offset,val)
- elseif rtype==WORD then
- return engine.pokew(offset,val)
- elseif rtype==BYTE then
- return engine.pokeb(offset,val)
- elseif rtype==QWORD then
- return engine.pokeq(offset,val)
- elseif rtype==FLOAT then
- return engine.pokefloat(offset,val)
- elseif rtype==DOUBLE then
- return engine.pokedouble(offset,val)
- else
- error("Invalid poke type:"..tostring(rtype))
- return
- end
-end
-function engine.sizeof(rtype)
- if rtype==STD_STRING then
- error("String has no constant size")
- return
- elseif rtype==DWORD then
- return 4;
- elseif rtype==WORD then
- return 2;
- elseif rtype==BYTE then
- return 1;
- else
- error("Invalid sizeof type")
- return
- end
-end
-function engine.peekpattern(offset,pattern)
- local ret={}
- for k,v in pairs(pattern) do
- --print("k:"..k.." v:"..type(v))
- if type(v)=="table" then
- ret[k]=engine.peek(offset+v.off,v.rtype)
- --print(k.." peeked:"..offset+v.off)
- else
- ret[k]=v
- end
- end
- ret.__offset=offset
- return ret
-end
-function engine.pokepattern(offset,pattern,val)
- for k,v in pairs(pattern) do
- --print("k:"..k.." v:"..type(v))
- if type(v)=="table" then
- engine.poke(offset+v.off,v.rtype,val[k])
- end
- end
-end
-
-function engine.LoadModData(file)
- local T2={}
- T2.symbols={}
- T2.data,T2.size=engine.loadobj(file)
- data,modsize=engine.loadobj(file)
- local T=engine.loadobjsymbols(file)
- for k,v in pairs(T) do
-
- if v.pos~=0 then
- T2.symbols[v.name]=v.pos
- end
- end
- return T2
-end
-function engine.FindMarkerCall(moddata,name)
- if moddata.symbols[name] ~=nil then
- return moddata.symbols[name]+1
- end
-end
-function engine.FindMarker(moddata,name)
- if moddata.symbols[name] ~=nil then
- return engine.findmarker(0xDEADBEEF,moddata.data,moddata.size,moddata.symbols[name])
- end
-end
-function engine.installMod(file,name,bonussize)
- local T=engine.LoadModData(file)
- local modpos,modsize=engine.loadmod(file,name,bonussize)
- T.pos=modpos
- return T
-end
-
-
-
-function PrintPattern(loadedpattern)
- for k,v in pairs(loadedpattern) do
- if type(v)== "string" then
- print(k.." "..v)
- else
- print(string.format("%s %d inhex:%x",k,v,v))
- end
- end
-end
-
-function printPattern(pattern)
- local i=0;
- local names={}
- names[STD_STRING]="std_string (STD_STRING)"
- names[DWORD]= "Double word (DWORD)"
- names[WORD]= "Word (WORD)"
- names[STD_STRING]="Byte (BYTE)"
- ret={}
- for k,v in pairs(pattern) do
- if type(v)=="table" and v.off~=nil then
-
- if names[v.rtype]~=nil then
- lname=names[v.rtype]
- else
- if type(v.rtype)=="table" then
- lname="Table (prob subpattern)"
- else
- lname="Other"
- end
- end
- print(string.format("%d. %s is %s with offset %x",i,k,lname,v.off))
- table.insert(ret,k)
- else
- print(string.format("%d. %s",i,k))
- end
- i=i+1
- end
- return ret;
-end
-function editPattern(offset,pattern,name)
- if type(pattern[name].rtype)=="table" then
- if pattern[name].rtype.setval~=nil then
- print(string.format("%x",offset+pattern[name].off))
- local t=engine.peek(offset+pattern[name].off,pattern[name].rtype)
- print("Value is now:"..t:getval())
- print("Enter new value:")
- val=io.stdin:read()
- t:setval(val)
- else
- ModPattern(offset+pattern[name].off,pattern[name].rtype)
- end
- return
- end
- val=engine.peek(offset,pattern[name])
- print("Value is now:"..val)
- print("Enter new value:")
- if pattern[name].rtype==STD_STRING then
- val=io.stdin:read()
- else
- val=tonumber(io.stdin:read())
- end
- engine.poke(offset,pattern[name],val)
-end
-function ModPattern(itemoffset,pattern)
- print("Select what to edit:")
- nm=printPattern(pattern)
- q=tonumber(io.stdin:read())
- if q~=nil and q<#nm then
- editPattern(itemoffset,pattern,nm[q+1])
- end
-end
-
-function findVectors()
- if __VECTORS ~=nil then --chache
- return __VECTORS
- end
- local text=GetTextRegion()
- local h=hexsearch(text.start,text["end"],0x8b,ANYBYTE,ANYDWORD,0x8b,ANYBYTE,ANYDWORD,0x2b)
- local pos=h:findall()
- local T={}
- for k,v in pairs(pos) do
- local loc1,loc2
- loc1=engine.peekd(v+2)
- loc2=engine.peekd(v+8)
- --print(string.format("%x - %x=%x",loc1,loc2,loc1-loc2))
- if(loc1-loc2==4) then
- if T[loc1-4]~=nil then
- T[loc1-4]=T[loc1-4]+1
- else
- T[loc1-4]=1
- end
- end
- end
- __VECTORS=T
- return T
-end
-
-function GetRaceToken(p) --actually gets token...
- local vec=df.global.world.raws.creatures.all
- return vec[p].creature_id
-end
-function BuildNameTable()
- local rtbl={}
- local vec=df.global.world.raws.creatures.all
- --print(string.format("Vector start:%x",vec.st))
- --print(string.format("Vector end:%x",vec.en))
- --print("Creature count:"..vec.size)
- for k=0,#vec-1 do
- local name=vec[k].creature_id
- --print(k.." "..tostring(name))
- rtbl[name]=k
- end
- return rtbl;
-end
-function BuildMaterialTable()
- local rtbl={}
- local vec=engine.peek(offsets.getEx('Materials'),ptr_vector)
- --print(string.format("Vector start:%x",vec.st))
- --print(string.format("Vector end:%x",vec.en))
- --local i=0
- for p=0,vec:size()-1 do
- local off=vec:getval(p)
- --print("First member:"..off)
- local name=engine.peek(off,ptt_dfstring)
- --print("Loading:"..p.."="..name:getval())
- rtbl[name:getval()]=p
- --i=i+1
- --if i>100 then
- -- io.stdin:read()
- -- i=0
- --end
- end
- return rtbl;
-end
-function BuildWordTables()
- local names={}
- local rnames={}
- local vector=engine.peek(offsets.getEx('WordVec'),ptr_vector)
-for i =0,vector:size()-1 do
- local off=vector:getval(i)
- local n=engine.peekstr(off)
- names[i]=n
- rnames[n]=i
-end
- return names,rnames
-end
-function ParseScript(file)
-
- io.input(file)
- f=""
- first=0
- nobraces=0
- function updFunction()
- if f~="" then
- first=0
- if nobraces==0 then
- f=f.."}"
- end
- nobraces=0
- print("Doing:"..f)
- assert(loadstring(f))()
-
- f=""
- end
- end
- while true do
-
- local line = io.read("*line")
- if line == nil then break end
- if string.sub(line,1,2)==">>" then
- updFunction()
- if string.find(line,"%b()") then
- f=string.sub(line,3)
- nobraces=1
- else
- f=string.sub(line,3).."{"
- end
- --print(string.sub(line,3)..)
- else
- if first~=0 then
- f=f..","
- else
- first=1
- end
- f=f..string.format('%q',line)
-
- end
-
- end
- updFunction()
-end
-function ParseNames(path)
- local ret={}
- local ff=io.open(path)
- for n in ff:lines() do
- table.insert(ret,n)
- end
- return ret
-end
-function getSelectedUnit()
- if df.global.ui.main.mode~=23 then
- return nil
- end
- local unit_indx=df.global.ui_selected_unit
- if unit_indx<#df.global.world.units.active-1 then
- return df.global.world.units.active[unit_indx]
- else
- return nil
- end
-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
-end
-function getCreatureAtPos(x,y,z) -- gets the creature index @ x,y,z coord
- --local x,y,z=getxyz() --get 'X' coords
- local vector=df.global.world.units.all -- load all creatures
- for i = 0, #vector-1 do -- look into all creatures offsets
- local curpos=vector[i].pos --get its coordinates
- local cx=curpos.x
- local cy=curpos.y
- local cz=curpos.z
- if cx==x and cy==y and cz==z then --compare them
- return vector[i] --return index
- end
- end
- --print("Creature not found!")
- return nil
-
-end
-function getCreatureAtPointer()
- return getCreatureAtPos(getxyz())
-end
-function getCreature()
- local unit=getSelectedUnit()
- if unit==nil then
- unit=getCreatureAtPointer()
- end
- --any other selection methods...
- return unit
-end
-function getNemesisId(unit)
- for k,v in pairs(unit.refs) do
- if df.general_ref_is_nemesisst:is_instance(v) then
- return v.nemesis_id
- end
- end
-end
-function getNemesis(unit)
- local id=getNemesisId(unit)
- if id then
- return df.nemesis_record.find(id)
- end
-end
-function Allocate(size)
- local ptr=engine.getmod('General_Space')
- if ptr==nil then
- ptr=engine.newmod("General_Space",4096) -- some time later maybe make some more space
- engine.poked(ptr,4)
- end
-
- local curptr=engine.peekd(ptr)
- curptr=curptr+size
- engine.poked(ptr,curptr)
- return curptr-size+ptr
-end
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/embark/build.bat b/plugins/Dfusion/luafiles/embark/build.bat
deleted file mode 100644
index 51eeb8140..000000000
--- a/plugins/Dfusion/luafiles/embark/build.bat
+++ /dev/null
@@ -1 +0,0 @@
-as -a --32 -o embark.o embark.asm
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/embark/embark.asm b/plugins/Dfusion/luafiles/embark/embark.asm
deleted file mode 100644
index d2fa91081..000000000
--- a/plugins/Dfusion/luafiles/embark/embark.asm
+++ /dev/null
@@ -1,7 +0,0 @@
-.intel_syntax
-mov eax , [esp+0x1C] # loop counter
-mark_caste:
-movsx ecx, word ptr[eax*2+0xdeadbeef]
-mark_race:
-movzx eax,word ptr [eax*2+0xDEADBEEF]
-ret
diff --git a/plugins/Dfusion/luafiles/embark/embark.o b/plugins/Dfusion/luafiles/embark/embark.o
deleted file mode 100644
index 87f5bbd68f5c8d0aaf6f81485f653a440145a952..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 369
zcmeZaWM%+?B|yvtX0bBrm84dbfY}g20!Z~B@j*-l27?5>l*E!mG;wsU1B1ZMAX_RACES then
- error("caste and race count must be less then "..MAX_RACES)
- end
- if stoff==nil then
- error("address for start_dwarf_count not found!")
- end
- local _,race_id_offset=df.sizeof(df.global.ui:_field("race_id"))
- print(string.format("start=%08x",stoff))
- local needle={0x0f,0xb7,0x0d} --movzx eax,dword ptr [race_id]
- local tmp_table=dfu.dwordToTable(race_id_offset)
- for k,v in ipairs(tmp_table) do
- table.insert(needle,v)
- end
-
- 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
- if trg_offset==nil then
- error("address for race_load not found")
- end
- local call_data={0x90,0x90}
- local _,data_offset=df.sizeof(self.data)
- dfu.concatTables(call_data,dfu.makeCall(trg_offset+2,data_offset))
- self.call_patch=dfu.BinaryPatch{pre_data=needle,data=call_data,address=trg_offset,name="custom_embark_call_patch"}
- needle={0x83,0xc8,0xff} -- or eax, 0xFF
- local _,caste_offset=mem.uint8_t:find(needle,mem.uint8_t:addr2idx(trg_offset),nil)
- if caste_offset==nil or caste_offset-stoff>1000 then
- error("Caste change code not found or found too far!")
- end
-
- self.disable_castes=dfu.BinaryPatch{pre_data={0x83,0xc8,0xff},data={0x90,0x90,0x90},address=caste_offset,name="custom_embark_caste_disable"}
- self.disable_castes:apply()
- 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()
- local caste_array=self:allocate("caste_array","uint16_t",#self.race_caste_data)
- local race_array=self:allocate("race_array","uint16_t",#self.race_caste_data)
- self:setEmbarkParty(self.race_caste_data)
- for k,v in ipairs(self.race_caste_data) do
- caste_array[k-1]=v[2]
- race_array[k-1]=v[1]
- end
- 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)
- self.race_caste_data=racesAndCastes
- 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()
- else
- self.dwarfcount:repatch(dfu.dwordToTable(#self.race_caste_data))
- end
-
- end
- function CustomEmbark:status()
- if self.installed then
- return "valid, installed"
- else
- return "valid, not installed"
- end
- end
- function CustomEmbark:uninstall()
- if self.installed then
- self.call_patch:remove()
- self.disable_castes:remove()
- self.dwarfcount:remove()
- end
- end
-else
- CustomEmbark.class_status="invalid, os not supported"
-end
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/embark/plugin.lua b/plugins/Dfusion/luafiles/embark/plugin.lua
deleted file mode 100644
index 039000656..000000000
--- a/plugins/Dfusion/luafiles/embark/plugin.lua
+++ /dev/null
@@ -1,5 +0,0 @@
-
-if not(FILE)then
- names=ParseNames("dfusion/embark/races.txt")--io.open("plugins/embark/races.txt"):lines()
- embark(names)
-end
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/embark/races.txt b/plugins/Dfusion/luafiles/embark/races.txt
deleted file mode 100644
index 376928866..000000000
--- a/plugins/Dfusion/luafiles/embark/races.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-ANT_MAN:0
-ANT_MAN:0
-ANT_MAN:0
-ANT_MAN:1
-ANT_MAN:1
-ANT_MAN:0
-ANT_MAN:0
-ANT_MAN:2
-ANT_MAN:3
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/friendship/compile.bat b/plugins/Dfusion/luafiles/friendship/compile.bat
deleted file mode 100644
index e084949f4..000000000
--- a/plugins/Dfusion/luafiles/friendship/compile.bat
+++ /dev/null
@@ -1 +0,0 @@
-as -anl --32 -o friendship.o friendship.asm
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/friendship/friendship.asm b/plugins/Dfusion/luafiles/friendship/friendship.asm
deleted file mode 100644
index b649e38de..000000000
--- a/plugins/Dfusion/luafiles/friendship/friendship.asm
+++ /dev/null
@@ -1,106 +0,0 @@
-.intel_syntax
-push eax
-mov eax,[esp+0x04]
-push ebx
-pushfd
-mov eax,[eax] # get a byte after the call this procedure to analyze what register holds cr ptr
-jmptbl:
-cmp al,0x81
-jz regC
-cmp al,0x82
-jz regD
-cmp al,0x83
-jz regB
-cmp al,0x85
-jz regBP
-cmp al,0x86
-jz regESI
-cmp al,0x87
-jz regEDI
-cmp al,0x88
-jz regA
-cmp al,0x8A
-jz regD
-cmp al,0x8B
-jz regB
-cmp al,0x8D
-jz regBP
-cmp al,0x8E
-jz regESI
-cmp al,0x8F
-jz regEDI
-cmp al,0x90
-jz regA
-cmp al,0x91
-jz regC
-cmp al,0x93
-jz regB
-cmp al,0x95
-jz regBP
-cmp al,0x96
-jz regESI
-cmp al,0x97
-jz regEDI
-jmp fail
-regA:
-mov eax, [esp+0x8]
-mov eax, [eax+0x8c]
-jmp compare
-regC:
-mov eax, [ecx+0x8c]
-jmp compare
-regB:
-mov eax, [ebx+0x8c]
-jmp compare
-regD:
-mov eax, [edx+0x8c]
-jmp compare
-regBP:
-mov eax, [ebp+0x8c]
-jmp compare
-regESI:
-mov eax, [esi+0x8c]
-jmp compare
-regEDI:
-mov eax, [edi+0x8c]
-#jmp compare
-compare:
-push ecx
-mark_racepointer:
-mov ebx,0xDEADBEEF #write a pointer to the list of allowed races
-mark_racecount:
-mov ecx,0xDEADBEEF #write a number of allowed races
-loop1:
-cmp word[ebx+ecx*2],ax
-jz endok
-dec ecx
-cmp ecx ,-1
-jnz loop1
-pop ecx
-popfd
-jmp fail
-endok:
-pop ecx
-popfd
-cmp eax,eax
-jmp endfinal
-fail:
-
-xor ebx,ebx
-xor eax,eax
-inc eax
-cmp eax,ebx
-endfinal:
-
-pop ebx
-pop eax
-mark_safeloc1:
-mov [0xDEADBEEF],eax #write a pointer to safe location (usually after this)
-pop eax
-pushfd
-inc eax #skip one instruction
-popfd
-push eax
-mark_safeloc2:
-mov eax,[0xDEADBEEF] #write a pointer to safe location (same as above)
-ret
diff --git a/plugins/Dfusion/luafiles/friendship/friendship.o b/plugins/Dfusion/luafiles/friendship/friendship.o
deleted file mode 100644
index c801562dbc1bc9ab11c74929ef422aff7629dcb5..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 854
zcmeZaWM%+?5JmI3a0tG+rTticRPp<-2Hyv+Iu@eM4F|GH&Y3hXYaMV#5$~(mYI_Z_29q%3=HXvX^Gh|0jPLZZb3;>4g&)x
zkPi%c1~!JG)O2T%WIVEn3rHj%S;Pq>l8z!00OXY;i?{}RGBDJmh`0bn+L1*ZfgFZl
zxJX)JCeSqu4C~<{$@#ejiAAXly>JnbJPQ!_p@@hAd6VHHIr;eohCtp7xJYVVN`5ww
zw-Q+-Ei*4MXB%7u$Y4+b;vFa=MnK*nxCnBp1cewgBPd;>0^}6Q1e9V1DMSOvsS%X+
uv8izYisvR4WycpKCZ`tUXXcfp79j+Z^GoweAl%}_wA7sZWJ4655d#3LE~Ebd
diff --git a/plugins/Dfusion/luafiles/friendship/init.lua b/plugins/Dfusion/luafiles/friendship/init.lua
deleted file mode 100644
index 0fc3219e4..000000000
--- a/plugins/Dfusion/luafiles/friendship/init.lua
+++ /dev/null
@@ -1,45 +0,0 @@
-function analyzeF(off)
- pos=offsets.find(off,0x39,ANYBYTE,0x8c,00,00,00)
- print(string.format("Compare at:%x",pos))
- if pos ==0 then
- return 0
- end
- if(pos-off>0x100) then
- print(string.format("Distance to cmp:%x",pos-off))
- pos =offsets.find(off,CALL)
- print(string.format("Distance to call:%x",pos-off))
- return 0
- --return analyzeF(pos)
- else
- return pos
- end
-end
-function minEx(list)
- local imin=list[1]
- for _,v in ipairs(list) do
- if imin> v and v~=0 then
- imin=v
- end
- end
- return imin
-end
-function signDword(dw)
- if(dw>0xFFFFFFFF) then
- return dw-0xFFFFFFFF
- end
- return dw
-end
---[[
- Warning: not all mov's are acounted for. Found one: mov EAX,WORD PTR[EBP+1EF4] WTF??
- Two more compares are missing. There are calls instead (same function)
-]]--
-
-friendship_in={}
-dofile("dfusion/friendship/install.lua")
-dofile("dfusion/friendship/patch.lua")
-
-function friendship(names)
- friendship_in.install(names)
- friendship_in.patch()
-end
-
diff --git a/plugins/Dfusion/luafiles/friendship/install.lua b/plugins/Dfusion/luafiles/friendship/install.lua
deleted file mode 100644
index 251d2fb3a..000000000
--- a/plugins/Dfusion/luafiles/friendship/install.lua
+++ /dev/null
@@ -1,35 +0,0 @@
-
-function friendship_in.install(names)
-RaceTable=RaceTable or BuildNameTable()
-mypos=engine.getmod("Friendship")
-if mypos then
- modpos=mypos
- _,modsize=engine.loadobj("dfusion/friendship/friendship.o")
- _=nil
-else
- modpos,modsize=engine.loadmod("dfusion/friendship/friendship.o","Friendship",1024)
- print(string.format("Loaded module @:%x",modpos))
-end
-count=0
-for _,v in pairs(names) do
- if RaceTable[v] == nil then
- --print("Failure, "..v.." not found!")
- error("Failure, "..v.." not found!")
- --break --maybe some indication of failure? and cleanup?
- end
- engine.pokew(modpos+modsize+count*2+4+2,RaceTable[v]) -- for some reason it compiled strangely
- -- cmp word[ebx+ecx*2],ax -> cmp word[ebx+ecx*2+2],ax
- count = count + 1
-end
-engine.poked(modpos+0x8f,modpos+modsize+4) -- set ptr to creatures
-engine.poked(modpos+0x94,count) -- set count of creatures
-engine.poked(modpos+0xb9,modpos+modsize) -- set safe location
-engine.poked(modpos+0xc3,modpos+modsize) -- set safe location
-SetExecute(modpos)
-end
-function pokeCall(off)
- engine.pokeb(off,0xe8)
- b=engine.peekb(off+1)
- engine.poked(off+1,modpos-off-5)
- engine.pokeb(off+5,b)
-end
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/friendship/patch.lua b/plugins/Dfusion/luafiles/friendship/patch.lua
deleted file mode 100644
index 247766db1..000000000
--- a/plugins/Dfusion/luafiles/friendship/patch.lua
+++ /dev/null
@@ -1,57 +0,0 @@
-function friendship_in.patch()
- UpdateRanges()
- pos=GetTextRegion().start
- local _,crace=df.sizeof(df.global.ui:_field("race_id"))
- hits={}
- i=1
- repeat
- --todo make something better/smarter...
- pos1=offsets.find(pos+7,0x0f,0xBF,ANYBYTE,DWORD_,crace) -- movsx
- pos2=offsets.find(pos+7,0x66,0xa1,DWORD_,crace) -- mov ax,[ptr]
- pos3=offsets.find(pos+7,0xa1,DWORD_,crace) -- mov eax,[ptr]
- pos4=offsets.find(pos+7,0x66,0x8b,ANYBYTE,DWORD_,crace) -- mov ANYREG,[ptr]
- --pos5=offsets.find(pos+7,0x66,0x8b,0x15,DWORD_,crace) -- mov dx,[ptr]
- pos=minEx{pos1,pos2,pos3,pos4}
- if pos ~=0 then
- hits[i]=pos
- i=i+1
- print(string.format("Found at %x",pos))
- end
- until pos==0
- print("=======================================")
- for _,p in pairs(hits) do
- myp=p
- repeat
-
- --print(string.format("Analyzing %x...",p))
- --TODO read offset from memory.xml
- pos1=offsets.find(myp,0x39,ANYBYTE,0x8c,00,00,00) -- compare [reg+08c] (creature race) with any reg
- pos2=offsets.find(myp,0x3b,ANYBYTE,0x8c,00,00,00) -- compare any reg with [reg+08c] (creature race)
- pos=minEx{pos1,pos2}
- if pos ~=0 then
-
- if(pos-p>250) then
- --this here does not work yet...
- --[[pos =offsets.find(p,CALL)
- print(string.format("Distance to call:%x",pos-p))
- print(string.format("Call: %x",signDword(engine.peekd(pos+1)+pos)))
- pos=analyzeF(signDword(signDword(engine.peekd(pos+1)+pos)))
-
- print(string.format("Cmp @:%x",pos))]]--
- print(string.format("skipping %x... Cmp too far away (dist=%i)",p,pos-p))
- else
- --print(string.format("Found at %x, simple compare",pos))
- --print(string.format("Distance =%x",pos-p))
- --patch compares
-
- pokeCall(pos)
- end
- else
- break
- end
- myp=myp+pos+6
- if myp-p >250 then break end
- until false
-
- end
-end
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/friendship/plugin.lua b/plugins/Dfusion/luafiles/friendship/plugin.lua
deleted file mode 100644
index 695ddf05e..000000000
--- a/plugins/Dfusion/luafiles/friendship/plugin.lua
+++ /dev/null
@@ -1,18 +0,0 @@
-if not(FILE) then
- --sanity test
- --print("race num:"..engine.peekw(offsets.getEx("CurrentRace")))
- --print(string.format("%x vs %x",offsets.getEx("CurrentRace"),VersionInfo.getGroup("Creatures"):getAddress("current_race")))
- print("Race num:"..df.global.ui.race_id)
- print("Your current race is:"..GetRaceToken(df.global.ui.race_id))
- print("If this is wrong please type 'q'")
- if(getline()=='q') then
- return
- end
-
-end
-
-if not(FILE) then
- names=ParseNames("dfusion/friendship/races.txt")--io.open("plugins/friendship/races.txt"):lines()
- friendship_in.install(names)
- friendship_in.patch()
-end
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/friendship/races.txt b/plugins/Dfusion/luafiles/friendship/races.txt
deleted file mode 100644
index e4ed7c5a6..000000000
--- a/plugins/Dfusion/luafiles/friendship/races.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-DWARF
-GOBLIN
-ELF
-HUMAN
-KOBOLD
-GREMLIN
-TIGERMAN
-ANT_MAN
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/friendship_civ/compile.bat b/plugins/Dfusion/luafiles/friendship_civ/compile.bat
deleted file mode 100644
index 64d4d4440..000000000
--- a/plugins/Dfusion/luafiles/friendship_civ/compile.bat
+++ /dev/null
@@ -1 +0,0 @@
-as -anl --32 -o friendship_c.o friendship_c.asm
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/friendship_civ/friendship_c.asm b/plugins/Dfusion/luafiles/friendship_civ/friendship_c.asm
deleted file mode 100644
index b2b49ee78..000000000
--- a/plugins/Dfusion/luafiles/friendship_civ/friendship_c.asm
+++ /dev/null
@@ -1,41 +0,0 @@
-.intel_syntax
-eaxpart:
-push eax
-push ecx
-jmp compare
-ecxpart:
-push eax
-push ecx
-mov eax,ecx
-
-compare:
-push ebx
-mov ebx,0xDEADBEEF #write a pointer to the list of allowed civs
-mov ecx,2000 #write a number of allowed civs
-loop1:
-cmp [ebx+ecx*4],eax
-jnz endok
-dec ecx
-cmp ecx ,-1
-jnz loop1
-
-pop ebx
-
-jmp fail
-
-endok:
-pop ebx
-
-cmp eax,eax
-jmp endfinal
-fail:
-
-xor ecx,ecx
-xor eax,eax
-inc eax
-cmp eax,ebx
-endfinal:
-
-pop ecx
-pop eax
-ret
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/friendship_civ/friendship_c.o b/plugins/Dfusion/luafiles/friendship_civ/friendship_c.o
deleted file mode 100644
index d85134682ac1e464b944b3e3403babe96a43a8b6..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 462
zcmeZaWM%+?JwVJ4X0bBrm84dbfY}hj07&&9@j*-l27?5>l*E!mG;wsU1B1Z1OTR|HW{tKy@S5H5q~QSv
z%NvmqhxO7jb5fxO{rk_rkj|Kvm<QhwOUcg$@)Y4BX^ELRKn{Z%Tm+~lEi*4MM;9)F9Ficrm>EG~
ai3*TIkqIcp3{r>&kV6m@U)a=uTn_-GKtCM-
diff --git a/plugins/Dfusion/luafiles/friendship_civ/init.lua b/plugins/Dfusion/luafiles/friendship_civ/init.lua
deleted file mode 100644
index 5390829de..000000000
--- a/plugins/Dfusion/luafiles/friendship_civ/init.lua
+++ /dev/null
@@ -1,89 +0,0 @@
-friendship_civ={}
-function friendship_civ.init()
- friendship_civ.count=0x0f
- friendship_civ.firsttime=true
- local mypos=engine.getmod("Friendship_civ")
- local modpos=0
- if mypos then
- modpos=mypos
- _,modsize=engine.loadobj("dfusion/friendship_civ/friendship_c.o")
- _=nil
- friendship_civ.firsttime=false
- else
- modpos,modsize=engine.loadmod("dfusion/friendship_civ/friendship_c.o","Friendship_civ",1024)
- print(string.format("Loaded module @:%x",modpos))
- end
- friendship_civ.modpos=modpos
- friendship_civ.modsize=modsize
-end
-function friendship_civ.install(civs)
- friendship_civ.init()
- local count=0
- for _,v in pairs(civs) do
- engine.poked(friendship_civ.modpos+friendship_civ.modsize+count*4,v) -- for some reason it compiled strangely
- -- cmp word[ebx+ecx*2],ax -> cmp word[ebx+ecx*2+2],ax
- count = count + 1
- end
- engine.poked(friendship_civ.modpos+0x0a,friendship_civ.modpos+friendship_civ.modsize) -- set ptr to civ ids
- engine.poked(friendship_civ.modpos+friendship_civ.count,count-1) -- set count of civs
- SetExecute(friendship_civ.modpos)
-
- if(friendship_civ.firsttime) then
- friendship_civ.patch()
- end
-end
-function friendship_civ.getcivs()
- if(friendship_civ.firsttime==nil)then
- return nil
- end
- friendship_civ.init()
- local count=engine.peekd(friendship_civ.modpos+friendship_civ.count)+1
- local ret={}
- for i=0, count-1 do
- table.insert(ret,engine.peekd(friendship_civ.modpos+friendship_civ.modsize+i*4))
- end
- return ret
-end
-function friendship_civ.addciv(civ) --if called with nil add current civ :)
- if civ==nil then
- local cciv=engine.peekd(VersionInfo.getGroup("Creatures"):getAddress("current_civ"))
- friendship_civ.install({cciv})
- return
- end
- local oldcivs=friendship_civ.getcivs()
- oldcivs=oldcivs or {}
- if type(civ)=="table" then
- for k,v in ipairs(civ) do
- table.insert(oldcivs,v)
- end
- else
- table.insert(oldcivs,civ)
- end
- friendship_civ.install(oldcivs)
-end
-function friendship_civ.patch_call(off,iseax)
- local calltrg=friendship_civ.modpos
- if not iseax then
- calltrg=calltrg+4
- end
- engine.pokeb(off,0xe8) --this is a call
- engine.poked(off+1,calltrg-off-5) --offset to call to (relative)
- engine.pokeb(off+5,0x90) --nop
-end
-function friendship_civ.patch()
- --UpdateRanges()
- local civloc= VersionInfo.getGroup("Creatures"):getAddress("current_civ")
- local pos1=offsets.findall(0,0x3B,0x05,DWORD_,civloc) --eax
- for k,v in pairs(pos1) do print(string.format("%d %x",k,v)) end
- local pos2=offsets.findall(0,0x3B,0x0D,DWORD_,civloc) --ecx
- for k,v in pairs(pos2) do print(string.format("%d %x",k,v)) end
-
- for k,v in pairs(pos1) do
- print(string.format("Patching eax compare %d: %x",k,v))
- friendship_civ.patch_call(v,true)
- end
- for k,v in pairs(pos2) do
- print(string.format("Patching ecx compare %d: %x",k,v))
- friendship_civ.patch_call(v,false)
- end
-end
diff --git a/plugins/Dfusion/luafiles/friendship_civ/plugin.lua b/plugins/Dfusion/luafiles/friendship_civ/plugin.lua
deleted file mode 100644
index 12f334fcf..000000000
--- a/plugins/Dfusion/luafiles/friendship_civ/plugin.lua
+++ /dev/null
@@ -1,57 +0,0 @@
-fc_ui={}
-fc_ui.menu=MakeMenu()
-function fc_ui.get()
- local mycivs=friendship_civ.getcivs()
- if mycivs~= nil then
- print(" Currently friendly civs:")
- for k,v in pairs(mycivs) do
- print(string.format("%d. %d",k,v))
- end
- else
- print(" Plugin no yet activated.")
- end
-end
-function fc_ui.add()
- print("Type in civ id to add (leave empty to add current, q cancels):")
- local r
- while r==nil and r~='q' do
- r=io.stdin:read()
- if r=="" then
- r=nil
- break
- end
- if r~='q' then r=tonumber(r) else
- return
- end
- end
- friendship_civ.addciv(r)
-end
-function fc_ui.remove()
- local mycivs=friendship_civ.getcivs()
- if mycivs~= nil then
- print(" Currently friendly civs:")
- for k,v in pairs(mycivs) do
- print(string.format("%d. %d",k,v))
- end
- else
- print(" Plugin no yet activated, nothing to remove.")
- return
- end
- print("Type in civ id to remove( q cancels):")
- local r
- while r==nil and r~='q' do
- r=io.stdin:read()
- if r~='q' then
- r=tonumber(r)
- if r>#mycivs then r=nil end
- else
- return
- end
- end
- table.remove(mycivs,r)
- friendship_civ.install(mycivs)
-end
-fc_ui.menu:add("Add civ",fc_ui.add)
-fc_ui.menu:add("Get civs",fc_ui.get)
-fc_ui.menu:add("Remove civ",fc_ui.remove)
-fc_ui.menu:display()
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/init.lua b/plugins/Dfusion/luafiles/init.lua
deleted file mode 100644
index c8eebcd23..000000000
--- a/plugins/Dfusion/luafiles/init.lua
+++ /dev/null
@@ -1,92 +0,0 @@
-function dofile(filename) --safer dofile, with traceback (very usefull)
- f,perr=loadfile(filename)
- if f~=nil then
- return safecall(f)
- else
- print(perr)
- end
-end
-function dofile_silent(filename) --safer dofile, with traceback, no file not found error
- f,perr=loadfile(filename)
- if f~=nil then
- return safecall(f)
- else
- if(string.sub(perr,1,11)~="cannot open") then --ugly hack
- print(perr)
- end
- end
-end
-function loadall(t1) --loads all non interactive plugin parts, so that later they could be used
- for k,v in pairs(t1) do
- dofile_silent("dfusion/"..v[1].."/init.lua")
- end
-end
-function mainmenu(t1)
- while true do
- print("No. Name Desc")
- for k,v in pairs(t1) do
- print(string.format("%3d %15s %s",k,v[1],v[2]))
- end
- local q=dfhack.lineedit("Select plugin to run (q to quit):")
- if q=='q' then return end
- q=tonumber(q)
- if q~=nil then
- if q>=1 and q<=#t1 then
- if t1[q][3]==nil then
- dofile("dfusion/"..t1[q][1].."/plugin.lua")
- else
- t1[q][3]()
- end
- end
- end
- end
-end
-function RunSaved()
- print("Locating saves...")
- local str=df.global.world.cur_savegame.save_dir
- print("Current region:"..str)
- str="data/save/"..str.."/dfusion/init.lua"
- print("Trying to run:"..str)
- dofile_silent(str)
-end
-dofile("dfusion/common.lua")
-dofile("dfusion/utils.lua")
-dofile("dfusion/offsets_misc.lua")
-dofile("dfusion/editor.lua")
-
-unlockDF()
-plugins={}
-table.insert(plugins,{"simple_embark","A simple embark dwarf count editor"})
-table.insert(plugins,{"tools","some misc tools"})
-table.insert(plugins,{"embark","Multi race embark"})
-table.insert(plugins,{"friendship","Multi race fort enabler"})
---[=[table.insert(plugins,{"items","A collection of item hacking tools"})
-table.insert(plugins,{"offsets","Find all offsets"})
-
-table.insert(plugins,{"friendship_civ","Multi civ fort enabler"})
-
-
-table.insert(plugins,{"triggers","a function calling plug (discontinued...)"})
-table.insert(plugins,{"migrants","multi race imigrations"})
---]=]
---table.insert(plugins,{"onfunction","run lua on some df function"})
---table.insert(plugins,{"editor","edit internals of df",EditDF})
-table.insert(plugins,{"saves","run current worlds's init.lua",RunSaved})
-table.insert(plugins,{"adv_tools","some tools for (mainly) adventurer hacking"})
-loadall(plugins)
-dofile_silent("dfusion/initcustom.lua")
-
-local args={...}
-
-
-local f,err=load(table.concat(args,' '))
-if f then
- f()
-else
- dfhack.printerr(err)
-end
-
-if not INIT then
-mainmenu(plugins)
-end
-
diff --git a/plugins/Dfusion/luafiles/migrants/compile.bat b/plugins/Dfusion/luafiles/migrants/compile.bat
deleted file mode 100644
index 4d226851d..000000000
--- a/plugins/Dfusion/luafiles/migrants/compile.bat
+++ /dev/null
@@ -1 +0,0 @@
-as -anl --32 -o migrants.o migrants.asm
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/migrants/init.lua b/plugins/Dfusion/luafiles/migrants/init.lua
deleted file mode 100644
index 6fb315923..000000000
--- a/plugins/Dfusion/luafiles/migrants/init.lua
+++ /dev/null
@@ -1,62 +0,0 @@
---install part
-function migrants(names)
-RaceTable=RaceTable or BuildNameTable()
-mypos=engine.getmod("Migrants")
-if mypos then
- print("Migrant mod is running already @:"..mypos)
- modpos=mypos
- _,modsize=engine.loadobj("dfusion/migrants/migrants.o")
- count=0
- for _,v in pairs(names) do
- if RaceTable[v] == nil then
- print("Failure, "..v.." not found!")
- break --maybe some indication of failure? and cleanup?
- end
- engine.pokew(modpos+modsize+count*2+4,RaceTable[v])
- count = count + 1
- end
- seedpos=modpos+modsize
- engine.poked(seedpos,math.random(1234567)) -- seed the generator :)
- engine.poked(modpos+0x1c,count) --max size for div
-
-else
- modpos,modsize=engine.loadmod("dfusion/migrants/migrants.o","Migrants",400)
- print(string.format("Loaded module @:%x",modpos))
- count=0
- for _,v in pairs(names) do
- if RaceTable[v] == nil then
- print("Failure, "..v.." not found!")
- break --maybe some indication of failure? and cleanup?
- end
- engine.pokew(modpos+modsize+count*2+4,RaceTable[v])
-
- count = count + 1
- end
-
- seedpos=modpos+modsize
- engine.poked(modpos+0x04,seedpos)
- engine.poked(modpos+0x15,seedpos)
-
- engine.poked(seedpos,math.random(1234567)) -- seed the generator :)
- engine.poked(modpos+0x1c,count) --max size for div
-
- engine.poked(modpos+0x26,seedpos+4) --start of array
-
- --patch part
- --pos=62873C+DF
- -- pattern: A1,DWORD_,"CURRENTRACE",56,89,ANYBYTE,ANYBYTE,34,e8
- _,raceoff=df.sizeof(df.global.ui:_field('race_id'))
- pos=offsets.find(offsets.base(),0xa1,DWORD_,raceoff,0x56,0x89,ANYBYTE,ANYBYTE,0x34,0xe8)
- function pokeCall(off)
- engine.pokeb(off,0xe8)
- engine.poked(off+1,modpos-off-5)
- end
- if pos~=0 then
- print(string.format("Found @:%x",pos))
- pokeCall(pos)
- else
- print("Not found patch location!!!")
- end
- end
-
-end
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/migrants/migrants.asm b/plugins/Dfusion/luafiles/migrants/migrants.asm
deleted file mode 100644
index 646497665..000000000
--- a/plugins/Dfusion/luafiles/migrants/migrants.asm
+++ /dev/null
@@ -1,20 +0,0 @@
-.intel_syntax
-pushfd
-push ebx
-push edx
-mov eax,[0xdeadbeef] # get old seed
-mov ebx,1103515245
-#mul 1103515245
-mul ebx
-add eax,12345
-mov [0xdeadbeef],eax #put seed back...thus generation rnd is complete
-
-xor edx,edx
-mov ebx,2000 #put size of array here
-div ebx #why oh why there is no div const? compiler prob makes some xor/add magic
-movzx eax,word ptr[0xdeadbeef+edx*2]
-pop edx
-pop ebx
-
-popfd
-ret
diff --git a/plugins/Dfusion/luafiles/migrants/migrants.o b/plugins/Dfusion/luafiles/migrants/migrants.o
deleted file mode 100644
index 30b5b14f03cd8e110b91123e0631f8e0b3378ed0..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 336
zcmeZaWM%+?JwVI>X0bBrm84dbfY}hj07&&9@j*-l27?5>l*E!mG;wsU1B1Zh*T58Y}8WPdP$)nF)LK=uPD#F#;bp#c^k
F9{~H9FI)fs
diff --git a/plugins/Dfusion/luafiles/migrants/plugin.lua b/plugins/Dfusion/luafiles/migrants/plugin.lua
deleted file mode 100644
index 651e4900c..000000000
--- a/plugins/Dfusion/luafiles/migrants/plugin.lua
+++ /dev/null
@@ -1,5 +0,0 @@
-
-if not(FILE) then
- names=ParseNames("dfusion/migrants/races.txt")--io.open("plugins/migrants/races.txt"):lines()
- migrants(names)
-end
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/migrants/races.txt b/plugins/Dfusion/luafiles/migrants/races.txt
deleted file mode 100644
index 9a3fa6cf6..000000000
--- a/plugins/Dfusion/luafiles/migrants/races.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-DWARF
-DWARF
-DWARF
-DWARF
-DWARF
-DWARF
-DWARF
-DWARF
-DWARF
-ELF
-HUMAN
-DWARF
-GREMLIN
-KOBOLD
-DWARF
-DWARF
-DWARF
-DWARF
-DWARF
-DWARF
-DWARF
-DWARF
-DWARF
-ELF
-HUMAN
-DWARF
-GREMLIN
-KOBOLD
-DEMON_13
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/offsets/plugin.lua b/plugins/Dfusion/luafiles/offsets/plugin.lua
deleted file mode 100644
index b9e2fc441..000000000
--- a/plugins/Dfusion/luafiles/offsets/plugin.lua
+++ /dev/null
@@ -1,2 +0,0 @@
-offsets.searchoffsets()
-offsets.save()
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/offsets_misc.lua b/plugins/Dfusion/luafiles/offsets_misc.lua
deleted file mode 100644
index 8bca50000..000000000
--- a/plugins/Dfusion/luafiles/offsets_misc.lua
+++ /dev/null
@@ -1,48 +0,0 @@
-offsets=offsets or {}
-function offsets.find(startoffset,...)
- -- [=[
- if startoffset== 0 then
- local text=GetTextRegion()
- --print("searching in:"..text.name)
- startoffset=text.start
- endadr=text["end"]
- else
- local reg=GetRegionIn(startoffset)
- --print("searching in:"..reg.name)
- if reg==nil then
- print(string.format("Warning: memory range for search @:%x not found!",startoffset))
- return 0
- end
- endadr=reg["end"]
- end
- --]=]
- --print(string.format("Searching (%x->%x)",startoffset,endadr))
- local h=hexsearch(startoffset,endadr,...)
- local pos=h:find()
- h=nil
- return pos
-end
-function offsets.findall(startoffset,...)
- local endadr;
- if startoffset== 0 then
- local text=GetTextRegion()
- --print("searching in:"..text.name)
- startoffset=text.start
- endadr=text["end"]
- else
- local reg=GetRegionIn(startoffset)
- --print("searching in:"..reg.name)
- endadr=reg["end"]
- end
- local h=hexsearch(startoffset,endadr,...)
- local pos=h:findall()
- h=nil
- return pos
-end
-function offsets.base()
- return Process.getBase()
-end
-function offsets.getvectors()
- return findVectors()
-end
-ADDRESS=ANYDWORD
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/simple_embark/plugin.lua b/plugins/Dfusion/luafiles/simple_embark/plugin.lua
deleted file mode 100644
index abc3530c2..000000000
--- a/plugins/Dfusion/luafiles/simple_embark/plugin.lua
+++ /dev/null
@@ -1,23 +0,0 @@
-function simple_embark(num)
- local stoff=dfhack.internal.getAddress('start_dwarf_count')
- print("Starting dwarves found:"..df.reinterpret_cast('int32_t', stoff).value)
- local tmp_val=df.new('int32_t')
- local size,pos=tmp_val:sizeof()
- tmp_val.value=num
- local ret=dfhack.internal.patchMemory(stoff,tmp_val,size)
- if ret then
- print("Success!")
- else
- qerror("Failed to patch in number")
- end
-end
-if not(FILE) then
-print("Type in new amount (more than 6, less than 15000):")
- repeat
- ans=tonumber(io.read())
- if ans==nil or not(ans<=15000 and ans>0) then
- print("incorrect choice")
- end
- until ans~=nil and (ans<=15000 and ans>0)
- simple_embark(ans)
-end
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/tools/init.lua b/plugins/Dfusion/luafiles/tools/init.lua
deleted file mode 100644
index a8c787ffb..000000000
--- a/plugins/Dfusion/luafiles/tools/init.lua
+++ /dev/null
@@ -1,511 +0,0 @@
-local ms=require "memscan"
-tools={}
-tools.menu=MakeMenu()
-function tools.setrace(name)
- RaceTable=BuildNameTable()
- print("Your current race is:"..GetRaceToken(df.global.ui.race_id))
- local id
- if name == nil then
- print("Type new race's token name in full caps (q to quit):")
- repeat
- entry=getline()
- 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
-tools.menu:add("Set current race",tools.setrace)
-function tools.GiveSentience(names)
- RaceTable=RaceTable or BuildNameTable() --slow.If loaded don't load again
- if names ==nil then
- ids={}
- print("Type race's token name in full caps to give sentience to:")
- repeat
- entry=getline()
- id=RaceTable[entry]
- until id~=nil
- table.insert(ids,id)
- 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.size))
- 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
-tools.menu:add("Give Sentience",tools.GiveSentience)
-function tools.embark() --windows only?
- local seg=ms.get_code_segment()
- local idx,off
-
- idx,off=seg.uint8_t:find_one{0x66, 0x83, 0x7F ,0x1A ,0xFF,0x74,0x04}
- if idx then
- local tmp_val=df.new('uint8_t',2)
- tmp_val[0]=0x90
- tmp_val[1]=0x90
- local size,pos=tmp_val:sizeof()
- local ret=dfhack.internal.patchMemory(off+5,pos,size*2)
- if ret then
- print("Found and patched:",off+5)
- else
- print("Patching failed at:",off+5)
- end
- tmp_val:delete()
- else
- qerror("Offset for embark patch not found!")
- end
-end
-if WINDOWS then
-tools.menu:add("Embark anywhere",tools.embark)
-end
-function tools.getCreatureId(vector) --redo it to getcreature by name/id or something
- tnames={}
- rnames={}
- --[[print("vector1 size:"..vector:size())
- print("vector2 size:"..vector2:size())]]--
- for i=0,vector:size()-1 do
- --print(string.format("%x",vector:getval(i)))
-
- local name=engine.peek(vector:getval(i),ptt_dfstring):getval()
- local lid= tools.getlegendsid(vector:getval(i))
- if lid ~=0 then
- print(i..")*Creature Name:"..name.." race="..engine.peekw(vector:getval(i)+ptr_Creature.race.off).." legendid="..lid)
- else
- print(i..") Creature Name:"..name.." race="..engine.peekw(vector:getval(i)+ptr_Creature.race.off))
- end
- if name ~="" and name~=nil then
- tnames[i]=name
- rnames[name]=i
- end
- end
- print("=====================================")
- print("type in name or number:")
- r=getline()
- if tonumber(r) ==nil then
- indx=rnames[r]
- if indx==nil then return end
- else
- r=tonumber(r)
- if rLOVE), q to quit:")
- names={}
- repeat
- w=getline();
-
- if rwords[w]~=nil then
- table.insert(names,w)
- print("--added--")
- end
-
- until w=='q'
- end
-
- tnames={}
- for _,v in pairs(names) do
- if rwords[v] ~=nil then
- table.insert(tnames,rwords[v]) --get word numbers
- end
- end
-
- local offsites=engine.peekd(offsets.getEx("SiteData"))+0x120
- snames={" pfort"," dfort"," cave","mohall","forest","hamlet","imploc"," lair"," fort"," camp"}
- vector=engine.peek(offsites,ptr_vector)
- print("Number of sites:"..vector:size())
- print("List of hits:")
- for i =0,vector:size()-1 do
- off=vector:getval(i)
-
- good=true
- r=""
- hits=0
- sname=engine.peek(off,ptr_site.name)
- for k=0,6 do
- vnum=sname[k]--engine.peekd(off+0x38+k*4)
- tgood=false
-
- if vnum~=0xFFFFFFFF then
- --print(string.format("%x",vnum))
- if names[vnum]~=nil then
- r=r..names[vnum].." "
- end
- for _,v in pairs(tnames) do
- if vnum==v then
- tgood=true
- --print("Match")
- hits=hits+1
- break
- end
- end
- if not tgood then
- good=false
- end
- end
- end
-
- if(good) and (hits>0)then
- --if true then
- --print("=====================")
- typ=engine.peek(off,ptr_site.type)--engine.peekw(off+0x78)
- flg=engine.peekd(engine.peek(off,ptr_site.flagptr))
- --flg=engine.peekd(off+224)
- --flg2=engine.peekw(off)
- --tv=engine.peek(off+0x84,ptr_vector)
- --tv2=engine.peek(off+0xA4,ptr_vector)
-
- print(string.format("%d)%s off=%x type=%s\t flags=%x",i,r,off,snames[typ+1],flg))
-
- if i%100==99 then
- r=getline()
- end
-
- end
- end
- print("Type which to change (q cancels):")
- repeat
- r=getline()
- n=tonumber(r)
- if(r=='q') then return end
- until n~=nil
- return vector:getval(n)
-end
-function tools.changesite(names)
- off=tools.getsite(names)
- snames={"Mountain halls (yours)","Dark fort","Cave","Mountain hall (NPC)","Forest retreat","Hamlet","Important location","Lair","Fort","Camp"}
-
- print("Type in the site type (q cancels):")
- for k,v in pairs(snames) do
- print((k-1).."->"..v)
- end
- repeat
- r=getline()
- n2=tonumber(r)
- if(r=='q') then return end
- until n2~=nil
- --off=vector:getval(n)
- print(string.format("%x->%d",off,n2))
- engine.poke(off,ptr_site.type,n2)
-end
-function tools.project(unit,trg)
- 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.refs:insert(#unit.refs,proj_ref)
- unit.flags1.projectile=true
-end
-function tools.empregnate(unit)
- if unit==nil then
- unit=getSelectedUnit()
- end
-
- if unit==nil then
- unit=getCreatureAtPos(getxyz())
- 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_ptr == nil then
- print("creating preg ptr.")
- if false then
- print(string.format("%x %x",df.sizeof(unit.relations:_field("pregnancy_ptr"))))
- return
- end
- unit.relations.pregnancy_ptr = { new = true, assign = genes }
- end
- local ngenes = unit.relations.pregnancy_ptr
- 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_mystery=1
-end
-tools.menu:add("Empregnate",tools.empregnate)
-function tools.changeflags(names)
- myflag_pattern=ptt_dfflag.new(3*8)
- off=tools.getsite(names)
- offflgs=engine.peek(off,ptr_site.flagptr)
- q=''
- print(string.format("Site offset %x flags offset %x",off,offflgs))
- repeat
- print("flags:")
-
- --off=vector:getval(n)
- flg=engine.peek(offflgs,myflag_pattern)
- r=""
- for i=0,3*8-1 do
- if flg:get(i)==1 then
- r=r.."x"
- else
- r=r.."o"
- end
- if i%8==7 then
- print(i-7 .."->"..r)
- r=""
- end
- end
- print("Type number to flip, or 'q' to quit.")
- q=getline()
- n2=tonumber(q)
- if n2~=nil then
-
- flg:flip(n2)
- engine.poke(offflgs,myflag_pattern,flg)
- end
- until q=='q'
-end
-function tools.hostilate()
- vector=engine.peek(offsets.getEx("CreatureVec"),ptr_vector)
- id=engine.peekd(offsets.getEx("CreaturePtr"))
- print(string.format("Vec:%d cr:%d",vector:size(),id))
- off=vector:getval(id)
- crciv=engine.peek(off,ptr_Creature.civ)
- print("Creatures civ:"..crciv)
- curciv=engine.peekd(offsets.getEx("CurrentRace")-12)
- print("My civ:"..curciv)
- if curciv==crciv then
- print("Friendly-making enemy")
- engine.poke(off,ptr_Creature.civ,-1)
- flg=engine.peek(off,ptr_Creature.flags)
- flg:set(17,0)
- print("flag 51:"..tostring(flg:get(51)))
- engine.poke(off,ptr_Creature.flags,flg)
- else
- print("Enemy- making friendly")
- engine.poke(off,ptr_Creature.civ,curciv)
- flg=engine.peek(off,ptr_Creature.flags)
- flg:set(17,1)
- flg:set(19,0)
- engine.poke(off,ptr_Creature.flags,flg)
- end
-end
-function tools.mouseBlock()
- local xs,ys,zs
- xs,ys,zs=getxyz()
- xs=math.floor(xs/16)
- ys=math.floor(ys/16)
- print("Mouse block is:"..xs.." "..ys.." "..zs)
-end
-function tools.fixwarp()
- local mapoffset=offsets.getEx("WorldData")--0x131C128+offsets.base()
- local x=engine.peek(mapoffset+24,DWORD)
- local y=engine.peek(mapoffset+28,DWORD)
- local z=engine.peek(mapoffset+32,DWORD)
- --vec=engine.peek(mapoffset,ptr_vector)
-
- print("Blocks loaded:"..x.." "..y.." "..z)
- print("Select type:")
- print("1. All (SLOW)")
- print("2. range (x0 x1 y0 y1 z0 z1)")
- print("3. One block around pointer")
- print("anything else- quit")
- q=getline()
- n2=tonumber(q)
- if n2==nil then return end
- if n2>3 or n2<1 then return end
- local xs,xe,ys,ye,zs,ze
- if n2==1 then
- xs=0
- xe=x-1
- ys=0
- ye=y-1
- zs=0
- ze=z-1
- elseif n2==2 then
- print("enter x0:")
- xs=tonumber(getline())
- print("enter x1:")
- xe=tonumber(getline())
- print("enter y0:")
- ys=tonumber(getline())
- print("enter y1:")
- ye=tonumber(getline())
- print("enter z0:")
- zs=tonumber(getline())
- print("enter z1:")
- ze=tonumber(getline())
- function clamp(t,vmin,vmax)
- if t> vmax then return vmax end
- if t< vmin then return vmin end
- return t
- end
- xs=clamp(xs,0,x-1)
- ys=clamp(ys,0,y-1)
- zs=clamp(zs,0,z-1)
- xe=clamp(xe,xs,x-1)
- ye=clamp(ye,ys,y-1)
- ze=clamp(ze,zs,z-1)
- else
- xs,ys,zs=getxyz()
- xs=math.floor(xs/16)
- ys=math.floor(ys/16)
- xe=xs
- ye=ys
- ze=zs
- end
- local xblocks=engine.peek(mapoffset,DWORD)
- local flg=bit.bnot(bit.lshift(1,3))
- for xx=xs,xe do
- local yblocks=engine.peek(xblocks+xx*4,DWORD)
- for yy=ys,ye do
- local zblocks=engine.peek(yblocks+yy*4,DWORD)
- for zz=zs,ze do
- local myblock=engine.peek(zblocks+zz*4,DWORD)
- if myblock~=0 then
- for i=0,255 do
- local ff=engine.peek(myblock+0x67c+i*4,DWORD)
- ff=bit.band(ff,flg) --set 14 flag to 1
- engine.poke(myblock+0x67c+i*4,DWORD,ff)
- end
- end
- end
- print("Blocks done:"..xx.." "..yy)
- end
- end
-end
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/tools/plugin.lua b/plugins/Dfusion/luafiles/tools/plugin.lua
deleted file mode 100644
index 8eaefd44d..000000000
--- a/plugins/Dfusion/luafiles/tools/plugin.lua
+++ /dev/null
@@ -1,8 +0,0 @@
-if not(FILE) then
- --tools.menu:add("Change site type",tools.changesite)
- --tools.menu:add("Change site flags",tools.changeflags)
- --tools.menu:add("Hostilate creature",tools.hostilate)
- --tools.menu:add("Print current mouse block",tools.mouseBlock)
-
- tools.menu:display()
-end
\ No newline at end of file
diff --git a/plugins/Dfusion/luafiles/utils.lua b/plugins/Dfusion/luafiles/utils.lua
deleted file mode 100644
index d481f5cfc..000000000
--- a/plugins/Dfusion/luafiles/utils.lua
+++ /dev/null
@@ -1 +0,0 @@
-function findVectorsSized(size)
local ret={}
local text=GetTextRegion()
for k,v in pairs(offsets.getvectors()) do
if GetRegionIn2(k)~=nil then
--if v>4 then
local tv=engine.peek(k,ptr_vector)
if tv:size() == size then
print(string.format("%x is size %d",k,size))
table.insert(ret,k)
end
end
end
return ret
end
function findMaterial(mattype,matname) --currently only stones
local tbl=BuildMaterialTable()
return tbl[matname]
end
function iter(tbl)
if getmetatable(tbl) ~=nil then
if getmetatable(tbl).__next~= nil then
return getmetatable(tbl).__next,tbl
else
return getmetatable(tbl).__pairs(tbl) or pairs(tbl)
end
else
return pairs(tbl)
end
end
\ No newline at end of file
diff --git a/plugins/lua/dfusion/embark.lua b/plugins/lua/dfusion/embark.lua
index 578c0b903..6e5df4eef 100644
--- a/plugins/lua/dfusion/embark.lua
+++ b/plugins/lua/dfusion/embark.lua
@@ -3,22 +3,34 @@ local dfu=require("plugins.dfusion")
local ms=require("memscan")
local MAX_RACES=100
CustomEmbark=defclass(CustomEmbark,dfu.BinaryPlugin)
-CustomEmbark.name="CustomEmbark"
-
-print(t)
local myos=dfhack.getOSType()
if myos=="windows" then
CustomEmbark.ATTRS{filename="hack/lua/plugins/dfusion/embark.o",name="CustomEmbark",race_caste_data=DEFAULT_NIL}
- CustomEmbark.class_status="valid, not installed"
- function CustomEmbark:install()
- local stoff=dfhack.internal.getAddress('start_dwarf_count')
-
- if #self.race_caste_data<7 then
+ function CustomEmbark:parseRaces(races)
+ if #races<7 then
error("caste and race count must be bigger than 6")
end
- if #self.race_caste_data>MAX_RACES then
+ if #races>MAX_RACES 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
+ ids[k]={}
+ ids[k][1]=n_to_id[race]
+ if ids[k][1]==nil then qerror(race.." not found!") end
+ ids[k][2]=v[2] or -1
+ end
+ self.race_caste_data=ids
+ end
+ function CustomEmbark:install(race_caste_data)
+ local stoff=dfhack.internal.getAddress('start_dwarf_count')
+ 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
@@ -40,14 +52,14 @@ if myos=="windows" then
local call_data={0x90,0x90}
local _,data_offset=df.sizeof(self.data)
dfu.concatTables(call_data,dfu.makeCall(trg_offset+2,data_offset))
- self.call_patch=dfu.BinaryPatch{pre_data=needle,data=call_data,address=trg_offset,name="custom_embark_call_patch"}
+ self.call_patch=self.call_patch or dfu.BinaryPatch{pre_data=needle,data=call_data,address=trg_offset,name="custom_embark_call_patch"}
needle={0x83,0xc8,0xff} -- or eax, 0xFF
local _,caste_offset=mem.uint8_t:find(needle,mem.uint8_t:addr2idx(trg_offset),nil)
if caste_offset==nil or caste_offset-stoff>1000 then
error("Caste change code not found or found too far!")
end
- self.disable_castes=dfu.BinaryPatch{pre_data={0x83,0xc8,0xff},data={0x90,0x90,0x90},address=caste_offset,name="custom_embark_caste_disable"}
+ 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()
@@ -66,16 +78,11 @@ if myos=="windows" then
self.call_patch:apply()
self.installed=true
end
+
function CustomEmbark:setEmbarkParty(racesAndCastes)
local stoff=dfhack.internal.getAddress('start_dwarf_count')
- if #racesAndCastes<7 then
- error("caste and race count must be bigger than 6")
- end
- if #racesAndCastes>MAX_RACES then
- error("caste and race count must be less then "..MAX_RACES)
- end
- self.race_caste_data=racesAndCastes
+
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()
@@ -84,8 +91,9 @@ 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]
+ caste_array[k-1]=v[2] or -1
race_array[k-1]=v[1]
end
end
@@ -103,48 +111,14 @@ if myos=="windows" then
self.dwarfcount:remove()
end
end
- function CustomEmbark:edit()
- local data=self.race_caste_data or {}
- print(string.format("Old race count:%d",#data))
- local endthis=false
- print("current:")
- while(not endthis) do
- print(" # RaceId Race name Caste num")
- for k,v in pairs(data) do
- local name=df.creature_raw.find(v[1]).creature_id or ""
- print(string.format("%3d. %6d %20s %d",k,v[1],name,v[2]))
- end
- print("a- add, r-remove, c-cancel, s-save and update")
- local choice=io.stdin:read()
- if choice=='a' then
- print("Enter new race then caste ids:")
- local race=tonumber(io.stdin:read())
- local caste=tonumber(io.stdin:read())
- if race and caste then
- table.insert(data,{race,caste})
- else
- print("input parse error")
- end
- elseif choice=='r' then
- print("enter number to remove:")
- local num_rem=tonumber(io.stdin:read())
- if num_rem~=nil then
- table.remove(data,num_rem)
- end
- elseif choice=='c' then
- endthis=true
- elseif choice=='s' then
- endthis=true
- if self.installed then
- self:setEmbarkParty(data)
- else
- self.race_caste_data=data
- self:install()
- end
- end
+ function CustomEmbark:unload()
+ self:uninstall()
+ if Embark~=nil then
+ Embark=nil
end
end
+ Embark=Embark or CustomEmbark()
else
- CustomEmbark.class_status="invalid, os not supported"
+ CustomEmbark.status=function() return"invalid, os not supported" end
end
return _ENV
\ No newline at end of file
diff --git a/plugins/lua/dfusion/friendship.lua b/plugins/lua/dfusion/friendship.lua
index 70a1ceea4..93a370c86 100644
--- a/plugins/lua/dfusion/friendship.lua
+++ b/plugins/lua/dfusion/friendship.lua
@@ -35,7 +35,7 @@ function FriendshipRainbow:find_all()
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
- printall(locations)
+
return self:filter_locations(code,locations)
end
function FriendshipRainbow:filter_locations(codesg,locations)
@@ -107,5 +107,6 @@ function FriendshipRainbow:install(races)
local addr=self:move_to_df()
self:patchCalls(addr)
self.installed=true
- end
+end
+Friendship=Friendship or FriendshipRainbow()
return _ENV
\ No newline at end of file
From 856c9ebd4b7bfb09a57576cb73763c1ead00baa1 Mon Sep 17 00:00:00 2001
From: Warmist
Date: Sun, 11 Nov 2012 12:39:49 +0200
Subject: [PATCH 042/158] Added save specific scripts to lua interpreter
script, also better error reporting.
---
scripts/lua.lua | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/scripts/lua.lua b/scripts/lua.lua
index 497498e86..556962347 100644
--- a/scripts/lua.lua
+++ b/scripts/lua.lua
@@ -1,9 +1,26 @@
local args={...}
if args[1]=="--file" or args[1]=="-f" then
- local f=loadfile (args[2])
+ local f,err=loadfile (args[2])
+ if f==nil then
+ qerror(err)
+ end
+ dfhack.pcall(f,table.unpack(args,3))
+elseif args[1]=="--save" or args[1]=="-s" then
+ if df.global.world.cur_savegame.save_dir=="" then
+ qerror("Savefile not loaded")
+ end
+ local fname=args[2] or "dfhack.lua"
+ fname=string.format("data/save/%s/%s",df.global.world.cur_savegame.save_dir,fname)
+ local f,err=loadfile (fname)
+ if f==nil then
+ qerror(err)
+ end
dfhack.pcall(f,table.unpack(args,3))
elseif args[1]~=nil then
- local f=load(args[1],'=(lua command)', 't')
+ local f,err=load(args[1],'=(lua command)', 't')
+ if f==nil then
+ qerror(err)
+ end
dfhack.pcall(f,table.unpack(args,2))
else
dfhack.interpreter("lua","lua.history")
From d5c31942b50accc840026182100c48928d76641f Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Sun, 11 Nov 2012 10:58:05 +0400
Subject: [PATCH 043/158] Add a way to only count locally-made items in
workflow.
---
Readme.html | 661 ++++++++++++++++++++++-----------------
Readme.rst | 82 ++++-
dfhack.init-example | 23 +-
plugins/lua/workflow.lua | 11 +-
plugins/workflow.cpp | 95 ++++--
scripts/gui/workflow.lua | 11 +-
6 files changed, 550 insertions(+), 333 deletions(-)
diff --git a/Readme.html b/Readme.html
index cd073459c..16f3aed5a 100644
--- a/Readme.html
+++ b/Readme.html
@@ -337,197 +337,201 @@ access DF memory and allow for easier development of new tools.
Introduction
Getting DFHack
Compatibility
-Installation/Removal
-Using DFHack
-- Patched binaries
+- Installation/Removal
-- Something doesn't work, help!
-- The init file
-- Setting keybindings
+- Using DFHack
-- Commands
-- Game progress
-- die
-- forcepause
-- nopause
-- fastdwarf
+- Something doesn't work, help!
+- The init file
-- Game interface
-- follow
-- tidlers
-- twaterlvl
-- copystock
-- rename
+- Commands
+- Game progress
-- Adventure mode
-- adv-bodyswap
-- advtools
+- Game interface
-- Map modification
-- changelayer
-- changevein
-- changeitem
-- colonies
-- deramp (by zilpin)
-- feature
-- liquids
-- liquids-here
-- tiletypes
-- tiletypes-commands
-- tiletypes-here
-- tiletypes-here-point
-- tubefill
-- extirpate
-- grow
-- immolate
-- regrass
-- weather
+- Adventure mode
-- Map inspection
-- cursecheck
-- flows
-- probe
-- prospect
-- Pre-embark estimate
+- Map modification
-- reveal
-- unreveal
-- revtoggle
-- revflood
-- revforget
-- showmood
+- Map inspection
+- cursecheck
+- flows
+- probe
+- prospect
-- Designations
-- Cleanup and garbage disposal
-- clean
-- spotclean
-- autodump
-- autodump-destroy-here
-- autodump-destroy-item
-- cleanowned
+- Designations
-- Bugfixes
-- drybuckets
-- fixdiplomats
-- fixmerchants
-- fixveins
-- tweak
-- fix-armory
+- Cleanup and garbage disposal
-- Mode switch and reclaim
-- lair
-- mode
+- Bugfixes
-- Visualizer and data export
-- ssense / stonesense
-- mapexport
-- dwarfexport
+- Mode switch and reclaim
-- Job management
-- job
-- job-material
-- job-duplicate
-- workflow
-- Function
-- Constraint examples
+- Visualizer and data export
+- Job management
+- job
+- job-material
+- job-duplicate
+- workflow
-- Fortress activity management
-- seedwatch
-- zone
-- autonestbox
-- autobutcher
-- autolabor
+- Fortress activity management
+- seedwatch
+- zone
-- Other
+- Other
-- Scripts
-- In-game interface tools
-- Dwarf Manipulator
-- Search
-- gui/liquids
-- gui/mechanisms
-- gui/rename
-- gui/room-list
-- gui/choose-weapons
-- gui/guide-path
-- gui/workshop-job
-- gui/workflow
-- gui/assign-rack
+- Scripts
-- Behavior Mods
-- Siege Engine
-- Rationale
-- Configuration UI
+- In-game interface tools
-- Power Meter
-- Steam Engine
@@ -570,9 +574,29 @@ remove the other DFHack files
The stonesense plugin might require some additional libraries on Linux.
If any of the plugins or dfhack itself refuses to load, check the stderr.log
file created in your DF folder.
+
+
+
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
+the console.
+
NOTE: The dfhack-run executable is there for calling DFHack commands in
+an already running DF+DFHack instance from external OS scripts and programs,
+and is not the way how you use DFHack normally.
+
DFHack has a lot of features, which can be accessed by typing commands in the
+console, or by mapping them to keyboard shortcuts. Most of the newer and more
+user-friendly tools are designed to be at least partially used via the latter
+way.
+
In order to set keybindings, you have to create a text configuration file
+called dfhack.init; the installation comes with an example version called
+dfhack.init-example, which is fully functional, covers all of the recent
+features and can be simply renamed to dfhack.init. You are encouraged to look
+through it to learn which features it makes available under which key combinations.
+
For more information, refer to the rest of this document.
+
-
+
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
@@ -595,7 +619,7 @@ they are re-created every time it is loaded.
Interactive commands like 'liquids' cannot be used as hotkeys.
Most of the commands come from plugins. Those reside in 'hack/plugins/'.
-
+
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:
@@ -624,7 +648,7 @@ system console:
-
+
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.
@@ -633,13 +657,13 @@ the issues tracker on github, contact me (
-
+
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.
-
+
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.
@@ -684,7 +708,7 @@ for context
foo/bar/baz, possible matches are
-
+
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.
@@ -706,13 +730,13 @@ The following two command lines are exactly equivalent:
to retrieve further help without having to look at this document. Alternatively,
some accept a 'help'/'?' option on their command line.
-
+
-
+
Instantly kills DF without saving.
-
+
Forces DF to pause. This is useful when your FPS drops below 1 and you lose
control of the game.
@@ -723,12 +747,12 @@ control of the game.
-
+
Disables pausing (both manual and automatic) with the exception of pause forced
by 'reveal hell'. This is nice for digging under rivers.
-
+
Controls speedydwarf and teledwarf. Speedydwarf makes dwarves move quickly and perform tasks quickly. Teledwarf makes dwarves move instantaneously, but do jobs at the same speed.
@@ -745,29 +769,29 @@ that implements an even more aggressive version of speedydwarf.
-
+
-
+
Makes the game view follow the currently highlighted unit after you exit from
current menu/cursor mode. Handy for watching dwarves running around. Deactivated
by moving the view manually.
-
+
Toggle between all possible positions where the idlers count can be placed.
-
+
Toggle between displaying/not displaying liquid depth as numbers.
-
+
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.
-
+
Allows renaming various things.
Options:
@@ -801,9 +825,9 @@ siege engine or an activity zone.
-
+
-
+
This allows taking control over your followers and other creatures in adventure
mode. For example, you can make them pick up new arms and armor and equip them
properly.
@@ -816,7 +840,7 @@ properly.
-
+
-
+
Changes material of the geology layer under cursor to the specified inorganic
RAW material. Can have impact on all surrounding regions, not only your embark!
By default changing stone to soil and vice versa is not allowed. By default
@@ -916,7 +940,7 @@ You did save your game, right?
-
+
Changes material of the vein under cursor to the specified inorganic RAW
material. Only affects tiles within the current 16x16 block - for veins and
large clusters, you will need to use this command multiple times.
@@ -929,7 +953,7 @@ large clusters, you will need to use this command multiple times.
-
+
Allows changing item material and base quality. By default the item currently
selected in the UI will be changed (you can select items in the 'k' list
or inside containers/inventory). By default change is only allowed if materials
@@ -969,7 +993,7 @@ crafters/haulers.
-
+
Allows listing all the vermin colonies on the map and optionally turning them into honey bee colonies.
Options:
@@ -984,12 +1008,12 @@ crafters/haulers.
-
+
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).
-
+
Enables management of map features.
- Discovering a magma feature (magma pool, volcano, magma sea, or curious
@@ -1014,7 +1038,7 @@ that cavern to grow within your fortress.
-
+
Allows adding magma, water and obsidian to the game. It replaces the normal
dfhack command line and can't be used from a hotkey. Settings will be remembered
as long as dfhack runs. Intended for use in combination with the command
@@ -1027,13 +1051,13 @@ temperatures (creating heat traps). You've been warned.
-
+
Run the liquid spawner with the current/last settings made in liquids (if no
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.
-
+
Can be used for painting map tiles and is an interactive command, much like
liquids.
The tool works with two set of options and a brush. The brush determines which
@@ -1094,27 +1118,27 @@ up.
For more details, see the 'help' command while using this.
-
+
Runs tiletypes commands, separated by ;. This makes it possible to change
tiletypes modes from a hotkey.
-
+
Apply the current tiletypes options at the in-game cursor position, including
the brush. Can be used from a hotkey.
-
+
Apply the current tiletypes options at the in-game cursor position to a single
tile. Can be used from a hotkey.
-
+
Fills all the adamantine veins again. Veins that were empty will be filled in
too, but might still trigger a demon invasion (this is a known bug).
-
+
A tool for getting rid of trees and shrubs. By default, it only kills
a tree/shrub under the cursor. The plants are turned into ashes instantly.
Options:
@@ -1134,20 +1158,20 @@ a tree/shrub under the cursor. The plants are turned into ashes instantly.
-
+
Makes all saplings present on the map grow into trees (almost) instantly.
-
+
Very similar to extirpate, but additionally sets the plants on fire. The fires
can and will spread ;)
-
+
Regrows grass. Not much to it ;)
-
+
Prints the current weather map by default.
Also lets you change the current weather to 'clear sky', 'rainy' or 'snowing'.
Options:
@@ -1168,9 +1192,9 @@ can and
will spread ;)
-
+
-
+
Checks a single map tile or the whole map/world for cursed creatures (ghosts,
vampires, necromancers, werebeasts, zombies).
With an active in-game cursor only the selected tile will be observed.
@@ -1225,17 +1249,17 @@ of curses, for example.
-
+
A tool for checking how many tiles contain flowing liquids. If you suspect that
your magma sea leaks into HFS, you can use this tool to be sure without
revealing the map.
-
+
Can be used to determine tile properties like temperature.
-
+
Prints a big list of all the present minerals and plants. By default, only
the visible part of the map is scanned.
Options:
@@ -1254,7 +1278,7 @@ the visible part of the map is scanned.
-
+
If prospect is called during the embark selection screen, it displays an estimate of
layer stone availability.
@@ -1279,7 +1303,7 @@ that is actually present.
-
+
This reveals the map. By default, HFS will remain hidden so that the demons
don't spawn. You can use 'reveal hell' to reveal everything. With hell revealed,
you won't be able to unpause until you hide the map again. If you really want
@@ -1288,34 +1312,34 @@ to unpause with hell revealed, use 'reveal demons'.
you move. When you use it this way, you don't need to run 'unreveal'.
-
+
Reverts the effects of 'reveal'.
-
+
Switches between 'reveal' and 'unreveal'.
-
+
This command will hide the whole map and then reveal all the tiles that have
a path to the in-game cursor.
-
+
When you use reveal, it saves information about what was/wasn't visible before
revealing everything. Unreveal uses this information to hide things again.
This command throws away the information. For example, use in cases where
you abandoned with the fort revealed and no longer want the data.
-
+
Shows all items needed for the currently active strange mood.
-
+
-
+
Miscellaneous burrow control. Allows manipulating burrows and automated burrow
expansion while digging.
Options:
@@ -1363,17 +1387,17 @@ Digging 1-wide corridors with the miner inside the burrow is SLOW.
-
+
Designates a whole vein for digging. Requires an active in-game cursor placed
over a vein tile. With the 'x' option, it will traverse z-levels (putting stairs
between the same-material tiles).
-
+
A permanent alias for 'digv x'.
-
+
Designates layer stone for digging. Requires an active in-game cursor placed
over a layer stone tile. With the 'x' option, it will traverse z-levels
(putting stairs between the same-material tiles). With the 'undo' option it
@@ -1381,11 +1405,11 @@ will remove the dig designation instead (if you realize that digging out a 50
z-level deep layer was not such a good idea after all).
-
+
A permanent alias for 'digl x'.
-
+
A command for easy designation of filled and hollow circles.
It has several types of options.
Shape:
@@ -1511,7 +1535,7 @@ repeats with the last selected parameters.
-
+
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.
If an argument is given, the designation of the selected tile is ignored, and all appropriate tiles are set to the specified designation.
Options:
@@ -1539,7 +1563,7 @@ If an argument is given, the designation of the selected tile is ignored, and al
-
+
Set traffic designations using flood-fill starting at the cursor.
Traffic Type Codes:
@@ -1578,7 +1602,7 @@ If an argument is given, the designation of the selected tile is ignored, and al
'filltraffic H' - When used in a room with doors, it will set traffic to HIGH in just that room.
-
+
Set traffic designations for every single tile of the map (useful for resetting traffic designations).
Traffic Type Codes:
@@ -1602,7 +1626,7 @@ If an argument is given, the designation of the selected tile is ignored, and al
'alltraffic N' - Set traffic to 'normal' for all tiles.
-
+
This tool allows plant gathering and tree cutting by RAW ID. Specify the types
of trees to cut down and/or shrubs to gather by their plant names, separated
by spaces.
@@ -1629,9 +1653,9 @@ all valid plant IDs will be listed.
-
+
-
+
Cleans all the splatter that get scattered all over the map, items and
creatures. In an old fortress, this can significantly reduce FPS lag. It can
also spoil your !!FUN!!, so think before you use it.
@@ -1665,12 +1689,12 @@ also spoil your !!FUN!!, so think before you use it.
-
+
Works like 'clean map snow mud', but only for the tile under the cursor. Ideal
if you want to keep that bloody entrance 'clean map' would clean up.
-
+
This utility lets you quickly move all items designated to be dumped.
Items are instantly moved to the cursor position, the dump flag is unset,
and the forbid flag is set, as if it had been dumped normally.
@@ -1697,17 +1721,17 @@ Be aware that any active dump item tasks still point at the item.
-
+
Destroy items marked for dumping under cursor. Identical to autodump
destroy-here, but intended for use as keybinding.
-
+
Destroy the selected item. The item may be selected in the 'k' list, or inside
a container. If called again before the game is resumed, cancels destroy.
-
+
Confiscates items owned by dwarfs. By default, owned food on the floor
and rotten items are confistacted and dumped.
Options:
@@ -1741,13 +1765,13 @@ worn items with 'X' damage and above.
-
+
-
+
This utility removes water from all buckets in your fortress, allowing them to be safely used for making lye.
-
+
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
@@ -1756,19 +1780,19 @@ to violate them and potentially start wars) in case you haven't already modified
your raws accordingly.
-
+
This command adds the Guild Representative position to all Human civilizations,
allowing them to make trade agreements (just as they did back in 0.28.181.40d
and earlier) in case you haven't already modified your raws accordingly.
-
+
Removes invalid references to mineral inclusions and restores missing ones.
Use this if you broke your embark with tools like tiletypes, or if you
accidentally placed a construction on top of a valuable mineral floor.
-
+
Contains various tweaks for minor bugs.
One-shot subcommands:
@@ -1855,7 +1879,7 @@ to make them stand out more in the list.
-
+
Enables a fix for storage of squad equipment in barracks.
Specifically, it prevents your haulers from moving that equipment
to stockpiles, and instead queues jobs to store it on weapon racks,
@@ -1908,9 +1932,9 @@ these rules is intended by Toady; the rest are invented by this plugin.
-
+
-
+
This command allows you to mark the map as 'monster lair', preventing item
scatter on abandon. When invoked as 'lair reset', it does the opposite.
Unlike reveal, this command doesn't save the information about tiles - you
@@ -1930,7 +1954,7 @@ won't be able to restore state of real monster lairs using 'lair reset'.
-
+
This command lets you see and change the game mode directly.
Not all combinations are good for every situation and most of them will
produce undesirable results. There are a few good ones though.
@@ -1950,9 +1974,9 @@ You just created a returnable mountain home and gained an adventurer.
-
+
-
+
Export the current loaded map as a file. This will be eventually usable
with visualizers.
-
+
Export dwarves to RuneSmith-compatible XML.
-
+
-
+
Command for general job query and manipulation.
- Options:
@@ -1996,7 +2020,7 @@ in a workshop, or the unit/jobs screen.
-
+
Alter the material of the selected job.
Invoked as:
@@ -2014,7 +2038,7 @@ over the first available choice with the matching material.
-
+
- Duplicate the selected job in a workshop:
@@ -2025,7 +2049,7 @@ instantly duplicates the job.
-
+
Manage control of repeat jobs.
Usage:
@@ -2042,14 +2066,22 @@ Otherwise, enables or disables any of the following options:
- List workflow-controlled jobs (if in a workshop, filtered by it).
- workflow list
- List active constraints, and their job counts.
-- workflow count <constraint-spec> <cnt-limit> [cnt-gap], workflow amount <constraint-spec> <cnt-limit> [cnt-gap]
-- Set a constraint. The first form counts each stack as only 1 item.
+- workflow list-commands
+- List active constraints as workflow commands that re-create them;
+this list can be copied to a file, and then reloaded using the
+script built-in command.
+- workflow count <constraint-spec> <cnt-limit> [cnt-gap]
+- Set a constraint, counting every stack as 1 item.
+- workflow amount <constraint-spec> <cnt-limit> [cnt-gap]
+- Set a constraint, counting all items within stacks.
- workflow unlimit <constraint-spec>
- Delete a constraint.
+- workflow unlimit-all
+- Delete all constraints.
-
+
When the plugin is enabled, it protects all repeat jobs from removal.
If they do disappear due to any cause, they are immediately re-added to their
workshop and suspended.
@@ -2061,8 +2093,37 @@ the frequency of jobs being toggled.
Check out the gui/workflow script below for a simple front-end integrated
in the game UI.
+
-
+
Keep metal bolts within 900-1000, and wood/bone within 150-200.
workflow amount AMMO:ITEM_AMMO_BOLTS/METAL 1000 100
@@ -2084,6 +2145,10 @@ workflow count BOX/CLOTH,SILK,YARN 30
workflow count BAR//COAL 20
workflow count BAR//COPPER 30
+
Produce 15-20 gold crafts.
+
+workflow count CRAFTS//GOLD 20
+
Collect 15-20 sand bags and clay boulders.
workflow count POWDER_MISC/SAND 20
@@ -2091,25 +2156,31 @@ workflow count BOULDER/CLAY 20
Make sure there are always 80-100 units of dimple dye.
- workflow amount POWDER_MISC//MUSHROOM_CUP_DIMPLE:MILL 100 20
-
-In order for this to work, you have to set the material of the PLANT input
+workflow amount POWDER_MISC//MUSHROOM_CUP_DIMPLE:MILL 100 20
+
+
+
Note
+
In order for this to work, you have to set the material of the PLANT input
on the Mill Plants job to MUSHROOM_CUP_DIMPLE using the 'job item-material'
-command.
+command. Otherwise the plugin won't be able to deduce the output material.
+
+
Maintain 10-100 locally-made crafts of exceptional quality.
+
+workflow count CRAFTS///LOCAL,EXCEPTIONAL 100 90
-
+
-
+
Tool for turning cooking of seeds and plants on/off depending on how much you
have of them.
See 'seedwatch help' for detailed description.
-
+
Helps a bit with managing activity zones (pens, pastures and pits) and cages.
Options:
@@ -2208,7 +2279,7 @@ for war/hunt). Negatable.
-
+
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
@@ -2217,7 +2288,7 @@ and use 'zone assign' to assign them to their new home. Allows pitting your
own dwarves, by the way.
-
+
All filters can be used together with the 'assign' command.
Restrictions: It's not possible to assign units who are inside built cages
or chained because in most cases that won't be desirable anyways.
@@ -2235,14 +2306,14 @@ are not properly added to your own stocks; slaughtering them should work).
Most filters can be negated (e.g. 'not grazer' -> race is not a grazer).
-
+
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
further optional filters) it will rename units matching the filter conditions.
-
+
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
@@ -2253,7 +2324,7 @@ would make no sense, but can be used together with 'nick' or 'remnick' and all
the usual filters.
-
+
- zone assign all own ALPACA minage 3 maxage 10
- Assign all own alpacas who are between 3 and 10 years old to the selected
@@ -2279,7 +2350,7 @@ on the current default zone.
-
+
Assigns unpastured female egg-layers to nestbox zones. Requires that you create
pen/pasture zones above nestboxes. If the pen is bigger than 1x1 the nestbox
must be in the top left corner. Only 1 unit will be assigned per pen, regardless
@@ -2308,7 +2379,7 @@ frames between runs.
-
+
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
@@ -2416,7 +2487,7 @@ autobutcher.bat
-
+
Automatically manage dwarf labors.
When enabled, autolabor periodically checks your dwarves and enables or
disables labors. It tries to keep as many dwarves as possible busy but
@@ -2430,14 +2501,14 @@ while it is enabled.
-
+
-
+
Makes cats just multiply. It is not a good idea to run this more than once or
twice.
-
+
When enabled, every new negative dwarven thought will be multiplied by a factor (2 by default).
Usage:
@@ -2483,7 +2554,7 @@ twice.
-
+
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.
@@ -2492,7 +2563,7 @@ 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:
-
+
Scripts in this subdirectory fix various bugs and issues, some of them obscure.
fix/dead-units
@@ -2518,22 +2589,22 @@ caused by autodump bugs or other hacking mishaps.
-
+
Scripts that implement dialogs inserted into the main game window are put in this
directory.
-
+
If called in dwarf mode, makes DF immediately auto-save the game by setting a flag
normally used in seasonal auto-save.
-
+
Run setfps <number> to set the FPS cap at runtime, in case you want to watch
combat in slow motion or something :)
-
+
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 +2612,7 @@ breaks will go on break again a lot sooner. The script is intended for
emergencies, e.g. when a siege appears, and all your military is partying.
-
+
Instantly grow seeds inside farming plots.
With no argument, this command list the various seed types currently in
use in your farming plots.
@@ -2553,7 +2624,7 @@ growcrops plump 40
-
+
This script remove negative thoughts from your dwarves. Very useful against
tantrum spirals.
The script can target a single creature, when used with the him argument,
@@ -2567,7 +2638,7 @@ but in the short term your dwarves will get much more joyful.
quickly after you unpause.
-
+
Kills any unit of a given race.
With no argument, lists the available races.
With the special argument him, targets only the selected creature.
@@ -2593,7 +2664,7 @@ slayrace elve magma
-
+
Create an infinite magma source on a tile.
This script registers a map tile as a magma source, and every 12 game ticks
that tile receives 1 new unit of flowing magma.
@@ -2608,7 +2679,7 @@ To remove all placed sources, call
magmasource stop
With no argument, this command shows an help message and list existing sources.
-
+
A script to designate an area for digging according to a plan in csv format.
This script, inspired from quickfort, can designate an area for digging.
Your plan should be stored in a .csv file like this:
@@ -2626,7 +2697,7 @@ To skip a row in your design, use a single
;.<
The script takes the plan filename, starting from the root df folder.
-
+
Similar to fastdwarf, per-creature.
To make any creature superfast, target it ingame using 'v' and:
@@ -2636,17 +2707,17 @@ superdwarf add
This plugin also shortens the 'sleeping' and 'on break' periods of targets.
-
+
Remove all 'aquifer' tag from the map blocks. Irreversible.
-
+
Focus a body part ingame, and this script will display the cause of death of
the creature.
-
+
These tools work by displaying dialogs or overlays in the game window, and
are mostly implemented by lua scripts.
@@ -2657,7 +2728,7 @@ display the word "DFHack" on the screen somewhere while active.
guideline because it arguably just fixes small usability bugs in the game UI.
-
+
Implemented by the manipulator plugin. To activate, open the unit screen and
press 'l'.
This tool implements a Dwarf Therapist-like interface within the game UI. The
@@ -2693,7 +2764,7 @@ cursor onto that cell instead of toggling it.
directly to the main dwarf mode screen.
-
+
The search plugin adds search to the Stocks, Trading and Unit List screens.
Searching works the same way as the search option in "Move to Depot" does.
You will see the Search option displayed on screen with a hotkey (usually 's').
@@ -2712,13 +2783,13 @@ Value numbers displayed by the screen. Because of this, pressing the 't'
key while search is active clears the search instead of executing the trade.
-
+
To use, bind to a key and activate in the 'k' mode.
While active, use the suggested keys to switch the usual liquids parameters, and Enter
to select the target area and apply changes.
-
+
To use, bind to a key and activate in the 'q' mode.
Lists mechanisms connected to the building, and their links. Navigating the list centers
the view on the relevant linked buildings.
@@ -2727,7 +2798,7 @@ focus on the current one. Shift-Enter has an effect equivalent to pressing Enter
re-entering the mechanisms ui.
-
+
Backed by the rename plugin, this script allows entering the desired name
via a simple dialog in the game ui.
-
+
To use, bind to a key and activate in the 'q' mode, 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.
-
+
Bind to a key, and activate in the Equip->View/Customize page of the military screen.
Depending on the cursor location, it rewrites all 'individual choice weapon' entries
in the selected squad or position to use a specific weapon type matching the assigned
@@ -2760,13 +2831,13 @@ only that entry, and does it even if it is not 'individual choice'.
and may lead to inappropriate weapons being selected.
-
+
Bind to a key, and activate in the Hauling menu with the cursor over a Guide order.
The script displays the cached path that will be used by the order; the game
computes it when the order is executed for the first time.
-
+
Bind to a key, and activate with a job selected in a workshop in the 'q' mode.
The script shows a list of the input reagents of the selected job, and allows changing
them like the job item-type and job item-material commands.
@@ -2794,7 +2865,7 @@ and then try to change the input item type, now it won't let you select
plan
you have to unset the material first.
-
+
Bind to a key, and activate with a job selected in a workshop in the 'q' mode.
This script provides a simple interface to constraints managed by the workflow
plugin. When active, it displays a list of all constraints applicable to the
@@ -2816,7 +2887,7 @@ as described in workflow documentation above.
can be used for troubleshooting jobs that don't match the right constraints.
-
+
Bind to a key, and activate when viewing a weapon rack in the 'q' mode.
This script is part of a group of related fixes to make the armory storage
work again. The existing issues are:
@@ -2836,7 +2907,7 @@ the intended user.
-
+
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.
@@ -2847,20 +2918,20 @@ technical challenge, and do not represent any long-term plans to produce more
similar modifications of the game.
-
+
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
just stones.
-
+
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,
e.g. like making siegers bring their own, are something only Toady can do.
-
+
The configuration front-end to the plugin is implemented by the gui/siege-engine
script. Bind it to a key and activate after selecting a siege engine in 'q' mode.
The main mode displays the current target, selected ammo item type, linked stockpiles and
@@ -2881,7 +2952,7 @@ menu.
-
+
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.
The configuration front-end is implemented by the gui/power-meter script. Bind it to a
@@ -2890,11 +2961,11 @@ key and activate after selecting Pressure Plate in the build menu.
configuration page, but configures parameters relevant to the modded power meter building.
-
+
The steam-engine plugin detects custom workshops with STEAM_ENGINE in
their token, and turns them into real steam engines.
-
+
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
@@ -2905,7 +2976,7 @@ it can be done just by combining existing features of the game engine
in a new way with some glue code and a bit of custom logic.
-
+
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.
@@ -2929,7 +3000,7 @@ short axles that can be built later than both of the engines.
-
+
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
@@ -2960,7 +3031,7 @@ decrease it by further 4%, and also decrease the whole steam
use rate by 10%.
-
+
The engine must be constructed using barrel, pipe and piston
from fire-safe, or in the magma version magma-safe metals.
During operation weak parts get gradually worn out, and
@@ -2969,7 +3040,7 @@ toppled during operation by a building destroyer, or a
tantruming dwarf.
-
+
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
@@ -2980,7 +3051,7 @@ being generated.
-
+
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
diff --git a/Readme.rst b/Readme.rst
index d9021c7cb..7fbc42528 100644
--- a/Readme.rst
+++ b/Readme.rst
@@ -58,9 +58,35 @@ The stonesense plugin might require some additional libraries on Linux.
If any of the plugins or dfhack itself refuses to load, check the stderr.log
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
+the console.
+
+**NOTE**: The dfhack-run executable is there for calling DFHack commands in
+an already running DF+DFHack instance from external OS scripts and programs,
+and is *not* the way how you use DFHack normally.
+
+DFHack has a lot of features, which can be accessed by typing commands in the
+console, or by mapping them to keyboard shortcuts. Most of the newer and more
+user-friendly tools are designed to be at least partially used via the latter
+way.
+
+In order to set keybindings, you have to create a text configuration file
+called ``dfhack.init``; the installation comes with an example version called
+``dfhack.init-example``, which is fully functional, covers all of the recent
+features and can be simply renamed to ``dfhack.init``. You are encouraged to look
+through it to learn which features it makes available under which key combinations.
+
+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
@@ -1258,10 +1284,18 @@ Usage:
List workflow-controlled jobs (if in a workshop, filtered by it).
``workflow list``
List active constraints, and their job counts.
- ``workflow count [cnt-gap], workflow amount [cnt-gap]``
- Set a constraint. The first form counts each stack as only 1 item.
+ ``workflow list-commands``
+ List active constraints as workflow commands that re-create them;
+ this list can be copied to a file, and then reloaded using the
+ ``script`` built-in command.
+ ``workflow count [cnt-gap]``
+ Set a constraint, counting every stack as 1 item.
+ ``workflow amount [cnt-gap]``
+ Set a constraint, counting all items within stacks.
``workflow unlimit ``
Delete a constraint.
+ ``workflow unlimit-all``
+ Delete all constraints.
Function
........
@@ -1279,6 +1313,34 @@ the frequency of jobs being toggled.
Check out the ``gui/workflow`` script below for a simple front-end integrated
in the game UI.
+Constraint format
+.................
+
+The contstraint 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
+
+The subsequent parts are optional:
+
+- A generic material spec constrains the item material to one of
+ the hard-coded generic classes, which currently include::
+
+ PLANT WOOD CLOTH SILK LEATHER BONE SHELL SOAP TOOTH HORN PEARL YARN
+ METAL STONE SAND GLASS CLAY MILK
+
+- 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:
+
+ 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.
Constraint examples
...................
@@ -1304,10 +1366,15 @@ Make sure there are always 25-30 empty bins/barrels/bags.
Make sure there are always 15-20 coal and 25-30 copper bars.
::
-
+
workflow count BAR//COAL 20
workflow count BAR//COPPER 30
+Produce 15-20 gold crafts.
+::
+
+ workflow count CRAFTS//GOLD 20
+
Collect 15-20 sand bags and clay boulders.
::
@@ -1319,9 +1386,16 @@ Make sure there are always 80-100 units of dimple dye.
workflow amount POWDER_MISC//MUSHROOM_CUP_DIMPLE:MILL 100 20
+.. note::
+
In order for this to work, you have to set the material of the PLANT input
on the Mill Plants job to MUSHROOM_CUP_DIMPLE using the 'job item-material'
- command.
+ command. Otherwise the plugin won't be able to deduce the output material.
+
+Maintain 10-100 locally-made crafts of exceptional quality.
+::
+
+ workflow count CRAFTS///LOCAL,EXCEPTIONAL 100 90
Fortress activity management
diff --git a/dfhack.init-example b/dfhack.init-example
index 20048e39e..729747714 100644
--- a/dfhack.init-example
+++ b/dfhack.init-example
@@ -2,21 +2,32 @@
# Generic dwarfmode bindings #
##############################
+# toggle the display of water level as 1-7 tiles
keybinding add Ctrl-W twaterlvl
# with cursor:
+
+# designate the whole vein for digging
keybinding add Ctrl-V digv
keybinding add Ctrl-Shift-V "digv x"
+
+# clean the selected tile of blood etc
keybinding add Ctrl-C spotclean
+
+# destroy items designated for dump in the selected tile
keybinding add Ctrl-Shift-K autodump-destroy-here
-# any item:
+# with an item selected:
+
+# destroy the selected item
keybinding add Ctrl-K autodump-destroy-item
+# scripts:
+
# quicksave, only in main dwarfmode screen and menu page
keybinding add Ctrl-Alt-S@dwarfmode/Default quicksave
-# gui/rename script
+# gui/rename script - rename units and buildings
keybinding add Ctrl-Shift-N gui/rename
keybinding add Ctrl-Shift-T "gui/rename unit-profession"
@@ -31,10 +42,10 @@ keybinding add Ctrl-Shift-B "adv-bodyswap force"
# Context-specific bindings #
#############################
-# q->stockpile; p
+# q->stockpile; p - copy & paste stockpiles
keybinding add Alt-P copystock
-# q->workshop
+# q->workshop - duplicate the selected job
keybinding add Ctrl-D job-duplicate
# materials: q->workshop; b->select items
@@ -48,7 +59,7 @@ keybinding add Shift-O "job-material OBSIDIAN"
keybinding add Shift-T "job-material ORTHOCLASE"
keybinding add Shift-G "job-material GLASS_GREEN"
-# sort units and items
+# sort units and items in the on-screen list
keybinding add Alt-Shift-N "sort-units name" "sort-items description"
keybinding add Alt-Shift-R "sort-units arrival"
keybinding add Alt-Shift-T "sort-units profession" "sort-items type material"
@@ -60,7 +71,7 @@ keybinding add Ctrl-M@dwarfmode/QueryBuilding/Some gui/mechanisms
# browse rooms of same owner
keybinding add Alt-R@dwarfmode/QueryBuilding/Some gui/room-list
-# interface for the liquids plugin
+# interface for the liquids plugin - spawn water/magma/obsidian
keybinding add Alt-L@dwarfmode/LookAround gui/liquids
# machine power sensitive pressure plate construction
diff --git a/plugins/lua/workflow.lua b/plugins/lua/workflow.lua
index c3dbe20d9..e3fb7b32e 100644
--- a/plugins/lua/workflow.lua
+++ b/plugins/lua/workflow.lua
@@ -266,9 +266,16 @@ function constraintToToken(cspec)
error('invalid material: '..cspec.mat_type..':'..(cspec.mat_index or -1))
end
end
- local qpart
+ local qlist = {}
+ if cspec.is_local then
+ table.insert(qlist, "LOCAL")
+ end
if cspec.quality and cspec.quality > 0 then
- qpart = df.item_quality[cspec.quality] or error('invalid quality: '..cspec.quality)
+ table.insert(qlist, df.item_quality[cspec.quality] or error('invalid quality: '..cspec.quality))
+ end
+ local qpart
+ if #qlist > 0 then
+ qpart = table.concat(qlist, ',')
end
if mask_part or mat_part or qpart then
diff --git a/plugins/workflow.cpp b/plugins/workflow.cpp
index c89d87333..04e3c13b0 100644
--- a/plugins/workflow.cpp
+++ b/plugins/workflow.cpp
@@ -100,6 +100,19 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector ]\n"
+ " The first part is mandatory and specifies the item type and subtype,\n"
+ " using the raw tokens for items, in the same syntax you would e.g. use\n"
+ " for a custom reaction input. The subsequent parts are optional:\n"
+ " - A generic material spec constrains the item material to one of\n"
+ " the hard-coded generic classes, like WOOD, METAL, YARN or MILK.\n"
+ " - A specific material spec chooses the material exactly, using the\n"
+ " raw syntax for reaction input materials, e.g. INORGANIC:IRON,\n"
+ " although for convenience it also allows just IRON, or ACACIA:WOOD.\n"
+ " - A comma-separated list of miscellaneous flags, which currently can\n"
+ " be used to ignore imported items or items below a certain quality.\n"
"Constraint examples:\n"
" workflow amount AMMO:ITEM_AMMO_BOLTS/METAL 1000 100\n"
" workflow amount AMMO:ITEM_AMMO_BOLTS/WOOD,BONE 200 50\n"
@@ -124,6 +137,8 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector , bool> TMaterialCache;
struct ItemConstraint {
PersistentDataItem config;
+ // Fixed key parsed into fields
bool is_craft;
ItemTypeInfo item;
MaterialInfo material;
df::dfhack_material_category mat_mask;
+ item_quality::item_quality min_quality;
+ bool is_local;
+
+ // Tracking data
int weight;
std::vector jobs;
- item_quality::item_quality min_quality;
-
int item_amount, item_count, item_inuse;
bool request_suspend, request_resume;
@@ -299,8 +317,9 @@ struct ItemConstraint {
public:
ItemConstraint()
- : is_craft(false), weight(0), min_quality(item_quality::Ordinary),item_amount(0),
- item_count(0), item_inuse(0), is_active(false), cant_resume_reported(false)
+ : is_craft(false), min_quality(item_quality::Ordinary), is_local(false),
+ weight(0), item_amount(0), item_count(0), item_inuse(0),
+ is_active(false), cant_resume_reported(false)
{}
int goalCount() { return config.ival(0); }
@@ -673,7 +692,7 @@ static ItemConstraint *get_constraint(color_ostream &out, const std::string &str
if (mat_mask.whole != 0)
weight += 100;
-
+
MaterialInfo material;
std::string matstr = vector_get(tokens,2);
if (!matstr.empty() && (!material.find(matstr) || !material.isValid())) {
@@ -681,21 +700,6 @@ static ItemConstraint *get_constraint(color_ostream &out, const std::string &str
return NULL;
}
- item_quality::item_quality minqual = item_quality::Ordinary;
- std::string qualstr = vector_get(tokens, 3);
- if(!qualstr.empty()) {
- if(qualstr == "ordinary") minqual = item_quality::Ordinary;
- else if(qualstr == "wellcrafted") minqual = item_quality::WellCrafted;
- else if(qualstr == "finelycrafted") minqual = item_quality::FinelyCrafted;
- else if(qualstr == "superior") minqual = item_quality::Superior;
- else if(qualstr == "exceptional") minqual = item_quality::Exceptional;
- else if(qualstr == "masterful") minqual = item_quality::Masterful;
- else {
- out.printerr("Cannot find quality: %s\nKnown qualities: ordinary, wellcrafted, finelycrafted, superior, exceptional, masterful\n", qualstr.c_str());
- return NULL;
- }
- }
-
if (material.type >= 0)
weight += (material.index >= 0 ? 5000 : 1000);
@@ -704,13 +708,52 @@ static ItemConstraint *get_constraint(color_ostream &out, const std::string &str
return NULL;
}
+ item_quality::item_quality minqual = item_quality::Ordinary;
+ bool is_local = false;
+ std::string qualstr = vector_get(tokens, 3);
+
+ if(!qualstr.empty())
+ {
+ std::vector qtokens;
+ split_string(&qtokens, qualstr, ",");
+
+ for (size_t i = 0; i < qtokens.size(); i++)
+ {
+ auto token = toLower(qtokens[i]);
+
+ if (token == "local")
+ is_local = true;
+ else
+ {
+ bool found = false;
+ FOR_ENUM_ITEMS(item_quality, qv)
+ {
+ if (toLower(ENUM_KEY_STR(item_quality, qv)) != token)
+ continue;
+ minqual = qv;
+ found = true;
+ }
+
+ if (!found)
+ {
+ out.printerr("Cannot parse token: %s\n", token.c_str());
+ return NULL;
+ }
+ }
+ }
+ }
+
+ if (is_local || minqual > item_quality::Ordinary)
+ weight += 10;
+
for (size_t i = 0; i < constraints.size(); i++)
{
ItemConstraint *ct = constraints[i];
if (ct->is_craft == is_craft &&
ct->item == item && ct->material == material &&
ct->mat_mask.whole == mat_mask.whole &&
- ct->min_quality == minqual)
+ ct->min_quality == minqual &&
+ ct->is_local == is_local)
return ct;
}
@@ -720,6 +763,7 @@ static ItemConstraint *get_constraint(color_ostream &out, const std::string &str
nct->material = material;
nct->mat_mask = mat_mask;
nct->min_quality = minqual;
+ nct->is_local = is_local;
nct->weight = weight;
if (cfg)
@@ -1099,9 +1143,11 @@ static void map_job_items(color_ostream &out)
(cv->item.subtype != -1 && cv->item.subtype != isubtype))
continue;
}
- if(item->getQuality() < cv->min_quality) {
- continue;
- }
+
+ if (cv->is_local && item->flags.bits.foreign)
+ continue;
+ if (item->getQuality() < cv->min_quality)
+ continue;
TMaterialCache::iterator it = cv->material_cache.find(matkey);
@@ -1307,6 +1353,7 @@ static void push_constraint(lua_State *L, ItemConstraint *cv)
Lua::SetField(L, cv->material.index, ctable, "mat_index");
Lua::SetField(L, (int)cv->min_quality, ctable, "min_quality");
+ Lua::SetField(L, (bool)cv->is_local, ctable, "is_local");
// Constraint value
diff --git a/scripts/gui/workflow.lua b/scripts/gui/workflow.lua
index 366e3ec91..84540b5ca 100644
--- a/scripts/gui/workflow.lua
+++ b/scripts/gui/workflow.lua
@@ -191,8 +191,15 @@ function JobConstraints:initListChoices(clist, sel_token)
order_pen = COLOR_BLUE
end
local itemstr = describe_item_type(cons)
- if cons.min_quality > 0 then
- itemstr = itemstr .. ' ('..df.item_quality[cons.min_quality]..')'
+ if cons.min_quality > 0 or cons.is_local then
+ local lst = {}
+ if cons.is_local then
+ table.insert(lst, 'local')
+ end
+ if cons.min_quality > 0 then
+ table.insert(lst, string.lower(df.item_quality[cons.min_quality]))
+ end
+ itemstr = itemstr .. ' ('..table.concat(lst,',')..')'
end
local matstr = describe_material(cons)
local matflagstr = ''
From f657c20a1da4b5d6ce0ae95d60c5f2921c68ebf9 Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Sun, 11 Nov 2012 15:49:01 +0400
Subject: [PATCH 044/158] Add an internal API for converting between file and
memory offsets.
---
Lua API.html | 8 +++++++
Lua API.rst | 10 +++++++++
library/LuaApi.cpp | 15 +++++++++++++
library/Process-darwin.cpp | 9 ++++++--
library/Process-linux.cpp | 9 ++++++--
library/Process-windows.cpp | 39 +++++++++++++++++++++++++++++++---
library/VersionInfoFactory.cpp | 4 ++--
library/include/MemAccess.h | 4 +++-
8 files changed, 88 insertions(+), 10 deletions(-)
diff --git a/Lua API.html b/Lua API.html
index 226afa98a..d2e0da1ef 100644
--- a/Lua API.html
+++ b/Lua API.html
@@ -1763,9 +1763,17 @@ global environment, persistent between calls to the script.
dfhack.internal.getVTable(name)
Returns the pre-extracted vtable address name, or nil.
+
dfhack.internal.getImageBase()
+Returns the mmap base of the executable.
+
dfhack.internal.getRebaseDelta()
Returns the ASLR rebase offset of the DF executable.
+
dfhack.internal.adjustOffset(offset[,to_file])
+Returns the re-aligned offset, or nil if invalid.
+If to_file is true, the offset is adjusted from memory to file.
+This function returns the original value everywhere except windows.
+
dfhack.internal.getMemRanges()
Returns a sequence of tables describing virtual memory ranges of the process.
diff --git a/Lua API.rst b/Lua API.rst
index d06e3d2e6..f89750e88 100644
--- a/Lua API.rst
+++ b/Lua API.rst
@@ -1618,10 +1618,20 @@ and are only documented here for completeness:
Returns the pre-extracted vtable address ``name``, or *nil*.
+* ``dfhack.internal.getImageBase()``
+
+ Returns the mmap base of the executable.
+
* ``dfhack.internal.getRebaseDelta()``
Returns the ASLR rebase offset of the DF executable.
+* ``dfhack.internal.adjustOffset(offset[,to_file])``
+
+ Returns the re-aligned offset, or *nil* if invalid.
+ If ``to_file`` is true, the offset is adjusted from memory to file.
+ This function returns the original value everywhere except windows.
+
* ``dfhack.internal.getMemRanges()``
Returns a sequence of tables describing virtual memory ranges of the process.
diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp
index 0151ed404..3862530dd 100644
--- a/library/LuaApi.cpp
+++ b/library/LuaApi.cpp
@@ -1718,9 +1718,11 @@ static void *checkaddr(lua_State *L, int idx, bool allow_null = false)
return rv;
}
+static uint32_t getImageBase() { return Core::getInstance().p->getBase(); }
static int getRebaseDelta() { return Core::getInstance().vinfo->getRebaseDelta(); }
static const LuaWrapper::FunctionReg dfhack_internal_module[] = {
+ WRAP(getImageBase),
WRAP(getRebaseDelta),
{ NULL, NULL }
};
@@ -1774,6 +1776,18 @@ static int internal_getVTable(lua_State *L)
return 1;
}
+static int internal_adjustOffset(lua_State *L)
+{
+ lua_settop(L, 2);
+ int off = luaL_checkint(L, 1);
+ int rv = Core::getInstance().p->adjustOffset(off, lua_toboolean(L, 2));
+ if (rv >= 0)
+ lua_pushinteger(L, rv);
+ else
+ lua_pushnil(L);
+ return 1;
+}
+
static int internal_getMemRanges(lua_State *L)
{
std::vector
ranges;
@@ -1981,6 +1995,7 @@ static const luaL_Reg dfhack_internal_funcs[] = {
{ "getAddress", internal_getAddress },
{ "setAddress", internal_setAddress },
{ "getVTable", internal_getVTable },
+ { "adjustOffset", internal_adjustOffset },
{ "getMemRanges", internal_getMemRanges },
{ "patchMemory", internal_patchMemory },
{ "patchBytes", internal_patchBytes },
diff --git a/library/Process-darwin.cpp b/library/Process-darwin.cpp
index c5e4e4b85..d081c8c5c 100644
--- a/library/Process-darwin.cpp
+++ b/library/Process-darwin.cpp
@@ -220,9 +220,14 @@ void Process::getMemRanges( vector & ranges )
}*/
}
-uint32_t Process::getBase()
+uintptr_t Process::getBase()
{
- return 0;
+ return 0x1000000;
+}
+
+int Process::adjustOffset(int offset, bool /*to_file*/)
+{
+ return offset;
}
static int getdir (string dir, vector &files)
diff --git a/library/Process-linux.cpp b/library/Process-linux.cpp
index f88279b3f..046b7696d 100644
--- a/library/Process-linux.cpp
+++ b/library/Process-linux.cpp
@@ -155,9 +155,14 @@ void Process::getMemRanges( vector & ranges )
fclose(mapFile);
}
-uint32_t Process::getBase()
+uintptr_t Process::getBase()
{
- return 0;
+ return 0x8048000;
+}
+
+int Process::adjustOffset(int offset, bool /*to_file*/)
+{
+ return offset;
}
static int getdir (string dir, vector &files)
diff --git a/library/Process-windows.cpp b/library/Process-windows.cpp
index 966468fb5..6f79236f9 100644
--- a/library/Process-windows.cpp
+++ b/library/Process-windows.cpp
@@ -160,7 +160,7 @@ Process::Process(VersionInfoFactory * factory)
identified = true;
// give the process a data model and memory layout fixed for the base of first module
my_descriptor = new VersionInfo(*vinfo);
- my_descriptor->rebaseTo((uint32_t)d->base);
+ my_descriptor->rebaseTo(getBase());
for(size_t i = 0; i < threads_ids.size();i++)
{
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, (DWORD) threads_ids[i]);
@@ -394,13 +394,46 @@ void Process::getMemRanges( vector & ranges )
}
}
-uint32_t Process::getBase()
+uintptr_t Process::getBase()
{
if(d)
- return (uint32_t) d->base;
+ return (uintptr_t) d->base;
return 0x400000;
}
+int Process::adjustOffset(int offset, bool to_file)
+{
+ if (!d)
+ return -1;
+
+ for(int i = 0; i < d->pe_header.FileHeader.NumberOfSections; i++)
+ {
+ auto §ion = d->sections[i];
+
+ if (to_file)
+ {
+ unsigned delta = offset - section.VirtualAddress;
+ if (delta >= section.Misc.VirtualSize)
+ continue;
+ if (!section.PointerToRawData || delta >= section.SizeOfRawData)
+ return -1;
+ return (int)(section.PointerToRawData + delta);
+ }
+ else
+ {
+ unsigned delta = offset - section.PointerToRawData;
+ if (!section.PointerToRawData || delta >= section.SizeOfRawData)
+ continue;
+ if (delta >= section.Misc.VirtualSize)
+ return -1;
+ return (int)(section.VirtualAddress + delta);
+ }
+ }
+
+ return -1;
+}
+
+
string Process::doReadClassName (void * vptr)
{
char * rtti = readPtr((char *)vptr - 0x4);
diff --git a/library/VersionInfoFactory.cpp b/library/VersionInfoFactory.cpp
index e8c0561cd..7142233d8 100644
--- a/library/VersionInfoFactory.cpp
+++ b/library/VersionInfoFactory.cpp
@@ -103,13 +103,13 @@ void VersionInfoFactory::ParseVersion (TiXmlElement* entry, VersionInfo* mem)
{
mem->setOS(OS_LINUX);
// this is wrong... I'm not going to do base image relocation on linux though.
- mem->setBase(0x0);
+ mem->setBase(0x8048000);
}
else if(os == "darwin")
{
mem->setOS(OS_APPLE);
// this is wrong... I'm not going to do base image relocation on linux though.
- mem->setBase(0x0);
+ mem->setBase(0x1000000);
}
else
{
diff --git a/library/include/MemAccess.h b/library/include/MemAccess.h
index 1b8e687b9..22f15eecf 100644
--- a/library/include/MemAccess.h
+++ b/library/include/MemAccess.h
@@ -275,11 +275,13 @@ namespace DFHack
{
return my_descriptor;
};
- uint32_t getBase();
+ uintptr_t getBase();
/// get the DF Process ID
int getPID();
/// get the DF Process FilePath
std::string getPath();
+ /// Adjust between in-memory and in-file image offset
+ int adjustOffset(int offset, bool to_file = false);
/// millisecond tick count, exactly as DF uses
uint32_t getTickCount();
From 012d22fa4f8c6562ed9fc9e11b6059942fa5e8c8 Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Sun, 11 Nov 2012 17:24:13 +0400
Subject: [PATCH 045/158] Add a script for manipulating binary patches at
runtime, and some patches.
---
NEWS | 1 +
Readme.html | 151 ++++++++++--------
Readme.rst | 11 ++
dfhack.init-example | 23 +++
library/CMakeLists.txt | 4 +
patches/v0.34.11 SDL/armorstand-capacity.dif | 142 ++++++++++++++++
patches/v0.34.11 SDL/custom-reagent-size.dif | 91 +++++++++++
patches/v0.34.11 SDL/deconstruct-heapfall.dif | 61 +++++++
patches/v0.34.11 SDL/deconstruct-teleport.dif | 104 ++++++++++++
.../v0.34.11 SDL/hospital-overstocking.dif | 62 +++++++
patches/v0.34.11 SDL/training-ammo.dif | 83 ++++++++++
patches/v0.34.11 SDL/weaponrack-unassign.dif | 61 +++++++
.../v0.34.11 linux/armorstand-capacity.dif | 147 +++++++++++++++++
.../v0.34.11 linux/custom-reagent-size.dif | 40 +++++
.../v0.34.11 linux/deconstruct-heapfall.dif | 83 ++++++++++
.../v0.34.11 linux/deconstruct-teleport.dif | 139 ++++++++++++++++
.../v0.34.11 linux/hospital-overstocking.dif | 60 +++++++
patches/v0.34.11 linux/training-ammo.dif | 85 ++++++++++
.../v0.34.11 linux/weaponrack-unassign.dif | 45 ++++++
scripts/binpatch.lua | 117 ++++++++++++++
20 files changed, 1440 insertions(+), 70 deletions(-)
create mode 100644 patches/v0.34.11 SDL/armorstand-capacity.dif
create mode 100644 patches/v0.34.11 SDL/custom-reagent-size.dif
create mode 100644 patches/v0.34.11 SDL/deconstruct-heapfall.dif
create mode 100644 patches/v0.34.11 SDL/deconstruct-teleport.dif
create mode 100644 patches/v0.34.11 SDL/hospital-overstocking.dif
create mode 100644 patches/v0.34.11 SDL/training-ammo.dif
create mode 100644 patches/v0.34.11 SDL/weaponrack-unassign.dif
create mode 100644 patches/v0.34.11 linux/armorstand-capacity.dif
create mode 100644 patches/v0.34.11 linux/custom-reagent-size.dif
create mode 100644 patches/v0.34.11 linux/deconstruct-heapfall.dif
create mode 100644 patches/v0.34.11 linux/deconstruct-teleport.dif
create mode 100644 patches/v0.34.11 linux/hospital-overstocking.dif
create mode 100644 patches/v0.34.11 linux/training-ammo.dif
create mode 100644 patches/v0.34.11 linux/weaponrack-unassign.dif
create mode 100644 scripts/binpatch.lua
diff --git a/NEWS b/NEWS
index 51321be95..494a6c680 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,7 @@ DFHack future
- added a small stand-alone utility for applying and removing binary patches.
- removebadthoughts: add --dry-run option
New scripts:
+ - binpatch: the same as the stand-alone binpatch.exe, but works at runtime.
- region-pops: displays animal populations of the region and allows tweaking them.
New GUI scripts:
- gui/guide-path: displays the cached path for minecart Guide orders.
diff --git a/Readme.html b/Readme.html
index 16f3aed5a..737963372 100644
--- a/Readme.html
+++ b/Readme.html
@@ -489,49 +489,50 @@ access DF memory and allow for easier development of new tools.
- Scripts
-- In-game interface tools
+
+
+
Checks, applies or removes binary patches directly in memory at runtime:
+
+binpatch check/apply/remove <patchname>
+
+
If the name of the patch has no extension or directory separators, the
+script uses hack/patches/<df-version>/<name>.dif, thus auto-selecting
+the version appropriate for the currently loaded executable.
+
-
+
If called in dwarf mode, makes DF immediately auto-save the game by setting a flag
normally used in seasonal auto-save.
-
+
Run setfps <number> to set the FPS cap at runtime, in case you want to watch
combat in slow motion or something :)
-
+
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
@@ -2612,7 +2623,7 @@ breaks will go on break again a lot sooner. The script is intended for
emergencies, e.g. when a siege appears, and all your military is partying.
-
+
Instantly grow seeds inside farming plots.
With no argument, this command list the various seed types currently in
use in your farming plots.
@@ -2624,7 +2635,7 @@ growcrops plump 40
-
+
This script remove negative thoughts from your dwarves. Very useful against
tantrum spirals.
The script can target a single creature, when used with the him argument,
@@ -2638,7 +2649,7 @@ but in the short term your dwarves will get much more joyful.
quickly after you unpause.
-
+
Kills any unit of a given race.
With no argument, lists the available races.
With the special argument him, targets only the selected creature.
@@ -2664,7 +2675,7 @@ slayrace elve magma
-
+
Create an infinite magma source on a tile.
This script registers a map tile as a magma source, and every 12 game ticks
that tile receives 1 new unit of flowing magma.
@@ -2679,7 +2690,7 @@ To remove all placed sources, call
magmasource stop
With no argument, this command shows an help message and list existing sources.
-
+
A script to designate an area for digging according to a plan in csv format.
This script, inspired from quickfort, can designate an area for digging.
Your plan should be stored in a .csv file like this:
@@ -2697,7 +2708,7 @@ To skip a row in your design, use a single
;.<
The script takes the plan filename, starting from the root df folder.
-
+
Similar to fastdwarf, per-creature.
To make any creature superfast, target it ingame using 'v' and:
@@ -2707,17 +2718,17 @@ superdwarf add
This plugin also shortens the 'sleeping' and 'on break' periods of targets.
-
+
Remove all 'aquifer' tag from the map blocks. Irreversible.
-
+
Focus a body part ingame, and this script will display the cause of death of
the creature.
-
+
These tools work by displaying dialogs or overlays in the game window, and
are mostly implemented by lua scripts.
@@ -2728,7 +2739,7 @@ display the word "DFHack" on the screen somewhere while active.
guideline because it arguably just fixes small usability bugs in the game UI.
-
+
Implemented by the manipulator plugin. To activate, open the unit screen and
press 'l'.
This tool implements a Dwarf Therapist-like interface within the game UI. The
@@ -2764,7 +2775,7 @@ cursor onto that cell instead of toggling it.
directly to the main dwarf mode screen.
-
+
The search plugin adds search to the Stocks, Trading and Unit List screens.
Searching works the same way as the search option in "Move to Depot" does.
You will see the Search option displayed on screen with a hotkey (usually 's').
@@ -2783,13 +2794,13 @@ Value numbers displayed by the screen. Because of this, pressing the 't'
key while search is active clears the search instead of executing the trade.
-
+
To use, bind to a key and activate in the 'k' mode.
While active, use the suggested keys to switch the usual liquids parameters, and Enter
to select the target area and apply changes.
-
+
To use, bind to a key and activate in the 'q' mode.
Lists mechanisms connected to the building, and their links. Navigating the list centers
the view on the relevant linked buildings.
@@ -2798,7 +2809,7 @@ focus on the current one. Shift-Enter has an effect equivalent to pressing Enter
re-entering the mechanisms ui.
-
+
Backed by the rename plugin, this script allows entering the desired name
via a simple dialog in the game ui.
-
+
To use, bind to a key and activate in the 'q' mode, 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.
-
+
Bind to a key, and activate in the Equip->View/Customize page of the military screen.
Depending on the cursor location, it rewrites all 'individual choice weapon' entries
in the selected squad or position to use a specific weapon type matching the assigned
@@ -2831,13 +2842,13 @@ only that entry, and does it even if it is not 'individual choice'.
and may lead to inappropriate weapons being selected.
-
+
Bind to a key, and activate in the Hauling menu with the cursor over a Guide order.
The script displays the cached path that will be used by the order; the game
computes it when the order is executed for the first time.
-
+
Bind to a key, and activate with a job selected in a workshop in the 'q' mode.
The script shows a list of the input reagents of the selected job, and allows changing
them like the job item-type and job item-material commands.
@@ -2865,7 +2876,7 @@ and then try to change the input item type, now it won't let you select
plan
you have to unset the material first.
-
+
Bind to a key, and activate with a job selected in a workshop in the 'q' mode.
This script provides a simple interface to constraints managed by the workflow
plugin. When active, it displays a list of all constraints applicable to the
@@ -2887,7 +2898,7 @@ as described in workflow documentation above.
can be used for troubleshooting jobs that don't match the right constraints.
-
+
Bind to a key, and activate when viewing a weapon rack in the 'q' mode.
This script is part of a group of related fixes to make the armory storage
work again. The existing issues are:
@@ -2907,7 +2918,7 @@ the intended user.
-
+
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.
@@ -2918,20 +2929,20 @@ technical challenge, and do not represent any long-term plans to produce more
similar modifications of the game.
-
+
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
just stones.
-
+
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,
e.g. like making siegers bring their own, are something only Toady can do.
-
+
The configuration front-end to the plugin is implemented by the gui/siege-engine
script. Bind it to a key and activate after selecting a siege engine in 'q' mode.
The main mode displays the current target, selected ammo item type, linked stockpiles and
@@ -2952,7 +2963,7 @@ menu.
-
+
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.
The configuration front-end is implemented by the gui/power-meter script. Bind it to a
@@ -2961,11 +2972,11 @@ key and activate after selecting Pressure Plate in the build menu.
configuration page, but configures parameters relevant to the modded power meter building.
-
+
The steam-engine plugin detects custom workshops with STEAM_ENGINE in
their token, and turns them into real steam engines.
-
+
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
@@ -2976,7 +2987,7 @@ it can be done just by combining existing features of the game engine
in a new way with some glue code and a bit of custom logic.
-
+
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.
@@ -3000,7 +3011,7 @@ short axles that can be built later than both of the engines.
-
+
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
@@ -3031,7 +3042,7 @@ decrease it by further 4%, and also decrease the whole steam
use rate by 10%.
-
+
The engine must be constructed using barrel, pipe and piston
from fire-safe, or in the magma version magma-safe metals.
During operation weak parts get gradually worn out, and
@@ -3040,7 +3051,7 @@ toppled during operation by a building destroyer, or a
tantruming dwarf.
-
+
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
@@ -3051,7 +3062,7 @@ being generated.
-
+
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
diff --git a/Readme.rst b/Readme.rst
index 7fbc42528..16665ab98 100644
--- a/Readme.rst
+++ b/Readme.rst
@@ -1761,6 +1761,17 @@ gui/*
Scripts that implement dialogs inserted into the main game window are put in this
directory.
+binpatch
+========
+
+Checks, applies or removes binary patches directly in memory at runtime::
+
+ binpatch check/apply/remove
+
+If the name of the patch has no extension or directory separators, the
+script uses ``hack/patches//.dif``, thus auto-selecting
+the version appropriate for the currently loaded executable.
+
quicksave
=========
diff --git a/dfhack.init-example b/dfhack.init-example
index 729747714..885849c33 100644
--- a/dfhack.init-example
+++ b/dfhack.init-example
@@ -132,3 +132,26 @@ tweak fast-trade
tweak military-stable-assign
# in same list, color units already assigned to squads in brown & green
tweak military-color-assigned
+
+#######################################################
+# Apply binary patches at runtime #
+# #
+# Commented out by default; enable the ones you want. #
+#######################################################
+
+# Bug 5994 - items teleported when removing a construction
+#binpatch apply deconstruct-teleport
+#binpatch apply deconstruct-heapfall
+
+# Bug 4406 - hospital overstocking on all items
+#binpatch apply hospital-overstocking
+
+# Bug 808 - custom reactions completely using up all of their reagents
+#binpatch apply custom-reagent-size
+
+# Bug 4530 - marksdwarves not training when quiver full of combat-only ammo
+#binpatch apply training-ammo
+
+# Bug 1445 - weapon racks broken, armor stand capacity too low
+#binpatch apply weaponrack-unassign
+#binpatch apply armorstand-capacity
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 6f33d5c8a..b141e9fa5 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -346,6 +346,10 @@ install(DIRECTORY ${dfhack_SOURCE_DIR}/scripts
PATTERN "*.rb"
)
+install(DIRECTORY ${dfhack_SOURCE_DIR}/patches
+ DESTINATION ${DFHACK_DATA_DESTINATION}
+ FILES_MATCHING PATTERN "*.dif")
+
# Unused for so long that it's not even relevant now...
if(BUILD_DEVEL)
if(WIN32)
diff --git a/patches/v0.34.11 SDL/armorstand-capacity.dif b/patches/v0.34.11 SDL/armorstand-capacity.dif
new file mode 100644
index 000000000..e7d69a8c2
--- /dev/null
+++ b/patches/v0.34.11 SDL/armorstand-capacity.dif
@@ -0,0 +1,142 @@
+http://www.bay12games.com/dwarves/mantisbt/view.php?id=1445
+
+0x2ac6b
+CC CC CC CC CC
+66 39 E8 EB 53
+
+.text:0042B86B loc_42B86B:
+.text:0042B86B cmp ax, bp
+.text:0042B86E jmp short loc_42B8C3
+
+0x2ac7b
+CC CC CC CC CC
+E9 96 A2 00 00
+
+.text:0042B87B loc_42B87B:
+.text:0042B87B jmp loc_435B16
+
+0x2acc3
+CC CC CC CC CC CC CC CC CC CC CC CC CC
+75 0A 66 FF 4C 24 16 79 03 58 EB AC C3
+
+.text:0042B8C3 loc_42B8C3:
+.text:0042B8C3 jnz short locret_42B8CF
+.text:0042B8C5 dec word ptr [esp+16h] ; 4+8+8+2
+.text:0042B8CA jns short locret_42B8CF
+.text:0042B8CC pop eax
+.text:0042B8CD jmp short loc_42B87B
+.text:0042B8CF locret_42B8CF:
+.text:0042B8CF retn
+
+0x2b2a1
+CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC
+66 C7 44 24 0E 01 00 8B 90 44 01 00 00 C3 CC
+
+.text:0042BEA1 loc_42BEA1:
+.text:0042BEA1 mov word ptr [esp+0Eh], 1 ; 4+8+2
+.text:0042BEA8 mov edx, [eax+144h]
+.text:0042BEAE retn
+
+0x34d91
+8B 90 44 01 00 00
+E8 0B 65 FF FF 90
+
+<<<<
+.text:00435991 mov edx, [eax+144h]
+====
+.text:00435991 call loc_42BEA1
+.text:00435996 nop
+>>>>
+
+0x34e53
+0F 84 BD 00 00 00
+E8 6B 5E FF FF 90
+
+<<<<
+.text:00435A53 jz loc_435B16
+====
+.text:00435A53 call loc_42B8C3
+.text:00435A58 nop
+>>>>
+
+0x34ef3
+66 3B C5 74 1E
+E8 73 5D FF FF
+
+<<<<
+.text:00435AF3 cmp ax, bp
+.text:00435AF6 jz short loc_435B16
+====
+.text:00435AF3 call loc_42B86B
+>>>>
+
+
+basically:
+
++ int allowed_count = 1; // to mean 2
+ ...
+- if (type(item) == new_type)
++ if (type(item) == new_type && --allowed_count < 0)
+ return false;
+
+to allow up to two items of the same type at the same time
+
+
+---8<---
+This difference file is created by The Interactive Disassembler
+
+Dwarf Fortress.exe
+0002AC6B: CC 66
+0002AC6C: CC 39
+0002AC6D: CC E8
+0002AC6E: CC EB
+0002AC6F: CC 53
+0002AC7B: CC E9
+0002AC7C: CC 96
+0002AC7D: CC A2
+0002AC7E: CC 00
+0002AC7F: CC 00
+0002ACC3: CC 75
+0002ACC4: CC 0A
+0002ACC5: CC 66
+0002ACC6: CC FF
+0002ACC7: CC 4C
+0002ACC8: CC 24
+0002ACC9: CC 16
+0002ACCA: CC 79
+0002ACCB: CC 03
+0002ACCC: CC 58
+0002ACCD: CC EB
+0002ACCE: CC AC
+0002ACCF: CC C3
+0002B2A1: CC 66
+0002B2A2: CC C7
+0002B2A3: CC 44
+0002B2A4: CC 24
+0002B2A5: CC 0E
+0002B2A6: CC 01
+0002B2A7: CC 00
+0002B2A8: CC 8B
+0002B2A9: CC 90
+0002B2AA: CC 44
+0002B2AB: CC 01
+0002B2AC: CC 00
+0002B2AD: CC 00
+0002B2AE: CC C3
+00034D91: 8B E8
+00034D92: 90 0B
+00034D93: 44 65
+00034D94: 01 FF
+00034D95: 00 FF
+00034D96: 00 90
+00034E53: 0F E8
+00034E54: 84 6B
+00034E55: BD 5E
+00034E56: 00 FF
+00034E57: 00 FF
+00034E58: 00 90
+00034EF3: 66 E8
+00034EF4: 3B 73
+00034EF5: C5 5D
+00034EF6: 74 FF
+00034EF7: 1E FF
diff --git a/patches/v0.34.11 SDL/custom-reagent-size.dif b/patches/v0.34.11 SDL/custom-reagent-size.dif
new file mode 100644
index 000000000..2227a48d0
--- /dev/null
+++ b/patches/v0.34.11 SDL/custom-reagent-size.dif
@@ -0,0 +1,91 @@
+http://www.bay12games.com/dwarves/mantisbt/view.php?id=808
+
+Original code:
+
+.text:00916BCE mov edi, ebp
+.text:00916BD0 call eax
+.text:00916BD2 test eax, eax
+.text:00916BD4 jnz short loc_916C1C
+
+.text:00916C0A mov edi, ebp
+
+.text:00916C14 mov edi, ebp
+
+Patch:
+
+0x2ac34:
+CC CC CC CC CC CC CC CC CC CC CC CC
+8B 7C 24 78 8B 3C B7 FF D0 EB 25 CC
+
+.text:0042B834 loc_42B834:
+.text:0042B834 mov edi, [esp+78h]
+.text:0042B838 mov edi, [edi+esi*4]
+.text:0042B83B call eax
+.text:0042B83D jmp short unk_42B864
+
+0x2ac64
+CC CC CC CC CC CC CC CC CC CC CC CC
+85 C0 E9 69 B3 4E 00 CC CC CC CC CC
+
+.text:0042B864 loc_42B864:
+.text:0042B864 test eax, eax
+.text:0042B866 jmp loc_916BD4
+
+0x515fce
+8B FD FF D0 85 C0
+E9 61 4C B1 FF 90
+
+.text:00916BCE jmp loc_42B834
+.text:00916BD3 nop
+.text:00916BD4 loc_916BD4:
+
+0x51600a
+8B FD
+90 90
+
+.text:00916C0A nop
+.text:00916C0B nop
+
+0x516014
+8B FD
+90 90
+
+.text:00916C14 nop
+.text:00916C15 nop
+
+
+You can use this script to apply the generated patch below:
+http://stalkr.net/files/ida/idadif.py
+
+----8<----
+This difference file is created by The Interactive Disassembler
+
+Dwarf Fortress.exe
+0002AC34: CC 8B
+0002AC35: CC 7C
+0002AC36: CC 24
+0002AC37: CC 78
+0002AC38: CC 8B
+0002AC39: CC 3C
+0002AC3A: CC B7
+0002AC3B: CC FF
+0002AC3C: CC D0
+0002AC3D: CC EB
+0002AC3E: CC 25
+0002AC64: CC 85
+0002AC65: CC C0
+0002AC66: CC E9
+0002AC67: CC 69
+0002AC68: CC B3
+0002AC69: CC 4E
+0002AC6A: CC 00
+00515FCE: 8B E9
+00515FCF: FD 61
+00515FD0: FF 4C
+00515FD1: D0 B1
+00515FD2: 85 FF
+00515FD3: C0 90
+0051600A: 8B 90
+0051600B: FD 90
+00516014: 8B 90
+00516015: FD 90
diff --git a/patches/v0.34.11 SDL/deconstruct-heapfall.dif b/patches/v0.34.11 SDL/deconstruct-heapfall.dif
new file mode 100644
index 000000000..05c0047d3
--- /dev/null
+++ b/patches/v0.34.11 SDL/deconstruct-heapfall.dif
@@ -0,0 +1,61 @@
+http://www.bay12games.com/dwarves/mantisbt/view.php?id=5994
+
+Original code:
+
+.text:008629BD mov edi, [eax+38h]
+.text:008629C0 mov eax, [eax+3Ch]
+.text:008629C3 mov [esp+1Ch], eax
+.text:008629C7 cmp edi, eax
+.text:008629C9 jnb short loc_862A22
+.text:008629CB jmp short loc_8629D0
+.text:008629CD lea ecx, [ecx+0]
+...
+.text:00862A19 add edi, 4
+.text:00862A1C cmp edi, [esp+1Ch]
+.text:00862A20 jb short loc_8629D0
+
+Patch:
+
+0x461dbd
+8B 78 38 8B 40 3C 89 44 24 1C 3B F8
+8B 78 3C 8B 40 38 89 44 24 1C 39 F8
+
+.text:008629BD mov edi, [eax+3Ch]
+.text:008629C0 mov eax, [eax+38h]
+.text:008629C3 mov [esp+1Ch], eax
+.text:008629C7 cmp eax, edi
+
+0x461dcb
+EB 03 8D 49 00
+83 EF 04 90 90
+
+.text:008629CB sub edi, 4
+.text:008629CE nop
+.text:008629CF nop
+
+0x461e19
+83 C7 04 3B 7C 24 1C 72 AE
+83 EF 04 3B 7C 24 1C 73 AE
+
+.text:00862A19 sub edi, 4
+.text:00862A1C cmp edi, [esp+1Ch]
+.text:00862A20 jnb short loc_8629D0
+
+
+You can use this script to apply the generated patch below:
+http://stalkr.net/files/ida/idadif.py
+
+----8<----
+This difference file is created by The Interactive Disassembler
+
+Dwarf_Fortress
+00461DBF: 38 3C
+00461DC2: 3C 38
+00461DC7: 3B 39
+00461DCB: EB 83
+00461DCC: 03 EF
+00461DCD: 8D 04
+00461DCE: 49 90
+00461DCF: 00 90
+00461E1A: C7 EF
+00461E20: 72 73
diff --git a/patches/v0.34.11 SDL/deconstruct-teleport.dif b/patches/v0.34.11 SDL/deconstruct-teleport.dif
new file mode 100644
index 000000000..c6037e2c6
--- /dev/null
+++ b/patches/v0.34.11 SDL/deconstruct-teleport.dif
@@ -0,0 +1,104 @@
+http://www.bay12games.com/dwarves/mantisbt/view.php?id=5994
+
+0x461de2
+F6 46 0C 01 74 31
+E9 0A 8E BC FF 90
+
+.text:008629E2 jmp near ptr loc_42B7F1 ; << CAVE
+.text:008629E7 nop
+.text:008629E8 loc_8629E8:
+
+0x2abf1
+CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC
+8B 4C 24 2C F6 46 0C 01 75 08 E9 19 72 43 00
+
+.text:0042B7F1 loc_42B7F1:
+.text:0042B7F1 mov ecx, [esp+2Ch] ; job
+.text:0042B7F5 test byte ptr [esi+0Ch], 1
+.text:0042B7F9 jnz short near ptr loc_42B803
+.text:0042B7FB coord_test_jfail:
+.text:0042B7FB jmp loc_862A19
+
+0x2ac03
+CC CC CC CC CC CC CC CC CC CC CC CC CC
+8B 41 10 3B 46 04 75 F0 EB 06 CC CC CC
+
+.text:0042B803 loc_42B803:
+.text:0042B803 mov eax, [ecx+10h] ; job->pos.(x,y)
+.text:0042B806 cmp eax, [esi+4] ; item->pos.(x,y)
+.text:0042B809 jnz short coord_test_jfail
+.text:0042B80B jmp short near ptr loc_42B813
+
+0x2ac13
+CC CC CC CC CC CC CC CC CC CC CC CC CC
+66 8B 41 14 66 3B 46 08 75 DE EB 06 CC
+
+text:0042B813 loc_42B813:
+.text:0042B813 mov ax, [ecx+14h] ; job->pos.z
+.text:0042B817 cmp ax, [esi+8] ; item->pos.z
+.text:0042B81B jnz short coord_test_jfail
+.text:0042B81D jmp short near ptr loc_42B825
+
+0x2ac25
+CC CC CC CC CC CC CC CC CC CC CC
+E9 BE 71 43 00 CC CC CC CC CC CC
+
+.text:0042B825 loc_42B825:
+.text:0042B825 jmp loc_8629E8
+
+
+You can use this script to apply the generated patch below:
+http://stalkr.net/files/ida/idadif.py
+
+----8<----
+This difference file is created by The Interactive Disassembler
+
+Dwarf Fortress.exe
+0002ABF1: CC 8B
+0002ABF2: CC 4C
+0002ABF3: CC 24
+0002ABF4: CC 2C
+0002ABF5: CC F6
+0002ABF6: CC 46
+0002ABF7: CC 0C
+0002ABF8: CC 01
+0002ABF9: CC 75
+0002ABFA: CC 08
+0002ABFB: CC E9
+0002ABFC: CC 19
+0002ABFD: CC 72
+0002ABFE: CC 43
+0002ABFF: CC 00
+0002AC03: CC 8B
+0002AC04: CC 41
+0002AC05: CC 10
+0002AC06: CC 3B
+0002AC07: CC 46
+0002AC08: CC 04
+0002AC09: CC 75
+0002AC0A: CC F0
+0002AC0B: CC EB
+0002AC0C: CC 06
+0002AC13: CC 66
+0002AC14: CC 8B
+0002AC15: CC 41
+0002AC16: CC 14
+0002AC17: CC 66
+0002AC18: CC 3B
+0002AC19: CC 46
+0002AC1A: CC 08
+0002AC1B: CC 75
+0002AC1C: CC DE
+0002AC1D: CC EB
+0002AC1E: CC 06
+0002AC25: CC E9
+0002AC26: CC BE
+0002AC27: CC 71
+0002AC28: CC 43
+0002AC29: CC 00
+00461DE2: F6 E9
+00461DE3: 46 0A
+00461DE4: 0C 8E
+00461DE5: 01 BC
+00461DE6: 74 FF
+00461DE7: 31 90
diff --git a/patches/v0.34.11 SDL/hospital-overstocking.dif b/patches/v0.34.11 SDL/hospital-overstocking.dif
new file mode 100644
index 000000000..2bc305e60
--- /dev/null
+++ b/patches/v0.34.11 SDL/hospital-overstocking.dif
@@ -0,0 +1,62 @@
+http://www.bay12games.com/dwarves/mantisbt/view.php?id=4406
+
+1. Include store in hospital jobs when recomputing counters
+
+0x68a63
+0F 85 58 01 00 00
+90 90 90 90 90 90
+
+<<<<
+.text:00469663 jnz loc_4697C1
+====
+.text:00469663 nop
+.text:00469664 nop
+.text:00469665 nop
+.text:00469666 nop
+.text:00469667 nop
+.text:00469668 nop
+>>>>
+
+- if (job->getBuildingRef(BUILDING_DESTINATION) != this) continue;
++ // NOP
+
+This reference points to the containers, not the hospital civzone.
+Since fixing this properly is too hard for a patch, just remove the
+check. Most people have only one hospital anyway, and it is better
+to err on the side of caution here.
+
+
+2. Make the stockpiling code increment the right stock counters
+
+0x3dcbf9
+8B 0C 90 8B 81 80 00 00 00
+8B 3C 90 8B 87 80 00 00 00
+
+<<<<
+.text:007DD7F9 mov ecx, [eax+edx*4]
+.text:007DD7FC mov eax, [ecx+80h]
+====
+.text:007DD7F9 mov edi, [eax+edx*4]
+.text:007DD7FC mov eax, [edi+80h]
+>>>>
+
+- id = civzones[i]->children[child_idx[i]]->id
++ cur_civzone = civzones[i] // existing var from previous loop
++ id = cur_civzone->children[child_idx[i]]->id
+
+The reason being, later code uses that var (at this point containing
+useless data) to increment counters and amounts in the hospital.
+
+
+---8<---
+This difference file is created by The Interactive Disassembler
+
+Dwarf Fortress.exe
+00068A63: 0F 90
+00068A64: 85 90
+00068A65: 58 90
+00068A66: 01 90
+00068A67: 00 90
+00068A68: 00 90
+003DCBFA: 0C 3C
+003DCBFD: 81 87
diff --git a/patches/v0.34.11 SDL/training-ammo.dif b/patches/v0.34.11 SDL/training-ammo.dif
new file mode 100644
index 000000000..ea50d4221
--- /dev/null
+++ b/patches/v0.34.11 SDL/training-ammo.dif
@@ -0,0 +1,83 @@
+http://www.bay12games.com/dwarves/mantisbt/view.php?id=4530
+
+0x2ac85
+CC CC CC CC CC CC CC CC CC CC CC
+29 44 24 24 8B 9D 28 01 00 00 C3
+
+.text:0042B885 loc_42B885:
+.text:0042B885 sub [esp+24h], eax
+.text:0042B889 mov ebx, [ebp+128h]
+.text:0042B88F retn
+
+0x2ac94
+CC CC CC CC CC CC CC CC CC CC CC CC
+89 C1 8B 00 FF 90 34 02 00 00 EB E5
+
+.text:0042B894 loc_42B894:
+.text:0042B894 mov ecx, eax
+.text:0042B896 mov eax, [eax]
+.text:0042B898 call dword ptr [eax+234h]
+.text:0042B89E jmp short loc_42B885
+
+0x6e28ff
+29 44 24 20
+90 90 90 90
+
+<<<<
+.text:00AE34FF sub [esp+20h], eax
+====
+.text:00AE34FF nop
+.text:00AE3500 nop
+.text:00AE3501 nop
+.text:00AE3502 nop
+>>>>
+
+0x6e2999
+8B 9D 28 01 00 00
+E8 F6 82 94 FF 90
+
+<<<<
+.text:00AE3599 mov ebx, [ebp+128h]
+====
+.text:00AE3599 call loc_42B894
+.text:00AE359E nop
+>>>>
+
+---8<---
+This difference file is created by The Interactive Disassembler
+
+Dwarf Fortress.exe
+0002AC85: CC 29
+0002AC86: CC 44
+0002AC87: CC 24
+0002AC88: CC 24
+0002AC89: CC 8B
+0002AC8A: CC 9D
+0002AC8B: CC 28
+0002AC8C: CC 01
+0002AC8D: CC 00
+0002AC8E: CC 00
+0002AC8F: CC C3
+0002AC94: CC 89
+0002AC95: CC C1
+0002AC96: CC 8B
+0002AC97: CC 00
+0002AC98: CC FF
+0002AC99: CC 90
+0002AC9A: CC 34
+0002AC9B: CC 02
+0002AC9C: CC 00
+0002AC9D: CC 00
+0002AC9E: CC EB
+0002AC9F: CC E5
+006E28FF: 29 90
+006E2900: 44 90
+006E2901: 24 90
+006E2902: 20 90
+006E2999: 8B E8
+006E299A: 9D F6
+006E299B: 28 82
+006E299C: 01 94
+006E299D: 00 FF
+006E299E: 00 90
+
diff --git a/patches/v0.34.11 SDL/weaponrack-unassign.dif b/patches/v0.34.11 SDL/weaponrack-unassign.dif
new file mode 100644
index 000000000..7760048ba
--- /dev/null
+++ b/patches/v0.34.11 SDL/weaponrack-unassign.dif
@@ -0,0 +1,61 @@
+http://www.bay12games.com/dwarves/mantisbt/view.php?id=1445
+
+0x4c05c4
+8B 8C 24 80 00 00 00
+89 C1 90 90 90 90 90
+
+<<<<
+.text:008C11C4 mov ecx, [esp+98h+var_18]
+====
+.text:008C11C4 mov ecx, eax
+.text:008C11C6 nop
+.text:008C11C7 nop
+.text:008C11C8 nop
+.text:008C11C9 nop
+.text:008C11CA nop
+>>>>
+
+0x4c06a1
+8B 8C 24 80 00 00 00
+89 C1 90 90 90 90 90
+
+<<<<
+.text:008C12A1 mov ecx, [esp+98h+var_18]
+====
+.text:008C12A1 mov ecx, eax
+.text:008C12A3 nop
+.text:008C12A4 nop
+.text:008C12A5 nop
+.text:008C12A6 nop
+.text:008C12A7 nop
+>>>>
+
+
+basically:
+
+ b_squad_id = building->getSpecificSquad();
+- if (b_squad_id != squad->id || !building->canUse(some_squad_id, 4))
++ if (b_squad_id != squad->id || !building->canUse(b_squad_id, 4))
+ unassign(building);
+
+the reason being, some_other_squad_id contains irrelevant garbage at this point
+
+
+---8<---
+This difference file is created by The Interactive Disassembler
+
+Dwarf Fortress.exe
+004C05C4: 8B 89
+004C05C5: 8C C1
+004C05C6: 24 90
+004C05C7: 80 90
+004C05C8: 00 90
+004C05C9: 00 90
+004C05CA: 00 90
+004C06A1: 8B 89
+004C06A2: 8C C1
+004C06A3: 24 90
+004C06A4: 80 90
+004C06A5: 00 90
+004C06A6: 00 90
+004C06A7: 00 90
diff --git a/patches/v0.34.11 linux/armorstand-capacity.dif b/patches/v0.34.11 linux/armorstand-capacity.dif
new file mode 100644
index 000000000..36dbcf0a9
--- /dev/null
+++ b/patches/v0.34.11 linux/armorstand-capacity.dif
@@ -0,0 +1,147 @@
+http://www.bay12games.com/dwarves/mantisbt/view.php?id=1445
+
+0x9461
+90 90 90 90 90 90 90 90 90 90 90 90 90 90
+C7 44 24 18 01 00 00 00 FF A0 44 01 00 00
+
+.text:08051461 sub_8051461 proc near
+.text:08051461 mov dword ptr [esp+18h], 1
+.text:08051469 jmp dword ptr [eax+144h]
+.text:08051469 sub_8051461 endp
+
+0x9548
+90 90 90 90 90 90 90 90
+FF 4C 24 14 78 08 EB 0B
+
+.text:08051548 loc_8051548:
+.text:08051548 dec dword ptr [esp+14h]
+.text:0805154C js short loc_8051556
+.text:0805154E jmp short loc_805155B
+
+0x9556
+90 90 90 90 90 90 90 90 90 90
+E9 F6 8C 05 00 E9 D0 8D 05 00
+
+.text:08051556 loc_8051556:
+.text:08051556 jmp loc_80AA251
+.text:0805155B loc_805155B:
+.text:0805155B jmp loc_80AA330
+
+0x9568
+90 90 90 90 90 90 90 90
+FF 4C 24 14 78 E8 EB 06
+
+.text:08051568 loc_8051568:
+.text:08051568 dec [esp+14h]
+.text:0805156C js short loc_8051556
+.text:0805156E jmp short loc_8051576
+
+0x9576
+90 90 90 90 90
+E9 4D 8E 05 00
+
+.text:08051576 loc_8051576:
+.text:08051576 jmp loc_80AA3C8
+
+0x62243
+FF 90 44 01 00 00
+E8 19 72 FA FF 90
+
+<<<<
+.text:080AA243 call dword ptr [eax+144h]
+====
+.text:080AA243 call sub_8051461
+.text:080AA248 nop
+>>>>
+
+0x62369
+E9 E3 FE FF FF
+E9 DA 71 FA FF
+
+<<<<
+.text:080AA369 jmp loc_80AA251
+====
+.text:080AA369 jmp loc_8051548
+>>>>
+
+0x623f6
+E9 56 FE FF FF
+E9 6D 71 FA FF
+
+<<<<
+.text:080AA3F6 jmp loc_80AA251
+====
+.text:080AA3F6 jmp loc_8051568
+>>>>
+
+basically:
+
++ int allowed_count = 1; // to mean 2
+ ...
+- if (type(item) == new_type)
++ if (type(item) == new_type && --allowed_count < 0)
+ return false;
+
+to allow up to two items of the same type at the same time
+
+---8<---
+This difference file is created by The Interactive Disassembler
+
+Dwarf_Fortress
+00009461: 90 C7
+00009462: 90 44
+00009463: 90 24
+00009464: 90 18
+00009465: 90 01
+00009466: 90 00
+00009467: 90 00
+00009468: 90 00
+00009469: 90 FF
+0000946A: 90 A0
+0000946B: 90 44
+0000946C: 90 01
+0000946D: 90 00
+0000946E: 90 00
+00009548: 90 FF
+00009549: 90 4C
+0000954A: 90 24
+0000954B: 90 14
+0000954C: 90 78
+0000954D: 90 08
+0000954E: 90 EB
+0000954F: 90 0B
+00009556: 90 E9
+00009557: 90 F6
+00009558: 90 8C
+00009559: 90 05
+0000955A: 90 00
+0000955B: 90 E9
+0000955C: 90 D0
+0000955D: 90 8D
+0000955E: 90 05
+0000955F: 90 00
+00009568: 90 FF
+00009569: 90 4C
+0000956A: 90 24
+0000956B: 90 14
+0000956C: 90 78
+0000956D: 90 E8
+0000956E: 90 EB
+0000956F: 90 06
+00009576: 90 E9
+00009577: 90 4D
+00009578: 90 8E
+00009579: 90 05
+0000957A: 90 00
+00062243: FF E8
+00062244: 90 19
+00062245: 44 72
+00062246: 01 FA
+00062247: 00 FF
+00062248: 00 90
+0006236A: E3 DA
+0006236B: FE 71
+0006236C: FF FA
+000623F7: 56 6D
+000623F8: FE 71
+000623F9: FF FA
diff --git a/patches/v0.34.11 linux/custom-reagent-size.dif b/patches/v0.34.11 linux/custom-reagent-size.dif
new file mode 100644
index 000000000..d99269db1
--- /dev/null
+++ b/patches/v0.34.11 linux/custom-reagent-size.dif
@@ -0,0 +1,40 @@
+http://www.bay12games.com/dwarves/mantisbt/view.php?id=808
+
+for (i = 0; i < num_items; i++)
+{
+ ridx = reagent_idx[i];
+ sz = reagent_quantity[ridx]; // used quantity
+ if (sz <= 0) continue;
+ reag = reagent[ridx];
+ if (reag->flags.PRESERVE_REAGENT) continue;
+ rsz = items[i]->getTotalDimension();
+<<<<<<<<
+ if (reag->flags3.ANY_RAW_MATERIAL)
+ rsz *= BASE_SIZE(items[i]->getType());
+ if (items[i]->subtractDimension(rsz))
+========
+ /* Not in patch, but necessary for full correctness:
+ if (reag->flags3.ANY_RAW_MATERIAL)
+ rsz /= BASE_SIZE(items[i]->getType());
+ */
+ if (reag->flags3.ANY_RAW_MATERIAL)
+ sz *= BASE_SIZE(items[i]->getType());
+ if (items[i]->subtractDimension(sz))
+>>>>>>>>
+ destroy_item(items[i]);
+ reagent_quantity[ridx] -= rsz
+ if (reagent_quantity[ridx] < 0)
+ reagent_quantity[ridx] = 0;
+}
+
+You can use this script to apply the generated patch below:
+http://stalkr.net/files/ida/idadif.py
+
+----8<----
+This difference file is created by The Interactive Disassembler
+
+Dwarf_Fortress
+0087F7EF: F8 D8
+0087F86F: F8 D8
+0087F9AD: C7 C3
+0087F9ED: C7 C3
diff --git a/patches/v0.34.11 linux/deconstruct-heapfall.dif b/patches/v0.34.11 linux/deconstruct-heapfall.dif
new file mode 100644
index 000000000..294118ac5
--- /dev/null
+++ b/patches/v0.34.11 linux/deconstruct-heapfall.dif
@@ -0,0 +1,83 @@
+http://www.bay12games.com/dwarves/mantisbt/view.php?id=5994
+
+Original code:
+
+.text:087AC378 cmp edx, eax
+.text:087AC37A mov [esp+4Ch], eax
+.text:087AC37E jnb loc_87A7034
+.text:087AC384 mov [esp+48h], edx
+.text:087AC388 mov [esp+54h], ebx
+...
+.text:087AC440 add dword ptr [esp+48h], 4
+.text:087AC445 mov ebp, [esp+48h]
+.text:087AC449 cmp [esp+4Ch], ebp
+.text:087AC44D ja loc_87AC38C
+
+Patch:
+
+0x76437a
+89 44 24 4C
+89 54 24 4C
+
+.text:087AC37A mov [esp+4Ch], edx
+
+0x764384
+89 54 24 48 89 5C 24 54
+E8 8A 51 8A FF 90 90 90
+
+.text:087AC384 call sub_8051513
+.text:087AC389 nop
+.text:087AC38A nop
+.text:087AC38B nop
+
+0x764440
+83 44 24 48 04 8B 6C 24 48 39 6C 24 4C 0F 87 39 FF FF FF
+83 6C 24 48 04 8B 6C 24 48 39 6C 24 4C 0F 86 39 FF FF FF
+
+.text:087AC440 sub dword ptr [esp+48h], 4
+.text:087AC445 mov ebp, [esp+48h]
+.text:087AC449 cmp [esp+4Ch], ebp
+.text:087AC44D jbe loc_87AC38C
+
+0x9513
+90 90 90 90 90 90 90 90 90 90 90 90 90
+83 E8 04 89 44 24 4C 89 5C 24 58 C3 90
+
+.text:08051513 sub_8051513 proc near
+.text:08051513 sub eax, 4
+.text:08051516 mov [esp+4Ch], eax ; 48h
+.text:0805151A mov [esp+58h], ebx ; 54h
+.text:0805151E retn
+.text:0805151E sub_8051513 endp
+
+
+You can use this script to apply the generated patch below:
+http://stalkr.net/files/ida/idadif.py
+
+----8<----
+This difference file is created by The Interactive Disassembler
+
+Dwarf_Fortress
+00009513: 90 83
+00009514: 90 E8
+00009515: 90 04
+00009516: 90 89
+00009517: 90 44
+00009518: 90 24
+00009519: 90 4C
+0000951A: 90 89
+0000951B: 90 5C
+0000951C: 90 24
+0000951D: 90 58
+0000951E: 90 C3
+0076437B: 44 54
+00764384: 89 E8
+00764385: 54 8A
+00764386: 24 51
+00764387: 48 8A
+00764388: 89 FF
+00764389: 5C 90
+0076438A: 24 90
+0076438B: 54 90
+00764441: 44 6C
+0076444E: 87 86
diff --git a/patches/v0.34.11 linux/deconstruct-teleport.dif b/patches/v0.34.11 linux/deconstruct-teleport.dif
new file mode 100644
index 000000000..3b3212109
--- /dev/null
+++ b/patches/v0.34.11 linux/deconstruct-teleport.dif
@@ -0,0 +1,139 @@
+http://www.bay12games.com/dwarves/mantisbt/view.php?id=5994
+
+0x7643f8
+F6 46 0C 01 74 42
+E9 B6 50 8A FF 90
+
+.text:087AC3F8 jmp loc_80514B3 ; << CAVE
+.text:087AC3FD nop
+.text:087AC3FE loc_87AC3FE:
+
+0x94b3
+90 90 90 90 90 90 90 90 90 90 90 90 90
+F6 46 0C 01 75 0A E9 82 AF 75 00 90 90
+
+.text:080514B3 loc_80514B3:
+.text:080514B3 test byte ptr [esi+0Ch], 1
+.text:080514B7 jnz short loc_80514C3
+.text:080514B9 coord_test_jfail:
+.text:080514B9 jmp loc_87AC440
+
+0x94c3
+90 90 90 90 90 90 90 90 90 90 90 90 90
+8D 9C 24 60 03 00 00 0F BF 03 EB 07 90
+
+.text:080514C3 loc_80514C3:
+.text:080514C3 lea ebx, [esp+360h]
+.text:080514CA movsx eax, word ptr [ebx] ; job_z
+.text:080514CD jmp short loc_80514D6
+
+0x94d6
+90 90 90 90 90 90 90 90 90 90
+66 3B 46 08 75 DD EB 05 90 90
+
+.text:080514D6 loc_80514D6:
+.text:080514D6 cmp ax, [esi+8] ; item->pos.z
+.text:080514DA jnz short coord_test_jfail
+.text:080514DC jmp short loc_80514E3
+
+0x94e3
+90 90 90 90 90 90 90 90 90 90 90 90 90
+0F BF 43 10 66 3B 46 04 75 CC EB 04 90
+
+.text:080514E3 loc_80514E3:
+.text:080514E3 movsx eax, word ptr [ebx+10h] ; job_x
+.text:080514E7 cmp ax, [esi+4] ; item->pos.x
+.text:080514EB jnz short coord_test_jfail
+.text:080514ED jmp short loc_80514F3
+
+0x94f3
+90 90 90 90 90 90 90 90 90 90 90 90 90
+0F BF 43 20 66 3B 46 06 75 BC EB 04 90
+
+.text:080514F3 loc_80514F3:
+.text:080514F3 movsx eax, word ptr [ebx+20h] ; job_y
+.text:080514F7 cmp ax, [esi+6] ; item->pos.y
+.text:080514FB jnz short coord_test_jfail
+.text:080514FD jmp short loc_8051503
+
+0x9503
+90 90 90 90 90 90 90 90 90 90 90 90 90
+E9 F6 AE 75 00 90 90 90 90 90 90 90 90
+
+.text:08051503 loc_8051503:
+.text:08051503 jmp loc_87AC3FE
+
+
+You can use this script to apply the generated patch below:
+http://stalkr.net/files/ida/idadif.py
+
+----8<----
+This difference file is created by The Interactive Disassembler
+
+Dwarf_Fortress
+000094B3: 90 F6
+000094B4: 90 46
+000094B5: 90 0C
+000094B6: 90 01
+000094B7: 90 75
+000094B8: 90 0A
+000094B9: 90 E9
+000094BA: 90 82
+000094BB: 90 AF
+000094BC: 90 75
+000094BD: 90 00
+000094C3: 90 8D
+000094C4: 90 9C
+000094C5: 90 24
+000094C6: 90 60
+000094C7: 90 03
+000094C8: 90 00
+000094C9: 90 00
+000094CA: 90 0F
+000094CB: 90 BF
+000094CC: 90 03
+000094CD: 90 EB
+000094CE: 90 07
+000094D6: 90 66
+000094D7: 90 3B
+000094D8: 90 46
+000094D9: 90 08
+000094DA: 90 75
+000094DB: 90 DD
+000094DC: 90 EB
+000094DD: 90 05
+000094E3: 90 0F
+000094E4: 90 BF
+000094E5: 90 43
+000094E6: 90 10
+000094E7: 90 66
+000094E8: 90 3B
+000094E9: 90 46
+000094EA: 90 04
+000094EB: 90 75
+000094EC: 90 CC
+000094ED: 90 EB
+000094EE: 90 04
+000094F3: 90 0F
+000094F4: 90 BF
+000094F5: 90 43
+000094F6: 90 20
+000094F7: 90 66
+000094F8: 90 3B
+000094F9: 90 46
+000094FA: 90 06
+000094FB: 90 75
+000094FC: 90 BC
+000094FD: 90 EB
+000094FE: 90 04
+00009503: 90 E9
+00009504: 90 F6
+00009505: 90 AE
+00009506: 90 75
+00009507: 90 00
+007643F8: F6 E9
+007643F9: 46 B6
+007643FA: 0C 50
+007643FB: 01 8A
+007643FC: 74 FF
+007643FD: 42 90
diff --git a/patches/v0.34.11 linux/hospital-overstocking.dif b/patches/v0.34.11 linux/hospital-overstocking.dif
new file mode 100644
index 000000000..73e5d2fac
--- /dev/null
+++ b/patches/v0.34.11 linux/hospital-overstocking.dif
@@ -0,0 +1,60 @@
+http://www.bay12games.com/dwarves/mantisbt/view.php?id=4406
+
+1. Include store in hospital jobs when recomputing counters
+
+0x746d7
+75 D7
+90 90
+
+<<<<
+.text:080BC6D7 jnz short loc_80BC6B0
+====
+.text:080BC6D7 nop
+.text:080BC6D8 nop
+>>>>
+
+- if (job->getBuildingRef(BUILDING_DESTINATION) != this) continue;
++ // NOP
+
+This reference points to the containers, not the hospital civzone.
+Since fixing this properly is too hard for a patch, just remove the
+check. Most people have only one hospital anyway, and it is better
+to err on the side of caution here.
+
+
+2. Make the stockpiling code increment the right stock counters
+
+0x67cb0e
+0B 04 90
+8B 1C 90
+
+0x67cb18
+8B 40 74
+8B 43 74
+
+<<<<
+.text:086C4B0E mov eax, [eax+edx*4]
+.text:086C4B11 mov edx, [esp+ecx*4+39Ch+var_2B4]
+.text:086C4B18 mov eax, [eax+74h]
+====
+.text:086C4B0E mov ebx, [eax+edx*4]
+.text:086C4B11 mov edx, [esp+ecx*4+39Ch+var_2B4]
+.text:086C4B18 mov eax, [ebx+74h]
+>>>>
+
+- id = civzones[i]->children[child_idx[i]]->id
++ cur_civzone = civzones[i] // existing var from previous loop
++ id = cur_civzone->children[child_idx[i]]->id
+
+The reason being, later code uses that var (at this point containing
+useless data) to increment counters and amounts in the hospital.
+
+
+---8<---
+This difference file is created by The Interactive Disassembler
+
+Dwarf_Fortress
+000746D7: 75 90
+000746D8: D7 90
+0067CB0F: 04 1C
+0067CB19: 40 43
diff --git a/patches/v0.34.11 linux/training-ammo.dif b/patches/v0.34.11 linux/training-ammo.dif
new file mode 100644
index 000000000..9fbcabe78
--- /dev/null
+++ b/patches/v0.34.11 linux/training-ammo.dif
@@ -0,0 +1,85 @@
+http://www.bay12games.com/dwarves/mantisbt/view.php?id=4530
+
+0x9508
+
+90 90 90 90 90 90 90 90
+E9 13 76 9C 00 90 90 90
+
+.text:08051508 loc_8051508:
+.text:08051508 jmp sub_8A18B20
+
+0x9523
+
+90 90 90 90 90 90 90 90 90 90 90 90 90
+50 8B 03 53 FF 90 34 02 00 00 EB 09 90
+
+.text:08051523 sub_8051523:
+.text:08051523 push eax
+.text:08051524 mov eax, [ebx]
+.text:08051526 push ebx
+.text:08051527 call dword ptr [eax+234h]
+.text:0805152D jmp short loc_8051538
+
+0x9538
+
+90 90 90 90 90 90 90 90
+29 44 24 64 5B 58 EB C8
+
+.text:08051538 loc_8051538:
+.text:08051538 sub [esp+64h], eax
+.text:0805153C pop ebx
+.text:0805153D pop eax
+.text:0805153E jmp short loc_8051508
+
+0xa5cdd0
+
+29 44 24 58
+90 90 90 90
+
+.text:08AA4DD0 nop
+.text:08AA4DD1 nop
+.text:08AA4DD2 nop
+.text:08AA4DD3 nop
+
+0xa5e2c3
+
+E8 58 28 F7 FF
+E8 5B B2 5A FF
+
+.text:08AA62C3 call sub_8051523
+
+---8<---
+This difference file is created by The Interactive Disassembler
+
+Dwarf_Fortress
+00009508: 90 E9
+00009509: 90 13
+0000950A: 90 76
+0000950B: 90 9C
+0000950C: 90 00
+00009523: 90 50
+00009524: 90 8B
+00009525: 90 03
+00009526: 90 53
+00009527: 90 FF
+00009529: 90 34
+0000952A: 90 02
+0000952B: 90 00
+0000952C: 90 00
+0000952D: 90 EB
+0000952E: 90 09
+00009538: 90 29
+00009539: 90 44
+0000953A: 90 24
+0000953B: 90 64
+0000953C: 90 5B
+0000953D: 90 58
+0000953E: 90 EB
+0000953F: 90 C8
+00A5CDD0: 29 90
+00A5CDD1: 44 90
+00A5CDD2: 24 90
+00A5CDD3: 58 90
+00A5E2C4: 58 5B
+00A5E2C5: 28 B2
+00A5E2C6: F7 5A
diff --git a/patches/v0.34.11 linux/weaponrack-unassign.dif b/patches/v0.34.11 linux/weaponrack-unassign.dif
new file mode 100644
index 000000000..721f235e8
--- /dev/null
+++ b/patches/v0.34.11 linux/weaponrack-unassign.dif
@@ -0,0 +1,45 @@
+http://www.bay12games.com/dwarves/mantisbt/view.php?id=1445
+
+Fix use of uninitialized variables to stop auto-unassigning racks:
+
+0x7ee948
+8B 7C 24 3C
+89 C7 90 90
+
+.text:08836948 mov edi, eax
+.text:0883694A nop
+.text:0883694B nop
+
+
+0x7eea2f
+8B 7C 24 3C
+89 C7 90 90
+
+.text:08836A2F mov edi, eax
+.text:08836A31 nop
+.text:08836A32 nop
+
+
+basically:
+
+ b_squad_id = building->getSpecificSquad();
+- if (b_squad_id != squad->id || !building->canUse(some_squad_id, 4))
++ if (b_squad_id != squad->id || !building->canUse(b_squad_id, 4))
+ unassign(building);
+
+the reason being, some_other_squad_id contains irrelevant garbage at this point
+
+
+---8<---
+This difference file is created by The Interactive Disassembler
+
+Dwarf_Fortress
+007EE948: 8B 89
+007EE949: 7C C7
+007EE94A: 24 90
+007EE94B: 3C 90
+007EEA2F: 8B 89
+007EEA30: 7C C7
+007EEA31: 24 90
+007EEA32: 3C 90
+
diff --git a/scripts/binpatch.lua b/scripts/binpatch.lua
new file mode 100644
index 000000000..f0f14e929
--- /dev/null
+++ b/scripts/binpatch.lua
@@ -0,0 +1,117 @@
+-- Apply or remove binary patches at runtime.
+
+local utils = require('utils')
+
+function load_patch(name)
+ local filename = name
+ local auto = false
+ if not string.match(filename, '[./\\]') then
+ auto = true
+ filename = dfhack.getHackPath()..'/patches/'..dfhack.getDFVersion()..'/'..name..'.dif'
+ end
+
+ local file, err = io.open(filename, 'r')
+ if not file then
+ if auto and string.match(err, ': No such file or directory') then
+ return nil, 'no patch '..name..' for '..dfhack.getDFVersion()
+ else
+ return nil, err
+ end
+ end
+
+ local old_bytes = {}
+ local new_bytes = {}
+
+ for line in file:lines() do
+ if string.match(line, '^%x+:') then
+ local offset, oldv, newv = string.match(line, '^(%x+):%s*(%x+)%s+(%x+)%s*$')
+ if not offset then
+ file:close()
+ return nil, 'Could not parse: '..line
+ end
+
+ offset, oldv, newv = tonumber(offset,16), tonumber(oldv,16), tonumber(newv,16)
+ if oldv > 255 or newv > 255 then
+ file:close()
+ return nil, 'Invalid byte values: '..line
+ end
+
+ old_bytes[offset] = oldv
+ new_bytes[offset] = newv
+ end
+ end
+
+ return { name = name, old_bytes = old_bytes, new_bytes = new_bytes }
+end
+
+function rebase_table(input)
+ local output = {}
+ local base = dfhack.internal.getImageBase()
+ for k,v in pairs(input) do
+ local offset = dfhack.internal.adjustOffset(k)
+ if not offset then
+ return nil, string.format('invalid offset: %x', k)
+ end
+ output[base + offset] = v
+ end
+ return output
+end
+
+function rebase_patch(patch)
+ local nold, err = rebase_table(patch.old_bytes)
+ if not nold then return nil, err end
+ local nnew, err = rebase_table(patch.new_bytes)
+ if not nnew then return nil, err end
+ return { name = patch.name, old_bytes = nold, new_bytes = nnew }
+end
+
+function run_command(cmd,name)
+ local patch, err = load_patch(name)
+ if not patch then
+ dfhack.printerr('Could not load: '..err)
+ return
+ end
+
+ local rpatch, err = rebase_patch(patch)
+ if not rpatch then
+ dfhack.printerr(name..': '..err)
+ return
+ end
+
+ if cmd == 'check' then
+ local old_ok, err, addr = dfhack.internal.patchBytes({}, rpatch.old_bytes)
+ if old_ok then
+ print(name..': patch is not applied.')
+ elseif dfhack.internal.patchBytes({}, rpatch.new_bytes) then
+ print(name..': patch is applied.')
+ else
+ dfhack.printerr(string.format('%s: conflict at address %x', name, addr))
+ end
+ elseif cmd == 'apply' then
+ local ok, err, addr = dfhack.internal.patchBytes(rpatch.new_bytes, rpatch.old_bytes)
+ if ok then
+ print(name..': applied the patch.')
+ elseif dfhack.internal.patchBytes({}, rpatch.new_bytes) then
+ print(name..': patch is already applied.')
+ else
+ dfhack.printerr(string.format('%s: conflict at address %x', name, addr))
+ end
+ elseif cmd == 'remove' then
+ local ok, err, addr = dfhack.internal.patchBytes(rpatch.old_bytes, rpatch.new_bytes)
+ if ok then
+ print(name..': removed the patch.')
+ elseif dfhack.internal.patchBytes({}, rpatch.old_bytes) then
+ print(name..': patch is already removed.')
+ else
+ dfhack.printerr(string.format('%s: conflict at address %x', name, addr))
+ end
+ else
+ qerror('Invalid command: '..cmd)
+ end
+end
+
+local cmd,name = ...
+if not cmd or not name then
+ qerror('Usage: binpatch check/apply/remove ')
+end
+run_command(cmd, name)
From 683da39636c6dd9c9a3d3d51061e166cbfec8ca7 Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Sun, 11 Nov 2012 17:24:25 +0400
Subject: [PATCH 046/158] Fix dfusion build on linux.
---
plugins/Dfusion/dfusion.cpp | 2 +-
plugins/Dfusion/include/OutFile.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/plugins/Dfusion/dfusion.cpp b/plugins/Dfusion/dfusion.cpp
index 4507f9a15..15bcfa7a8 100644
--- a/plugins/Dfusion/dfusion.cpp
+++ b/plugins/Dfusion/dfusion.cpp
@@ -41,7 +41,7 @@ static int loadObjectFile(lua_State* L)
//Lua::Push(L,buf);
lua_pushlightuserdata(L,buf);
lua_setfield(L,table_pos,"data");
- OutFile::vSymbol& symbols=f.GetSymbols();
+ const OutFile::vSymbol &symbols=f.GetSymbols();
lua_newtable(L);
for(size_t i=0;i
Date: Sun, 11 Nov 2012 17:19:37 +0200
Subject: [PATCH 047/158] Fixed error in dfusion and added some readme.
---
NEWS | 8 +++++++-
Readme.rst | 22 +++++++++++++++-------
plugins/Dfusion/include/OutFile.h | 2 +-
3 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/NEWS b/NEWS
index 51321be95..ad340447e 100644
--- a/NEWS
+++ b/NEWS
@@ -12,11 +12,16 @@ DFHack future
- removebadthoughts: add --dry-run option
New scripts:
- region-pops: displays animal populations of the region and allows tweaking them.
+ - lua: lua interpreter.
+ - dfusion: misc scripts with a text based menu.
+ - embark: lets you embark anywhere.
New GUI scripts:
- gui/guide-path: displays the cached path for minecart Guide orders.
- gui/workshop-job: displays inputs of a workshop job and allows tweaking them.
- gui/workflow: a front-end for the workflow plugin.
- gui/assign-rack: works together with a binary patch to fix weapon racks.
+ - gui/gm-editor: an universal editor for lots of dfhack things.
+ - gui/companion-order: a adventure mode command interface for your companions.
Workflow plugin:
- properly considers minecarts assigned to routes busy.
- code for deducing job outputs rewritten in lua for flexibility.
@@ -29,7 +34,8 @@ DFHack future
properly designated barracks be used again for storage of squad equipment.
New Search plugin by falconne:
Adds an incremental search function to the Stocks, Trading and Unit List screens.
-
+ Dfusion plugin:
+ Reworked to make use of lua modules, now all the scripts can be used from other scripts.
DFHack v0.34.11-r2
diff --git a/Readme.rst b/Readme.rst
index d9021c7cb..668d8be50 100644
--- a/Readme.rst
+++ b/Readme.rst
@@ -1611,19 +1611,17 @@ twice.
dfusion
-------
-This is the DFusion lua plugin system by warmist/darius, running as a DFHack plugin.
+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:
+ :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=69682.15
+See the bay12 thread for details: http://www.bay12forums.com/smf/index.php?topic=93317.0
-Confirmed working DFusion plugins:
-
-:simple_embark: allows changing the number of dwarves available on embark.
.. note::
* Some of the DFusion plugins aren't completely ported yet. This can lead to crashes.
- * This is currently working only on Windows.
- * The game will be suspended while you're using dfusion. Don't panic when it doen't respond.
+ * The game will be suspended while you're using dfusion. Don't panic when it doesn't respond.
misery
------
@@ -1836,6 +1834,16 @@ deathcause
Focus a body part ingame, and this script will display the cause of death of
the creature.
+lua
+===
+There are three ways to invoke this command:
+ 1. without any parameters - starts an interactive lua interpreter
+ 2. -f "filename" or --file "filename" - loads and runs the file indicated by filename
+ 3. -s ["filename"] or --save ["filename"] - loads and runs the file indicated by filename from save directory. If filename is not supplied it loads "dfhack.lua"
+
+embark
+======
+Allows to embark anywhere. Currently windows only.
=======================
In-game interface tools
diff --git a/plugins/Dfusion/include/OutFile.h b/plugins/Dfusion/include/OutFile.h
index 665a1e132..2ba9ecc80 100644
--- a/plugins/Dfusion/include/OutFile.h
+++ b/plugins/Dfusion/include/OutFile.h
@@ -105,7 +105,7 @@ public:
void GetText(char *ptr);
size_t GetTextSize();
void LoadSymbols();
- vSymbol GetSymbols(){LoadSymbols();return symbols;};
+ const vSymbol& GetSymbols(){LoadSymbols();return symbols;};
void PrintSymbols();
void PrintRelocations();
protected:
From 3eb852a43b6c1b9076084b4b89d2a78dce76f32b Mon Sep 17 00:00:00 2001
From: Warmist
Date: Sun, 11 Nov 2012 21:18:59 +0200
Subject: [PATCH 048/158] Added cheat commands to companion-order, (including
rumrushers)
---
plugins/lua/dfusion/tools.lua | 70 ++++++++++++++++++++++++++++++---
scripts/gui/companion-order.lua | 57 +++++++++++++++++++++++++--
2 files changed, 118 insertions(+), 9 deletions(-)
diff --git a/plugins/lua/dfusion/tools.lua b/plugins/lua/dfusion/tools.lua
index e577a9418..86efe009c 100644
--- a/plugins/lua/dfusion/tools.lua
+++ b/plugins/lua/dfusion/tools.lua
@@ -150,13 +150,8 @@ function project(unit,trg) --TODO add to menu?
end
function empregnate(unit)
if unit==nil then
- unit=getSelectedUnit()
- end
-
- if unit==nil then
- unit=getCreatureAtPos(getxyz())
+ unit=dfhack.gui.getSelectedUnit()
end
-
if unit==nil then
error("Failed to empregnate. Unit not selected/valid")
end
@@ -182,4 +177,67 @@ function empregnate(unit)
unit.relations.pregnancy_mystery=1
end
menu:add("Empregnate",empregnate)
+function healunit(unit)
+ if unit==nil then
+ unit=dfhack.gui.getSelectedUnit()
+ 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.able_stand=4
+ unit.status2.able_stand_impair=4
+ unit.status2.able_grasp=4
+ unit.status2.able_grasp_impair=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
+
+ if unit.status.current_soul== nil then
+ error("Failed to power up unit. Unit has no soul")
+ end
+ local utils = require 'utils'
+ labor_rating = labor_rating or 15
+ military_rating = military_rating or 70
+
+ skill =skill or { 0,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,41,42,43,44,45,46,47,48,49,54,55,57,58,59,60,61,62,63,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,95,96,97,98,99,100,101,102,103,104,105,109,110,111,112,113,114,115 }
+ local military = { 38,39,41,42,43,44,45,46,54,99,100,101,102,103,104,105 }
+
+ for sk,sv in ipairs(skill) do
+ local new_rating = labor_rating
+ for _,v in ipairs(military) do
+ if v == sv then
+ local new_rating = military_rating
+ end
+ 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
\ No newline at end of file
diff --git a/scripts/gui/companion-order.lua b/scripts/gui/companion-order.lua
index 6b6a79aa2..6a25787e6 100644
--- a/scripts/gui/companion-order.lua
+++ b/scripts/gui/companion-order.lua
@@ -1,7 +1,8 @@
local gui = require 'gui'
local dlg = require 'gui.dialogs'
-
+local args={...}
+local is_cheat=(#args>0 and args[1]=="-c")
local cursor=xyz2pos(df.global.cursor.x,df.global.cursor.y,df.global.cursor.z)
local permited_equips={}
@@ -28,6 +29,13 @@ function CheckCursor(p)
end
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
+end
+
function GetCaste(race_id,caste_id)
local race=df.creature_raw.find(race_id)
return race.caste[caste_id]
@@ -302,8 +310,39 @@ end},
end
return true
end},
+{name="Get in",f=function (unit_list,pos)
+ if not CheckCursor(pos) then
+ return false
+ end
+ 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.itemrefs:insert("#",ref)
+ end
+ return true
+end},
+}
+local cheats={
+{name="Patch up",f=function (unit_list)
+ local dft=require("plugins.dfusion.tools")
+ for k,v in pairs(unit_list) do
+ dft.healunit(v)
+ 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
+ dft.powerup(d)
+ end
+ return true
+end},
+
}
-local cheats={}
--[[ todo: add cheats...]]--
function getCompanions(unit)
unit=unit or df.global.world.units.active[0]
@@ -371,7 +410,14 @@ function CompanionUi:onInput(keys)
self:dismiss()
end
end
- --do order
+ if is_cheat then
+ idx=idx-#orders
+ if cheats[idx] and cheats[idx].f then
+ if cheats[idx].f(self:GetSelectedUnits(),cursor) then
+ self:dismiss()
+ end
+ end
+ end
end
end
end
@@ -393,6 +439,11 @@ function CompanionUi:onRenderBody( dc)
for k,v in ipairs(orders) do
dc:seek(w/2,k):string(string.char(k+char_A)..". "):string(v.name);
end
+ if is_cheat then
+ for k,v in ipairs(cheats) do
+ dc:seek(w/2,k+#orders):string(string.char(k+#orders+char_A)..". "):string(v.name);
+ end
+ end
end
local screen=CompanionUi{unit_list=getCompanions()}
screen:show()
\ No newline at end of file
From ce8ada4419727d20c710a911fd257970667c91ef Mon Sep 17 00:00:00 2001
From: Warmist
Date: Sun, 11 Nov 2012 22:14:00 +0200
Subject: [PATCH 049/158] More bug fixing
---
plugins/lua/dfusion/tools.lua | 4 +--
scripts/gui/companion-order.lua | 55 +++++++++++++++++++++++----------
2 files changed, 40 insertions(+), 19 deletions(-)
diff --git a/plugins/lua/dfusion/tools.lua b/plugins/lua/dfusion/tools.lua
index 86efe009c..f1fdadf2b 100644
--- a/plugins/lua/dfusion/tools.lua
+++ b/plugins/lua/dfusion/tools.lua
@@ -94,8 +94,8 @@ function MakeFollow(unit,trgunit)
trgunit=df.global.world.units.active[0]
end
unit.relations.group_leader_id=trgunit.id
- local u_nem=getNemesis(unit)
- local t_nem=getNemesis(trgunit)
+ 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
diff --git a/scripts/gui/companion-order.lua b/scripts/gui/companion-order.lua
index 6a25787e6..b9e3b8300 100644
--- a/scripts/gui/companion-order.lua
+++ b/scripts/gui/companion-order.lua
@@ -7,6 +7,7 @@ local cursor=xyz2pos(df.global.cursor.x,df.global.cursor.y,df.global.cursor.z)
local permited_equips={}
permited_equips[df.item_backpackst]="UPPERBODY"
+permited_equips[df.item_quiverst]="UPPERBODY"
permited_equips[df.item_flaskst]="UPPERBODY"
permited_equips[df.item_armorst]="UPPERBODY"
permited_equips[df.item_shoesst]="STANCE"
@@ -14,7 +15,7 @@ permited_equips[df.item_glovesst]="GRASP"
permited_equips[df.item_helmst]="HEAD"
permited_equips[df.item_pantsst]="LOWERBODY"
function DoesHaveSubtype(item)
- if df.item_backpackst:is_instance(item) or df.item_flaskst:is_instance(item) then
+ if df.item_backpackst:is_instance(item) or df.item_flaskst:is_instance(item) or df.item_quiverst:is_instance(item) then
return false
end
return true
@@ -263,6 +264,26 @@ end},
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
+ if it.mode==1 then
+ wep_count=wep_count+1
+ end
+ end
+ for i=1,wep_count do
+ for _,it in pairs(v.inventory) do
+ if it.mode==1 then
+ dfhack.items.moveToGround(it.item,v.pos)
+ break
+ end
+ end
+ end
+ end
+ return true
+end},
--[=[
{name="roam not working :<",f=function (unit_list,pos,dist) --does not work
if not CheckCursor(pos) then
@@ -310,21 +331,7 @@ end},
end
return true
end},
-{name="Get in",f=function (unit_list,pos)
- if not CheckCursor(pos) then
- return false
- end
- 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.itemrefs:insert("#",ref)
- end
- return true
-end},
+
}
local cheats={
{name="Patch up",f=function (unit_list)
@@ -341,7 +348,21 @@ end},
end
return true
end},
-
+{name="get in",f=function (unit_list,pos)
+ if not CheckCursor(pos) then
+ return false
+ end
+ 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.itemrefs:insert("#",ref)
+ end
+ return true
+end},
}
--[[ todo: add cheats...]]--
function getCompanions(unit)
From 6cf85b43185d5cd3bab4de368805cfea7f08b912 Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Mon, 12 Nov 2012 12:26:31 +0400
Subject: [PATCH 050/158] Abstract the back-end from the binpatch script, and
use in gui/assign-rack.
---
Readme.html | 142 +++++++++++++++++++++---------------
Readme.rst | 11 ++-
library/lua/binpatch.lua | 121 ++++++++++++++++++++++++++++++
scripts/binpatch.lua | 103 ++++----------------------
scripts/gui/assign-rack.lua | 26 +++----
5 files changed, 239 insertions(+), 164 deletions(-)
create mode 100644 library/lua/binpatch.lua
diff --git a/Readme.html b/Readme.html
index 737963372..b7ca94964 100644
--- a/Readme.html
+++ b/Readme.html
@@ -501,38 +501,40 @@ access DF memory and allow for easier development of new tools.
- superdwarf
- drainaquifer
- deathcause
+
- lua
+
- embark
-
- In-game interface tools
-- Dwarf Manipulator
-- Search
-- gui/liquids
-- gui/mechanisms
-- gui/rename
-- gui/room-list
-- gui/choose-weapons
-- gui/guide-path
-- gui/workshop-job
-- gui/workflow
-- gui/assign-rack
+- In-game interface tools
-- Behavior Mods
-- Siege Engine
-- Rationale
-- Configuration UI
+- Behavior Mods
@@ -1882,7 +1884,7 @@ to make them stand out more in the list.
Enables a fix for storage of squad equipment in barracks.
-
Specifically, it prevents your haulers from moving that equipment
+
Specifically, it prevents your haulers from moving squad equipment
to stockpiles, and instead queues jobs to store it on weapon racks,
armor stands, and in containers.
@@ -1890,9 +1892,10 @@ armor stands, and in containers.
In order to actually be used, weapon racks have to be patched and
manually assigned to a squad. See documentation for gui/assign-rack
below.
-
Also, the default capacity of armor stands is way too low, so check out
+
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 a patch addressing that too.
+for more information about the bugs.
Note that the buildings in the armory are used as follows:
@@ -2510,23 +2513,26 @@ twice.
-
This is the DFusion lua plugin system by warmist/darius, running as a DFHack plugin.
-
See the bay12 thread for details: http://www.bay12forums.com/smf/index.php?topic=69682.15
-
Confirmed working DFusion plugins:
-
+
+- 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:
+
-simple_embark: | allows changing the number of dwarves available on embark. |
+
---|
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.
-- This is currently working only on Windows.
-- The game will be suspended while you're using dfusion. Don't panic when it doen't respond.
+- The game will be suspended while you're using dfusion. Don't panic when it doesn't respond.
@@ -2726,9 +2732,25 @@ superdwarf add
Focus a body part ingame, and this script will display the cause of death of
the creature.
+
+
+
+- There are three ways to invoke this command:
+
+- without any parameters - starts an interactive lua interpreter
+- -f "filename" or --file "filename" - loads and runs the file indicated by filename
+- -s ["filename"] or --save ["filename"] - loads and runs the file indicated by filename from save directory. If filename is not supplied it loads "dfhack.lua"
+
+
+
+
+
+
+
Allows to embark anywhere. Currently windows only.
+
-
+
These tools work by displaying dialogs or overlays in the game window, and
are mostly implemented by lua scripts.
@@ -2739,7 +2761,7 @@ display the word "DFHack" on the screen somewhere while active.
guideline because it arguably just fixes small usability bugs in the game UI.
-
+
Implemented by the manipulator plugin. To activate, open the unit screen and
press 'l'.
This tool implements a Dwarf Therapist-like interface within the game UI. The
@@ -2775,7 +2797,7 @@ cursor onto that cell instead of toggling it.
directly to the main dwarf mode screen.
-
+
The search plugin adds search to the Stocks, Trading and Unit List screens.
Searching works the same way as the search option in "Move to Depot" does.
You will see the Search option displayed on screen with a hotkey (usually 's').
@@ -2794,13 +2816,13 @@ Value numbers displayed by the screen. Because of this, pressing the 't'
key while search is active clears the search instead of executing the trade.
-
+
To use, bind to a key and activate in the 'k' mode.
While active, use the suggested keys to switch the usual liquids parameters, and Enter
to select the target area and apply changes.
-
+
To use, bind to a key and activate in the 'q' mode.
Lists mechanisms connected to the building, and their links. Navigating the list centers
the view on the relevant linked buildings.
@@ -2809,7 +2831,7 @@ focus on the current one. Shift-Enter has an effect equivalent to pressing Enter
re-entering the mechanisms ui.
-
+
Backed by the rename plugin, this script allows entering the desired name
via a simple dialog in the game ui.
-
+
To use, bind to a key and activate in the 'q' mode, 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.
-
+
Bind to a key, and activate in the Equip->View/Customize page of the military screen.
Depending on the cursor location, it rewrites all 'individual choice weapon' entries
in the selected squad or position to use a specific weapon type matching the assigned
@@ -2842,13 +2864,13 @@ only that entry, and does it even if it is not 'individual choice'.
and may lead to inappropriate weapons being selected.
-
+
Bind to a key, and activate in the Hauling menu with the cursor over a Guide order.
The script displays the cached path that will be used by the order; the game
computes it when the order is executed for the first time.
-
+
Bind to a key, and activate with a job selected in a workshop in the 'q' mode.
The script shows a list of the input reagents of the selected job, and allows changing
them like the job item-type and job item-material commands.
@@ -2876,7 +2898,7 @@ and then try to change the input item type, now it won't let you select
plan
you have to unset the material first.
-
+
Bind to a key, and activate with a job selected in a workshop in the 'q' mode.
This script provides a simple interface to constraints managed by the workflow
plugin. When active, it displays a list of all constraints applicable to the
@@ -2898,7 +2920,7 @@ as described in workflow documentation above.
can be used for troubleshooting jobs that don't match the right constraints.
-
+
Bind to a key, and activate when viewing a weapon rack in the 'q' mode.
This script is part of a group of related fixes to make the armory storage
work again. The existing issues are:
@@ -2907,7 +2929,9 @@ work again. The existing issues are:
beds/boxes/armor stands and individual squad members, but nothing in
the game does this. This issue is what this script addresses.
- Even if assigned by the script, the game will unassign the racks again without a binary patch.
-Check the comments for this bug to get it:
+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
- Haulers still take equpment stored in the armory away to the stockpiles,
unless the fix-armory plugin above is used.
@@ -2918,7 +2942,7 @@ the intended user.
-
+
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.
@@ -2929,20 +2953,20 @@ technical challenge, and do not represent any long-term plans to produce more
similar modifications of the game.
-
+
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
just stones.
-
+
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,
e.g. like making siegers bring their own, are something only Toady can do.
-
+
The configuration front-end to the plugin is implemented by the gui/siege-engine
script. Bind it to a key and activate after selecting a siege engine in 'q' mode.
The main mode displays the current target, selected ammo item type, linked stockpiles and
@@ -2963,7 +2987,7 @@ menu.
-
+
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.
The configuration front-end is implemented by the gui/power-meter script. Bind it to a
@@ -2972,11 +2996,11 @@ key and activate after selecting Pressure Plate in the build menu.
configuration page, but configures parameters relevant to the modded power meter building.
-
+
The steam-engine plugin detects custom workshops with STEAM_ENGINE in
their token, and turns them into real steam engines.
-
+
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
@@ -2987,7 +3011,7 @@ it can be done just by combining existing features of the game engine
in a new way with some glue code and a bit of custom logic.
-
+
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.
@@ -3011,7 +3035,7 @@ short axles that can be built later than both of the engines.
-
+
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
@@ -3042,7 +3066,7 @@ decrease it by further 4%, and also decrease the whole steam
use rate by 10%.
-
+
The engine must be constructed using barrel, pipe and piston
from fire-safe, or in the magma version magma-safe metals.
During operation weak parts get gradually worn out, and
@@ -3051,7 +3075,7 @@ toppled during operation by a building destroyer, or a
tantruming dwarf.
-
+
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
@@ -3062,7 +3086,7 @@ being generated.
-
+
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
diff --git a/Readme.rst b/Readme.rst
index 66f4017c7..ed2fe3ee8 100644
--- a/Readme.rst
+++ b/Readme.rst
@@ -1103,7 +1103,7 @@ fix-armory
Enables a fix for storage of squad equipment in barracks.
-Specifically, it prevents your haulers from moving that equipment
+Specifically, it prevents your haulers from moving squad equipment
to stockpiles, and instead queues jobs to store it on weapon racks,
armor stands, and in containers.
@@ -1113,9 +1113,10 @@ armor stands, and in containers.
manually assigned to a squad. See documentation for ``gui/assign-rack``
below.
- Also, the default capacity of armor stands is way too low, so check out
+ 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 a patch addressing that too.
+ for more information about the bugs.
Note that the buildings in the armory are used as follows:
@@ -2165,7 +2166,9 @@ work again. The existing issues are:
the game does this. This issue is what this script addresses.
* Even if assigned by the script, **the game will unassign the racks again without a binary patch**.
- Check the comments for this bug to get it:
+ 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
* Haulers still take equpment stored in the armory away to the stockpiles,
diff --git a/library/lua/binpatch.lua b/library/lua/binpatch.lua
new file mode 100644
index 000000000..e957148f7
--- /dev/null
+++ b/library/lua/binpatch.lua
@@ -0,0 +1,121 @@
+-- Simple binary patch with IDA dif file support.
+
+local function load_patch(name)
+ local filename = name
+ if not string.match(filename, '[./\\]') then
+ filename = dfhack.getHackPath()..'/patches/'..dfhack.getDFVersion()..'/'..name..'.dif'
+ end
+
+ local file, err = io.open(filename, 'r')
+ if not file then
+ if string.match(err, ': No such file or directory') then
+ return nil, 'patch not found'
+ end
+ end
+
+ local old_bytes = {}
+ local new_bytes = {}
+
+ for line in file:lines() do
+ if string.match(line, '^%x+:') then
+ local offset, oldv, newv = string.match(line, '^(%x+):%s*(%x+)%s+(%x+)%s*$')
+ if not offset then
+ file:close()
+ return nil, 'could not parse: '..line
+ end
+
+ offset, oldv, newv = tonumber(offset,16), tonumber(oldv,16), tonumber(newv,16)
+ if oldv > 255 or newv > 255 then
+ file:close()
+ return nil, 'invalid byte values: '..line
+ end
+
+ old_bytes[offset] = oldv
+ new_bytes[offset] = newv
+ end
+ end
+
+ return { name = name, old_bytes = old_bytes, new_bytes = new_bytes }
+end
+
+local function rebase_table(input)
+ local output = {}
+ local base = dfhack.internal.getImageBase()
+ for k,v in pairs(input) do
+ local offset = dfhack.internal.adjustOffset(k)
+ if not offset then
+ return nil, string.format('invalid offset: %x', k)
+ end
+ output[base + offset] = v
+ end
+ return output
+end
+
+local function rebase_patch(patch)
+ local nold, err = rebase_table(patch.old_bytes)
+ if not nold then return nil, err end
+ local nnew, err = rebase_table(patch.new_bytes)
+ if not nnew then return nil, err end
+ return { name = patch.name, old_bytes = nold, new_bytes = nnew }
+end
+
+BinaryPatch = defclass(BinaryPatch)
+
+BinaryPatch.ATTRS {
+ name = DEFAULT_NIL,
+ old_bytes = DEFAULT_NIL,
+ new_bytes = DEFAULT_NIL,
+}
+
+function load_dif_file(name)
+ local patch, err = load_patch(name)
+ if not patch then return nil, err end
+
+ local rpatch, err = rebase_patch(patch)
+ if not rpatch then return nil, err end
+
+ return BinaryPatch(rpatch)
+end
+
+function BinaryPatch:status()
+ local old_ok, err, addr = dfhack.internal.patchBytes({}, self.old_bytes)
+ if old_ok then
+ return 'removed'
+ elseif dfhack.internal.patchBytes({}, self.new_bytes) then
+ return 'applied'
+ else
+ return 'conflict', addr
+ end
+end
+
+function BinaryPatch:isApplied()
+ return dfhack.internal.patchBytes({}, self.new_bytes)
+end
+
+function BinaryPatch:apply()
+ local ok, err, addr = dfhack.internal.patchBytes(self.new_bytes, self.old_bytes)
+ if ok then
+ return true, 'applied the patch'
+ elseif dfhack.internal.patchBytes({}, self.new_bytes) then
+ return true, 'patch is already applied'
+ else
+ return false, string.format('conflict at address %x', addr)
+ end
+end
+
+function BinaryPatch:isRemoved()
+ return dfhack.internal.patchBytes({}, self.old_bytes)
+end
+
+function BinaryPatch:remove()
+ local ok, err, addr = dfhack.internal.patchBytes(self.old_bytes, self.new_bytes)
+ if ok then
+ return true, 'removed the patch'
+ elseif dfhack.internal.patchBytes({}, self.old_bytes) then
+ return true, 'patch is already removed'
+ else
+ return false, string.format('conflict at address %x', addr)
+ end
+end
+
+return _ENV
diff --git a/scripts/binpatch.lua b/scripts/binpatch.lua
index f0f14e929..b9a4cf0b1 100644
--- a/scripts/binpatch.lua
+++ b/scripts/binpatch.lua
@@ -1,109 +1,36 @@
-- Apply or remove binary patches at runtime.
-local utils = require('utils')
-
-function load_patch(name)
- local filename = name
- local auto = false
- if not string.match(filename, '[./\\]') then
- auto = true
- filename = dfhack.getHackPath()..'/patches/'..dfhack.getDFVersion()..'/'..name..'.dif'
- end
-
- local file, err = io.open(filename, 'r')
- if not file then
- if auto and string.match(err, ': No such file or directory') then
- return nil, 'no patch '..name..' for '..dfhack.getDFVersion()
- else
- return nil, err
- end
- end
-
- local old_bytes = {}
- local new_bytes = {}
-
- for line in file:lines() do
- if string.match(line, '^%x+:') then
- local offset, oldv, newv = string.match(line, '^(%x+):%s*(%x+)%s+(%x+)%s*$')
- if not offset then
- file:close()
- return nil, 'Could not parse: '..line
- end
-
- offset, oldv, newv = tonumber(offset,16), tonumber(oldv,16), tonumber(newv,16)
- if oldv > 255 or newv > 255 then
- file:close()
- return nil, 'Invalid byte values: '..line
- end
-
- old_bytes[offset] = oldv
- new_bytes[offset] = newv
- end
- end
-
- return { name = name, old_bytes = old_bytes, new_bytes = new_bytes }
-end
-
-function rebase_table(input)
- local output = {}
- local base = dfhack.internal.getImageBase()
- for k,v in pairs(input) do
- local offset = dfhack.internal.adjustOffset(k)
- if not offset then
- return nil, string.format('invalid offset: %x', k)
- end
- output[base + offset] = v
- end
- return output
-end
-
-function rebase_patch(patch)
- local nold, err = rebase_table(patch.old_bytes)
- if not nold then return nil, err end
- local nnew, err = rebase_table(patch.new_bytes)
- if not nnew then return nil, err end
- return { name = patch.name, old_bytes = nold, new_bytes = nnew }
-end
+local bp = require('binpatch')
function run_command(cmd,name)
- local patch, err = load_patch(name)
- if not patch then
- dfhack.printerr('Could not load: '..err)
- return
- end
+ local pfix = name..': '
- local rpatch, err = rebase_patch(patch)
- if not rpatch then
- dfhack.printerr(name..': '..err)
+ local patch, err = bp.load_dif_file(name)
+ if not patch then
+ dfhack.printerr(pfix..err)
return
end
if cmd == 'check' then
- local old_ok, err, addr = dfhack.internal.patchBytes({}, rpatch.old_bytes)
- if old_ok then
- print(name..': patch is not applied.')
- elseif dfhack.internal.patchBytes({}, rpatch.new_bytes) then
- print(name..': patch is applied.')
+ local status, addr = patch:status()
+ if status == 'conflict' then
+ dfhack.printerr(string.format('%sconflict at address %x', pfix, addr))
else
- dfhack.printerr(string.format('%s: conflict at address %x', name, addr))
+ print(pfix..'patch is '..status)
end
elseif cmd == 'apply' then
- local ok, err, addr = dfhack.internal.patchBytes(rpatch.new_bytes, rpatch.old_bytes)
+ local ok, msg = patch:apply()
if ok then
- print(name..': applied the patch.')
- elseif dfhack.internal.patchBytes({}, rpatch.new_bytes) then
- print(name..': patch is already applied.')
+ print(pfix..msg)
else
- dfhack.printerr(string.format('%s: conflict at address %x', name, addr))
+ dfhack.printerr(pfix..msg)
end
elseif cmd == 'remove' then
- local ok, err, addr = dfhack.internal.patchBytes(rpatch.old_bytes, rpatch.new_bytes)
+ local ok, msg = patch:remove()
if ok then
- print(name..': removed the patch.')
- elseif dfhack.internal.patchBytes({}, rpatch.old_bytes) then
- print(name..': patch is already removed.')
+ print(pfix..msg)
else
- dfhack.printerr(string.format('%s: conflict at address %x', name, addr))
+ dfhack.printerr(pfix..msg)
end
else
qerror('Invalid command: '..cmd)
diff --git a/scripts/gui/assign-rack.lua b/scripts/gui/assign-rack.lua
index d358dfff1..92535d793 100644
--- a/scripts/gui/assign-rack.lua
+++ b/scripts/gui/assign-rack.lua
@@ -1,19 +1,13 @@
--- Assign weapon racks to squads. Requires patch from bug 1445.
+-- Assign weapon racks to squads. Requires the weaponrack-unassign patch.
---[[
-
- Required patches:
-
- v0.34.11 linux: http://pastebin.com/mt5EUgFZ
- v0.34.11 windows: http://pastebin.com/09nRCybe
-
-]]
+-- See bug 1445 for more info about the patches.
local utils = require 'utils'
local gui = require 'gui'
local guidm = require 'gui.dwarfmode'
local widgets = require 'gui.widgets'
local dlg = require 'gui.dialogs'
+local bp = require 'binpatch'
AssignRack = defclass(AssignRack, guidm.MenuOverlay)
@@ -190,12 +184,18 @@ end
AssignRack{ building = dfhack.gui.getSelectedBuilding() }:show()
-if not already_warned then
- already_warned = true
+if not already_patched then
+ local patch = bp.load_dif_file('weaponrack-unassign')
+ if patch and patch:isApplied() then
+ already_patched = true
+ end
+end
+
+if not already_patched then
dlg.showMessage(
'BUG ALERT',
- { 'This script requires a binary patch from', NEWLINE,
- 'bug 1445 on the tracker. Otherwise the game', NEWLINE,
+ { 'This script requires applying the binary patch', NEWLINE,
+ 'named weaponrack-unassign. Otherwise the game', NEWLINE,
'will lose your settings due to a bug.' },
COLOR_YELLOW
)
From bd75cad508859ecb4f0d35000803de293d62cb3b Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Mon, 12 Nov 2012 12:48:17 +0400
Subject: [PATCH 051/158] Support ! and ~ prefixes in the lua script, and edit
readme.
---
Readme.html | 23 +++++++++++++++--------
Readme.rst | 23 +++++++++++++++++++----
scripts/lua.lua | 31 +++++++++++++++++++++++++------
3 files changed, 59 insertions(+), 18 deletions(-)
diff --git a/Readme.html b/Readme.html
index b7ca94964..c596371e7 100644
--- a/Readme.html
+++ b/Readme.html
@@ -2734,15 +2734,22 @@ the creature.
-
-- There are three ways to invoke this command:
-
-- without any parameters - starts an interactive lua interpreter
-- -f "filename" or --file "filename" - loads and runs the file indicated by filename
-- -s ["filename"] or --save ["filename"] - loads and runs the file indicated by filename from save directory. If filename is not supplied it loads "dfhack.lua"
+There are the following ways to invoke this command:
+
+lua (without any parameters)
+This starts an interactive lua interpreter.
+
+lua -f "filename" or lua --file "filename"
+This loads and runs the file indicated by filename.
+
+lua -s ["filename"] or lua --save ["filename"]
+This loads and runs the file indicated by filename from the save
+directory. If the filename is not supplied, it loads "dfhack.lua".
+
+:lua lua statement...
+Parses and executes the lua statement like the interactive interpreter would.
+
-
-
diff --git a/Readme.rst b/Readme.rst
index ed2fe3ee8..009d82d77 100644
--- a/Readme.rst
+++ b/Readme.rst
@@ -1922,10 +1922,25 @@ the creature.
lua
===
-There are three ways to invoke this command:
- 1. without any parameters - starts an interactive lua interpreter
- 2. -f "filename" or --file "filename" - loads and runs the file indicated by filename
- 3. -s ["filename"] or --save ["filename"] - loads and runs the file indicated by filename from save directory. If filename is not supplied it loads "dfhack.lua"
+
+There are the following ways to invoke this command:
+
+1. ``lua`` (without any parameters)
+
+ This starts an interactive lua interpreter.
+
+2. ``lua -f "filename"`` or ``lua --file "filename"``
+
+ This loads and runs the file indicated by filename.
+
+3. ``lua -s ["filename"]`` or ``lua --save ["filename"]``
+
+ This loads and runs the file indicated by filename from the save
+ directory. If the filename is not supplied, it loads "dfhack.lua".
+
+4. ``:lua`` *lua statement...*
+
+ Parses and executes the lua statement like the interactive interpreter would.
embark
======
diff --git a/scripts/lua.lua b/scripts/lua.lua
index 556962347..9bf6ce793 100644
--- a/scripts/lua.lua
+++ b/scripts/lua.lua
@@ -1,11 +1,15 @@
+-- Execute lua commands interactively or from files.
+
local args={...}
-if args[1]=="--file" or args[1]=="-f" then
+local cmd = args[1]
+
+if cmd=="--file" or cmd=="-f" then
local f,err=loadfile (args[2])
if f==nil then
qerror(err)
end
dfhack.pcall(f,table.unpack(args,3))
-elseif args[1]=="--save" or args[1]=="-s" then
+elseif cmd=="--save" or cmd=="-s" then
if df.global.world.cur_savegame.save_dir=="" then
qerror("Savefile not loaded")
end
@@ -16,12 +20,27 @@ elseif args[1]=="--save" or args[1]=="-s" then
qerror(err)
end
dfhack.pcall(f,table.unpack(args,3))
-elseif args[1]~=nil then
- local f,err=load(args[1],'=(lua command)', 't')
+elseif cmd~=nil then
+ -- Support some of the prefixes allowed by dfhack.interpreter
+ local prefix
+ if string.match(cmd, "^[~!]") then
+ prefix = string.sub(cmd, 1, 1)
+ cmd = 'return '..string.sub(cmd, 2)
+ end
+
+ local f,err=load(cmd,'=(lua command)', 't')
if f==nil then
qerror(err)
end
- dfhack.pcall(f,table.unpack(args,2))
+
+ local rv = table.pack(dfhack.safecall(f,table.unpack(args,2)))
+
+ if rv[1] and prefix then
+ print(table.unpack(rv,2,rv.n))
+ if prefix == '~' then
+ printall(rv[2])
+ end
+ end
else
dfhack.interpreter("lua","lua.history")
-end
\ No newline at end of file
+end
From 766aca4911d72b4b6724c20e37e50fd5280b2e46 Mon Sep 17 00:00:00 2001
From: Quietust
Date: Mon, 12 Nov 2012 08:27:58 -0600
Subject: [PATCH 052/158] Rename general_ref vectors for consistency
---
library/modules/Buildings.cpp | 4 ++--
library/modules/Items.cpp | 42 +++++++++++++++++------------------
library/modules/Job.cpp | 22 +++++++++---------
library/modules/Units.cpp | 10 ++++-----
library/xml | 2 +-
plugins/advtools.cpp | 8 +++----
plugins/autodump.cpp | 4 ++--
plugins/autolabor.cpp | 8 +++----
plugins/devel/stockcheck.cpp | 8 +++----
plugins/devel/stripcaged.cpp | 4 ++--
plugins/fix-armory.cpp | 4 ++--
plugins/ruby/building.rb | 4 ++--
plugins/showmood.cpp | 4 ++--
plugins/workflow.cpp | 8 +++----
plugins/zone.cpp | 38 +++++++++++++++----------------
15 files changed, 85 insertions(+), 85 deletions(-)
diff --git a/library/modules/Buildings.cpp b/library/modules/Buildings.cpp
index 6421114a1..ca6cb2c17 100644
--- a/library/modules/Buildings.cpp
+++ b/library/modules/Buildings.cpp
@@ -1,4 +1,4 @@
-/*
+/*
https://github.com/peterix/dfhack
Copyright (c) 2009-2012 Petr Mrázek (peterix@gmail.com)
@@ -895,7 +895,7 @@ static bool linkForConstruct(df::job* &job, df::building *bld)
job = new df::job();
job->job_type = df::job_type::ConstructBuilding;
job->pos = df::coord(bld->centerx, bld->centery, bld->z);
- job->references.push_back(ref);
+ job->general_refs.push_back(ref);
bld->jobs.push_back(job);
diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp
index 877f8abe0..4045e6baa 100644
--- a/library/modules/Items.cpp
+++ b/library/modules/Items.cpp
@@ -1,4 +1,4 @@
-/*
+/*
https://github.com/peterix/dfhack
Copyright (c) 2009-2012 Petr Mrázek (peterix@gmail.com)
@@ -509,7 +509,7 @@ df::general_ref *Items::getGeneralRef(df::item *item, df::general_ref_type type)
{
CHECK_NULL_POINTER(item);
- return findRef(item->itemrefs, type);
+ return findRef(item->general_refs, type);
}
df::specific_ref *Items::getSpecificRef(df::item *item, df::specific_ref_type type)
@@ -530,9 +530,9 @@ bool Items::setOwner(df::item *item, df::unit *unit)
{
CHECK_NULL_POINTER(item);
- for (int i = item->itemrefs.size()-1; i >= 0; i--)
+ for (int i = item->general_refs.size()-1; i >= 0; i--)
{
- df::general_ref *ref = item->itemrefs[i];
+ df::general_ref *ref = item->general_refs[i];
if (!strict_virtual_cast(ref))
continue;
@@ -546,7 +546,7 @@ bool Items::setOwner(df::item *item, df::unit *unit)
}
delete ref;
- vector_erase_at(item->itemrefs, i);
+ vector_erase_at(item->general_refs, i);
}
item->flags.bits.owned = false;
@@ -561,7 +561,7 @@ bool Items::setOwner(df::item *item, df::unit *unit)
ref->unit_id = unit->id;
insert_into_vector(unit->owned_items, item->id);
- item->itemrefs.push_back(ref);
+ item->general_refs.push_back(ref);
}
return true;
@@ -580,9 +580,9 @@ void Items::getContainedItems(df::item *item, std::vector *items)
items->clear();
- for (size_t i = 0; i < item->itemrefs.size(); i++)
+ for (size_t i = 0; i < item->general_refs.size(); i++)
{
- df::general_ref *ref = item->itemrefs[i];
+ df::general_ref *ref = item->general_refs[i];
if (ref->getType() != general_ref_type::CONTAINS_ITEM)
continue;
@@ -617,9 +617,9 @@ df::coord Items::getPosition(df::item *item)
if (item->flags.bits.in_inventory)
{
- for (size_t i = 0; i < item->itemrefs.size(); i++)
+ for (size_t i = 0; i < item->general_refs.size(); i++)
{
- df::general_ref *ref = item->itemrefs[i];
+ df::general_ref *ref = item->general_refs[i];
switch (ref->getType())
{
@@ -716,9 +716,9 @@ static bool detachItem(MapExtras::MapCache &mc, df::item *item)
if (item->world_data_id != -1)
return false;
- for (size_t i = 0; i < item->itemrefs.size(); i++)
+ for (size_t i = 0; i < item->general_refs.size(); i++)
{
- df::general_ref *ref = item->itemrefs[i];
+ df::general_ref *ref = item->general_refs[i];
switch (ref->getType())
{
@@ -748,9 +748,9 @@ static bool detachItem(MapExtras::MapCache &mc, df::item *item)
{
bool found = false;
- for (int i = item->itemrefs.size()-1; i >= 0; i--)
+ for (int i = item->general_refs.size()-1; i >= 0; i--)
{
- df::general_ref *ref = item->itemrefs[i];
+ df::general_ref *ref = item->general_refs[i];
switch (ref->getType())
{
@@ -767,7 +767,7 @@ static bool detachItem(MapExtras::MapCache &mc, df::item *item)
item2->flags.bits.weight_computed = false;
- removeRef(item2->itemrefs, general_ref_type::CONTAINS_ITEM, item->id);
+ removeRef(item2->general_refs, general_ref_type::CONTAINS_ITEM, item->id);
}
break;
@@ -799,7 +799,7 @@ static bool detachItem(MapExtras::MapCache &mc, df::item *item)
}
found = true;
- vector_erase_at(item->itemrefs, i);
+ vector_erase_at(item->general_refs, i);
delete ref;
}
@@ -878,10 +878,10 @@ bool DFHack::Items::moveToContainer(MapExtras::MapCache &mc, df::item *item, df:
container->flags.bits.weight_computed = false;
ref1->item_id = item->id;
- container->itemrefs.push_back(ref1);
+ container->general_refs.push_back(ref1);
ref2->item_id = container->id;
- item->itemrefs.push_back(ref2);
+ item->general_refs.push_back(ref2);
return true;
}
@@ -912,7 +912,7 @@ bool DFHack::Items::moveToBuilding(MapExtras::MapCache &mc, df::item *item, df::
item->flags.bits.in_building=true;
ref->building_id=building->id;
- item->itemrefs.push_back(ref);
+ item->general_refs.push_back(ref);
auto con=new df::building_actual::T_contained_items;
con->item=item;
@@ -955,7 +955,7 @@ bool DFHack::Items::moveToInventory(
unit->inventory.push_back(newInventoryItem);
holderReference->unit_id = unit->id;
- item->itemrefs.push_back(holderReference);
+ item->general_refs.push_back(holderReference);
resetUnitInvFlags(unit, newInventoryItem);
@@ -1016,7 +1016,7 @@ df::proj_itemst *Items::makeProjectile(MapExtras::MapCache &mc, df::item *item)
proj->item = item;
ref->projectile_id = proj->id;
- item->itemrefs.push_back(ref);
+ item->general_refs.push_back(ref);
linked_list_append(&world->proj_list, proj->link);
diff --git a/library/modules/Job.cpp b/library/modules/Job.cpp
index 757000885..db0fd73fe 100644
--- a/library/modules/Job.cpp
+++ b/library/modules/Job.cpp
@@ -1,4 +1,4 @@
-/*
+/*
https://github.com/peterix/dfhack
Copyright (c) 2009-2012 Petr Mrázek (peterix@gmail.com)
@@ -71,14 +71,14 @@ df::job *DFHack::Job::cloneJobStruct(df::job *job)
pnew->specific_refs.clear();
// Clone refs
- for (int i = pnew->references.size()-1; i >= 0; i--)
+ for (int i = pnew->general_refs.size()-1; i >= 0; i--)
{
- df::general_ref *ref = pnew->references[i];
+ df::general_ref *ref = pnew->general_refs[i];
if (virtual_cast(ref))
- vector_erase_at(pnew->references, i);
+ vector_erase_at(pnew->general_refs, i);
else
- pnew->references[i] = ref->clone();
+ pnew->general_refs[i] = ref->clone();
}
// Clone items
@@ -96,8 +96,8 @@ void DFHack::Job::deleteJobStruct(df::job *job)
// Only allow free-floating job structs
assert(!job->list_link && job->items.empty() && job->specific_refs.empty());
- for (int i = job->references.size()-1; i >= 0; i--)
- delete job->references[i];
+ for (int i = job->general_refs.size()-1; i >= 0; i--)
+ delete job->general_refs[i];
for (int i = job->job_items.size()-1; i >= 0; i--)
delete job->job_items[i];
@@ -232,9 +232,9 @@ df::building *DFHack::Job::getHolder(df::job *job)
{
CHECK_NULL_POINTER(job);
- for (size_t i = 0; i < job->references.size(); i++)
+ for (size_t i = 0; i < job->general_refs.size(); i++)
{
- VIRTUAL_CAST_VAR(ref, df::general_ref_building_holderst, job->references[i]);
+ VIRTUAL_CAST_VAR(ref, df::general_ref_building_holderst, job->general_refs[i]);
if (ref)
return ref->getBuilding();
}
@@ -246,9 +246,9 @@ df::unit *DFHack::Job::getWorker(df::job *job)
{
CHECK_NULL_POINTER(job);
- for (size_t i = 0; i < job->references.size(); i++)
+ for (size_t i = 0; i < job->general_refs.size(); i++)
{
- VIRTUAL_CAST_VAR(ref, df::general_ref_unit_workerst, job->references[i]);
+ VIRTUAL_CAST_VAR(ref, df::general_ref_unit_workerst, job->general_refs[i]);
if (ref)
return ref->getUnit();
}
diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp
index 7a0a7549b..aa0459d08 100644
--- a/library/modules/Units.cpp
+++ b/library/modules/Units.cpp
@@ -1,4 +1,4 @@
-/*
+/*
https://github.com/peterix/dfhack
Copyright (c) 2009-2012 Petr Mrázek (peterix@gmail.com)
@@ -523,9 +523,9 @@ df::item *Units::getContainer(df::unit *unit)
{
CHECK_NULL_POINTER(unit);
- for (size_t i = 0; i < unit->refs.size(); i++)
+ for (size_t i = 0; i < unit->general_refs.size(); i++)
{
- df::general_ref *ref = unit->refs[i];
+ df::general_ref *ref = unit->general_refs[i];
if (ref->getType() == general_ref_type::CONTAINED_IN_ITEM)
return ref->getItem();
}
@@ -607,9 +607,9 @@ df::nemesis_record *Units::getNemesis(df::unit *unit)
if (!unit)
return NULL;
- for (unsigned i = 0; i < unit->refs.size(); i++)
+ for (unsigned i = 0; i < unit->general_refs.size(); i++)
{
- df::nemesis_record *rv = unit->refs[i]->getNemesis();
+ df::nemesis_record *rv = unit->general_refs[i]->getNemesis();
if (rv && rv->unit == unit)
return rv;
}
diff --git a/library/xml b/library/xml
index 4b2124957..327a9662b 160000
--- a/library/xml
+++ b/library/xml
@@ -1 +1 @@
-Subproject commit 4b2124957e282683480eaf05922e63c353364ec1
+Subproject commit 327a9662be81627ebcbb3aea11ffbca3e536b7ee
diff --git a/plugins/advtools.cpp b/plugins/advtools.cpp
index 59b88087b..5ceea69c8 100644
--- a/plugins/advtools.cpp
+++ b/plugins/advtools.cpp
@@ -331,7 +331,7 @@ typedef std::pair inv_item;
static void listContainerInventory(std::vector *list, df::item *container)
{
- auto &refs = container->itemrefs;
+ auto &refs = container->general_refs;
for (size_t i = 0; i < refs.size(); i++)
{
auto ref = refs[i];
@@ -372,9 +372,9 @@ void listUnitInventory(std::vector *list, df::unit *unit)
bool isShopItem(df::item *item)
{
- for (size_t k = 0; k < item->itemrefs.size(); k++)
+ for (size_t k = 0; k < item->general_refs.size(); k++)
{
- auto ref = item->itemrefs[k];
+ auto ref = item->general_refs[k];
if (virtual_cast(ref))
return true;
}
@@ -404,7 +404,7 @@ int containsMetalItems(df::item *item, bool all, bool non_trader, bool rec = fal
{
int cnt = 0;
- auto &refs = item->itemrefs;
+ auto &refs = item->general_refs;
for (size_t i = 0; i < refs.size(); i++)
{
auto ref = refs[i];
diff --git a/plugins/autodump.cpp b/plugins/autodump.cpp
index cfb73fa8b..5eb25964e 100644
--- a/plugins/autodump.cpp
+++ b/plugins/autodump.cpp
@@ -277,9 +277,9 @@ command_result df_autodump_destroy_item(color_ostream &out, vector & pa
return CR_FAILURE;
}
- for (size_t i = 0; i < item->itemrefs.size(); i++)
+ for (size_t i = 0; i < item->general_refs.size(); i++)
{
- df::general_ref *ref = item->itemrefs[i];
+ df::general_ref *ref = item->general_refs[i];
if (ref->getType() == general_ref_type::UNIT_HOLDER)
{
out.printerr("Choosing not to destroy items in unit inventory.\n");
diff --git a/plugins/autolabor.cpp b/plugins/autolabor.cpp
index 44984cfdb..4ee5c0a54 100644
--- a/plugins/autolabor.cpp
+++ b/plugins/autolabor.cpp
@@ -1582,9 +1582,9 @@ static int stockcheck(color_ostream &out, vector & parameters)
df::unit *holder = 0;
df::building *building = 0;
- for (size_t i = 0; i < item->itemrefs.size(); i++)
+ for (size_t i = 0; i < item->general_refs.size(); i++)
{
- df::general_ref *ref = item->itemrefs[i];
+ df::general_ref *ref = item->general_refs[i];
switch (ref->getType())
{
@@ -1611,9 +1611,9 @@ static int stockcheck(color_ostream &out, vector & parameters)
while(nextcontainer) {
df::item *thiscontainer = nextcontainer;
nextcontainer = 0;
- for (size_t i = 0; i < thiscontainer->itemrefs.size(); i++)
+ for (size_t i = 0; i < thiscontainer->general_refs.size(); i++)
{
- df::general_ref *ref = thiscontainer->itemrefs[i];
+ df::general_ref *ref = thiscontainer->general_refs[i];
switch (ref->getType())
{
diff --git a/plugins/devel/stockcheck.cpp b/plugins/devel/stockcheck.cpp
index 452a637fc..57be4b126 100644
--- a/plugins/devel/stockcheck.cpp
+++ b/plugins/devel/stockcheck.cpp
@@ -170,9 +170,9 @@ static command_result stockcheck(color_ostream &out, vector & parameter
df::unit *holder = 0;
df::building *building = 0;
- for (size_t i = 0; i < item->itemrefs.size(); i++)
+ for (size_t i = 0; i < item->general_refs.size(); i++)
{
- df::general_ref *ref = item->itemrefs[i];
+ df::general_ref *ref = item->general_refs[i];
switch (ref->getType())
{
@@ -199,9 +199,9 @@ static command_result stockcheck(color_ostream &out, vector & parameter
while(nextcontainer) {
df::item *thiscontainer = nextcontainer;
nextcontainer = 0;
- for (size_t i = 0; i < thiscontainer->itemrefs.size(); i++)
+ for (size_t i = 0; i < thiscontainer->general_refs.size(); i++)
{
- df::general_ref *ref = thiscontainer->itemrefs[i];
+ df::general_ref *ref = thiscontainer->general_refs[i];
switch (ref->getType())
{
diff --git a/plugins/devel/stripcaged.cpp b/plugins/devel/stripcaged.cpp
index e3d2a82fc..a7683a9bb 100644
--- a/plugins/devel/stripcaged.cpp
+++ b/plugins/devel/stripcaged.cpp
@@ -46,9 +46,9 @@ DFHACK_PLUGIN("stripcaged");
bool isContainedInItem(df::unit* unit)
{
bool contained = false;
- for (size_t r=0; r < unit->refs.size(); r++)
+ for (size_t r=0; r < unit->general_refs.size(); r++)
{
- df::general_ref * ref = unit->refs[r];
+ df::general_ref * ref = unit->general_refs[r];
auto rtype = ref->getType();
if(rtype == df::general_ref_type::CONTAINED_IN_ITEM)
{
diff --git a/plugins/fix-armory.cpp b/plugins/fix-armory.cpp
index 99e5fd500..efa9350ff 100644
--- a/plugins/fix-armory.cpp
+++ b/plugins/fix-armory.cpp
@@ -528,7 +528,7 @@ static bool try_store_item(df::building *target, df::item *item)
// job <-> building link
href->building_id = target->id;
target->jobs.push_back(job);
- job->references.push_back(href);
+ job->general_refs.push_back(href);
// Two of the jobs need this link to find the job in canStoreItem().
// They also don't actually need BUILDING_HOLDER, but it doesn't hurt.
@@ -539,7 +539,7 @@ static bool try_store_item(df::building *target, df::item *item)
if (rdest)
{
rdest->building_id = target->id;
- job->references.push_back(rdest);
+ job->general_refs.push_back(rdest);
}
}
diff --git a/plugins/ruby/building.rb b/plugins/ruby/building.rb
index e863ec5d5..37b91d166 100644
--- a/plugins/ruby/building.rb
+++ b/plugins/ruby/building.rb
@@ -275,7 +275,7 @@ module DFHack
job = Job.cpp_new
job.job_type = :ConstructBuilding
job.pos = [bld.centerx, bld.centery, bld.z]
- job.references << ref
+ job.general_refs << ref
bld.jobs << job
job_link job
job
@@ -346,7 +346,7 @@ module DFHack
refbuildingholder = GeneralRefBuildingHolderst.cpp_new
job.job_type = :DestroyBuilding
refbuildingholder.building_id = bld.id
- job.references << refbuildingholder
+ job.general_refs << refbuildingholder
bld.jobs << job
job_link job
job
diff --git a/plugins/showmood.cpp b/plugins/showmood.cpp
index 0b3fa8a99..7a3662f82 100644
--- a/plugins/showmood.cpp
+++ b/plugins/showmood.cpp
@@ -49,9 +49,9 @@ command_result df_showmood (color_ostream &out, vector & parameters)
found = true;
df::unit *unit = NULL;
df::building *building = NULL;
- for (size_t i = 0; i < job->references.size(); i++)
+ for (size_t i = 0; i < job->general_refs.size(); i++)
{
- df::general_ref *ref = job->references[i];
+ df::general_ref *ref = job->general_refs[i];
if (ref->getType() == general_ref_type::UNIT_WORKER)
unit = ref->getUnit();
if (ref->getType() == general_ref_type::BUILDING_HOLDER)
diff --git a/plugins/workflow.cpp b/plugins/workflow.cpp
index 04e3c13b0..6ba45cfd3 100644
--- a/plugins/workflow.cpp
+++ b/plugins/workflow.cpp
@@ -974,9 +974,9 @@ static void map_job_constraints(color_ostream &out)
static void dryBucket(df::item *item)
{
- for (size_t i = 0; i < item->itemrefs.size(); i++)
+ for (size_t i = 0; i < item->general_refs.size(); i++)
{
- df::general_ref *ref = item->itemrefs[i];
+ df::general_ref *ref = item->general_refs[i];
if (ref->getType() == general_ref_type::CONTAINS_ITEM)
{
df::item *obj = ref->getItem();
@@ -996,9 +996,9 @@ static bool itemBusy(df::item *item)
{
using namespace df::enums::item_type;
- for (size_t i = 0; i < item->itemrefs.size(); i++)
+ for (size_t i = 0; i < item->general_refs.size(); i++)
{
- df::general_ref *ref = item->itemrefs[i];
+ df::general_ref *ref = item->general_refs[i];
if (ref->getType() == general_ref_type::CONTAINS_ITEM)
{
df::item *obj = ref->getItem();
diff --git a/plugins/zone.cpp b/plugins/zone.cpp
index 2c63b6af7..15d310dc1 100644
--- a/plugins/zone.cpp
+++ b/plugins/zone.cpp
@@ -753,10 +753,10 @@ void unitInfo(color_ostream & out, df::unit* unit, bool verbose = false)
if(!verbose)
return;
- //out << "number of refs: " << creature->refs.size() << endl;
- for(size_t r = 0; rrefs.size(); r++)
+ //out << "number of refs: " << creature->general_refs.size() << endl;
+ for(size_t r = 0; rgeneral_refs.size(); r++)
{
- df::general_ref* ref = unit->refs.at(r);
+ df::general_ref* ref = unit->general_refs.at(r);
df::general_ref_type refType = ref->getType();
out << " ref#" << r <<" refType#" << refType << " "; //endl;
switch(refType)
@@ -975,10 +975,10 @@ df::general_ref_building_civzone_assignedst * createCivzoneRef()
for(size_t i = 0; i < world->units.all.size(); i++)
{
df::unit * creature = world->units.all[i];
- for(size_t r = 0; rrefs.size(); r++)
+ for(size_t r = 0; rgeneral_refs.size(); r++)
{
df::general_ref* ref;
- ref = creature->refs.at(r);
+ ref = creature->general_refs.at(r);
if(ref->getType() == df::general_ref_type::BUILDING_CIVZONE_ASSIGNED)
{
if (strict_virtual_cast(ref))
@@ -1007,9 +1007,9 @@ bool isInBuiltCage(df::unit* unit);
bool isAssigned(df::unit* unit)
{
bool assigned = false;
- for (size_t r=0; r < unit->refs.size(); r++)
+ for (size_t r=0; r < unit->general_refs.size(); r++)
{
- df::general_ref * ref = unit->refs[r];
+ df::general_ref * ref = unit->general_refs[r];
auto rtype = ref->getType();
if( rtype == df::general_ref_type::BUILDING_CIVZONE_ASSIGNED
|| rtype == df::general_ref_type::BUILDING_CAGED
@@ -1029,9 +1029,9 @@ bool isAssigned(df::unit* unit)
bool isChained(df::unit* unit)
{
bool contained = false;
- for (size_t r=0; r < unit->refs.size(); r++)
+ for (size_t r=0; r < unit->general_refs.size(); r++)
{
- df::general_ref * ref = unit->refs[r];
+ df::general_ref * ref = unit->general_refs[r];
auto rtype = ref->getType();
if(rtype == df::general_ref_type::BUILDING_CHAIN)
{
@@ -1046,9 +1046,9 @@ bool isChained(df::unit* unit)
bool isContainedInItem(df::unit* unit)
{
bool contained = false;
- for (size_t r=0; r < unit->refs.size(); r++)
+ for (size_t r=0; r < unit->general_refs.size(); r++)
{
- df::general_ref * ref = unit->refs[r];
+ df::general_ref * ref = unit->general_refs[r];
auto rtype = ref->getType();
if(rtype == df::general_ref_type::CONTAINED_IN_ITEM)
{
@@ -1280,14 +1280,14 @@ size_t countFreeEgglayers()
bool unassignUnitFromBuilding(df::unit* unit)
{
bool success = false;
- for (std::size_t idx = 0; idx < unit->refs.size(); idx++)
+ for (std::size_t idx = 0; idx < unit->general_refs.size(); idx++)
{
- df::general_ref * oldref = unit->refs[idx];
+ df::general_ref * oldref = unit->general_refs[idx];
switch(oldref->getType())
{
case df::general_ref_type::BUILDING_CIVZONE_ASSIGNED:
{
- unit->refs.erase(unit->refs.begin() + idx);
+ unit->general_refs.erase(unit->general_refs.begin() + idx);
df::building_civzonest * oldciv = (df::building_civzonest *) oldref->getBuilding();
for(size_t oc=0; ocassigned_creature.size(); oc++)
{
@@ -1305,7 +1305,7 @@ bool unassignUnitFromBuilding(df::unit* unit)
case df::general_ref_type::CONTAINED_IN_ITEM:
{
// game does not erase the ref until creature gets removed from cage
- //unit->refs.erase(unit->refs.begin() + idx);
+ //unit->general_refs.erase(unit->general_refs.begin() + idx);
// walk through buildings, check cages for inhabitants, compare ids
for (size_t b=0; b < world->buildings.all.size(); b++)
@@ -1335,7 +1335,7 @@ bool unassignUnitFromBuilding(df::unit* unit)
case df::general_ref_type::BUILDING_CHAIN:
{
// try not erasing the ref and see what happens
- //unit->refs.erase(unit->refs.begin() + idx);
+ //unit->general_refs.erase(unit->general_refs.begin() + idx);
// probably need to delete chain reference here
//success = true;
break;
@@ -1344,7 +1344,7 @@ bool unassignUnitFromBuilding(df::unit* unit)
case df::general_ref_type::BUILDING_CAGED:
{
// not sure what to do here, doesn't seem to get used by the game
- //unit->refs.erase(unit->refs.begin() + idx);
+ //unit->general_refs.erase(unit->general_refs.begin() + idx);
//success = true;
break;
}
@@ -1396,7 +1396,7 @@ command_result assignUnitToZone(color_ostream& out, df::unit* unit, df::building
}
ref->building_id = building->id;
- unit->refs.push_back(ref);
+ unit->general_refs.push_back(ref);
df::building_civzonest * civz = (df::building_civzonest *) building;
civz->assigned_creature.push_back(unit->id);
@@ -1437,7 +1437,7 @@ command_result assignUnitToCage(color_ostream& out, df::unit* unit, df::building
}
//ref->building_id = building->id;
- //unit->refs.push_back(ref);
+ //unit->general_refs.push_back(ref);
df::building_cagest* civz = (df::building_cagest*) building;
civz->assigned_creature.push_back(unit->id);
From 7a3de785ec534fd14055befb36dc8d29e630e625 Mon Sep 17 00:00:00 2001
From: Quietust
Date: Mon, 12 Nov 2012 08:29:44 -0600
Subject: [PATCH 053/158] Missed a few spots
---
scripts/growcrops.rb | 4 ++--
scripts/gui/companion-order.lua | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/scripts/growcrops.rb b/scripts/growcrops.rb
index e3abe54ac..c591dff87 100644
--- a/scripts/growcrops.rb
+++ b/scripts/growcrops.rb
@@ -17,7 +17,7 @@ end
inventory = Hash.new(0)
df.world.items.other[:SEEDS].each { |seed|
next if not seed.flags.in_building
- next if not seed.itemrefs.find { |ref| ref._rtti_classname == :general_ref_building_holderst }
+ 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
}
@@ -40,7 +40,7 @@ else
df.world.items.other[:SEEDS].each { |seed|
next if seed.mat_index != wantmat
next if not seed.flags.in_building
- next if not seed.itemrefs.find { |ref| ref._rtti_classname == :general_ref_building_holderst }
+ 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
diff --git a/scripts/gui/companion-order.lua b/scripts/gui/companion-order.lua
index b9e3b8300..68bc7ab39 100644
--- a/scripts/gui/companion-order.lua
+++ b/scripts/gui/companion-order.lua
@@ -359,7 +359,7 @@ end},
v.riding_item_id=item.id
local ref=df.general_ref_unit_riderst:new()
ref.unit_id=v.id
- item.itemrefs:insert("#",ref)
+ item.general_refs:insert("#",ref)
end
return true
end},
From 55fcb7e3cade121bfb5455e7d4416b5e849c123f Mon Sep 17 00:00:00 2001
From: Quietust
Date: Mon, 12 Nov 2012 08:33:05 -0600
Subject: [PATCH 054/158] One more missed
---
plugins/lua/dfusion/tools.lua | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plugins/lua/dfusion/tools.lua b/plugins/lua/dfusion/tools.lua
index f1fdadf2b..3e24c169d 100644
--- a/plugins/lua/dfusion/tools.lua
+++ b/plugins/lua/dfusion/tools.lua
@@ -145,7 +145,7 @@ function project(unit,trg) --TODO add to menu?
citem.next=newlink
local proj_ref=df.general_ref_projectile:new()
proj_ref.projectile_id=p.id
- unit.refs:insert(#unit.refs,proj_ref)
+ unit.general_refs:insert(#unit.general_refs,proj_ref)
unit.flags1.projectile=true
end
function empregnate(unit)
From a99d47ee7a2ccbd8ebecac5fafb8803510d672fd Mon Sep 17 00:00:00 2001
From: Quietust
Date: Mon, 12 Nov 2012 08:38:29 -0600
Subject: [PATCH 055/158] Remove UTF-8 BOMs added by notepad
---
library/modules/Buildings.cpp | 2 +-
library/modules/Items.cpp | 2 +-
library/modules/Job.cpp | 2 +-
library/modules/Units.cpp | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/library/modules/Buildings.cpp b/library/modules/Buildings.cpp
index ca6cb2c17..de121bfa8 100644
--- a/library/modules/Buildings.cpp
+++ b/library/modules/Buildings.cpp
@@ -1,4 +1,4 @@
-/*
+/*
https://github.com/peterix/dfhack
Copyright (c) 2009-2012 Petr Mrázek (peterix@gmail.com)
diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp
index 4045e6baa..91448ab3f 100644
--- a/library/modules/Items.cpp
+++ b/library/modules/Items.cpp
@@ -1,4 +1,4 @@
-/*
+/*
https://github.com/peterix/dfhack
Copyright (c) 2009-2012 Petr Mrázek (peterix@gmail.com)
diff --git a/library/modules/Job.cpp b/library/modules/Job.cpp
index db0fd73fe..f913a71b6 100644
--- a/library/modules/Job.cpp
+++ b/library/modules/Job.cpp
@@ -1,4 +1,4 @@
-/*
+/*
https://github.com/peterix/dfhack
Copyright (c) 2009-2012 Petr Mrázek (peterix@gmail.com)
diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp
index aa0459d08..d22022914 100644
--- a/library/modules/Units.cpp
+++ b/library/modules/Units.cpp
@@ -1,4 +1,4 @@
-/*
+/*
https://github.com/peterix/dfhack
Copyright (c) 2009-2012 Petr Mrázek (peterix@gmail.com)
From b4dcc7e7adf7c6e1deab4a0a77e0697610c8f6f3 Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Mon, 12 Nov 2012 19:17:32 +0400
Subject: [PATCH 056/158] Add more native api functions for finding general and
specific refs.
---
Lua API.rst | 24 ++++++++++++++++++++++++
library/LuaApi.cpp | 6 ++++++
library/Types.cpp | 18 ++++++++++++++++++
library/include/Types.h | 4 ++++
library/include/modules/Buildings.h | 3 +++
library/include/modules/Job.h | 5 +++++
library/include/modules/Units.h | 3 +++
library/modules/Buildings.cpp | 14 ++++++++++++++
library/modules/Job.cpp | 15 +++++++++++++++
library/modules/Units.cpp | 23 +++++++++++++++--------
10 files changed, 107 insertions(+), 8 deletions(-)
diff --git a/Lua API.rst b/Lua API.rst
index f89750e88..126bc7f9d 100644
--- a/Lua API.rst
+++ b/Lua API.rst
@@ -833,6 +833,14 @@ Job module
Prints info about the job item.
+* ``dfhack.job.getGeneralRef(job, type)``
+
+ Searches for a general_ref with the given type.
+
+* ``dfhack.job.getSpecificRef(job, type)``
+
+ Searches for a specific_ref with the given type.
+
* ``dfhack.job.getHolder(job)``
Returns the building holding the job.
@@ -879,6 +887,14 @@ Units module
Returns true *x,y,z* of the unit, or *nil* if invalid; may be not equal to unit.pos if caged.
+* ``dfhack.units.getGeneralRef(unit, type)``
+
+ Searches for a general_ref with the given type.
+
+* ``dfhack.units.getSpecificRef(unit, type)``
+
+ Searches for a specific_ref with the given type.
+
* ``dfhack.units.getContainer(unit)``
Returns the container (cage) item or *nil*.
@@ -1198,6 +1214,14 @@ Burrows module
Buildings module
----------------
+* ``dfhack.buildings.getGeneralRef(building, type)``
+
+ Searches for a general_ref with the given type.
+
+* ``dfhack.buildings.getSpecificRef(building, type)``
+
+ Searches for a specific_ref with the given type.
+
* ``dfhack.buildings.setOwner(item,unit)``
Replaces the owner of the building. If unit is *nil*, removes ownership.
diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp
index 3862530dd..b186316a8 100644
--- a/library/LuaApi.cpp
+++ b/library/LuaApi.cpp
@@ -1121,6 +1121,8 @@ static const LuaWrapper::FunctionReg dfhack_job_module[] = {
WRAPM(Job,cloneJobStruct),
WRAPM(Job,printItemDetails),
WRAPM(Job,printJobDetails),
+ WRAPM(Job,getGeneralRef),
+ WRAPM(Job,getSpecificRef),
WRAPM(Job,getHolder),
WRAPM(Job,getWorker),
WRAPM(Job,checkBuildingsNow),
@@ -1157,6 +1159,8 @@ static const luaL_Reg dfhack_job_funcs[] = {
/***** Units module *****/
static const LuaWrapper::FunctionReg dfhack_units_module[] = {
+ WRAPM(Units, getGeneralRef),
+ WRAPM(Units, getSpecificRef),
WRAPM(Units, getContainer),
WRAPM(Units, setNickname),
WRAPM(Units, getVisibleName),
@@ -1427,6 +1431,8 @@ static bool buildings_containsTile(df::building *bld, int x, int y, bool room) {
}
static const LuaWrapper::FunctionReg dfhack_buildings_module[] = {
+ WRAPM(Buildings, getGeneralRef),
+ WRAPM(Buildings, getSpecificRef),
WRAPM(Buildings, setOwner),
WRAPM(Buildings, allocInstance),
WRAPM(Buildings, checkFreeTiles),
diff --git a/library/Types.cpp b/library/Types.cpp
index 1ba87f839..80d629934 100644
--- a/library/Types.cpp
+++ b/library/Types.cpp
@@ -100,6 +100,24 @@ bool DFHack::removeRef(std::vector &vec, df::general_ref_type
return false;
}
+df::item *DFHack::findItemRef(std::vector &vec, df::general_ref_type type)
+{
+ auto ref = findRef(vec, type);
+ return ref ? ref->getItem() : NULL;
+}
+
+df::building *DFHack::findBuildingRef(std::vector &vec, df::general_ref_type type)
+{
+ auto ref = findRef(vec, type);
+ return ref ? ref->getBuilding() : NULL;
+}
+
+df::unit *DFHack::findUnitRef(std::vector &vec, df::general_ref_type type)
+{
+ auto ref = findRef(vec, type);
+ return ref ? ref->getUnit() : NULL;
+}
+
df::specific_ref *DFHack::findRef(std::vector &vec, df::specific_ref_type type)
{
for (int i = vec.size()-1; i >= 0; i--)
diff --git a/library/include/Types.h b/library/include/Types.h
index 3b9bf00b6..98dbb7e74 100644
--- a/library/include/Types.h
+++ b/library/include/Types.h
@@ -80,6 +80,10 @@ namespace DFHack
DFHACK_EXPORT df::general_ref *findRef(std::vector &vec, df::general_ref_type type);
DFHACK_EXPORT bool removeRef(std::vector &vec, df::general_ref_type type, int id);
+ DFHACK_EXPORT df::item *findItemRef(std::vector &vec, df::general_ref_type type);
+ DFHACK_EXPORT df::building *findBuildingRef(std::vector &vec, df::general_ref_type type);
+ DFHACK_EXPORT df::unit *findUnitRef(std::vector &vec, df::general_ref_type type);
+
DFHACK_EXPORT df::specific_ref *findRef(std::vector &vec, df::specific_ref_type type);
DFHACK_EXPORT bool removeRef(std::vector &vec, df::specific_ref_type type, void *ptr);
}// namespace DFHack
\ No newline at end of file
diff --git a/library/include/modules/Buildings.h b/library/include/modules/Buildings.h
index 266aadcb8..53852efbb 100644
--- a/library/include/modules/Buildings.h
+++ b/library/include/modules/Buildings.h
@@ -92,6 +92,9 @@ DFHACK_EXPORT bool Read (const uint32_t index, t_building & building);
*/
DFHACK_EXPORT bool ReadCustomWorkshopTypes(std::map & btypes);
+DFHACK_EXPORT df::general_ref *getGeneralRef(df::building *building, df::general_ref_type type);
+DFHACK_EXPORT df::specific_ref *getSpecificRef(df::building *building, df::specific_ref_type type);
+
/**
* Sets the owner unit for the building.
*/
diff --git a/library/include/modules/Job.h b/library/include/modules/Job.h
index 853813073..e33e8717c 100644
--- a/library/include/modules/Job.h
+++ b/library/include/modules/Job.h
@@ -28,6 +28,8 @@ distribution.
#include "Export.h"
#include "Module.h"
+#include "Types.h"
+
#include
#include "DataDefs.h"
@@ -55,6 +57,9 @@ namespace DFHack
DFHACK_EXPORT void printItemDetails(color_ostream &out, df::job_item *item, int idx);
DFHACK_EXPORT void printJobDetails(color_ostream &out, df::job *job);
+ DFHACK_EXPORT df::general_ref *getGeneralRef(df::job *job, df::general_ref_type type);
+ DFHACK_EXPORT df::specific_ref *getSpecificRef(df::job *job, df::specific_ref_type type);
+
DFHACK_EXPORT df::building *getHolder(df::job *job);
DFHACK_EXPORT df::unit *getWorker(df::job *job);
diff --git a/library/include/modules/Units.h b/library/include/modules/Units.h
index ab1a5f63a..93e11afb1 100644
--- a/library/include/modules/Units.h
+++ b/library/include/modules/Units.h
@@ -205,6 +205,9 @@ DFHACK_EXPORT void CopyNameTo(df::unit *creature, df::language_name * target);
/// Returns the true position of the unit (non-trivial in case of caged).
DFHACK_EXPORT df::coord getPosition(df::unit *unit);
+DFHACK_EXPORT df::general_ref *getGeneralRef(df::unit *unit, df::general_ref_type type);
+DFHACK_EXPORT df::specific_ref *getSpecificRef(df::unit *unit, df::specific_ref_type type);
+
DFHACK_EXPORT df::item *getContainer(df::unit *unit);
DFHACK_EXPORT void setNickname(df::unit *unit, std::string nick);
diff --git a/library/modules/Buildings.cpp b/library/modules/Buildings.cpp
index de121bfa8..1667a27ac 100644
--- a/library/modules/Buildings.cpp
+++ b/library/modules/Buildings.cpp
@@ -178,6 +178,20 @@ bool Buildings::ReadCustomWorkshopTypes(map & btypes)
return true;
}
+df::general_ref *Buildings::getGeneralRef(df::building *building, df::general_ref_type type)
+{
+ CHECK_NULL_POINTER(building);
+
+ return findRef(building->general_refs, type);
+}
+
+df::specific_ref *Buildings::getSpecificRef(df::building *building, df::specific_ref_type type)
+{
+ CHECK_NULL_POINTER(building);
+
+ return findRef(building->specific_refs, type);
+}
+
bool Buildings::setOwner(df::building *bld, df::unit *unit)
{
CHECK_NULL_POINTER(bld);
diff --git a/library/modules/Job.cpp b/library/modules/Job.cpp
index f913a71b6..5a8a8c7a4 100644
--- a/library/modules/Job.cpp
+++ b/library/modules/Job.cpp
@@ -35,6 +35,7 @@ using namespace std;
#include "Error.h"
#include "PluginManager.h"
#include "MiscUtils.h"
+#include "Types.h"
#include "modules/Job.h"
#include "modules/Materials.h"
@@ -228,6 +229,20 @@ void DFHack::Job::printJobDetails(color_ostream &out, df::job *job)
printItemDetails(out, job->job_items[i], i);
}
+df::general_ref *Job::getGeneralRef(df::job *job, df::general_ref_type type)
+{
+ CHECK_NULL_POINTER(job);
+
+ return findRef(job->general_refs, type);
+}
+
+df::specific_ref *Job::getSpecificRef(df::job *job, df::specific_ref_type type)
+{
+ CHECK_NULL_POINTER(job);
+
+ return findRef(job->specific_refs, type);
+}
+
df::building *DFHack::Job::getHolder(df::job *job)
{
CHECK_NULL_POINTER(job);
diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp
index d22022914..ddbb8cb79 100644
--- a/library/modules/Units.cpp
+++ b/library/modules/Units.cpp
@@ -519,18 +519,25 @@ df::coord Units::getPosition(df::unit *unit)
return unit->pos;
}
-df::item *Units::getContainer(df::unit *unit)
+df::general_ref *Units::getGeneralRef(df::unit *unit, df::general_ref_type type)
{
CHECK_NULL_POINTER(unit);
- for (size_t i = 0; i < unit->general_refs.size(); i++)
- {
- df::general_ref *ref = unit->general_refs[i];
- if (ref->getType() == general_ref_type::CONTAINED_IN_ITEM)
- return ref->getItem();
- }
+ return findRef(unit->general_refs, type);
+}
- return NULL;
+df::specific_ref *Units::getSpecificRef(df::unit *unit, df::specific_ref_type type)
+{
+ CHECK_NULL_POINTER(unit);
+
+ return findRef(unit->specific_refs, type);
+}
+
+df::item *Units::getContainer(df::unit *unit)
+{
+ CHECK_NULL_POINTER(unit);
+
+ return findItemRef(unit->general_refs, general_ref_type::CONTAINED_IN_ITEM);
}
static df::assumed_identity *getFigureIdentity(df::historical_figure *figure)
From bbe94c006f56c1c5ea181071473ef280d5bb7a93 Mon Sep 17 00:00:00 2001
From: Quietust
Date: Mon, 12 Nov 2012 11:54:21 -0600
Subject: [PATCH 057/158] Update for temperaturest
---
library/modules/Vegetation.cpp | 10 +++++-----
plugins/steam-engine.cpp | 8 ++++----
plugins/tweak.cpp | 20 ++++++++++----------
scripts/fix/stable-temp.lua | 10 +++++-----
4 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/library/modules/Vegetation.cpp b/library/modules/Vegetation.cpp
index 1a6779553..f7c4c9b0c 100644
--- a/library/modules/Vegetation.cpp
+++ b/library/modules/Vegetation.cpp
@@ -71,15 +71,15 @@ bool Vegetation::copyPlant(const int32_t index, t_plant &out)
out.material = out.origin->material;
out.pos = out.origin->pos;
out.grow_counter = out.origin->grow_counter;
- out.temperature_1 = out.origin->temperature_1;
- out.temperature_2 = out.origin->temperature_2;
+ out.temperature_1 = out.origin->temperature.whole;
+ out.temperature_2 = out.origin->temperature.fraction;
out.is_burning = out.origin->is_burning;
out.hitpoints = out.origin->hitpoints;
out.update_order = out.origin->update_order;
//out.unk1 = out.origin->anon_1;
//out.unk2 = out.origin->anon_2;
- //out.temperature_3 = out.origin->temperature_3;
- //out.temperature_4 = out.origin->temperature_4;
- //out.temperature_5 = out.origin->temperature_5;
+ //out.temperature_3 = out.origin->temperature_unk;
+ //out.temperature_4 = out.origin->min_safe_temp;
+ //out.temperature_5 = out.origin->max_safe_temp;
return true;
}
diff --git a/plugins/steam-engine.cpp b/plugins/steam-engine.cpp
index 60f38ef83..a8ba0e214 100644
--- a/plugins/steam-engine.cpp
+++ b/plugins/steam-engine.cpp
@@ -263,7 +263,7 @@ struct liquid_hook : df::item_liquid_miscst {
DEFINE_VMETHOD_INTERPOSE(bool, checkTemperatureDamage, ())
{
if (mat_state.whole & BOILING_FLAG)
- temperature = std::max(int(temperature), getBoilingPoint()-1);
+ temperature.whole = std::max(int(temperature.whole), getBoilingPoint()-1);
return INTERPOSE_NEXT(checkTemperatureDamage)();
}
@@ -371,8 +371,8 @@ struct workshop_hook : df::building_workshopst {
// Update flags
liquid->flags.bits.in_building = true;
liquid->mat_state.whole |= liquid_hook::BOILING_FLAG;
- liquid->temperature = liquid->getBoilingPoint()-1;
- liquid->temperature_fraction = 0;
+ liquid->temperature.whole = liquid->getBoilingPoint()-1;
+ liquid->temperature.fraction = 0;
// This affects where the steam appears to come from
if (engine->hearth_tile.isValid())
@@ -387,7 +387,7 @@ struct workshop_hook : df::building_workshopst {
{
liquid->wear = 4;
liquid->flags.bits.in_building = false;
- liquid->temperature = liquid->getBoilingPoint() + 10;
+ liquid->temperature.whole = liquid->getBoilingPoint() + 10;
return liquid->checkMeltBoil();
}
diff --git a/plugins/tweak.cpp b/plugins/tweak.cpp
index 93e5ab3bc..b4a435421 100644
--- a/plugins/tweak.cpp
+++ b/plugins/tweak.cpp
@@ -291,18 +291,18 @@ struct stable_temp_hook : df::item_actual {
DEFINE_VMETHOD_INTERPOSE(bool, adjustTemperature, (uint16_t temp, int32_t rate_mult))
{
- if (temperature != temp)
+ if (temperature.whole != temp)
{
// Bug 6012 is caused by fixed-point precision mismatch jitter
// when an item is being pushed by two sources at N and N+1.
// This check suppresses it altogether.
- if (temp == temperature+1 ||
- (temp == temperature-1 && temperature_fraction == 0))
- temp = temperature;
+ if (temp == temperature.whole+1 ||
+ (temp == temperature.whole-1 && temperature.fraction == 0))
+ temp = temperature.whole;
// When SPEC_HEAT is NONE, the original function seems to not
// change the temperature, yet return true, which is silly.
else if (getSpecHeat() == 60001)
- temp = temperature;
+ temp = temperature.whole;
}
return INTERPOSE_NEXT(adjustTemperature)(temp, rate_mult);
@@ -317,10 +317,10 @@ struct stable_temp_hook : df::item_actual {
{
auto obj = (*contaminants)[i];
- if (abs(obj->temperature - temperature) == 1)
+ if (abs(obj->temperature.whole - temperature.whole) == 1)
{
- obj->temperature = temperature;
- obj->temperature_fraction = temperature_fraction;
+ obj->temperature.whole = temperature.whole;
+ obj->temperature.fraction = temperature.fraction;
}
}
}
@@ -355,11 +355,11 @@ struct fast_heat_hook : df::item_actual {
(uint16_t temp, bool local, bool contained, bool adjust, int32_t rate_mult)
) {
// Some items take ages to cross the last degree, so speed them up
- if (map_temp_mult > 0 && temp != temperature && max_heat_ticks > 0)
+ if (map_temp_mult > 0 && temp != temperature.whole && max_heat_ticks > 0)
{
int spec = getSpecHeat();
if (spec != 60001)
- rate_mult = std::max(map_temp_mult, spec/max_heat_ticks/abs(temp - temperature));
+ rate_mult = std::max(map_temp_mult, spec/max_heat_ticks/abs(temp - temperature.whole));
}
return INTERPOSE_NEXT(updateTemperature)(temp, local, contained, adjust, rate_mult);
diff --git a/scripts/fix/stable-temp.lua b/scripts/fix/stable-temp.lua
index 27a88ef7b..63739f8ea 100644
--- a/scripts/fix/stable-temp.lua
+++ b/scripts/fix/stable-temp.lua
@@ -8,20 +8,20 @@ local count = 0
local types = {}
local function update_temp(item,btemp)
- if item.temperature ~= btemp then
+ if item.temperature.whole ~= btemp then
count = count + 1
local tid = item:getType()
types[tid] = (types[tid] or 0) + 1
end
if apply then
- item.temperature = btemp
- item.temperature_fraction = 0
+ item.temperature.whole = btemp
+ item.temperature.fraction = 0
if item.contaminants then
for _,c in ipairs(item.contaminants) do
- c.temperature = btemp
- c.temperature_fraction = 0
+ c.temperature.whole = btemp
+ c.temperature.fraction = 0
end
end
end
From dd89baf6f88b5e111dbe21b24a2f951f0799a5e2 Mon Sep 17 00:00:00 2001
From: jj
Date: Mon, 12 Nov 2012 19:18:03 +0100
Subject: [PATCH 058/158] add raw mmap/mprotect access
---
library/Process-darwin.cpp | 27 ++++++++++++++++++++++++-
library/Process-linux.cpp | 27 ++++++++++++++++++++++++-
library/Process-windows.cpp | 39 +++++++++++++++++++++++++++++++++++++
library/include/MemAccess.h | 21 ++++++++++++++++++++
4 files changed, 112 insertions(+), 2 deletions(-)
diff --git a/library/Process-darwin.cpp b/library/Process-darwin.cpp
index d081c8c5c..72311e83a 100644
--- a/library/Process-darwin.cpp
+++ b/library/Process-darwin.cpp
@@ -304,4 +304,29 @@ bool Process::setPermisions(const t_memrange & range,const t_memrange &trgrange)
result=mprotect((void *)range.start, (size_t)range.end-(size_t)range.start,protect);
return result==0;
-}
\ No newline at end of file
+}
+
+// returns -1 on error
+void* Process::memAlloc(const int length)
+{
+ return mmap(0, length, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
+}
+
+int Process::memDealloc(const void *ptr, const int length)
+{
+ return munmap(ptr, length);
+}
+
+int Process::memProtect(const void *ptr, const int length, const int prot)
+{
+ int prot_native = 0;
+
+ if (prot & Process::MemProt::READ)
+ prot_native |= PROT_READ;
+ if (prot & Process::MemProt::WRITE)
+ prot_native |= PROT_WRITE;
+ if (prot & Process::MemProt::EXEC)
+ prot_native |= PROT_EXEC;
+
+ return mprotect(ptr, length, prot_native);
+}
diff --git a/library/Process-linux.cpp b/library/Process-linux.cpp
index 046b7696d..c3995a2aa 100644
--- a/library/Process-linux.cpp
+++ b/library/Process-linux.cpp
@@ -235,4 +235,29 @@ bool Process::setPermisions(const t_memrange & range,const t_memrange &trgrange)
result=mprotect((void *)range.start, (size_t)range.end-(size_t)range.start,protect);
return result==0;
-}
\ No newline at end of file
+}
+
+// returns -1 on error
+void* Process::memAlloc(const int length)
+{
+ return mmap(0, length, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+}
+
+int Process::memDealloc(void *ptr, const int length)
+{
+ return munmap(ptr, length);
+}
+
+int Process::memProtect(void *ptr, const int length, const int prot)
+{
+ int prot_native = 0;
+
+ if (prot & Process::MemProt::READ)
+ prot_native |= PROT_READ;
+ if (prot & Process::MemProt::WRITE)
+ prot_native |= PROT_WRITE;
+ if (prot & Process::MemProt::EXEC)
+ prot_native |= PROT_EXEC;
+
+ return mprotect(ptr, length, prot_native);
+}
diff --git a/library/Process-windows.cpp b/library/Process-windows.cpp
index 6f79236f9..cfa0b688d 100644
--- a/library/Process-windows.cpp
+++ b/library/Process-windows.cpp
@@ -473,3 +473,42 @@ bool Process::setPermisions(const t_memrange & range,const t_memrange &trgrange)
return result;
}
+
+void* Process::memAlloc(const int length)
+{
+ void *ret;
+ // returns 0 on error
+ ret = VirtualAlloc(0, length, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
+ if (!ret)
+ ret = (void*)-1;
+ return ret;
+}
+
+int Process::memDealloc(const void *ptr, const int length)
+{
+ // can only free the whole region at once
+ // vfree returns 0 on error
+ return !VirtualFree(ptr, 0, MEM_RELEASE)
+}
+
+int Process::memProtect(const void *ptr, const int length, const int prot)
+{
+ int prot_native = 0;
+ int old_prot = 0;
+
+ // only support a few constant combinations
+ if (prot == 0)
+ prot_native = PAGE_NOACCESS;
+ else if (prot == Process::MemProt::READ)
+ prot_native = PAGE_READONLY;
+ else if (prot == Process::MemProt::READ | Process::MemProt::WRITE)
+ prot_native = PAGE_READWRITE;
+ else if (prot == Process::MemProt::READ | Process::MemProt::WRITE | Process::MemProt::EXECUTE)
+ prot_native = PAGE_EXECUTE_READWRITE;
+ else if (prot == Process::MemProt::READ | Process::MemProt::EXECUTE)
+ prot_native = PAGE_EXECUTE_READ;
+ else
+ return -1;
+
+ return !VirtualProtect(ptr, length, prot_native, &old_prot);
+}
diff --git a/library/include/MemAccess.h b/library/include/MemAccess.h
index 22f15eecf..31647a25e 100644
--- a/library/include/MemAccess.h
+++ b/library/include/MemAccess.h
@@ -291,6 +291,27 @@ namespace DFHack
/// write a possibly read-only memory area
bool patchMemory(void *target, const void* src, size_t count);
+
+ /// allocate new memory pages for code or stuff
+ /// returns -1 on error (0 is a valid address)
+ void* memAlloc(const int length);
+
+ /// free memory pages from memAlloc
+ /// should have length = alloced length for portability
+ /// returns 0 on success
+ int memDealloc(void *ptr, const int length);
+
+ /// change memory page permissions
+ /// prot is a bitwise OR of the MemProt enum
+ /// returns 0 on success
+ int memProtect(void *ptr, const int length, const int prot);
+
+ enum MemProt {
+ READ = 1,
+ WRITE = 2,
+ EXEC = 4
+ };
+
private:
VersionInfo * my_descriptor;
PlatformSpecific *d;
From 72912edf58ea562592f00c8bab308c13529427a2 Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Fri, 16 Nov 2012 18:45:51 +0400
Subject: [PATCH 059/158] Ensure AddPersistentData won't create duplicate ids.
If anything messes around with the histfig vector between calls.
---
library/modules/World.cpp | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/library/modules/World.cpp b/library/modules/World.cpp
index f3283c3a3..9ae4266b2 100644
--- a/library/modules/World.cpp
+++ b/library/modules/World.cpp
@@ -197,11 +197,15 @@ PersistentDataItem World::AddPersistentData(const std::string &key)
std::vector &hfvec = df::historical_figure::get_vector();
df::historical_figure *hfig = new df::historical_figure();
- hfig->id = next_persistent_id--;
+ hfig->id = next_persistent_id;
hfig->name.has_name = true;
hfig->name.first_name = key;
memset(hfig->name.words, 0xFF, sizeof(hfig->name.words));
+ if (!hfvec.empty())
+ hfig->id = std::min(hfig->id, hfvec[0]->id-1);
+ next_persistent_id = hfig->id-1;
+
hfvec.insert(hfvec.begin(), hfig);
persistent_index.insert(T_persistent_item(key, -hfig->id));
From 423c1224248195fa22d72781b7b26fa84e9dd2c7 Mon Sep 17 00:00:00 2001
From: jj
Date: Fri, 16 Nov 2012 17:39:08 +0100
Subject: [PATCH 060/158] ruby: fix unit_find for advmode
---
plugins/ruby/unit.rb | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/plugins/ruby/unit.rb b/plugins/ruby/unit.rb
index 4fbf75d8d..4c638b1a9 100644
--- a/plugins/ruby/unit.rb
+++ b/plugins/ruby/unit.rb
@@ -21,7 +21,7 @@ module DFHack
when :SelectTrainer
v.trainer_unit[v.trainer_cursor]
end
- else
+ when :viewscreen_dwarfmodest
case ui.main.mode
when :ViewUnits
# nobody selected => idx == 0
@@ -33,6 +33,15 @@ module DFHack
else
ui.follow_unit_tg if ui.follow_unit != -1
end
+ when :viewscreen_dungeonmodest
+ case ui_advmode.menu
+ when :Default
+ world.units.active[0]
+ else
+ unit_find(cursor) # XXX
+ end
+ when :viewscreen_dungeon_monsterstatusst
+ curview.unit
end
elsif what.kind_of?(Integer)
# search by id
From 342badac982d63b3c600c5307624e3a4402a93f8 Mon Sep 17 00:00:00 2001
From: jj
Date: Fri, 16 Nov 2012 17:46:41 +0100
Subject: [PATCH 061/158] scripts/superdwarf: advmode support
---
NEWS | 1 +
scripts/superdwarf.rb | 7 ++++++-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/NEWS b/NEWS
index 48aaf26a2..4ccb1d18d 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,7 @@ DFHack future
- fastdwarf: new mode using debug flags, and some internal consistency fixes.
- added a small stand-alone utility for applying and removing binary patches.
- removebadthoughts: add --dry-run option
+ - superdwarf: work in adventure mode too
New scripts:
- binpatch: the same as the stand-alone binpatch.exe, but works at runtime.
- region-pops: displays animal populations of the region and allows tweaking them.
diff --git a/scripts/superdwarf.rb b/scripts/superdwarf.rb
index 7f5296b74..6277db97f 100644
--- a/scripts/superdwarf.rb
+++ b/scripts/superdwarf.rb
@@ -8,7 +8,12 @@ when 'add'
if u = df.unit_find
$superdwarf_ids |= [u.id]
- $superdwarf_onupdate ||= df.onupdate_register(1) {
+ if df.gamemode == :ADVENTURE
+ onupdate_delay = nil
+ else
+ onupdate_delay = 1
+ end
+ $superdwarf_onupdate ||= df.onupdate_register(onupdate_delay) {
if $superdwarf_ids.empty?
df.onupdate_unregister($superdwarf_onupdate)
$superdwarf_onupdate = nil
From 2401be1b3b4ed423542e232deeafa8406ffc79b8 Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Fri, 16 Nov 2012 22:48:49 +0400
Subject: [PATCH 062/158] Add an api function to retrieve unit skill
experience.
---
Lua API.html | 21 +++++++++++++++++++++
Lua API.rst | 4 ++++
library/LuaApi.cpp | 1 +
library/include/modules/Units.h | 2 ++
library/modules/Units.cpp | 18 ++++++++++++++++++
5 files changed, 46 insertions(+)
diff --git a/Lua API.html b/Lua API.html
index d2e0da1ef..04af5d672 100644
--- a/Lua API.html
+++ b/Lua API.html
@@ -1109,6 +1109,12 @@ above operations accordingly. If enabled, pauses and zooms to position.
dfhack.job.printItemDetails(jobitem,idx)
Prints info about the job item.
+dfhack.job.getGeneralRef(job, type)
+Searches for a general_ref with the given type.
+
+dfhack.job.getSpecificRef(job, type)
+Searches for a specific_ref with the given type.
+
dfhack.job.getHolder(job)
Returns the building holding the job.
@@ -1147,6 +1153,12 @@ the flags in the job item.
dfhack.units.getPosition(unit)
Returns true x,y,z of the unit, or nil if invalid; may be not equal to unit.pos if caged.
+dfhack.units.getGeneralRef(unit, type)
+Searches for a general_ref with the given type.
+
+dfhack.units.getSpecificRef(unit, type)
+Searches for a specific_ref with the given type.
+
dfhack.units.getContainer(unit)
Returns the container (cage) item or nil.
@@ -1209,6 +1221,9 @@ is true, subtracts the rust penalty.
dfhack.units.getEffectiveSkill(unit, skill)
Computes the effective rating for the given skill, taking into account exhaustion, pain etc.
+dfhack.units.getExperience(unit, skill[, total])
+Returns the experience value for the given skill. If total is true, adds experience implied by the current rating.
+
dfhack.units.computeMovementSpeed(unit)
Computes number of frames * 100 it takes the unit to move in its current state of mind and body.
@@ -1403,6 +1418,12 @@ burrows, or the presence of invaders.
+dfhack.buildings.getGeneralRef(building, type)
+Searches for a general_ref with the given type.
+
+dfhack.buildings.getSpecificRef(building, type)
+Searches for a specific_ref with the given type.
+
dfhack.buildings.setOwner(item,unit)
Replaces the owner of the building. If unit is nil, removes ownership.
Returns false in case of error.
diff --git a/Lua API.rst b/Lua API.rst
index 126bc7f9d..4087ff0aa 100644
--- a/Lua API.rst
+++ b/Lua API.rst
@@ -970,6 +970,10 @@ Units module
Computes the effective rating for the given skill, taking into account exhaustion, pain etc.
+* ``dfhack.units.getExperience(unit, skill[, total])``
+
+ Returns the experience value for the given skill. If ``total`` is true, adds experience implied by the current rating.
+
* ``dfhack.units.computeMovementSpeed(unit)``
Computes number of frames * 100 it takes the unit to move in its current state of mind and body.
diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp
index b186316a8..a4ebbea5b 100644
--- a/library/LuaApi.cpp
+++ b/library/LuaApi.cpp
@@ -1180,6 +1180,7 @@ static const LuaWrapper::FunctionReg dfhack_units_module[] = {
WRAPM(Units, getAge),
WRAPM(Units, getNominalSkill),
WRAPM(Units, getEffectiveSkill),
+ WRAPM(Units, getExperience),
WRAPM(Units, computeMovementSpeed),
WRAPM(Units, getProfessionName),
WRAPM(Units, getCasteProfessionName),
diff --git a/library/include/modules/Units.h b/library/include/modules/Units.h
index 93e11afb1..c2eb7ca18 100644
--- a/library/include/modules/Units.h
+++ b/library/include/modules/Units.h
@@ -238,6 +238,8 @@ DFHACK_EXPORT double getAge(df::unit *unit, bool true_age = false);
DFHACK_EXPORT int getNominalSkill(df::unit *unit, df::job_skill skill_id, bool use_rust = false);
DFHACK_EXPORT int getEffectiveSkill(df::unit *unit, df::job_skill skill_id);
+DFHACK_EXPORT int getExperience(df::unit *unit, df::job_skill skill_id, bool total = false);
+
DFHACK_EXPORT int computeMovementSpeed(df::unit *unit);
struct NoblePosition {
diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp
index ddbb8cb79..b19399c6c 100644
--- a/library/modules/Units.cpp
+++ b/library/modules/Units.cpp
@@ -909,6 +909,24 @@ int Units::getNominalSkill(df::unit *unit, df::job_skill skill_id, bool use_rust
return 0;
}
+int Units::getExperience(df::unit *unit, df::job_skill skill_id, bool total)
+{
+ CHECK_NULL_POINTER(unit);
+
+ if (!unit->status.current_soul)
+ return 0;
+
+ auto skill = binsearch_in_vector(unit->status.current_soul->skills, &df::unit_skill::id, skill_id);
+ if (!skill)
+ return 0;
+
+ int xp = skill->experience;
+ // exact formula used by the game:
+ if (total && skill->rating > 0)
+ xp += 500*skill->rating + 100*skill->rating*(skill->rating - 1)/2;
+ return xp;
+}
+
int Units::getEffectiveSkill(df::unit *unit, df::job_skill skill_id)
{
/*
From d506dd713717aedb4ef98a087834845c13ac92c7 Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Fri, 16 Nov 2012 22:51:07 +0400
Subject: [PATCH 063/158] Add a tweak to speed up melee squad training.
---
NEWS | 2 +
dfhack.init-example | 3 +
library/xml | 2 +-
plugins/tweak.cpp | 189 ++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 195 insertions(+), 1 deletion(-)
diff --git a/NEWS b/NEWS
index 48aaf26a2..39b4ccf02 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,8 @@ DFHack future
- fastdwarf: new mode using debug flags, and some internal consistency fixes.
- added a small stand-alone utility for applying and removing binary patches.
- removebadthoughts: add --dry-run option
+ New tweaks:
+ - tweak military-training: speed up melee squad training up to 10x (depends on unit count).
New scripts:
- binpatch: the same as the stand-alone binpatch.exe, but works at runtime.
- region-pops: displays animal populations of the region and allows tweaking them.
diff --git a/dfhack.init-example b/dfhack.init-example
index 885849c33..8fafa4cf4 100644
--- a/dfhack.init-example
+++ b/dfhack.init-example
@@ -133,6 +133,9 @@ tweak military-stable-assign
# in same list, color units already assigned to squads in brown & green
tweak military-color-assigned
+# remove inverse dependency of squad training speed on unit list size and use more sparring
+tweak military-training
+
#######################################################
# Apply binary patches at runtime #
# #
diff --git a/library/xml b/library/xml
index 327a9662b..9b4dc47a5 160000
--- a/library/xml
+++ b/library/xml
@@ -1 +1 @@
-Subproject commit 327a9662be81627ebcbb3aea11ffbca3e536b7ee
+Subproject commit 9b4dc47a54c8b15db2f30fbf926deb8c1bf992f6
diff --git a/plugins/tweak.cpp b/plugins/tweak.cpp
index b4a435421..c2309a3ee 100644
--- a/plugins/tweak.cpp
+++ b/plugins/tweak.cpp
@@ -51,6 +51,12 @@
#include "df/squad_position.h"
#include "df/job.h"
#include "df/general_ref_building_holderst.h"
+#include "df/unit_health_info.h"
+#include "df/activity_entry.h"
+#include "df/activity_event_combat_trainingst.h"
+#include "df/activity_event_individual_skill_drillst.h"
+#include "df/activity_event_skill_demonstrationst.h"
+#include "df/activity_event_sparringst.h"
#include
@@ -128,6 +134,8 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector counters2.exhaustion <= 2000 && // actually 4000, but leave a gap
+ (unit->status2.able_grasp_impair > 0 || unit->status2.able_grasp == 0) &&
+ (!unit->health || (unit->health->flags.whole&0x7FF) == 0) &&
+ (!unit->job.current_job || unit->job.current_job != job_type::Rest);
+}
+
+struct military_training_ct_hook : df::activity_event_combat_trainingst {
+ typedef df::activity_event_combat_trainingst interpose_base;
+
+ DEFINE_VMETHOD_INTERPOSE(void, process, (df::unit *unit))
+ {
+ auto act = df::activity_entry::find(activity_id);
+ int cur_neid = act ? act->next_event_id : 0;
+ int cur_oc = organize_counter;
+
+ INTERPOSE_NEXT(process)(unit);
+
+ // Shorten the time it takes to organize stuff, so that in
+ // reality it remains the same instead of growing proportionally
+ // to the unit count.
+ if (organize_counter > cur_oc && organize_counter > 0)
+ organize_counter = adjust_unit_divisor(organize_counter);
+
+ if (act && act->next_event_id > cur_neid)
+ {
+ // New events were added. Check them.
+ for (size_t i = 0; i < act->events.size(); i++)
+ {
+ auto event = act->events[i];
+ if (event->flags.bits.dismissed || event->event_id < cur_neid)
+ continue;
+
+ if (auto sp = strict_virtual_cast(event))
+ {
+ // Sparring has a problem in that all of its participants decrement
+ // the countdown variable. Fix this by multiplying it by the member count.
+ sp->countdown = sp->countdown * sp->participants.hist_figure_ids.size();
+ }
+ else if (auto sd = strict_virtual_cast(event))
+ {
+ // Adjust initial counter values
+ sd->train_countdown = adjust_unit_divisor(sd->train_countdown);
+ sd->wait_countdown = adjust_unit_divisor(sd->wait_countdown);
+
+ // Check if the game selected the most skilled unit as the teacher
+ auto &units = sd->participants.participant_ids;
+ int maxv = -1, cur_xp = -1, minv = 0;
+ int best = -1;
+ size_t spar = 0;
+
+ for (size_t j = 0; j < units.size(); j++)
+ {
+ auto unit = df::unit::find(units[j]);
+ if (!unit) continue;
+ int xp = Units::getExperience(unit, sd->skill, true);
+ if (units[j] == sd->unit_id)
+ cur_xp = xp;
+ if (j == 0 || xp < minv)
+ minv = xp;
+ if (xp > maxv) {
+ maxv = xp;
+ best = j;
+ }
+ if (can_spar(unit))
+ spar++;
+ }
+
+ color_ostream_proxy out(Core::getInstance().getConsole());
+
+ // If the xp gap is low, sometimes replace with sparring
+ if ((maxv - minv) < 64*15 && spar == units.size() &&
+ random_int(20) >= 5 + (maxv-minv)/64)
+ {
+ out.print("Replacing demonstration with sparring.\n");
+
+ if (auto spar = df::allocate())
+ {
+ spar->event_id = sd->event_id;
+ spar->activity_id = sd->activity_id;
+ spar->parent_event_id = sd->parent_event_id;
+ spar->flags = sd->flags;
+ spar->participants = sd->participants;
+ spar->building_id = sd->building_id;
+ spar->countdown = 300*units.size();
+
+ delete sd;
+ act->events[i] = spar;
+
+ continue;
+ }
+ }
+
+ // If the teacher has less xp than somebody else, switch
+ if (best >= 0 && maxv > cur_xp)
+ {
+ out.print("Replacing teacher %d (%d xp) with %d (%d xp)\n",
+ sd->unit_id, cur_xp, units[best], maxv);
+
+ sd->hist_figure_id = sd->participants.hist_figure_ids[best];
+ sd->unit_id = units[best];
+ }
+ }
+ }
+ }
+ }
+};
+
+IMPLEMENT_VMETHOD_INTERPOSE(military_training_ct_hook, process);
+
+struct military_training_sd_hook : df::activity_event_skill_demonstrationst {
+ typedef df::activity_event_skill_demonstrationst interpose_base;
+
+ DEFINE_VMETHOD_INTERPOSE(void, process, (df::unit *unit))
+ {
+ int cur_oc = organize_counter;
+ int cur_tc = train_countdown;
+
+ INTERPOSE_NEXT(process)(unit);
+
+ // Shorten the counters if they changed
+ if (organize_counter > cur_oc && organize_counter > 0)
+ organize_counter = adjust_unit_divisor(organize_counter);
+ if (train_countdown > cur_tc)
+ train_countdown = adjust_unit_divisor(train_countdown);
+ }
+};
+
+IMPLEMENT_VMETHOD_INTERPOSE(military_training_sd_hook, process);
+
+static bool is_done(df::activity_event *event, df::unit *unit)
+{
+ return event->flags.bits.dismissed ||
+ binsearch_index(event->participants.participant_ids, unit->id) < 0;
+}
+
+struct military_training_sp_hook : df::activity_event_sparringst {
+ typedef df::activity_event_sparringst interpose_base;
+
+ DEFINE_VMETHOD_INTERPOSE(void, process, (df::unit *unit))
+ {
+ INTERPOSE_NEXT(process)(unit);
+
+ // Since there are no counters to fix, repeat the call
+ int cnt = (DF_GLOBAL_FIELD(ui, unit_action_divisor, 10)+5) / 10;
+ for (int i = 1; i < cnt && !is_done(this, unit); i++)
+ INTERPOSE_NEXT(process)(unit);
+ }
+};
+
+IMPLEMENT_VMETHOD_INTERPOSE(military_training_sp_hook, process);
+
+struct military_training_id_hook : df::activity_event_individual_skill_drillst {
+ typedef df::activity_event_individual_skill_drillst interpose_base;
+
+ DEFINE_VMETHOD_INTERPOSE(void, process, (df::unit *unit))
+ {
+ INTERPOSE_NEXT(process)(unit);
+
+ // Since there are no counters to fix, repeat the call
+ int cnt = (DF_GLOBAL_FIELD(ui, unit_action_divisor, 10)+5) / 10;
+ for (int i = 1; i < cnt && !is_done(this, unit); i++)
+ INTERPOSE_NEXT(process)(unit);
+ }
+};
+
+IMPLEMENT_VMETHOD_INTERPOSE(military_training_id_hook, process);
+
static void enable_hook(color_ostream &out, VMethodInterposeLinkBase &hook, vector ¶meters)
{
if (vector_get(parameters, 1) == "disable")
@@ -835,6 +1017,13 @@ static command_result tweak(color_ostream &out, vector ¶meters)
{
enable_hook(out, INTERPOSE_HOOK(military_assign_hook, render), parameters);
}
+ else if (cmd == "military-training")
+ {
+ enable_hook(out, INTERPOSE_HOOK(military_training_ct_hook, process), parameters);
+ enable_hook(out, INTERPOSE_HOOK(military_training_sd_hook, process), parameters);
+ enable_hook(out, INTERPOSE_HOOK(military_training_sp_hook, process), parameters);
+ enable_hook(out, INTERPOSE_HOOK(military_training_id_hook, process), parameters);
+ }
else
return CR_WRONG_USAGE;
From cbe37417518ac1757ca783c73863851c8e02ac5e Mon Sep 17 00:00:00 2001
From: Kelly Martin
Date: Fri, 16 Nov 2012 13:09:05 -0600
Subject: [PATCH 064/158] Check all depots for trader requested, not just the
last one.
---
plugins/autolabor.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plugins/autolabor.cpp b/plugins/autolabor.cpp
index 44984cfdb..909adc04f 100644
--- a/plugins/autolabor.cpp
+++ b/plugins/autolabor.cpp
@@ -964,7 +964,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out )
else if (building_type::TradeDepot == type)
{
df::building_tradedepotst* depot = (df::building_tradedepotst*) build;
- trader_requested = depot->trade_flags.bits.trader_requested;
+ trader_requested = trader_requested || depot->trade_flags.bits.trader_requested;
if (print_debug)
{
if (trader_requested)
From a6fba3daf24ce9633d9fccd985178a1d5780a64c Mon Sep 17 00:00:00 2001
From: Kelly Martin
Date: Fri, 16 Nov 2012 13:44:38 -0600
Subject: [PATCH 065/158] const void* -> void* in memDealloc and memProtect for
Windows too
---
library/Process-windows.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/library/Process-windows.cpp b/library/Process-windows.cpp
index cfa0b688d..ff180025e 100644
--- a/library/Process-windows.cpp
+++ b/library/Process-windows.cpp
@@ -484,14 +484,14 @@ void* Process::memAlloc(const int length)
return ret;
}
-int Process::memDealloc(const void *ptr, const int length)
+int Process::memDealloc(void *ptr, const int length)
{
// can only free the whole region at once
// vfree returns 0 on error
return !VirtualFree(ptr, 0, MEM_RELEASE)
}
-int Process::memProtect(const void *ptr, const int length, const int prot)
+int Process::memProtect(void *ptr, const int length, const int prot)
{
int prot_native = 0;
int old_prot = 0;
From 2b087a7081ab2eca6181a86a37e2f5b481815918 Mon Sep 17 00:00:00 2001
From: jj
Date: Fri, 16 Nov 2012 20:49:30 +0100
Subject: [PATCH 066/158] fix windows typos
---
library/Process-windows.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/library/Process-windows.cpp b/library/Process-windows.cpp
index cfa0b688d..fdef9e225 100644
--- a/library/Process-windows.cpp
+++ b/library/Process-windows.cpp
@@ -484,28 +484,28 @@ void* Process::memAlloc(const int length)
return ret;
}
-int Process::memDealloc(const void *ptr, const int length)
+int Process::memDealloc(void *ptr, const int length)
{
// can only free the whole region at once
// vfree returns 0 on error
- return !VirtualFree(ptr, 0, MEM_RELEASE)
+ return !VirtualFree(ptr, 0, MEM_RELEASE);
}
-int Process::memProtect(const void *ptr, const int length, const int prot)
+int Process::memProtect(void *ptr, const int length, const int prot)
{
int prot_native = 0;
- int old_prot = 0;
+ DWORD old_prot = 0;
// only support a few constant combinations
if (prot == 0)
prot_native = PAGE_NOACCESS;
else if (prot == Process::MemProt::READ)
prot_native = PAGE_READONLY;
- else if (prot == Process::MemProt::READ | Process::MemProt::WRITE)
+ else if (prot == (Process::MemProt::READ | Process::MemProt::WRITE))
prot_native = PAGE_READWRITE;
- else if (prot == Process::MemProt::READ | Process::MemProt::WRITE | Process::MemProt::EXECUTE)
+ else if (prot == (Process::MemProt::READ | Process::MemProt::WRITE | Process::MemProt::EXEC))
prot_native = PAGE_EXECUTE_READWRITE;
- else if (prot == Process::MemProt::READ | Process::MemProt::EXECUTE)
+ else if (prot == (Process::MemProt::READ | Process::MemProt::EXEC))
prot_native = PAGE_EXECUTE_READ;
else
return -1;
From 648abee28595f17b711e94f2a89e22fc65c70378 Mon Sep 17 00:00:00 2001
From: Kelly Martin
Date: Fri, 16 Nov 2012 13:50:38 -0600
Subject: [PATCH 067/158] EXECUTE -> EXEC and add parenthesis to make MSVC
whine less.
---
library/Process-windows.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/library/Process-windows.cpp b/library/Process-windows.cpp
index ff180025e..6846ccccf 100644
--- a/library/Process-windows.cpp
+++ b/library/Process-windows.cpp
@@ -488,7 +488,7 @@ int Process::memDealloc(void *ptr, const int length)
{
// can only free the whole region at once
// vfree returns 0 on error
- return !VirtualFree(ptr, 0, MEM_RELEASE)
+ return !VirtualFree(ptr, 0, MEM_RELEASE);
}
int Process::memProtect(void *ptr, const int length, const int prot)
@@ -501,11 +501,11 @@ int Process::memProtect(void *ptr, const int length, const int prot)
prot_native = PAGE_NOACCESS;
else if (prot == Process::MemProt::READ)
prot_native = PAGE_READONLY;
- else if (prot == Process::MemProt::READ | Process::MemProt::WRITE)
+ else if (prot == (Process::MemProt::READ | Process::MemProt::WRITE))
prot_native = PAGE_READWRITE;
- else if (prot == Process::MemProt::READ | Process::MemProt::WRITE | Process::MemProt::EXECUTE)
+ else if (prot == (Process::MemProt::READ | Process::MemProt::WRITE | Process::MemProt::EXEC))
prot_native = PAGE_EXECUTE_READWRITE;
- else if (prot == Process::MemProt::READ | Process::MemProt::EXECUTE)
+ else if (prot == (Process::MemProt::READ | Process::MemProt::EXEC))
prot_native = PAGE_EXECUTE_READ;
else
return -1;
From e2b9b703a07d88fcad9a8f4f61057a44f12644ba Mon Sep 17 00:00:00 2001
From: Quietust
Date: Fri, 16 Nov 2012 15:33:36 -0600
Subject: [PATCH 068/158] Get rid of tabs
---
CMakeLists.txt | 12 +-
library/CMakeLists.txt | 38 +-
library/Core.cpp | 8 +-
library/Hooks-windows.cpp | 66 +--
library/MacPool.mm | 14 +-
library/Process-darwin.cpp | 60 +--
library/include/Console.h | 14 +-
library/include/DataDefs.h | 2 +-
library/include/TileTypes.h | 2 +-
library/include/modules/Graphic.h | 90 ++--
library/modules/Graphic.cpp | 74 ++--
plugins/cleanowned.cpp | 2 +-
plugins/devel/memview.cpp | 240 +++++------
plugins/devel/nestboxes.cpp | 74 ++--
plugins/devel/rprobe.cpp | 24 +-
plugins/devel/stockcheck.cpp | 360 ++++++++--------
plugins/devel/stripcaged.cpp | 64 +--
plugins/dfstream.cpp | 2 +-
plugins/filltraffic.cpp | 2 +-
plugins/forceequip.cpp | 682 +++++++++++++++---------------
plugins/reactionhooks.cpp | 26 +-
plugins/workflow.cpp | 6 +-
plugins/zone.cpp | 164 +++----
23 files changed, 1013 insertions(+), 1013 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 41c38bd44..0165d9964 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -121,7 +121,7 @@ ADD_DEFINITIONS(-DPROTOBUF_USE_DLLS)
ADD_DEFINITIONS(-DLUA_BUILD_AS_DLL)
if(APPLE)
- add_definitions(-D_DARWIN)
+ add_definitions(-D_DARWIN)
elseif(UNIX)
add_definitions(-D_LINUX)
elseif(WIN32)
@@ -181,11 +181,11 @@ endif()
# Packaging with CPack!
IF(UNIX)
- if(APPLE)
- SET(CPACK_GENERATOR "ZIP")
- else()
- SET(CPACK_GENERATOR "TGZ")
- endif()
+ if(APPLE)
+ SET(CPACK_GENERATOR "ZIP")
+ else()
+ SET(CPACK_GENERATOR "TGZ")
+ endif()
ELSEIF(WIN32)
SET(CPACK_GENERATOR "ZIP")
ENDIF()
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index b141e9fa5..f67b6fe44 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -167,7 +167,7 @@ IF(UNIX)
IF(BUILD_EGGY)
LIST(APPEND PROJECT_SOURCES ${MAIN_SOURCES_LINUX_EGGY})
ELSEIF(APPLE)
- LIST(APPEND PROJECT_SOURCES ${MAIN_SOURCES_DARWIN})
+ LIST(APPEND PROJECT_SOURCES ${MAIN_SOURCES_DARWIN})
ELSE()
LIST(APPEND PROJECT_SOURCES ${MAIN_SOURCES_LINUX})
ENDIF()
@@ -235,7 +235,7 @@ ENDIF()
IF(UNIX)
SET(PROJECT_LIBS rt dl dfhack-md5 dfhack-tinyxml dfhack-tinythread)
IF(APPLE)
- SET(PROJECT_LIBS dl dfhack-md5 dfhack-tinyxml dfhack-tinythread)
+ SET(PROJECT_LIBS dl dfhack-md5 dfhack-tinyxml dfhack-tinythread)
ENDIF()
ELSE(WIN32)
#FIXME: do we really need psapi?
@@ -273,14 +273,14 @@ ENDIF()
SET_TARGET_PROPERTIES(dfhack PROPERTIES DEBUG_POSTFIX "-debug" )
IF(APPLE)
- SET(SDL_LIBRARY ${CMAKE_INSTALL_PREFIX}/libs/SDL.framework)
- SET(CXX_LIBRARY ${CMAKE_INSTALL_PREFIX}/libs/libstdc++.6.dylib)
- SET(ZIP_LIBRARY /usr/lib/libz.dylib)
- TARGET_LINK_LIBRARIES(dfhack ${SDL_LIBRARY})
- TARGET_LINK_LIBRARIES(dfhack ${CXX_LIBRARY})
- TARGET_LINK_LIBRARIES(dfhack ${ZIP_LIBRARY})
- SET_TARGET_PROPERTIES(dfhack PROPERTIES VERSION 1.0.0)
- SET_TARGET_PROPERTIES(dfhack PROPERTIES SOVERSION 1.0.0)
+ SET(SDL_LIBRARY ${CMAKE_INSTALL_PREFIX}/libs/SDL.framework)
+ SET(CXX_LIBRARY ${CMAKE_INSTALL_PREFIX}/libs/libstdc++.6.dylib)
+ SET(ZIP_LIBRARY /usr/lib/libz.dylib)
+ TARGET_LINK_LIBRARIES(dfhack ${SDL_LIBRARY})
+ TARGET_LINK_LIBRARIES(dfhack ${CXX_LIBRARY})
+ TARGET_LINK_LIBRARIES(dfhack ${ZIP_LIBRARY})
+ SET_TARGET_PROPERTIES(dfhack PROPERTIES VERSION 1.0.0)
+ SET_TARGET_PROPERTIES(dfhack PROPERTIES SOVERSION 1.0.0)
ENDIF()
TARGET_LINK_LIBRARIES(dfhack protobuf-lite clsocket lua ${PROJECT_LIBS})
@@ -290,20 +290,20 @@ TARGET_LINK_LIBRARIES(dfhack-client protobuf-lite clsocket)
TARGET_LINK_LIBRARIES(dfhack-run dfhack-client)
if(APPLE)
- add_custom_command(TARGET dfhack-run COMMAND ${dfhack_SOURCE_DIR}/package/darwin/fix-libs.sh WORKING_DIRECTORY ../ COMMENT "Fixing library dependencies...")
+ add_custom_command(TARGET dfhack-run COMMAND ${dfhack_SOURCE_DIR}/package/darwin/fix-libs.sh WORKING_DIRECTORY ../ COMMENT "Fixing library dependencies...")
endif()
IF(UNIX)
- if (APPLE)
- install(PROGRAMS ${dfhack_SOURCE_DIR}/package/darwin/dfhack
- DESTINATION .)
- install(PROGRAMS ${dfhack_SOURCE_DIR}/package/darwin/dfhack-run
- DESTINATION .)
+ if (APPLE)
+ install(PROGRAMS ${dfhack_SOURCE_DIR}/package/darwin/dfhack
+ DESTINATION .)
+ install(PROGRAMS ${dfhack_SOURCE_DIR}/package/darwin/dfhack-run
+ DESTINATION .)
else()
- # On linux, copy our version of the df launch script which sets LD_PRELOAD
- install(PROGRAMS ${dfhack_SOURCE_DIR}/package/linux/dfhack
+ # On linux, copy our version of the df launch script which sets LD_PRELOAD
+ install(PROGRAMS ${dfhack_SOURCE_DIR}/package/linux/dfhack
DESTINATION .)
- install(PROGRAMS ${dfhack_SOURCE_DIR}/package/linux/dfhack-run
+ install(PROGRAMS ${dfhack_SOURCE_DIR}/package/linux/dfhack-run
DESTINATION .)
endif()
ELSE()
diff --git a/library/Core.cpp b/library/Core.cpp
index 26c0acbb0..fd96d5601 100644
--- a/library/Core.cpp
+++ b/library/Core.cpp
@@ -375,7 +375,7 @@ command_result Core::runCommand(color_ostream &con, const std::string &first, ve
" reload PLUGIN|all - Reload a plugin or all loaded plugins.\n"
);
- con.print("\nDFHack version " DFHACK_VERSION ".\n");
+ con.print("\nDFHack version " DFHACK_VERSION ".\n");
}
else if (parts.size() == 1)
{
@@ -747,13 +747,13 @@ void fIOthread(void * iodata)
else if(ret)
{
// a proper, non-empty command was entered
- fprintf(stderr,"Adding command to history\n");
+ fprintf(stderr,"Adding command to history\n");
main_history.add(command);
- fprintf(stderr,"Saving history\n");
+ fprintf(stderr,"Saving history\n");
main_history.save("dfhack.history");
}
- fprintf(stderr,"Running command\n");
+ fprintf(stderr,"Running command\n");
auto rv = core->runCommand(con, command);
diff --git a/library/Hooks-windows.cpp b/library/Hooks-windows.cpp
index 1e6679855..c8bd22dda 100644
--- a/library/Hooks-windows.cpp
+++ b/library/Hooks-windows.cpp
@@ -271,39 +271,39 @@ DFhackCExport vPtr SDL_SetVideoMode(int width, int height, int bpp, uint32_t fla
static int (*_SDL_UpperBlit)(DFHack::DFSDL_Surface* src, DFHack::DFSDL_Rect* srcrect, DFHack::DFSDL_Surface* dst, DFHack::DFSDL_Rect* dstrect) = 0;
DFhackCExport int SDL_UpperBlit(DFHack::DFSDL_Surface* src, DFHack::DFSDL_Rect* srcrect, DFHack::DFSDL_Surface* dst, DFHack::DFSDL_Rect* dstrect)
{
- if ( dstrect != NULL && dstrect->h != 0 && dstrect->w != 0 )
- {
- DFHack::Core & c = DFHack::Core::getInstance();
- DFHack::Graphic* g = c.getGraphic();
- DFHack::DFTileSurface* ov = g->Call(dstrect->x/dstrect->w, dstrect->y/dstrect->h);
-
- if ( ov != NULL )
- {
- if ( ov->paintOver )
- {
- _SDL_UpperBlit(src, srcrect, dst, dstrect);
- }
-
- DFHack::DFSDL_Rect* dstrect2 = new DFHack::DFSDL_Rect;
- dstrect2->x = dstrect->x;
- dstrect2->y = dstrect->y;
- dstrect2->w = dstrect->w;
- dstrect2->h = dstrect->h;
-
- if ( ov->dstResize != NULL )
- {
- DFHack::DFSDL_Rect* r = (DFHack::DFSDL_Rect*)ov->dstResize;
- dstrect2->x += r->x;
- dstrect2->y += r->y;
- dstrect2->w += r->w;
- dstrect2->h += r->h;
- }
-
- int result = _SDL_UpperBlit(ov->surface, ov->rect, dst, dstrect2);
- delete dstrect2;
- return result;
- }
- }
+ if ( dstrect != NULL && dstrect->h != 0 && dstrect->w != 0 )
+ {
+ DFHack::Core & c = DFHack::Core::getInstance();
+ DFHack::Graphic* g = c.getGraphic();
+ DFHack::DFTileSurface* ov = g->Call(dstrect->x/dstrect->w, dstrect->y/dstrect->h);
+
+ if ( ov != NULL )
+ {
+ if ( ov->paintOver )
+ {
+ _SDL_UpperBlit(src, srcrect, dst, dstrect);
+ }
+
+ DFHack::DFSDL_Rect* dstrect2 = new DFHack::DFSDL_Rect;
+ dstrect2->x = dstrect->x;
+ dstrect2->y = dstrect->y;
+ dstrect2->w = dstrect->w;
+ dstrect2->h = dstrect->h;
+
+ if ( ov->dstResize != NULL )
+ {
+ DFHack::DFSDL_Rect* r = (DFHack::DFSDL_Rect*)ov->dstResize;
+ dstrect2->x += r->x;
+ dstrect2->y += r->y;
+ dstrect2->w += r->w;
+ dstrect2->h += r->h;
+ }
+
+ int result = _SDL_UpperBlit(ov->surface, ov->rect, dst, dstrect2);
+ delete dstrect2;
+ return result;
+ }
+ }
return _SDL_UpperBlit(src, srcrect, dst, dstrect);
}
diff --git a/library/MacPool.mm b/library/MacPool.mm
index 2453aca29..8f26543e9 100644
--- a/library/MacPool.mm
+++ b/library/MacPool.mm
@@ -9,14 +9,14 @@
NSAutoreleasePool *thePool;
int create_pool() {
- fprintf(stderr,"Creating autorelease pool\n");
- thePool = [[NSAutoreleasePool alloc] init];
- return 1;
+ fprintf(stderr,"Creating autorelease pool\n");
+ thePool = [[NSAutoreleasePool alloc] init];
+ return 1;
}
int destroy_pool() {
- fprintf(stderr,"Draining and releasing autorelease pool\n");
- [thePool drain];
- [thePool release];
- return 0;
+ fprintf(stderr,"Draining and releasing autorelease pool\n");
+ [thePool drain];
+ [thePool release];
+ return 0;
}
\ No newline at end of file
diff --git a/library/Process-darwin.cpp b/library/Process-darwin.cpp
index 72311e83a..2e2be277b 100644
--- a/library/Process-darwin.cpp
+++ b/library/Process-darwin.cpp
@@ -50,13 +50,13 @@ using namespace DFHack;
Process::Process(VersionInfoFactory * known_versions)
{
int target_result;
-
+
char path[1024];
char *real_path;
- uint32_t size = sizeof(path);
- if (_NSGetExecutablePath(path, &size) == 0) {
- real_path = realpath(path, NULL);
- }
+ uint32_t size = sizeof(path);
+ if (_NSGetExecutablePath(path, &size) == 0) {
+ real_path = realpath(path, NULL);
+ }
identified = false;
my_descriptor = 0;
@@ -166,29 +166,29 @@ void Process::getMemRanges( vector & ranges )
(vm_region_info_t)&info, &info_count, &object);
if (kr == KERN_SUCCESS) {
if (info.reserved==1) {
- address += vmsize;
- continue;
+ address += vmsize;
+ continue;
}
Dl_info dlinfo;
int dlcheck;
dlcheck = dladdr((const void*)address, &dlinfo);
if (dlcheck==0) {
- dlinfo.dli_fname = "";
+ dlinfo.dli_fname = "";
}
-
+
t_memrange temp;
- strncpy( temp.name, dlinfo.dli_fname, 1023 );
- temp.name[1023] = 0;
- temp.start = (void *) address;
- temp.end = (void *) (address+vmsize);
- temp.read = (info.protection & VM_PROT_READ);
- temp.write = (info.protection & VM_PROT_WRITE);
- temp.execute = (info.protection & VM_PROT_EXECUTE);
- temp.shared = info.shared;
- temp.valid = true;
- ranges.push_back(temp);
-
- fprintf(stderr,
+ strncpy( temp.name, dlinfo.dli_fname, 1023 );
+ temp.name[1023] = 0;
+ temp.start = (void *) address;
+ temp.end = (void *) (address+vmsize);
+ temp.read = (info.protection & VM_PROT_READ);
+ temp.write = (info.protection & VM_PROT_WRITE);
+ temp.execute = (info.protection & VM_PROT_EXECUTE);
+ temp.shared = info.shared;
+ temp.valid = true;
+ ranges.push_back(temp);
+
+ fprintf(stderr,
"%08x-%08x %8uK %c%c%c/%c%c%c %11s %6s %10s uwir=%hu sub=%u dlname: %s\n",
address, (address + vmsize), (vmsize >> 10),
(info.protection & VM_PROT_READ) ? 'r' : '-',
@@ -203,7 +203,7 @@ void Process::getMemRanges( vector & ranges )
info.user_wired_count,
info.reserved,
dlinfo.dli_fname);
-
+
address += vmsize;
} else if (kr != KERN_INVALID_ADDRESS) {
@@ -277,15 +277,15 @@ uint32_t Process::getTickCount()
string Process::getPath()
{
- char path[1024];
+ char path[1024];
char *real_path;
- uint32_t size = sizeof(path);
- if (_NSGetExecutablePath(path, &size) == 0) {
- real_path = realpath(path, NULL);
- }
- std::string path_string(real_path);
- int last_slash = path_string.find_last_of("/");
- std::string directory = path_string.substr(0,last_slash);
+ uint32_t size = sizeof(path);
+ if (_NSGetExecutablePath(path, &size) == 0) {
+ real_path = realpath(path, NULL);
+ }
+ std::string path_string(real_path);
+ int last_slash = path_string.find_last_of("/");
+ std::string directory = path_string.substr(0,last_slash);
return directory;
}
diff --git a/library/include/Console.h b/library/include/Console.h
index 8d848135a..2f2f68cfa 100644
--- a/library/include/Console.h
+++ b/library/include/Console.h
@@ -65,20 +65,20 @@ namespace DFHack
bool save (const char * filename)
{
std::ofstream outfile (filename);
- //fprintf(stderr,"Save: Initialized stream\n");
+ //fprintf(stderr,"Save: Initialized stream\n");
if(outfile.bad())
return false;
- //fprintf(stderr,"Save: Iterating...\n");
+ //fprintf(stderr,"Save: Iterating...\n");
for(auto iter = history.begin();iter < history.end(); iter++)
{
- //fprintf(stderr,"Save: Dumping %s\n",(*iter).c_str());
+ //fprintf(stderr,"Save: Dumping %s\n",(*iter).c_str());
outfile << *iter << std::endl;
- //fprintf(stderr,"Save: Flushing\n");
- outfile.flush();
+ //fprintf(stderr,"Save: Flushing\n");
+ outfile.flush();
}
- //fprintf(stderr,"Save: Closing\n");
+ //fprintf(stderr,"Save: Closing\n");
outfile.close();
- //fprintf(stderr,"Save: Done\n");
+ //fprintf(stderr,"Save: Done\n");
return true;
}
/// add a command to the history
diff --git a/library/include/DataDefs.h b/library/include/DataDefs.h
index 32ffabc32..3591be045 100644
--- a/library/include/DataDefs.h
+++ b/library/include/DataDefs.h
@@ -35,7 +35,7 @@ distribution.
// Stop some MS stupidity
#ifdef interface
- #undef interface
+ #undef interface
#endif
typedef struct lua_State lua_State;
diff --git a/library/include/TileTypes.h b/library/include/TileTypes.h
index 48c10146a..f46cf2f2c 100644
--- a/library/include/TileTypes.h
+++ b/library/include/TileTypes.h
@@ -41,7 +41,7 @@ namespace DFHack
struct
{
//Maybe should add 'up' and 'down' for Z-levels?
- unsigned char north,south,west,east;
+ unsigned char north,south,west,east;
};
inline TileDirection()
diff --git a/library/include/modules/Graphic.h b/library/include/modules/Graphic.h
index a4b2dad10..8ee9c33b0 100644
--- a/library/include/modules/Graphic.h
+++ b/library/include/modules/Graphic.h
@@ -36,55 +36,55 @@ distribution.
namespace DFHack
{
- // SDL stuff
- typedef signed short SINT16;
- typedef struct
- {
- int16_t x, y;
- uint16_t w, h;
- } DFSDL_Rect;
- typedef struct
- {
- uint32_t flags;
- void* format; // PixelFormat*
- int w, h;
- int pitch;
- void* pixels;
- void* userdata; // as far as i could see DF doesnt use this
- int locked;
- void* lock_data;
- DFSDL_Rect clip_rect;
- void* map;
- int refcount;
- } DFSDL_Surface;
+ // SDL stuff
+ typedef signed short SINT16;
+ typedef struct
+ {
+ int16_t x, y;
+ uint16_t w, h;
+ } DFSDL_Rect;
+ typedef struct
+ {
+ uint32_t flags;
+ void* format; // PixelFormat*
+ int w, h;
+ int pitch;
+ void* pixels;
+ void* userdata; // as far as i could see DF doesnt use this
+ int locked;
+ void* lock_data;
+ DFSDL_Rect clip_rect;
+ void* map;
+ int refcount;
+ } DFSDL_Surface;
- // =========
- struct DFTileSurface
- {
- bool paintOver; // draw over original tile?
- DFSDL_Surface* surface; // from where it should be drawn
- DFSDL_Rect* rect; // from which coords (NULL to draw whole surface)
- DFSDL_Rect* dstResize; // if not NULL dst rect will be resized (x/y/w/h will be added to original dst)
- };
+ // =========
+ struct DFTileSurface
+ {
+ bool paintOver; // draw over original tile?
+ DFSDL_Surface* surface; // from where it should be drawn
+ DFSDL_Rect* rect; // from which coords (NULL to draw whole surface)
+ DFSDL_Rect* dstResize; // if not NULL dst rect will be resized (x/y/w/h will be added to original dst)
+ };
- class DFHACK_EXPORT Graphic : public Module
- {
- public:
- Graphic();
- ~Graphic();
- bool Finish()
- {
- return true;
- }
- bool Register(DFTileSurface* (*func)(int,int));
- bool Unregister(DFTileSurface* (*func)(int,int));
- DFTileSurface* Call(int x, int y);
+ class DFHACK_EXPORT Graphic : public Module
+ {
+ public:
+ Graphic();
+ ~Graphic();
+ bool Finish()
+ {
+ return true;
+ }
+ bool Register(DFTileSurface* (*func)(int,int));
+ bool Unregister(DFTileSurface* (*func)(int,int));
+ DFTileSurface* Call(int x, int y);
- private:
- struct Private;
- Private *d;
- };
+ private:
+ struct Private;
+ Private *d;
+ };
}
diff --git a/library/modules/Graphic.cpp b/library/modules/Graphic.cpp
index 4188df2b8..e965bc7e1 100644
--- a/library/modules/Graphic.cpp
+++ b/library/modules/Graphic.cpp
@@ -48,63 +48,63 @@ Module* DFHack::createGraphic()
struct Graphic::Private
{
- bool Started;
- vector funcs;
+ bool Started;
+ vector funcs;
};
Graphic::Graphic()
{
- d = new Private;
+ d = new Private;
- d->Started = true;
+ d->Started = true;
}
Graphic::~Graphic()
{
- delete d;
+ delete d;
}
bool Graphic::Register(DFTileSurface* (*func)(int,int))
{
- d->funcs.push_back(func);
- return true;
+ d->funcs.push_back(func);
+ return true;
}
bool Graphic::Unregister(DFTileSurface* (*func)(int,int))
{
- if ( d->funcs.empty() ) return false;
-
- vector::iterator it = d->funcs.begin();
- while ( it != d->funcs.end() )
- {
- if ( *it == func )
- {
- d->funcs.erase(it);
- return true;
- }
- it++;
- }
-
- return false;
+ if ( d->funcs.empty() ) return false;
+
+ vector::iterator it = d->funcs.begin();
+ while ( it != d->funcs.end() )
+ {
+ if ( *it == func )
+ {
+ d->funcs.erase(it);
+ return true;
+ }
+ it++;
+ }
+
+ return false;
}
// This will return first DFTileSurface it can get (or NULL if theres none)
DFTileSurface* Graphic::Call(int x, int y)
{
- if ( d->funcs.empty() ) return NULL;
-
- DFTileSurface* temp = NULL;
-
- vector::iterator it = d->funcs.begin();
- while ( it != d->funcs.end() )
- {
- temp = (*it)(x,y);
- if ( temp != NULL )
- {
- return temp;
- }
- it++;
- }
-
- return NULL;
+ if ( d->funcs.empty() ) return NULL;
+
+ DFTileSurface* temp = NULL;
+
+ vector::iterator it = d->funcs.begin();
+ while ( it != d->funcs.end() )
+ {
+ temp = (*it)(x,y);
+ if ( temp != NULL )
+ {
+ return temp;
+ }
+ it++;
+ }
+
+ return NULL;
}
\ No newline at end of file
diff --git a/plugins/cleanowned.cpp b/plugins/cleanowned.cpp
index cd01fd616..28314d3f0 100644
--- a/plugins/cleanowned.cpp
+++ b/plugins/cleanowned.cpp
@@ -117,7 +117,7 @@ command_result df_cleanowned (color_ostream &out, vector & parameters)
else if (item->flags.bits.on_ground)
{
df::item_type type = item->getType();
- if(type == item_type::MEAT ||
+ if(type == item_type::MEAT ||
type == item_type::FISH ||
type == item_type::VERMIN ||
type == item_type::PET ||
diff --git a/plugins/devel/memview.cpp b/plugins/devel/memview.cpp
index 29b8403f8..a43e6a7bf 100644
--- a/plugins/devel/memview.cpp
+++ b/plugins/devel/memview.cpp
@@ -17,16 +17,16 @@ static tthread::mutex* mymutex=0;
struct memory_data
{
- void * addr;
- size_t len;
- size_t refresh;
- int state;
- uint8_t *buf,*lbuf;
- vector ranges;
+ void * addr;
+ size_t len;
+ size_t refresh;
+ int state;
+ uint8_t *buf,*lbuf;
+ vector ranges;
}memdata;
enum HEXVIEW_STATES
{
- STATE_OFF,STATE_ON
+ STATE_OFF,STATE_ON
};
command_result memview (color_ostream &out, vector & parameters);
@@ -34,151 +34,151 @@ 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;
+ 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;
+ 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");
+ }
+ if(lbuf[j+i]!=buf[j+i])
+ con.print("*%02X",buf[j+i]); //if modfied show a star
+ else
+ con.print(" %02X",buf[j+i]);
+ }
+ con.reset_color();
+ con.print(" | ");
+ for(size_t j=0;(j31)&&(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)
- {
- memdata.state=STATE_OFF;
- delete [] memdata.buf;
- delete [] memdata.lbuf;
- }
+ if(memdata.state==STATE_ON)
+ {
+ 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;
+ 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;
+ 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);
+ 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;
+ 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;
- mymutex->unlock();
- return CR_OK;
- }
- else
- {
- Deinit();
- bool isValid=false;
- for(size_t i=0;iunlock();
- return CR_OK;
- }
- memdata.state=STATE_ON;
- }
- if(parameters.size()>1)
- memdata.len=convert(parameters[1]);
- else
- memdata.len=20*16;
+ mymutex->lock();
+ Core::getInstance().p->getMemRanges(memdata.ranges);
+ memdata.addr=(void *)convert(parameters[0],true);
+ if(memdata.addr==0)
+ {
+ Deinit();
+ memdata.state=STATE_OFF;
+ mymutex->unlock();
+ return CR_OK;
+ }
+ else
+ {
+ Deinit();
+ bool isValid=false;
+ for(size_t i=0;iunlock();
+ return CR_OK;
+ }
+ 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;
+ 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;
+ 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;
+ mymutex->lock();
+ Deinit();
+ delete mymutex;
+ mymutex->unlock();
+ return CR_OK;
}
diff --git a/plugins/devel/nestboxes.cpp b/plugins/devel/nestboxes.cpp
index 42c3c0660..8c51b57ae 100644
--- a/plugins/devel/nestboxes.cpp
+++ b/plugins/devel/nestboxes.cpp
@@ -35,32 +35,32 @@ static bool enabled = false;
static void eggscan(color_ostream &out)
{
- CoreSuspender suspend;
-
- for (int i = 0; i < world->buildings.all.size(); ++i)
- {
- df::building *build = world->buildings.all[i];
- auto type = build->getType();
- if (df::enums::building_type::NestBox == type)
- {
+ CoreSuspender suspend;
+
+ for (int i = 0; i < world->buildings.all.size(); ++i)
+ {
+ df::building *build = world->buildings.all[i];
+ auto type = build->getType();
+ if (df::enums::building_type::NestBox == type)
+ {
bool fertile = false;
- df::building_nest_boxst *nb = virtual_cast(build);
- if (nb->claimed_by != -1)
+ df::building_nest_boxst *nb = virtual_cast(build);
+ if (nb->claimed_by != -1)
{
df::unit* u = df::unit::find(nb->claimed_by);
- if (u && u->relations.pregnancy_timer > 0)
+ if (u && u->relations.pregnancy_timer > 0)
fertile = true;
}
for (int j = 1; j < nb->contained_items.size(); j++)
{
df::item* item = nb->contained_items[j]->item;
- if (item->flags.bits.forbid != fertile)
- {
- item->flags.bits.forbid = fertile;
- out << item->getStackSize() << " eggs " << (fertile ? "forbidden" : "unforbidden.") << endl;
- }
+ if (item->flags.bits.forbid != fertile)
+ {
+ item->flags.bits.forbid = fertile;
+ out << item->getStackSize() << " eggs " << (fertile ? "forbidden" : "unforbidden.") << endl;
+ }
}
- }
+ }
}
}
@@ -68,12 +68,12 @@ static void eggscan(color_ostream &out)
DFhackCExport command_result plugin_init (color_ostream &out, std::vector &commands)
{
if (world && ui) {
- commands.push_back(
- PluginCommand("nestboxes", "Derp.",
- nestboxes, false,
- "Derp.\n"
- )
- );
+ commands.push_back(
+ PluginCommand("nestboxes", "Derp.",
+ nestboxes, false,
+ "Derp.\n"
+ )
+ );
}
return CR_OK;
}
@@ -92,28 +92,28 @@ DFhackCExport command_result plugin_onupdate(color_ostream &out)
if ((++cnt % 5) != 0)
return CR_OK;
- eggscan(out);
+ eggscan(out);
return CR_OK;
}
static command_result nestboxes(color_ostream &out, vector & parameters)
{
- CoreSuspender suspend;
- bool clean = false;
+ CoreSuspender suspend;
+ bool clean = false;
int dump_count = 0;
int good_egg = 0;
- if (parameters.size() == 1) {
- if (parameters[0] == "enable")
- enabled = true;
- else if (parameters[0] == "disable")
- enabled = false;
- else
- return CR_WRONG_USAGE;
- } else {
- out << "Plugin " << (enabled ? "enabled" : "disabled") << "." << endl;
- }
- return CR_OK;
+ if (parameters.size() == 1) {
+ if (parameters[0] == "enable")
+ enabled = true;
+ else if (parameters[0] == "disable")
+ enabled = false;
+ else
+ return CR_WRONG_USAGE;
+ } else {
+ out << "Plugin " << (enabled ? "enabled" : "disabled") << "." << endl;
+ }
+ return CR_OK;
}
diff --git a/plugins/devel/rprobe.cpp b/plugins/devel/rprobe.cpp
index 805489d5e..9591fa8f1 100644
--- a/plugins/devel/rprobe.cpp
+++ b/plugins/devel/rprobe.cpp
@@ -67,10 +67,10 @@ command_result rprobe (color_ostream &out, vector & parameters)
// Embark screen active: estimate using world geology data
VIRTUAL_CAST_VAR(screen, df::viewscreen_choose_start_sitest, Core::getTopViewscreen());
-
- if (!screen)
- return CR_WRONG_USAGE;
-
+
+ if (!screen)
+ return CR_WRONG_USAGE;
+
if (!world || !world->world_data)
{
out.printerr("World data is not available.\n");
@@ -78,9 +78,9 @@ command_result rprobe (color_ostream &out, vector & parameters)
}
- if (parameters.size() == 2)
+ if (parameters.size() == 2)
{
- if (parameters[0] == "rai")
+ if (parameters[0] == "rai")
set_field = 0;
else if (parameters[0] == "veg")
set_field = 1;
@@ -97,7 +97,7 @@ command_result rprobe (color_ostream &out, vector & parameters)
else
return CR_WRONG_USAGE;
- if (screen->biome_highlighted)
+ if (screen->biome_highlighted)
to_set = screen->biome_idx;
else
to_set = 0;
@@ -110,7 +110,7 @@ command_result rprobe (color_ostream &out, vector & parameters)
coord2d cur_region = screen->region_pos;
// Compute biomes
- for (int i = 0; i < screen->biome_rgn.size(); i++)
+ for (int i = 0; i < screen->biome_rgn.size(); i++)
{
coord2d rg = screen->biome_rgn[i];
@@ -140,7 +140,7 @@ command_result rprobe (color_ostream &out, vector & parameters)
" geo_index: " << rd->geo_index <<
" landmass_id: " << rd->landmass_id <<
" flags: " << hex << rd->flags.as_int() << dec << endl;
- out <<
+ out <<
"rai: " << rd->rainfall << " " <<
"veg: " << rd->vegetation << " " <<
"tem: " << rd->temperature << " " <<
@@ -148,17 +148,17 @@ command_result rprobe (color_ostream &out, vector & parameters)
"dra: " << rd->drainage << " " <<
"sav: " << rd->savagery << " " <<
"sal: " << rd->salinity;
-
+
int32_t *p = (int32_t *)rd;
int c = sizeof(*rd) / sizeof(int32_t);
for (int j = 0; j < c; j++) {
- if (j % 8 == 0)
+ if (j % 8 == 0)
out << endl << setfill('0') << setw(8) << hex << (int)(rd+j) << ": ";
out << " " << setfill('0') << setw(8) << hex << p[j];
}
out << setfill(' ') << setw(0) << dec << endl;
}
-
+
return CR_OK;
}
diff --git a/plugins/devel/stockcheck.cpp b/plugins/devel/stockcheck.cpp
index 57be4b126..666db0d79 100644
--- a/plugins/devel/stockcheck.cpp
+++ b/plugins/devel/stockcheck.cpp
@@ -38,12 +38,12 @@ DFHACK_PLUGIN("stockcheck");
DFhackCExport command_result plugin_init (color_ostream &out, std::vector &commands)
{
if (world && ui) {
- commands.push_back(
- PluginCommand("stockcheck", "Check for unprotected rottable items.",
- stockcheck, false,
- "Scan world for items that are susceptible to rot. Currently just lists the items.\n"
- )
- );
+ commands.push_back(
+ PluginCommand("stockcheck", "Check for unprotected rottable items.",
+ stockcheck, false,
+ "Scan world for items that are susceptible to rot. Currently just lists the items.\n"
+ )
+ );
}
return CR_OK;
}
@@ -54,90 +54,90 @@ DFhackCExport command_result plugin_shutdown ( color_ostream &out )
}
struct StockpileInfo {
- building_stockpilest* sp;
- int size;
- int free;
- int x1, x2, y1, y2, z;
+ building_stockpilest* sp;
+ int size;
+ int free;
+ int x1, x2, y1, y2, z;
public:
- StockpileInfo(building_stockpilest *sp_) : sp(sp_)
- {
- MapExtras::MapCache mc;
-
- z = sp_->z;
- x1 = sp_->room.x;
- x2 = sp_->room.x + sp_->room.width;
- y1 = sp_->room.y;
- y2 = sp_->room.y + sp_->room.height;
- int e = 0;
- size = 0;
- free = 0;
- for (int y = y1; y < y2; y++)
- for (int x = x1; x < x2; x++)
- if (sp_->room.extents[e++] == 1)
- {
- size++;
- DFCoord cursor (x,y,z);
- uint32_t blockX = x / 16;
- uint32_t tileX = x % 16;
- uint32_t blockY = y / 16;
- uint32_t tileY = y % 16;
- MapExtras::Block * b = mc.BlockAt(cursor/16);
- if(b && b->is_valid())
- {
- auto &block = *b->getRaw();
- df::tile_occupancy &occ = block.occupancy[tileX][tileY];
- if (!occ.bits.item)
- free++;
- }
- }
- }
-
- bool isFull() { return free == 0; }
-
- bool canHold(df::item *i)
- {
- return false;
- }
-
- bool inStockpile(df::item *i)
- {
- df::item *container = Items::getContainer(i);
- if (container)
- return inStockpile(container);
-
- if (i->pos.z != z) return false;
- if (i->pos.x < x1 || i->pos.x >= x2 ||
- i->pos.y < y1 || i->pos.y >= y2) return false;
- int e = (i->pos.x - x1) + (i->pos.y - y1) * sp->room.width;
- return sp->room.extents[e] == 1;
- }
-
- int getId() { return sp->id; }
+ StockpileInfo(building_stockpilest *sp_) : sp(sp_)
+ {
+ MapExtras::MapCache mc;
+
+ z = sp_->z;
+ x1 = sp_->room.x;
+ x2 = sp_->room.x + sp_->room.width;
+ y1 = sp_->room.y;
+ y2 = sp_->room.y + sp_->room.height;
+ int e = 0;
+ size = 0;
+ free = 0;
+ for (int y = y1; y < y2; y++)
+ for (int x = x1; x < x2; x++)
+ if (sp_->room.extents[e++] == 1)
+ {
+ size++;
+ DFCoord cursor (x,y,z);
+ uint32_t blockX = x / 16;
+ uint32_t tileX = x % 16;
+ uint32_t blockY = y / 16;
+ uint32_t tileY = y % 16;
+ MapExtras::Block * b = mc.BlockAt(cursor/16);
+ if(b && b->is_valid())
+ {
+ auto &block = *b->getRaw();
+ df::tile_occupancy &occ = block.occupancy[tileX][tileY];
+ if (!occ.bits.item)
+ free++;
+ }
+ }
+ }
+
+ bool isFull() { return free == 0; }
+
+ bool canHold(df::item *i)
+ {
+ return false;
+ }
+
+ bool inStockpile(df::item *i)
+ {
+ df::item *container = Items::getContainer(i);
+ if (container)
+ return inStockpile(container);
+
+ if (i->pos.z != z) return false;
+ if (i->pos.x < x1 || i->pos.x >= x2 ||
+ i->pos.y < y1 || i->pos.y >= y2) return false;
+ int e = (i->pos.x - x1) + (i->pos.y - y1) * sp->room.width;
+ return sp->room.extents[e] == 1;
+ }
+
+ int getId() { return sp->id; }
};
static command_result stockcheck(color_ostream &out, vector & parameters)
{
- CoreSuspender suspend;
-
- std::vector stockpiles;
-
- for (int i = 0; i < world->buildings.all.size(); ++i)
- {
- df::building *build = world->buildings.all[i];
- auto type = build->getType();
- if (df::enums::building_type::Stockpile == type)
- {
- building_stockpilest *sp = virtual_cast(build);
- StockpileInfo *spi = new StockpileInfo(sp);
- stockpiles.push_back(spi);
- }
-
- }
-
- std::vector &items = world->items.other[items_other_id::IN_PLAY];
-
- // Precompute a bitmask with the bad flags
+ CoreSuspender suspend;
+
+ std::vector stockpiles;
+
+ for (int i = 0; i < world->buildings.all.size(); ++i)
+ {
+ df::building *build = world->buildings.all[i];
+ auto type = build->getType();
+ if (df::enums::building_type::Stockpile == type)
+ {
+ building_stockpilest *sp = virtual_cast(build);
+ StockpileInfo *spi = new StockpileInfo(sp);
+ stockpiles.push_back(spi);
+ }
+
+ }
+
+ std::vector &items = world->items.other[items_other_id::IN_PLAY];
+
+ // Precompute a bitmask with the bad flags
df::item_flags bad_flags;
bad_flags.whole = 0;
@@ -145,30 +145,30 @@ static command_result stockcheck(color_ostream &out, vector & parameter
F(dump); F(forbid); F(garbage_collect);
F(hostile); F(on_fire); F(rotten); F(trader);
F(in_building); F(construction); F(artifact1);
- F(spider_web); F(owned); F(in_job);
+ F(spider_web); F(owned); F(in_job);
#undef F
for (size_t i = 0; i < items.size(); i++)
{
df::item *item = items[i];
- if (item->flags.whole & bad_flags.whole)
+ if (item->flags.whole & bad_flags.whole)
continue;
- // we really only care about MEAT, FISH, FISH_RAW, PLANT, CHEESE, FOOD, and EGG
+ // we really only care about MEAT, FISH, FISH_RAW, PLANT, CHEESE, FOOD, and EGG
- df::item_type typ = item->getType();
- if (typ != df::enums::item_type::MEAT &&
- typ != df::enums::item_type::FISH &&
- typ != df::enums::item_type::FISH_RAW &&
- typ != df::enums::item_type::PLANT &&
- typ != df::enums::item_type::CHEESE &&
- typ != df::enums::item_type::FOOD &&
- typ != df::enums::item_type::EGG)
- continue;
+ df::item_type typ = item->getType();
+ if (typ != df::enums::item_type::MEAT &&
+ typ != df::enums::item_type::FISH &&
+ typ != df::enums::item_type::FISH_RAW &&
+ typ != df::enums::item_type::PLANT &&
+ typ != df::enums::item_type::CHEESE &&
+ typ != df::enums::item_type::FOOD &&
+ typ != df::enums::item_type::EGG)
+ continue;
- df::item *container = 0;
- df::unit *holder = 0;
- df::building *building = 0;
+ df::item *container = 0;
+ df::unit *holder = 0;
+ df::building *building = 0;
for (size_t i = 0; i < item->general_refs.size(); i++)
{
@@ -177,106 +177,106 @@ static command_result stockcheck(color_ostream &out, vector & parameter
switch (ref->getType())
{
case general_ref_type::CONTAINED_IN_ITEM:
- container = ref->getItem();
+ container = ref->getItem();
break;
case general_ref_type::UNIT_HOLDER:
- holder = ref->getUnit();
+ holder = ref->getUnit();
break;
case general_ref_type::BUILDING_HOLDER:
- building = ref->getBuilding();
+ building = ref->getBuilding();
break;
default:
break;
- }
- }
+ }
+ }
- df::item *nextcontainer = container;
- df::item *lastcontainer = 0;
+ df::item *nextcontainer = container;
+ df::item *lastcontainer = 0;
- while(nextcontainer) {
- df::item *thiscontainer = nextcontainer;
- nextcontainer = 0;
- for (size_t i = 0; i < thiscontainer->general_refs.size(); i++)
- {
- df::general_ref *ref = thiscontainer->general_refs[i];
+ while(nextcontainer) {
+ df::item *thiscontainer = nextcontainer;
+ nextcontainer = 0;
+ for (size_t i = 0; i < thiscontainer->general_refs.size(); i++)
+ {
+ df::general_ref *ref = thiscontainer->general_refs[i];
- switch (ref->getType())
- {
- case general_ref_type::CONTAINED_IN_ITEM:
- lastcontainer = nextcontainer = ref->getItem();
- break;
+ switch (ref->getType())
+ {
+ case general_ref_type::CONTAINED_IN_ITEM:
+ lastcontainer = nextcontainer = ref->getItem();
+ break;
- case general_ref_type::UNIT_HOLDER:
- holder = ref->getUnit();
- break;
+ case general_ref_type::UNIT_HOLDER:
+ holder = ref->getUnit();
+ break;
- case general_ref_type::BUILDING_HOLDER:
- building = ref->getBuilding();
- break;
+ case general_ref_type::BUILDING_HOLDER:
+ building = ref->getBuilding();
+ break;
default:
break;
- }
- }
- }
-
- if (holder)
- continue; // carried items do not rot as far as i know
-
- if (building) {
- df::building_type btype = building->getType();
- if (btype == df::enums::building_type::TradeDepot ||
- btype == df::enums::building_type::Wagon)
- continue; // items in trade depot or the embark wagon do not rot
-
- if (typ == df::enums::item_type::EGG && btype ==df::enums::building_type::NestBox)
- continue; // eggs in nest box do not rot
- }
-
- int canHoldCount = 0;
- StockpileInfo *current = 0;
-
- for (int idx = 0; idx < stockpiles.size(); idx++)
- {
- StockpileInfo *spi = stockpiles[idx];
- if (spi->canHold(item)) canHoldCount++;
- if (spi->inStockpile(item)) current=spi;
- }
-
- if (current)
- continue;
-
- std::string description;
- item->getItemDescription(&description, 0);
- out << " * " << description;
+ }
+ }
+ }
+
+ if (holder)
+ continue; // carried items do not rot as far as i know
+
+ if (building) {
+ df::building_type btype = building->getType();
+ if (btype == df::enums::building_type::TradeDepot ||
+ btype == df::enums::building_type::Wagon)
+ continue; // items in trade depot or the embark wagon do not rot
+
+ if (typ == df::enums::item_type::EGG && btype ==df::enums::building_type::NestBox)
+ continue; // eggs in nest box do not rot
+ }
+
+ int canHoldCount = 0;
+ StockpileInfo *current = 0;
+
+ for (int idx = 0; idx < stockpiles.size(); idx++)
+ {
+ StockpileInfo *spi = stockpiles[idx];
+ if (spi->canHold(item)) canHoldCount++;
+ if (spi->inStockpile(item)) current=spi;
+ }
+
+ if (current)
+ continue;
+
+ std::string description;
+ item->getItemDescription(&description, 0);
+ out << " * " << description;
if (container) {
- std::string containerDescription;
- container->getItemDescription(&containerDescription, 0);
- out << ", in container " << containerDescription;
- if (lastcontainer) {
- std::string lastcontainerDescription;
- lastcontainer->getItemDescription(&lastcontainerDescription, 0);
- out << ", in container " << lastcontainerDescription;
- }
- }
-
- if (holder) {
- out << ", carried";
- }
-
- if (building) {
- out << ", in building " << building->id << " (type=" << building->getType() << ")";
- }
-
- out << ", flags=" << std::hex << item->flags.whole << std::dec;
- out << endl;
-
- }
-
- return CR_OK;
+ std::string containerDescription;
+ container->getItemDescription(&containerDescription, 0);
+ out << ", in container " << containerDescription;
+ if (lastcontainer) {
+ std::string lastcontainerDescription;
+ lastcontainer->getItemDescription(&lastcontainerDescription, 0);
+ out << ", in container " << lastcontainerDescription;
+ }
+ }
+
+ if (holder) {
+ out << ", carried";
+ }
+
+ if (building) {
+ out << ", in building " << building->id << " (type=" << building->getType() << ")";
+ }
+
+ out << ", flags=" << std::hex << item->flags.whole << std::dec;
+ out << endl;
+
+ }
+
+ return CR_OK;
}
diff --git a/plugins/devel/stripcaged.cpp b/plugins/devel/stripcaged.cpp
index a7683a9bb..30d0b0d2b 100644
--- a/plugins/devel/stripcaged.cpp
+++ b/plugins/devel/stripcaged.cpp
@@ -61,11 +61,11 @@ bool isContainedInItem(df::unit* unit)
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector &commands)
{
- commands.push_back(PluginCommand(
- "stripcaged", "strip caged units of all items",
- df_stripcaged, false,
- "Clears forbid and sets dump for the inventories of all caged units."
- ));
+ commands.push_back(PluginCommand(
+ "stripcaged", "strip caged units of all items",
+ df_stripcaged, false,
+ "Clears forbid and sets dump for the inventories of all caged units."
+ ));
return CR_OK;
}
@@ -77,39 +77,39 @@ DFhackCExport command_result plugin_shutdown ( color_ostream &out )
command_result df_stripcaged(color_ostream &out, vector & parameters)
{
CoreSuspender suspend;
- bool keeparmor = true;
+ bool keeparmor = true;
- if (parameters.size() == 1 && parameters[0] == "dumparmor")
- {
- out << "Dumping armor too" << endl;
- keeparmor = false;
- }
+ if (parameters.size() == 1 && parameters[0] == "dumparmor")
+ {
+ out << "Dumping armor too" << endl;
+ keeparmor = false;
+ }
- size_t count = 0;
+ size_t count = 0;
for (size_t i=0; i < world->units.all.size(); i++)
{
df::unit* unit = world->units.all[i];
- if (isContainedInItem(unit))
- {
- for (size_t j=0; j < unit->inventory.size(); j++)
- {
- df::unit_inventory_item* uii = unit->inventory[j];
- if (uii->item)
- {
- if (keeparmor && (uii->item->isArmorNotClothing() || uii->item->isClothing()))
- continue;
- std::string desc;
- uii->item->getItemDescription(&desc,0);
- out << "Item " << desc << " dumped." << endl;
- uii->item->flags.bits.forbid = 0;
- uii->item->flags.bits.dump = 1;
- count++;
- }
- }
- }
- }
+ if (isContainedInItem(unit))
+ {
+ for (size_t j=0; j < unit->inventory.size(); j++)
+ {
+ df::unit_inventory_item* uii = unit->inventory[j];
+ if (uii->item)
+ {
+ if (keeparmor && (uii->item->isArmorNotClothing() || uii->item->isClothing()))
+ continue;
+ std::string desc;
+ uii->item->getItemDescription(&desc,0);
+ out << "Item " << desc << " dumped." << endl;
+ uii->item->flags.bits.forbid = 0;
+ uii->item->flags.bits.dump = 1;
+ count++;
+ }
+ }
+ }
+ }
- out << count << " items marked for dumping" << endl;
+ out << count << " items marked for dumping" << endl;
return CR_OK;
}
diff --git a/plugins/dfstream.cpp b/plugins/dfstream.cpp
index 1ed906881..19334abae 100644
--- a/plugins/dfstream.cpp
+++ b/plugins/dfstream.cpp
@@ -323,7 +323,7 @@ public:
auto_renderer_decorator & operator=(renderer_decorator *p) {
reset();
this->p = p;
- return *this;
+ return *this;
}
renderer_decorator * get() {
diff --git a/plugins/filltraffic.cpp b/plugins/filltraffic.cpp
index 6e87fd854..eeacc8781 100644
--- a/plugins/filltraffic.cpp
+++ b/plugins/filltraffic.cpp
@@ -1,7 +1,7 @@
// Wide-area traffic designation utility.
// Flood-fill from cursor or fill entire map.
-#include //For toupper().
+#include //For toupper().
#include //for min().
#include