added automatic forceloading

This commit is contained in:
Peter Maloney 2015-07-16 19:57:11 +02:00
parent c328f0a978
commit a1011b332a
2 changed files with 89 additions and 9 deletions

View File

@ -13,6 +13,41 @@ local quarry_dig_above_nodes = 3 -- How far above the quarry we will dig nodes
local quarry_max_depth = 100
local quarry_demand = 10000
-- keeps the quarry and the full dig zone loaded
-- pos - the position of the quarry
-- pos1,pos2 - two opposite corner positions that mark the zone to force load
local function forceload_dig(pos, pos1, pos2)
if not technic.auto_forceloading_enabled then
return
end
local meta = minetest.get_meta(pos)
minpos = vector.new(math.min(pos.x, pos1.x, pos2.x), math.min(pos.y, pos1.y, pos2.y), math.min(pos.z, pos1.z, pos2.z))
maxpos = vector.new(math.max(pos.x, pos1.x, pos2.x), math.max(pos.y, pos1.y, pos2.y), math.max(pos.z, pos1.z, pos2.z))
flpos = technic.compute_forceload_positions_between_points(minpos, maxpos)
technic.forceload_on_flposes(flpos, meta)
print("DEBUG: forceload_dig(), currently forceloaded = " .. dump(technic.currently_forceloaded_positions(meta)))
end
-- keeps only the quarry loaded
local function forceload_purge(pos)
if not technic.auto_forceloading_enabled then
return
end
local meta = minetest.get_meta(pos)
flpos = technic.compute_forceload_positions_between_points(pos, pos)
technic.forceload_on_flposes(flpos, meta)
print("DEBUG: forceload_dig(), currently forceloaded = " .. dump(technic.currently_forceloaded_positions(meta)))
end
local function forceload_off(meta)
if not technic.auto_forceloading_enabled then
return
end
technic.forceload_off(meta)
end
local function set_quarry_formspec(meta)
local radius = meta:get_int("size")
local formspec = "size[6,4.3]"..
@ -78,6 +113,7 @@ local function quarry_handle_purge(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local i = 0
forceload_purge(pos)
for _,stack in ipairs(inv:get_list("cache")) do
i = i + 1
if stack then
@ -107,21 +143,43 @@ local function quarry_run(pos, node)
end
if meta:get_int("enabled") and meta:get_int("HV_EU_input") >= quarry_demand and meta:get_int("purge_on") == 0 then
-- the direction the quarry faces
local pdir = minetest.facedir_to_dir(node.param2)
-- the direction to the right of where the quarry faces
local qdir = pdir.x == 1 and vector.new(0,0,-1) or
(pdir.z == -1 and vector.new(-1,0,0) or
(pdir.x == -1 and vector.new(0,0,1) or
vector.new(1,0,0)))
local radius = meta:get_int("size")
local diameter = radius*2 + 1
local startpos = vector.add(vector.add(vector.add(pos,
vector.new(0, quarry_dig_above_nodes, 0)),
pdir),
vector.multiply(qdir, -radius))
local endpos = vector.add(vector.add(vector.add(startpos,
vector.new(0, -quarry_dig_above_nodes-quarry_max_depth, 0)),
vector.multiply(pdir, diameter-1)),
vector.multiply(qdir, diameter-1))
-- the back left top corner of the digging zone
local startpos = vector.add(
vector.add(
vector.add(
pos,
vector.new(0, quarry_dig_above_nodes, 0)
),
pdir
),
vector.multiply(qdir, -radius)
)
-- the forward right bottom corner of the digging zone
local endpos = vector.add(
vector.add(
vector.add(
startpos,
vector.new(0, -quarry_dig_above_nodes-quarry_max_depth, 0)
),
vector.multiply(pdir, diameter-1)
),
vector.multiply(qdir, diameter-1)
)
--TEST
-- print("DEBUG: startpos = (" .. startpos.x .. "," .. startpos.y .. "," .. startpos.z .. ")")
-- print("DEBUG: endpos = (" .. endpos.x .. "," .. endpos.y .. "," .. endpos.z .. ")")
forceload_dig(pos, startpos, endpos)
local vm = VoxelManip()
local minpos, maxpos = vm:read_from_map(startpos, endpos)
local area = VoxelArea:new({MinEdge=minpos, MaxEdge=maxpos})
@ -236,6 +294,10 @@ minetest.register_node("technic:quarry", {
set_quarry_formspec(meta)
set_quarry_demand(meta)
end,
on_destruct = function (pos)
local meta = minetest.get_meta(pos)
forceload_off(meta)
end,
after_place_node = function(pos, placer, itemstack)
local meta = minetest.get_meta(pos)
meta:set_string("owner", placer:get_player_name())

View File

@ -2,6 +2,9 @@ local S = technic.getter
local desc = S("Administrative World Anchor")
-- set to false to disable autoforceloading in other files, such as the quarry force loading itself and dig area
technic.auto_forceloading_enabled = true
-- pos - position of the anchor node
-- meta - contains "radius"
-- return table of positions, one position per block
@ -9,6 +12,12 @@ local function compute_forceload_positions(pos, meta)
local radius = meta:get_int("radius")
local minpos = vector.subtract(pos, vector.new(radius, radius, radius))
local maxpos = vector.add(pos, vector.new(radius, radius, radius))
return compute_forceload_positions_between_points(minpos, maxpos)
end
-- minpos,maxpos - two opposite corner positions that mark the zone to force load; all coordinates in minpos have to be lower than the ones in maxpos
-- return table of positions, one position per block
local function compute_forceload_positions_between_points(minpos, maxpos)
local minbpos = {}
local maxbpos = {}
for _, coord in ipairs({"x","y","z"}) do
@ -25,6 +34,7 @@ local function compute_forceload_positions(pos, meta)
end
return flposes
end
technic.compute_forceload_positions_between_points = compute_forceload_positions_between_points
-- meta - contains "forceloaded", which is a serialized table of positions that are currently forceloaded
-- return table of positions that are currently forceloaded
@ -32,6 +42,7 @@ local function currently_forceloaded_positions(meta)
local ser = meta:get_string("forceloaded")
return ser == "" and {} or minetest.deserialize(ser)
end
technic.currently_forceloaded_positions = currently_forceloaded_positions
-- turns off forceloading for all positions in the table
-- meta - contains "forceloaded" (used by currently_forceloaded_positions)
@ -42,12 +53,18 @@ local function forceload_off(meta)
minetest.forceload_free_block(p)
end
end
technic.forceload_off = forceload_off
-- computes the forceload positions (using compute_forceload_positions) and tries to force load all of them, and records them in meta "forcedloaded"
-- computes the forceload positions (using compute_forceload_positions) and tries to force load all of them, and records them in meta "forceloaded"
-- pos - position of the anchor node
-- meta - contains "radius" (to be read) and "forceloaded" (to be written)
local function forceload_on(pos, meta)
local want_flposes = compute_forceload_positions(pos, meta)
forceload_on_flposes(want_flposes, meta)
return
end
local function forceload_on_flposes(want_flposes, meta)
local have_flposes = {}
for _, p in ipairs(want_flposes) do
if minetest.forceload_block(p) then
@ -56,6 +73,7 @@ local function forceload_on(pos, meta)
end
meta:set_string("forceloaded", #have_flposes == 0 and "" or minetest.serialize(have_flposes))
end
technic.forceload_on_flposes = forceload_on_flposes
local function set_display(pos, meta)
meta:set_string("infotext", S(meta:get_int("enabled") ~= 0 and "%s Enabled" or "%s Disabled"):format(desc))