portalgun/scripts/turrets.lua
2022-08-14 14:36:22 +02:00

355 lines
13 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:tureta",
{
description = "Tureta",
tiles = {"portalgun_sentry_turret.png"},
drawtype = "mesh",
mesh = "turret1.obj",
--spawn turretgun and set to air
on_place = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.above
local obj = minetest.add_entity(pos, "portalgun:turretgun")
--rotate turret to face player
local dir = placer:get_look_dir()
local yaw = math.atan(dir.z, dir.x) + math.pi / 2
if dir.x < 0 then
yaw = yaw + math.pi
end
yaw = yaw + math.pi
local deg = math.deg(yaw)
deg = math.fmod(deg, 360)
deg = math.floor(deg / 90) * 90
deg = deg + 90
deg = math.fmod(deg, 360)
obj:set_yaw(math.rad(deg))
--set turret to air
minetest.set_node(pos, {name = "air"})
end
}
)
minetest.register_craftitem(
"portalgun:turret_rotator",
{
description = "Turret rotator",
inventory_image = "portalgun_turret_rotator.png",
stack_max = 1,
on_use = function(itemstack, user, pointed_thing)
--if pointing at a entity
if pointed_thing.type == "object" then
local obj = pointed_thing.ref
--if entity is a turret
if obj:get_luaentity().name == "portalgun:turretgun" then
--get object yaw
local yaw = obj:get_yaw()
local deg = math.deg(yaw)
deg = math.fmod(deg, 360)
deg = math.floor(deg / 90) * 90
deg = deg + 90
deg = math.fmod(deg, 360)
--set object yaw
obj:set_yaw(math.rad(deg))
end
end
end,
}
)
minetest.register_entity(
"portalgun:turretgun2",
{
description = "Sentry turret",
textures = {"portalgun_sentry_turret.png"},
visual = "mesh",
hp_max = 100,
physical = true,
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
weight = 5,
is_visible = true,
visual_size = {x = 6, y = 6},
make_footstep_sound = true,
_tmr = 0,
_stop = 1,
automatic_rotate = 0,
mesh = "turret2.obj",
on_step = function(self, elapsed, moveresult)
self._tmr = self._tmr + elapsed
self.object:set_yaw(math.rad(math.fmod((math.floor(math.fmod(math.deg(self.object:get_yaw()), 360) / 90) * 90), 360)))
--get yaw and convert it into param2
local p = self.object:getyaw()
--convert yaw from rad to degrees
local yaw = math.deg(p)
yaw = math.floor(yaw / 90)
--if param2 is less than 0, set it to 3
if yaw < 0 then
yaw = 3
end
p = yaw
--add -y force
local force = {x = 0, y = -10, z = 0}
self.object:setvelocity(force)
if self._tmr < 0.2 then
return
else
self._tmr = 0
end
local pos = self.object:getpos()
local pos1 = {x = pos.x, y = pos.y + 0.5, z = pos.z}
local d
--swap 1 and 3 in p
if p == 1 then
p = 3
elseif p == 3 then
p = 1
end
for i, ob in pairs(minetest.get_objects_inside_radius(pos, 10)) do
if portalgun_visiable(pos1, ob) and (ob:is_player()) 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.sound_play("portalgun_bullet1", {pos = pos, gain = 1, max_hear_distance = 15})
else
local obj = minetest.add_entity(pos1, "portalgun:turretgun")
obj:setyaw(self.object:getyaw())
self.object:remove()
end
return true
end
}
)
minetest.register_node("portalgun:turretgun_spawner",
{
--this node spawns a turret on top of the block if there is no turret nearby
description = "Turret spawner",
--separate tile for top others same
tiles = {"portalgun_turret_spawner_top.png", "portalgun_turret_spawner_side.png"},
groups = {cracky = 3},
sounds = stone_sounds,
drawtype = "allfaces",
paramtype = "light",
paramtype2 = "facedir",
drop = "",
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("pos", minetest.pos_to_string(pos))
meta:set_int("yaw", 0)
meta:set_string("infotext", "Turret spawner (" .. meta:get_int("yaw") .. ")")
minetest.get_node_timer(pos):start(1.0)
end,
on_punch = function(pos, node, puncher, pointed_thing)
local haspriv, missingpriv = minetest.check_player_privs(puncher:get_player_name(), {server = true})
--if puncher has privilege server add 90 degrees to yaw
if haspriv then
local meta = minetest.get_meta(pos)
local tmppos = minetest.string_to_pos(meta:get_string("pos"))
if tmppos ~= pos then
minetest.crash("hehe")
end
local yaw = meta:get_int("yaw")
yaw = yaw + 90
yaw = yaw % 360
meta:set_int("yaw", yaw)
meta:set_string("infotext", "Turret spawner (" .. meta:get_int("yaw") .. ")")
end
end,
on_timer = function (pos, elapsed)
local meta = minetest.get_meta(pos)
local pos = meta:get_string("pos")
local pos1 = minetest.string_to_pos(pos)
local pos2 = {x = pos1.x, y = pos1.y + 1, z = pos1.z}
local objs = minetest.get_objects_inside_radius(pos2, 1)
local found = 0
for i, obj in pairs(objs) do
if obj:get_luaentity().name == "portalgun:turretgun" then
found = found + 1
end
end
if found == 0 then
local obj = minetest.add_entity(pos2, "portalgun:turretgun")
obj:setyaw(math.rad(meta:get_int("yaw")))
end
minetest.get_node_timer(pos1):start(10)
end
})
minetest.register_entity(
"portalgun:turretgun",
{
description = "Sentry turret",
textures = {"portalgun_sentry_turret.png"},
visual = "mesh",
hp_max = 100,
physical = true,
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
weight = 5,
is_visible = true,
make_footstep_sound = true,
automatic_rotate = 0,
_tmr = 0,
_stop = 1,
visual_size = {x = 6, y = 6},
mesh = "turret1.obj",
on_step = function(self, elapsed, moveresult)
self.object:set_yaw(math.rad(math.fmod((math.floor(math.fmod(math.deg(self.object:get_yaw()), 360) / 90) * 90), 360)))
--get yaw and convert it into param2
local p = self.object:getyaw()
--convert yaw from rad to degrees
local yaw = math.deg(p)
yaw = math.floor(yaw / 90)
--if param2 is less than 0, set it to 3
if yaw < 0 then
yaw = 3
end
p = yaw
local pos = self.object:get_pos()
local pos1 = {x = pos.x, y = pos.y + 0.5, z = pos.z}
local force = {x = 0, y = -10, z = 0}
self.object:setvelocity(force)
self._tmr = self._tmr + elapsed
if self._tmr < 0.2 then
return
else
self._tmr = 0
end
--swap 1 and 3 in p
if p == 1 then
p = 3
elseif p == 3 then
p = 1
end
local d
for i, ob in pairs(minetest.get_objects_inside_radius(pos1, 10)) do
if portalgun_visiable(pos1, ob) and (ob:is_player()) 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
local obj = minetest.add_entity(pos1, "portalgun:turretgun2")
--set yaw to same as this object
obj:setyaw(self.object:getyaw())
self.object:remove()
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
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() > 3 then
ob:set_hp(ob:get_hp() - 3)
elseif ob:get_hp() == 0 then
else
ob:set_hp(0)
end
self.object:remove()
return
end
end
end,
timer = 0,
timer2 = 0
}
)