diff --git a/README.md b/README.md index 1b70518..7b52b03 100644 --- a/README.md +++ b/README.md @@ -7,26 +7,21 @@ Combines various tech to allow advanced mining operations. * Orehud: The original Oretracker mod with a single command to toggle the mod on or off per individual player. * Xray: Based on Orehud except trackes non-ores and makes them appear invisible. -### Planned features for both mods - -* Require a priviledge for both mods to prevent every player from using all features. (Perhaps you allow your regulars only orehud but not xray) - ## Orehud Displays ore positions via the player's HUD. > `/orehud` toggles the rendering of the ore positions on or off. -## Xray (Comming Soon) +## Xray Hides unwanted stone (and other varients) from view, only showing a empty node in it's wake. > `/xray` toggles the unwanted stone from visible to invisible (on or off). -### To be done +Yes, because xray interacts server side, all clients can make use of a single players client with xray. (This means you can see other players and ores they can see too by their xray) -* Use the pre-existing orehud code in a seperate mod for tracking stone (including varients). -* Make replacement nodes that are "invisible" with a general category feature (light grey for stone, dark red for netherrack, etc.)\* -* When wished to be on, swap nodes in the detect range from their visible to invisble counterparts. +## Common Issues -\* I need to make invisible counterparts for all varients so you still get the original resource. +* It was found that if the server crashes while a player is using xray, xray's nodes are kept. Created a special mode (fix_mode) to attempt to repair nodes which should return back to their original uppon detection. (If fix_mode is left on in production other players xrays can be overriden) +* It is possible to get xray nodes to say simply by logging off, xray attempts to cleanup nodes by players who are attempting to log out. (Please make an issue report with any logs and screenshots/video showing this still occurs) diff --git a/orehud/init.lua b/orehud/init.lua index d41c17f..9bdfb8d 100644 --- a/orehud/init.lua +++ b/orehud/init.lua @@ -191,9 +191,16 @@ minetest.register_on_leaveplayer(function(player, timeout) end end) +-- A priv for those to use this power +minetest.register_privilege("orehud", { + description = "Oretracker Orehud Priv", + give_to_singleplayer = true -- Also given to those with server priv +}) + minetest.register_chatcommand("orehud", { privs = { shout = true, + orehud = true -- Require our own priv }, func = function(name, param) if orehud.p_stats[name] then diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000..98df189 Binary files /dev/null and b/screenshot.png differ diff --git a/xray/LICENSE b/xray/LICENSE new file mode 100644 index 0000000..a2d2240 --- /dev/null +++ b/xray/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Beanzilla + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/xray/README.md b/xray/README.md new file mode 100644 index 0000000..bd2857c --- /dev/null +++ b/xray/README.md @@ -0,0 +1,38 @@ +# Ore Tracker > Xray + +Hides stone and stone varients from view. + +## About this mod + +This mod provides graphical counterparts for stone and stone varients to appear invisible. + +Simply use `/xray` to enable or disable displaying the stone or stone varients around you. + +> If your server crashes while any of your players are using xray it may cause residual invisible nodes... simply enable the fix_mode and then wander around the area they were at. (make sure you disable fix_mode in production, as it can overwrite other player's xray zones) + +## How it works + +When you issue `/xray` and it becomes active, it checks a cube like area around you, if within this scan area it detects stone for example it then swaps it with it's own stone node (Which simply is a transparent node, but the counterpart was made so I could replace particular stone varients without causing the player to only get stone and nothing else). Reverse the process for reverting the invisible counterpart back to the visible node. + +> Yes you can see other player's xray's since there isn't a way to hide nodes just for one client but show them for other clients. + +## Settings + +### Detect Range + +The distance at which nodes will be swapped. (Higher numbers means more blocks swapped but might increase server/client loads) + +> Recommended detect_range of 6. (No more than 16) + +### Scan Frequency + +The rate at which nodes will be checked and swapped. (Lower numbers means more "updates" making it smoother to move around and see the environment change, but might increase server/client loads) + +> Recommended scan_frequency of 1. (Use 0 or negative numbers for instantanious "updates", This number is in seconds) + +### Light Level + +The level that xray nodes emit light. (0 is minimum and 14 is maximum, dictated by minetest) + +> Recommended level 4. (This makes xray a dark dull but if you don't mind players never using torches you could make this higher) + diff --git a/xray/api.lua b/xray/api.lua new file mode 100644 index 0000000..393472a --- /dev/null +++ b/xray/api.lua @@ -0,0 +1,136 @@ + +-- Adds a node to track, only if that node actually is a valid node +xray.add_node = function(nodename) + if minetest.registered_nodes[nodename] then + table.insert(xray.nodes, nodename) + else + minetest.log("action", "[oretracker-xray] Failed to add '"..nodename.."' as it is a unregistered node.") + end +end + +-- Swaps with one of the registered nodes that has the invisiblity factor +xray.add_pos = function(pname, pos) + local current = minetest.get_node_or_nil(pos) + if current == nil then + minetest.log("action", "[oretracker-xray] Failed to obtain node at "..minetest.pos_to_string(pos).." for swap.") + end + current = current.name + --minetest.log("action", "[oretracker-xray] Swapping "..current) + local nps = xray.store[pname] or {} + table.insert(nps, pos) + -- Place a switch here to identify which kind of node would be best used here + if current == "default:stone" then + minetest.swap_node(pos, {name="xray:mtg_stone"}) + elseif current == "default:desert_stone" then + minetest.swap_node(pos, {name="xray:mtg_dstone"}) + elseif current == "default:sandstone" then + minetest.swap_node(pos, {name="xray:mtg_sstone"}) + elseif current == "default:desert_sandstone" then + minetest.swap_node(pos, {name="xray:mtg_dsstone"}) + elseif current == "default:silver_sandstone" then + minetest.swap_node(pos, {name="xray:mtg_ssstone"}) + elseif current == "mcl_core:stone" then + minetest.swap_node(pos, {name="xray:mcl_stone"}) + elseif current == "mcl_core:granite" then + minetest.swap_node(pos, {name="xray:mcl_granite"}) + elseif current == "mcl_core:andesite" then + minetest.swap_node(pos, {name="xray:mcl_andesite"}) + elseif current == "mcl_core:diorite" then + minetest.swap_node(pos, {name="xray:mcl_diorite"}) + elseif current == "mcl_core:sandstone" then + minetest.swap_node(pos, {name="xray:mcl_sstone"}) + elseif current == "mcl_core:redsandstone" then + minetest.swap_node(pos, {name="xray:mcl_rsstone"}) + elseif current == "mcl_blackstone:blackstone" then + minetest.swap_node(pos, {name="xray:mcl_bstone"}) + elseif current == "mcl_blackstone:basalt" then + minetest.swap_node(pos, {name="xray:mcl_basalt"}) + elseif current == "mcl_nether:netherrack" then + minetest.swap_node(pos, {name="xray:mcl_netherrack"}) + end + -- Stone, Diorite, Anasite, Granite, etc. + xray.store[pname] = nps +end + +-- Clears all invisible nodes back to their originals (per player) +xray.clear_pos = function(pname) + --local player = minetest.get_player_by_name(pname) + local wps = xray.store[pname] or {} + for i, v in ipairs(wps) do + local node = minetest.get_node_or_nil(v) + if node == nil then + minetest.log("action", "[oretracker-xray] Failed to obtain node at "..minetest.pos_to_string(v).." for revert ("..i..")") + end + node = node.name + --minetest.log("action", "[oretracker-xray] Reverting "..current) + -- Place a switch here to identify what node should be put back here + if node == "xray:mtg_stone" then + minetest.swap_node(v, {name="default:stone"}) + elseif node == "xray:mtg_dstone" then + minetest.swap_node(v, {name="default:desert_stone"}) + elseif node == "xray:mtg_sstone" then + minetest.swap_node(v, {name="default:sandstone"}) + elseif node == "xray:mtg_dsstone" then + minetest.swap_node(v, {name="default:desert_sandstone"}) + elseif node == "xray:mtg_ssstone" then + minetest.swap_node(v, {name="default:silver_sandstone"}) + elseif node == "xray:mcl_stone" then + minetest.swap_node(v, {name="mcl_core:stone"}) + elseif node == "xray:mcl_granite" then + minetest.swap_node(v, {name="mcl_core:granite"}) + elseif node == "xray:mcl_andesite" then + minetest.swap_node(v, {name="mcl_core:andesite"}) + elseif node == "xray:mcl_diorite" then + minetest.swap_node(v, {name="mcl_core:diorite"}) + elseif node == "xray:mcl_sstone" then + minetest.swap_node(v, {name="mcl_core:sandstone"}) + elseif node == "xray:mcl_rsstone" then + minetest.swap_node(v, {name="mcl_core:redsandstone"}) + elseif node == "xray:mcl_bstone" then + minetest.swap_node(v, {name="mcl_blackstone:blackstone"}) + elseif node == "xray:mcl_basalt" then + minetest.swap_node(v, {name="mcl_blackstone:basalt"}) + elseif node == "xray:mcl_netherrack" then + minetest.swap_node(v, {name="mcl_nether:netherrack"}) + end + end + xray.store[pname] = {} +end + +-- Attempt to repair the damage to this node (In the process of development I found my system made a ball of unrepairable goo, invisible blocks) +xray.fix_pos = function (pos) + local node = minetest.get_node_or_nil(pos) + if node == nil then + minetest.log("action", "[oretracker-xray] Failed to obtain node at "..minetest.pos_to_string(pos).." for revert (fix_pos)") + end + node = node.name + if node == "xray:mtg_stone" then + minetest.swap_node(pos, {name="default:stone"}) + elseif node == "xray:mtg_dstone" then + minetest.swap_node(pos, {name="default:desert_stone"}) + elseif node == "xray:mtg_sstone" then + minetest.swap_node(pos, {name="default:sandstone"}) + elseif node == "xray:mtg_dsstone" then + minetest.swap_node(pos, {name="default:desert_sandstone"}) + elseif node == "xray:mtg_ssstone" then + minetest.swap_node(pos, {name="default:silver_sandstone"}) + elseif node == "xray:mcl_stone" then + minetest.swap_node(pos, {name="mcl_core:stone"}) + elseif node == "xray:mcl_granite" then + minetest.swap_node(pos, {name="mcl_core:granite"}) + elseif node == "xray:mcl_andesite" then + minetest.swap_node(pos, {name="mcl_core:andesite"}) + elseif node == "xray:mcl_diorite" then + minetest.swap_node(pos, {name="mcl_core:diorite"}) + elseif node == "xray:mcl_sstone" then + minetest.swap_node(pos, {name="mcl_core:sandstone"}) + elseif node == "xray:mcl_rsstone" then + minetest.swap_node(pos, {name="mcl_core:redsandstone"}) + elseif node == "xray:mcl_bstone" then + minetest.swap_node(pos, {name="mcl_blackstone:blackstone"}) + elseif node == "xray:mcl_basalt" then + minetest.swap_node(pos, {name="mcl_blackstone:basalt"}) + elseif node == "xray:mcl_netherrack" then + minetest.swap_node(pos, {name="mcl_nether:netherrack"}) + end +end \ No newline at end of file diff --git a/xray/init.lua b/xray/init.lua new file mode 100644 index 0000000..b9b8b14 --- /dev/null +++ b/xray/init.lua @@ -0,0 +1,198 @@ +-- https://rubenwardy.com/minetest_modding_book/en/map/environment.html#finding-nodes + +-- A public API +xray = {} + +xray.S = minetest.get_translator("xray") +xray.modpath = minetest.get_modpath("xray") +xray.store = {} +xray.p_stats = {} + +-- Settings +-- Do not set detect_range to a very high number it may cause extreme loads when there are multiple players with this range +-- Recommended range is 6 blocks +xray.detect_range = 6 -- Range in blocks +-- 0 or negative is instantanious updates (Which greatly impacts the server/client) +-- Recommended frequency is 1 second. +xray.scan_frequency = 1 -- Frequency in seconds +-- Light level that xray nodes emit (Max is 14 min is 0) +-- Recommended light_level is 4. (Provides enough light to use the mod, might need to use torches if you want it lighter, or adjust here) +xray.light_level = 4 -- From 0-14 + +-- Only turn this on if you have strange blobs of invisible blocks (due to a server crash, etc.) +local fix_mode = false + +-- This attempts to detect the gamemode +if not minetest.registered_nodes["default:stone"] then + if not minetest.registered_nodes["mcl_core:stone"] then + xray.gamemode = "N/A" + else + xray.gamemode = "MCL" + -- Attempt to determine if it's MCL5 or MCL2 + if not minetest.registered_nodes["mcl_nether:ancient_debris"] then + xray.gamemode = "MCL2" + else + xray.gamemode = "MCL5" + end + end +else + xray.gamemode = "MTG" +end + +minetest.log("action", "[oretracker-xray] Detected game "..xray.gamemode..".") + +-- Form a container to track what ores we want to follow +xray.nodes = {} + +-- Make our counterparts +dofile(xray.modpath .. "/register.lua") + +-- Make our api +dofile(xray.modpath .. "/api.lua") + +-- Use api to assign ores we know/should be caring about +if xray.gamemode == "MCL2" or xray.gamemode == "MCL5" then + xray.add_node("mcl_core:stone") -- xray:mcl_stone + xray.add_node("mcl_core:granite") -- xray:mcl_granite + xray.add_node("mcl_core:andesite") -- xray:mcl_andesite + xray.add_node("mcl_core:diorite") -- xray:mcl_diorite + xray.add_node("mcl_core:sandstone") -- xray:mcl_sstone + xray.add_node("mcl_core:redsandstone") -- xray:mcl_rsstone +end + +if xray.gamemode == "MCL5" then + xray.add_node("mcl_blackstone:blackstone") -- xray:mcl_bstone + xray.add_node("mcl_blackstone:basalt") -- xray:mcl_basalt + xray.add_node("mcl_nether:netherrack") -- xray:mcl_netherrack +end + +if xray.gamemode == "MTG" then + xray.add_node("default:stone") -- xray:mtg_stone + xray.add_node("default:desert_stone") -- xray:mtg_dstone + xray.add_node("default:sandstone") -- xray:mtg_sstone + xray.add_node("default:desert_sandstone") -- xray:mtg_dsstone + xray.add_node("default:silver_sandstone") -- xray:mtg_ssstone +end + +-- Include our nodes so we can cleanup after ourselves +xray.add_node("xray:mtg_stone") +xray.add_node("xray:mtg_dstone") +xray.add_node("xray:mtg_sstone") +xray.add_node("xray:mtg_dsstone") +xray.add_node("xray:mtg_ssstone") +xray.add_node("xray:mcl_stone") +xray.add_node("xray:mcl_granite") +xray.add_node("xray:mcl_andesite") +xray.add_node("xray:mcl_diorite") +xray.add_node("xray:mcl_sstone") +xray.add_node("xray:mcl_rsstone") +xray.add_node("xray:mcl_bstone") +xray.add_node("xray:mcl_basalt") +xray.add_node("xray:mcl_netherrack") + +local size = 0 +local result = "Nodes: " +for i, v in ipairs(xray.nodes) do + result = result..v.." " + size = size + 1 +end +minetest.log("action", "[oretracker-xray] Found "..size.." nodes configured.") +minetest.log("action", "[oretracker-xray] "..result) + +-- Itterates an area of nodes, then swaps nodes if stone or stone varient +xray.check_player = function(p) + local pos = p:get_pos() + local pname = p:get_player_name() + local p1 = vector.subtract(pos, {x = xray.detect_range, y = xray.detect_range, z = xray.detect_range}) + local p2 = vector.add(pos, {x = xray.detect_range, y = xray.detect_range, z = xray.detect_range}) + local area = minetest.find_nodes_in_area(p1, p2, xray.nodes) + for i=1, #area do + local node = minetest.get_node_or_nil(area[i]) + if node == nil then + minetest.log("action", "[oretracker-xray] Failed to obtain node at "..minetest.pos_to_string(area[1], 1)..".") + else + local delta = vector.subtract(area[i], pos) + local distance = (delta.x*delta.x) + (delta.y*delta.y) + (delta.z*delta.z) + if distance <= xray.detect_range*xray.detect_range then + --distance = string.format("%.0f", math.sqrt(distance)) + -- Place the counterpart + --minetest.log("action", "xray "..pname.." "..minetest.pos_to_string(area[1], 1)) + if xray.p_stats[pname] then + -- Adds the counter since we are enabled + xray.add_pos(pname, area[i]) + elseif string.find(node.name, "xray") and fix_mode then + -- Attempt to cleanup that node if it's one of ours + -- Warning don't leave fix_mode on all the time, can cause someone elses xray to be blocked because of ordering + xray.fix_pos(area[i]) + end + end + end + end +end + +-- Now register with minetest to actually do something + +local interval = 0 +minetest.register_globalstep(function(dtime) + interval = interval - dtime + if interval <= 0 then + for _, player in ipairs(minetest.get_connected_players()) do + local p = player + if not minetest.is_player(p) then + p = minetest.get_player_by_name(p) + end + if p ~= nil then + -- I need to clean up the player's nodes added by the latter code + xray.clear_pos(p:get_player_name()) + -- Now make new nodes + xray.check_player(p) + end + end + interval = xray.scan_frequency + end +end) + +minetest.register_on_joinplayer(function(player, laston) + xray.p_stats[player:get_player_name()] = false +end) + +minetest.register_on_leaveplayer(function(player, timeout) + local indx = 0 + local found = false + for pname, val in ipairs(xray.p_stats) do + if pname == player:get_player_name() then + found = true + break + end + indx = indx + 1 + end + if found then + -- Attempt to cleanup that player's invisible nodes before they log off + xray.p_stats[player:get_player_name()] = false + minetest.log("action", "Cleaning up "..player:get_player_name().." as they wish to leave.") + xray.clear_pos(player:get_player_name()) + table.remove(xray.p_stats, indx) + end +end) + +-- A priv for players so they can't abuse this power +minetest.register_privilege("xray", { + description = "Oretracker Xray Priv", + give_to_singleplayer = true -- Also given to those with server priv +}) + +minetest.register_chatcommand("xray", { + privs = { + shout = true, + xray = true -- Require our xray + }, + func = function(name, param) + if xray.p_stats[name] then + xray.p_stats[name] = false + minetest.chat_send_player(name, "Xray: OFF") + else + xray.p_stats[name] = true + minetest.chat_send_player(name, "Xray: ON") + end + end, +}) diff --git a/xray/mcl.png b/xray/mcl.png new file mode 100644 index 0000000..61081c4 Binary files /dev/null and b/xray/mcl.png differ diff --git a/xray/mod.conf b/xray/mod.conf new file mode 100644 index 0000000..792a977 --- /dev/null +++ b/xray/mod.conf @@ -0,0 +1,4 @@ +name = xray +description = Hides stone and stone varients from view. +author = ApolloX +optional_depends = default, mcl_core, mcl_sounds diff --git a/xray/mtg.png b/xray/mtg.png new file mode 100644 index 0000000..56170d2 Binary files /dev/null and b/xray/mtg.png differ diff --git a/xray/register.lua b/xray/register.lua new file mode 100644 index 0000000..5697616 --- /dev/null +++ b/xray/register.lua @@ -0,0 +1,218 @@ + +-- MTG +if xray.gamemode == "MTG" then + minetest.register_node("xray:mtg_stone", { + description = xray.S("Xray Stone"), + tiles = {"xray_stone.png"}, + groups = {cracky = 3, stone = 1}, + drop = "default:cobble", + drawtype = "glasslike", + sunlight_propagates = true, + legacy_mineral = true, + light_source = xray.light_level, + sounds = default.node_sound_stone_defaults(), + }) + minetest.register_node("xray:mtg_dstone", { + description = xray.S("Xray Stone"), + tiles = {"xray_stone.png"}, + groups = {cracky = 3, stone = 1}, + drop = "default:desert_cobble", + drawtype = "glasslike", + sunlight_propagates = true, + legacy_mineral = true, + light_source = xray.light_level, + sounds = default.node_sound_stone_defaults(), + }) + minetest.register_node("xray:mtg_sstone", { + description = xray.S("Xray Stone"), + tiles = {"xray_stone.png"}, + groups = {cracky = 3, stone = 1}, + drop = "default:sandstone", + drawtype = "glasslike", + sunlight_propagates = true, + legacy_mineral = true, + light_source = xray.light_level, + sounds = default.node_sound_stone_defaults(), + }) + minetest.register_node("xray:mtg_dsstone", { + description = xray.S("Xray Stone"), + tiles = {"xray_stone.png"}, + groups = {cracky = 3, stone = 1}, + drop = "default:desert_sandstone", + drawtype = "glasslike", + sunlight_propagates = true, + legacy_mineral = true, + light_source = xray.light_level, + sounds = default.node_sound_stone_defaults(), + }) + minetest.register_node("xray:mtg_ssstone", { + description = xray.S("Xray Stone"), + tiles = {"xray_stone.png"}, + groups = {cracky = 3, stone = 1}, + drop = "default:silver_sandstone", + drawtype = "glasslike", + sunlight_propagates = true, + legacy_mineral = true, + light_source = xray.light_level, + sounds = default.node_sound_stone_defaults(), + }) +end + +-- MCL (2 and 5) +if xray.gamemode == "MCL2" or xray.gamemode == "MCL5" then + minetest.register_node("xray:mcl_stone", { + description = xray.S("Xray Stone"), + _doc_items_longdesc = xray.S("An Invisible block"), + _doc_items_hidden = true, + tiles = {"xray_stone.png"}, + is_ground_content = false, + stack_max = 1, + groups = {pickaxey=1, stone=1, building_block=1, material_stone=1}, + drawtype = "glasslike", + sunlight_propagates = true, + light_source = xray.light_level, + drop = 'mcl_core:cobble', + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 1.5, + _mcl_silk_touch_drop = false, + }) + minetest.register_node("xray:mcl_granite", { + description = xray.S("Xray Stone"), + _doc_items_longdesc = xray.S("An Invisible block"), + _doc_items_hidden = true, + tiles = {"xray_stone.png"}, + is_ground_content = false, + stack_max = 1, + groups = {pickaxey=1, stone=1, building_block=1, material_stone=1}, + drawtype = "glasslike", + sunlight_propagates = true, + light_source = xray.light_level, + drop = 'mcl_core:granite', + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 1.5, + _mcl_silk_touch_drop = false, + }) + minetest.register_node("xray:mcl_andesite", { + description = xray.S("Xray Stone"), + _doc_items_longdesc = xray.S("An Invisible block"), + _doc_items_hidden = true, + tiles = {"xray_stone.png"}, + is_ground_content = false, + stack_max = 1, + groups = {pickaxey=1, stone=1, building_block=1, material_stone=1}, + drawtype = "glasslike", + sunlight_propagates = true, + light_source = xray.light_level, + drop = 'mcl_core:andesite', + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 1.5, + _mcl_silk_touch_drop = false, + }) + minetest.register_node("xray:mcl_diorite", { + description = xray.S("Xray Stone"), + _doc_items_longdesc = xray.S("An Invisible block"), + _doc_items_hidden = true, + tiles = {"xray_stone.png"}, + is_ground_content = false, + light_source = xray.light_level, + stack_max = 1, + groups = {pickaxey=1, stone=1, building_block=1, material_stone=1}, + drawtype = "glasslike", + sunlight_propagates = true, + drop = 'mcl_core:diorite', + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 1.5, + _mcl_silk_touch_drop = false, + }) + minetest.register_node("xray:mcl_sstone", { + description = xray.S("Xray Stone"), + _doc_items_hidden = true, + _doc_items_longdesc = xray.S("An Invisible block"), + tiles = {"xray_stone.png"}, + is_ground_content = false, + light_source = xray.light_level, + stack_max = 1, + groups = {pickaxey=1, sandstone=1, normal_sandstone=1, building_block=1, material_stone=1}, + drawtype = "glasslike", + sunlight_propagates = true, + drop = 'mcl_core:sandstone', + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 0.8, + _mcl_hardness = 0.8, + _mcl_silk_touch_drop = false, + }) + minetest.register_node("xray:mcl_rsstone", { + description = xray.S("Xray Stone"), + _doc_items_hidden = true, + _doc_items_longdesc = xray.S("An Invisible block"), + tiles = {"xray_stone.png"}, + is_ground_content = false, + light_source = xray.light_level, + stack_max = 1, + groups = {pickaxey=1, sandstone=1, normal_sandstone=1, building_block=1, material_stone=1}, + drawtype = "glasslike", + sunlight_propagates = true, + drop = 'mcl_core:redsandstone', + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 0.8, + _mcl_hardness = 0.8, + _mcl_silk_touch_drop = false, + }) +end + +-- MCL (5 only) +if xray.gamemode == "MCL5" then + minetest.register_node("xray:mcl_bstone", { + description = xray.S("Xray Stone"), + _doc_items_hidden = true, + tiles = {"xray_dark.png"}, + light_source = xray.light_level, + sounds = mcl_sounds.node_sound_stone_defaults(), + is_ground_content = false, + stack_max = 1, + groups = {cracky = 3, pickaxey=2, material_stone=1}, + drawtype = "glasslike", + sunlight_propagates = true, + drop = 'mcl_blackstone:blackstone', + _mcl_blast_resistance = 2, + _mcl_hardness = 2, + _mcl_silk_touch_drop = false, + }) + minetest.register_node("xray:mcl_basalt", { + description = xray.S("Xray Stone"), + _doc_items_hidden = true, + tiles = {"xray_dark.png"}, + light_source = xray.light_level, + sounds = mcl_sounds.node_sound_stone_defaults(), + drawtype = "glasslike", + sunlight_propagates = true, + is_ground_content = false, + stack_max = 1, + groups = {cracky = 3, pickaxey=2, material_stone=1}, + drop = 'mcl_blackstone:basalt', + _mcl_blast_resistance = 2, + _mcl_hardness = 2, + _mcl_silk_touch_drop = false, + }) + minetest.register_node("xray:mcl_netherrack", { + description = xray.S("Xray Stone"), + _doc_items_hidden = true, + light_source = xray.light_level, + _doc_items_longdesc = xray.S("An Invisible block"), + stack_max = 1, + tiles = {"xray_nether.png"}, + is_ground_content = false, + groups = {pickaxey=1, building_block=1, material_stone=1}, + drawtype = "glasslike", + sunlight_propagates = true, + drop = 'mcl_nether:netherrack', + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 0.4, + _mcl_hardness = 0.4, + _mcl_silk_touch_drop = false, + }) +end \ No newline at end of file diff --git a/xray/textures/xray_dark.png b/xray/textures/xray_dark.png new file mode 100644 index 0000000..2f4cd90 Binary files /dev/null and b/xray/textures/xray_dark.png differ diff --git a/xray/textures/xray_nether.png b/xray/textures/xray_nether.png new file mode 100644 index 0000000..2768db2 Binary files /dev/null and b/xray/textures/xray_nether.png differ diff --git a/xray/textures/xray_stone.png b/xray/textures/xray_stone.png new file mode 100644 index 0000000..f3e62a6 Binary files /dev/null and b/xray/textures/xray_stone.png differ