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:get_yaw()
            --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:set_velocity(force)
            if self._tmr < 0.2 then
                return
            else
                self._tmr = 0
            end
            local pos = self.object:get_pos()
            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_visible(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 bullet_ent = minetest.add_entity(pos1, "portalgun:bullet1")
                bullet_ent:set_velocity(d)
                --rotate bullet to by 90 degrees in x axis
                local yaw = math.rad(math.fmod((math.floor(math.fmod(math.deg(self.object:get_yaw()), 360) / 90) * 90), 360))
                bullet_ent:set_yaw(yaw)
                minetest.sound_play("portalgun_bullet1", {pos = pos, gain = 1, max_hear_distance = 15})
            else
                local obj = minetest.add_entity(pos1, "portalgun:turretgun")
                obj:set_yaw(self.object:get_yaw())
                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
            local name = obj:get_luaentity().name
            if name== "portalgun:turretgun" or name == "portalgun:turretgun2" 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(120)
    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 = 5.8, y = 5.8},
        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:get_yaw()
            --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:set_velocity(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_visible(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:get_yaw())
                self.object:remove()
            end
            return true
        end
    }
)

function portalgun_visible(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",
        visual_size = {x = 2, y = 2},
        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
    }
)
