289 lines
7.4 KiB
Lua
289 lines
7.4 KiB
Lua
--[[
|
|
Shooter Turret Gun [shooter_turret]
|
|
Copyright (C) 2013-2019 stujones11, Stuart Jones
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation; either version 2.1 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License along
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
]]--
|
|
|
|
local use_player_api = minetest.get_modpath("player_api")
|
|
|
|
local function get_turret_entity(pos)
|
|
local entity = nil
|
|
local objects = minetest.get_objects_inside_radius(pos, 1)
|
|
for _, obj in ipairs(objects) do
|
|
local ent = obj:get_luaentity()
|
|
if ent then
|
|
if ent.name == "shooter_turret:turret_entity" then
|
|
-- Remove duplicates
|
|
if entity then
|
|
obj:remove()
|
|
else
|
|
entity = ent
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return entity
|
|
end
|
|
|
|
minetest.register_entity("shooter_turret:turret_entity", {
|
|
physical = true,
|
|
visual = "mesh",
|
|
mesh = "shooter_turret.b3d",
|
|
visual_size = {x=1, y=1},
|
|
collisionbox = {-0.3, 0.5,-0.3, 0.3,1,0.3},
|
|
textures = {
|
|
"shooter_turret_uv.png",
|
|
},
|
|
timer = 0,
|
|
user = nil,
|
|
pitch = 40,
|
|
yaw = 0,
|
|
firing = false,
|
|
on_activate = function(self)
|
|
self.pos = self.object:get_pos()
|
|
self.yaw = self.object:get_yaw()
|
|
if minetest.get_node(self.pos).name ~= "shooter_turret:turret" then
|
|
self.object:remove()
|
|
return
|
|
end
|
|
self.object:set_animation({x=self.pitch, y=self.pitch}, 0)
|
|
self.object:set_armor_groups({immortal=1})
|
|
-- Remove duplicates
|
|
get_turret_entity(self.pos)
|
|
end,
|
|
on_rightclick = function(self, clicker)
|
|
if self.user then
|
|
local player = minetest.get_player_by_name(self.user)
|
|
if player then
|
|
player:set_detach()
|
|
if use_player_api then
|
|
player_api.player_attached[self.user] = false
|
|
end
|
|
end
|
|
self.user = nil
|
|
else
|
|
clicker:set_attach(self.object, "", {x=0,y=-5,z=-8}, {x=0,y=0,z=0})
|
|
self.user = clicker:get_player_name()
|
|
if use_player_api then
|
|
player_api.player_attached[self.user] = true
|
|
end
|
|
end
|
|
end,
|
|
on_step = function(self, dtime)
|
|
if not self.user then
|
|
return
|
|
end
|
|
self.timer = self.timer + dtime
|
|
if self.timer < 0.2 then
|
|
return
|
|
end
|
|
local player = minetest.get_player_by_name(self.user)
|
|
if player then
|
|
local pitch = self.pitch
|
|
local yaw = self.object:get_yaw()
|
|
local ctrl = player:get_player_control()
|
|
local step = 2
|
|
if ctrl then
|
|
if ctrl.sneak then
|
|
step = 1
|
|
if ctrl.jump then
|
|
if self.firing == false then
|
|
self:fire()
|
|
self.firing = true
|
|
end
|
|
else
|
|
self.firing = false
|
|
end
|
|
end
|
|
if ctrl.down then
|
|
pitch = pitch + 1 * step
|
|
elseif ctrl.up then
|
|
pitch = pitch - 1 * step
|
|
end
|
|
if ctrl.left then
|
|
yaw = yaw + 0.025 * step
|
|
elseif ctrl.right then
|
|
yaw = yaw - 0.025 * step
|
|
end
|
|
if pitch < 0 then
|
|
pitch = 0
|
|
elseif pitch > 90 then
|
|
pitch = 90
|
|
end
|
|
if self.pitch ~= pitch then
|
|
self.object:set_animation({x=pitch, y=pitch}, 0)
|
|
self.pitch = pitch
|
|
end
|
|
if self.yaw ~= yaw then
|
|
self.object:set_yaw(yaw)
|
|
self.yaw = yaw
|
|
end
|
|
end
|
|
end
|
|
self.timer = 0
|
|
end,
|
|
fire = function(self)
|
|
if not self.user then
|
|
return
|
|
end
|
|
local meta = minetest.get_meta(self.pos)
|
|
local inv = meta:get_inventory()
|
|
if not inv then
|
|
return
|
|
end
|
|
if not inv:contains_item("main", "shooter_rocket:rocket") then
|
|
minetest.sound_play("shooter_click", {object=self.object})
|
|
return
|
|
end
|
|
inv:remove_item("main", "shooter_rocket:rocket")
|
|
minetest.sound_play("shooter_shotgun", {object=self.object})
|
|
local pitch = math.rad(self.pitch - 40)
|
|
local len = math.cos(pitch)
|
|
local dir = vector.normalize({
|
|
x = len * math.sin(-self.yaw),
|
|
y = math.sin(pitch),
|
|
z = len * math.cos(self.yaw),
|
|
})
|
|
local pos = {x=self.pos.x, y=self.pos.y + 0.87, z=self.pos.z}
|
|
pos = vector.add(pos, vector.multiply(dir, 1.5))
|
|
local obj = minetest.add_entity(pos, "shooter_rocket:rocket_entity")
|
|
if obj then
|
|
local ent = obj:get_luaentity()
|
|
if ent then
|
|
minetest.sound_play("shooter_rocket_fire", {object=obj})
|
|
ent.user = self.user
|
|
obj:set_yaw(self.yaw)
|
|
obj:set_velocity(vector.multiply(dir, 30))
|
|
obj:set_acceleration({x=dir.x * -3, y=-10, z=dir.z * -3})
|
|
end
|
|
end
|
|
if shooter.config.enable_particle_fx == true then
|
|
minetest.add_particlespawner({
|
|
amount = 10,
|
|
time = 0.1,
|
|
minpos = {x=pos.x - 1, y=pos.y - 1, z=pos.z - 1},
|
|
maxpos = {x=pos.x + 1, y=pos.y + 1, z=pos.z + 1},
|
|
minvel = {x=0, y=0, z=0},
|
|
maxvel = {x=0, y=0, z=0},
|
|
minacc = {x=-0.5, y=-0.5, z=-0.5},
|
|
maxacc = {x=0.5, y=0.5, z=0.5},
|
|
minexptime = 0.1,
|
|
maxexptime = 1,
|
|
minsize = 8,
|
|
maxsize = 15,
|
|
collisiondetection = false,
|
|
texture = "shooter_smoke.png",
|
|
})
|
|
end
|
|
end
|
|
})
|
|
|
|
minetest.register_node("shooter_turret:turret", {
|
|
description = "Turret Gun",
|
|
tiles = {"shooter_turret_base.png"},
|
|
inventory_image = "shooter_turret_gun.png",
|
|
wield_image = "shooter_turret_gun.png",
|
|
drawtype = "nodebox",
|
|
paramtype = "light",
|
|
paramtype2 = "facedir",
|
|
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=3},
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = {
|
|
{-1/8, 1/8, -1/8, 1/8, 1/2, 1/8},
|
|
{-5/16, 0, -5/16, 5/16, 1/8, 5/16},
|
|
{-3/8, -1/2, -3/8, -1/4, 0, -1/4},
|
|
{1/4, -1/2, 1/4, 3/8, 0, 3/8},
|
|
{1/4, -1/2, -3/8, 3/8, 0, -1/4},
|
|
{-3/8, -1/2, 1/4, -1/4, 0, 3/8},
|
|
},
|
|
},
|
|
on_construct = function(pos)
|
|
local meta = minetest.get_meta(pos)
|
|
meta:set_string("formspec", "size[8,9]"..
|
|
"list[current_name;main;2,0;4,4;]"..
|
|
"list[current_player;main;0,5;8,4;]"..
|
|
"listring[]"
|
|
)
|
|
meta:set_string("infotext", "Turret Gun")
|
|
local inv = meta:get_inventory()
|
|
inv:set_size("main", 16)
|
|
end,
|
|
after_place_node = function(pos)
|
|
local node = minetest.get_node({x=pos.x, y=pos.y + 1, z=pos.z})
|
|
if node.name == "air" then
|
|
if not get_turret_entity(pos) then
|
|
minetest.add_entity(pos, "shooter_turret:turret_entity")
|
|
end
|
|
end
|
|
end,
|
|
can_dig = function(pos)
|
|
local meta = minetest.get_meta(pos);
|
|
local inv = meta:get_inventory()
|
|
return inv:is_empty("main")
|
|
end,
|
|
after_destruct = function(pos)
|
|
local ent = get_turret_entity(pos)
|
|
if ent then
|
|
ent.object:remove()
|
|
end
|
|
end,
|
|
mesecons = {
|
|
effector = {
|
|
action_on = function(pos)
|
|
local ent = get_turret_entity(pos)
|
|
if ent then
|
|
if ent.firing == false then
|
|
ent:fire()
|
|
ent.firing = true
|
|
end
|
|
end
|
|
end,
|
|
action_off = function(pos)
|
|
local ent = get_turret_entity(pos)
|
|
if ent then
|
|
ent.firing = false
|
|
end
|
|
end,
|
|
},
|
|
},
|
|
})
|
|
|
|
minetest.register_abm({
|
|
nodenames = {"shooter_turret:turret"},
|
|
interval = 15,
|
|
chance = 1,
|
|
action = function(pos)
|
|
if not get_turret_entity(pos) then
|
|
minetest.add_entity(pos, "shooter_turret:turret_entity")
|
|
end
|
|
end
|
|
})
|
|
|
|
if shooter.config.enable_crafting == true then
|
|
minetest.register_craft({
|
|
output = "shooter_turret:turret",
|
|
recipe = {
|
|
{"default:bronze_ingot", "default:bronze_ingot", "default:steel_ingot"},
|
|
{"", "default:bronze_ingot", "default:steel_ingot"},
|
|
{"", "default:diamond", ""},
|
|
},
|
|
})
|
|
end
|
|
|
|
--Backward compatibility
|
|
minetest.register_alias("shooter:turret", "shooter_turret:turret")
|
|
|