Compare commits

...

14 Commits

Author SHA1 Message Date
loosewheel
6d4369ee91 Add files via upload 2022-01-07 18:55:19 +10:00
loosewheel
c7ec545ef7 Add files via upload 2022-01-07 18:53:39 +10:00
loosewheel
923faa59a3 Add files via upload 2022-01-07 18:50:47 +10:00
loosewheel
201c01131f Add files via upload 2022-01-07 18:49:57 +10:00
loosewheel
a0c9dd1d0c Add files via upload 2022-01-07 18:49:14 +10:00
loosewheel
c43dab66d7 Add files via upload 2021-12-06 21:15:05 +10:00
loosewheel
ca31c40d8b Add files via upload 2021-12-05 01:24:47 +10:00
loosewheel
2b61dfb872 Add files via upload 2021-11-29 11:29:56 +10:00
loosewheel
1459dc2029 Add files via upload 2021-11-29 11:27:33 +10:00
loosewheel
a3f6a4d203 Add files via upload 2021-11-29 11:25:24 +10:00
loosewheel
6c8a60c3f7 Add files via upload 2021-11-29 11:24:38 +10:00
loosewheel
be384872dd Add files via upload 2021-11-29 11:22:46 +10:00
loosewheel
ec08eebfd3 Add files via upload 2021-11-25 07:15:45 +10:00
loosewheel
cf8c44cb80 Add files via upload 2021-11-25 07:06:57 +10:00
45 changed files with 2785 additions and 97 deletions

View File

@@ -138,9 +138,9 @@ local function can_break_node (pos, breakpos)
if node_def then if node_def then
-- try tool first -- try tool first
local tool = get_tool (pos) local tool = get_tool (pos)
local dig_params = nil
if tool then if tool then
local dig_params = nil
local tool_def = minetest.registered_items[tool:get_name ()] local tool_def = minetest.registered_items[tool:get_name ()]
if tool_def then if tool_def then

View File

@@ -5,7 +5,7 @@ local S = utils.S
local cannon_force = 20 local cannon_force = 20
local min_pitch = -20 local min_pitch = -20
local max_pitch = 50 local max_pitch = 70
local min_rotation = -60 local min_rotation = -60
local max_rotation = 60 local max_rotation = 60
@@ -180,6 +180,25 @@ end
local function aim_barrel_delayed (pos, aimpos)
local x = tonumber (aimpos.x) or 0
local y = tonumber (aimpos.y) or 0
local z = tonumber (aimpos.z) or 0
if z < 1 then
return
end
local angle = vector.dir_to_rotation (aimpos)
local rot = math.floor (math.deg (-angle.y) + 0.5)
local pitch = math.floor (math.deg (angle.x) + 0.5)
set_barrel_angle_delayed (pos, pitch, rot)
end
local function fire_cannon (pos) local function fire_cannon (pos)
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
@@ -279,6 +298,7 @@ local function process_controller_input (pos, input)
local pitch = input.pitch * -180 / math.pi local pitch = input.pitch * -180 / math.pi
local node_rot = vector.dir_to_rotation (minetest.facedir_to_dir ((node.param2 + 2) % 4)) local node_rot = vector.dir_to_rotation (minetest.facedir_to_dir ((node.param2 + 2) % 4))
local rot = (input.yaw - node_rot.y) * 180 / math.pi local rot = (input.yaw - node_rot.y) * 180 / math.pi
local sensitivity = (meta:get_string ("sensitive") == "true" and 3) or 1
while rot > 180 do while rot > 180 do
rot = rot - 360 rot = rot - 360
@@ -292,8 +312,8 @@ local function process_controller_input (pos, input)
rot = -rot rot = -rot
end end
set_barrel_pitch (pos, pitch * 3) set_barrel_pitch (pos, pitch * sensitivity)
set_barrel_rotation (pos, rot * 3) set_barrel_rotation (pos, rot * sensitivity)
if input.dig then if input.dig then
fire_cannon (pos) fire_cannon (pos)
@@ -304,15 +324,19 @@ end
local function get_formspec () local function get_formspec (pos)
local meta = minetest.get_meta (pos)
local sensitive = (meta and meta:get_string ("sensitive")) or "false"
return return
"formspec_version[3]\n".. "formspec_version[3]\n"..
"size[11.75,10.75;true]\n".. "size[11.75,10.75;true]\n"..
"field[1.0,1.0;4.0,0.8;channel;Channel;${channel}]\n".. "field[1.0,1.0;4.0,0.8;channel;Channel;${channel}]\n"..
"button[5.5,1.0;2.0,0.8;setchannel;Set]\n".. "button[5.5,1.0;2.0,0.8;setchannel;Set]\n"..
"button[8.5,1.0;2.0,0.8;hide;Hide]\n".. "button[8.5,1.0;2.0,0.8;hide;Hide]\n"..
"field[1.0,3.0;4.0,0.8;controller;Controller;${controller}]\n".. "field[1.0,2.6;4.0,0.8;controller;Controller;${controller}]\n"..
"button[5.5,3.0;2.0,0.8;setcontroller;Set]\n".. "button[5.5,2.6;2.0,0.8;setcontroller;Set]\n"..
"checkbox[1.3,3.8;sensitive;Sensitive;"..sensitive.."]\n"..
"list[context;main;9.0,2.75;1,1;]\n".. "list[context;main;9.0,2.75;1,1;]\n"..
"list[current_player;main;1.0,5.0;8,4;]\n".. "list[current_player;main;1.0,5.0;8,4;]\n"..
"listring[]" "listring[]"
@@ -346,6 +370,7 @@ local function on_construct (pos)
if barrel then if barrel then
set_barrel_rotation (pos, 0) set_barrel_rotation (pos, 0)
set_barrel_pitch (pos, 0) set_barrel_pitch (pos, 0)
barrel:set_armor_groups ({ immortal = 1 })
end end
minetest.set_node (blank_pos, { name = "lwcomponents:cannon_blank" }) minetest.set_node (blank_pos, { name = "lwcomponents:cannon_blank" })
@@ -373,14 +398,16 @@ end
local function after_place_node (pos, placer, itemstack, pointed_thing) local function after_place_node (pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
meta:set_string ("sensitive", "true")
meta:set_string ("inventory", "{ main = { } }") meta:set_string ("inventory", "{ main = { } }")
meta:set_string ("formspec", get_formspec ())
local inv = meta:get_inventory () local inv = meta:get_inventory ()
inv:set_size ("main", 1) inv:set_size ("main", 1)
inv:set_width ("main", 1) inv:set_width ("main", 1)
meta:set_string ("formspec", get_formspec (pos))
-- If return true no item is taken from itemstack -- If return true no item is taken from itemstack
return false return false
end end
@@ -523,6 +550,15 @@ local function on_receive_fields (pos, formname, fields, sender)
meta:set_string ("formspec", "") meta:set_string ("formspec", "")
end end
end end
if fields.sensitive ~= nil then
local meta = minetest.get_meta (pos)
if meta then
meta:set_string ("sensitive", fields.sensitive)
meta:set_string ("formspec", get_formspec (pos))
end
end
end end
@@ -641,29 +677,26 @@ local function on_rightclick (pos, node, clicker, itemstack, pointed_thing)
if hz == 0.5 and hy >= -0.5 and hy <= 0.2 then if hz == 0.5 and hy >= -0.5 and hy <= 0.2 then
local angle = get_barrel_angle (pos) local angle = get_barrel_angle (pos)
if hx >= -0.5 and hx <= -0.25 and hy >= -0.25 and hy <= -0.0625 then if angle then
-- left if hx >= -0.5 and hx <= -0.25 and hy >= -0.25 and hy <= -0.0625 then
set_barrel_rotation (pos, angle.y + inc) -- left
set_barrel_rotation (pos, angle.y + inc)
elseif hx >= 0.25 and hx <= 0.5 and hy >= -0.25 and hy <= -0.0625 then elseif hx >= 0.25 and hx <= 0.5 and hy >= -0.25 and hy <= -0.0625 then
-- right -- right
set_barrel_rotation (pos, angle.y - inc) set_barrel_rotation (pos, angle.y - inc)
elseif hx >= -0.125 and hx <= 0.125 and hy >= 0.0 and hy <= 0.1875 then
elseif hx >= -0.125 and hx <= 0.125 and hy >= 0.0 and hy <= 0.1875 then -- up
-- up set_barrel_pitch (pos, angle.x + inc)
set_barrel_pitch (pos, angle.x + inc) elseif hx >= -0.125 and hx <= 0.125 and hy >= -0.5 and hy <= -0.3125 then
-- down
elseif hx >= -0.125 and hx <= 0.125 and hy >= -0.5 and hy <= -0.3125 then set_barrel_pitch (pos, angle.x - inc)
-- down elseif hx >= -0.125 and hx <= 0.125 and hy >= -0.25 and hy <= -0.0625 then
set_barrel_pitch (pos, angle.x - inc) -- fire
fire_cannon (pos)
elseif hx >= -0.125 and hx <= 0.125 and hy >= -0.25 and hy <= -0.0625 then end
-- fire
fire_cannon (pos)
end end
else else
meta:set_string ("formspec", get_formspec ()) meta:set_string ("formspec", get_formspec (pos))
end end
end end
end end
@@ -764,6 +797,12 @@ local function digilines_support ()
msg.pitch and msg.yaw and msg.name and msg.look_vector then msg.pitch and msg.yaw and msg.name and msg.look_vector then
process_controller_input (pos, msg) process_controller_input (pos, msg)
elseif type (msg.action) == "string" and msg.action == "aim" and
type (msg.aim) == "table" then
aim_barrel_delayed (pos, msg.aim)
end end
end end
@@ -814,6 +853,8 @@ minetest.register_node("lwcomponents:cannon_blank", {
drop = "", drop = "",
groups = { not_in_creative_inventory = 1 }, groups = { not_in_creative_inventory = 1 },
paramtype = "light", paramtype = "light",
-- unaffected by explosions
on_blast = function() end,
}) })
@@ -833,6 +874,8 @@ minetest.register_node("lwcomponents:cannon_blank_fire", {
drop = "", drop = "",
groups = { not_in_creative_inventory = 1 }, groups = { not_in_creative_inventory = 1 },
paramtype = "light", paramtype = "light",
-- unaffected by explosions
on_blast = function() end,
}) })
@@ -852,7 +895,7 @@ minetest.register_node("lwcomponents:cannon", {
type = "fixed", type = "fixed",
fixed = { fixed = {
{ -0.09, 0, -0.09, 0.09, 0.5, 0.09 }, { -0.09, 0, -0.09, 0.09, 0.5, 0.09 },
{ -0.5, -0.1875, -0.5, 0.5, 0.125, 0.5 }, { -0.5, -0.25, -0.5, 0.5, 0.125, 0.5 },
{ -0.4375, -0.1875, -0.4375, 0.4375, 0.1875, 0.5 }, { -0.4375, -0.1875, -0.4375, 0.4375, 0.1875, 0.5 },
{ -0.5, -0.5, 0.3125, 0.5, 0.125, 0.5 }, { -0.5, -0.5, 0.3125, 0.5, 0.125, 0.5 },
{ -0.5, -0.5, -0.5, -0.3125, 0.125, -0.3125 }, { -0.5, -0.5, -0.5, -0.3125, 0.125, -0.3125 },
@@ -914,7 +957,7 @@ minetest.register_node("lwcomponents:cannon_locked", {
type = "fixed", type = "fixed",
fixed = { fixed = {
{ -0.09, 0, -0.09, 0.09, 0.5, 0.09 }, { -0.09, 0, -0.09, 0.09, 0.5, 0.09 },
{ -0.5, -0.1875, -0.5, 0.5, 0.125, 0.5 }, { -0.5, -0.25, -0.5, 0.5, 0.125, 0.5 },
{ -0.4375, -0.1875, -0.4375, 0.4375, 0.1875, 0.5 }, { -0.4375, -0.1875, -0.4375, 0.4375, 0.1875, 0.5 },
{ -0.5, -0.5, 0.3125, 0.5, 0.125, 0.5 }, { -0.5, -0.5, 0.3125, 0.5, 0.125, 0.5 },
{ -0.5, -0.5, -0.5, -0.3125, 0.125, -0.3125 }, { -0.5, -0.5, -0.5, -0.3125, 0.125, -0.3125 },
@@ -998,6 +1041,10 @@ minetest.register_entity ("lwcomponents:cannon_barrel", {
on_punch = function (self, puncher, time_from_last_punch, tool_capabilities, dir) on_punch = function (self, puncher, time_from_last_punch, tool_capabilities, dir)
return true return true
end, end,
on_blast = function (self, damage)
return false, false, nil
end,
}) })

293
cannon_shell.lua Normal file
View File

@@ -0,0 +1,293 @@
local utils = ...
local S = utils.S
--[[
on_step info
info.touching_ground = bool
info.standing_on_object = bool
info.collides = bool
info.collisions[n].type = "node"
info.collisions[n].node_pos = vector
info.collisions[n].old_velocity = vector
info.collisions[n].now_velocity = vector
info.collisions[n].axis = "x" | "y" | "z" - axis hit
or
info.collisions[n].type = "object"
info.collisions[n].object = userdata
info.collisions[n].old_velocity = vector
info.collisions[n].now_velocity = vector
info.collisions[n].axis = "x" | "y" | "z" - axis hit
]]
local function get_adjacent_node (collision_info, spawn_pos)
if vector.equals (collision_info.node_pos, spawn_pos) then
return collision_info.node_pos
end
local adj = { x = 0, y = 0, z = 0 }
if collision_info.axis == "x" then
adj.x = (collision_info.old_velocity.x > 0 and -1) or 1
elseif collision_info.axis == "y" then
adj.y = (collision_info.old_velocity.y > 0 and -1) or 1
elseif collision_info.axis == "z" then
adj.z = (collision_info.old_velocity.z > 0 and -1) or 1
end
local pos = vector.new (collision_info.node_pos)
local node = utils.get_far_node (pos)
local def = minetest.registered_nodes[node and node.name or nil]
while (node and node.name ~= "air") and (def and not def.buildable_to) do
local next_pos = vector.add (pos, adj)
if vector.equals (next_pos, spawn_pos) then
return pos
end
pos = next_pos
node = utils.get_far_node (pos)
def = minetest.registered_nodes[node and node.name or nil]
end
return pos
end
local function register_shell (name, description, texture, inventory_image,
stack_max, shell_speed, explode_func)
minetest.register_entity (name.."_entity", {
initial_properties = {
physical = true,
collide_with_objects = true,
collisionbox = { -0.25, -0.125, -0.25, 0.25, 0.125, 0.25 },
pointable = false,
visual_size = { x = 0.7, y = 0.7, z = 0.7 },
visual = "mesh",
mesh = "lwcomponents_shell.obj",
textures = { texture },
use_texture_alpha = false,
is_visible = true,
makes_footstep_sound = false,
automatic_face_movement_dir = false,
automatic_face_movement_max_rotation_per_sec = false,
automatic_rotate = 0,
backface_culling = true,
damage_texture_modifier = "",
glow = 0,
static_save = false,
shaded = true,
show_on_minimap = false,
},
on_activate = function (self, staticdata, dtime_s)
if not self.spawn_pos then
self.spawn_pos = vector.new (self.object:get_pos ())
end
if not self.time_lived then
self.time_lived = 0
end
if not self.shell_speed then
self.shell_speed = shell_speed
end
self.staticdata = staticdata
end,
get_staticdata = function (self)
return self.staticdata
end,
on_step = function (self, dtime, info)
local explode_pos = nil
self.object:set_rotation (vector.dir_to_rotation (self.object:get_velocity ()))
if self.time_lived then
self.time_lived = self.time_lived + dtime
if self.time_lived > self.shell_speed then
self.object:remove ()
return
end
end
if info.collides then
--For each collision that was found in reverse order
for i = #info.collisions, 1, -1 do
local c = info.collisions[i]
if c.type == "node" then
local node = utils.get_far_node (c.node_pos)
if node and node.name ~= "air" then
local def = minetest.registered_nodes[node.name]
if def and def.walkable then
-- adjacent for explosion
explode_pos = get_adjacent_node (c, self.spawn_pos)
--minetest.log ("action", "Shell on node "..node.name.." at "..minetest.pos_to_string (explode_pos)..
--" node at "..minetest.pos_to_string (c.node_pos))
break
end
end
if not explode_pos then
self.object:set_velocity (c.old_velocity)
end
elseif c.type == "object" then
-- explode at this pos
if c.object:get_armor_groups ().immortal then
self.object:set_velocity (c.old_velocity)
else
explode_pos = vector.new (c.object:get_pos ())
--minetest.log ("action", "Shell on entity "..c.object:get_luaentity ().name.." at "..minetest.pos_to_string (explode_pos))
break
end
end
end
end
if explode_pos then
self.object:remove ()
explode_func (explode_pos)
end
end,
on_punch = function (self, puncher, time_from_last_punch, tool_capabilities, dir)
return true
end,
})
minetest.register_craftitem (name, {
description = description,
short_description = description,
groups = { },
inventory_image = inventory_image,
wield_image = inventory_image,
stack_max = stack_max,
})
lwcomponents.register_spawner (name,
function (spawn_pos, itemstack, owner, spawner_pos, spawner_dir, force)
if not itemstack:is_empty() then
local def = minetest.registered_entities[name.."_entity"]
if def then
local obj = minetest.add_entity (spawn_pos, name.."_entity")
if obj then
obj:set_armor_groups ({ immortal = 1 })
obj:set_acceleration ({ x = 0, y = -9.81, z = 0 })
obj:set_rotation (vector.dir_to_rotation (vector.multiply (spawner_dir, shell_speed)))
obj:set_velocity (vector.multiply (spawner_dir, shell_speed))
local luaent = obj:get_luaentity ()
if luaent then
luaent.spawn_pos = { x = spawn_pos.x, y = spawn_pos.y, z = spawn_pos.z }
luaent.time_lived = 0
luaent.shell_speed = shell_speed
end
return obj, false
end
end
end
return nil, false
end)
end
register_shell ("lwcomponents:cannon_shell",
S("Shell"),
"lwcannon_shell.png",
"lwcannon_shell_item.png",
99,
25,
function (pos)
utils.boom (pos,
2, -- node_radius
70, -- node_chance in 100
2, -- fire_radius
5, -- fire_chance in 100
4, -- entity_radius
20, -- entity_damage
false, -- disable_drops
nil, -- node_filter
false, -- burn_all
nil) -- sound
end)
register_shell ("lwcomponents:cannon_soft_shell",
S("Soft Shell"),
"lwcannon_soft_shell.png",
"lwcannon_soft_shell_item.png",
99,
25,
function (pos)
utils.boom (pos,
2, -- node_radius
50, -- node_chance in 100
2, -- fire_radius
5, -- fire_chance in 100
4, -- entity_radius
20, -- entity_damage
false, -- disable_drops
{
buildable_to = true,
buildable_to_undefined = false,
}, -- node_filter
false, -- burn_all
nil) -- sound
end)
if minetest.global_exists ("fire") then
register_shell ("lwcomponents:cannon_fire_shell",
S("Fire Shell"),
"lwcannon_fire_shell.png",
"lwcannon_fire_shell_item.png",
99,
25,
function (pos)
utils.boom (pos,
2, -- node_radius
0, -- node_chance in 100
2, -- fire_radius
70, -- fire_chance in 100
4, -- entity_radius
20, -- entity_damage
false, -- disable_drops
nil, -- node_filter
true, -- burn_all
nil) -- sound
end)
end
--

View File

@@ -62,3 +62,28 @@ v0.1.9
v0.1.10 v0.1.10
* Added cannons. * Added cannons.
v0.1.11
* Fix to breakers (?).
* Added position aiming to cannons.
v0.1.12
* Added sensitivity option for game controller in cannons.
* Added cannon shells.
* Fixed bug in utils.is_creative.
* Increased cannon pitch to -20 to 70.
v0.1.13
* Removed optional dependency lwdrops.
v0.1.14
* Calls on_drop when item is dropped.
v0.1.15
* Fixed bug call to clear_map in fan on_blast.
* Added pistons.

View File

@@ -23,6 +23,35 @@ minetest.register_craft( {
}) })
minetest.register_craft( {
output = "lwcomponents:cannon_shell 10",
recipe = {
{ "default:steel_ingot", "default:steel_ingot" },
{ "", "default:coalblock" },
},
})
minetest.register_craft( {
output = "lwcomponents:cannon_soft_shell 10",
recipe = {
{ "default:steel_ingot", "default:steel_ingot" },
{ "default:copper_lump", "default:coalblock" },
},
})
if minetest.global_exists ("fire") then
minetest.register_craft( {
output = "lwcomponents:cannon_fire_shell 10",
recipe = {
{ "default:steel_ingot", "default:steel_ingot" },
{ "default:iron_lump", "default:coalblock" },
},
})
end
if utils.digilines_supported or utils.mesecon_supported then if utils.digilines_supported or utils.mesecon_supported then
@@ -189,6 +218,26 @@ minetest.register_craft( {
}, },
}) })
minetest.register_craft({
output = "lwcomponents:piston 2",
recipe = {
{ "group:wood", "group:wood", "group:wood" },
{ "default:cobble", "default:steel_ingot", "default:cobble" },
{ "default:stone", "default:copper_ingot", "default:stone" },
}
})
minetest.register_craft({
output = "lwcomponents:piston_sticky",
recipe = {
{"group:sapling"},
{"lwcomponents:piston"},
}
})
end -- utils.digilines_supported or utils.mesecon_supported end -- utils.digilines_supported or utils.mesecon_supported

View File

@@ -1,5 +1,4 @@
default default
lwdrops?
mesecons? mesecons?
digilines? digilines?
unifieddyes? unifieddyes?

View File

@@ -73,7 +73,7 @@ end
local function place_node (itemname, pos) local function place_node (item, pos)
local node = minetest.get_node_or_nil ({ x = pos.x, y = pos.y - 1, z = pos.z }) local node = minetest.get_node_or_nil ({ x = pos.x, y = pos.y - 1, z = pos.z })
if not node then if not node then
@@ -100,8 +100,8 @@ local function place_node (itemname, pos)
end end
end end
local stack = ItemStack (itemname) local stack = ItemStack (item)
local itemdef = utils.find_item_def (itemname) local itemdef = utils.find_item_def (stack:get_name ())
if stack and itemdef then if stack and itemdef then
local placed = false local placed = false
@@ -122,23 +122,23 @@ local function place_node (itemname, pos)
end end
if itemdef and itemdef.on_place then if itemdef and itemdef.on_place then
local result, msg = pcall (itemdef.on_place, stack, nil, pointed_thing) local result, leftover = pcall (itemdef.on_place, stack, nil, pointed_thing)
placed = result placed = result
if not placed then if not placed then
if utils.settings.alert_handler_errors then if utils.settings.alert_handler_errors then
minetest.log ("error", "on_place handler for "..itemname.." crashed - "..msg) minetest.log ("error", "on_place handler for "..stack:get_name ().." crashed - "..leftover)
end end
end end
end end
if not placed then if not placed then
if not minetest.registered_nodes[itemname] then if not minetest.registered_nodes[stack:get_name ()] then
return false return false
end end
minetest.set_node (pos, { name = itemname, param1 = 0, param2 = 0 }) minetest.set_node (pos, { name = stack:get_name (), param1 = 0, param2 = 0 })
if itemdef and itemdef.after_place_node then if itemdef and itemdef.after_place_node then
local result, msg = pcall (itemdef.after_place_node, pos, nil, stack, pointed_thing) local result, msg = pcall (itemdef.after_place_node, pos, nil, stack, pointed_thing)
@@ -154,9 +154,11 @@ local function place_node (itemname, pos)
pcall (minetest.sound_play, itemdef.sounds.place, { pos = pos }) pcall (minetest.sound_play, itemdef.sounds.place, { pos = pos })
end end
end end
return true
end end
return true return false
end end
@@ -219,7 +221,7 @@ local function deploy_item (pos, node, slot, range)
local deploypos = get_deploy_pos (pos, node.param2, range) local deploypos = get_deploy_pos (pos, node.param2, range)
if item and deploypos then if item and deploypos then
if place_node (name, deploypos) then if place_node (stack, deploypos) then
stack:set_count (stack:get_count () - 1) stack:set_count (stack:get_count () - 1)
inv:set_stack ("main", slot, stack) inv:set_stack ("main", slot, stack)

View File

@@ -9,7 +9,7 @@ release them from the bottom.
Cannon rotation range: Cannon rotation range:
side to side - +/-60 degrees (- = left, + = right) side to side - +/-60 degrees (- = left, + = right)
down to up: -20 to 50 degrees (- = down, + = up) down to up: -20 to 70 degrees (- = down, + = up)
To spawn entities from cannons include the lwcomponents_spawners mod. To spawn entities from cannons include the lwcomponents_spawners mod.
@@ -21,6 +21,7 @@ Channel - digilines channel of cannon.
Hide - hides the form so the cannon can be used manually, double right click Hide - hides the form so the cannon can be used manually, double right click
any other face besides the rear to bring up the form. any other face besides the rear to bring up the form.
Controller - digistuff game controller digilines channel. Controller - digistuff game controller digilines channel.
Sensitive - if checked game controller movements have a x3 sensitivity.
Top 1 slot inventory - storage of items to shoot. Top 1 slot inventory - storage of items to shoot.
Bottom 32 slot inventory - player's inventory. Bottom 32 slot inventory - player's inventory.
@@ -35,11 +36,11 @@ Digistuff game controller
Connect a game controller to the cannon with digilines cable. Enter the Connect a game controller to the cannon with digilines cable. Enter the
game controller's channel in the Controller field of the cannon's form game controller's channel in the Controller field of the cannon's form
(click Set). Your turning movements turn the cannon's barrel in the (click Set). Your turning movements turn the cannon's barrel in the
direction the cannon is facing. The movements have an increased sensitivity direction the cannon is facing. If Sensitive is checked the movements
(x3) to try and keep the target in your view. Punching shoots an item. have an increased sensitivity (x3) to try and keep the target in your view,
The game controller updates every 0.2 seconds, so a quick punch may not otherwise x1. Punching shoots an item. The game controller updates every
register. A locked cannon can only be controlled by it's owner with a game 0.2 seconds, so a quick punch may not register. A locked cannon can only
controller. be controlled by it's owner with a game controller.
Mesecons Mesecons
Shoots an item when power is turned on. Shoots an item when power is turned on.
@@ -47,7 +48,7 @@ Mesecons
Digilines messages Digilines messages
"pitch <n>" "pitch <n>"
Sets the pitch of the barrel. n should be between -20 to 50, and will Sets the pitch of the barrel. n should be between -20 to 70, and will
be clipped to this range. be clipped to this range.
eg. "pitch 22" eg. "pitch 22"
@@ -56,8 +57,47 @@ Digilines messages
be clipped to this range. be clipped to this range.
eg. "rotation 45" eg. "rotation 45"
table - aim position
{
action = "aim",
aim = { x, y, z }
}
x is the horizontal left (negative) to right. 0 is straight ahead.
y is the vertical down (negative) to up. 0 is straight ahead.
z is the depth. Must be > 0 or ignored. 1 is the position directly in
front of the cannon.
* The cannon barrel's height is 0.65 above the cannon's placed position.
When aiming for height, if the cannon's base height is taken as -0.5,
and consider height from there. This allows for the barrel height
and a little drop in the projectile at close range.
"fire" "fire"
Shoots an item. Shoots an item.
* Note: turning the barrel is animated and takes 0.1 seconds per 10 * Note: turning the barrel is animated and takes 0.1 seconds per 10
degrees of movement. A fire command while moving is ignored. degrees of movement. A fire command while moving is ignored.
Three shells are provided for cannons.
Shell
This shell has a 70% chance of destroying a node within a radius of 2 from
the impact, a 5% chance a flammable node will be set on fire within a
radius of 2 (if fire is installed), and damages players and entities within
a radius of 4 with a maximum of 20 damage points.
Soft Shell
This shell has a 50% chance of destroying only soft (buildable_to) nodes,
such as grass, within a radius of 2 from the impact, a 5% chance a flammable
node will be set on fire within a radius of 2 (if fire is installed), and
damages players and entities within a radius of 4 with a maximum of 20
damage points.
Fire Shell
* This item is only available if fire is installed.
This shell does not destroying nodes, has a 70% chance of setting a node
on fire, whether its flammable or not within a radius of 2, and damages
players and entities within a radius of 4 with a maximum of 20 damage
points.

31
docs/pistons.txt Normal file
View File

@@ -0,0 +1,31 @@
Pistons and sticky pistons
--------------------------
* These blocks are only available if digilines and/or mesecons are loaded.
Pistons push up to the setting Maximum piston nodes (default 15) in front
of the pusher when extended. Sticky piston draw back a single node in
front of the pusher when retracted. Piston also act as a digilines
conductor.
UI
Channel - digilines channel of piston.
Single move - pusher extends 1 node if checked, otherwise 2 nodes.
Mesecons
Piston extends while power is turned on.
Digilines messages
"extend n"
Extends the piston pusher to extent n (0, 1 or 2). If n is not given
pusher extends to maximum extent. 0 is retracted.
"retract"
Same as 'extend 0'.
"single"
Sets piston to single move mode.
"double"
Sets piston to double move mode.

512
explode.lua Normal file
View File

@@ -0,0 +1,512 @@
local utils = ...
local S = utils.S
local explode = { }
if minetest.global_exists ("fire") then
explode.fire_supported = true
function explode.set_fire (pos, burn_all)
local node = utils.get_far_node (pos)
if not node then
return
end
if node.name ~= "air" then
local def = minetest.registered_nodes[node.name]
if not def or not def.buildable_to then
return
end
end
local dirs =
{
{ x = 0, y = -1, z = 0 },
{ x = -1, y = 0, z = 0 },
{ x = 0, y = 0, z = -1 },
{ x = 1, y = 0, z = 0 },
{ x = 0, y = 0, z = 1 }
}
for i = 1, #dirs do
node = utils.get_far_node (vector.add (pos, dirs[i]))
if node and node.name ~= "air" and node.name ~= "fire:basic_flame" then
local def = minetest.registered_nodes[node.name]
if def and def.liquidtype == "none" then
if (def.groups and def.groups.flammable) or burn_all then
minetest.set_node (pos, { name = "fire:basic_flame" })
return
end
end
end
end
end
else
explode.fire_supported = false
function explode.set_fire (pos, burn_all)
end
end
local function is_same_item (stack1, stack2)
local copy1 = ItemStack (stack1)
local copy2 = ItemStack (stack2)
if copy1 and copy2 then
copy1:set_count (1)
copy2:set_count (1)
if copy1:to_string () == copy2:to_string () then
return true
end
end
return false
end
local function dig_node (pos, toolname)
local node = utils.get_far_node (pos)
local dig = false
local drops = nil
if toolname == true then
dig = true
toolname = nil
end
if node and node.name ~= "air" then
local def = utils.find_item_def (node.name)
if not dig then
if def and def.can_dig then
local result, can_dig = pcall (def.can_dig, pos)
dig = ((not result) or (result and (can_dig == nil or can_dig == true)))
else
dig = true
end
end
if dig then
local items = minetest.get_node_drops (node, toolname)
if items then
drops = { }
for i = 1, #items do
drops[i] = ItemStack (items[i])
end
if def and def.preserve_metadata then
def.preserve_metadata (pos, node, minetest.get_meta (pos), drops)
end
end
minetest.remove_node (pos)
end
end
return drops
end
local function add_drops (drops, drop)
if drops and drop then
for i = 1, #drop do
local item = ItemStack (drop[i])
if item and not item:is_empty () then
local existing = drops[item:get_name ()]
if existing and is_same_item (item, existing) then
existing:set_count (existing:get_count () + item:get_count ())
else
drops[item:get_name ()] = item
end
end
end
end
end
local function explode_node (pos, dig_chance, intensity, drops, filter)
if not utils.is_protected (pos, nil) then
dig_chance = math.min (math.max (dig_chance, 0), 100)
if math.random (100) <= dig_chance then
local node = utils.get_far_node (pos)
local blasted = false
if node and node.name ~= "air" then
local def = minetest.registered_nodes[node.name]
if def then
if def.diggable == false then
return false
end
for k, v in pairs (filter) do
if def[k] == nil then
if filter[k.."_undefined"] == false then
return false
end
elseif def[k] ~= v then
return false
end
end
if def.on_blast then
def.on_blast (pos, intensity)
blasted = true
end
end
if not blasted then
local drop = dig_node (pos, true)
add_drops (drops, drop)
end
minetest.check_for_falling ({ x = pos.x, y = pos.y + 1, z = pos.z })
return true
end
end
end
return false
end
local function burn_node (pos, fire_chance, burn_all)
if not utils.is_protected (pos, nil) then
fire_chance = math.min (math.max (fire_chance, 0), 100)
if math.random (100) <= fire_chance then
explode.set_fire (pos, burn_all)
end
end
end
local function entity_is_drop (obj)
return obj.get_luaentity and obj:get_luaentity () and
obj:get_luaentity ().name and
obj:get_luaentity ().name == "__builtin:item"
end
local function explode_entities (pos, radius, damage, drops)
local objs = minetest.get_objects_inside_radius (pos, radius)
for _, obj in pairs (objs) do
local obj_pos = obj:get_pos ()
local dir = vector.direction (pos, obj_pos)
local dist = vector.length (vector.subtract (obj_pos, pos))
local vel = vector.multiply (dir, ((radius + 1) - dist) / (radius + 1) * damage * 5)
if entity_is_drop (obj) then
obj:add_velocity (vel)
elseif not obj:get_armor_groups ().immortal then
local ent_damage = ((radius - dist) / radius * damage / 2) + (damage / 2)
local reason = { type = "set_hp", from = "lwcomponents" }
if obj:is_player() then
obj:add_velocity (vel)
obj:set_hp (obj:get_hp() - ent_damage, reason)
else
local luaobj = obj:get_luaentity()
-- object might have disappeared somehow
if luaobj then
local do_damage = true
local do_knockback = true
local entity_drops = {}
local objdef = minetest.registered_entities[luaobj.name]
if objdef and objdef.on_blast then
do_damage, do_knockback, entity_drops = objdef.on_blast (luaobj, ent_damage)
end
if do_knockback then
obj:add_velocity (vel)
end
if do_damage then
obj:set_hp (obj:get_hp() - ent_damage, reason)
end
add_drops (drops, entity_drops)
end
end
end
end
end
local function spray_drops (pos, drops, damage)
local max_vel = damage * 2.5
for k, stack in pairs (drops) do
local vel =
{
x = math.random (max_vel) - (max_vel / 2),
y = math.random (max_vel) - (max_vel / 2),
z = math.random (max_vel) - (max_vel / 2)
}
local drop = minetest.add_item (pos, stack)
if drop then
drop:set_velocity (vel)
end
end
end
local function add_effects (pos, radius, drops)
minetest.add_particle ({
pos = pos,
velocity = vector.new (),
acceleration = vector.new (),
expirationtime = 0.4,
size = 30, -- radius * 10,
collisiondetection = false,
vertical = false,
texture = "lwcomponents_boom.png",
glow = 15,
})
minetest.add_particlespawner ({
amount = 64,
time = 0.5,
minpos = vector.subtract (pos, radius / 2),
maxpos = vector.add (pos, radius / 2),
minvel = {x = -10, y = -10, z = -10},
maxvel = {x = 10, y = 10, z = 10},
minacc = vector.new (),
maxacc = vector.new (),
minexptime = 1,
maxexptime = 2.5,
minsize = 9, -- radius * 3,
maxsize = 15, -- radius * 5,
texture = "lwcomponents_smoke.png",
})
-- we just dropped some items. Look at the items entities and pick
-- one of them to use as texture
local texture = "lwcomponents_blast.png" --fallback texture
local node
local most = 0
if drops then
for name, stack in pairs (drops) do
local count = stack:get_count()
if count > most then
most = count
local def = minetest.registered_nodes[name]
if def then
node = { name = name }
end
if def and def.tiles and def.tiles[1] then
if type (def.tiles[1]) == "table" then
texture = def.tiles[1].name or "lwcomponents_blast.png"
elseif type (def.tiles[1]) == "string" then
texture = def.tiles[1]
end
end
end
end
end
minetest.add_particlespawner ({
amount = 64,
time = 0.1,
minpos = vector.subtract (pos, radius / 2),
maxpos = vector.add (pos, radius / 2),
minvel = {x = -3, y = 0, z = -3},
maxvel = {x = 3, y = 5, z = 3},
minacc = {x = 0, y = -10, z = 0},
maxacc = {x = 0, y = -10, z = 0},
minexptime = 0.8,
maxexptime = 2.0,
minsize = 1, -- radius * 0.33,
maxsize = 3, -- radius,
texture = texture,
-- ^ only as fallback for clients without support for `node` parameter
node = node,
collisiondetection = true,
})
end
function utils.boom (pos, -- center of explosion
node_radius, node_chance, -- radius and chance in 100
fire_radius, fire_chance, -- radius and chance in 100
entity_radius, entity_damage, -- radius and max damage applied
disable_drops, -- true to disable drops
node_filter, -- node filter table as { buildable_to = true, buildable_to_undefined = false, ... }
burn_all, -- true to set fire to anything, otherwise only flammable
sound) -- sound on blast, if nil plays default
pos = vector.round (pos)
node_radius = math.floor (node_radius or 1)
fire_radius = math.floor (fire_radius or node_radius)
entity_radius = math.floor (entity_radius or node_radius * 2)
node_chance = node_chance or 80
fire_chance = fire_chance or 30
entity_damage = math.floor (entity_damage or entity_radius)
disable_drops = disable_drops == true
node_filter = node_filter or { }
burn_all = burn_all == true
sound = sound or "lwcannon"
local drops = { }
local effects_radius = (node_radius > 0 and node_radius) or entity_radius
local center_free = false
if not utils.is_protected (pos, nil) then
local center_node = utils.get_far_node (pos)
if not node or node.name == "air" then
center_free = true
end
end
if node_radius > 0 and node_chance > 0 then
local extents = node_radius * 2
for y = -extents, extents, 1 do
for z = -extents, extents, 1 do
for x = -extents, extents, 1 do
local node_pos = { x = x + pos.x, y = y + pos.y, z = z + pos.z }
local length = vector.length ({ x = x, y = y, z = z })
if node_chance > 0 and length <= node_radius then
if explode_node (node_pos, node_chance, 1.0, drops, node_filter) then
if vector.equals (pos, node_pos) then
center_free = true
end
end
end
end
end
end
end
if fire_radius > 0 and fire_chance > 0 then
local extents = fire_radius * 2
for y = -extents, extents, 1 do
for z = -extents, extents, 1 do
for x = -extents, extents, 1 do
local node_pos = { x = x + pos.x, y = y + pos.y, z = z + pos.z }
local length = vector.length ({ x = x, y = y, z = z })
if fire_chance > 0 and length <= fire_radius then
burn_node (node_pos, fire_chance, burn_all)
end
end
end
end
end
minetest.sound_play (sound,
{
pos = pos,
gain = 2.5,
max_hear_distance = math.min (effects_radius * 20, 128)
},
true)
if center_free then
minetest.set_node (pos, { name = "lwcomponents:boom" })
end
explode_entities (pos, entity_radius, entity_damage, drops)
if not disable_drops then
spray_drops (pos, drops, entity_damage)
end
add_effects (pos, effects_radius, drops)
minetest.log ("action", "A Shell explosion occurred at " .. minetest.pos_to_string (pos) ..
" with radius " .. entity_radius)
end
minetest.register_node ("lwcomponents:boom", {
description = S("Boom"),
drawtype = "airlike",
tiles = { "lwcomponents_boom.png" },
inventory_image = "lwcomponents_boom.png",
wield_image = "lwcomponents_boom.png",
light_source = default.LIGHT_MAX,
use_texture_alpha = "blend",
sunlight_propagates = true,
walkable = false,
pointable = false,
diggable = false,
climbable = false,
buildable_to = true,
floodable = true,
is_ground_content = false,
drop = "",
paramtype = "light",
param1 = 255,
post_effect_color = { a = 128, r = 255, g = 0, b = 0 },
groups = { dig_immediate = 3, not_in_creative_inventory = 1 },
on_construct = function (pos)
minetest.get_node_timer (pos):start (0.5)
end,
on_timer = function (pos, elapsed)
minetest.remove_node (pos)
return false
end,
-- unaffected by explosions
on_blast = function() end,
})
--

View File

@@ -199,14 +199,10 @@ local function on_blast (pos, intensity)
if meta then if meta then
if intensity >= 1.0 then if intensity >= 1.0 then
clear_map (pos)
minetest.remove_node (pos) minetest.remove_node (pos)
else -- intensity < 1.0 else -- intensity < 1.0
clear_map (pos)
local node = minetest.get_node_or_nil (pos) local node = minetest.get_node_or_nil (pos)
if node then if node then
local items = minetest.get_node_drops (node, nil) local items = minetest.get_node_drops (node, nil)

View File

@@ -1,4 +1,4 @@
local version = "0.1.10" local version = "0.1.15"
local mod_storage = minetest.get_mod_storage () local mod_storage = minetest.get_mod_storage ()
@@ -15,8 +15,9 @@ end
local utils = { } local utils = { }
local modpath = minetest.get_modpath ("lwcomponents") local modpath = minetest.get_modpath ("lwcomponents")
loadfile (modpath.."/utils.lua") (utils, mod_storage)
loadfile (modpath.."/settings.lua") (utils) loadfile (modpath.."/settings.lua") (utils)
loadfile (modpath.."/utils.lua") (utils, mod_storage)
loadfile (modpath.."/explode.lua") (utils)
loadfile (modpath.."/api.lua") (utils) loadfile (modpath.."/api.lua") (utils)
utils.connections = loadfile (modpath.."/connections.lua") () utils.connections = loadfile (modpath.."/connections.lua") ()
loadfile (modpath.."/dropper.lua") (utils) loadfile (modpath.."/dropper.lua") (utils)
@@ -32,6 +33,8 @@ loadfile (modpath.."/deployer.lua") (utils)
loadfile (modpath.."/fan.lua") (utils) loadfile (modpath.."/fan.lua") (utils)
loadfile (modpath.."/conduit.lua") (utils, mod_storage) loadfile (modpath.."/conduit.lua") (utils, mod_storage)
loadfile (modpath.."/cannon.lua") (utils) loadfile (modpath.."/cannon.lua") (utils)
loadfile (modpath.."/cannon_shell.lua") (utils)
loadfile (modpath.."/pistons.lua") (utils)
loadfile (modpath.."/extras.lua") (utils) loadfile (modpath.."/extras.lua") (utils)
loadfile (modpath.."/digiswitch.lua") (utils) loadfile (modpath.."/digiswitch.lua") (utils)
loadfile (modpath.."/movefloor.lua") (utils) loadfile (modpath.."/movefloor.lua") (utils)

View File

@@ -69,7 +69,12 @@ public domain.
player button images derived from mesecons button image. player button images derived from mesecons button image.
cannon firing sound from tnt, released under CC BY-SA 3.0 and CC0 1.0 cannon firing and explosion sound from tnt (TumeniNodes/steveygos93),
released under CC0 1.0 (originally from https://freesound.org/s/80401/)
boom image from tnt, released under CC BY-SA 3.0.
Piston images and sounds from mesecons_pistons, released under CC-BY-SA 3.0.
All other media, or media not covered by a licence, is licensed All other media, or media not covered by a licence, is licensed
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)

View File

@@ -3,4 +3,4 @@ description = Various components for mesecons and digilines.
title = LWComponents title = LWComponents
name = lwcomponents name = lwcomponents
depends = default depends = default
optional_depends = lwdrops, mesecons, digilines, unifieddyes, intllib, hopper, digistuff optional_depends = mesecons, digilines, unifieddyes, intllib, hopper, digistuff

View File

@@ -0,0 +1,162 @@
# Blender v2.82 (sub 7) OBJ File: 'shell.blend'
# www.blender.org
mtllib shell.mtl
o Sell
v 1.188815 0.386266 -2.500000
v 1.188815 -0.386266 -0.000000
v 1.188815 -0.386266 -2.500000
v -1.188815 -0.386266 0.000000
v -1.188815 0.386266 -2.500000
v -1.188815 -0.386266 -2.500000
v 1.188815 0.386266 -0.000000
v 0.951055 -0.309014 0.499997
v 0.734730 -1.011265 -0.000000
v -0.734730 -1.011265 -2.500000
v -0.734730 -1.011265 0.000000
v -0.951055 0.309014 0.499997
v -1.188815 0.386266 0.000000
v 0.237761 -0.077252 2.000000
v 0.440836 -0.606760 1.000000
v 0.713290 -0.231762 1.000000
v 0.734730 1.011265 -2.500000
v 0.146942 0.202250 2.000000
v 0.146942 -0.202250 2.000000
v 0.951055 0.309014 0.499997
v -0.000000 -1.250000 -2.500000
v 0.000000 -1.250000 0.000000
v -0.587785 -0.809015 0.499997
v -0.734730 1.011265 0.000000
v -0.587785 0.809015 0.499997
v 0.000000 1.250000 0.000000
v 0.734730 -1.011265 -2.500000
v 0.734730 1.011265 -0.000000
v -0.000000 1.250000 -2.500000
v -0.146942 -0.202250 2.000000
v -0.237760 -0.077252 2.000000
v -0.951055 -0.309014 0.499997
v -0.734730 1.011265 -2.500000
v -0.237760 0.077252 2.000000
v 0.000000 -0.249996 2.000000
v -0.440836 -0.606760 1.000000
v 0.587785 -0.809015 0.499997
v 0.713290 0.231762 1.000000
v 0.237761 0.077252 2.000000
v 0.587785 0.809015 0.499997
v 0.440836 0.606760 1.000000
v -0.713290 0.231762 1.000000
v -0.440836 0.606760 1.000000
v -0.713290 -0.231762 1.000000
v 0.000000 0.249996 2.000000
v -0.146942 0.202250 2.000000
vn 1.0000 0.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.7306 -0.5308 0.4294
vn -0.8090 -0.5878 0.0000
vn -0.9031 0.0000 0.4294
vn 0.8090 0.5878 0.0000
vn 0.0000 0.0000 1.0000
vn 0.9031 0.0000 0.4294
vn 0.0000 0.0000 -1.0000
vn -0.2791 -0.8589 0.4294
vn -0.2791 0.8589 0.4294
vn -0.3090 -0.9511 0.0000
vn 0.7306 0.5308 0.4294
vn 0.3090 0.9511 0.0000
vn -0.8090 0.5878 0.0000
vn -0.3090 0.9511 0.0000
vn 0.3090 -0.9511 0.0000
vn -0.7306 -0.5308 0.4294
vn 0.2791 -0.8589 0.4294
vn 0.8090 -0.5878 0.0000
vn 0.2791 0.8589 0.4294
vn -0.7306 0.5308 0.4294
usemtl None
s off
f 1//1 2//1 3//1
f 4//2 5//2 6//2
f 7//1 2//1 1//1
f 2//3 8//3 9//3
f 4//4 10//4 11//4
f 4//5 12//5 13//5
f 14//3 15//3 16//3
f 1//6 17//6 7//6
f 14//7 18//7 19//7
f 8//8 20//8 16//8
f 10//9 5//9 21//9
f 6//4 10//4 4//4
f 22//10 23//10 11//10
f 24//11 25//11 26//11
f 3//9 5//9 1//9
f 21//9 5//9 27//9
f 11//12 10//12 22//12
f 28//13 20//13 7//13
f 17//14 26//14 28//14
f 7//6 17//6 28//6
f 29//14 26//14 17//14
f 24//15 5//15 13//15
f 29//16 24//16 26//16
f 22//17 27//17 9//17
f 30//7 18//7 31//7
f 11//18 32//18 4//18
f 33//15 5//15 24//15
f 29//9 5//9 33//9
f 31//7 18//7 34//7
f 15//19 19//19 35//19
f 33//16 24//16 29//16
f 27//9 5//9 3//9
f 22//12 10//12 21//12
f 21//17 27//17 22//17
f 13//2 5//2 4//2
f 6//9 5//9 10//9
f 2//20 27//20 3//20
f 9//20 27//20 2//20
f 31//18 36//18 30//18
f 32//5 12//5 4//5
f 17//9 5//9 29//9
f 1//9 5//9 17//9
f 35//7 18//7 30//7
f 16//3 37//3 9//3
f 14//8 38//8 39//8
f 26//21 40//21 28//21
f 41//13 18//13 39//13
f 24//22 42//22 25//22
f 25//11 43//11 26//11
f 31//5 34//5 44//5
f 30//10 36//10 35//10
f 34//22 43//22 42//22
f 44//18 32//18 11//18
f 45//21 18//21 41//21
f 16//8 38//8 14//8
f 9//3 8//3 16//3
f 22//19 15//19 35//19
f 15//3 37//3 16//3
f 16//8 20//8 38//8
f 38//13 20//13 28//13
f 32//5 42//5 12//5
f 13//22 12//22 24//22
f 12//22 42//22 24//22
f 42//22 43//22 25//22
f 46//22 43//22 34//22
f 26//21 45//21 41//21
f 14//3 19//3 15//3
f 35//10 36//10 22//10
f 22//19 37//19 15//19
f 9//19 37//19 22//19
f 44//5 34//5 42//5
f 39//7 18//7 14//7
f 2//8 20//8 8//8
f 7//8 20//8 2//8
f 38//13 41//13 39//13
f 41//21 40//21 26//21
f 44//5 42//5 32//5
f 19//7 18//7 35//7
f 34//7 18//7 46//7
f 46//7 18//7 45//7
f 44//18 36//18 31//18
f 36//10 23//10 22//10
f 38//13 40//13 41//13
f 28//13 40//13 38//13
f 44//18 23//18 36//18
f 11//18 23//18 44//18
f 45//11 43//11 46//11
f 26//11 43//11 45//11

143
models/piston_normal_1.obj Normal file
View File

@@ -0,0 +1,143 @@
# Blender v2.82 (sub 7) OBJ File: ''
# www.blender.org
mtllib piston_normal_1.mtl
o cube
v 0.500000 -0.500000 0.500000
v -0.500000 -0.500000 0.500000
v -0.500000 -0.500000 -0.312500
v 0.500000 -0.500000 -0.312500
v 0.500000 0.500000 0.500000
v 0.500000 0.500000 -0.312500
v -0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.312500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.333333 0.333333
vt 0.666667 0.333333
vt 0.666667 0.666667
vt 0.333333 0.666667
vt 0.333333 0.666667
vt 0.666667 1.000000
vt 0.333333 1.000000
vn 0.0000 -1.0000 0.0000
vn 1.0000 -0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 -0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 -0.0000 1.0000
usemtl m_7
s 1
f 1/1/1 2/2/1 3/3/1 4/4/1
f 5/5/2 1/6/2 4/7/2 6/8/2
f 7/9/3 5/10/3 6/11/3 8/12/3
f 2/13/4 7/14/4 8/15/4 3/16/4
f 8/17/5 6/18/5 4/19/5 3/20/5
f 2/21/6 1/1/6 5/22/6 7/23/6
o cube.000
v 0.500000 -0.500000 -1.312500
v -0.500000 -0.500000 -1.312500
v -0.500000 -0.500000 -1.500000
v 0.500000 -0.500000 -1.500000
v 0.500000 0.500000 -1.312500
v 0.500000 0.500000 -1.500000
v -0.500000 0.500000 -1.312500
v -0.500000 0.500000 -1.500000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.333333 0.000000
vt 0.666667 0.000000
vt 0.666667 0.333333
vt 0.333333 0.333333
vt 0.666667 0.333333
vt 1.000000 0.333333
vt 1.000000 0.666667
vt 0.666667 0.666667
vn 0.0000 -1.0000 0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl m_7
s 1
f 9/24/7 10/25/7 11/26/7 12/27/7
f 13/28/8 9/29/8 12/30/8 14/31/8
f 15/32/9 13/33/9 14/34/9 16/35/9
f 10/36/10 15/37/10 16/38/10 11/39/10
f 16/40/11 14/41/11 12/42/11 11/43/11
f 10/44/12 9/45/12 13/46/12 15/47/12
o cube.001
v 0.125000 -0.125000 0.375000
v -0.125000 -0.125000 0.375000
v -0.125000 -0.125000 -1.375000
v 0.125000 -0.125000 -1.375000
v 0.125000 0.125000 0.375000
v 0.125000 0.125000 -1.375000
v -0.125000 0.125000 0.375000
v -0.125000 0.125000 -1.375000
vt 0.125000 0.354167
vt 0.208333 0.354167
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.354167
vt 0.208333 0.354167
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.354167
vt 0.208333 0.354167
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.354167
vt 0.208333 0.354167
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.458333 0.130208
vt 0.541667 0.130208
vt 0.541667 0.213542
vt 0.458333 0.213542
vt 0.791667 0.463542
vt 0.875000 0.463542
vt 0.875000 0.546875
vt 0.791667 0.546875
vn 0.0000 -1.0000 -0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl m_7
s 1
f 17/48/13 18/49/13 19/50/13 20/51/13
f 21/52/14 17/53/14 20/54/14 22/55/14
f 23/56/15 21/57/15 22/58/15 24/59/15
f 18/60/16 23/61/16 24/62/16 19/63/16
f 24/64/17 22/65/17 20/66/17 19/67/17
f 18/68/18 17/69/18 21/70/18 23/71/18

143
models/piston_normal_2.obj Normal file
View File

@@ -0,0 +1,143 @@
# Blender v2.82 (sub 7) OBJ File: ''
# www.blender.org
mtllib piston_normal_2.mtl
o cube.011
v 0.500000 -0.500000 0.500000
v -0.500000 -0.500000 0.500000
v -0.500000 -0.500000 -0.312500
v 0.500000 -0.500000 -0.312500
v 0.500000 0.500000 0.500000
v 0.500000 0.500000 -0.312500
v -0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.312500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.333333 0.333333
vt 0.666667 0.333333
vt 0.666667 0.666667
vt 0.333333 0.666667
vt 0.333333 0.666667
vt 0.666667 1.000000
vt 0.333333 1.000000
vn 0.0000 -1.0000 0.0000
vn 1.0000 -0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 -0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 -0.0000 1.0000
usemtl m_0.001
s 1
f 1/1/1 2/2/1 3/3/1 4/4/1
f 5/5/2 1/6/2 4/7/2 6/8/2
f 7/9/3 5/10/3 6/11/3 8/12/3
f 2/13/4 7/14/4 8/15/4 3/16/4
f 8/17/5 6/18/5 4/19/5 3/20/5
f 2/21/6 1/1/6 5/22/6 7/23/6
o cube.012
v 0.500000 -0.500000 -2.312500
v -0.500000 -0.500000 -2.312500
v -0.500000 -0.500000 -2.500000
v 0.500000 -0.500000 -2.500000
v 0.500000 0.500000 -2.312500
v 0.500000 0.500000 -2.500000
v -0.500000 0.500000 -2.312500
v -0.500000 0.500000 -2.500000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.333333 0.000000
vt 0.666667 0.000000
vt 0.666667 0.333333
vt 0.333333 0.333333
vt 0.666667 0.333333
vt 1.000000 0.333333
vt 1.000000 0.666667
vt 0.666667 0.666667
vn 0.0000 -1.0000 -0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl m_0.001
s 1
f 9/24/7 10/25/7 11/26/7 12/27/7
f 13/28/8 9/29/8 12/30/8 14/31/8
f 15/32/9 13/33/9 14/34/9 16/35/9
f 10/36/10 15/37/10 16/38/10 11/39/10
f 16/40/11 14/41/11 12/42/11 11/43/11
f 10/44/12 9/45/12 13/46/12 15/47/12
o cube.013
v 0.125000 -0.125000 0.375000
v -0.125000 -0.125000 0.375000
v -0.125000 -0.125000 -2.375000
v 0.125000 -0.125000 -2.375000
v 0.125000 0.125000 0.375000
v 0.125000 0.125000 -2.375000
v -0.125000 0.125000 0.375000
v -0.125000 0.125000 -2.375000
vt 0.125000 0.020833
vt 0.208333 0.020833
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.020833
vt 0.208333 0.020833
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.020833
vt 0.208333 0.020833
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.020833
vt 0.208333 0.020833
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.562500 0.229167
vt 0.458333 0.229167
vt 0.458333 0.125000
vt 0.562500 0.125000
vt 0.875000 0.458333
vt 0.791667 0.458333
vt 0.791667 0.541667
vt 0.875000 0.541667
vn 0.0000 -1.0000 -0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl m_0.001
s 1
f 17/48/13 18/49/13 19/50/13 20/51/13
f 21/52/14 17/53/14 20/54/14 22/55/14
f 23/56/15 21/57/15 22/58/15 24/59/15
f 18/60/16 23/61/16 24/62/16 19/63/16
f 24/64/17 22/65/17 20/66/17 19/67/17
f 18/68/18 17/69/18 21/70/18 23/71/18

143
models/piston_sticky_1.obj Normal file
View File

@@ -0,0 +1,143 @@
# Blender v2.82 (sub 7) OBJ File: ''
# www.blender.org
mtllib piston_sticky_1.mtl
o cube.002
v 0.500000 -0.500000 0.500000
v -0.500000 -0.500000 0.500000
v -0.500000 -0.500000 -0.312500
v 0.500000 -0.500000 -0.312500
v 0.500000 0.500000 0.500000
v 0.500000 0.500000 -0.312500
v -0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.312500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.333333 0.333333
vt 0.666667 0.333333
vt 0.666667 0.666667
vt 0.333333 0.666667
vt 0.333333 0.666667
vt 0.666667 1.000000
vt 0.333333 1.000000
vn 0.0000 -1.0000 0.0000
vn 1.0000 -0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 -0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 -0.0000 1.0000
usemtl m_7.001
s 1
f 1/1/1 2/2/1 3/3/1 4/4/1
f 5/5/2 1/6/2 4/7/2 6/8/2
f 7/9/3 5/10/3 6/11/3 8/12/3
f 2/13/4 7/14/4 8/15/4 3/16/4
f 8/17/5 6/18/5 4/19/5 3/20/5
f 2/21/6 1/1/6 5/22/6 7/23/6
o cube.003
v 0.500000 -0.500000 -1.312500
v -0.500000 -0.500000 -1.312500
v -0.500000 -0.500000 -1.500000
v 0.500000 -0.500000 -1.500000
v 0.500000 0.500000 -1.312500
v 0.500000 0.500000 -1.500000
v -0.500000 0.500000 -1.312500
v -0.500000 0.500000 -1.500000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.000000
vt 1.000000 0.000000
vt 1.000000 0.333333
vt 0.666667 0.333333
vt 0.666667 0.333333
vt 1.000000 0.333333
vt 1.000000 0.666667
vt 0.666667 0.666667
vn 0.0000 -1.0000 0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl m_7.001
s 1
f 9/24/7 10/25/7 11/26/7 12/27/7
f 13/28/8 9/29/8 12/30/8 14/31/8
f 15/32/9 13/33/9 14/34/9 16/35/9
f 10/36/10 15/37/10 16/38/10 11/39/10
f 16/40/11 14/41/11 12/42/11 11/43/11
f 10/44/12 9/45/12 13/46/12 15/47/12
o cube.004
v 0.125000 -0.125000 0.375000
v -0.125000 -0.125000 0.375000
v -0.125000 -0.125000 -1.375000
v 0.125000 -0.125000 -1.375000
v 0.125000 0.125000 0.375000
v 0.125000 0.125000 -1.375000
v -0.125000 0.125000 0.375000
v -0.125000 0.125000 -1.375000
vt 0.125000 0.354167
vt 0.208333 0.354167
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.354167
vt 0.208333 0.354167
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.354167
vt 0.208333 0.354167
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.354167
vt 0.208333 0.354167
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.458333 0.130208
vt 0.541667 0.130208
vt 0.541667 0.213542
vt 0.458333 0.213542
vt 0.791667 0.463542
vt 0.875000 0.463542
vt 0.875000 0.546875
vt 0.791667 0.546875
vn 0.0000 -1.0000 -0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl m_7.001
s 1
f 17/48/13 18/49/13 19/50/13 20/51/13
f 21/52/14 17/53/14 20/54/14 22/55/14
f 23/56/15 21/57/15 22/58/15 24/59/15
f 18/60/16 23/61/16 24/62/16 19/63/16
f 24/64/17 22/65/17 20/66/17 19/67/17
f 18/68/18 17/69/18 21/70/18 23/71/18

143
models/piston_sticky_2.obj Normal file
View File

@@ -0,0 +1,143 @@
# Blender v2.82 (sub 7) OBJ File: ''
# www.blender.org
mtllib piston_sticky_2.mtl
o cube.008
v 0.500000 -0.500000 0.500000
v -0.500000 -0.500000 0.500000
v -0.500000 -0.500000 -0.312500
v 0.500000 -0.500000 -0.312500
v 0.500000 0.500000 0.500000
v 0.500000 0.500000 -0.312500
v -0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.312500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.333333 0.333333
vt 0.666667 0.333333
vt 0.666667 0.666667
vt 0.333333 0.666667
vt 0.333333 0.666667
vt 0.666667 1.000000
vt 0.333333 1.000000
vn 0.0000 -1.0000 0.0000
vn 1.0000 -0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 -0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 -0.0000 1.0000
usemtl m_0
s 1
f 1/1/1 2/2/1 3/3/1 4/4/1
f 5/5/2 1/6/2 4/7/2 6/8/2
f 7/9/3 5/10/3 6/11/3 8/12/3
f 2/13/4 7/14/4 8/15/4 3/16/4
f 8/17/5 6/18/5 4/19/5 3/20/5
f 2/21/6 1/1/6 5/22/6 7/23/6
o cube.009
v 0.500000 -0.500000 -2.312500
v -0.500000 -0.500000 -2.312500
v -0.500000 -0.500000 -2.500000
v 0.500000 -0.500000 -2.500000
v 0.500000 0.500000 -2.312500
v 0.500000 0.500000 -2.500000
v -0.500000 0.500000 -2.312500
v -0.500000 0.500000 -2.500000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.000000
vt 1.000000 0.000000
vt 1.000000 0.333333
vt 0.666667 0.333333
vt 0.666667 0.333333
vt 1.000000 0.333333
vt 1.000000 0.666667
vt 0.666667 0.666667
vn 0.0000 -1.0000 -0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl m_0
s 1
f 9/24/7 10/25/7 11/26/7 12/27/7
f 13/28/8 9/29/8 12/30/8 14/31/8
f 15/32/9 13/33/9 14/34/9 16/35/9
f 10/36/10 15/37/10 16/38/10 11/39/10
f 16/40/11 14/41/11 12/42/11 11/43/11
f 10/44/12 9/45/12 13/46/12 15/47/12
o cube.010
v 0.125000 -0.125000 0.375000
v -0.125000 -0.125000 0.375000
v -0.125000 -0.125000 -2.375000
v 0.125000 -0.125000 -2.375000
v 0.125000 0.125000 0.375000
v 0.125000 0.125000 -2.375000
v -0.125000 0.125000 0.375000
v -0.125000 0.125000 -2.375000
vt 0.125000 0.020833
vt 0.208333 0.020833
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.020833
vt 0.208333 0.020833
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.020833
vt 0.208333 0.020833
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.020833
vt 0.208333 0.020833
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.562500 0.229167
vt 0.458333 0.229167
vt 0.458333 0.125000
vt 0.562500 0.125000
vt 0.875000 0.458333
vt 0.791667 0.458333
vt 0.791667 0.541667
vt 0.875000 0.541667
vn 0.0000 -1.0000 -0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl m_0
s 1
f 17/48/13 18/49/13 19/50/13 20/51/13
f 21/52/14 17/53/14 20/54/14 22/55/14
f 23/56/15 21/57/15 22/58/15 24/59/15
f 18/60/16 23/61/16 24/62/16 19/63/16
f 24/64/17 22/65/17 20/66/17 19/67/17
f 18/68/18 17/69/18 21/70/18 23/71/18

930
pistons.lua Normal file
View File

@@ -0,0 +1,930 @@
local utils = ...
local S = utils.S
if utils.digilines_supported or utils.mesecon_supported then
local piston_interval = 0.2
local function direction_vector (node)
local axis = math.floor (node.param2 / 4)
local rotate = node.param2 % 4
local vec = { x = 0, y = 0, z = 0 }
if rotate == 0 then
vec = { x = 0, y = 0, z = -1 }
elseif rotate == 1 then
vec = { x = -1, y = 0, z = 0 }
elseif rotate == 2 then
vec = { x = 0, y = 0, z = 1 }
elseif rotate == 3 then
vec = { x = 1, y = 0, z = 0 }
end
if axis == 1 then
vec = vector.rotate (vec, { x = math.pi / -2, y = 0, z = 0 })
elseif axis == 2 then
vec = vector.rotate (vec, { x = math.pi / 2, y = 0, z = 0 })
elseif axis == 3 then
vec = vector.rotate (vec, { x = 0, y = 0, z = math.pi / 2 })
elseif axis == 4 then
vec = vector.rotate (vec, { x = 0, y = 0, z = math.pi / -2 })
elseif axis == 5 then
vec = vector.rotate (vec, { x = math.pi, y = 0, z = 0 })
end
return vec
end
local function push_entities (pos, vec)
local tpos = vector.add (pos, vec)
local tnode = utils.get_far_node (tpos)
local can_move = false
if tnode then
if tnode.name == "air" then
can_move = true
else
tdef = utils.find_item_def (tnode.name)
can_move = tdef and not tdef.walkable
end
end
if can_move then
local object = minetest.get_objects_inside_radius (pos, 1.5)
for j = 1, #object do
if object[j].get_pos then
local opos = object[j]:get_pos ()
if opos.x > (pos.x - 0.5) and opos.x < (pos.x + 0.5) and
opos.z > (pos.z - 0.5) and opos.z < (pos.z + 0.5) and
opos.y > (pos.y - 0.5) and opos.y < (pos.y + 0.5) then
object[j]:set_pos (vector.add (opos, vec))
end
end
end
end
end
local function push_nodes (pos, extent)
local node = utils.get_far_node (pos)
if node then
local vec = direction_vector (node)
local last = vector.add (pos, vector.multiply (vec, extent))
local maxnodes = utils.settings.max_piston_nodes + 1
local count = 0
for i = 1, maxnodes do
local tnode = utils.get_far_node (last)
if not tnode then
return false
end
if tnode.name == "air" then
count = i - 1
break
end
if i == maxnodes then
return false
end
last = vector.add (last, vec)
end
push_entities (last, vec)
for i = 1, count, 1 do
local cpos = vector.subtract (last, vec)
local cnode = utils.get_far_node (cpos)
local cmeta = minetest.get_meta (cpos)
if not cnode or not cmeta then
return false
end
local tmeta = cmeta:to_table ()
push_entities (cpos, vec)
minetest.remove_node (cpos)
minetest.set_node (last, cnode)
if tmeta then
cmeta = minetest.get_meta (last)
if not cmeta then
return false
end
cmeta:from_table (tmeta)
end
last = cpos
end
end
return true
end
local function pull_node (pos, extent)
local node = utils.get_far_node (pos)
if node then
local vec = direction_vector (node)
local cpos = vector.add (pos, vector.multiply (vec, extent))
local cnode = utils.get_far_node (cpos)
if cnode and cnode ~= "air" then
local cmeta = minetest.get_meta (cpos)
if cmeta then
local tpos = vector.subtract (cpos, vec)
local tmeta = cmeta:to_table ()
minetest.remove_node (cpos)
minetest.set_node (tpos, cnode)
if tmeta then
cmeta = minetest.get_meta (tpos)
if cmeta then
cmeta:from_table (tmeta)
end
end
end
end
end
end
local function place_blank (pos, extent)
local node = utils.get_far_node (pos)
if node then
local vec = direction_vector (node)
local blank_pos = vector.add (pos, vector.multiply (vec, extent))
local blank_node = utils.get_far_node (blank_pos)
if blank_node and blank_node.name == "air" then
minetest.set_node (blank_pos,
{
name = "lwcomponents:piston_blank_"..tostring (extent),
param2 = node.param2
})
end
end
end
local function remove_blank (pos, extent)
local node = utils.get_far_node (pos)
if node then
local vec = direction_vector (node)
local blank_pos = vector.add (pos, vector.multiply (vec, extent))
local blank_node = utils.get_far_node (blank_pos)
if blank_node and
blank_node.name == "lwcomponents:piston_blank_"..tostring (extent) then
minetest.remove_node (blank_pos)
end
end
end
local function extend_piston (pos, extent)
local node = utils.get_far_node (pos)
local meta = minetest.get_meta (pos)
if node and meta then
extent = math.max (math.min (tonumber (extent or 2), meta:get_int ("max_extent")), 0)
if node.name == "lwcomponents:piston" then
if extent ~= 0 then
if push_nodes (pos, 1) then
node.name = "lwcomponents:piston_1"
minetest.swap_node (pos, node)
place_blank (pos, 1)
minetest.sound_play ("lwpiston_extend",
{
pos = pos,
max_hear_distance = 20,
gain = 0.3
},
true)
if extent == 2 then
meta:set_int ("extent", 2)
minetest.get_node_timer (pos):start (piston_interval)
return true
end
end
end
elseif node.name == "lwcomponents:piston_1" then
if extent == 0 then
remove_blank (pos, 1)
node.name = "lwcomponents:piston"
minetest.swap_node (pos, node)
minetest.sound_play ("lwpiston_retract",
{
pos = pos,
max_hear_distance = 20,
gain = 0.3
},
true)
elseif extent == 2 then
if push_nodes (pos, 2) then
node.name = "lwcomponents:piston_2"
minetest.swap_node (pos, node)
place_blank (pos, 2)
minetest.sound_play ("lwpiston_extend",
{
pos = pos,
max_hear_distance = 20,
gain = 0.3
},
true)
end
end
elseif node.name == "lwcomponents:piston_2" then
if extent ~= 2 then
remove_blank (pos, 2)
node.name = "lwcomponents:piston_1"
minetest.swap_node (pos, node)
minetest.sound_play ("lwpiston_retract",
{
pos = pos,
max_hear_distance = 20,
gain = 0.3
},
true)
if extent == 0 then
meta:set_int ("extent", 0)
minetest.get_node_timer (pos):start (piston_interval)
return true
end
end
elseif node.name == "lwcomponents:piston_sticky" then
if extent ~= 0 then
if push_nodes (pos, 1) then
node.name = "lwcomponents:piston_sticky_1"
minetest.swap_node (pos, node)
place_blank (pos, 1)
minetest.sound_play ("lwpiston_extend",
{
pos = pos,
max_hear_distance = 20,
gain = 0.3
},
true)
if extent == 2 then
meta:set_int ("extent", 2)
minetest.get_node_timer (pos):start (piston_interval)
return true
end
end
end
elseif node.name == "lwcomponents:piston_sticky_1" then
if extent == 0 then
remove_blank (pos, 1)
node.name = "lwcomponents:piston_sticky"
minetest.swap_node (pos, node)
pull_node (pos, 2)
minetest.sound_play ("lwpiston_retract",
{
pos = pos,
max_hear_distance = 20,
gain = 0.3
},
true)
elseif extent == 2 then
if push_nodes (pos, 2) then
node.name = "lwcomponents:piston_sticky_2"
minetest.swap_node (pos, node)
place_blank (pos, 2)
minetest.sound_play ("lwpiston_extend",
{
pos = pos,
max_hear_distance = 20,
gain = 0.3
},
true)
end
end
elseif node.name == "lwcomponents:piston_sticky_2" then
if extent ~= 2 then
remove_blank (pos, 2)
node.name = "lwcomponents:piston_sticky_1"
minetest.swap_node (pos, node)
pull_node (pos, 3)
minetest.sound_play ("lwpiston_retract",
{
pos = pos,
max_hear_distance = 20,
gain = 0.3
},
true)
if extent == 0 then
meta:set_int ("extent", 0)
minetest.get_node_timer (pos):start (piston_interval)
return true
end
end
end
end
return false
end
local function on_destruct_1 (pos)
remove_blank (pos, 1)
end
local function on_destruct_2 (pos)
remove_blank (pos, 2)
remove_blank (pos, 1)
end
local function on_place (itemstack, placer, pointed_thing)
local param2 = 0
if placer and placer:is_player () then
param2 = minetest.dir_to_facedir (placer:get_look_dir (), true)
elseif pointed_thing and pointed_thing.type == "node" then
param2 = minetest.dir_to_facedir (vector.subtract (pointed_thing.under, pointed_thing.above), true)
end
return minetest.item_place (itemstack, placer, pointed_thing, param2)
end
local function after_place_node (pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta (pos)
local spec =
"size[7,3.3]"..
"field[1,1;4,2;channel;Channel;${channel}]"..
"button_exit[4.6,1.15;1.5,1;submit;Set]"..
"checkbox[1,2;single;Single move;false]"
meta:set_string ("formspec", spec)
meta:set_int ("max_extent", 2)
-- If return true no item is taken from itemstack
return false
end
local function on_receive_fields (pos, formname, fields, sender)
if not utils.can_interact_with_node (pos, sender) then
return
end
local meta = minetest.get_meta (pos)
if meta then
if fields.submit then
meta:set_string ("channel", fields.channel)
end
if fields.single then
if fields.single == "true" then
local spec =
"size[7,3.3]"..
"field[1,1;4,2;channel;Channel;${channel}]"..
"button_exit[4.6,1.15;1.5,1;submit;Set]"..
"checkbox[1,2;single;Single move;true]"
meta:set_int ("max_extent", 1)
meta:set_string ("formspec", spec)
else
local spec =
"size[7,3.3]"..
"field[1,1;4,2;channel;Channel;${channel}]"..
"button_exit[4.6,1.15;1.5,1;submit;Set]"..
"checkbox[1,2;single;Single move;false]"
meta:set_int ("max_extent", 2)
meta:set_string ("formspec", spec)
end
end
end
end
local function on_blast (pos, intensity)
local meta = minetest.get_meta (pos)
if meta then
if intensity >= 1.0 then
minetest.remove_node (pos)
else -- intensity < 1.0
local node = minetest.get_node_or_nil (pos)
if node then
local items = minetest.get_node_drops (node, nil)
if items and #items > 0 then
local stack = ItemStack (items[1])
if stack then
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos)
minetest.remove_node (pos)
end
end
end
end
end
end
local function can_dig (pos, player)
if not utils.can_interact_with_node (pos, player) then
return false
end
return true
end
local function on_rightclick (pos, node, clicker, itemstack, pointed_thing)
if not utils.can_interact_with_node (pos, clicker) then
if clicker and clicker:is_player () then
local owner = "<unknown>"
local meta = minetest.get_meta (pos)
if meta then
owner = meta:get_string ("owner")
end
local spec =
"formspec_version[3]"..
"size[8.0,4.0,false]"..
"label[1.0,1.0;Owned by "..minetest.formspec_escape (owner).."]"..
"button_exit[3.0,2.0;2.0,1.0;close;Close]"
minetest.show_formspec (clicker:get_player_name (),
"lwcomponents:component_privately_owned",
spec)
end
end
return itemstack
end
local function on_timer (pos, elapsed)
local meta = minetest.get_meta (pos)
if meta then
return extend_piston (pos, meta:get_int ("extent"))
end
return false
end
local function digilines_support ()
if utils.digilines_supported then
return
{
wire =
{
rules = utils.digilines_default_rules,
},
effector =
{
action = function (pos, node, channel, msg)
local meta = minetest.get_meta(pos)
if meta then
local this_channel = meta:get_string ("channel")
if this_channel ~= "" and this_channel == channel then
if type (msg) == "string" then
local m = { }
for w in string.gmatch(msg, "[^%s]+") do
m[#m + 1] = w
end
if m[1] == "extend" then
extend_piston (pos, m[2])
elseif m[1] == "retract" then
extend_piston (pos, 0)
elseif m[1] == "single" then
local spec =
"size[7,3.3]"..
"field[1,1;4,2;channel;Channel;${channel}]"..
"button_exit[4.6,1.15;1.5,1;submit;Set]"..
"checkbox[1,2;single;Single move;true]"
meta:set_int ("max_extent", 1)
meta:set_string ("formspec", spec)
elseif m[1] == "double" then
local spec =
"size[7,3.3]"..
"field[1,1;4,2;channel;Channel;${channel}]"..
"button_exit[4.6,1.15;1.5,1;submit;Set]"..
"checkbox[1,2;single;Single move;false]"
meta:set_int ("max_extent", 2)
meta:set_string ("formspec", spec)
end
end
end
end
end,
}
}
end
return nil
end
local function mesecon_support ()
if utils.mesecon_supported then
return
{
effector =
{
rules = utils.mesecon_default_rules,
action_on = function (pos, node)
-- do something to turn the effector on
extend_piston (pos, 2)
end,
action_off = function (pos, node)
-- do something to turn the effector off
extend_piston (pos, 0)
end,
}
}
end
return nil
end
minetest.register_node("lwcomponents:piston_blank_1", {
description = S("Piston blank"),
drawtype = "airlike",
light_source = 0,
sunlight_propagates = true,
walkable = false,
pointable = false,
diggable = false,
climbable = false,
buildable_to = false,
floodable = false,
is_ground_content = false,
drop = "",
groups = { not_in_creative_inventory = 1 },
paramtype = "light",
-- unaffected by explosions
on_blast = function() end,
})
minetest.register_node("lwcomponents:piston_blank_2", {
description = S("Piston blank"),
drawtype = "airlike",
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 0,
collision_box = {
type = "fixed",
fixed = {
{-0.125, -0.125, -0.4, 0.125, 0.125, 0.4},
{-0.5, -0.5, -0.5, 0.5, 0.5, -0.3125},
},
},
light_source = 0,
sunlight_propagates = true,
walkable = true,
pointable = false,
diggable = false,
climbable = false,
buildable_to = false,
floodable = false,
is_ground_content = false,
drop = "",
groups = { not_in_creative_inventory = 1 },
paramtype = "light",
-- unaffected by explosions
on_blast = function() end,
})
minetest.register_node("lwcomponents:piston", {
description = S("Piston"),
tiles = { "lwcomponents_piston_top.png", "lwcomponents_piston_bottom.png",
"lwcomponents_piston_right.png", "lwcomponents_piston_left.png",
"lwcomponents_piston_base.png", "lwcomponents_piston_pusher.png" },
is_ground_content = false,
groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 0,
floodable = false,
drop = "lwcomponents:piston",
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
digiline = digilines_support (),
on_place = on_place,
on_receive_fields = on_receive_fields,
can_dig = can_dig,
after_place_node = after_place_node,
on_blast = on_blast,
on_rightclick = on_rightclick,
on_timer = on_timer
})
minetest.register_node("lwcomponents:piston_1", {
description = S("Piston"),
drawtype = "mesh",
mesh = "piston_normal_1.obj",
tiles = { "lwcomponents_piston.png" },
visual_scale = 1.0,
selection_box = {
type = "fixed",
fixed = {
{-0.125, -0.125, -1.4, 0.125, 0.125, 0.4},
{-0.5, -0.5, -1.5, 0.5, 0.5, -1.3125},
{-0.5, -0.5, -0.3125, 0.5, 0.5, 0.5},
},
},
collision_box = {
type = "fixed",
fixed = {
{-0.125, -0.125, -1.4, 0.125, 0.125, 0.4},
{-0.5, -0.5, -1.5, 0.5, 0.5, -1.3125},
{-0.5, -0.5, -0.3125, 0.5, 0.5, 0.5},
},
},
is_ground_content = false,
groups = { cracky = 3 , not_in_creative_inventory = 1 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 0,
floodable = false,
drop = "lwcomponents:piston",
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
digiline = digilines_support (),
on_destruct = on_destruct_1,
on_receive_fields = on_receive_fields,
can_dig = can_dig,
after_place_node = after_place_node,
on_blast = on_blast,
on_rightclick = on_rightclick,
on_timer = on_timer
})
minetest.register_node("lwcomponents:piston_2", {
description = S("Piston"),
drawtype = "mesh",
mesh = "piston_normal_2.obj",
tiles = { "lwcomponents_piston.png" },
visual_scale = 1.0,
selection_box = {
type = "fixed",
fixed = {
{-0.125, -0.125, -2.4, 0.125, 0.125, 0.4},
{-0.5, -0.5, -2.5, 0.5, 0.5, -2.3125},
{-0.5, -0.5, -0.3125, 0.5, 0.5, 0.5},
},
},
collision_box = {
type = "fixed",
fixed = {
{-0.125, -0.125, -2.4, 0.125, 0.125, 0.4},
{-0.5, -0.5, -2.5, 0.5, 0.5, -2.3125},
{-0.5, -0.5, -0.3125, 0.5, 0.5, 0.5},
},
},
is_ground_content = false,
groups = { cracky = 3 , not_in_creative_inventory = 1 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 0,
floodable = false,
drop = "lwcomponents:piston",
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
digiline = digilines_support (),
on_destruct = on_destruct_2,
on_receive_fields = on_receive_fields,
can_dig = can_dig,
after_place_node = after_place_node,
on_blast = on_blast,
on_rightclick = on_rightclick,
on_timer = on_timer
})
minetest.register_node("lwcomponents:piston_sticky", {
description = S("Sticky Piston"),
tiles = { "lwcomponents_piston_top.png", "lwcomponents_piston_bottom.png",
"lwcomponents_piston_right.png", "lwcomponents_piston_left.png",
"lwcomponents_piston_base.png", "lwcomponents_piston_pusher_sticky.png" },
is_ground_content = false,
groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 0,
floodable = false,
drop = "lwcomponents:piston_sticky",
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
digiline = digilines_support (),
on_place = on_place,
on_receive_fields = on_receive_fields,
can_dig = can_dig,
after_place_node = after_place_node,
on_blast = on_blast,
on_rightclick = on_rightclick,
on_timer = on_timer
})
minetest.register_node("lwcomponents:piston_sticky_1", {
description = S("Sticky Piston"),
drawtype = "mesh",
mesh = "piston_sticky_1.obj",
tiles = { "lwcomponents_piston.png" },
visual_scale = 1.0,
selection_box = {
type = "fixed",
fixed = {
{-0.125, -0.125, -1.4, 0.125, 0.125, 0.4},
{-0.5, -0.5, -1.5, 0.5, 0.5, -1.3125},
{-0.5, -0.5, -0.3125, 0.5, 0.5, 0.5},
},
},
collision_box = {
type = "fixed",
fixed = {
{-0.125, -0.125, -1.4, 0.125, 0.125, 0.4},
{-0.5, -0.5, -1.5, 0.5, 0.5, -1.3125},
{-0.5, -0.5, -0.3125, 0.5, 0.5, 0.5},
},
},
is_ground_content = false,
groups = { cracky = 3 , not_in_creative_inventory = 1 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 0,
floodable = false,
drop = "lwcomponents:piston_sticky",
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
digiline = digilines_support (),
on_destruct = on_destruct_1,
on_receive_fields = on_receive_fields,
can_dig = can_dig,
after_place_node = after_place_node,
on_blast = on_blast,
on_rightclick = on_rightclick,
on_timer = on_timer
})
minetest.register_node("lwcomponents:piston_sticky_2", {
description = S("Sticky Piston"),
drawtype = "mesh",
mesh = "piston_sticky_2.obj",
tiles = { "lwcomponents_piston.png" },
visual_scale = 1.0,
selection_box = {
type = "fixed",
fixed = {
{-0.125, -0.125, -2.4, 0.125, 0.125, 0.4},
{-0.5, -0.5, -2.5, 0.5, 0.5, -2.3125},
{-0.5, -0.5, -0.3125, 0.5, 0.5, 0.5},
},
},
collision_box = {
type = "fixed",
fixed = {
{-0.125, -0.125, -2.4, 0.125, 0.125, 0.4},
{-0.5, -0.5, -2.5, 0.5, 0.5, -2.3125},
{-0.5, -0.5, -0.3125, 0.5, 0.5, 0.5},
},
},
is_ground_content = false,
groups = { cracky = 3 , not_in_creative_inventory = 1 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 0,
floodable = false,
drop = "lwcomponents:piston_sticky",
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
digiline = digilines_support (),
on_destruct = on_destruct_2,
on_receive_fields = on_receive_fields,
can_dig = can_dig,
after_place_node = after_place_node,
on_blast = on_blast,
on_rightclick = on_rightclick,
on_timer = on_timer
})
end -- utils.digilines_supported or utils.mesecon_supported

View File

@@ -95,6 +95,7 @@ minetest.register_node ("lwcomponents:player_button", {
"lwplayer_button_side.png", "lwplayer_button_side.png",
"lwplayer_button.png" "lwplayer_button.png"
}, },
use_texture_alpha = "clip",
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
legacy_wallmounted = true, legacy_wallmounted = true,
@@ -143,6 +144,7 @@ minetest.register_node ("lwcomponents:player_button_off", {
"lwplayer_button_side.png", "lwplayer_button_side.png",
"lwplayer_button.png" "lwplayer_button.png"
}, },
use_texture_alpha = "clip",
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
legacy_wallmounted = true, legacy_wallmounted = true,
@@ -192,6 +194,7 @@ minetest.register_node ("lwcomponents:player_button_on", {
"lwplayer_button_side.png", "lwplayer_button_side.png",
"lwplayer_button_on.png" "lwplayer_button_on.png"
}, },
use_texture_alpha = "clip",
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
legacy_wallmounted = true, legacy_wallmounted = true,

View File

@@ -13,7 +13,7 @@ CC BY-SA 3.0
Version Version
======= =======
0.1.10 0.1.15
Minetest Version Minetest Version
@@ -28,7 +28,6 @@ default
Optional Dependencies Optional Dependencies
===================== =====================
lwdrops
mesecons mesecons
digilines digilines
unifieddyes unifieddyes
@@ -63,7 +62,8 @@ Various components for mesecons and digilines.
* Hologram, projects a hologram above the hologram node. * Hologram, projects a hologram above the hologram node.
* Fan, blows any entity, player or drop in front of the fan. * Fan, blows any entity, player or drop in front of the fan.
* Conduit, connected in a circuit to move items. * Conduit, connected in a circuit to move items.
* Cannon, shoots an item on command with directional aiming. * Cannon, shoots an item on command with directional aiming (plus 3 shells).
* Double (optionally single) reach pistons and sticky pistons.
* Digiswitch, digilines controlled mesecons power. * Digiswitch, digilines controlled mesecons power.
* Movefloor, similar to vertical mesecons movestone. * Movefloor, similar to vertical mesecons movestone.
* Solid color conductor blocks, same as Solid Color Block but also mesecons * Solid color conductor blocks, same as Solid Color Block but also mesecons
@@ -93,6 +93,9 @@ Alert handler errors
Issue errors when handler's of other mods fail. Issue errors when handler's of other mods fail.
Default: true Default: true
Maximum piston nodes
Maximum nodes a piston can push.
Default: 15
------------------------------------------------------------------------ ------------------------------------------------------------------------

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View File

@@ -9,6 +9,9 @@ utils.settings.spawn_mobs =
utils.settings.alert_handler_errors = utils.settings.alert_handler_errors =
minetest.settings:get_bool ("lwcomponents_alert_handler_errors", true) minetest.settings:get_bool ("lwcomponents_alert_handler_errors", true)
utils.settings.max_piston_nodes =
tonumber(minetest.settings:get("lwcomponents_max_piston_nodes") or 15)
-- --

View File

@@ -3,3 +3,6 @@ lwcomponents_spawn_mobs (Spawn mobs) bool true
# Issue errors when handler's of other mods fail. # Issue errors when handler's of other mods fail.
lwcomponents_alert_handler_errors (Alert handler errors) bool true lwcomponents_alert_handler_errors (Alert handler errors) bool true
# Maximum nodes a piston can push.
lwcomponents_max_piston_nodes (Maximum piston nodes) int 15

BIN
sounds/lwpiston_extend.ogg Normal file

Binary file not shown.

BIN
sounds/lwpiston_retract.ogg Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
textures/lwcannon_shell.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 723 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 873 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 857 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 719 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 698 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 864 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

View File

@@ -67,43 +67,6 @@ end
-- check for lwdrops
if minetest.global_exists ("lwdrops") then
utils.lwdrops_supported = true
utils.on_destroy = lwdrops.on_destroy
utils.item_pickup = lwdrops.item_pickup
utils.item_drop = lwdrops.item_drop
else
utils.lwdrops_supported = false
-- dummy
utils.on_destroy = function (itemstack)
end
utils.item_pickup = function (entity, cleanup)
local stack = nil
if entity and entity.name and entity.name == "__builtin:item" and
entity.itemstring and entity.itemstring ~= "" then
stack = ItemStack (entity.itemstring)
if cleanup ~= false then
entity.itemstring = ""
entity.object:remove ()
end
end
return stack
end
utils.item_drop = function (itemstack, dropper, pos)
return minetest.item_drop (itemstack, dropper, pos)
end
end
-- check for unifieddyes -- check for unifieddyes
if minetest.global_exists ("unifieddyes") then if minetest.global_exists ("unifieddyes") then
utils.unifieddyes_supported = true utils.unifieddyes_supported = true
@@ -138,6 +101,53 @@ end
function utils.on_destroy (itemstack)
local stack = ItemStack (itemstack)
if stack and stack:get_count () > 0 then
local def = utils.find_item_def (stack:get_name ())
if def and def.on_destroy then
def.on_destroy (stack)
end
end
end
function utils.item_pickup (entity, cleanup)
local stack = nil
if entity and entity.name and entity.name == "__builtin:item" and
entity.itemstring and entity.itemstring ~= "" then
stack = ItemStack (entity.itemstring)
if cleanup ~= false then
entity.itemstring = ""
entity.object:remove ()
end
end
return stack
end
function utils.item_drop (itemstack, dropper, pos)
if itemstack then
local def = utils.find_item_def (itemstack:get_name ())
if def and def.on_drop then
return def.on_drop (itemstack, dropper, pos)
end
end
return minetest.item_drop (itemstack, dropper, pos)
end
function utils.can_interact_with_node (pos, player) function utils.can_interact_with_node (pos, player)
if not player or not player:is_player () then if not player or not player:is_player () then
return false return false
@@ -321,7 +331,7 @@ function utils.is_creative (player)
if player and player:is_player () then if player and player:is_player () then
return minetest.is_creative_enabled (player:get_player_name ()) or return minetest.is_creative_enabled (player:get_player_name ()) or
minetest.check_player_privs (placer, "creative") minetest.check_player_privs (player, "creative")
end end
return false return false