diff --git a/crystals.lua b/crystals.lua index 81fbf61..e417e18 100644 --- a/crystals.lua +++ b/crystals.lua @@ -212,13 +212,21 @@ function magicalities.register_crystal(element, description, color) deco_type = "simple", place_on = "default:stone", sidelen = 16, - y_max = -30, y_min = -31000, - flags = "all_floors, all_ceilings", - - fill_ratio = 0.0008, + flags = "all_ceilings", + fill_ratio = 0.0004, + decoration = "magicalities:crystal_cluster_"..element, + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = "default:stone", + sidelen = 16, + y_max = -30, + y_min = -31000, + flags = "all_floors", + fill_ratio = 0.0004, decoration = "magicalities:crystal_cluster_"..element, }) diff --git a/focuses.lua b/focuses.lua index 5c8fc80..e4faee6 100644 --- a/focuses.lua +++ b/focuses.lua @@ -113,3 +113,156 @@ minetest.register_craftitem("magicalities:focus_swap", { return itemstack end }) + + +local tunneler_memory = {} +local tunneler_depth = 8 + +local function reset_tunnel(tid) + local infos = tunneler_memory['t' .. tid] + if not infos then return end + + local manip = minetest.get_voxel_manip() + local e1, e2 = manip:read_from_map(infos.minp, infos.maxp) + local area = VoxelArea:new{MinEdge=e1, MaxEdge=e2} + + local data = manip:get_data() + + for i in area:iterp(infos.minp, infos.maxp) do + if infos.data[i] ~= nil then + data[i] = infos.data[i] + end + end + + manip:set_data(data) + manip:write_to_map() + + tunneler_memory['t' .. tid] = nil + + t = false +end + +local function create_tunnel(pos, dir, owner) + -- Ensure no double tunnels + for id,data in pairs(tunneler_memory) do + if data.owner == owner then + return + end + end + + local minp + local maxp + + if dir.x < 0 or dir.y < 0 or dir.z < 0 then + maxp = vector.add(pos, dir) + minp = vector.add(pos, vector.multiply(dir, tunneler_depth)) + else + minp = vector.add(pos, dir) + maxp = vector.add(pos, vector.multiply(dir, tunneler_depth)) + end + + if dir.z ~= 0 then + minp.x = minp.x + -1 + maxp.x = maxp.x + 1 + + minp.y = minp.y + -1 + maxp.y = maxp.y + 1 + end + + if dir.y ~= 0 then + minp.z = minp.z + -1 + maxp.z = maxp.z + 1 + + minp.x = minp.x + -1 + maxp.x = maxp.x + 1 + end + + if dir.x ~= 0 then + minp.z = minp.z + -1 + maxp.z = maxp.z + 1 + + minp.y = minp.y + -1 + maxp.y = maxp.y + 1 + end + + -- Set the nodes + local manip = minetest.get_voxel_manip() + local e1, e2 = manip:read_from_map(minp, maxp) + local area = VoxelArea:new{MinEdge=e1, MaxEdge=e2} + + local data = manip:get_data() + + local c_air = minetest.get_content_id("air") + local c_tunnel = minetest.get_content_id("magicalities:tunnel_node") + local dtree = {} + local abort = false + + for i in area:iterp(minp, maxp) do + if data[i] ~= c_air then + dtree[i] = data[i] + data[i] = c_tunnel + elseif data[i] == c_tunnel then + abort = true + break + end + end + + if abort then return end + + -- Set nodes in map + manip:set_data(data) + manip:write_to_map() + + -- Save in cache + local cnum = math.random(10, 1000) + local comp1 = math.random(10, 1000) + local comp2 = math.random(10, 1000) + cnum = (math.ceil(comp2 + comp1 / cnum) + cnum) + + tunneler_memory['t' .. cnum] = { + data = dtree, + minp = minp, + maxp = maxp, + owner = owner, + } + + minetest.after(10, reset_tunnel, cnum) +end + +minetest.register_node("magicalities:tunnel_node", { + groups = {not_in_creative_inventory = 1}, + walkable = false, + pointable = false, + diggable = false, + drawtype = "glasslike_framed", + paramtype = "light", + sunlight_propagates = true, + tiles = {"magicalities_void.png"}, +}) + +minetest.register_craftitem("magicalities:focus_tunnel", { + description = "Wand Focus of Tunneling", + groups = {wand_focus = 1}, + inventory_image = "magicalities_focus_tunnel.png", + stack_max = 1, + _wand_requirements = { + ["air"] = 1 + }, + _wand_use = function (itemstack, user, pointed_thing) + if not pointed_thing.above or pointed_thing.type ~= "node" then return itemstack end + if not user or user:get_player_name() == "" then return itemstack end + local dir = user:get_look_dir() + local wm = minetest.dir_to_wallmounted(dir) + dir = minetest.wallmounted_to_dir(wm) + + minetest.after(0.1, create_tunnel, pointed_thing.above, dir, user:get_player_name()) + + return itemstack + end +}) + +minetest.register_on_shutdown(function () + for id in pairs(tunneler_memory) do + reset_tunnel(id) + end +end) diff --git a/textures/magicalities_focus_tunnel.png b/textures/magicalities_focus_tunnel.png new file mode 100644 index 0000000..7b0e2be Binary files /dev/null and b/textures/magicalities_focus_tunnel.png differ diff --git a/textures/magicalities_void.png b/textures/magicalities_void.png new file mode 100644 index 0000000..3cac879 Binary files /dev/null and b/textures/magicalities_void.png differ