forked from Mirrorlandia_minetest/portalgun
258 lines
9.6 KiB
Lua
258 lines
9.6 KiB
Lua
|
stone_sounds = {}
|
||
|
stone_sounds.footstep = {name = "stone_walk", gain = 1.0}
|
||
|
stone_sounds.dug = {name = "stone_break", gain = 1.0}
|
||
|
stone_sounds.place = {name = "block_place", gain = 1.0}
|
||
|
glass_sounds = {}
|
||
|
glass_sounds.footstep = {name = "glass_walk", gain = 1.0}
|
||
|
glass_sounds.dug = {name = "glass_break", gain = 1.0}
|
||
|
glass_sounds.place = {name = "block_place", gain = 1.0}
|
||
|
wood_sounds = {}
|
||
|
wood_sounds.footstep = {name = "wood_walk", gain = 1.0}
|
||
|
wood_sounds.dug = {name = "wood_break", gain = 1.0}
|
||
|
wood_sounds.place = {name = "block_place", gain = 1.0}
|
||
|
minetest.register_node(
|
||
|
"portalgun:turretgun2",
|
||
|
{
|
||
|
description = "Sentry turret",
|
||
|
groups = {oddly_breakable_by_hand = 1, not_in_creative_inventory = 1},
|
||
|
drop = "portalgun:turretgun",
|
||
|
paramtype = "light",
|
||
|
paramtype2 = "facedir",
|
||
|
sunlight_propagates = true,
|
||
|
sounds = stone_sounds,
|
||
|
tiles = {"portalgun_sentry_turret.png"},
|
||
|
drawtype = "mesh",
|
||
|
mesh = "turret2.obj",
|
||
|
selection_box = {
|
||
|
type = "fixed",
|
||
|
fixed = {
|
||
|
{-0.3, -0.5, -0.3, 0.3, 1, 0.3}
|
||
|
}
|
||
|
},
|
||
|
on_timer = function(pos, elapsed)
|
||
|
local p = minetest.get_node(pos).param2
|
||
|
local pos1 = {x = pos.x, y = pos.y + 0.5, z = pos.z}
|
||
|
local d
|
||
|
for i, ob in pairs(minetest.get_objects_inside_radius(pos, 10)) do
|
||
|
if
|
||
|
portalgun_visiable(pos1, ob) and
|
||
|
(ob:is_player() or
|
||
|
(ob:get_luaentity() and (ob:get_luaentity().type or ob:get_luaentity().portalgun == nil)))
|
||
|
then
|
||
|
local a = ob:get_pos()
|
||
|
if a.y < pos.y + 2 and a.y > pos.y - 1 then
|
||
|
a = {x = math.floor(a.x), y = math.floor(a.y), z = math.floor(a.z)}
|
||
|
if p == 3 and a.x > pos.x and a.z == pos.z then
|
||
|
d = {x = 20, y = 0, z = 0}
|
||
|
break
|
||
|
elseif p == 1 and a.x < pos.x and a.z == pos.z then
|
||
|
d = {x = -20, y = 0, z = 0}
|
||
|
break
|
||
|
elseif p == 2 and a.z > pos.z and a.x == pos.x then
|
||
|
d = {x = 0, y = 0, z = 20}
|
||
|
break
|
||
|
elseif p == 0 and a.z < pos.z and a.x == pos.x then
|
||
|
d = {x = 0, y = 0, z = -20}
|
||
|
break
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
local m = minetest.get_meta(pos)
|
||
|
if d then
|
||
|
m:set_int("stop", 0)
|
||
|
minetest.add_entity(pos1, "portalgun:bullet1"):set_velocity(d)
|
||
|
minetest.sound_play("portalgun_bullet1", {pos = pos, gain = 1, max_hear_distance = 15})
|
||
|
for i = 2, 5, 1 do
|
||
|
minetest.after(
|
||
|
i * 0.1,
|
||
|
function(pos, d)
|
||
|
minetest.add_entity(pos1, "portalgun:bullet1"):set_velocity(d)
|
||
|
minetest.sound_play("portalgun_bullet1", {pos = pos, gain = 1, max_hear_distance = 15})
|
||
|
end,
|
||
|
pos,
|
||
|
d
|
||
|
)
|
||
|
end
|
||
|
else
|
||
|
if m:get_int("stop") == 1 then
|
||
|
minetest.set_node(pos, {name = "portalgun:turretgun", param2 = p})
|
||
|
minetest.get_node_timer(pos):start(0.2)
|
||
|
else
|
||
|
m:set_int("stop", 1)
|
||
|
end
|
||
|
end
|
||
|
return true
|
||
|
end
|
||
|
}
|
||
|
)
|
||
|
|
||
|
minetest.register_node(
|
||
|
"portalgun:turretgun",
|
||
|
{
|
||
|
description = "Sentry turret",
|
||
|
groups = {oddly_breakable_by_hand = 1},
|
||
|
paramtype = "light",
|
||
|
paramtype2 = "facedir",
|
||
|
sunlight_propagates = true,
|
||
|
sounds = stone_sounds,
|
||
|
tiles = {"portalgun_sentry_turret.png"},
|
||
|
drawtype = "mesh",
|
||
|
mesh = "turret1.obj",
|
||
|
selection_box = {
|
||
|
type = "fixed",
|
||
|
fixed = {
|
||
|
{-0.3, -0.5, -0.3, 0.3, 1, 0.3}
|
||
|
}
|
||
|
},
|
||
|
on_construct = function(pos)
|
||
|
minetest.get_node_timer(pos):start(0.2)
|
||
|
end,
|
||
|
on_timer = function(pos, elapsed)
|
||
|
local p = minetest.get_node(pos).param2
|
||
|
local pos1 = {x = pos.x, y = pos.y + 0.5, z = pos.z}
|
||
|
local d
|
||
|
for i, ob in pairs(minetest.get_objects_inside_radius(pos1, 10)) do
|
||
|
if
|
||
|
portalgun_visiable(pos1, ob) and
|
||
|
(ob:is_player() or
|
||
|
(ob:get_luaentity() and (ob:get_luaentity().type or ob:get_luaentity().portalgun == nil)))
|
||
|
then
|
||
|
local a = ob:get_pos()
|
||
|
if a.y < pos.y + 2 and a.y > pos.y - 1 then
|
||
|
a = {x = math.floor(a.x), y = math.floor(a.y), z = math.floor(a.z)}
|
||
|
if p == 3 and a.x > pos.x and a.z == pos.z then
|
||
|
d = {x = 20, y = 0, z = 0}
|
||
|
break
|
||
|
elseif p == 1 and a.x < pos.x and a.z == pos.z then
|
||
|
d = {x = -20, y = 0, z = 0}
|
||
|
break
|
||
|
elseif p == 2 and a.z > pos.z and a.x == pos.x then
|
||
|
d = {x = 0, y = 0, z = 20}
|
||
|
break
|
||
|
elseif p == 0 and a.z < pos.z and a.x == pos.x then
|
||
|
d = {x = 0, y = 0, z = -20}
|
||
|
break
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if d then
|
||
|
minetest.add_entity(pos1, "portalgun:bullet1"):set_velocity(d)
|
||
|
minetest.set_node(pos, {name = "portalgun:turretgun2", param2 = p})
|
||
|
minetest.get_node_timer(pos):start(1)
|
||
|
minetest.sound_play("portalgun_bullet1", {pos = pos, gain = 1, max_hear_distance = 15})
|
||
|
for i = 2, 5, 1 do
|
||
|
minetest.after(
|
||
|
i * 0.1,
|
||
|
function(pos, d)
|
||
|
minetest.add_entity(pos1, "portalgun:bullet1"):set_velocity(d)
|
||
|
minetest.sound_play("portalgun_bullet1", {pos = pos, gain = 1, max_hear_distance = 15})
|
||
|
end,
|
||
|
pos,
|
||
|
d
|
||
|
)
|
||
|
end
|
||
|
end
|
||
|
return true
|
||
|
end
|
||
|
}
|
||
|
)
|
||
|
|
||
|
function portalgun_visiable(pos, ob)
|
||
|
if ob == nil or ob:get_pos() == nil or ob:get_pos().y == nil then
|
||
|
return false
|
||
|
end
|
||
|
local ta = ob:get_pos()
|
||
|
local v = {x = pos.x - ta.x, y = pos.y - ta.y - 1, z = pos.z - ta.z}
|
||
|
v.y = v.y - 1
|
||
|
local amount = (v.x ^ 2 + v.y ^ 2 + v.z ^ 2) ^ 0.5
|
||
|
local d =
|
||
|
math.sqrt((pos.x - ta.x) * (pos.x - ta.x) + (pos.y - ta.y) * (pos.y - ta.y) + (pos.z - ta.z) * (pos.z - ta.z))
|
||
|
v.x = (v.x / amount) * -1
|
||
|
v.y = (v.y / amount) * -1
|
||
|
v.z = (v.z / amount) * -1
|
||
|
for i = 1, d, 1 do
|
||
|
local node =
|
||
|
minetest.registered_nodes[
|
||
|
minetest.get_node({x = pos.x + (v.x * i), y = pos.y + (v.y * i), z = pos.z + (v.z * i)}).name
|
||
|
]
|
||
|
if node.walkable then
|
||
|
return false
|
||
|
end
|
||
|
end
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
function portalgun_round(x)
|
||
|
if x % 2 ~= 0.5 then
|
||
|
return math.floor(x + 0.5)
|
||
|
end
|
||
|
return x - 0.5
|
||
|
end
|
||
|
|
||
|
function portalgun_ra2shoot(pos, ob)
|
||
|
local op = ob:get_pos()
|
||
|
local m = minetest.get_meta(pos)
|
||
|
local x = m:get_int("x")
|
||
|
local y = m:get_int("y")
|
||
|
local z = m:get_int("z")
|
||
|
local ox = portalgun_round(op.x)
|
||
|
local oy = portalgun_round(op.y)
|
||
|
local oz = portalgun_round(op.z)
|
||
|
if x == 1 and ox == pos.x and oz <= pos.z then
|
||
|
return true
|
||
|
end
|
||
|
if x == -1 and ox == pos.x and oz >= pos.z then
|
||
|
return true
|
||
|
end
|
||
|
if z == -1 and oz == pos.z and ox <= pos.x then
|
||
|
return true
|
||
|
end
|
||
|
if z == 1 and oz == pos.z and ox >= pos.x then
|
||
|
return true
|
||
|
end
|
||
|
return false
|
||
|
end
|
||
|
|
||
|
minetest.register_entity(
|
||
|
"portalgun:bullet1",
|
||
|
{
|
||
|
hp_max = 1,
|
||
|
--physical = true,
|
||
|
--collisionbox={-0.01,-0.01,-0.01,0.01,0.01,0.01},
|
||
|
pointable = false,
|
||
|
visual = "mesh",
|
||
|
mesh = "bullet.obj",
|
||
|
--yellow color as tiles
|
||
|
tiles = {"#color[yellow]"},
|
||
|
initial_sprite_basepos = {x = 0, y = 0},
|
||
|
portalgun = 2,
|
||
|
bullet = 1,
|
||
|
on_step = function(self, dtime)
|
||
|
self.timer = self.timer + dtime
|
||
|
self.timer2 = self.timer2 + dtime
|
||
|
local pos = self.object:get_pos()
|
||
|
local n = minetest.registered_nodes[minetest.get_node(self.object:get_pos()).name]
|
||
|
if self.timer > 1 or (n and n.walkable) then
|
||
|
self.object:remove()
|
||
|
return
|
||
|
end
|
||
|
for i, ob in pairs(minetest.get_objects_inside_radius(pos, 1.5)) do
|
||
|
if ob:is_player() then
|
||
|
if ob:get_hp() > 2 then
|
||
|
ob:set_hp(ob:get_hp() - 2)
|
||
|
else
|
||
|
ob:set_hp(0)
|
||
|
end
|
||
|
self.object:remove()
|
||
|
return
|
||
|
end
|
||
|
end
|
||
|
end,
|
||
|
timer = 0,
|
||
|
timer2 = 0
|
||
|
}
|
||
|
)
|