From eaf6a679c388a161568bd870f66387dee951fd3f Mon Sep 17 00:00:00 2001 From: loosewheel <76670709+loosewheel@users.noreply.github.com> Date: Sat, 19 Feb 2022 14:08:26 +1000 Subject: [PATCH] Add files via upload --- change.log | 6 + crafting.lua | 4 +- detector.lua | 2 +- init.lua | 2 +- license.txt | 10 ++ movefloor.lua | 378 +++++++++++++++++++++++++++++++++++++++++--------- pistons.lua | 22 +++ readme.txt | 2 +- 8 files changed, 352 insertions(+), 74 deletions(-) diff --git a/change.log b/change.log index 6aa74a1..712f563 100644 --- a/change.log +++ b/change.log @@ -108,3 +108,9 @@ v0.1.19 v0.1.20 * Valid distance and resolution for camera set by digilines message. * 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. diff --git a/crafting.lua b/crafting.lua index e7ba70c..d210082 100644 --- a/crafting.lua +++ b/crafting.lua @@ -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 ({ output = "lwcomponents:movefloor", @@ -343,7 +343,7 @@ minetest.register_craft ({ } }) -end -- utils.mesecon_supported and mesecon.mvps_push +end -- utils.mesecon_supported diff --git a/detector.lua b/detector.lua index c82658c..e8be173 100644 --- a/detector.lua +++ b/detector.lua @@ -130,7 +130,7 @@ end local function get_entity_height (objref) if objref.get_luaentity then - entity = objref:get_luaentity () + local entity = objref:get_luaentity () if entity and entity.name then def = minetest.registered_entities[entity.name] diff --git a/init.lua b/init.lua index 1d18fa1..ba56b76 100644 --- a/init.lua +++ b/init.lua @@ -1,4 +1,4 @@ -local version = "0.1.20" +local version = "0.1.21" local mod_storage = minetest.get_mod_storage () diff --git a/license.txt b/license.txt index df43986..2897723 100644 --- a/license.txt +++ b/license.txt @@ -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 ------------- siren images derived from images from https://openclipart.org, which is diff --git a/movefloor.lua b/movefloor.lua index 2b426db..ac96031 100644 --- a/movefloor.lua +++ b/movefloor.lua @@ -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_pull = 3 --- helper functions: local function get_movefloor_direction (rulename) if rulename.y > 0 then return { x = 0, y = 1, z = 0 } @@ -38,6 +34,7 @@ local function get_movefloor_direction (rulename) end + local function add_movefloor_list (pos, list) for i = 1, #list do if list[i].x == pos.x and @@ -76,10 +73,289 @@ end --- copied from mesecons movestone -local function movefloor_move (pos, node, rulename, is_sticky) +local function get_node_height (node) + 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 play_sound = false local list = { @@ -88,68 +364,34 @@ local function movefloor_move (pos, node, rulename, is_sticky) 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 + local nodes, height, protected = get_affected_nodes (list) - -- ### 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 + if protected then return 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 @@ -164,8 +406,8 @@ local function mesecon_support () 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) + if rulename then + movefloor_move (pos, node, rulename) end end } @@ -190,8 +432,6 @@ minetest.register_node("lwcomponents:movefloor", { groups = { cracky = 2 }, sounds = default.node_sound_wood_defaults (), mesecons = mesecon_support (), - - on_timer = on_timer, }) diff --git a/pistons.lua b/pistons.lua index 4e5fa9c..52a5999 100644 --- a/pistons.lua +++ b/pistons.lua @@ -120,6 +120,9 @@ local function push_nodes (pos, extent) end 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) @@ -136,6 +139,14 @@ local function push_nodes (pos, extent) cmeta:from_table (tmeta) end + if ctimeout > 0 then + ctimer = minetest.get_node_timer (last) + + if ctimer then + ctimer:set (ctimeout, celapsed) + end + end + last = cpos end end @@ -161,6 +172,9 @@ local function pull_node (pos, extent) if cmeta then local tpos = vector.subtract (cpos, vec) 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.set_node (tpos, cnode) @@ -172,6 +186,14 @@ local function pull_node (pos, extent) cmeta:from_table (tmeta) end end + + if ctimeout > 0 then + ctimer = minetest.get_node_timer (tpos) + + if ctimer then + ctimer:set (ctimeout, celapsed) + end + end end end end diff --git a/readme.txt b/readme.txt index 319bd6f..aa82cb0 100644 --- a/readme.txt +++ b/readme.txt @@ -13,7 +13,7 @@ CC BY-SA 3.0 Version ======= -0.1.20 +0.1.21 Minetest Version