Add files via upload
This commit is contained in:
199
movefloor.lua
Normal file
199
movefloor.lua
Normal file
@@ -0,0 +1,199 @@
|
||||
local utils = ...
|
||||
local S = utils.S
|
||||
|
||||
|
||||
|
||||
if utils.mesecon_supported and mesecon.mvps_push then
|
||||
|
||||
|
||||
|
||||
local mesecon_rules =
|
||||
{
|
||||
{ x = 1, y = 1, z = 0 },
|
||||
{ x = -1, y = 1, z = 0 },
|
||||
{ x = 0, y = 1, z = 1 },
|
||||
{ x = 0, y = 1, z = -1 },
|
||||
{ x = 1, y = -1, z = 0 },
|
||||
{ x = -1, y = -1, z = 0 },
|
||||
{ x = 0, y = -1, z = 1 },
|
||||
{ x = 0, y = -1, z = -1 },
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- use mesecons movestone settings
|
||||
local timer_interval = 1 / mesecon.setting ("movestone_speed", 3)
|
||||
local max_push = 3
|
||||
local max_pull = 3
|
||||
|
||||
|
||||
|
||||
-- helper functions:
|
||||
local function get_movefloor_direction (rulename)
|
||||
if rulename.y > 0 then
|
||||
return { x = 0, y = 1, z = 0 }
|
||||
elseif rulename.y < 0 then
|
||||
return { x = 0, y = -1, z = 0 }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function add_movefloor_list (pos, list)
|
||||
for i = 1, #list do
|
||||
if list[i].x == pos.x and
|
||||
list[i].y == pos.y and
|
||||
list[i].z == pos.z then
|
||||
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
list[#list + 1] = { x = pos.x, y = pos.y, z = pos.z }
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function find_adjoining_movefloor (pos, list)
|
||||
local tpos =
|
||||
{
|
||||
{ x = pos.x + 1, y = pos.y, z = pos.z },
|
||||
{ x = pos.x - 1, y = pos.y, z = pos.z },
|
||||
{ x = pos.x, y = pos.y, z = pos.z + 1 },
|
||||
{ x = pos.x, y = pos.y, z = pos.z - 1 }
|
||||
}
|
||||
|
||||
for i = 1, #tpos do
|
||||
local node = minetest.get_node (tpos[i])
|
||||
if node and node.name == "lwcomponents:movefloor" then
|
||||
if add_movefloor_list (tpos[i], list) then
|
||||
find_adjoining_movefloor (tpos[i], list)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- copied from mesecons movestone
|
||||
local function movefloor_move (pos, node, rulename, is_sticky)
|
||||
local direction = get_movefloor_direction (rulename)
|
||||
local play_sound = false
|
||||
|
||||
local list =
|
||||
{
|
||||
{ x = pos.x, y = pos.y, z = pos.z }
|
||||
}
|
||||
|
||||
find_adjoining_movefloor (pos, list)
|
||||
|
||||
for i = 1, #list do
|
||||
local frontpos = vector.add (list[i], direction)
|
||||
local meta = minetest.get_meta (list[i])
|
||||
local owner = meta:get_string ("owner")
|
||||
local continue = true
|
||||
|
||||
-- ### Step 1: Push nodes in front ###
|
||||
local success, stack, oldstack = mesecon.mvps_push (frontpos, direction, max_push, owner)
|
||||
if not success then
|
||||
if stack == "protected" then
|
||||
meta:set_string ("infotext", "Can't move: protected area on the way")
|
||||
else
|
||||
minetest.get_node_timer (list[i]):start (timer_interval)
|
||||
continue = false
|
||||
end
|
||||
end
|
||||
|
||||
if continue then
|
||||
mesecon.mvps_move_objects (frontpos, direction, oldstack)
|
||||
|
||||
-- ### Step 2: Move the movestone ###
|
||||
minetest.set_node (frontpos, node)
|
||||
local meta2 = minetest.get_meta (frontpos)
|
||||
meta2:set_string ("owner", owner)
|
||||
minetest.remove_node (list[i])
|
||||
mesecon.on_dignode (list[i], node)
|
||||
mesecon.on_placenode (frontpos, node)
|
||||
minetest.get_node_timer (frontpos):start (timer_interval)
|
||||
play_sound = true
|
||||
|
||||
-- ### Step 3: If sticky, pull stack behind ###
|
||||
if is_sticky and direction.y < 0 then
|
||||
local backpos = vector.subtract (list[i], direction)
|
||||
success, stack, oldstack = mesecon.mvps_pull_all (backpos, direction, max_pull, owner)
|
||||
if success then
|
||||
mesecon.mvps_move_objects (backpos, vector.multiply (direction, -1), oldstack, -1)
|
||||
end
|
||||
end
|
||||
|
||||
-- ### Step 4: Let things fall ###
|
||||
minetest.check_for_falling (vector.add (list[i], { x = 0, y = 1, z = 0 }))
|
||||
end
|
||||
end
|
||||
|
||||
if play_sound then
|
||||
minetest.sound_play("movestone", { pos = list[i], max_hear_distance = 20, gain = 0.5 }, true)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function on_timer (pos, elapsed)
|
||||
local sourcepos = mesecon.is_powered (pos)
|
||||
|
||||
if not sourcepos then
|
||||
return
|
||||
end
|
||||
|
||||
local rulename = vector.subtract (sourcepos[1], pos)
|
||||
|
||||
mesecon.activate (pos, minetest.get_node (pos), rulename, 0)
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function mesecon_support ()
|
||||
return
|
||||
{
|
||||
effector =
|
||||
{
|
||||
rules = table.copy (mesecon_rules),
|
||||
|
||||
action_on = function (pos, node, rulename)
|
||||
-- do something to turn the effector on
|
||||
|
||||
if rulename and not minetest.get_node_timer (pos):is_started () then
|
||||
movefloor_move (pos, node, rulename, true)
|
||||
end
|
||||
end
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
|
||||
minetest.register_node("lwcomponents:movefloor", {
|
||||
description = S("Moving Floor"),
|
||||
tiles = { "lwmovefloortop.png", "lwmovefloortop.png",
|
||||
"lwmovefloorside.png", "lwmovefloorside.png",
|
||||
"lwmovefloorside.png", "lwmovefloorside.png" },
|
||||
sunlight_propagates = false,
|
||||
drawtype = "normal",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
|
||||
}
|
||||
},
|
||||
groups = { cracky = 2 },
|
||||
sounds = default.node_sound_wood_defaults (),
|
||||
mesecons = mesecon_support (),
|
||||
|
||||
on_timer = on_timer,
|
||||
})
|
||||
|
||||
|
||||
|
||||
end
|
Reference in New Issue
Block a user