cannons/functions.lua
2013-12-05 02:24:34 +01:00

389 lines
11 KiB
Lua

function cannons.destroy(pos,range)
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}
local n = minetest.env:get_node(np)
if n.name ~= "air" then
minetest.env:remove_node(np)
end
end
end
end
end
end
function cannons.sound_defaults(table)
table = table or {}
table.footstep = table.footstep or
{name="cannons_walk", gain=1.0}
table.dig = table.dig or
{name="cannons_dig", gain=0.5}
table.dug = table.dug or
{name="default_dug_node", gain=0.5}
table.place = table.place or
{name="default_place_node_hard", gain=1.0}
return table
end
function cannons.inventory_modified(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack("muni", 1)
local muni = stack:to_table()
local addition = ""
if meta:get_string("owner") ~="" then
addition = " (owned by "..meta:get_string("owner")..")"
end
if muni == nil then
muni = false
else
muni = cannons.is_muni(muni.name)
end
local gunpowder = inv:contains_item("gunpowder","cannons:gunpowder 1")
if not muni and not gunpowder then
meta:set_string("infotext","Cannon has no muni and no gunpowder"..addition)
elseif not muni then
meta:set_string("infotext","Cannon has no muni"..addition)
elseif not gunpowder then
meta:set_string("infotext","Cannon has no gunpowder"..addition)
else
meta:set_string("infotext","Cannon is ready"..addition)
end
end
cannons.allow_metadata_inventory_put = function(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos)
if(meta:get_string("owner") ~="" and not( locks:lock_allow_use( pos, player ))) then
return 0;
end
local inv = meta:get_inventory()
stack = stack:to_table()
if listname == "gunpowder" and stack.name == "cannons:gunpowder" then
return stack.count
elseif listname == "muni" and cannons.is_muni(stack.name) then
return stack.count
else return 0
end
end
cannons.allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
local meta = minetest.get_meta(pos)
if(meta:get_string("owner") ~="" and not( locks:lock_allow_use( pos, player ))) then
return 0;
end
local inv = meta:get_inventory()
local stack = inv:get_stack(from_list, from_index)
stack = stack:to_table()
if to_list == "gunpowder" and stack.name == "cannons:gunpowder" then
return count
elseif to_list == "muni" and cannons.is_muni(stack.name) then
return count
else
return 0
end
end
cannons.can_dig = function(pos,player)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
if not inv:is_empty("gunpowder") then
return false
elseif not inv:is_empty("muni") then
return false
else
return true
end
end
cannons.formspec =
"size[8,9]"..
"list[current_name;muni;0,1;1,1;] label[0,0.5;Muni:]"..
"list[current_name;gunpowder;0,3;1,1;] label[0,2.5;Gunpowder:]"..
"list[current_player;main;0,5;8,4;]"
cannons.disabled_formspec =
"size[8,9]"..
"label[2,0.5;Cannon is Disabled. Place it on a cannonstand to activate it]"..
"list[current_player;main;0,5;8,4;]"
cannons.on_construct = function(pos)
local node = minetest.get_node({x = pos.x ,y = pos.y-1, z = pos.z})
if minetest.registered_nodes[node.name].groups.cannonstand then
local meta = minetest.get_meta(pos)
meta:set_string("formspec", cannons.formspec)
meta:set_string("infotext", "Cannon has no muni and no gunpowder")
local inv = meta:get_inventory()
inv:set_size("gunpowder", 1)
inv:set_size("muni", 1)
else
local meta = minetest.get_meta(pos)
meta:set_string("formspec", cannons.disabled_formspec)
meta:set_string("infotext", "Cannon is out of order")
end
end
cannons.on_construct_locks = function(pos)
local node = minetest.get_node({x = pos.x ,y = pos.y-1, z = pos.z})
if minetest.registered_nodes[node.name].groups.cannonstand then
local meta = minetest.get_meta(pos)
meta:set_string("formspec", cannons.formspec..
"field[2,1.3;6,0.7;locks_sent_lock_command;Locked Cannon. Type /help for help:;]"..
"button[6,2;1.7,0.7;locks_sent_input;Proceed]")
meta:set_string("infotext", "Cannon has no muni and no gunpowder")
local inv = meta:get_inventory()
inv:set_size("gunpowder", 1)
inv:set_size("muni", 1)
else
local meta = minetest.get_meta(pos)
meta:set_string("formspec", cannons.disabled_formspec)
meta:set_string("infotext", "Cannon is out of order")
end
end
function cannons.nodehitparticles(pos,node)
if type(minetest.registered_nodes[node.name]) == "table" and type(minetest.registered_nodes[node.name].tiles) == "table" and type(minetest.registered_nodes[node.name].tiles[1])== "string" then
local texture = minetest.registered_nodes[node.name].tiles[1]
minetest.add_particlespawner(
30, --amount
0.5, --time
{x=pos.x-0.3, y=pos.y+0.3, z=pos.z-0.3}, --minpos
{x=pos.x+0.3, y=pos.y+0.5, z=pos.z+0.3}, --maxpos
{x=0, y=2, z=0}, --minvel
{x=0, y=3, z=0}, --maxvel
{x=-4,y=-4,z=-4}, --minacc
{x=4,y=-4,z=4}, --maxacc
0.1, --minexptime
1, --maxexptime
1, --minsize
3, --maxsize
false, --collisiondetection
texture --texture
)
end
end
function cannons.fire(pos,node,puncher)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack("muni", 1)
local muni = stack:to_table()
if inv:contains_item("gunpowder","cannons:gunpowder 1")
and muni ~= nil
and cannons.is_muni(muni.name)
and inv:contains_item("muni",muni.name.." 1")
then
if puncher ~= nil then
dir=puncher:get_look_dir()
meta:set_string("dir", minetest.serialize(dir))
else
dir = {}
dir = minetest.deserialize(meta:get_string("dir"));
if dir == nil then
return
end
end
minetest.sound_play("cannons_shot",
{pos = pos, gain = 1.0, max_hear_distance = 32,})
inv:remove_item("muni", muni.name.." 1")
inv:remove_item("gunpowder", "cannons:gunpowder 1")
cannons.inventory_modified(pos)
local settings = cannons.get_settings(muni.name)
local obj=minetest.env:add_entity(pos, cannons.get_entity(muni.name))
obj:setvelocity({x=dir.x*settings.velocity, y=-1, z=dir.z*settings.velocity})
obj:setacceleration({x=dir.x*-3, y=-settings.gravity, z=dir.z*-3})
minetest.add_particlespawner(50,0.5,
pos, pos,
{x=dir.x*settings.velocity, y=-1, z=dir.z*settings.velocity}, {x=dir.x*settings.velocity/2, y=-1, z=dir.z*settings.velocity/2},
{x=dir.x*-3/4, y=-settings.gravity*2, z=dir.z*-3/4}, {x=dir.x*-3/2, y=-settings.gravity, z=dir.z*-3/2},
0.1, 0.5,--time
0.5, 1,
false, "cannons_gunpowder.png")
end
end
function cannons.punched(pos, node, puncher)
if not puncher or not node then
return
end
local wield = puncher:get_wielded_item()
if not wield then
return
end
wield = wield:get_name()
if wield and wield == 'default:torch' then
cannons.fire(pos,node,puncher)
end
end
--++++++++++++++++++++++++++++++++++++
--+ cannons.register_muni +
--++++++++++++++++++++++++++++++++++++
cannons.registered_muni = {}
function cannons.register_muni(node,entity)
cannons.registered_muni[node] = {}
cannons.registered_muni[node].entity = entity
local name = node:split(":")
cannons.registered_muni[node].entity.name ="cannons:entity_"..name[1].."_"..name[2]
cannons.registered_muni[node].entity.on_step = function(self, dtime)
self.timer=self.timer+dtime
if self.timer >= 0.3 then --easiesst less laggiest way to find out that it left his start position
local pos = self.object:getpos()
local node = minetest.env:get_node(pos)
if node.name == "air" then
local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, self.range)
for k, obj in pairs(objs) do
if obj:get_luaentity() ~= nil then
if obj:get_luaentity().name ~= self.name and obj:get_luaentity().name ~= "__builtin:item" then --something other found
local mob = obj
self.on_mob_hit(self,pos,mob)
end
elseif obj:is_player() then --player found
local player = obj
self.on_player_hit(self,pos,player)
end
end
elseif node.name ~=air then
self.on_node_hit(self,pos,node)
end
self.lastpos={x=pos.x, y=pos.y, z=pos.z}
end
end
cannons.registered_muni[node].obj = entity.name
minetest.register_entity(entity.name, cannons.registered_muni[node].entity)
end
function cannons.is_muni(node)
return cannons.registered_muni[node] ~= nil
end
function cannons.get_entity(node)
return cannons.registered_muni[node].obj
end
function cannons.get_settings(node)
return cannons.registered_muni[node].entity
end
--++++++++++++++++++++++++++++++++++++
--+ mesecons stuff +
--++++++++++++++++++++++++++++++++++++
cannons.rules ={
{x = 1, y = 0, z = 0},
{x =-1, y = 0, z = 0},
{x = 0, y = 0, z = 1},
{x = 0, y = 0, z =-1}
}
function cannons.meseconsfire(pos,node)
cannons.fire(pos,node)
end
cannons.supportMesecons = {
effector = {
rules = cannons.rules,
action_on = cannons.meseconsfire,
}
}
--++++++++++++++++++++++++++++++++++++
--+ cannons.nodeboxes +
--++++++++++++++++++++++++++++++++++++
cannons.nodeboxes = {}
cannons.nodeboxes.ball = {
type = "fixed",
fixed = {
{-0.2, -0.5, -0.2, 0.2, -0.1, 0.2},
-- side , top , side , side , bottom, side,
},
}
cannons.nodeboxes.ball_stack = {
type = "fixed",
fixed = {
{-0.2, -0.1, -0.2, 0.2, 0.3, 0.2}, -- ball top
{0.1, -0.5, -0.2, 0.2, -0.1, 0.2}, -- ball left
{0.5, -0.5, -0.2, 0.2, -0.1, 0.2}, -- ball left
{-0.2, -0.5, 0.5, 0.0, -0.1, 0.2},-- ball back
{0.0, -0.5, 0.1, -0.4, -0.1, 0.2},--ball back
{-0.2, -0.5, 0.5, -0.4, -0.1, 0.2},-- ball back
{-0.2, -0.5, 0.1, -0.4, -0.1, 0.2},-- ball back
{-0.2, -0.5, -0.1, -0.4, -0.1, -0.5},
{0.0, -0.5, -0.1, -0.4, -0.1, -0.5},
-- side , top , side , side , bottom, side,
},
}
cannons.nodeboxes.cannon = {
type = "fixed",
fixed = {
{-0.2, 0.2, -0.7, 0.2, -0.2, 0.9}, -- barrle --
{0.53, -0.1, 0.1, -0.53, 0.1, -0.1}, -- plinth --
-- side , top hight , depth , side , bottom, side,
}
}
cannons.nodeboxes.stand = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, -- bottom --
{-0.5, -0.5, -0.5, -0.35, 1.0, 0.5}, -- side left --
{0.35, -0.5, -0.5, 0.5, 1.0, 0.5}, -- side right --
{0.35, -0.5, -0.2, 0.5, 1.2, 0.5}, -- side right --
{-0.5, -0.5, -0.2, -0.35, 1.2, 0.5}, -- side left --
-- side , top , side , side , bottom, side,
},
}
local apple={
physical = false,
timer=0,
textures = {"default_apple.png"},
lastpos={},
damage=-10,
range=2,
gravity=10,
velocity=30,
collisionbox = {-0.25,-0.25,-0.25, 0.25,0.25,0.25},
on_player_hit = function(self,pos,player)
local playername = player:get_player_name()
player:punch(self.object, 1.0, {
full_punch_interval=1.0,
damage_groups={fleshy=self.damage},
}, nil)
self.object:remove()
minetest.chat_send_player(playername ," this is not an easter egg!")
end,
on_mob_hit = function(self,pos,mob)
self.object:remove()
end,
on_node_hit = function(self,pos,node)
pos = self.lastpos
minetest.env:set_node({x=pos.x, y=pos.y, z=pos.z},{name="default:apple"})
minetest.sound_play("canons_hit",
{pos = pos, gain = 1.0, max_hear_distance = 32,})
self.object:remove()
end,
}
cannons.register_muni("default:apple",apple)