Initial commit.
62
README.md
Normal file
@ -0,0 +1,62 @@
|
||||
Cave Tools [cavetools]
|
||||
======================
|
||||
Some useful tools for exploring caves.
|
||||
|
||||
By David G (kestral246@gmail.com)
|
||||
|
||||
![Cave Tools](screenshot.png "Cave Tools")
|
||||
|
||||
A compilation of some of my other mods focused on making cave exploration easier.
|
||||
|
||||
A set of flash lamps that momentarily light up the direction the player is pointed.
|
||||
|
||||
- Flash Lamp
|
||||
- Flash Wand
|
||||
- Super Flash Lamp
|
||||
|
||||
A set of depth finders that probe depth in the direction the player is pointed.
|
||||
|
||||
- Flint Depth Finder
|
||||
- Diamond Depth Finder
|
||||
|
||||
An override to the default ladders to allow them to be easily extended down by just right clicking a ladder with another ladder.
|
||||
|
||||
- **Note:** This can create freestanding ladders. If the lack of ladder thickness bothers you, you can use Linuxdirks redef mod, which provides 3-d ladders.
|
||||
|
||||
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
- Ladder overrides only enabled if default exists.
|
||||
- Craft recipes optionally depend on default and tnt.
|
||||
- Wand also optionally depends on mana.
|
||||
|
||||
|
||||
Craft Recipes
|
||||
-------------
|
||||
|
||||
![Flash Lamp](images/craft_lamp1.png "Flash Lamp (copper)")
|
||||
![Flash Lamp](images/craft_lamp2.png "Flash Lamp (tin)")
|
||||
|
||||
![Flash Wand](images/craft_wand.png "Flash Wand")
|
||||
![Super Flash Lamp](images/craft_super.png "Super Flash Lamp")
|
||||
|
||||
![Flint Depth Finder](images/craft_flint.png "Flint Depth Finder")
|
||||
![Diamond Depth Finder](images/craft_diamond.png "Diamond Depth Finder")
|
||||
|
||||
|
||||
Licenses
|
||||
--------
|
||||
|
||||
Source code
|
||||
|
||||
> The MIT License (MIT)
|
||||
|
||||
Media (textures)
|
||||
|
||||
> Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
|
||||
- Flint texture copied from default\_flint.png by Gambit.
|
||||
- Diamond texture copied from default\_diamond.png by BlockMen.
|
||||
- Stick texture copied from default\_stick.png by BlockMen.
|
158
depth_finder.lua
Normal file
@ -0,0 +1,158 @@
|
||||
-- Depth Finder [depth_finder]
|
||||
-- by David G (kestral246@gmail.com)
|
||||
-- 2020-06-22
|
||||
|
||||
-- Either two flints or two diamonds--bang them together and the return echo indicates depth.
|
||||
|
||||
local scan_angle = math.pi/4 -- corresponds to 90°
|
||||
|
||||
-- Maximum number of nodes to check
|
||||
local maxcount = 150000
|
||||
|
||||
-- The wear and radius can now be set independently for each lamp tool.
|
||||
|
||||
-- Set to true to print debug statistics.
|
||||
local debug = false
|
||||
|
||||
local scanned = {} -- Set containing scanned nodes, so they don't get scanned multiple times.
|
||||
local tocheck = {} -- Table of nodes to check.
|
||||
local max_depth = {} -- Deepest node scanned.
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
local pname = player:get_player_name()
|
||||
scanned[pname] = {}
|
||||
tocheck[pname] = {}
|
||||
max_depth[pname] = 0
|
||||
end)
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
local pname = player:get_player_name()
|
||||
scanned[pname] = nil
|
||||
tocheck[pname] = nil
|
||||
max_depth[pname] = nil
|
||||
end)
|
||||
|
||||
-- Determine number of elements in table, for summary output.
|
||||
local tlength = function(T)
|
||||
local count = 0
|
||||
for _ in pairs(T) do count = count + 1 end
|
||||
return count
|
||||
end
|
||||
|
||||
-- Scan neighboring nodes, flag for checking if air.
|
||||
local scan_node = function(pname, pos, origin, vdir, maxdist)
|
||||
-- Update to search a cone pattern in direction pointed.
|
||||
-- Need small sphere to get cone out.
|
||||
local origin2d = {x=origin.x, y=0, z=origin.z}
|
||||
local pos2d = {x=pos.x, y=0, z=pos.z}
|
||||
local radius = vector.distance(origin2d, pos2d)
|
||||
if radius <= 2 or (radius <= maxdist and vector.angle(vdir, vector.direction(origin2d, pos2d)) < scan_angle) then
|
||||
local enc_pos = minetest.hash_node_position(pos)
|
||||
if scanned[pname][enc_pos] ~= true then -- hasn't been scanned
|
||||
local name = minetest.get_node(pos).name
|
||||
if name == "air" then -- checkable
|
||||
table.insert(tocheck[pname], enc_pos) -- add to check list
|
||||
end
|
||||
scanned[pname][enc_pos] = true -- don't scan again
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- To check, scan all neighbors and determine if this node needs to be converted to light.
|
||||
local check_node = function(pname, pos, origin, vdir, maxdist, height, depth)
|
||||
local enc_pos = minetest.hash_node_position(pos)
|
||||
local name = minetest.get_node(pos).name
|
||||
scan_node(pname, vector.add(pos, {x=0,y=0,z=1}), origin, vdir, maxdist) -- north
|
||||
scan_node(pname, vector.add(pos, {x=1,y=0,z=0}), origin, vdir, maxdist) -- east
|
||||
scan_node(pname, vector.add(pos, {x=0,y=0,z=-1}), origin, vdir, maxdist) -- south
|
||||
scan_node(pname, vector.add(pos, {x=-1,y=0,z=0}), origin, vdir, maxdist) -- west
|
||||
if pos.y > origin.y - depth then
|
||||
scan_node(pname, vector.add(pos, {x=0,y=-1,z=0}), origin, vdir, maxdist) -- down
|
||||
end
|
||||
if pos.y < origin.y + height then
|
||||
scan_node(pname, vector.add(pos, {x=0,y=1,z=0}), origin, vdir, maxdist) -- up
|
||||
end
|
||||
if pos.y < max_depth[pname] then
|
||||
max_depth[pname] = pos.y
|
||||
end
|
||||
end
|
||||
|
||||
local use_finder = function(player, itemstack, radius, height, depth, wear)
|
||||
local pname = player:get_player_name()
|
||||
local pos = vector.add(vector.round(player:get_pos()), {x=0,y=0,z=0}) -- position of wand
|
||||
local theta = math.fmod(player:get_look_horizontal() + math.pi/2, 2*math.pi)
|
||||
local vdir = vector.normalize({x=math.cos(theta), y=0, z=math.sin(theta)})
|
||||
local key_stats = player:get_player_control()
|
||||
local wear_cost = wear
|
||||
|
||||
-- Initialize temporary tables for safety.
|
||||
scanned[pname] = {}
|
||||
tocheck[pname] = {}
|
||||
max_depth[pname] = pos.y
|
||||
-- Search starts at finder position.
|
||||
table.insert(tocheck[pname], minetest.hash_node_position(pos))
|
||||
local count = 1
|
||||
while count <= table.getn(tocheck[pname]) and count <= maxcount do
|
||||
check_node(pname, minetest.get_position_from_hash(tocheck[pname][count]), pos, vdir, radius, height, depth)
|
||||
count = count + 1
|
||||
end
|
||||
count = count - 1
|
||||
if debug then -- print statistics
|
||||
minetest.debug("depth_finder: y = "..tostring(pos.y)..", scan = "..
|
||||
tostring(tlength(scanned[pname]))..", check = "..tostring(count)..", depth = "..
|
||||
tostring(max_depth[pname]))
|
||||
end
|
||||
minetest.chat_send_player(pname, "depth = "..tostring(max_depth[pname] - pos.y))
|
||||
-- Clear temporary tables, which could be large.
|
||||
scanned[pname] = {}
|
||||
tocheck[pname] = {}
|
||||
max_depth[pname] = 0
|
||||
-- Add wear to finder
|
||||
itemstack:add_wear(wear_cost)
|
||||
return itemstack
|
||||
end
|
||||
|
||||
minetest.register_tool("cavetools:depth_finder_flint", {
|
||||
description = "Flint Depth Finder",
|
||||
inventory_image = "cavetools_depth_finder_flint.png",
|
||||
stack_max = 1,
|
||||
on_use = function(itemstack, player, pointed_thing)
|
||||
local radius = 30
|
||||
local height = 6
|
||||
local depth = 40
|
||||
local wear = math.floor(65535/25)
|
||||
local worn_item = use_finder(player, itemstack, radius, height, depth, wear)
|
||||
return worn_item
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_tool("cavetools:depth_finder_diamond", {
|
||||
description = "Diamond Depth Finder",
|
||||
inventory_image = "cavetools_depth_finder_diamond.png",
|
||||
stack_max = 1,
|
||||
on_use = function(itemstack, player, pointed_thing)
|
||||
local radius = 50
|
||||
local height = 10
|
||||
local depth = 80
|
||||
local wear = math.floor(65535/40)
|
||||
local worn_item = use_finder(player, itemstack, radius, height, depth, wear)
|
||||
return worn_item
|
||||
end,
|
||||
})
|
||||
|
||||
-- Need default for crafting recipe.
|
||||
-- Example craft recipe.
|
||||
if minetest.get_modpath("default") ~= nil then
|
||||
minetest.register_craft({
|
||||
output = "cavetools:depth_finder_flint",
|
||||
recipe = {
|
||||
{"default:flint", "default:flint"}
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "cavetools:depth_finder_diamond",
|
||||
recipe = {
|
||||
{"default:diamond", "default:diamond"}
|
||||
}
|
||||
})
|
||||
end
|
274
flash_lamps.lua
Normal file
@ -0,0 +1,274 @@
|
||||
-- Flash Lamps (formerly Wand of Illumination) [flash_lamps]
|
||||
-- by David G (kestral246@gmail.com)
|
||||
-- 2020-06-22
|
||||
|
||||
-- Lights up what's in front, but only for a moment.
|
||||
-- Provides a flash_lamp, flash_wand, and super_flash_lamp.
|
||||
|
||||
-- How bright and wide to make lights.
|
||||
-- For reference, the default:torch has a brightness of 12.
|
||||
local brightness_value = 11
|
||||
local light_cone = math.pi/3 -- corresponds to 120°
|
||||
|
||||
-- Maximum number of nodes to check (use debug to determine).
|
||||
local maxcount = 100000
|
||||
|
||||
-- The wear, mana, and radius can now be set independently for each lamp tool.
|
||||
-- For extended range, all of these values are doubled.
|
||||
|
||||
-- Setting to allow optional use of ABM for light decay.
|
||||
-- Make sure all lights have faded before disabling this option.
|
||||
local use_abm = minetest.settings:get_bool("cavetools_use_abm", false)
|
||||
if use_abm then
|
||||
minetest.log("warning", "Flash Lamps using ABM for light decay.")
|
||||
end
|
||||
|
||||
-- Set to true to print debug statistics.
|
||||
local debug = false
|
||||
|
||||
-- Check for mana mod
|
||||
local using_mana_mod = false
|
||||
if minetest.get_modpath("mana") ~= nil then
|
||||
using_mana_mod = true
|
||||
end
|
||||
|
||||
local scanned = {} -- Set containing scanned nodes, so they don't get scanned multiple times.
|
||||
local tocheck = {} -- Table of nodes to check.
|
||||
local tolight = {} -- Table of nodes that need to be converted to fill lights.
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
local pname = player:get_player_name()
|
||||
scanned[pname] = {}
|
||||
tocheck[pname] = {}
|
||||
tolight[pname] = {}
|
||||
end)
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
local pname = player:get_player_name()
|
||||
scanned[pname] = nil
|
||||
tocheck[pname] = nil
|
||||
tolight[pname] = nil
|
||||
end)
|
||||
|
||||
local mana_check = function(player, cost)
|
||||
local allowed
|
||||
if cost > 0 then
|
||||
if using_mana_mod then
|
||||
if mana.subtract(player:get_player_name(), cost) then
|
||||
allowed = true
|
||||
else
|
||||
allowed = false
|
||||
end
|
||||
else
|
||||
allowed = true
|
||||
end
|
||||
return allowed
|
||||
else -- always allowed when not using mana
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("cavetools:light", {
|
||||
description = "Flash Lamp Light",
|
||||
drawtype = "airlike",
|
||||
walkable = false,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
light_source = brightness_value,
|
||||
pointable = false,
|
||||
buildable_to = true,
|
||||
drops = "",
|
||||
groups = {cracky = 3, oddly_breakable_by_hand = 3, fill_hidden = 1, not_in_creative_inventory = 1},
|
||||
on_timer = function(pos) -- use node timer
|
||||
minetest.remove_node(pos)
|
||||
end,
|
||||
})
|
||||
|
||||
if use_abm then -- optional ABM
|
||||
minetest.register_abm({
|
||||
nodenames = {"cavetools:light"},
|
||||
interval = 2.0, -- need to tune
|
||||
chance = 10, -- need to tune
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
minetest.set_node(pos, {name = "air"})
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
-- Determine number of elements in table, for summary output.
|
||||
local tlength = function(T)
|
||||
local count = 0
|
||||
for _ in pairs(T) do count = count + 1 end
|
||||
return count
|
||||
end
|
||||
|
||||
-- Scan neighboring nodes, flag for checking if air.
|
||||
local scan_node = function(pname, pos, origin, vdir, maxdist)
|
||||
-- Update to send out a cone of light in direction pointed.
|
||||
-- Need small sphere to get cone of light out.
|
||||
local radius = vector.distance(origin, pos)
|
||||
if radius <= 2 or (radius <= maxdist and vector.angle(vdir, vector.direction(origin, pos)) < light_cone) then
|
||||
local enc_pos = minetest.hash_node_position(pos)
|
||||
if scanned[pname][enc_pos] ~= true then -- hasn't been scanned
|
||||
local name = minetest.get_node(pos).name
|
||||
if name == "air" then -- checkable
|
||||
table.insert(tocheck[pname], enc_pos) -- add to check list
|
||||
end
|
||||
scanned[pname][enc_pos] = true -- don't scan again
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- To check, scan all neighbors and determine if this node needs to be converted to light.
|
||||
local check_node = function(pname, pos, origin, vdir, maxdist)
|
||||
local enc_pos = minetest.hash_node_position(pos)
|
||||
local name = minetest.get_node(pos).name
|
||||
scan_node(pname, vector.add(pos, {x=0,y=0,z=1}), origin, vdir, maxdist) -- north
|
||||
scan_node(pname, vector.add(pos, {x=1,y=0,z=0}), origin, vdir, maxdist) -- east
|
||||
scan_node(pname, vector.add(pos, {x=0,y=0,z=-1}), origin, vdir, maxdist) -- south
|
||||
scan_node(pname, vector.add(pos, {x=-1,y=0,z=0}), origin, vdir, maxdist) -- west
|
||||
scan_node(pname, vector.add(pos, {x=0,y=-1,z=0}), origin, vdir, maxdist) -- down
|
||||
scan_node(pname, vector.add(pos, {x=0,y=1,z=0}), origin, vdir, maxdist) -- up
|
||||
if name == "air" and ((pos.x%4 == 0 and pos.y%8 == 0 and pos.z%4 == 0) or
|
||||
(pos.x%4 == 2 and pos.y%8 == 4 and pos.z%4 == 2))
|
||||
and minetest.get_node_light(pos) < brightness_value then
|
||||
table.insert(tolight[pname], enc_pos)
|
||||
end
|
||||
end
|
||||
|
||||
local use_lamp = function(player, itemstack, radius, wear, mana)
|
||||
local pname = player:get_player_name()
|
||||
local pos = vector.add(vector.round(player:get_pos()), {x=0,y=1,z=0}) -- position of wand
|
||||
local theta = math.fmod(player:get_look_horizontal() + math.pi/2, 2*math.pi)
|
||||
local phi = player:get_look_vertical() + math.pi/2
|
||||
local vdir = vector.normalize({x=math.sin(phi)*math.cos(theta), y=math.cos(phi), z=math.sin(phi)*math.sin(theta)})
|
||||
-- For debug only.
|
||||
--minetest.chat_send_player(pname, "theta = "..tostring(theta)..", phi = "..tostring(phi)..", vdir = "..tostring(minetest.serialize(vdir)))
|
||||
local key_stats = player:get_player_control()
|
||||
local wear_cost = wear
|
||||
local mana_cost = mana
|
||||
if key_stats.sneak or key_stats.aux1 then -- extended
|
||||
radius = 2 * radius
|
||||
wear_cost = 2 * wear_cost
|
||||
mana_cost = 2 * mana_cost
|
||||
end
|
||||
if mana_check(player, mana_cost) then
|
||||
-- Initialize temporary tables for safety.
|
||||
scanned[pname] = {}
|
||||
tocheck[pname] = {}
|
||||
tolight[pname] = {}
|
||||
-- Search starts at wand position.
|
||||
table.insert(tocheck[pname], minetest.hash_node_position(pos))
|
||||
local count = 1
|
||||
while count <= table.getn(tocheck[pname]) and count <= maxcount do
|
||||
check_node(pname, minetest.get_position_from_hash(tocheck[pname][count]), pos, vdir, radius)
|
||||
count = count + 1
|
||||
end
|
||||
count = count - 1
|
||||
if debug then -- print statistics
|
||||
minetest.debug("flash_lamps: y = "..tostring(pos.y)..", scan = "..
|
||||
tostring(tlength(scanned[pname]))..", check = "..tostring(count)..", lights = "..
|
||||
tostring(tlength(tolight[pname])))
|
||||
end
|
||||
-- Add lights to all locations flagged for lighting.
|
||||
for _,v in ipairs(tolight[pname]) do
|
||||
local fpos = minetest.get_position_from_hash(v)
|
||||
minetest.set_node(fpos, {name="cavetools:light"})
|
||||
if not use_abm then
|
||||
local timer = minetest.get_node_timer(fpos) -- use node timer
|
||||
timer:set(math.random(60), 0)
|
||||
end
|
||||
end
|
||||
-- Clear temporary tables, which could be large.
|
||||
scanned[pname] = {}
|
||||
tocheck[pname] = {}
|
||||
tolight[pname] = {}
|
||||
-- Add wear to wand
|
||||
itemstack:add_wear(wear_cost)
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_tool("cavetools:flash_wand", {
|
||||
description = "Flash Wand",
|
||||
inventory_image = "cavetools_flash_wand.png",
|
||||
stack_max = 1,
|
||||
on_use = function(itemstack, player, pointed_thing)
|
||||
local radius = 15 -- or 30
|
||||
local wear = math.floor(65535/25)
|
||||
local mana = 100
|
||||
local worn_item = use_lamp(player, itemstack, radius, wear, mana)
|
||||
return worn_item
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_tool("cavetools:flash_lamp", {
|
||||
description = "Flash Lamp",
|
||||
inventory_image = "cavetools_flash_lamp.png",
|
||||
stack_max = 1,
|
||||
on_use = function(itemstack, player, pointed_thing)
|
||||
local radius = 10 -- or 20
|
||||
local wear = math.floor(65535/15)
|
||||
local mana = 0
|
||||
local worn_item = use_lamp(player, itemstack, radius, wear, mana)
|
||||
return worn_item
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_tool("cavetools:super_flash_lamp", {
|
||||
description = "Super Flash Lamp",
|
||||
inventory_image = "cavetools_super_flash_lamp.png",
|
||||
stack_max = 1,
|
||||
on_use = function(itemstack, player, pointed_thing)
|
||||
local radius = 20 -- or 40
|
||||
local wear = math.floor(65535/40)
|
||||
local mana = 0
|
||||
local worn_item = use_lamp(player, itemstack, radius, wear, mana)
|
||||
return worn_item
|
||||
end,
|
||||
})
|
||||
|
||||
-- Need default for crafting recipe.
|
||||
-- Example craft recipe for wand.
|
||||
if minetest.get_modpath("default") ~= nil then
|
||||
minetest.register_craft({
|
||||
output = "cavetools:flash_wand",
|
||||
recipe = {
|
||||
{"default:mese_crystal"},
|
||||
{"group:stick"}
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
-- Need default and tnt mods for crafting recipe.
|
||||
-- Add copper or tin to make harder to craft.
|
||||
if minetest.get_modpath("default") ~= nil and minetest.get_modpath("tnt") ~= nil then
|
||||
minetest.register_craft({
|
||||
output = "cavetools:flash_lamp",
|
||||
recipe = {
|
||||
{"tnt:gunpowder", "tnt:gunpowder", "tnt:gunpowder"},
|
||||
{"", "default:tin_ingot", ""},
|
||||
{"", "group:stick", ""}
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "cavetools:flash_lamp",
|
||||
recipe = {
|
||||
{"tnt:gunpowder", "tnt:gunpowder", "tnt:gunpowder"},
|
||||
{"", "default:copper_ingot", ""},
|
||||
{"", "group:stick", ""}
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
-- Need default for crafting recipe.
|
||||
if minetest.get_modpath("default") ~= nil then
|
||||
minetest.register_craft({
|
||||
output = "cavetools:super_flash_lamp",
|
||||
recipe = {
|
||||
{"default:meselamp", "default:obsidian", "default:meselamp"},
|
||||
{"default:obsidian", "default:meselamp", "default:obsidian"},
|
||||
{"default:meselamp", "default:obsidian", "default:meselamp"}
|
||||
}
|
||||
})
|
||||
end
|
BIN
images/craft_diamond.png
Normal file
After Width: | Height: | Size: 935 B |
BIN
images/craft_flint.png
Normal file
After Width: | Height: | Size: 739 B |
BIN
images/craft_lamp1.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
images/craft_lamp2.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
images/craft_super.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
images/craft_wand.png
Normal file
After Width: | Height: | Size: 873 B |
9
init.lua
Normal file
@ -0,0 +1,9 @@
|
||||
-- Cave Tools [cavetools]
|
||||
|
||||
dofile(minetest.get_modpath("cavetools").."/depth_finder.lua")
|
||||
dofile(minetest.get_modpath("cavetools").."/flash_lamps.lua")
|
||||
|
||||
if minetest.get_modpath("default") ~= nil then
|
||||
dofile(minetest.get_modpath("cavetools").."/ladder_overrides.lua")
|
||||
end
|
||||
|
29
ladder_overrides.lua
Normal file
@ -0,0 +1,29 @@
|
||||
-- Cave Ladders [cave_ladders]
|
||||
-- by David G (kestral246@gmail.com)
|
||||
-- 2020-06-22
|
||||
|
||||
minetest.override_item("default:ladder_wood", {
|
||||
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
||||
if clicker:get_wielded_item():get_name() == "default:ladder_wood" then
|
||||
local below = {x = pos.x, y = pos.y - 1, z = pos.z}
|
||||
if minetest.get_node(below).name == "air" then
|
||||
minetest.set_node(below, {name = "default:ladder_wood", param2 = node.param2})
|
||||
itemstack:take_item(1)
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
minetest.override_item("default:ladder_steel", {
|
||||
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
||||
if clicker:get_wielded_item():get_name() == "default:ladder_steel" then
|
||||
local below = {x = pos.x, y = pos.y - 1, z = pos.z}
|
||||
if minetest.get_node(below).name == "air" then
|
||||
minetest.set_node(below, {name = "default:ladder_steel", param2 = node.param2})
|
||||
itemstack:take_item(1)
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
})
|
3
mod.conf
Normal file
@ -0,0 +1,3 @@
|
||||
name = cavetools
|
||||
description = Some useful tools for exploring caves.
|
||||
optional_depends = default, mana, tnt
|
BIN
screenshot.png
Normal file
After Width: | Height: | Size: 121 KiB |
BIN
textures/cavetools_depth_finder_diamond.png
Normal file
After Width: | Height: | Size: 328 B |
BIN
textures/cavetools_depth_finder_flint.png
Normal file
After Width: | Height: | Size: 205 B |
BIN
textures/cavetools_flash_lamp.png
Normal file
After Width: | Height: | Size: 176 B |
BIN
textures/cavetools_flash_wand.png
Normal file
After Width: | Height: | Size: 161 B |
BIN
textures/cavetools_super_flash_lamp.png
Normal file
After Width: | Height: | Size: 173 B |