forked from minetest-mods/technic
Compare commits
6 Commits
master
...
frames-exp
Author | SHA1 | Date | |
---|---|---|---|
|
cac6914270 | ||
|
902cd07218 | ||
|
83ecc59e5b | ||
|
a93a61a329 | ||
|
b05e764e77 | ||
|
5aa229d454 |
|
@ -1,5 +1,9 @@
|
|||
frames = {}
|
||||
|
||||
local infinite_stacks = minetest.setting_getbool("creative_mode") and minetest.get_modpath("unified_inventory") == nil
|
||||
|
||||
local frames_pos = {}
|
||||
|
||||
-- Helpers
|
||||
|
||||
local function get_face(pos,ppos,pvect)
|
||||
|
@ -9,34 +13,34 @@ local function get_face(pos,ppos,pvect)
|
|||
local t=(-0.5-ppos.x)/pvect.x
|
||||
local y_int=ppos.y+t*pvect.y
|
||||
local z_int=ppos.z+t*pvect.z
|
||||
if y_int>-0.4 and y_int<0.4 and z_int>-0.4 and z_int<0.4 then return 1 end
|
||||
if y_int>-0.45 and y_int<0.45 and z_int>-0.45 and z_int<0.45 then return 1 end
|
||||
elseif pvect.x<0 then
|
||||
local t=(0.5-ppos.x)/pvect.x
|
||||
local y_int=ppos.y+t*pvect.y
|
||||
local z_int=ppos.z+t*pvect.z
|
||||
if y_int>-0.4 and y_int<0.4 and z_int>-0.4 and z_int<0.4 then return 2 end
|
||||
if y_int>-0.45 and y_int<0.45 and z_int>-0.45 and z_int<0.45 then return 2 end
|
||||
end
|
||||
if pvect.y>0 then
|
||||
local t=(-0.5-ppos.y)/pvect.y
|
||||
local x_int=ppos.x+t*pvect.x
|
||||
local z_int=ppos.z+t*pvect.z
|
||||
if x_int>-0.4 and x_int<0.4 and z_int>-0.4 and z_int<0.4 then return 3 end
|
||||
if x_int>-0.45 and x_int<0.45 and z_int>-0.45 and z_int<0.45 then return 3 end
|
||||
elseif pvect.y<0 then
|
||||
local t=(0.5-ppos.y)/pvect.y
|
||||
local x_int=ppos.x+t*pvect.x
|
||||
local z_int=ppos.z+t*pvect.z
|
||||
if x_int>-0.4 and x_int<0.4 and z_int>-0.4 and z_int<0.4 then return 4 end
|
||||
if x_int>-0.45 and x_int<0.45 and z_int>-0.45 and z_int<0.45 then return 4 end
|
||||
end
|
||||
if pvect.z>0 then
|
||||
local t=(-0.5-ppos.z)/pvect.z
|
||||
local x_int=ppos.x+t*pvect.x
|
||||
local y_int=ppos.y+t*pvect.y
|
||||
if x_int>-0.4 and x_int<0.4 and y_int>-0.4 and y_int<0.4 then return 5 end
|
||||
if x_int>-0.45 and x_int<0.45 and y_int>-0.45 and y_int<0.45 then return 5 end
|
||||
elseif pvect.z<0 then
|
||||
local t=(0.5-ppos.z)/pvect.z
|
||||
local x_int=ppos.x+t*pvect.x
|
||||
local y_int=ppos.y+t*pvect.y
|
||||
if x_int>-0.4 and x_int<0.4 and y_int>-0.4 and y_int<0.4 then return 6 end
|
||||
if x_int>-0.45 and x_int<0.45 and y_int>-0.45 and y_int<0.45 then return 6 end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -74,14 +78,14 @@ local function table_empty(table)
|
|||
end
|
||||
|
||||
local function add_table(table,toadd)
|
||||
local i=1
|
||||
local i = 1
|
||||
while true do
|
||||
o=table[i]
|
||||
if o==toadd then return end
|
||||
if o==nil then break end
|
||||
i=i+1
|
||||
o = table[i]
|
||||
if o == toadd then return end
|
||||
if o == nil then break end
|
||||
i = i+1
|
||||
end
|
||||
table[i]=toadd
|
||||
table[i] = toadd
|
||||
end
|
||||
|
||||
local function move_nodes_vect(poslist,vect,must_not_move,owner)
|
||||
|
@ -95,50 +99,55 @@ local function move_nodes_vect(poslist,vect,must_not_move,owner)
|
|||
end
|
||||
for _,pos in ipairs(poslist) do
|
||||
local npos=vector.add(pos,vect)
|
||||
local name = minetest.env:get_node(npos).name
|
||||
if (name~="air" and minetest.registered_nodes[name].liquidtype=="none") and not(pos_in_list(poslist,npos)) then
|
||||
local name = minetest.get_node(npos).name
|
||||
if ((name~="air" and minetest.registered_nodes[name].liquidtype=="none") or frames_pos[pos_to_string(npos)]) and not(pos_in_list(poslist,npos)) then
|
||||
return
|
||||
end
|
||||
--[[if pos.x==must_not_move.x and pos.y==must_not_move.y and pos.z==must_not_move.z then
|
||||
return
|
||||
end]]
|
||||
end
|
||||
nodelist={}
|
||||
for _,pos in ipairs(poslist) do
|
||||
local node=minetest.env:get_node(pos)
|
||||
local meta=minetest.env:get_meta(pos):to_table()
|
||||
nodelist[#(nodelist)+1]={pos=pos,node=node,meta=meta}
|
||||
local nodelist = {}
|
||||
for _, pos in ipairs(poslist) do
|
||||
local node = minetest.get_node(pos)
|
||||
local meta = minetest.get_meta(pos):to_table()
|
||||
nodelist[#(nodelist)+1] = {oldpos = pos, pos = vector.add(pos, vect), node = node, meta = meta}
|
||||
end
|
||||
objects={}
|
||||
for _,pos in ipairs(poslist) do
|
||||
for _,object in ipairs(minetest.env:get_objects_inside_radius(pos, 1)) do
|
||||
add_table(objects,object)
|
||||
local objects = {}
|
||||
for _, pos in ipairs(poslist) do
|
||||
for _,object in ipairs(minetest.get_objects_inside_radius(pos, 1)) do
|
||||
local entity = object:get_luaentity()
|
||||
if not entity or not mesecon:is_mvps_unmov(entity.name) then
|
||||
add_table(objects, object)
|
||||
end
|
||||
end
|
||||
end
|
||||
for _,obj in ipairs(objects) do
|
||||
obj:setpos(vector.add(obj:getpos(),vect))
|
||||
le=obj:get_luaentity()
|
||||
if le and le.name == "pipeworks:tubed_item" then
|
||||
le.start_pos=vector.add(le.start_pos,vect)
|
||||
end
|
||||
for _, obj in ipairs(objects) do
|
||||
obj:setpos(vector.add(obj:getpos(), vect))
|
||||
end
|
||||
for _,n in ipairs(nodelist) do
|
||||
local npos=vector.add(n.pos,vect)
|
||||
minetest.env:set_node(npos,n.node)
|
||||
local meta=minetest.env:get_meta(npos)
|
||||
local npos = n.pos
|
||||
minetest.set_node(npos, n.node)
|
||||
local meta = minetest.get_meta(npos)
|
||||
meta:from_table(n.meta)
|
||||
for __,pos in ipairs(poslist) do
|
||||
if npos.x==pos.x and npos.y==pos.y and npos.z==pos.z then
|
||||
if npos.x == pos.x and npos.y == pos.y and npos.z == pos.z then
|
||||
table.remove(poslist, __)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
for __,pos in ipairs(poslist) do
|
||||
minetest.env:remove_node(pos)
|
||||
for __, pos in ipairs(poslist) do
|
||||
minetest.remove_node(pos)
|
||||
end
|
||||
for _, callback in ipairs(mesecon.on_mvps_move) do
|
||||
callback(nodelist)
|
||||
end
|
||||
end
|
||||
|
||||
local function is_supported_node(name)
|
||||
return ((string.find(name, "tube") ~= nil) and (string.find(name, "pipeworks") ~= nil))
|
||||
end
|
||||
|
||||
|
||||
-- Frames
|
||||
|
@ -210,8 +219,8 @@ local nodeboxes= {
|
|||
paramtype = "light",
|
||||
frame=1,
|
||||
drop="technic:frame_111111",
|
||||
frame_connect_all=function(pos)
|
||||
local nodename=minetest.env:get_node(pos).name
|
||||
sunlight_propagates = true,
|
||||
frame_connect_all=function(nodename)
|
||||
l2={}
|
||||
l1={{x=-1,y=0,z=0},{x=1,y=0,z=0},{x=0,y=-1,z=0},{x=0,y=1,z=0},{x=0,y=0,z=-1},{x=0,y=0,z=1}}
|
||||
for i,dir in ipairs(l1) do
|
||||
|
@ -234,8 +243,84 @@ local nodeboxes= {
|
|||
nodename=string.sub(nodename,1,-2)..newstate
|
||||
end
|
||||
node.name=nodename
|
||||
minetest.env:set_node(pos,node)
|
||||
end
|
||||
minetest.set_node(pos,node)
|
||||
end,
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
local pos = pointed_thing.above
|
||||
if minetest.is_protected(pos, placer:get_player_name()) then
|
||||
minetest.log("action", placer:get_player_name()
|
||||
.. " tried to place " .. itemstack:get_name()
|
||||
.. " at protected position "
|
||||
.. minetest.pos_to_string(pos))
|
||||
minetest.record_protection_violation(pos, placer:get_player_name())
|
||||
return itemstack
|
||||
end
|
||||
if pos == nil then return end
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name ~= "air" then
|
||||
if is_supported_node(node.name) then
|
||||
obj = minetest.add_entity(pos, "technic:frame_entity")
|
||||
obj:get_luaentity():set_node({name=itemstack:get_name()})
|
||||
end
|
||||
else
|
||||
minetest.set_node(pos, {name = itemstack:get_name()})
|
||||
end
|
||||
if not infinite_stacks then
|
||||
itemstack:take_item()
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
on_rightclick = function(pos, node, placer, itemstack, pointed_thing)
|
||||
if is_supported_node(itemstack:get_name()) then
|
||||
if minetest.is_protected(pos, placer:get_player_name()) then
|
||||
minetest.log("action", placer:get_player_name()
|
||||
.. " tried to place " .. itemstack:get_name()
|
||||
.. " at protected position "
|
||||
.. minetest.pos_to_string(pos))
|
||||
minetest.record_protection_violation(pos, placer:get_player_name())
|
||||
return itemstack
|
||||
end
|
||||
|
||||
minetest.set_node(pos, {name = itemstack:get_name()})
|
||||
|
||||
local take_item = true
|
||||
local def = minetest.registered_items[itemstack:get_name()]
|
||||
-- Run callback
|
||||
if def.after_place_node then
|
||||
-- Copy place_to because callback can modify it
|
||||
local pos_copy = {x=pos.x, y=pos.y, z=pos.z}
|
||||
if def.after_place_node(pos_copy, placer, itemstack) then
|
||||
take_item = false
|
||||
end
|
||||
end
|
||||
|
||||
-- Run script hook
|
||||
local _, callback
|
||||
for _, callback in ipairs(minetest.registered_on_placenodes) do
|
||||
-- Copy pos and node because callback can modify them
|
||||
local pos_copy = {x=pos.x, y=pos.y, z=pos.z}
|
||||
local newnode_copy = {name=def.name, param1=0, param2=0}
|
||||
local oldnode_copy = {name="air", param1=0, param2=0}
|
||||
if callback(pos_copy, 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
|
||||
else
|
||||
--local pointed_thing = {type = "node", under = pos}
|
||||
if pointed_thing then
|
||||
minetest.item_place_node(itemstack, placer, pointed_thing)
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
end
|
||||
|
@ -245,20 +330,190 @@ end
|
|||
end
|
||||
end
|
||||
|
||||
minetest.register_entity("technic:frame_entity", {
|
||||
initial_properties = {
|
||||
physical = true,
|
||||
collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
|
||||
visual = "wielditem",
|
||||
textures = {},
|
||||
visual_size = {x=0.667, y=0.667},
|
||||
},
|
||||
|
||||
node = {},
|
||||
|
||||
set_node = function(self, node)
|
||||
self.node = node
|
||||
local pos = self.object:getpos()
|
||||
pos = {x = math.floor(pos.x+0.5), y = math.floor(pos.y+0.5), z = math.floor(pos.z+0.5)}
|
||||
frames_pos[pos_to_string(pos)] = node.name
|
||||
local stack = ItemStack(node.name)
|
||||
local itemtable = stack:to_table()
|
||||
local itemname = nil
|
||||
if itemtable then
|
||||
itemname = stack:to_table().name
|
||||
end
|
||||
local item_texture = nil
|
||||
local item_type = ""
|
||||
if minetest.registered_items[itemname] then
|
||||
item_texture = minetest.registered_items[itemname].inventory_image
|
||||
item_type = minetest.registered_items[itemname].type
|
||||
end
|
||||
prop = {
|
||||
is_visible = true,
|
||||
textures = {node.name},
|
||||
}
|
||||
self.object:set_properties(prop)
|
||||
end,
|
||||
|
||||
get_staticdata = function(self)
|
||||
return self.node.name
|
||||
end,
|
||||
|
||||
on_activate = function(self, staticdata)
|
||||
self.object:set_armor_groups({immortal=1})
|
||||
self:set_node({name=staticdata})
|
||||
end,
|
||||
|
||||
dig = function(self)
|
||||
minetest.handle_node_drops(self.object:getpos(), {ItemStack("technic:frame_111111")}, self.last_puncher)
|
||||
local pos = self.object:getpos()
|
||||
pos = {x = math.floor(pos.x+0.5), y = math.floor(pos.y+0.5), z = math.floor(pos.z+0.5)}
|
||||
frames_pos[pos_to_string(pos)] = nil
|
||||
self.object:remove()
|
||||
end,
|
||||
|
||||
on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
|
||||
local pos = self.object:getpos()
|
||||
if self.damage_object == nil then
|
||||
self.damage_object = minetest.add_entity(pos, "technic:damage_entity")
|
||||
self.damage_object:get_luaentity().remaining_time = 0.25
|
||||
self.damage_object:get_luaentity().frame_object = self
|
||||
self.damage_object:get_luaentity().texture_index = 0
|
||||
self.damage_object:get_luaentity().texture_change_time = 0.15
|
||||
else
|
||||
self.damage_object:get_luaentity().remaining_time = 0.25
|
||||
end
|
||||
self.last_puncher = puncher
|
||||
local ppos = puncher:getpos()
|
||||
local pvect = puncher:get_look_dir()
|
||||
local pface = get_face(pos,ppos,pvect)
|
||||
if pface == nil then return end
|
||||
local nodename = self.node.name
|
||||
local newstate = tostring(1-tonumber(string.sub(nodename, -7+pface, -7+pface)))
|
||||
if pface <= 5 then
|
||||
nodename = string.sub(nodename, 1, -7+pface-1)..newstate..string.sub(nodename, -7+pface+1)
|
||||
else
|
||||
nodename = string.sub(nodename, 1, -2)..newstate
|
||||
end
|
||||
self.node.name = nodename
|
||||
self:set_node(self.node)
|
||||
end,
|
||||
|
||||
on_rightclick = function(self, clicker)
|
||||
local pos = self.object:getpos()
|
||||
local ppos = clicker:getpos()
|
||||
local pvect = clicker:get_look_dir()
|
||||
local pface = get_face(pos, ppos, pvect)
|
||||
if pface == nil then return end
|
||||
local pos_under = {x = math.floor(pos.x+0.5), y = math.floor(pos.y+0.5), z = math.floor(pos.z+0.5)}
|
||||
local pos_above = {x = pos_under.x, y = pos_under.y, z = pos_under.z}
|
||||
local index = ({"x", "y", "z"})[math.floor((pface+1)/2)]
|
||||
pos_above[index] = pos_above[index] + 2*((pface+1)%2) - 1
|
||||
local pointed_thing = {type = "node", under = pos_under, above = pos_above}
|
||||
local itemstack = clicker:get_wielded_item()
|
||||
local itemdef = minetest.registered_items[itemstack:get_name()]
|
||||
if itemdef ~= nil then
|
||||
itemdef.on_place(itemstack, clicker, pointed_thing)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
local crack = "crack_anylength.png^[verticalframe:5:0"
|
||||
minetest.register_entity("technic:damage_entity", {
|
||||
initial_properties = {
|
||||
visual = "cube",
|
||||
visual_size = {x=1.01, y=1.01},
|
||||
textures = {crack, crack, crack, crack, crack, crack},
|
||||
collisionbox = {0, 0, 0, 0, 0, 0},
|
||||
physical = false,
|
||||
},
|
||||
on_step = function(self, dtime)
|
||||
if self.remaining_time == nil then
|
||||
self.object:remove()
|
||||
self.frame_object.damage_object = nil
|
||||
end
|
||||
self.remaining_time = self.remaining_time - dtime
|
||||
if self.remaining_time < 0 then
|
||||
self.object:remove()
|
||||
self.frame_object.damage_object = nil
|
||||
end
|
||||
self.texture_change_time = self.texture_change_time - dtime
|
||||
if self.texture_change_time < 0 then
|
||||
self.texture_change_time = self.texture_change_time + 0.15
|
||||
self.texture_index = self.texture_index + 1
|
||||
if self.texture_index == 5 then
|
||||
self.object:remove()
|
||||
self.frame_object.damage_object = nil
|
||||
self.frame_object:dig()
|
||||
end
|
||||
local ct = "crack_anylength.png^[verticalframe:5:"..self.texture_index
|
||||
self.object:set_properties({textures = {ct, ct, ct, ct, ct, ct}})
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
mesecon:register_mvps_unmov("technic:frame_entity")
|
||||
mesecon:register_mvps_unmov("technic:damage_entity")
|
||||
mesecon:register_on_mvps_move(function(moved_nodes)
|
||||
local to_move = {}
|
||||
for _, n in ipairs(moved_nodes) do
|
||||
if frames_pos[pos_to_string(n.oldpos)] ~= nil then
|
||||
to_move[#to_move+1] = {pos = n.pos, oldpos = n.oldpos, name = frames_pos[pos_to_string(n.oldpos)]}
|
||||
frames_pos[pos_to_string(n.oldpos)] = nil
|
||||
end
|
||||
end
|
||||
if #to_move > 0 then
|
||||
for _, t in ipairs(to_move) do
|
||||
frames_pos[pos_to_string(t.pos)] = t.name
|
||||
local objects = minetest.get_objects_inside_radius(t.oldpos, 0.1)
|
||||
for _, obj in ipairs(objects) do
|
||||
local entity = obj:get_luaentity()
|
||||
if entity and (entity.name == "technic:frame_entity" or entity.name == "technic:damage_entity") then
|
||||
obj:setpos(t.pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_dignode(function(pos, node)
|
||||
if frames_pos[pos_to_string(pos)] ~= nil then
|
||||
minetest.set_node(pos, {name = frames_pos[pos_to_string(pos)]})
|
||||
frames_pos[pos_to_string(pos)] = nil
|
||||
local objects = minetest.get_objects_inside_radius(pos, 0.1)
|
||||
for _, obj in ipairs(objects) do
|
||||
local entity = obj:get_luaentity()
|
||||
if entity and (entity.name == "technic:frame_entity" or entity.name == "technic:damage_entity") then
|
||||
obj:remove()
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Frame motor
|
||||
local function connected(pos,c,adj)
|
||||
for _,vect in ipairs(adj) do
|
||||
local pos1=vector.add(pos,vect)
|
||||
local nodename=minetest.env:get_node(pos1).name
|
||||
local nodename=minetest.get_node(pos1).name
|
||||
if frames_pos[pos_to_string(pos1)] then
|
||||
nodename = frames_pos[pos_to_string(pos1)]
|
||||
end
|
||||
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(pos1)
|
||||
local adj=minetest.registered_nodes[nodename].frame_connect_all(nodename)
|
||||
connected(pos1,c,adj)
|
||||
end
|
||||
end
|
||||
|
@ -267,8 +522,11 @@ end
|
|||
|
||||
local function get_connected_nodes(pos)
|
||||
c={pos}
|
||||
local nodename=minetest.env:get_node(pos).name
|
||||
connected(pos,c,minetest.registered_nodes[nodename].frame_connect_all(pos))
|
||||
local nodename=minetest.get_node(pos).name
|
||||
if frames_pos[pos_to_string(pos)] then
|
||||
nodename = frames_pos[pos_to_string(pos)]
|
||||
end
|
||||
connected(pos,c,minetest.registered_nodes[nodename].frame_connect_all(nodename))
|
||||
return c
|
||||
end
|
||||
|
||||
|
@ -277,6 +535,9 @@ local function frame_motor_on(pos, node)
|
|||
local nnodepos = vector.add(pos, dirs[math.floor(node.param2/4)+1])
|
||||
local dir = minetest.facedir_to_dir(node.param2)
|
||||
local nnode=minetest.get_node(nnodepos)
|
||||
if frames_pos[pos_to_string(nnodepos)] then
|
||||
nnode.name = frames_pos[pos_to_string(nnodepos)]
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local owner = meta:get_string("owner")
|
||||
if minetest.registered_nodes[nnode.name].frame==1 then
|
||||
|
@ -565,7 +826,7 @@ local function get_template_nodes(pos)
|
|||
local c = {}
|
||||
for _,vect in ipairs(adj) do
|
||||
local pos1=vector.add(pos,vect)
|
||||
local nodename=minetest.env:get_node(pos1).name
|
||||
local nodename=minetest.get_node(pos1).name
|
||||
if not(pos_in_list(c,pos1)) and nodename~="air" then
|
||||
c[#(c)+1]=pos1
|
||||
end
|
||||
|
|
|
@ -3,4 +3,6 @@ local path = technic.modpath.."/machines/other"
|
|||
-- mesecons and tubes related
|
||||
dofile(path.."/injector.lua")
|
||||
dofile(path.."/constructor.lua")
|
||||
dofile(path.."/frames.lua")
|
||||
if minetest.get_modpath("mesecons_mvps") ~= nil then
|
||||
dofile(path.."/frames.lua")
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue
Block a user