summaryrefslogtreecommitdiff
path: root/util.lua
diff options
context:
space:
mode:
authorFaceDeer <derksenmobile@gmail.com>2017-01-07 09:52:39 -0700
committerFaceDeer <derksenmobile@gmail.com>2017-01-07 09:52:39 -0700
commite43c5d3974e99b5d8d9a96f5d5461be35eeec65b (patch)
treecefc7494f5def045921ba5334d97678bda3c26ff /util.lua
parent152e0f7883d58297ebf9beac97741aab480d6ef2 (diff)
Splitting some code files into more manageably-sized chunks.
Diffstat (limited to 'util.lua')
-rw-r--r--util.lua227
1 files changed, 3 insertions, 224 deletions
diff --git a/util.lua b/util.lua
index 93e89df..dba9db8 100644
--- a/util.lua
+++ b/util.lua
@@ -3,6 +3,9 @@
digtron = {}
dofile( minetest.get_modpath( "digtron" ) .. "/util_item_place_node.lua" ) -- separated out to avoid potential for license complexity
+dofile( minetest.get_modpath( "digtron" ) .. "/util_movement.lua" ) -- separated out simply for tidiness, there's some big code in there
+dofile( minetest.get_modpath( "digtron" ) .. "/util_layout.lua" ) -- separated out simply for tidiness, there's some big code in there
+dofile( minetest.get_modpath( "digtron" ) .. "/util_execute_cycle.lua" ) -- separated out simply for tidiness, there's some big code in there
-- Apparently node_sound_metal_defaults is a newer thing, I ran into games using an older version of the default mod without it.
if default.node_sound_metal_defaults ~= nil then
@@ -95,160 +98,6 @@ digtron.can_move_to = function(pos, protected_nodes, dug_nodes)
return false
end
-digtron.move_node = function(pos, newpos, player_name)
- -- Moves nodes, preserving digtron metadata and inventory
- local node = minetest.get_node(pos)
- local node_def = minetest.registered_nodes[node.name]
- local oldnode = minetest.get_node(newpos)
- minetest.log("action", string.format("%s moves %s from (%d, %d, %d) to (%d, %d, %d), displacing %s", player_name, node.name, pos.x, pos.y, pos.z, newpos.x, newpos.y, newpos.z, oldnode.name))
- minetest.add_node(newpos, { name=node.name, param1=node.param1, param2=node.param2 })
- if node_def.after_place_node then
- node_def.after_place_node(newpos)
- end
-
- local oldmeta = minetest.get_meta(pos)
- local oldinv = oldmeta:get_inventory()
- local list = oldinv:get_list("main")
- local fuel = oldinv:get_list("fuel")
- local oldformspec = oldmeta:get_string("formspec")
-
- local newmeta = minetest.get_meta(newpos)
- local newinv = newmeta:get_inventory()
- newinv:set_list("main", list)
- newinv:set_list("fuel", fuel)
- newmeta:set_string("formspec", oldformspec)
-
- newmeta:set_string("triggering_player", oldmeta:get_string("triggering_player")) -- for auto-controllers
-
- newmeta:set_int("offset", oldmeta:get_int("offset"))
- newmeta:set_int("period", oldmeta:get_int("period"))
- newmeta:set_int("build_facing", oldmeta:get_int("build_facing"))
- newmeta:set_float("fuel_burning", oldmeta:get_float("fuel_burning"))
- newmeta:set_string("infotext", oldmeta:get_string("infotext"))
-
- -- Move the little floaty entity inside the builders
- if minetest.get_item_group(node.name, "digtron") == 4 then
- digtron.update_builder_item(newpos)
- end
-
- -- remove node from old position
- minetest.remove_node(pos)
- if node_def.after_dig_node then
- node_def.after_dig_node(pos)
- end
-end
-
-digtron.get_all_digtron_neighbours = function(pos, player)
- -- returns table containing a list of all digtron node locations, lists of special digtron node types, a table of the coordinate extents of the digtron array, a Pointset of protected nodes, and a number to determine how many adjacent solid non-digtron nodes there are (for traction)
-
- local layout = {}
- --initialize. We're assuming that the start position is a controller digtron, should be a safe assumption since only the controller node should call this
- layout.traction = 0
- layout.all = {}
- layout.inventories = {}
- layout.fuelstores = {}
- layout.diggers = {}
- layout.builders = {}
- layout.extents = {}
- layout.water_touching = false
- layout.lava_touching = false
- layout.protected = Pointset.create() -- if any nodes we look at are protected, make note of that. That way we don't need to keep re-testing protection state later.
- layout.controller = {x=pos.x, y=pos.y, z=pos.z} --Make a deep copy of the pos parameter just in case the calling code wants to play silly buggers with it
-
- table.insert(layout.all, layout.controller)
- layout.extents.max_x = pos.x
- layout.extents.min_x = pos.x
- layout.extents.max_y = pos.y
- layout.extents.min_y = pos.y
- layout.extents.max_z = pos.z
- layout.extents.min_z = pos.z
-
- -- temporary pointsets used while searching
- local to_test = Pointset.create()
- local tested = Pointset.create()
-
- tested:set(pos.x, pos.y, pos.z, true)
- to_test:set(pos.x + 1, pos.y, pos.z, true)
- to_test:set(pos.x - 1, pos.y, pos.z, true)
- to_test:set(pos.x, pos.y + 1, pos.z, true)
- to_test:set(pos.x, pos.y - 1, pos.z, true)
- to_test:set(pos.x, pos.y, pos.z + 1, true)
- to_test:set(pos.x, pos.y, pos.z - 1, true)
-
- if minetest.is_protected(pos, player:get_player_name()) and not minetest.check_player_privs(player, "protection_bypass") then
- layout.protected:set(pos.x, pos.y, pos.z, true)
- end
-
- -- Do a loop on to_test positions, adding new to_test positions as we find digtron nodes. This is a flood fill operation
- -- that follows node faces (no diagonals)
- local testpos, _ = to_test:pop()
- while testpos ~= nil do
- tested:set(testpos.x, testpos.y, testpos.z, true) -- track nodes we've looked at to prevent infinite loops
- local node = minetest.get_node(testpos)
-
- if node.name == "ignore" then
- --buildtron array is next to unloaded nodes, too dangerous to do anything. Abort.
- layout.all = nil
- return layout
- end
-
- if minetest.is_protected(pos, player:get_player_name()) and not minetest.check_player_privs(player, "protection_bypass") then
- layout.protected:set(testpos.x, testpos.y, testpos.z, true)
- end
-
- if minetest.get_item_group(node.name, "water") ~= 0 then
- layout.water_touching = true
- elseif minetest.get_item_group(node.name, "lava") ~= 0 then
- layout.lava_touching = true
- if digtron.lava_impassible == true then
- layout.protected:set(testpos.x, testpos.y, testpos.z, true)
- end
- end
-
- local group_number = minetest.get_item_group(node.name, "digtron")
- if group_number > 0 then
- --found one. Add it to the digtrons output
- table.insert(layout.all, testpos)
-
- -- update extents
- layout.extents.max_x = math.max(layout.extents.max_x, testpos.x)
- layout.extents.min_x = math.min(layout.extents.min_x, testpos.x)
- layout.extents.max_y = math.max(layout.extents.max_y, testpos.y)
- layout.extents.min_y = math.min(layout.extents.min_y, testpos.y)
- layout.extents.max_z = math.max(layout.extents.max_z, testpos.z)
- layout.extents.min_z = math.min(layout.extents.min_z, testpos.z)
-
- -- add a reference to this node's position to special node lists
- if group_number == 2 then
- table.insert(layout.inventories, testpos)
- elseif group_number == 3 then
- table.insert(layout.diggers, testpos)
- elseif group_number == 4 then
- table.insert(layout.builders, testpos)
- elseif group_number == 5 then
- table.insert(layout.fuelstores, testpos)
- elseif group_number == 6 then
- table.insert(layout.inventories, testpos)
- table.insert(layout.fuelstores, testpos)
- end
-
- --queue up potential new test points adjacent to this digtron node
- to_test:set_if_not_in(tested, testpos.x + 1, testpos.y, testpos.z, true)
- to_test:set_if_not_in(tested, testpos.x - 1, testpos.y, testpos.z, true)
- to_test:set_if_not_in(tested, testpos.x, testpos.y + 1, testpos.z, true)
- to_test:set_if_not_in(tested, testpos.x, testpos.y - 1, testpos.z, true)
- to_test:set_if_not_in(tested, testpos.x, testpos.y, testpos.z + 1, true)
- to_test:set_if_not_in(tested, testpos.x, testpos.y, testpos.z - 1, true)
- elseif minetest.registered_nodes[node.name].buildable_to ~= true then
- -- Tracks whether the digtron is hovering in mid-air. If any part of the digtron array touches something solid it gains traction.
- layout.traction = layout.traction + 1
- end
-
- testpos, _ = to_test:pop()
- end
-
- return layout
-end
digtron.place_in_inventory = function(itemname, inventory_positions, fallback_pos)
--tries placing the item in each inventory node in turn. If there's no room, drop it at fallback_pos
@@ -291,76 +140,6 @@ digtron.take_from_inventory = function(itemname, inventory_positions)
return nil
end
-digtron.move_digtron = function(facing, digtrons, extents, nodes_dug, player_name)
- -- move everything. Note! order is important or they'll step on each other, that's why this has complicated loops and filtering.
- -- Nodes are moved in a "caterpillar" pattern - front plane first, then next plane back, then next plane back, etc.
- -- positions in the digtron list will be updated when this method executes. Note that the inventories list shares
- -- references to the node position tables in the digtron list, so it will reflect the updates too.
- local dir = digtron.facedir_to_dir_map[facing]
- local increment
- local filter
- local index
- local target
- if dir == 1 then -- z+
- filter = "z"
- increment = -1
- index = extents.max_z
- target = extents.min_z
- extents.max_z = extents.max_z + 1
- extents.min_z = extents.min_z + 1
- elseif dir == 2 then -- x+
- filter = "x"
- increment = -1
- index = extents.max_x
- target = extents.min_x
- extents.max_x = extents.max_x + 1
- extents.min_x = extents.min_x + 1
- elseif dir == 3 then -- z-
- filter = "z"
- increment = 1
- index = extents.min_z
- target = extents.max_z
- extents.max_z = extents.max_z - 1
- extents.min_z = extents.min_z - 1
- elseif dir == 4 then -- x-
- filter = "x"
- increment = 1
- index = extents.min_x
- target = extents.max_x
- extents.max_x = extents.max_x - 1
- extents.min_x = extents.min_x - 1
- elseif dir == 5 then -- y-
- filter = "y"
- increment = 1
- index = extents.min_y
- target = extents.max_y
- extents.max_y = extents.max_y - 1
- extents.min_y = extents.min_y - 1
- elseif dir == 6 then -- y+
- filter = "y"
- increment = -1
- index = extents.max_y
- target = extents.min_y
- extents.max_y = extents.max_y + 1
- extents.min_y = extents.min_y + 1
- end
-
- while index ~= target + increment do
- for k, location in pairs(digtrons) do
- if location[filter] == index then
- local newpos = digtron.find_new_pos(location, facing)
- digtron.move_node(location, newpos, player_name)
- --By updating the digtron position table in-place we also update all the special node tables as well
- digtrons[k].x= newpos.x
- digtrons[k].y= newpos.y
- digtrons[k].z= newpos.z
- nodes_dug:set(newpos.x, newpos.y, newpos.z, false) -- we've moved a digtron node into this space, mark it so that we don't dig it.
- end
- end
- index = index + increment
- end
-end
-
-- Used to determine which coordinate is being checked for periodicity. eg, if the digtron is moving in the z direction, then periodicity is checked for every n nodes in the z axis.
digtron.get_controlling_coordinate = function(pos, facedir)
-- used for determining builder period and offset