spacecannon/util.lua

178 lines
4.1 KiB
Lua
Raw Normal View History

local has_digilines = minetest.get_modpath("digilines")
spacecannon.update_formspec_digilines = function(meta)
local channel = meta:get_string("channel") or ""
local formspec =
"formspec_version[4]" ..
"size[6,4;]" ..
-- Digiline channel
"field[0.5,0.5;3.5,1;digiline_channel;Digiline Channel;" ..
channel .. "]" ..
"button_exit[4.5,0.5;1,1;set_digiline_channel;Set]" ..
-- Manual "fire" button
"button_exit[0.5,2.5;5,1;fire;Fire]"
meta:set_string("formspec", formspec)
end
2018-04-24 09:37:53 +02:00
2018-04-24 11:24:41 +02:00
spacecannon.update_formspec = function(meta)
if has_digilines then
spacecannon.update_formspec_digilines(meta)
else
meta:set_string("formspec", "size[8,2;]" ..
"button_exit[0,1;8,1;fire;Fire]")
end
2018-04-24 11:24:41 +02:00
end
2021-01-10 19:34:08 +01:00
spacecannon.can_shoot = function()
-- arguments: pos
2019-07-29 11:10:24 +02:00
return true
end
2018-11-16 08:05:42 +01:00
2021-01-10 19:34:08 +01:00
spacecannon.can_destroy = function()
-- arguments: pos
2019-07-29 11:10:24 +02:00
return true
end
spacecannon.fire = function(pos, color, speed, range)
2018-11-16 08:05:42 +01:00
2019-07-29 11:10:24 +02:00
if not spacecannon.can_shoot(pos) then
return
2018-11-16 08:05:42 +01:00
end
2018-04-24 11:34:07 +02:00
-- check fuel/power
local meta = minetest.get_meta(pos)
if meta:get_int("powerstorage") < spacecannon.config.powerstorage * range then
2018-11-15 14:40:14 +01:00
-- not enough power
return
2018-04-24 11:34:07 +02:00
else
-- use power
meta:set_int("powerstorage", 0)
end
2018-11-16 08:43:37 +01:00
minetest.sound_play("spacecannon_shoot", {
pos = pos,
gain = 1.0,
max_hear_distance = 16
})
2018-04-24 11:34:07 +02:00
2018-04-24 11:24:41 +02:00
local node = minetest.get_node(pos)
local dir = spacecannon.facedir_to_down_dir(node.param2)
local obj = minetest.add_entity({x=pos.x+dir.x, y=pos.y+dir.y, z=pos.z+dir.z}, "spacecannon:energycube_" .. color)
obj:setvelocity({x=dir.x*speed, y=dir.y*speed, z=dir.z*speed})
end
2018-04-24 09:37:53 +02:00
-- destroy stuff in range
2018-11-15 14:15:10 +01:00
-- TODO: resilient material list
2019-07-29 13:13:46 +02:00
spacecannon.destroy = function(pos, range, intensity)
2019-07-29 11:10:24 +02:00
if not spacecannon.can_destroy(pos) then
return
end
2019-07-29 13:13:46 +02:00
local particle_texture = nil
2018-04-24 09:37:53 +02:00
for x=-range,range do
for y=-range,range do
for z=-range,range do
if x*x+y*y+z*z <= range * range + range then
local np={x=pos.x+x,y=pos.y+y,z=pos.z+z}
if minetest.is_protected(np, "") then
return -- fail fast
end
2018-11-15 14:40:14 +01:00
local n = minetest.get_node_or_nil(np)
if n and n.name ~= "air" then
2019-07-29 13:13:46 +02:00
local node_def = minetest.registered_nodes[n.name]
if node_def and node_def.tiles and node_def.tiles[1] then
particle_texture = node_def.tiles[1]
end
if node_def.on_blast then
-- custom on_blast
node_def.on_blast(np, intensity)
else
-- default behavior
2019-07-29 13:37:56 +02:00
local resilience = spacecannon.node_resilience[n.name] or 1
if resilience <= 1 or math.random(resilience) == resilience then
minetest.set_node(np, {name="air"})
local itemstacks = minetest.get_node_drops(n.name)
for _, itemname in ipairs(itemstacks) do
if math.random(5) == 5 then
-- chance drop
minetest.add_item(np, itemname)
end
2019-07-29 13:13:46 +02:00
end
2018-11-15 14:40:14 +01:00
end
end
2019-07-29 13:13:46 +02:00
2018-04-24 09:37:53 +02:00
end
end
end
end
end
local radius = range
-- https://github.com/minetest/minetest_game/blob/master/mods/tnt/init.lua
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 = radius * 3,
maxsize = radius * 5,
texture = "spacecannon_spark.png",
2018-04-24 13:42:55 +02:00
glow = 5
2018-04-24 09:37:53 +02:00
})
2019-07-29 13:13:46 +02:00
if particle_texture then
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 = radius * 3,
maxsize = radius * 5,
texture = particle_texture,
glow = 5
})
end
2018-04-24 09:37:53 +02:00
minetest.sound_play("tnt_explode", {pos = pos, gain = 1.5, max_hear_distance = math.min(radius * 20, 128)})
end
-- convert face dir to vector
spacecannon.facedir_to_down_dir = function(facing)
return (
{[0]={x=0, y=-1, z=0},
{x=0, y=0, z=-1},
{x=0, y=0, z=1},
{x=-1, y=0, z=0},
{x=1, y=0, z=0},
{x=0, y=1, z=0}})[math.floor(facing/4)]
2018-11-15 14:40:14 +01:00
end