
-------------------------------------------------------------------

minetest.register_node("tools:e_sword", {
	description = "Energy Sword".."\n"..
	"",
	drawtype = 'mesh',
	mesh = 'sword.obj',
	tiles = {"e_sword.png"},
	paramtype = "light",
	paramtype2 = "facedir",
	groups = {dig_immediate = 3,crumbly = 3,},
	drop = "tools:e_sword",
	light_source =  8,
	tool_capabilities = {
	damage_groups = {fleshy= 5},
	},
	})


-------------------------------------------------------------------

minetest.register_tool("tools:all_tool", {
	description = "All tool".."\n"..
		"All in One Tool",
	inventory_image = "all_tool.png",
	tool_capabilities = {
		full_punch_interval = 1.0,
		max_drop_level = 0,
		groupcaps={
			crumbly={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255},
			snappy={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255},
			choppy={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255},
		},
		damage_groups = {fleshy= 1},
	},
})

-------------------------------------------------------------------

local laser_item = "tools:freezeray"  
local laser_entity = "tools:ice_laser_beam"

-- Register the laser beam entity
minetest.register_entity(laser_entity, {
    initial_properties = {
        physical = false,
        collide_with_objects = false,
        collisionbox = {0, 0, 0, 0, 0, 0},
        visual = "sprite",
        textures = {"laser_beam.png"},
        visual_size = {x = 0.2, y = 0.2},
        pointable = false,
    },

    timer = 0,
    range = 20,  -- Maximum range of the laser beam

    on_step = function(self, dtime)
        self.timer = self.timer + dtime
        local pos = self.object:get_pos()
        
        -- Check for objects (entities) within a small radius along the laser's path
        local objects = minetest.get_objects_inside_radius(pos, 1)
        local hit_entity = false
        for _, obj in ipairs(objects) do
            if obj ~= self.object then
                -- If an entity is hit, place ice on top of it and mark as hit
                local obj_pos = obj:get_pos()
                for i = -1, 1 do
                    for j = -1, 1 do
                        for k = -1, 1 do
                            local ice_pos = {x = obj_pos.x + i, y = obj_pos.y + j, z = obj_pos.z + k}
                            minetest.set_node(ice_pos, {name = "default:ice"})
                        end
                    end
                end
                hit_entity = true
                break
            end
        end

        -- Replace nearby area with ice, regardless of entity detection
        if hit_entity or self.timer >= self.range / 10 then
            local range = 2  -- Radius for replacing nodes with ice
            for x = -range, range do
                for y = -range, range do
                    for z = -range, range do
                        local node_pos = vector.add(pos, {x = x, y = y, z = z})
                        local node = minetest.get_node(node_pos)
                        if node.name ~= "air" then
                            minetest.set_node(node_pos, {name = "default:ice"})
                        end
                    end
                end
            end
            -- Remove the laser beam entity after impact
            self.object:remove()
        end
    end,
})

minetest.register_node("tools:freezeray", {
	description = "Freeze Ray".."\n"..
	"Freezes when Used(WARNING:If aimed at player, it will Freeze Player too !)",
	drawtype = 'mesh',
	mesh = 'freezeray.obj',
	tiles = {"freezeray.png"},
	paramtype = "light",
	paramtype2 = "facedir",
	groups = {dig_immediate = 3, crumbly = 3,},
	drop = "tools:freezeray",
	light_source =  5,
	tool_capabilities = {
	full_punch_interval = 0.5,
	damage_groups = {fleshy=100},
	},
	on_use = function(itemstack, user, pointed_thing)
	local player_pos = user:get_pos()
	local dir = user:get_look_dir()

        -- Spawn the laser beam entity slightly in front of the player
	local start_pos = {
	x = player_pos.x + dir.x,
	y = player_pos.y + dir.y + 1.5,  -- Aligns with the player's eye level
	z = player_pos.z + dir.z
	}
	local obj = minetest.add_entity(start_pos, laser_entity)

	if obj then
	-- Set the laser beam velocity to move quickly in the direction the player is looking
	obj:set_velocity({
	x = dir.x * 30,
	y = dir.y * 30,
	z = dir.z * 30
	})
	obj:set_acceleration({x = 0, y = 0, z = 0}) -- No gravity
		end
		
	if pointed_thing.type == "node" then
            local pos = pointed_thing.under
            local node = minetest.get_node(pos)

            -- Check if the node can be dug (is diggable) and replaceable with ice
            if minetest.get_node_drops(node.name) then
                minetest.remove_node(pos)  -- Remove the original node
                minetest.set_node(pos, {name = "default:ice"})  -- Spawn an ice node at the position
                minetest.sound_play("default_place_node", {pos = pos, gain = 0.5})  -- Optional sound effect

                -- Damage the tool or use up 1 durability
                itemstack:add_wear(65535 / 100)  -- Adjust for durability
            end
        end
        return itemstack
		
	end,
})
-----------------------------------------------------------------

minetest.register_node("tools:phone", {
	description = "Phone".."\n"..
	"phony phone",
	drawtype = 'mesh',
	mesh = 'phone.obj',
	tiles = {"phone.png"},
	paramtype = "light",
	paramtype2 = "facedir",
	groups = {dig_immediate = 3,crumbly = 3,},
	drop = "tools:phone",
	light_source =  7,
	})

------------------------------------------------------------------	
minetest.register_node("tools:immortal_belt", {
	description = "Immortal Belt".."\n"..
	"Make Player Immortal when Used",
	drawtype = 'mesh',
	mesh = 'immortal_belt.obj',
	tiles = {"immortal_belt.png"},
	paramtype = "light",
	paramtype2 = "facedir",
	groups = {dig_immediate = 3,crumbly = 3,},
	drop = "tools:immortal_belt",
	light_source =  5,
	})

-- Function to check and update player's immortality status
local function update_player_immortality(player)
	local wielded_item = player:get_wielded_item():get_name()
    
--Check if the player is wielding the specific item
	if wielded_item == "tools:immortal_belt" then
		player:set_armor_groups({immortal = 1})  -- Set player to be immortal
	else
		player:set_armor_groups({fleshy = 100})  -- Reset to normal mortality
	end
end

-- Global step to continually check all players' wielded items
minetest.register_globalstep(function(dtime)
for _, player in ipairs(minetest.get_connected_players()) do
	update_player_immortality(player)
	end
end)
----------------------------------------------------------------------
minetest.register_node("tools:scouter", {
	description = "Scouter".."\n"..
	"Detects Entities when Used",
	inventory_image = "scouter_inv.png",
	wield_image = "scouter_inv.png",
	drawtype = 'mesh',
	mesh = 'scouter.obj',
	tiles = {"scouter_obj.png"},
	use_texture_alpha = "blend",
	paramtype = "light",
	paramtype2 = "facedir",
	groups = {dig_immediate = 3,crumbly = 3,},
	drop = "tools:scouter",
	light_source =  5,
})


local waypoint_item = "tools:scouter"
local range = 100  -- Range to detect nearby entities (in nodes)
local update_interval = 0.5  -- Update interval in seconds for checking nearby entities
local player_waypoints = {}

-- Function to add waypoints for nearby entities
local function update_waypoints_for_player(player)
	local player_name = player:get_player_name()
	local wielded_item = player:get_wielded_item():get_name()
	
	if wielded_item == waypoint_item then
-- Remove existing waypoints first
	if player_waypoints[player_name] then
		for _, hud_id in ipairs(player_waypoints[player_name]) do
		player:hud_remove(hud_id)
		end
	end

	player_waypoints[player_name] = {}

-- Get player position and find nearby entities
	local pos = player:get_pos()
	local entities = minetest.get_objects_inside_radius(pos, range)

-- Add a waypoint for each nearby entity
        for _, entity in ipairs(entities) do
		if entity:is_player() or entity:get_luaentity() then
		local entity_pos = entity:get_pos()
		local hud_id = player:hud_add({
		hud_elem_type = "waypoint",
		name = entity:is_player() and "Player" or "Entity",
		number = 0xFF0000,  -- Red color for the waypoint
			world_pos = entity_pos
		})
		table.insert(player_waypoints[player_name], hud_id)
		end
	end
	else
-- Remove waypoints if player is not wielding the item
	if player_waypoints[player_name] then
		for _, hud_id in ipairs(player_waypoints[player_name]) do
	player:hud_remove(hud_id)
		end
	player_waypoints[player_name] = nil
	end
 	   end
		end

-- Global step to update waypoints every interval for all players
local time_elapsed = 0
minetest.register_globalstep(function(dtime)
	time_elapsed = time_elapsed + dtime
	if time_elapsed >= update_interval then
	time_elapsed = 0
	for _, player in ipairs(minetest.get_connected_players()) do
	update_waypoints_for_player(player)
		end
	end
end)
------------------------------------------------------------------------------

local throw_item = "tools:throw_bomb"  
local throw_entity = "tools:throw_bomb"

-- Register the throwable entity
minetest.register_entity(throw_entity, {
    initial_properties = {
	physical = true,
	collide_with_objects = true,
	collisionbox = {-1/2,-1/2,-1/2,1/2,1/2,1/2},
	visual = "mesh",
	mesh = "throw_bomb.b3d",
	textures = {"throw_bomb.png"},
        visual_size = {x = 5, y = 5},
    },

    timer = 0,  -- Add a timer property

    on_step = function(self, dtime)
        self.timer = self.timer + dtime  -- Increase the timer

        if self.timer >= 15 then  -- Check if 1 second has passed
            local pos = self.object:get_pos()
            local objects = minetest.get_objects_inside_radius(pos, 3)  -- Increase detection radius to 3

            for _, obj in ipairs(objects) do
                if obj ~= self.object then
                    obj:remove()  -- Remove any nearby object
                end
            end

            self.object:remove()  -- Remove the thrown entity itself after 1 second
        end
    end,
})

minetest.register_node("tools:throw_bomb", {
    description = "Throw Bomb".."\n"..
    "Removes Entities when Used",
    drawtype = 'mesh',
    mesh = 'throw_bomb.obj',
    tiles = {"throw_bomb.png"},
    paramtype = "light",
    paramtype2 = "facedir",
    groups = {dig_immediate = 3,crumbly = 3,},
    drop = "tools:throw_bomb",
    light_source = 5,
    
    on_use = function(itemstack, user, pointed_thing)
        local player_pos = user:get_pos()
        local dir = user:get_look_dir()
        local obj = minetest.add_entity({
            x = player_pos.x + dir.x,
            y = player_pos.y + dir.y + 1.5, -- Slightly above player's head
            z = player_pos.z + dir.z
        }, throw_entity)

        if obj then
            obj:set_velocity({
                x = dir.x * 10,
                y = dir.y * 10,
                z = dir.z * 10
            })
            obj:set_acceleration({x = 0, y = -9.8, z = 0}) -- Gravity
        end
    end,
})
--------------------------------------------------------

local laser_item = "tools:gun_repulsor"
local laser_entity = "tools:laser_beam"

-- List of entities that take only 50% damage
local half_damage_entities = {
	"beast:beast",
}

-- List of nodes that cannot be destroyed by the laser
local protected_nodes = {
	"misc:node_1",
	"misc:node_2",
	"misc:node_3",
	"misc:node_4",
	"misc:node_5",
	"misc:node_6",
	"misc:node_1",
	"misc:node_8",
	"misc:node_9",
	"misc:node_10",
	"misc:node_11",
	"misc:node_12",
	"misc:node_13",
	"misc:node_0",
}

-- Function to check if an entity is in the half-damage list
local function is_half_damage_entity(entity_name)
	for _, name in ipairs(half_damage_entities) do
		if entity_name == name then
			return true
		end
	end
	return false
end

-- Function to check if a node is protected
local function is_protected_node(node_name)
	for _, protected_name in ipairs(protected_nodes) do
		if node_name == protected_name then
			return true
		end
	end
	return false
end

-- Register the laser beam entity
minetest.register_entity(laser_entity, {
	initial_properties = {
		physical = false,
		collide_with_objects = false,
		collisionbox = {0, 0, 0, 0, 0, 0},
		visual = "sprite",
		textures = {"laser_beam.png"},
		visual_size = {x = 0.2, y = 0.2},
		pointable = false,
	},

	timer = 0,
	range = 20, -- Maximum range of the laser beam

	on_step = function(self, dtime)
		self.timer = self.timer + dtime
		local pos = self.object:get_pos()

		-- Check for objects within a small radius along the laser's path
		local objects = minetest.get_objects_inside_radius(pos, 1)
		for _, obj in ipairs(objects) do
			if obj ~= self.object and obj:is_player() == false then
				local lua_entity = obj:get_luaentity()
				if lua_entity then
					if is_half_damage_entity(lua_entity.name) then
						-- If the entity is in the half-damage list, apply 25% damage
						local hp = obj:get_hp()
						obj:set_hp(hp - (hp * 0.25))
						if obj:get_hp() <= 0 then
							obj:remove()
						end
					else
						-- If not in the list, remove the entity
						obj:remove()
					end
				else
					-- Remove non-registered entities
					obj:remove()
				end

				-- Destroy nearby nodes
				local range = 2 -- Destruction radius around the impact point
				for x = -range, range do
					for y = -range, range do
						for z = -range, range do
							local node_pos = vector.add(pos, {x = x, y = y, z = z})
							local node = minetest.get_node(node_pos)
							-- Check if the node is not in the protected list
							if node.name ~= "air" and not is_protected_node(node.name) then
								minetest.remove_node(node_pos)
							end
						end
					end
				end
				-- Remove the laser beam entity after impact
				self.object:remove()
				return
			end
		end

		-- Check if the laser has exceeded its range
		if self.timer >= self.range / 10 then
			self.object:remove()
			return
		end
	end,
})

-- Register the gun repulsor node
minetest.register_node("tools:gun_repulsor", {
    description = "Gun Repulsor" .. "\n" ..
     "Damage 50% to Entities when Used (Works on Entity only)",
    drawtype = 'mesh',
    mesh = 'gun_repulsor.obj',
    tiles = {"gun_repulsor.png"},
    paramtype = "light",
    paramtype2 = "facedir",
    groups = {dig_immediate = 3,crumbly = 3,},
    drop = "tools:gun_repulsor",
    light_source = 5,
    tool_capabilities = {
        full_punch_interval = 0.5,
        damage_groups = {fleshy = 100},
    },
    on_use = function(itemstack, user, pointed_thing)
        local player_pos = user:get_pos()
        local dir = user:get_look_dir()

        -- Spawn the laser beam entity slightly in front of the player
        local start_pos = {
            x = player_pos.x + dir.x,
            y = player_pos.y + dir.y + 1.5, -- Adjust to align with the player's eye level
            z = player_pos.z + dir.z
        }
        local obj = minetest.add_entity(start_pos, laser_entity)

        if obj then
            -- Set the laser beam velocity to move quickly in the direction the player is looking
            obj:set_velocity({
                x = dir.x * 30,
                y = dir.y * 30,
                z = dir.z * 30
            })
            obj:set_acceleration({x = 0, y = 0, z = 0}) -- No gravity
        end
    end,
})

	
minetest.register_node("tools:knocker", {
	description = "Knocker".."\n"..
	"Knock back Entities when Used",
	drawtype = 'mesh',
	mesh = 'knocker.obj',
	tiles = {"knocker.png"},
	paramtype = "light",
	paramtype2 = "facedir",
	groups = {dig_immediate = 3,crumbly = 3,},
	drop = "tools:knocker",
	light_source = 5,
	on_use = function(itemstack, user, pointed_thing)
	-- Get the player's position and direction
	local pos = user:get_pos()
	local dir = user:get_look_dir()

	-- Offset the position to be slightly in front of the player
	pos = vector.add(pos, vector.multiply(dir, 1.5))

	-- Range of effect and knockback force
	local range = 4
	local knockback_force = 10

	-- Find nearby entities
	local objects = minetest.get_objects_inside_radius(pos, range)
	for _, obj in ipairs(objects) do
	-- Ensure we only affect entities, not players or the user themselves
	if obj ~= user and obj:is_player() == false then
	-- Calculate knockback direction and apply force
	local entity_pos = obj:get_pos()
	local knockback_dir = vector.normalize(vector.subtract(entity_pos, pos))
	knockback_dir = vector.multiply(knockback_dir, knockback_force)

	obj:add_velocity(knockback_dir)
	end
end

	return itemstack
end,		
})
