Upload files to "/"
This commit is contained in:
parent
fa5c8d6faf
commit
52d49224b7
5 changed files with 2804 additions and 0 deletions
12
api.lua
Normal file
12
api.lua
Normal file
|
@ -0,0 +1,12 @@
|
|||
local utils = ...
|
||||
|
||||
|
||||
|
||||
-- function (spawn_pos, itemstack, owner, spawner_pos, spawner_dir, force)
|
||||
function lwcomponents.register_spawner (itemname, spawn_func)
|
||||
return utils.register_spawner (itemname, spawn_func)
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
891
breaker.lua
Normal file
891
breaker.lua
Normal file
|
@ -0,0 +1,891 @@
|
|||
local utils = ...
|
||||
local S = utils.S
|
||||
|
||||
|
||||
|
||||
if utils.digilines_supported or utils.mesecon_supported then
|
||||
|
||||
|
||||
|
||||
local break_interval = 1.0
|
||||
|
||||
|
||||
|
||||
local function get_breaker_side (pos, param2, side)
|
||||
local base
|
||||
|
||||
if side == "left" then
|
||||
base = { x = -1, y = pos.y, z = 0 }
|
||||
elseif side == "right" then
|
||||
base = { x = 1, y = pos.y, z = 0 }
|
||||
elseif side == "back" then
|
||||
base = { x = 0, y = pos.y, z = -1 }
|
||||
else -- "front"
|
||||
base = { x = 0, y = pos.y, z = 1 }
|
||||
end
|
||||
|
||||
if param2 == 3 then -- +x
|
||||
return { x = base.z + pos.x, y = base.y, z = (base.x * -1) + pos.z }
|
||||
elseif param2 == 0 then -- -z
|
||||
return { x = (base.x * -1) + pos.x, y = base.y, z = (base.z * -1) + pos.z }
|
||||
elseif param2 == 1 then -- -x
|
||||
return { x = (base.z * -1) + pos.x, y = base.y, z = base.x + pos.z }
|
||||
else -- param2 == 2 +z
|
||||
return { x = base.x + pos.x, y = base.y, z = base.z + pos.z }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function get_break_pos (pos, param2, range)
|
||||
local breakpos = { x = pos.x, y = pos.y, z = pos.z }
|
||||
|
||||
for i = 1, range do
|
||||
breakpos = get_breaker_side (breakpos, param2, "front")
|
||||
|
||||
if i < range then
|
||||
local node = minetest.get_node_or_nil (breakpos)
|
||||
|
||||
if not node or node.name ~= "air" then
|
||||
return nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return breakpos
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function send_break_message (pos, action, name, range)
|
||||
if utils.digilines_supported then
|
||||
local meta = minetest.get_meta (pos)
|
||||
|
||||
if meta then
|
||||
local channel = meta:get_string ("channel")
|
||||
|
||||
if channel:len () > 0 then
|
||||
utils.digilines_receptor_send (pos,
|
||||
utils.digilines_default_rules,
|
||||
channel,
|
||||
{ action = action,
|
||||
name = name,
|
||||
range = range })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function get_tool (pos)
|
||||
local meta = minetest.get_meta (pos)
|
||||
|
||||
if meta then
|
||||
local inv = meta:get_inventory ()
|
||||
|
||||
if inv then
|
||||
local stack = inv:get_stack ("tool", 1)
|
||||
|
||||
if stack and not stack:is_empty () then
|
||||
return stack
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function add_wear (pos, wear)
|
||||
if wear > 0 then
|
||||
local meta = minetest.get_meta (pos)
|
||||
|
||||
if meta then
|
||||
local inv = meta:get_inventory ()
|
||||
|
||||
if inv then
|
||||
local stack = inv:get_stack ("tool", 1)
|
||||
|
||||
if stack and not stack:is_empty () then
|
||||
local cur_wear = stack:get_wear ()
|
||||
|
||||
if (cur_wear + wear) >= 65535 then
|
||||
inv:set_stack ("tool", 1, nil)
|
||||
send_break_message (pos, "tool", stack:get_name ())
|
||||
else
|
||||
stack:set_wear (cur_wear + wear)
|
||||
inv:set_stack ("tool", 1, stack)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function can_break_node (pos, breakpos)
|
||||
local node = minetest.get_node (pos)
|
||||
|
||||
if node then
|
||||
local dig_node = minetest.get_node_or_nil (breakpos)
|
||||
|
||||
if dig_node and dig_node.name ~= "air" then
|
||||
local node_def = minetest.registered_nodes[dig_node.name]
|
||||
|
||||
if node_def then
|
||||
-- try tool first
|
||||
local tool = get_tool (pos)
|
||||
local dig_params
|
||||
|
||||
if tool then
|
||||
local tool_def = minetest.registered_items[tool:get_name ()]
|
||||
|
||||
if tool_def then
|
||||
dig_params =
|
||||
minetest.get_dig_params (node_def.groups,
|
||||
tool_def.tool_capabilities)
|
||||
|
||||
if dig_params.diggable then
|
||||
return true, tool:get_name (), dig_params.wear
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- then try hand
|
||||
dig_params =
|
||||
minetest.get_dig_params (node_def.groups,
|
||||
minetest.registered_items[""].tool_capabilities)
|
||||
|
||||
if dig_params.diggable then
|
||||
return true, nil, 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function dig_node (pos, toolname)
|
||||
local node = minetest.get_node_or_nil (pos)
|
||||
local dig = false
|
||||
local drops = nil
|
||||
|
||||
if toolname == true then
|
||||
dig = true
|
||||
toolname = nil
|
||||
end
|
||||
|
||||
if node and node.name ~= "air" and node.name ~= "ignore" 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
|
||||
|
||||
if def and def.sounds and def.sounds.dug then
|
||||
pcall (minetest.sound_play, def.sounds.dug, { pos = pos })
|
||||
end
|
||||
|
||||
minetest.remove_node (pos)
|
||||
end
|
||||
end
|
||||
|
||||
return drops
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function eject_item (pos, stack, eject_pos)
|
||||
if utils.pipeworks_supported then
|
||||
local node = utils.get_far_node (eject_pos)
|
||||
|
||||
if node and minetest.get_item_group (node.name, "tube") > 0 then
|
||||
local owner = nil
|
||||
local meta = minetest.get_meta (pos)
|
||||
|
||||
if meta then
|
||||
local o = meta:get_string ("owner")
|
||||
|
||||
if o ~= "" then
|
||||
owner = o
|
||||
end
|
||||
end
|
||||
|
||||
local vel = vector.subtract (eject_pos, pos)
|
||||
|
||||
pipeworks.tube_inject_item (pos, pos, vel, stack, owner)
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
utils.item_drop (stack, nil, eject_pos)
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function break_node (pos, range)
|
||||
local node = minetest.get_node_or_nil (pos)
|
||||
local meta = minetest.get_meta (pos)
|
||||
|
||||
if node then
|
||||
if meta and minetest.is_protected (pos, meta:get_string ("owner")) then
|
||||
return
|
||||
end
|
||||
|
||||
local breakpos = get_break_pos (pos, node.param2, range)
|
||||
|
||||
if breakpos then
|
||||
local diggable, toolname, wear = can_break_node (pos, breakpos)
|
||||
|
||||
if diggable then
|
||||
local breaknode = minetest.get_node_or_nil (breakpos)
|
||||
|
||||
if breaknode and breaknode.name ~= "air" then
|
||||
local drops = dig_node (breakpos, toolname)
|
||||
|
||||
if drops then
|
||||
local break_name = breaknode.name
|
||||
local eject_pos = get_breaker_side (pos, node.param2, "back")
|
||||
|
||||
for i = 1, #drops do
|
||||
eject_item (pos, drops[i], eject_pos)
|
||||
end
|
||||
|
||||
add_wear (pos, wear)
|
||||
send_break_message (pos, "break", break_name, range)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function breaker_off (pos)
|
||||
local node = minetest.get_node (pos)
|
||||
|
||||
if node then
|
||||
if node.name == "lwcomponents:breaker_on" then
|
||||
node.name = "lwcomponents:breaker"
|
||||
|
||||
minetest.get_node_timer (pos):stop ()
|
||||
minetest.swap_node (pos, node)
|
||||
|
||||
elseif node.name == "lwcomponents:breaker_locked_on" then
|
||||
node.name = "lwcomponents:breaker_locked"
|
||||
|
||||
minetest.get_node_timer (pos):stop ()
|
||||
minetest.swap_node (pos, node)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function breaker_on (pos, range)
|
||||
local node = minetest.get_node (pos)
|
||||
|
||||
range = tonumber (range) or 1
|
||||
|
||||
if node and range < 6 and range > 0 then
|
||||
if node.name == "lwcomponents:breaker" then
|
||||
node.name = "lwcomponents:breaker_on"
|
||||
|
||||
minetest.swap_node (pos, node)
|
||||
break_node (pos, range)
|
||||
minetest.get_node_timer (pos):start (break_interval)
|
||||
|
||||
elseif node.name == "lwcomponents:breaker_locked" then
|
||||
node.name = "lwcomponents:breaker_locked_on"
|
||||
|
||||
minetest.swap_node (pos, node)
|
||||
break_node (pos, range)
|
||||
minetest.get_node_timer (pos):start (break_interval)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function eject_tool (pos, side)
|
||||
local node = minetest.get_node (pos)
|
||||
local meta = minetest.get_meta (pos)
|
||||
|
||||
if meta and node then
|
||||
local inv = meta:get_inventory ()
|
||||
|
||||
if inv then
|
||||
local stack = inv:get_stack ("tool", 1)
|
||||
|
||||
if stack and not stack:is_empty () then
|
||||
utils.item_drop (stack, nil, get_breaker_side (pos, node.param2, side))
|
||||
inv:set_stack ("tool", 1, nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function after_place_base (pos, placer, itemstack, pointed_thing)
|
||||
local meta = minetest.get_meta (pos)
|
||||
local spec =
|
||||
"formspec_version[3]\n"..
|
||||
"size[11.75,10.75;true]\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"..
|
||||
"list[context;tool;5.0,2.75;1,1;]\n"..
|
||||
"list[current_player;main;1.0,5.0;8,4;]\n"..
|
||||
"listring[]"
|
||||
|
||||
meta:set_string ("inventory", "{ tool = { } }")
|
||||
meta:set_string ("formspec", spec)
|
||||
|
||||
local inv = meta:get_inventory ()
|
||||
|
||||
inv:set_size ("tool", 1)
|
||||
inv:set_width ("tool", 1)
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function after_place_node (pos, placer, itemstack, pointed_thing)
|
||||
after_place_base (pos, placer, itemstack, pointed_thing)
|
||||
utils.pipeworks_after_place (pos)
|
||||
|
||||
-- If return true no item is taken from itemstack
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
|
||||
after_place_base (pos, placer, itemstack, pointed_thing)
|
||||
|
||||
if placer and placer:is_player () then
|
||||
local meta = minetest.get_meta (pos)
|
||||
|
||||
meta:set_string ("owner", placer:get_player_name ())
|
||||
meta:set_string ("infotext", "Breaker (owned by "..placer:get_player_name ()..")")
|
||||
end
|
||||
|
||||
utils.pipeworks_after_place (pos)
|
||||
|
||||
-- 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
|
||||
|
||||
if fields.setchannel then
|
||||
local meta = minetest.get_meta (pos)
|
||||
|
||||
if meta then
|
||||
meta:set_string ("channel", fields.channel)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function can_dig (pos, player)
|
||||
if not utils.can_interact_with_node (pos, player) then
|
||||
return false
|
||||
end
|
||||
|
||||
local meta = minetest.get_meta (pos)
|
||||
|
||||
if meta then
|
||||
local inv = meta:get_inventory ()
|
||||
|
||||
if inv then
|
||||
if not inv:is_empty ("tool") then
|
||||
return false
|
||||
end
|
||||
end
|
||||
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_blast (pos, intensity)
|
||||
local meta = minetest.get_meta (pos)
|
||||
|
||||
if meta then
|
||||
if intensity >= 1.0 then
|
||||
local inv = meta:get_inventory ()
|
||||
|
||||
if inv then
|
||||
local slots = inv:get_size ("tool")
|
||||
|
||||
for slot = 1, slots do
|
||||
local stack = inv:get_stack ("tool", slot)
|
||||
|
||||
if stack and not stack:is_empty () then
|
||||
if math.floor (math.random (0, 5)) == 3 then
|
||||
utils.item_drop (stack, nil, pos)
|
||||
else
|
||||
utils.on_destroy (stack)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.remove_node (pos)
|
||||
|
||||
else -- intensity < 1.0
|
||||
local inv = meta:get_inventory ()
|
||||
|
||||
if inv then
|
||||
local slots = inv:get_size ("tool")
|
||||
|
||||
for slot = 1, slots do
|
||||
local stack = inv:get_stack ("tool", slot)
|
||||
|
||||
if stack and not stack:is_empty () then
|
||||
utils.item_drop (stack, nil, pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
utils.item_drop (stack, nil, pos)
|
||||
minetest.remove_node (pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function on_timer (pos, elapsed)
|
||||
breaker_off (pos)
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function allow_metadata_inventory_put (pos, listname, index, stack, player)
|
||||
if listname == "tool" then
|
||||
if stack and not stack:is_empty () then
|
||||
local def = utils.find_item_def (stack:get_name ())
|
||||
|
||||
if def and def.tool_capabilities then
|
||||
return 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return 0
|
||||
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 and
|
||||
type (msg) == "string" then
|
||||
|
||||
local m = { }
|
||||
for w in string.gmatch(msg, "[^%s]+") do
|
||||
m[#m + 1] = w
|
||||
end
|
||||
|
||||
if m[1] == "break" then
|
||||
breaker_on (pos, m[2])
|
||||
|
||||
elseif m[1] == "eject" then
|
||||
eject_tool (pos, m[2])
|
||||
|
||||
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
|
||||
breaker_on (pos, 1)
|
||||
end,
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function pipeworks_support ()
|
||||
if utils.pipeworks_supported then
|
||||
return
|
||||
{
|
||||
priority = 100,
|
||||
input_inventory = "tool",
|
||||
connect_sides = { left = 1, right = 1, back = 1, bottom = 1, top = 1 },
|
||||
|
||||
insert_object = function (pos, node, stack, direction)
|
||||
local meta = minetest.get_meta (pos)
|
||||
local inv = (meta and meta:get_inventory ()) or nil
|
||||
|
||||
if inv then
|
||||
return inv:add_item ("tool", stack)
|
||||
end
|
||||
|
||||
return stack
|
||||
end,
|
||||
|
||||
can_insert = function (pos, node, stack, direction)
|
||||
if stack and not stack:is_empty () then
|
||||
local def = utils.find_item_def (stack:get_name ())
|
||||
|
||||
if def and def.tool_capabilities then
|
||||
local meta = minetest.get_meta (pos)
|
||||
local inv = (meta and meta:get_inventory ()) or nil
|
||||
|
||||
if inv then
|
||||
return inv:room_for_item ("tool", stack)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end,
|
||||
|
||||
can_remove = function (pos, node, stack, dir)
|
||||
-- returns the maximum number of items of that stack that can be removed
|
||||
local meta = minetest.get_meta (pos)
|
||||
local inv = (meta and meta:get_inventory ()) or nil
|
||||
|
||||
if inv then
|
||||
local slots = inv:get_size ("tool")
|
||||
|
||||
for i = 1, slots, 1 do
|
||||
local s = inv:get_stack ("tool", i)
|
||||
|
||||
if s and not s:is_empty () and utils.is_same_item (stack, s) then
|
||||
return s:get_count ()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return 0
|
||||
end,
|
||||
|
||||
remove_items = function (pos, node, stack, dir, count)
|
||||
-- removes count items and returns them
|
||||
local meta = minetest.get_meta (pos)
|
||||
local inv = (meta and meta:get_inventory ()) or nil
|
||||
local left = count
|
||||
|
||||
if inv then
|
||||
local slots = inv:get_size ("tool")
|
||||
|
||||
for i = 1, slots, 1 do
|
||||
local s = inv:get_stack ("tool", i)
|
||||
|
||||
if s and not s:is_empty () and utils.is_same_item (s, stack) then
|
||||
if s:get_count () > left then
|
||||
s:set_count (s:get_count () - left)
|
||||
inv:set_stack ("tool", i, s)
|
||||
left = 0
|
||||
else
|
||||
left = left - s:get_count ()
|
||||
inv:set_stack ("tool", i, nil)
|
||||
end
|
||||
end
|
||||
|
||||
if left == 0 then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local result = ItemStack (stack)
|
||||
result:set_count (count - left)
|
||||
|
||||
return result
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
local breaker_groups = { cracky = 3, wires_connect = 1 }
|
||||
if utils.pipeworks_supported then
|
||||
breaker_groups.tubedevice = 1
|
||||
breaker_groups.tubedevice_receiver = 1
|
||||
end
|
||||
|
||||
|
||||
|
||||
local breaker_on_groups = { cracky = 3, not_in_creative_inventory = 1, wires_connect = 1 }
|
||||
if utils.pipeworks_supported then
|
||||
breaker_on_groups.tubedevice = 1
|
||||
breaker_on_groups.tubedevice_receiver = 1
|
||||
end
|
||||
|
||||
|
||||
|
||||
minetest.register_node("lwcomponents:breaker", {
|
||||
description = S("Breaker"),
|
||||
tiles = { "lwbreaker.png", "lwbreaker.png", "lwbreaker.png",
|
||||
"lwbreaker.png", "lwbreaker_rear.png", "lwbreaker_face.png"},
|
||||
is_ground_content = false,
|
||||
groups = table.copy (breaker_groups),
|
||||
--sounds = default.node_sound_stone_defaults (),
|
||||
paramtype = "none",
|
||||
param1 = 0,
|
||||
paramtype2 = "facedir",
|
||||
param2 = 1,
|
||||
floodable = false,
|
||||
drop = "lwcomponents:breaker",
|
||||
_digistuff_channelcopier_fieldname = "channel",
|
||||
|
||||
mesecons = mesecon_support (),
|
||||
digiline = digilines_support (),
|
||||
tube = pipeworks_support (),
|
||||
|
||||
on_receive_fields = on_receive_fields,
|
||||
can_dig = can_dig,
|
||||
after_dig_node = utils.pipeworks_after_dig,
|
||||
after_place_node = after_place_node,
|
||||
on_blast = on_blast,
|
||||
on_timer = on_timer,
|
||||
on_rightclick = on_rightclick,
|
||||
allow_metadata_inventory_put = allow_metadata_inventory_put
|
||||
})
|
||||
|
||||
|
||||
|
||||
minetest.register_node("lwcomponents:breaker_locked", {
|
||||
description = S("Breaker (locked)"),
|
||||
tiles = { "lwbreaker.png", "lwbreaker.png", "lwbreaker.png",
|
||||
"lwbreaker.png", "lwbreaker_rear.png", "lwbreaker_face.png"},
|
||||
is_ground_content = false,
|
||||
groups = table.copy (breaker_groups),
|
||||
--sounds = default.node_sound_stone_defaults (),
|
||||
paramtype = "none",
|
||||
param1 = 0,
|
||||
paramtype2 = "facedir",
|
||||
param2 = 1,
|
||||
floodable = false,
|
||||
drop = "lwcomponents:breaker_locked",
|
||||
_digistuff_channelcopier_fieldname = "channel",
|
||||
|
||||
mesecons = mesecon_support (),
|
||||
digiline = digilines_support (),
|
||||
tube = pipeworks_support (),
|
||||
|
||||
on_receive_fields = on_receive_fields,
|
||||
can_dig = can_dig,
|
||||
after_dig_node = utils.pipeworks_after_dig,
|
||||
after_place_node = after_place_node_locked,
|
||||
on_blast = on_blast,
|
||||
on_timer = on_timer,
|
||||
on_rightclick = on_rightclick,
|
||||
allow_metadata_inventory_put = allow_metadata_inventory_put
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
minetest.register_node("lwcomponents:breaker_on", {
|
||||
description = S("Breaker"),
|
||||
tiles = { "lwbreaker.png", "lwbreaker.png", "lwbreaker.png",
|
||||
"lwbreaker.png", "lwbreaker_rear.png", "lwbreaker_face_on.png"},
|
||||
is_ground_content = false,
|
||||
groups = table.copy (breaker_on_groups),
|
||||
--sounds = default.node_sound_stone_defaults (),
|
||||
paramtype = "none",
|
||||
param1 = 0,
|
||||
paramtype2 = "facedir",
|
||||
param2 = 1,
|
||||
light_source = 3,
|
||||
floodable = false,
|
||||
drop = "lwcomponents:breaker",
|
||||
_digistuff_channelcopier_fieldname = "channel",
|
||||
|
||||
mesecons = mesecon_support (),
|
||||
digiline = digilines_support (),
|
||||
tube = pipeworks_support (),
|
||||
|
||||
on_receive_fields = on_receive_fields,
|
||||
can_dig = can_dig,
|
||||
after_dig_node = utils.pipeworks_after_dig,
|
||||
after_place_node = after_place_node,
|
||||
on_blast = on_blast,
|
||||
on_timer = on_timer,
|
||||
on_rightclick = on_rightclick,
|
||||
allow_metadata_inventory_put = allow_metadata_inventory_put
|
||||
})
|
||||
|
||||
|
||||
|
||||
minetest.register_node("lwcomponents:breaker_locked_on", {
|
||||
description = S("Breaker (locked)"),
|
||||
tiles = { "lwbreaker.png", "lwbreaker.png", "lwbreaker.png",
|
||||
"lwbreaker.png", "lwbreaker_rear.png", "lwbreaker_face_on.png"},
|
||||
is_ground_content = false,
|
||||
groups = table.copy (breaker_on_groups),
|
||||
--sounds = default.node_sound_stone_defaults (),
|
||||
paramtype = "none",
|
||||
param1 = 0,
|
||||
paramtype2 = "facedir",
|
||||
param2 = 1,
|
||||
light_source = 3,
|
||||
floodable = false,
|
||||
drop = "lwcomponents:breaker_locked",
|
||||
_digistuff_channelcopier_fieldname = "channel",
|
||||
|
||||
mesecons = mesecon_support (),
|
||||
digiline = digilines_support (),
|
||||
tube = pipeworks_support (),
|
||||
|
||||
on_receive_fields = on_receive_fields,
|
||||
can_dig = can_dig,
|
||||
after_dig_node = utils.pipeworks_after_dig,
|
||||
after_place_node = after_place_node_locked,
|
||||
on_blast = on_blast,
|
||||
on_timer = on_timer,
|
||||
on_rightclick = on_rightclick,
|
||||
allow_metadata_inventory_put = allow_metadata_inventory_put
|
||||
})
|
||||
|
||||
|
||||
|
||||
utils.hopper_add_container({
|
||||
{"bottom", "lwcomponents:breaker", "tool"}, -- insert items below from hopper above
|
||||
{"side", "lwcomponents:breaker", "tool"}, -- insert items from hopper at side
|
||||
})
|
||||
|
||||
|
||||
|
||||
utils.hopper_add_container({
|
||||
{"bottom", "lwcomponents:breaker_locked", "tool"}, -- insert items below from hopper above
|
||||
{"side", "lwcomponents:breaker_locked", "tool"}, -- insert items from hopper at side
|
||||
})
|
||||
|
||||
|
||||
|
||||
utils.hopper_add_container({
|
||||
{"bottom", "lwcomponents:breaker_on", "tool"}, -- insert items below from hopper above
|
||||
{"side", "lwcomponents:breaker_on", "tool"}, -- insert items from hopper at side
|
||||
})
|
||||
|
||||
|
||||
|
||||
utils.hopper_add_container({
|
||||
{"bottom", "lwcomponents:breaker_locked_on", "tool"}, -- insert items below from hopper above
|
||||
{"side", "lwcomponents:breaker_locked_on", "tool"}, -- insert items from hopper at side
|
||||
})
|
||||
|
||||
|
||||
|
||||
end -- utils.digilines_supported or utils.mesecon_supported
|
439
camera.lua
Normal file
439
camera.lua
Normal file
|
@ -0,0 +1,439 @@
|
|||
local utils = ...
|
||||
local S = utils.S
|
||||
|
||||
|
||||
|
||||
if utils.digilines_supported then
|
||||
|
||||
|
||||
|
||||
local function get_entity_dims (obj)
|
||||
local dims = { -0.5, 0, -0.5, 0.5, 2, 0.5 }
|
||||
local found = false
|
||||
|
||||
if obj.get_luaentity then
|
||||
local entity = obj:get_luaentity ()
|
||||
|
||||
if entity and entity.name then
|
||||
local def = minetest.registered_entities[entity.name]
|
||||
|
||||
if def and type (def.collisionbox) == "table" then
|
||||
|
||||
dims = { def.collisionbox[1] or -0.5,
|
||||
def.collisionbox[2] or -0.5,
|
||||
def.collisionbox[3] or -0.5,
|
||||
def.collisionbox[4] or 0.5,
|
||||
def.collisionbox[5] or 0.5,
|
||||
def.collisionbox[6] or 0.5 }
|
||||
|
||||
found = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not found then
|
||||
local props = obj:get_properties ()
|
||||
if props and props.collisionbox and type (props.collisionbox) == "table" then
|
||||
|
||||
dims = { props.collisionbox[1] or -0.5,
|
||||
props.collisionbox[2] or -0.5,
|
||||
props.collisionbox[3] or -0.5,
|
||||
props.collisionbox[4] or 0.5,
|
||||
props.collisionbox[5] or 0.5,
|
||||
props.collisionbox[6] or 0.5 }
|
||||
end
|
||||
end
|
||||
|
||||
dims[1] = math.min (dims[1], dims[3])
|
||||
dims[3] = dims[1]
|
||||
dims[4] = math.max (dims[4], dims[6])
|
||||
dims[6] = dims[4]
|
||||
|
||||
if (dims[3] - dims[1]) < 1 then
|
||||
dims[1] = -0.5
|
||||
dims[3] = -0.5
|
||||
dims[4] = 0.5
|
||||
dims[6] = 0.5
|
||||
end
|
||||
|
||||
return dims
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function get_entity (pos)
|
||||
local objects = minetest.get_objects_inside_radius (pos, 2.0)
|
||||
|
||||
if #objects > 0 then
|
||||
for _, obj in ipairs (objects) do
|
||||
if obj.get_pos then
|
||||
if obj:is_player () then
|
||||
local epos = vector.round (obj:get_pos ())
|
||||
|
||||
if epos.x == pos.x and epos.z == pos.z and
|
||||
(epos.y == pos.y or epos.y == pos.y - 1) then
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
if not utils.is_drop (obj) then
|
||||
local epos = vector.new (obj:get_pos ())
|
||||
local dims = get_entity_dims (obj)
|
||||
|
||||
if pos.x >= (epos.x + dims[1]) and pos.x <= (epos.x + dims[4]) and
|
||||
pos.y >= (epos.y + dims[2]) and pos.y <= (epos.y + dims[5]) and
|
||||
pos.z >= (epos.z + dims[3]) and pos.z <= (epos.z + dims[6]) then
|
||||
return 2
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function camera_scan (pos, resolution, distance)
|
||||
local node = utils.get_far_node (pos)
|
||||
local image = { }
|
||||
|
||||
for y = 1, resolution, 1 do
|
||||
image[y] = { }
|
||||
|
||||
for x = 1, resolution, 1 do
|
||||
image[y][x] = "000000"
|
||||
end
|
||||
end
|
||||
|
||||
if node then
|
||||
local dir = vector.multiply (minetest.facedir_to_dir (node.param2), -1)
|
||||
local last_pos = nil
|
||||
local last_color = "000000"
|
||||
local view = (distance * 1.414213562) / resolution
|
||||
|
||||
for dist = distance, 1, -1 do
|
||||
local scale = dist / distance
|
||||
|
||||
for y = 1, resolution, 1 do
|
||||
for x = 1, resolution, 1 do
|
||||
local horz = (x - (resolution / 2)) * scale * view
|
||||
local vert = (y - (resolution / 2)) * scale * view
|
||||
|
||||
local tpos
|
||||
if dir.x ~= 0 then
|
||||
tpos = vector.round ({ x = (dist * dir.x) + pos.x, y = pos.y - vert, z = horz + pos.z })
|
||||
else
|
||||
tpos = vector.round ({ x = horz + pos.x, y = pos.y - vert, z = (dist * dir.z) + pos.z })
|
||||
end
|
||||
|
||||
if last_pos and vector.equals (last_pos, tpos) then
|
||||
if last_color then
|
||||
image[y][x] = last_color
|
||||
end
|
||||
else
|
||||
local entity = get_entity (tpos)
|
||||
|
||||
if entity == 1 then
|
||||
local color = (((distance - dist) / distance) * 98) + 30
|
||||
|
||||
last_color = string.format ("00%02X00", color)
|
||||
image[y][x] = last_color
|
||||
elseif entity == 2 then
|
||||
local color = (((distance - dist) / distance) * 98) + 30
|
||||
|
||||
last_color = string.format ("0000%02X", color)
|
||||
image[y][x] = last_color
|
||||
else
|
||||
local tnode = utils.get_far_node (tpos)
|
||||
|
||||
if tnode and tnode.name ~= "air" then
|
||||
local color = (((distance - dist) / distance) * 98) + 30
|
||||
|
||||
last_color = string.format ("%02X%02X%02X", color, color, color)
|
||||
image[y][x] = last_color
|
||||
else
|
||||
last_color = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
last_pos = tpos
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return image
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function send_scan (pos)
|
||||
local meta = minetest.get_meta (pos)
|
||||
|
||||
if meta then
|
||||
local channel = meta:get_string ("channel")
|
||||
|
||||
if channel:len () > 0 then
|
||||
local image = camera_scan (pos,
|
||||
tonumber (meta:get_string ("resolution")),
|
||||
tonumber (meta:get_string ("distance")))
|
||||
|
||||
utils.digilines_receptor_send (pos,
|
||||
utils.digilines_default_rules,
|
||||
channel,
|
||||
image)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function after_place_node (pos, placer, itemstack, pointed_thing)
|
||||
local meta = minetest.get_meta (pos)
|
||||
local spec =
|
||||
"formspec_version[3]"..
|
||||
"size[8.5,5.5;true]"..
|
||||
"field[1.0,1.0;4.0,0.8;channel;Channel;${channel}]"..
|
||||
"button[5.5,1.0;2.0,0.8;setchannel;Set]"..
|
||||
"field[1.0,2.5;4.0,0.8;distance;Distance;${distance}]"..
|
||||
"button[5.5,2.5;2.0,0.8;setdistance;Set]"..
|
||||
"field[1.0,4.0;4.0,0.8;resolution;Resolution;${resolution}]"..
|
||||
"button[5.5,4.0;2.0,0.8;setresolution;Set]"
|
||||
|
||||
meta:set_string ("formspec", spec)
|
||||
meta:set_string ("distance", "5")
|
||||
meta:set_string ("resolution", "16")
|
||||
|
||||
-- If return true no item is taken from itemstack
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
|
||||
after_place_node (pos, placer, itemstack, pointed_thing)
|
||||
|
||||
if placer and placer:is_player () then
|
||||
local meta = minetest.get_meta (pos)
|
||||
|
||||
meta:set_string ("owner", placer:get_player_name ())
|
||||
meta:set_string ("infotext", "Camera (owned by "..placer:get_player_name ()..")")
|
||||
end
|
||||
|
||||
-- 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
|
||||
|
||||
if fields.setchannel then
|
||||
local meta = minetest.get_meta (pos)
|
||||
|
||||
if meta then
|
||||
meta:set_string ("channel", fields.channel)
|
||||
end
|
||||
end
|
||||
|
||||
if fields.setdistance then
|
||||
local meta = minetest.get_meta (pos)
|
||||
|
||||
if meta then
|
||||
local distance = math.min (math.max (tonumber (fields.distance) or 1, 1), 16)
|
||||
fields.distance = tostring (distance)
|
||||
|
||||
meta:set_string ("distance", tostring (distance))
|
||||
end
|
||||
end
|
||||
|
||||
if fields.setresolution then
|
||||
local meta = minetest.get_meta (pos)
|
||||
|
||||
if meta then
|
||||
local resolution = math.min (math.max (tonumber (fields.resolution) or 1, 1), 128)
|
||||
fields.resolution = tostring (resolution)
|
||||
|
||||
meta:set_string ("resolution", tostring (resolution))
|
||||
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_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
|
||||
utils.item_drop (stack, nil, pos)
|
||||
minetest.remove_node (pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
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 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 and
|
||||
type (msg) == "string" then
|
||||
|
||||
local m = { }
|
||||
for w in string.gmatch(msg, "[^%s]+") do
|
||||
m[#m + 1] = w
|
||||
end
|
||||
|
||||
if m[1] == "scan" then
|
||||
send_scan (pos)
|
||||
|
||||
elseif m[1] == "distance" then
|
||||
local distance = math.min (math.max (tonumber (m[2] or 5) or 5, 1), 16)
|
||||
meta:set_string ("distance", tostring (distance))
|
||||
|
||||
elseif m[1] == "resolution" then
|
||||
local resolution = math.min (math.max (tonumber (m[2] or 16) or 16, 1), 128)
|
||||
meta:set_string ("resolution", tostring (resolution))
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
minetest.register_node("lwcomponents:camera", {
|
||||
description = S("Camera"),
|
||||
tiles = { "lwcamera.png", "lwcamera.png", "lwcamera.png",
|
||||
"lwcamera.png", "lwcamera.png", "lwcamera_lens.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:camera",
|
||||
_digistuff_channelcopier_fieldname = "channel",
|
||||
|
||||
digiline = digilines_support (),
|
||||
|
||||
on_receive_fields = on_receive_fields,
|
||||
can_dig = can_dig,
|
||||
after_place_node = after_place_node,
|
||||
on_blast = on_blast,
|
||||
on_rightclick = on_rightclick
|
||||
})
|
||||
|
||||
|
||||
|
||||
minetest.register_node("lwcomponents:camera_locked", {
|
||||
description = S("Camera (locked)"),
|
||||
tiles = { "lwcamera.png", "lwcamera.png", "lwcamera.png",
|
||||
"lwcamera.png", "lwcamera.png", "lwcamera_lens.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:camera_locked",
|
||||
_digistuff_channelcopier_fieldname = "channel",
|
||||
|
||||
digiline = digilines_support (),
|
||||
|
||||
on_receive_fields = on_receive_fields,
|
||||
can_dig = can_dig,
|
||||
after_place_node = after_place_node_locked,
|
||||
on_blast = on_blast,
|
||||
on_rightclick = on_rightclick
|
||||
})
|
||||
|
||||
|
||||
|
||||
end -- utils.digilines_supported
|
||||
|
||||
|
||||
|
||||
--
|
1165
cannon.lua
Normal file
1165
cannon.lua
Normal file
File diff suppressed because it is too large
Load diff
297
cannon_shell.lua
Normal file
297
cannon_shell.lua
Normal file
|
@ -0,0 +1,297 @@
|
|||
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
|
||||
local c_name = (c.object.get_luaentity and
|
||||
c.object:get_luaentity () and
|
||||
c.object:get_luaentity ().name) or ""
|
||||
local s_name = (self.name) or ""
|
||||
|
||||
-- explode at this pos
|
||||
if c.object:get_armor_groups ().immortal or s_name == c_name 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_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
|
||||
|
||||
|
||||
|
||||
--
|
Loading…
Add table
Add a link
Reference in a new issue