Merge branch 'master' of git://github.com/peterix/dfhack
commit
b851ee2d22
@ -0,0 +1,234 @@
|
|||||||
|
--[[ DataDumper.lua
|
||||||
|
Copyright (c) 2007 Olivetti-Engineering SA
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person
|
||||||
|
obtaining a copy of this software and associated documentation
|
||||||
|
files (the "Software"), to deal in the Software without
|
||||||
|
restriction, including without limitation the rights to use,
|
||||||
|
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following
|
||||||
|
conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
]]
|
||||||
|
|
||||||
|
local _ENV = mkmodule('dumper')
|
||||||
|
|
||||||
|
local dumplua_closure = [[
|
||||||
|
local closures = {}
|
||||||
|
local function closure(t)
|
||||||
|
closures[#closures+1] = t
|
||||||
|
t[1] = assert(loadstring(t[1]))
|
||||||
|
return t[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
for _,t in pairs(closures) do
|
||||||
|
for i = 2,#t do
|
||||||
|
debug.setupvalue(t[1], i-1, t[i])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
]]
|
||||||
|
|
||||||
|
local lua_reserved_keywords = {
|
||||||
|
'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for',
|
||||||
|
'function', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat',
|
||||||
|
'return', 'then', 'true', 'until', 'while' }
|
||||||
|
|
||||||
|
local function keys(t)
|
||||||
|
local res = {}
|
||||||
|
local oktypes = { stringstring = true, numbernumber = true }
|
||||||
|
local function cmpfct(a,b)
|
||||||
|
if oktypes[type(a)..type(b)] then
|
||||||
|
return a < b
|
||||||
|
else
|
||||||
|
return type(a) < type(b)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for k in pairs(t) do
|
||||||
|
res[#res+1] = k
|
||||||
|
end
|
||||||
|
table.sort(res, cmpfct)
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
local c_functions = {}
|
||||||
|
for _,lib in pairs{'_G', 'string', 'table', 'math',
|
||||||
|
'io', 'os', 'coroutine', 'package', 'debug'} do
|
||||||
|
local t = _G[lib] or {}
|
||||||
|
lib = lib .. "."
|
||||||
|
if lib == "_G." then lib = "" end
|
||||||
|
for k,v in pairs(t) do
|
||||||
|
if type(v) == 'function' and not pcall(string.dump, v) then
|
||||||
|
c_functions[v] = lib..k
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function DataDumper(value, varname, fastmode, ident, indent_step)
|
||||||
|
indent_step = indent_step or 2
|
||||||
|
local defined, dumplua = {}
|
||||||
|
-- Local variables for speed optimization
|
||||||
|
local string_format, type, string_dump, string_rep =
|
||||||
|
string.format, type, string.dump, string.rep
|
||||||
|
local tostring, pairs, table_concat =
|
||||||
|
tostring, pairs, table.concat
|
||||||
|
local keycache, strvalcache, out, closure_cnt = {}, {}, {}, 0
|
||||||
|
setmetatable(strvalcache, {__index = function(t,value)
|
||||||
|
local res = string_format('%q', value)
|
||||||
|
t[value] = res
|
||||||
|
return res
|
||||||
|
end})
|
||||||
|
local fcts = {
|
||||||
|
string = function(value) return strvalcache[value] end,
|
||||||
|
number = function(value) return value end,
|
||||||
|
boolean = function(value) return tostring(value) end,
|
||||||
|
['nil'] = function(value) return 'nil' end,
|
||||||
|
['function'] = function(value)
|
||||||
|
return string_format("loadstring(%q)", string_dump(value))
|
||||||
|
end,
|
||||||
|
userdata = function() error("Cannot dump userdata") end,
|
||||||
|
thread = function() error("Cannot dump threads") end,
|
||||||
|
}
|
||||||
|
local function test_defined(value, path)
|
||||||
|
if defined[value] then
|
||||||
|
if path:match("^getmetatable.*%)$") then
|
||||||
|
out[#out+1] = string_format("s%s, %s)\n", path:sub(2,-2), defined[value])
|
||||||
|
else
|
||||||
|
out[#out+1] = path .. " = " .. defined[value] .. "\n"
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
defined[value] = path
|
||||||
|
end
|
||||||
|
local function make_key(t, key)
|
||||||
|
local s
|
||||||
|
if type(key) == 'string' and key:match('^[_%a][_%w]*$') then
|
||||||
|
s = key .. "="
|
||||||
|
else
|
||||||
|
s = "[" .. dumplua(key, 0) .. "]="
|
||||||
|
end
|
||||||
|
t[key] = s
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
for _,k in ipairs(lua_reserved_keywords) do
|
||||||
|
keycache[k] = '["'..k..'"] = '
|
||||||
|
end
|
||||||
|
if fastmode then
|
||||||
|
fcts.table = function (value)
|
||||||
|
-- Table value
|
||||||
|
local numidx = 1
|
||||||
|
out[#out+1] = "{"
|
||||||
|
for key,val in pairs(value) do
|
||||||
|
if key == numidx then
|
||||||
|
numidx = numidx + 1
|
||||||
|
else
|
||||||
|
out[#out+1] = keycache[key]
|
||||||
|
end
|
||||||
|
local str = dumplua(val)
|
||||||
|
out[#out+1] = str..","
|
||||||
|
end
|
||||||
|
if string.sub(out[#out], -1) == "," then
|
||||||
|
out[#out] = string.sub(out[#out], 1, -2);
|
||||||
|
end
|
||||||
|
out[#out+1] = "}"
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
else
|
||||||
|
fcts.table = function (value, ident, path)
|
||||||
|
if test_defined(value, path) then return "nil" end
|
||||||
|
-- Table value
|
||||||
|
local sep, str, numidx, totallen = " ", {}, 1, 0
|
||||||
|
local meta, metastr = (debug or getfenv()).getmetatable(value)
|
||||||
|
if meta then
|
||||||
|
ident = ident + 1
|
||||||
|
metastr = dumplua(meta, ident, "getmetatable("..path..")")
|
||||||
|
totallen = totallen + #metastr + 16
|
||||||
|
end
|
||||||
|
for _,key in pairs(keys(value)) do
|
||||||
|
local val = value[key]
|
||||||
|
local s = ""
|
||||||
|
local subpath = path
|
||||||
|
if key == numidx then
|
||||||
|
subpath = subpath .. "[" .. numidx .. "]"
|
||||||
|
numidx = numidx + 1
|
||||||
|
else
|
||||||
|
s = keycache[key]
|
||||||
|
if not s:match "^%[" then subpath = subpath .. "." end
|
||||||
|
subpath = subpath .. s:gsub("%s*=%s*$","")
|
||||||
|
end
|
||||||
|
s = s .. dumplua(val, ident+1, subpath)
|
||||||
|
str[#str+1] = s
|
||||||
|
totallen = totallen + #s + 2
|
||||||
|
end
|
||||||
|
if totallen > 80 then
|
||||||
|
sep = "\n" .. string_rep(' ', indent_step*(ident+1))
|
||||||
|
end
|
||||||
|
str = "{"..sep..table_concat(str, ","..sep).." "..sep:sub(1,-1-indent_step).."}"
|
||||||
|
if meta then
|
||||||
|
sep = sep:sub(1,-3)
|
||||||
|
return "setmetatable("..sep..str..","..sep..metastr..sep:sub(1,-3)..")"
|
||||||
|
end
|
||||||
|
return str
|
||||||
|
end
|
||||||
|
fcts['function'] = function (value, ident, path)
|
||||||
|
if test_defined(value, path) then return "nil" end
|
||||||
|
if c_functions[value] then
|
||||||
|
return c_functions[value]
|
||||||
|
elseif debug == nil or debug.getupvalue(value, 1) == nil then
|
||||||
|
return string_format("loadstring(%q)", string_dump(value))
|
||||||
|
end
|
||||||
|
closure_cnt = closure_cnt + 1
|
||||||
|
local res = {string.dump(value)}
|
||||||
|
for i = 1,math.huge do
|
||||||
|
local name, v = debug.getupvalue(value,i)
|
||||||
|
if name == nil then break end
|
||||||
|
res[i+1] = v
|
||||||
|
end
|
||||||
|
return "closure " .. dumplua(res, ident, "closures["..closure_cnt.."]")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function dumplua(value, ident, path)
|
||||||
|
return fcts[type(value)](value, ident, path)
|
||||||
|
end
|
||||||
|
if varname == nil then
|
||||||
|
varname = "return "
|
||||||
|
elseif varname:match("^[%a_][%w_]*$") then
|
||||||
|
varname = varname .. " = "
|
||||||
|
end
|
||||||
|
if fastmode then
|
||||||
|
setmetatable(keycache, {__index = make_key })
|
||||||
|
out[1] = varname
|
||||||
|
table.insert(out,dumplua(value, 0))
|
||||||
|
return table.concat(out)
|
||||||
|
else
|
||||||
|
setmetatable(keycache, {__index = make_key })
|
||||||
|
local items = {}
|
||||||
|
for i=1,10 do items[i] = '' end
|
||||||
|
items[3] = dumplua(value, ident or 0, "t")
|
||||||
|
if closure_cnt > 0 then
|
||||||
|
items[1], items[6] = dumplua_closure:match("(.*\n)\n(.*)")
|
||||||
|
out[#out+1] = ""
|
||||||
|
end
|
||||||
|
if #out > 0 then
|
||||||
|
items[2], items[4] = "local t = ", "\n"
|
||||||
|
items[5] = table.concat(out)
|
||||||
|
items[7] = varname .. "t"
|
||||||
|
else
|
||||||
|
items[2] = varname
|
||||||
|
end
|
||||||
|
return table.concat(items)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return _ENV
|
@ -1 +1 @@
|
|||||||
Subproject commit 970bb0ae9530e9c0522cb0ca8fe357815d72fab1
|
Subproject commit f004804fd655efcb4bf9ea31bd95ae4f759937b4
|
@ -1 +1 @@
|
|||||||
Subproject commit 15e3b726c3e68d2985aecd95d2a33bf4550caaa1
|
Subproject commit 37a823541538023b9f3d0d1e8039cf32851de68d
|
@ -0,0 +1,42 @@
|
|||||||
|
-- Lists and/or compares two tiletype material groups.
|
||||||
|
-- Usage: devel/cmptiles material1 [material2]
|
||||||
|
|
||||||
|
local nmat1,nmat2=...
|
||||||
|
local mat1 = df.tiletype_material[nmat1]
|
||||||
|
local mat2 = df.tiletype_material[nmat2]
|
||||||
|
|
||||||
|
local tmat1 = {}
|
||||||
|
local tmat2 = {}
|
||||||
|
|
||||||
|
local attrs = df.tiletype.attrs
|
||||||
|
|
||||||
|
for i=df.tiletype._first_item,df.tiletype._last_item do
|
||||||
|
local shape = df.tiletype_shape[attrs[i].shape] or ''
|
||||||
|
local variant = df.tiletype_variant[attrs[i].variant] or ''
|
||||||
|
local special = df.tiletype_special[attrs[i].special] or ''
|
||||||
|
local direction = attrs[i].direction or ''
|
||||||
|
local code = shape..':'..variant..':'..special..':'..direction
|
||||||
|
|
||||||
|
if attrs[i].material == mat1 then
|
||||||
|
tmat1[code] = true
|
||||||
|
end
|
||||||
|
if attrs[i].material == mat2 then
|
||||||
|
tmat2[code] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function list_diff(n, t1, t2)
|
||||||
|
local lst = {}
|
||||||
|
for k,v in pairs(t1) do
|
||||||
|
if not t2[k] then
|
||||||
|
lst[#lst+1] = k
|
||||||
|
end
|
||||||
|
end
|
||||||
|
table.sort(lst)
|
||||||
|
for k,v in ipairs(lst) do
|
||||||
|
print(n, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
list_diff(nmat1,tmat1,tmat2)
|
||||||
|
list_diff(nmat2,tmat2,tmat1)
|
@ -0,0 +1,72 @@
|
|||||||
|
-- List input items for the building currently being built.
|
||||||
|
--
|
||||||
|
-- This is where the filters in lua/dfhack/buildings.lua come from.
|
||||||
|
|
||||||
|
local dumper = require 'dumper'
|
||||||
|
local utils = require 'utils'
|
||||||
|
local buildings = require 'dfhack.buildings'
|
||||||
|
|
||||||
|
local function name_enum(tgt,name,ename,enum)
|
||||||
|
if tgt[name] ~= nil then
|
||||||
|
tgt[name] = ename..'.'..enum[tgt[name]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local lookup = {}
|
||||||
|
local items = df.global.world.items
|
||||||
|
|
||||||
|
for i=df.job_item_vector_id._first_item,df.job_item_vector_id._last_item do
|
||||||
|
local id = df.job_item_vector_id.attrs[i].other
|
||||||
|
local ptr
|
||||||
|
if id == df.items_other_id.ANY then
|
||||||
|
ptr = items.all
|
||||||
|
elseif id == df.items_other_id.BAD then
|
||||||
|
ptr = items.bad
|
||||||
|
else
|
||||||
|
ptr = items.other[id]
|
||||||
|
end
|
||||||
|
if ptr then
|
||||||
|
local _,addr = df.sizeof(ptr)
|
||||||
|
lookup[addr] = 'df.job_item_vector_id.'..df.job_item_vector_id[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function clone_filter(src,quantity)
|
||||||
|
local tgt = utils.clone_with_default(src, buildings.input_filter_defaults, true)
|
||||||
|
if quantity ~= 1 then
|
||||||
|
tgt.quantity = quantity
|
||||||
|
end
|
||||||
|
name_enum(tgt, 'item_type', 'df.item_type', df.item_type)
|
||||||
|
name_enum(tgt, 'has_tool_use', 'df.tool_uses', df.tool_uses)
|
||||||
|
local ptr = src.item_vector
|
||||||
|
if ptr and ptr ~= df.global.world.items.other[0] then
|
||||||
|
local _,addr = df.sizeof(ptr)
|
||||||
|
tgt.vector_id = lookup[addr]
|
||||||
|
end
|
||||||
|
return tgt
|
||||||
|
end
|
||||||
|
|
||||||
|
local function dump(name)
|
||||||
|
local out = {}
|
||||||
|
for i,v in ipairs(df.global.ui_build_selector.requirements) do
|
||||||
|
out[#out+1] = clone_filter(v.filter, v.count_required)
|
||||||
|
end
|
||||||
|
|
||||||
|
local fmt = dumper.DataDumper(out,name,false,1,4)
|
||||||
|
fmt = string.gsub(fmt, '"(df%.[^"]+)"','%1')
|
||||||
|
fmt = string.gsub(fmt, '%s+$', '')
|
||||||
|
print(fmt)
|
||||||
|
end
|
||||||
|
|
||||||
|
local itype = df.global.ui_build_selector.building_type
|
||||||
|
local stype = df.global.ui_build_selector.building_subtype
|
||||||
|
|
||||||
|
if itype == df.building_type.Workshop then
|
||||||
|
dump(' [df.workshop_type.'..df.workshop_type[stype]..'] = ')
|
||||||
|
elseif itype == df.building_type.Furnace then
|
||||||
|
dump(' [df.furnace_type.'..df.furnace_type[stype]..'] = ')
|
||||||
|
elseif itype == df.building_type.Trap then
|
||||||
|
dump(' [df.trap_type.'..df.trap_type[stype]..'] = ')
|
||||||
|
else
|
||||||
|
dump(' [df.building_type.'..df.building_type[itype]..'] = ')
|
||||||
|
end
|
@ -0,0 +1,74 @@
|
|||||||
|
-- Logs minecart coordinates and speeds to console.
|
||||||
|
|
||||||
|
last_stats = last_stats or {}
|
||||||
|
|
||||||
|
function compare_one(vehicle)
|
||||||
|
local last = last_stats[vehicle.id]
|
||||||
|
local item = df.item.find(vehicle.item_id)
|
||||||
|
local ipos = item.pos
|
||||||
|
local new = {
|
||||||
|
ipos.x*100000 + vehicle.offset_x, vehicle.speed_x,
|
||||||
|
ipos.y*100000 + vehicle.offset_y, vehicle.speed_y,
|
||||||
|
ipos.z*100000 + vehicle.offset_z, vehicle.speed_z
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last == nil) or item.flags.on_ground then
|
||||||
|
local delta = { vehicle.id }
|
||||||
|
local show = (last == nil)
|
||||||
|
|
||||||
|
for i=1,6 do
|
||||||
|
local rv = 0
|
||||||
|
if last then
|
||||||
|
rv = last[i]
|
||||||
|
end
|
||||||
|
delta[i*2] = new[i]/100000
|
||||||
|
local dv = new[i] - rv
|
||||||
|
delta[i*2+1] = dv/100000
|
||||||
|
if dv ~= 0 then
|
||||||
|
show = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if show then
|
||||||
|
print(table.unpack(delta))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
last_stats[vehicle.id] = new
|
||||||
|
end
|
||||||
|
|
||||||
|
function compare_all()
|
||||||
|
local seen = {}
|
||||||
|
for _,v in ipairs(df.global.world.vehicles.all) do
|
||||||
|
seen[v.id] = true
|
||||||
|
compare_one(v)
|
||||||
|
end
|
||||||
|
for k,v in pairs(last_stats) do
|
||||||
|
if not seen[k] then
|
||||||
|
print(k,'DEAD')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function start_timer()
|
||||||
|
if not dfhack.timeout_active(timeout_id) then
|
||||||
|
timeout_id = dfhack.timeout(1, 'ticks', function()
|
||||||
|
compare_all()
|
||||||
|
start_timer()
|
||||||
|
end);
|
||||||
|
if not timeout_id then
|
||||||
|
dfhack.printerr('Could not start timer in watch-minecarts')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
compare_all()
|
||||||
|
|
||||||
|
local cmd = ...
|
||||||
|
|
||||||
|
if cmd == 'start' then
|
||||||
|
start_timer()
|
||||||
|
elseif cmd == 'stop' then
|
||||||
|
dfhack.timeout_active(timeout_id, nil)
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,125 @@
|
|||||||
|
-- Verify item occupancy and block item list integrity.
|
||||||
|
--
|
||||||
|
-- Checks:
|
||||||
|
-- 1) Item has flags.on_ground <=> it is in the correct block item list
|
||||||
|
-- 2) A tile has items in block item list <=> it has occupancy.item
|
||||||
|
-- 3) The block item lists are sorted.
|
||||||
|
|
||||||
|
local utils = require 'utils'
|
||||||
|
|
||||||
|
function check_block_items(fix)
|
||||||
|
local cnt = 0
|
||||||
|
local icnt = 0
|
||||||
|
local found = {}
|
||||||
|
local found_somewhere = {}
|
||||||
|
|
||||||
|
local should_fix = false
|
||||||
|
local can_fix = true
|
||||||
|
|
||||||
|
for _,block in ipairs(df.global.world.map.map_blocks) do
|
||||||
|
local itable = {}
|
||||||
|
local bx,by,bz = pos2xyz(block.map_pos)
|
||||||
|
|
||||||
|
-- Scan the block item vector
|
||||||
|
local last_id = nil
|
||||||
|
local resort = false
|
||||||
|
|
||||||
|
for _,id in ipairs(block.items) do
|
||||||
|
local item = df.item.find(id)
|
||||||
|
local ix,iy,iz = pos2xyz(item.pos)
|
||||||
|
local dx,dy,dz = ix-bx,iy-by,iz-bz
|
||||||
|
|
||||||
|
-- Check sorted order
|
||||||
|
if last_id and last_id >= id then
|
||||||
|
print(bx,by,bz,last_id,id,'block items not sorted')
|
||||||
|
resort = true
|
||||||
|
else
|
||||||
|
last_id = id
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check valid coordinates and flags
|
||||||
|
if not item.flags.on_ground then
|
||||||
|
print(bx,by,bz,id,dx,dy,'in block & not on ground')
|
||||||
|
elseif dx < 0 or dx >= 16 or dy < 0 or dy >= 16 or dz ~= 0 then
|
||||||
|
found_somewhere[id] = true
|
||||||
|
print(bx,by,bz,id,dx,dy,dz,'invalid pos')
|
||||||
|
can_fix = false
|
||||||
|
else
|
||||||
|
found[id] = true
|
||||||
|
itable[dx + dy*16] = true;
|
||||||
|
|
||||||
|
-- Check missing occupancy
|
||||||
|
if not block.occupancy[dx][dy].item then
|
||||||
|
print(bx,by,bz,dx,dy,'item & not occupied')
|
||||||
|
if fix then
|
||||||
|
block.occupancy[dx][dy].item = true
|
||||||
|
else
|
||||||
|
should_fix = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Sort the vector if needed
|
||||||
|
if resort then
|
||||||
|
if fix then
|
||||||
|
utils.sort_vector(block.items)
|
||||||
|
else
|
||||||
|
should_fix = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
icnt = icnt + #block.items
|
||||||
|
|
||||||
|
-- Scan occupancy for spurious marks
|
||||||
|
for x=0,15 do
|
||||||
|
local ocx = block.occupancy[x]
|
||||||
|
for y=0,15 do
|
||||||
|
if ocx[y].item and not itable[x + y*16] then
|
||||||
|
print(bx,by,bz,x,y,'occupied & no item')
|
||||||
|
if fix then
|
||||||
|
ocx[y].item = false
|
||||||
|
else
|
||||||
|
should_fix = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
cnt = cnt + 256
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check if any items are missing from blocks
|
||||||
|
for _,item in ipairs(df.global.world.items.all) do
|
||||||
|
if item.flags.on_ground and not found[item.id] then
|
||||||
|
can_fix = false
|
||||||
|
if not found_somewhere[item.id] then
|
||||||
|
print(id,item.pos.x,item.pos.y,item.pos.z,'on ground & not in block')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Report
|
||||||
|
print(cnt.." tiles and "..icnt.." items checked.")
|
||||||
|
|
||||||
|
if should_fix and can_fix then
|
||||||
|
print("Use 'fix/item-occupancy --fix' to fix the listed problems.")
|
||||||
|
elseif should_fix then
|
||||||
|
print("The problems are too severe to be fixed by this script.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local opt = ...
|
||||||
|
local fix = false
|
||||||
|
|
||||||
|
if opt then
|
||||||
|
if opt == '--fix' then
|
||||||
|
fix = true
|
||||||
|
else
|
||||||
|
dfhack.printerr('Invalid option: '..opt)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
print("Checking item occupancy - this will take a few seconds.")
|
||||||
|
check_block_items(fix)
|
Loading…
Reference in New Issue