summaryrefslogtreecommitdiff
path: root/mesecons_mvps
diff options
context:
space:
mode:
authorVanessa Ezekowitz <vanessaezekowitz@gmail.com>2016-04-01 21:00:20 -0400
committerVanessa Ezekowitz <vanessaezekowitz@gmail.com>2016-04-01 21:10:04 -0400
commit888b0ebfec8c2eff9015163549a7e47443cb8665 (patch)
tree915080159bfaa6ba6e226087c7ce0e8d5464b518 /mesecons_mvps
parentda66780a569712c23ae4f2996cfb4608a9f9d69d (diff)
downloaddreambuilder_modpack-888b0ebfec8c2eff9015163549a7e47443cb8665.tar
dreambuilder_modpack-888b0ebfec8c2eff9015163549a7e47443cb8665.tar.gz
dreambuilder_modpack-888b0ebfec8c2eff9015163549a7e47443cb8665.tar.bz2
dreambuilder_modpack-888b0ebfec8c2eff9015163549a7e47443cb8665.tar.xz
dreambuilder_modpack-888b0ebfec8c2eff9015163549a7e47443cb8665.zip
"explode" all modpacks into their individual components
(you can't have a modpack buried inside a modpack)
Diffstat (limited to 'mesecons_mvps')
-rw-r--r--mesecons_mvps/depends.txt1
-rw-r--r--mesecons_mvps/init.lua238
2 files changed, 239 insertions, 0 deletions
diff --git a/mesecons_mvps/depends.txt b/mesecons_mvps/depends.txt
new file mode 100644
index 0000000..acaa924
--- /dev/null
+++ b/mesecons_mvps/depends.txt
@@ -0,0 +1 @@
+mesecons
diff --git a/mesecons_mvps/init.lua b/mesecons_mvps/init.lua
new file mode 100644
index 0000000..beec94b
--- /dev/null
+++ b/mesecons_mvps/init.lua
@@ -0,0 +1,238 @@
+--register stoppers for movestones/pistons
+
+mesecon.mvps_stoppers = {}
+mesecon.on_mvps_move = {}
+mesecon.mvps_unmov = {}
+
+--- Objects (entities) that cannot be moved
+function mesecon.register_mvps_unmov(objectname)
+ mesecon.mvps_unmov[objectname] = true;
+end
+
+function mesecon.is_mvps_unmov(objectname)
+ return mesecon.mvps_unmov[objectname]
+end
+
+-- Nodes that cannot be pushed / pulled by movestones, pistons
+function mesecon.is_mvps_stopper(node, pushdir, stack, stackid)
+ local get_stopper = mesecon.mvps_stoppers[node.name]
+ if type (get_stopper) == "function" then
+ get_stopper = get_stopper(node, pushdir, stack, stackid)
+ end
+ return get_stopper
+end
+
+function mesecon.register_mvps_stopper(nodename, get_stopper)
+ if get_stopper == nil then
+ get_stopper = true
+ end
+ mesecon.mvps_stoppers[nodename] = get_stopper
+end
+
+-- Functions to be called on mvps movement
+function mesecon.register_on_mvps_move(callback)
+ mesecon.on_mvps_move[#mesecon.on_mvps_move+1] = callback
+end
+
+local function on_mvps_move(moved_nodes)
+ for _, callback in ipairs(mesecon.on_mvps_move) do
+ callback(moved_nodes)
+ end
+end
+
+function mesecon.mvps_process_stack(stack)
+ -- update mesecons for placed nodes ( has to be done after all nodes have been added )
+ for _, n in ipairs(stack) do
+ mesecon.on_placenode(n.pos, minetest.get_node(n.pos))
+ end
+end
+
+function mesecon.mvps_get_stack(pos, dir, maximum, all_pull_sticky)
+ -- determine the number of nodes to be pushed
+ local nodes = {}
+ local frontiers = {pos}
+
+ while #frontiers > 0 do
+ local np = frontiers[1]
+ local nn = minetest.get_node(np)
+
+ if nn.name ~= "air"
+ and minetest.registered_nodes[nn.name]
+ and minetest.registered_nodes[nn.name].liquidtype == "none" then
+ table.insert(nodes, {node = nn, pos = np})
+ if #nodes > maximum then return nil end
+
+ -- add connected nodes to frontiers, connected is a vector list
+ -- the vectors must be absolute positions
+ local connected = {}
+ if minetest.registered_nodes[nn.name]
+ and minetest.registered_nodes[nn.name].mvps_sticky then
+ connected = minetest.registered_nodes[nn.name].mvps_sticky(np, nn)
+ end
+
+ table.insert(connected, vector.add(np, dir))
+
+ -- If adjacent node is sticky block and connects add that
+ -- position to the connected table
+ for _, r in ipairs(mesecon.rules.alldirs) do
+ local adjpos = vector.add(np, r)
+ local adjnode = minetest.get_node(adjpos)
+ if minetest.registered_nodes[adjnode.name]
+ and minetest.registered_nodes[adjnode.name].mvps_sticky then
+ local sticksto = minetest.registered_nodes[adjnode.name]
+ .mvps_sticky(adjpos, adjnode)
+
+ -- connects to this position?
+ for _, link in ipairs(sticksto) do
+ if vector.equals(link, np) then
+ table.insert(connected, adjpos)
+ end
+ end
+ end
+ end
+
+ if all_pull_sticky then
+ table.insert(connected, vector.subtract(np, dir))
+ end
+
+ -- Make sure there are no duplicates in frontiers / nodes before
+ -- adding nodes in "connected" to frontiers
+ for _, cp in ipairs(connected) do
+ local duplicate = false
+ for _, rp in ipairs(nodes) do
+ if vector.equals(cp, rp.pos) then
+ duplicate = true
+ end
+ end
+ for _, fp in ipairs(frontiers) do
+ if vector.equals(cp, fp) then
+ duplicate = true
+ end
+ end
+ if not duplicate then
+ table.insert(frontiers, cp)
+ end
+ end
+ end
+ table.remove(frontiers, 1)
+ end
+
+ return nodes
+end
+
+function mesecon.mvps_push(pos, dir, maximum)
+ return mesecon.mvps_push_or_pull(pos, dir, dir, maximum)
+end
+
+function mesecon.mvps_pull_all(pos, dir, maximum)
+ return mesecon.mvps_push_or_pull(pos, vector.multiply(dir, -1), dir, maximum, true)
+end
+
+function mesecon.mvps_pull_single(pos, dir, maximum)
+ return mesecon.mvps_push_or_pull(pos, vector.multiply(dir, -1), dir, maximum)
+end
+
+-- pos: pos of mvps; stackdir: direction of building the stack
+-- movedir: direction of actual movement
+-- maximum: maximum nodes to be pushed
+-- all_pull_sticky: All nodes are sticky in the direction that they are pulled from
+function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sticky)
+ local nodes = mesecon.mvps_get_stack(pos, movedir, maximum, all_pull_sticky)
+
+ if not nodes then return end
+ -- determine if one of the nodes blocks the push / pull
+ for id, n in ipairs(nodes) do
+ if mesecon.is_mvps_stopper(n.node, movedir, nodes, id) then
+ return
+ end
+ end
+
+ -- remove all nodes
+ for _, n in ipairs(nodes) do
+ n.meta = minetest.get_meta(n.pos):to_table()
+ minetest.remove_node(n.pos)
+ end
+
+ -- update mesecons for removed nodes ( has to be done after all nodes have been removed )
+ for _, n in ipairs(nodes) do
+ mesecon.on_dignode(n.pos, n.node)
+ end
+
+ -- add nodes
+ for _, n in ipairs(nodes) do
+ local np = mesecon.addPosRule(n.pos, movedir)
+
+ minetest.add_node(np, n.node)
+ minetest.get_meta(np):from_table(n.meta)
+ end
+
+ local moved_nodes = {}
+ local oldstack = mesecon.tablecopy(nodes)
+ for i in ipairs(nodes) do
+ moved_nodes[i] = {}
+ moved_nodes[i].oldpos = nodes[i].pos
+ nodes[i].pos = mesecon.addPosRule(nodes[i].pos, movedir)
+ moved_nodes[i].pos = nodes[i].pos
+ moved_nodes[i].node = nodes[i].node
+ moved_nodes[i].meta = nodes[i].meta
+ end
+
+ on_mvps_move(moved_nodes)
+
+ return true, nodes, oldstack
+end
+
+mesecon.register_on_mvps_move(function(moved_nodes)
+ for _, n in ipairs(moved_nodes) do
+ mesecon.on_placenode(n.pos, n.node)
+ mesecon.update_autoconnect(n.pos)
+ end
+end)
+
+function mesecon.mvps_move_objects(pos, dir, nodestack)
+ local objects_to_move = {}
+
+ -- Move object at tip of stack
+ local pushpos = mesecon.addPosRule(pos, -- get pos at tip of stack
+ {x = dir.x * #nodestack,
+ y = dir.y * #nodestack,
+ z = dir.z * #nodestack})
+
+
+ local objects = minetest.get_objects_inside_radius(pushpos, 1)
+ for _, obj in ipairs(objects) do
+ table.insert(objects_to_move, obj)
+ end
+
+ -- Move objects lying/standing on the stack (before it was pushed - oldstack)
+ if tonumber(minetest.setting_get("movement_gravity")) > 0 and dir.y == 0 then
+ -- If gravity positive and dir horizontal, push players standing on the stack
+ for _, n in ipairs(nodestack) do
+ local p_above = mesecon.addPosRule(n.pos, {x=0, y=1, z=0})
+ local objects = minetest.get_objects_inside_radius(p_above, 1)
+ for _, obj in ipairs(objects) do
+ table.insert(objects_to_move, obj)
+ end
+ end
+ end
+
+ for _, obj in ipairs(objects_to_move) do
+ local entity = obj:get_luaentity()
+ if not entity or not mesecon.is_mvps_unmov(entity.name) then
+ local np = mesecon.addPosRule(obj:getpos(), dir)
+
+ --move only if destination is not solid
+ local nn = minetest.get_node(np)
+ if not ((not minetest.registered_nodes[nn.name])
+ or minetest.registered_nodes[nn.name].walkable) then
+ obj:setpos(np)
+ end
+ end
+ end
+end
+
+mesecon.register_mvps_stopper("doors:door_steel_b_1")
+mesecon.register_mvps_stopper("doors:door_steel_t_1")
+mesecon.register_mvps_stopper("doors:door_steel_b_2")
+mesecon.register_mvps_stopper("doors:door_steel_t_2")
+mesecon.register_mvps_stopper("default:chest_locked")