diff --git a/basis/fly_lib.lua b/basis/fly_lib.lua index 007d02a..2a23038 100644 --- a/basis/fly_lib.lua +++ b/basis/fly_lib.lua @@ -57,6 +57,96 @@ local function rotate(v, yaw) return {x = v.x * cosyaw - v.z * sinyaw, y = v.y, z = v.x * sinyaw + v.z * cosyaw} end +local function set_node(item) + local dest_pos = item.dest_pos + local name = item.name or "air" + local param2 = item.param2 or 0 + local metadata = item.metadata or {} + local nvm = techage.get_nvm(item.base_pos) + local node = techage.get_node_lvm(dest_pos) + local ndef1 = minetest.registered_nodes[name] + local ndef2 = minetest.registered_nodes[node.name] + + nvm.running = false + M(item.base_pos):set_string("status", S("Stopped")) + if ndef1 and ndef2 then + if ndef2.buildable_to then + local meta = M(dest_pos) + minetest.set_node(dest_pos, {name=name, param2=param2}) + meta:from_table(item.metadata or {}) + meta:set_string("ta_move_block", "") + meta:set_int("ta_door_locked", 1) + return + end + local meta = M(dest_pos) + if not meta:contains("ta_move_block") then + meta:set_string("ta_move_block", minetest.serialize({name=name, param2=param2})) + return + end + elseif ndef1 then + minetest.add_item(dest_pos, ItemStack(name)) + end +end + +------------------------------------------------------------------------------- +-- Entity monitoring +------------------------------------------------------------------------------- +local queue = {} +local first = 0 +local last = -1 + +local function push(item) + last = last + 1 + queue[last] = item +end + +local function pop(nvm, time) + if first > last then return end + local item = queue[first] + queue[first] = nil -- to allow garbage collection + first = first + 1 + return item +end + +local function monitoring() + local num = last - first + 1 + for _ = 1, num do + local item = pop() + if item.ttl >= techage.SystemTime then + -- still valud + push(item) + elseif item.ttl ~= 0 then + set_node(item) + end + end + minetest.after(1, monitoring) +end +minetest.after(1, monitoring) + +minetest.register_on_shutdown(function() + local num = last - first + 1 + for _ = 1, num do + local item = pop() + if item.ttl ~= 0 then + set_node(item) + end + end +end) + +local function monitoring_add_entity(item) + item.ttl = techage.SystemTime + 1 + push(item) +end + +local function monitoring_del_entity(item) + -- Mark as timed out + item.ttl = 0 +end + +local function monitoring_trigger_entity(item) + item.ttl = techage.SystemTime + 1 +end + ------------------------------------------------------------------------------- -- to_path function for the fly/move path ------------------------------------------------------------------------------- @@ -308,47 +398,17 @@ local function detach_objects(pos, self) self.players = {} end -local function set_node(pos, name, param2, metadata) - local node = minetest.get_node(pos) - local ndef1 = minetest.registered_nodes[name] - local ndef2 = minetest.registered_nodes[node.name] - if ndef1 and ndef2 then - if ndef2.buildable_to then - local meta = M(pos) - minetest.set_node(pos, {name=name, param2=param2}) - meta:from_table(metadata) - meta:set_string("ta_move_block", "") - meta:set_int("ta_door_locked", 1) - return - end - local meta = M(pos) - if not meta:contains("ta_move_block") then - meta:set_string("ta_move_block", minetest.serialize({name=name, param2=param2})) - return - end - --minetest.add_item(pos, ItemStack(name)) - elseif ndef1 then - minetest.add_item(pos, ItemStack(name)) - end -end - local function entity_to_node(pos, obj) local self = obj:get_luaentity() - if self then - local name = self.item_name or "air" - local param2 = self.param2 or 0 - local metadata = self.metadata or {} + if self and self.item then detach_objects(pos, self) - if self.base_pos then - local nvm = techage.get_nvm(self.base_pos) - nvm.running = nil - end + monitoring_del_entity(self.item) minetest.after(0.1, obj.remove, obj) - set_node(pos, name, param2, metadata) + set_node(self.item) end end -local function node_to_entity(start_pos) +local function node_to_entity(base_pos, start_pos, dest_pos) local meta = M(start_pos) local node, metadata @@ -360,7 +420,7 @@ local function node_to_entity(start_pos) meta:set_string("ta_block_locked", "true") elseif not meta:contains("ta_block_locked") then -- Block with other metadata - node = minetest.get_node(start_pos) + node = techage.get_node_lvm(start_pos) metadata = meta:to_table() minetest.after(0.1, minetest.remove_node, start_pos) else @@ -375,9 +435,15 @@ local function node_to_entity(start_pos) obj:set_armor_groups({immortal=1}) -- To be able to revert to node - self.item_name = node.name self.param2 = node.param2 - self.metadata = metadata or {} + self.item = { + name = node.name, + param2 = node.param2, + metadata = metadata or {}, + dest_pos = dest_pos, + base_pos = base_pos, + } + monitoring_add_entity(self.item) -- Prepare for attachments self.players = {} @@ -440,7 +506,6 @@ local function handover_to(obj, self, pos1) end local pos2 = next_path_pos(pos1, self.lpath, 1) local dir = determine_dir(pos1, pos2) - --print("handover_to", P2S(pos1), P2S(pos2), P2S(dir), P2S(info.pos), meta:get_string("path")) if not self.handover then local nvm = techage.get_nvm(info.pos) nvm.lpos1 = nvm.lpos1 or {} @@ -462,7 +527,7 @@ minetest.register_entity("techage:move_item", { initial_properties = { pointable = true, makes_footstep_sound = true, - static_save = true, + static_save = false, collide_with_objects = false, physical = false, visual = "wielditem", @@ -471,55 +536,6 @@ minetest.register_entity("techage:move_item", { selectionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, }, - get_staticdata = function(self) - if self.start_pos and self.dest_pos then - local pos = vector.round(self.object:get_pos()) - if not vector.equals(pos, self.start_pos) and not vector.equals(pos, self.dest_pos) then - set_node(self.dest_pos, self.item_name, self.param2, self.metadata or {}) - end - end - return minetest.serialize({ - item_name = self.item_name, - param2 = self.param2, - metadata = self.metadata, - move2to1 = self.move2to1, - handover = self.handover, - path_idx = self.path_idx, - pos1_idx = self.pos1_idx, - lpath = self.lpath, - start_pos = self.start_pos, - base_pos = self.base_pos, - max_speed = self.max_speed, - dest_pos = self.dest_pos, - dir = self.dir, - respawn = true, - }) - end, - - on_activate = function(self, staticdata) - if staticdata then - local tbl = minetest.deserialize(staticdata) or {} - self.item_name = tbl.item_name or "air" - self.param2 = tbl.param2 or 0 - self.metadata = tbl.metadata or {} - self.move2to1 = tbl.move2to1 or false - self.handover = tbl.handover - self.path_idx = tbl.path_idx or 1 - self.pos1_idx = tbl.pos1_idx or 1 - self.lpath = tbl.lpath or {} - self.max_speed = tbl.max_speed or MAX_SPEED - self.dest_pos = tbl.dest_pos or self.object:get_pos() - self.start_pos = tbl.start_pos or self.object:get_pos() - self.base_pos = tbl.base_pos - self.dir = tbl.dir or {x=0, y=0, z=0} - self.object:set_properties({wield_item = self.item}) - --print("tbl.respawn", tbl.respawn) - if tbl.respawn then - entity_to_node(self.dest_pos, self.object) - end - end - end, - on_step = function(self, dtime, moveresult) local stop_obj = function(obj, self) local dest_pos = self.dest_pos @@ -528,7 +544,6 @@ minetest.register_entity("techage:move_item", { obj:set_velocity({x=0, y=0, z=0}) self.dest_pos = nil self.old_dist = nil - self.ttl = 2 return dest_pos end @@ -581,19 +596,13 @@ minetest.register_entity("techage:move_item", { end end - elseif self.ttl then - self.ttl = self.ttl - dtime - if self.ttl < 0 then - local obj = self.object - local pos = obj:get_pos() - entity_to_node(pos, obj) - end + monitoring_trigger_entity(self.item) end end, }) local function is_valid_dest(pos) - local node = minetest.get_node(pos) + local node = techage.get_node_lvm(pos) if techage.is_air_like(node.name) then return true end @@ -604,20 +613,19 @@ local function is_valid_dest(pos) end local function is_simple_node(pos) - local node = minetest.get_node(pos) + local node =techage.get_node_lvm(pos) local ndef = minetest.registered_nodes[node.name] return not techage.is_air_like(node.name) and techage.can_dig_node(node.name, ndef) end local function move_node(pos, pos1_idx, start_pos, lpath, max_speed, height, move2to1, handover, cpos) local pos2 = next_path_pos(start_pos, lpath, 1) - --print("move_node", P2S(pos), P2S(start_pos), lpath, max_speed, height, move2to1, P2S(pos2)) -- optional for non-player objects local yoffs = M(pos):get_float("offset") if pos2 then local dir = determine_dir(start_pos, pos2) - local obj = node_to_entity(start_pos) + local obj = node_to_entity(pos, start_pos, pos2) if obj then local offs = {x=0, y=height or 1, z=0} @@ -632,21 +640,17 @@ local function move_node(pos, pos1_idx, start_pos, lpath, max_speed, height, mov self.pos1_idx = pos1_idx self.lpath = lpath self.max_speed = max_speed - self.start_pos = start_pos - self.base_pos = pos self.move2to1 = move2to1 self.handover = handover self.yoffs = yoffs - --print("move_node", P2S(start_pos), P2S(pos2), P2S(dir), P2S(pos)) move_entity(obj, pos2, dir) end end end local function move_nodes(pos, meta, nvm, lpath, max_speed, height, move2to1, handover) - --print("move_nodes", dump(nvm), dump(lpath), max_speed, height, move2to1, handover) local owner = meta:get_string("owner") - techage.counting_add(owner, #nvm.lpos1 * #lpath) + techage.counting_add(owner, #lpath, #nvm.lpos1 * #lpath) for idx = 1, #nvm.lpos1 do local pos1 = nvm.lpos1[idx] @@ -656,7 +660,6 @@ local function move_nodes(pos, meta, nvm, lpath, max_speed, height, move2to1, ha pos1, pos2 = pos2, pos1 end - --print("move_nodes", P2S(pos1), P2S(pos2)) if not minetest.is_protected(pos1, owner) and not minetest.is_protected(pos2, owner) then if is_simple_node(pos1) and is_valid_dest(pos2) then move_node(pos, idx, pos1, lpath, max_speed, height, move2to1, handover) @@ -666,6 +669,7 @@ local function move_nodes(pos, meta, nvm, lpath, max_speed, height, move2to1, ha else meta:set_string("status", S("No valid destination position")) end + return false end else if minetest.is_protected(pos1, owner) then @@ -676,12 +680,12 @@ local function move_nodes(pos, meta, nvm, lpath, max_speed, height, move2to1, ha return false end end + meta:set_string("status", S("Running")) return true end -- Move nodes from lpos1 by the given x/y/z 'line' local function move_nodes2(pos, meta, lpos1, line, max_speed, height) - --print("move_nodes2", dump(lpos1), dump(line), max_speed, height) local owner = meta:get_string("owner") techage.counting_add(owner, #lpos1) @@ -701,6 +705,7 @@ local function move_nodes2(pos, meta, lpos1, line, max_speed, height) else meta:set_string("status", S("No valid destination position")) end + return false, lpos1 end else if minetest.is_protected(pos1, owner) then @@ -712,7 +717,7 @@ local function move_nodes2(pos, meta, lpos1, line, max_speed, height) end end - meta:set_string("status", "") + meta:set_string("status", S("Running")) return true, lpos2 end @@ -724,7 +729,7 @@ function flylib.move_to_other_pos(pos, move2to1) local height = meta:contains("height") and meta:get_float("height") or 1 local handover - if err then return false end + if err or nvm.running then return false end height = techage.in_range(height, 0, 1) max_speed = techage.in_range(max_speed, MIN_SPEED, MAX_SPEED) @@ -742,7 +747,9 @@ function flylib.move_to_other_pos(pos, move2to1) else handover = meta:contains("handoverB") and meta:get_string("handoverB") or nil end - return move_nodes(pos, meta, nvm, lpath, max_speed, height, move2to1, handover) + nvm.running = move_nodes(pos, meta, nvm, lpath, max_speed, height, move2to1, handover) + nvm.moveBA = nvm.running and not move2to1 + return nvm.running end function flylib.move_to(pos, line) @@ -752,8 +759,10 @@ function flylib.move_to(pos, line) local max_speed = meta:contains("max_speed") and meta:get_int("max_speed") or MAX_SPEED local resp - resp, nvm.lastpos = move_nodes2(pos, meta, nvm.lastpos or nvm.lpos1, line, max_speed, height) - return resp + if nvm.running then return false end + + nvm.running, nvm.lastpos = move_nodes2(pos, meta, nvm.lastpos or nvm.lpos1, line, max_speed, height) + return nvm.running end function flylib.reset_move(pos) @@ -761,12 +770,15 @@ function flylib.reset_move(pos) local nvm = techage.get_nvm(pos) local height = techage.in_range(meta:contains("height") and meta:get_float("height") or 1, 0, 1) local max_speed = meta:contains("max_speed") and meta:get_int("max_speed") or MAX_SPEED + + if nvm.running then return false end + if nvm.lpos1 and nvm.lpos1[1] then local move = vector.subtract(nvm.lpos1[1], (nvm.lastpos or nvm.lpos1)[1]) local resp - resp, nvm.lastpos = move_nodes2(pos, meta, nvm.lastpos or nvm.lpos1, move, max_speed, height) - return resp + nvm.running, nvm.lastpos = move_nodes2(pos, meta, nvm.lastpos or nvm.lpos1, move, max_speed, height) + return nvm.running end return false end @@ -855,4 +867,4 @@ minetest.register_on_dieplayer(function(player) end end) -return flylib +techage.flylib = flylib diff --git a/init.lua b/init.lua index b6d0287..a17e3ba 100644 --- a/init.lua +++ b/init.lua @@ -105,6 +105,7 @@ dofile(MP.."/basis/submenu.lua") dofile(MP.."/basis/shared_inv.lua") dofile(MP.."/basis/shared_tank.lua") dofile(MP.."/basis/teleport.lua") +dofile(MP.."/basis/fly_lib.lua") -- Main doc dofile(MP.."/doc/manual_DE.lua") diff --git a/move_controller/doorcontroller2.lua b/move_controller/doorcontroller2.lua index 48aa46d..70e69e7 100644 --- a/move_controller/doorcontroller2.lua +++ b/move_controller/doorcontroller2.lua @@ -17,9 +17,8 @@ local M = minetest.get_meta local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end local S = techage.S -local MP = minetest.get_modpath("techage") -local flylib = dofile(MP .. "/basis/fly_lib.lua") local logic = techage.logic +local fly = techage.flylib local MarkedNodes = {} -- t[player] = {{entity, pos},...} local CurrentPos -- to mark punched entities @@ -439,7 +438,7 @@ local Doors = { for _, name in ipairs(Doors) do for _, postfix in ipairs({"a", "b", "c", "d"}) do techage.register_simple_nodes({name .. "_" .. postfix}, true) - flylib.protect_door_from_being_opened(name .. "_" .. postfix) + fly.protect_door_from_being_opened(name .. "_" .. postfix) end end @@ -453,6 +452,6 @@ local ProtectorDoors = { for _, name in ipairs(ProtectorDoors) do for _, postfix in ipairs({"b_1", "b_2", "t_1", "t_2"}) do techage.register_simple_nodes({name .. "_" .. postfix}, true) - flylib.protect_door_from_being_opened(name .. "_" .. postfix) + fly.protect_door_from_being_opened(name .. "_" .. postfix) end end diff --git a/move_controller/flycontroller.lua b/move_controller/flycontroller.lua index 36354ff..6e56c49 100644 --- a/move_controller/flycontroller.lua +++ b/move_controller/flycontroller.lua @@ -19,8 +19,8 @@ local S2P = minetest.string_to_pos local S = techage.S local MP = minetest.get_modpath("techage") -local fly = dofile(MP .. "/basis/fly_lib.lua") local mark = dofile(MP .. "/basis/mark_lib.lua") +local fly = techage.flylib local MAX_DIST = 500 local MAX_BLOCKS = 16 diff --git a/move_controller/movecontroller.lua b/move_controller/movecontroller.lua index 2f795f3..be1bb5d 100644 --- a/move_controller/movecontroller.lua +++ b/move_controller/movecontroller.lua @@ -19,8 +19,8 @@ local S2P = minetest.string_to_pos local S = techage.S local MP = minetest.get_modpath("techage") -local fly = dofile(MP .. "/basis/fly_lib.lua") local mark = dofile(MP .. "/basis/mark_lib.lua") +local fly = techage.flylib local MAX_DIST = 200 local MAX_BLOCKS = 16 @@ -131,6 +131,7 @@ minetest.register_node("techage:ta4_movecontroller", { nvm.lpos2 = {} nvm.moveBA = false nvm.running = nil + nvm.lastpos = nil meta:set_string("status", S("Recording...")) local name = player:get_player_name() minetest.chat_send_player(name, S("Click on all blocks that shall be moved")) @@ -144,6 +145,7 @@ minetest.register_node("techage:ta4_movecontroller", { end local text = #pos_list.." "..S("block positions are stored.") nvm.running = nil + nvm.lastpos = nil meta:set_string("status", text) nvm.lpos1 = pos_list mark.unmark_all(name) @@ -161,11 +163,10 @@ minetest.register_node("techage:ta4_movecontroller", { mark.stop(name) nvm.moveBA = false nvm.running = nil + nvm.lastpos = nil elseif fields.moveAB then meta:set_string("status", "") if fly.move_to_other_pos(pos, false) then - nvm.moveBA = true - nvm.running = true meta:set_string("formspec", formspec(nvm, meta)) local name = player:get_player_name() mark.stop(name) @@ -174,8 +175,6 @@ minetest.register_node("techage:ta4_movecontroller", { elseif fields.moveBA then meta:set_string("status", "") if fly.move_to_other_pos(pos, true) then - nvm.moveBA = false - nvm.running = true meta:set_string("formspec", formspec(nvm, meta)) local name = player:get_player_name() mark.stop(name) @@ -187,11 +186,9 @@ minetest.register_node("techage:ta4_movecontroller", { end local line = fly.to_vector(meta:get_string("path"), MAX_DIST) if line then - nvm.running = true fly.move_to(pos, line) end elseif fields.reset then - nvm.running = true fly.reset_move(pos) end end, @@ -230,28 +227,18 @@ techage.register_node({"techage:ta4_movecontroller"}, { elseif topic == "state" then return nvm.running and "running" or "stopped" elseif not move_xyz and topic == "a2b" then - nvm.moveBA = true - nvm.running = true return fly.move_to_other_pos(pos, false) elseif not move_xyz and topic == "b2a" then - nvm.moveBA = false - nvm.running = true return fly.move_to_other_pos(pos, true) elseif not move_xyz and topic == "move" then - nvm.moveBA = nvm.moveBA == false - nvm.running = true return fly.move_to_other_pos(pos, nvm.moveBA == false) elseif move_xyz and topic == "move2" then local line = fly.to_vector(payload, MAX_DIST) if line then - nvm.running = true - nvm.controller_mode = true return fly.move_to(pos, line) end return false elseif topic == "reset" then - nvm.running = true - nvm.controller_mode = true return fly.reset_move(pos) end return false @@ -262,16 +249,10 @@ techage.register_node({"techage:ta4_movecontroller"}, { --print("on_beduino_receive_cmnd", P2S(pos), move_xyz, topic, payload[1]) if not move_xyz and topic == 11 then if payload[1] == 1 then - nvm.moveBA = true - nvm.running = true return fly.move_to_other_pos(pos, false) and 0 or 3 elseif payload[1] == 2 then - nvm.moveBA = false - nvm.running = true return fly.move_to_other_pos(pos, true) and 0 or 3 elseif payload[1] == 3 then - nvm.moveBA = nvm.moveBA == false - nvm.running = true return fly.move_to_other_pos(pos, nvm.moveBA == false) and 0 or 3 end elseif move_xyz and topic == 18 then -- move xyz @@ -280,12 +261,8 @@ techage.register_node({"techage:ta4_movecontroller"}, { y = techage.in_range(techage.beduino_signed_var(payload[2]), -100, 100), z = techage.in_range(techage.beduino_signed_var(payload[3]), -100, 100), } - nvm.running = true - nvm.controller_mode = true return fly.move_to(pos, line) and 0 or 3 elseif move_xyz and topic == 19 then -- reset - nvm.running = true - nvm.controller_mode = true return fly.reset_move(pos) and 0 or 3 else return 2 @@ -298,6 +275,10 @@ techage.register_node({"techage:ta4_movecontroller"}, { end return 2, "" end, + on_node_load = function(pos, node) + local nvm = techage.get_nvm(pos) + nvm.running = false + end, }) minetest.register_craft({ diff --git a/move_controller/turncontroller.lua b/move_controller/turncontroller.lua index 33a3b56..2dc9588 100644 --- a/move_controller/turncontroller.lua +++ b/move_controller/turncontroller.lua @@ -19,8 +19,8 @@ local S2P = minetest.string_to_pos local S = techage.S local MP = minetest.get_modpath("techage") -local fly = dofile(MP .. "/basis/fly_lib.lua") local mark = dofile(MP .. "/basis/mark_lib.lua") +local fly = techage.flylib local MAX_BLOCKS = 16