Compare commits

...

3 Commits

Author SHA1 Message Date
loosewheel
eaf6a679c3 Add files via upload 2022-02-19 14:08:26 +10:00
loosewheel
f41ab00398 Add files via upload 2022-02-19 14:06:27 +10:00
loosewheel
7f42fde4a0 Add files via upload 2022-02-19 14:04:44 +10:00
10 changed files with 353 additions and 75 deletions

View File

@@ -108,3 +108,9 @@ v0.1.19
v0.1.20 v0.1.20
* Valid distance and resolution for camera set by digilines message. * Valid distance and resolution for camera set by digilines message.
* Imposed maximum resolution of 128 for cameras. * Imposed maximum resolution of 128 for cameras.
v0.1.21
* Minor bug fix, movefloor global.
* Fixed movefloor so player doesn't fall through floor.
* Transfer timer in moved nodes for pistons.

View File

@@ -332,7 +332,7 @@ end -- utils.digilines_supported and utils.digistuff_supported
if utils.mesecon_supported and mesecon.mvps_push then if utils.mesecon_supported then
minetest.register_craft ({ minetest.register_craft ({
output = "lwcomponents:movefloor", output = "lwcomponents:movefloor",
@@ -343,7 +343,7 @@ minetest.register_craft ({
} }
}) })
end -- utils.mesecon_supported and mesecon.mvps_push end -- utils.mesecon_supported

View File

@@ -130,7 +130,7 @@ end
local function get_entity_height (objref) local function get_entity_height (objref)
if objref.get_luaentity then if objref.get_luaentity then
entity = objref:get_luaentity () local entity = objref:get_luaentity ()
if entity and entity.name then if entity and entity.name then
def = minetest.registered_entities[entity.name] def = minetest.registered_entities[entity.name]

View File

@@ -1,6 +1,6 @@
MoveFloor MoveFloor
--------- ---------
* This block is only available if mesecons and mesecons_mvps is loaded. * This block is only available if mesecons is loaded.
The MoveFloor block responds to a mesecons power source in the 4 horizontal The MoveFloor block responds to a mesecons power source in the 4 horizontal
directions. If the power source is one higher the MoveFloor moves up to directions. If the power source is one higher the MoveFloor moves up to

View File

@@ -1,4 +1,4 @@
local version = "0.1.20" local version = "0.1.21"
local mod_storage = minetest.get_mod_storage () local mod_storage = minetest.get_mod_storage ()

View File

@@ -61,6 +61,16 @@ https://creativecommons.org/licenses/by/4.0/
lwmovefloor.ogg
---------------
https://www.freesoundslibrary.com/elevator-sound-effect-elevator-ride-doors-closing-and-opening/
License: Attribution 4.0 International (CC BY 4.0). You are allowed to use
sound effects free of charge and royalty free in your multimedia projects
for commercial or non-commercial purposes.
Media license Media license
------------- -------------
siren images derived from images from https://openclipart.org, which is siren images derived from images from https://openclipart.org, which is

View File

@@ -3,7 +3,7 @@ local S = utils.S
if utils.mesecon_supported and mesecon.mvps_push then if utils.mesecon_supported then
@@ -21,14 +21,10 @@ local mesecon_rules =
-- use mesecons movestone settings
local timer_interval = 1 / mesecon.setting ("movestone_speed", 3)
local max_push = 3 local max_push = 3
local max_pull = 3
-- helper functions:
local function get_movefloor_direction (rulename) local function get_movefloor_direction (rulename)
if rulename.y > 0 then if rulename.y > 0 then
return { x = 0, y = 1, z = 0 } return { x = 0, y = 1, z = 0 }
@@ -38,6 +34,7 @@ local function get_movefloor_direction (rulename)
end end
local function add_movefloor_list (pos, list) local function add_movefloor_list (pos, list)
for i = 1, #list do for i = 1, #list do
if list[i].x == pos.x and if list[i].x == pos.x and
@@ -76,10 +73,289 @@ end
-- copied from mesecons movestone local function get_node_height (node)
local function movefloor_move (pos, node, rulename, is_sticky) local height = 0
local def = minetest.registered_nodes[node.name]
if def and type (def.collision_box) == "table" then
if def.collision_box.type and def.collision_box.type == "regular" then
height = 1
else
for _, box in pairs (def.collision_box) do
if type (box) == "table" then
if type (box[5]) == "number" then
height = box[5]
else
for _, b in ipairs (box) do
if type (b[5]) == "number" and b[5] > height then
height = b[5]
end
end
end
end
end
end
end
return height
end
local function get_affected_nodes (floor_list)
local list = { }
local max_height = 0
local protected = false
for _, fpos in ipairs (floor_list) do
for y = 0, max_push, 1 do
local npos = vector.add (fpos, { x = 0, y = y, z = 0 })
local node = utils.get_far_node (npos)
if node and node.name ~= "air" then
local meta = minetest.get_meta (npos)
local timer = minetest.get_node_timer (npos)
local h = get_node_height (node) + npos.y - fpos.y - 0.5
list[#list + 1] =
{
pos = npos,
node = node,
meta = (meta and meta:to_table ()),
timeout = (timer and timer:get_timeout ()) or 0,
elapsed = (timer and timer:get_elapsed ()) or 0
}
if h > max_height then
max_height = h
end
if utils.is_protected (npos, nil) then
protected = true
end
end
end
end
return list, math.ceil (max_height), protected
end
local function get_entity_height (obj, base)
local height = 0
if obj.get_pos then
local pos = obj:get_pos ()
if obj.get_luaentity then
local entity = obj:get_luaentity ()
if entity and entity.name then
local def = minetest.registered_entities[entity.name]
if def and type (def.collisionbox) == "table" and
type (def.collisionbox[5]) == "number" then
height = def.collisionbox[5] + pos.y - base
end
end
end
local props = obj:get_properties ()
if props and props.collisionbox and type (props.collisionbox) == "table" and
type (props.collisionbox[5]) == "number" then
if props.collisionbox[5] > height then
height = props.collisionbox[5] + pos.y - base
end
end
end
return height
end
local function get_affected_entities (floor_list)
local list = { }
local max_height = 0
for _, fpos in pairs (floor_list) do
local min_pos = vector.subtract (fpos, { x = 0.4999, y = 0.4999, z = 0.4999 })
local max_pos = vector.add (fpos, { x = 0.4999, y = max_push + 0.4999, z = 0.4999 })
local objects = minetest.get_objects_in_area (min_pos, max_pos)
for _, obj in ipairs (objects) do
local h = get_entity_height (obj, fpos.y + 0.5)
list[#list + 1] =
{
pos = obj:get_pos (),
obj = obj
}
if h > max_height then
max_height = h
end
end
end
return list, math.ceil (max_height)
end
local function is_obstructed (floor_list, height)
for _, fpos in pairs (floor_list) do
local npos = vector.add (fpos, { x = 0, y = height, z = 0 })
if utils.is_protected (npos, nil) then
return true
end
local node = utils.get_far_node (npos)
if node and node.name ~= "air" then
local def = minetest.registered_nodes[node.name]
if not def or not def.buildable_to then
return true
end
end
end
return false
end
local function move_entities (list, move, players)
for _, entry in ipairs (list) do
if entry.obj then
if players or not entry.obj:is_player () then
local pos = nil
if entry.obj:is_player () then
pos = vector.add (entry.pos, { x = move.x, y = move.y + 0.1, z = move.z })
else
pos = vector.add (entry.pos, move)
end
if entry.obj.move_to then
entry.obj:move_to (pos)
elseif entry.set_pos then
entry.obj:set_pos (pos)
end
end
end
end
end
local function update_player_position (list)
for _, entry in ipairs (list) do
local player = minetest.get_player_by_name (entry.name)
if player then
local pos = player:get_pos ()
if pos.y < entry.pos.y then
pos.y = entry.pos.y + 0.1
player:set_pos (pos)
end
end
end
end
local function queue_player_update (list, move)
local players = { }
for _, entry in ipairs (list) do
if entry.obj and entry.obj:is_player () then
players[#players + 1] =
{
pos = vector.add (entry.pos, move),
name = entry.obj:get_player_name ()
}
end
end
if #players > 0 then
minetest.after(0.1, update_player_position, players)
end
end
local function move_nodes (list, move)
if move.y > 0 then
for i = #list, 1, -1 do
local pos = vector.add (list[i].pos, move)
minetest.remove_node (list[i].pos)
minetest.set_node (pos, list[i].node)
if list[i].meta then
local meta = minetest.get_meta (pos)
if meta then
meta:from_table (list[i].meta)
end
end
if list[i].timeout > 0 then
timer = minetest.get_node_timer (pos)
if timer then
timer:set (list[i].timeout, list[i].elapsed)
end
end
end
else
for i = 1, #list, 1 do
local pos = vector.add (list[i].pos, move)
minetest.remove_node (list[i].pos)
minetest.set_node (pos, list[i].node)
if list[i].meta then
local meta = minetest.get_meta (pos)
if meta then
meta:from_table (list[i].meta)
end
end
if list[i].timeout > 0 then
timer = minetest.get_node_timer (pos)
if timer then
timer:set (list[i].timeout, list[i].elapsed)
end
end
end
end
end
local function check_for_falling (list)
for _, pos in ipairs (list) do
minetest.check_for_falling (vector.add (pos, { x = 0, y = max_push + 1, z = 0 }))
end
end
local function movefloor_move (pos, node, rulename)
local direction = get_movefloor_direction (rulename) local direction = get_movefloor_direction (rulename)
local play_sound = false
local list = local list =
{ {
@@ -88,68 +364,34 @@ local function movefloor_move (pos, node, rulename, is_sticky)
find_adjoining_movefloor (pos, list) find_adjoining_movefloor (pos, list)
for i = 1, #list do local nodes, height, protected = get_affected_nodes (list)
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 ### if protected then
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 return
end end
local rulename = vector.subtract (sourcepos[1], pos) local entities, h = get_affected_entities (list)
mesecon.activate (pos, minetest.get_node (pos), rulename, 0) if h > height then
height = h
end
if is_obstructed (list, (direction.y > 0 and height + 1) or -1) then
return
end
if direction.y > 0 then
move_entities (entities, direction, true)
move_nodes (nodes, direction)
queue_player_update (entities, direction)
else
move_nodes (nodes, direction)
move_entities (entities, direction, false)
check_for_falling (list)
queue_player_update (entities, direction)
end
minetest.sound_play ("lwmovefloor", { pos = pos, max_hear_distance = 10, gain = 1.0 }, true)
end end
@@ -164,8 +406,8 @@ local function mesecon_support ()
action_on = function (pos, node, rulename) action_on = function (pos, node, rulename)
-- do something to turn the effector on -- do something to turn the effector on
if rulename and not minetest.get_node_timer (pos):is_started () then if rulename then
movefloor_move (pos, node, rulename, true) movefloor_move (pos, node, rulename)
end end
end end
} }
@@ -190,8 +432,6 @@ minetest.register_node("lwcomponents:movefloor", {
groups = { cracky = 2 }, groups = { cracky = 2 },
sounds = default.node_sound_wood_defaults (), sounds = default.node_sound_wood_defaults (),
mesecons = mesecon_support (), mesecons = mesecon_support (),
on_timer = on_timer,
}) })

View File

@@ -120,6 +120,9 @@ local function push_nodes (pos, extent)
end end
local tmeta = cmeta:to_table () local tmeta = cmeta:to_table ()
local ctimer = minetest.get_node_timer (cpos)
local ctimeout = (ctimer and ctimer:get_timeout ()) or 0
local celapsed = (ctimer and ctimer:get_elapsed ()) or 0
push_entities (cpos, vec) push_entities (cpos, vec)
@@ -136,6 +139,14 @@ local function push_nodes (pos, extent)
cmeta:from_table (tmeta) cmeta:from_table (tmeta)
end end
if ctimeout > 0 then
ctimer = minetest.get_node_timer (last)
if ctimer then
ctimer:set (ctimeout, celapsed)
end
end
last = cpos last = cpos
end end
end end
@@ -161,6 +172,9 @@ local function pull_node (pos, extent)
if cmeta then if cmeta then
local tpos = vector.subtract (cpos, vec) local tpos = vector.subtract (cpos, vec)
local tmeta = cmeta:to_table () local tmeta = cmeta:to_table ()
local ctimer = minetest.get_node_timer (cpos)
local ctimeout = (ctimer and ctimer:get_timeout ()) or 0
local celapsed = (ctimer and ctimer:get_elapsed ()) or 0
minetest.remove_node (cpos) minetest.remove_node (cpos)
minetest.set_node (tpos, cnode) minetest.set_node (tpos, cnode)
@@ -172,6 +186,14 @@ local function pull_node (pos, extent)
cmeta:from_table (tmeta) cmeta:from_table (tmeta)
end end
end end
if ctimeout > 0 then
ctimer = minetest.get_node_timer (tpos)
if ctimer then
ctimer:set (ctimeout, celapsed)
end
end
end end
end end
end end

View File

@@ -13,7 +13,7 @@ CC BY-SA 3.0
Version Version
======= =======
0.1.20 0.1.21
Minetest Version Minetest Version

BIN
sounds/lwmovefloor.ogg Normal file

Binary file not shown.