mirror of
https://github.com/minetest-mods/technic.git
synced 2025-07-05 01:30:37 +02:00
update code
This commit is contained in:
@ -89,73 +89,123 @@ local function add_table(table,toadd)
|
|||||||
table[i] = toadd
|
table[i] = toadd
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- don't use minetest. Get node more times at the same position
|
||||||
|
local nodes_cache = {}
|
||||||
|
|
||||||
|
local function get_node(pos)
|
||||||
|
local node = get(nodes_cache, pos.z,pos.y,pos.x)
|
||||||
|
if node then
|
||||||
|
return node
|
||||||
|
end
|
||||||
|
node = minetest.get_node(pos)
|
||||||
|
set(nodes_cache, pos.z,pos.y,pos.x, node)
|
||||||
|
return node
|
||||||
|
end
|
||||||
|
|
||||||
|
local function set_node(pos, node)
|
||||||
|
set(nodes_cache, pos.z,pos.y,pos.x, node)
|
||||||
|
minetest.set_node(pos, node)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function remove_node(pos)
|
||||||
|
set(nodes_cache, pos.z,pos.y,pos.x, {name="air", param1=0, param2=0})
|
||||||
|
minetest.remove_node(pos)
|
||||||
|
end
|
||||||
|
|
||||||
local function move_nodes_vect(poslist, vect, must_not_move, owner)
|
local function move_nodes_vect(poslist, vect, must_not_move, owner)
|
||||||
local dones = {}
|
local dones = {}
|
||||||
for _,pos in ipairs(poslist) do
|
local oldps = {}
|
||||||
|
for _,pos in pairs(poslist) do
|
||||||
if not get(dones, pos.z,pos.y,pos.x) then
|
if not get(dones, pos.z,pos.y,pos.x) then
|
||||||
if minetest.is_protected(pos, owner) then
|
if minetest.is_protected(pos, owner) then
|
||||||
|
nodes_cache = {}
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
set(dones, pos.z,pos.y,pos.x, true)
|
set(dones, pos.z,pos.y,pos.x, true)
|
||||||
|
set(oldps, pos.z,pos.y,pos.x, true)
|
||||||
end
|
end
|
||||||
local pos = vector.add(pos, vect)
|
local pos = vector.add(pos, vect)
|
||||||
if not get(dones, pos.z,pos.y,pos.x) then
|
if not get(dones, pos.z,pos.y,pos.x) then
|
||||||
if minetest.is_protected(pos, owner) then
|
if minetest.is_protected(pos, owner) then
|
||||||
|
nodes_cache = {}
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
set(dones, pos.z,pos.y,pos.x, true)
|
set(dones, pos.z,pos.y,pos.x, true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
dones = nil
|
dones = nil
|
||||||
for _,pos in ipairs(poslist) do
|
|
||||||
|
-- search for blocking at the new positions where it moves to
|
||||||
|
for _,pos in pairs(poslist) do
|
||||||
local npos = vector.add(pos,vect)
|
local npos = vector.add(pos,vect)
|
||||||
local name = minetest.get_node(npos).name
|
if not get(oldps, npos.z,npos.y,npos.x) then
|
||||||
if (
|
if get_frame(npos) then
|
||||||
(name ~= "air" and minetest.registered_nodes[name].liquidtype == "none")
|
-- blocking alien frame
|
||||||
or get_frame(npos)
|
nodes_cache = {}
|
||||||
) and not pos_in_list(poslist,npos) then
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
--[[if pos.x==must_not_move.x and pos.y==must_not_move.y and pos.z==must_not_move.z then
|
local name = get_node(npos).name
|
||||||
|
if name ~= "air" then
|
||||||
|
name = minetest.registered_nodes[name]
|
||||||
|
if not name
|
||||||
|
or not name.buildable_to then
|
||||||
|
-- another blocking node
|
||||||
|
nodes_cache = {}
|
||||||
return
|
return
|
||||||
end]]
|
|
||||||
end
|
end
|
||||||
local nodelist = {}
|
|
||||||
for _, pos in ipairs(poslist) do
|
|
||||||
nodelist[#(nodelist)+1] = {oldpos=pos, pos=vector.add(pos, vect), node=minetest.get_node(pos), meta=minetest.get_meta(pos):to_table()}
|
|
||||||
end
|
end
|
||||||
local objects = {}
|
end
|
||||||
for _, pos in ipairs(poslist) do
|
end
|
||||||
for _,object in ipairs(minetest.get_objects_inside_radius(pos, 1)) do
|
oldps = nil
|
||||||
local entity = object:get_luaentity()
|
|
||||||
|
-- move objects
|
||||||
|
for _,pos in pairs(poslist) do
|
||||||
|
for _,obj in pairs(minetest.get_objects_inside_radius(pos, 1)) do
|
||||||
|
local entity = obj:get_luaentity()
|
||||||
if not entity
|
if not entity
|
||||||
or not mesecon.is_mvps_unmov(entity.name) then
|
or not mesecon.is_mvps_unmov(entity.name) then
|
||||||
add_table(objects, object)
|
obj:moveto(vector.add(obj:getpos(), vect))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for _, obj in ipairs(objects) do
|
|
||||||
obj:setpos(vector.add(obj:getpos(), vect))
|
-- store current node information
|
||||||
|
local nodelist = {}
|
||||||
|
for n,pos in pairs(poslist) do
|
||||||
|
nodelist[n] = {oldpos=pos, pos=vector.add(pos, vect), node=get_node(pos), meta=minetest.get_meta(pos):to_table()}
|
||||||
end
|
end
|
||||||
for _,n in ipairs(nodelist) do
|
|
||||||
|
-- set new nodes
|
||||||
|
local newps = {}
|
||||||
|
for _,n in pairs(nodelist) do
|
||||||
local npos = n.pos
|
local npos = n.pos
|
||||||
minetest.set_node(npos, n.node)
|
local current_node = get_node(npos)
|
||||||
|
local node = n.node
|
||||||
|
if current_node.name ~= node.name
|
||||||
|
or current_node.param1 ~= node.param1
|
||||||
|
or current_node.param2 ~= node.param2 then
|
||||||
|
set_node(npos, n.node)
|
||||||
|
end
|
||||||
minetest.get_meta(npos):from_table(n.meta)
|
minetest.get_meta(npos):from_table(n.meta)
|
||||||
for i,pos in ipairs(poslist) do
|
set(newps, npos.z,npos.y,npos.x, true)
|
||||||
if vector.equals(nops, pos) then
|
end
|
||||||
table.remove(poslist, i)
|
|
||||||
break
|
-- remove old ones
|
||||||
|
for _,pos in pairs(poslist) do
|
||||||
|
if not get(newps, pos.z,pos.y,pos.x)
|
||||||
|
and get_node(pos).name ~= "air" then
|
||||||
|
remove_node(pos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
nodes_cache = {}
|
||||||
for _, pos in ipairs(poslist) do
|
|
||||||
minetest.remove_node(pos)
|
-- update mesecons
|
||||||
end
|
|
||||||
for _,callback in ipairs(mesecon.on_mvps_move) do
|
for _,callback in ipairs(mesecon.on_mvps_move) do
|
||||||
callback(nodelist)
|
callback(nodelist)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- tells if it's a node which could be put into a frame
|
||||||
local function is_supported_node(name)
|
local function is_supported_node(name)
|
||||||
return string.find(name, "tube") ~= nil and string.find(name, "pipeworks") ~= nil
|
return string.find(name, "tube") ~= nil and string.find(name, "pipeworks") ~= nil
|
||||||
end
|
end
|
||||||
@ -193,7 +243,7 @@ end
|
|||||||
local function place_frame(itemstack, placer, pointed_thing)
|
local function place_frame(itemstack, placer, pointed_thing)
|
||||||
local pos = pointed_thing.above
|
local pos = pointed_thing.above
|
||||||
if not pos then
|
if not pos then
|
||||||
return
|
return itemstack
|
||||||
end
|
end
|
||||||
local pname = placer:get_player_name()
|
local pname = placer:get_player_name()
|
||||||
local nodename = itemstack:get_name()
|
local nodename = itemstack:get_name()
|
||||||
@ -205,12 +255,15 @@ local function place_frame(itemstack, placer, pointed_thing)
|
|||||||
minetest.record_protection_violation(pos, pname)
|
minetest.record_protection_violation(pos, pname)
|
||||||
return itemstack
|
return itemstack
|
||||||
end
|
end
|
||||||
local node = minetest.get_node(pos)
|
local name = minetest.get_node(pos).name
|
||||||
if node.name == "air" then
|
if name == "air" then
|
||||||
minetest.set_node(pos, {name = nodename})
|
minetest.set_node(pos, {name = nodename})
|
||||||
elseif is_supported_node(node.name) then
|
elseif is_supported_node(name) then
|
||||||
obj = minetest.add_entity(pos, "technic:frame_entity")
|
obj = minetest.add_entity(pos, "technic:frame_entity")
|
||||||
obj:get_luaentity():set_node({name=nodename})
|
obj:get_luaentity():set_node({name=nodename})
|
||||||
|
else
|
||||||
|
-- don't take an item when no frame is placed
|
||||||
|
return itemstack
|
||||||
end
|
end
|
||||||
if not infinite_stacks then
|
if not infinite_stacks then
|
||||||
itemstack:take_item()
|
itemstack:take_item()
|
||||||
@ -220,7 +273,12 @@ end
|
|||||||
|
|
||||||
local function rightclick_frame(pos, node, placer, itemstack, pointed_thing)
|
local function rightclick_frame(pos, node, placer, itemstack, pointed_thing)
|
||||||
local nodename = itemstack:get_name()
|
local nodename = itemstack:get_name()
|
||||||
if is_supported_node(nodename) then
|
if not is_supported_node(nodename) then
|
||||||
|
if pointed_thing then
|
||||||
|
return minetest.item_place_node(itemstack, placer, pointed_thing)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local pname = placer:get_player_name()
|
local pname = placer:get_player_name()
|
||||||
if minetest.is_protected(pos, pname) then
|
if minetest.is_protected(pos, pname) then
|
||||||
minetest.log("action", pname
|
minetest.log("action", pname
|
||||||
@ -231,40 +289,18 @@ local function rightclick_frame(pos, node, placer, itemstack, pointed_thing)
|
|||||||
return itemstack
|
return itemstack
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.set_node(pos, {name = nodename})
|
minetest.remove_node(pos)
|
||||||
|
itemstack,success = minetest.item_place_node(itemstack, placer, pointed_thing)
|
||||||
|
|
||||||
local take_item = true
|
if not success then
|
||||||
local def = minetest.registered_items[nodename]
|
-- this shouldn't happen
|
||||||
-- Run callback
|
minetest.set_node(pos, node)
|
||||||
if def.after_place_node then
|
return itemstack
|
||||||
if def.after_place_node(vector.new(pos), placer, itemstack) then
|
|
||||||
take_item = false
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Run script hook
|
minetest.add_entity(pos, "technic:frame_entity"):get_luaentity():set_node(node)
|
||||||
for _, callback in ipairs(minetest.registered_on_placenodes) do
|
|
||||||
local newnode_copy = {name=def.name, param1=0, param2=0}
|
|
||||||
local oldnode_copy = {name="air", param1=0, param2=0}
|
|
||||||
if callback(vector.new(pos), newnode_copy, placer, oldnode_copy, itemstack) then
|
|
||||||
take_item = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if take_item then
|
|
||||||
itemstack:take_item()
|
|
||||||
end
|
|
||||||
|
|
||||||
obj = minetest.add_entity(pos, "technic:frame_entity")
|
|
||||||
obj:get_luaentity():set_node({name=node.name})
|
|
||||||
|
|
||||||
return itemstack
|
return itemstack
|
||||||
else
|
|
||||||
--local pointed_thing = {type = "node", under = pos}
|
|
||||||
if pointed_thing then
|
|
||||||
minetest.item_place_node(itemstack, placer, pointed_thing)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -315,10 +351,15 @@ for zp=0,1 do
|
|||||||
table.insert(nodeboxes, {-b,-b,-a, b,b,-b})
|
table.insert(nodeboxes, {-b,-b,-a, b,b,-b})
|
||||||
end
|
end
|
||||||
|
|
||||||
local nameext = tostring(xm)..tostring(xp)..tostring(ym)..tostring(yp)..tostring(zm)..tostring(zp)
|
local nameext = string.format("%01o/%01o/%01o/%01o/%01o/%01o", xm, xp, ym, yp, zm, zp))
|
||||||
local groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}
|
local groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}
|
||||||
|
local place_function
|
||||||
if nameext ~= "111111" then
|
if nameext ~= "111111" then
|
||||||
groups.not_in_creative_inventory = 1
|
groups.not_in_creative_inventory = 1
|
||||||
|
else
|
||||||
|
function place_function(...)
|
||||||
|
return place_frame(...)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -342,9 +383,7 @@ for zp=0,1 do
|
|||||||
on_punch = function(...)
|
on_punch = function(...)
|
||||||
return punch_frame(...)
|
return punch_frame(...)
|
||||||
end,
|
end,
|
||||||
on_place = function(...)
|
on_place = place_function,
|
||||||
return place_frame(...)
|
|
||||||
end,
|
|
||||||
on_rightclick = function(...)
|
on_rightclick = function(...)
|
||||||
return rightclick_frame(...)
|
return rightclick_frame(...)
|
||||||
end,
|
end,
|
||||||
@ -516,8 +555,7 @@ minetest.register_on_dignode(function(pos, node)
|
|||||||
end
|
end
|
||||||
minetest.set_node(pos, {name = name})
|
minetest.set_node(pos, {name = name})
|
||||||
remove_frame(pos)
|
remove_frame(pos)
|
||||||
local objects = minetest.get_objects_inside_radius(pos, 0.1)
|
for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0.1)) do
|
||||||
for _, obj in ipairs(objects) do
|
|
||||||
local entity = obj:get_luaentity()
|
local entity = obj:get_luaentity()
|
||||||
if entity
|
if entity
|
||||||
and (entity.name == "technic:frame_entity" or entity.name == "technic:damage_entity") then
|
and (entity.name == "technic:frame_entity" or entity.name == "technic:damage_entity") then
|
||||||
@ -527,38 +565,49 @@ minetest.register_on_dignode(function(pos, node)
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
-- Frame motor
|
-- Frame motor
|
||||||
local function connected(pos, c, adj)
|
|
||||||
for _,vect in ipairs(adj) do
|
|
||||||
local pos1 = vector.add(pos,vect)
|
|
||||||
local nodename = get_frame(pos1) or minetest.get_node(pos1).name
|
|
||||||
if not pos_in_list(c,pos1)
|
|
||||||
and nodename~="air"
|
|
||||||
and (
|
|
||||||
minetest.registered_nodes[nodename].frames_can_connect == nil
|
|
||||||
or minetest.registered_nodes[nodename].frames_can_connect(pos1,vect)
|
|
||||||
) then
|
|
||||||
c[#(c)+1] = pos1
|
|
||||||
if minetest.registered_nodes[nodename].frame == 1 then
|
|
||||||
local adj = minetest.registered_nodes[nodename].frame_connect_all(nodename)
|
|
||||||
connected(pos1,c,adj)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get_connected_nodes(pos)
|
local function get_connected_nodes(pos)
|
||||||
c={pos}
|
local nodename = get_frame(pos) or get_node(pos).name
|
||||||
local nodename = get_frame(pos) or minetest.get_node(pos).name
|
local poslist,num = {},1
|
||||||
connected(pos,c,minetest.registered_nodes[nodename].frame_connect_all(nodename))
|
local dones = {}
|
||||||
return c
|
local todo = {{pos, minetest.registered_nodes[nodename].frame_connect_all(nodename)}}
|
||||||
|
while next(todo) do
|
||||||
|
for n,data in pairs(todo) do
|
||||||
|
local pos, adj = unpack(data)
|
||||||
|
for _,vect in pairs(adj) do
|
||||||
|
local p = vector.add(pos, vect)
|
||||||
|
if not get(dones, p.z,p.y,p.x) then
|
||||||
|
local nodename = get_frame(p) or get_node(p).name
|
||||||
|
if nodename ~= "air" then
|
||||||
|
local def = minetest.registered_nodes[nodename]
|
||||||
|
if not def then
|
||||||
|
-- unknown nodes found
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
local frame_can_connect = def.frames_can_connect
|
||||||
|
if not frame_can_connect -- ← no frame node
|
||||||
|
or frame_can_connect(p, vect) then
|
||||||
|
poslist[num] = p
|
||||||
|
num = num+1
|
||||||
|
if minetest.registered_nodes[nodename].frame == 1 then
|
||||||
|
table.insert(todo, {p, minetest.registered_nodes[nodename].frame_connect_all(nodename)})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
todo[n] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return poslist
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local motor_dirs = {{x=0,y=1,z=0},{x=0,y=0,z=1},{x=0,y=0,z=-1},{x=1,y=0,z=0},{x=-1,y=0,z=0},{x=0,y=-1,z=0}}
|
||||||
local function frame_motor_on(pos, node)
|
local function frame_motor_on(pos, node)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
if meta:get_int("last_moved") == minetest.get_gametime() then
|
if meta:get_int("last_moved") == minetest.get_gametime() then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local dirs = {{x=0,y=1,z=0},{x=0,y=0,z=1},{x=0,y=0,z=-1},{x=1,y=0,z=0},{x=-1,y=0,z=0},{x=0,y=-1,z=0}}
|
local dirs = motor_dirs
|
||||||
local nnodepos = vector.add(pos, dirs[math.floor(node.param2/4)+1])
|
local nnodepos = vector.add(pos, dirs[math.floor(node.param2/4)+1])
|
||||||
local name = get_frame(nnodepos) or minetest.get_node(nnodepos).name
|
local name = get_frame(nnodepos) or minetest.get_node(nnodepos).name
|
||||||
local dir = minetest.facedir_to_dir(node.param2)
|
local dir = minetest.facedir_to_dir(node.param2)
|
||||||
@ -579,7 +628,7 @@ minetest.register_node("technic:frame_motor",{
|
|||||||
minetest.get_meta(pos):set_string("owner", placer:get_player_name())
|
minetest.get_meta(pos):set_string("owner", placer:get_player_name())
|
||||||
end,
|
end,
|
||||||
frames_can_connect = function(pos, dir)
|
frames_can_connect = function(pos, dir)
|
||||||
local dir2 = ({{x=0,y=1,z=0},{x=0,y=0,z=1},{x=0,y=0,z=-1},{x=1,y=0,z=0},{x=-1,y=0,z=0},{x=0,y=-1,z=0}})[math.floor(minetest.get_node(pos).param2/4)+1]
|
local dir2 = motor_dirs[math.floor(minetest.get_node(pos).param2/4)+1]
|
||||||
return dir2.x~=-dir.x or dir2.y~=-dir.y or dir2.z~=-dir.z
|
return dir2.x~=-dir.x or dir2.y~=-dir.y or dir2.z~=-dir.z
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user