From 6097e844cfa748af08f0259af9e9f1fe48a0fee2 Mon Sep 17 00:00:00 2001 From: Duane Robertson Date: Mon, 25 Apr 2016 01:16:53 -0500 Subject: [PATCH] all caves --- README.md | 2 +- depends.txt | 1 + fungal_tree.lua | 358 ++++++++++++++ init.lua | 68 +-- mapgen.lua | 434 +++++++++++------ nodes.lua | 544 ++++++++++++++++++++++ textures/caverealms_algae.png | Bin 0 -> 3094 bytes textures/caverealms_glow_obsidian.png | Bin 0 -> 162 bytes textures/caverealms_glow_obsidian2.png | Bin 0 -> 661 bytes textures/caverealms_hot_cobble.png | Bin 0 -> 431 bytes textures/caverealms_salty2.png | Bin 0 -> 330 bytes textures/caverealms_thin_ice.png | Bin 0 -> 679 bytes textures/fun_caves_algae.png | Bin 0 -> 3508 bytes textures/fun_caves_brain_coral.png | Bin 0 -> 479 bytes textures/fun_caves_dragon_eye.png | Bin 0 -> 2589 bytes textures/fun_caves_fungal_tree_fruit.png | Bin 0 -> 3269 bytes textures/fun_caves_fungal_tree_leaves.png | Bin 0 -> 2135 bytes textures/fun_caves_lichen.png | Bin 0 -> 2470 bytes textures/fun_caves_lumin_tree.png | Bin 0 -> 2293 bytes textures/fun_caves_moss.png | Bin 0 -> 2694 bytes textures/fun_caves_pillar_coral.png | Bin 0 -> 2086 bytes textures/fun_caves_staghorn_coral.png | Bin 0 -> 633 bytes textures/vmg_glowing_fungal.png | Bin 0 -> 1164 bytes textures/vmg_glowing_fungus.png | Bin 0 -> 5084 bytes textures/vmg_moon_juice.png | Bin 0 -> 2988 bytes textures/vmg_moon_weed.png | Bin 0 -> 21426 bytes textures/vmg_mushroom_giant_cap.png | Bin 0 -> 756 bytes textures/vmg_mushroom_giant_stem.png | Bin 0 -> 714 bytes textures/vmg_mushroom_giant_under.png | Bin 0 -> 765 bytes textures/vmg_mushroom_steak.png | Bin 0 -> 2988 bytes textures/vmg_small_rocks.png | Bin 0 -> 3422 bytes 31 files changed, 1240 insertions(+), 167 deletions(-) create mode 100644 fungal_tree.lua create mode 100644 nodes.lua create mode 100644 textures/caverealms_algae.png create mode 100644 textures/caverealms_glow_obsidian.png create mode 100644 textures/caverealms_glow_obsidian2.png create mode 100644 textures/caverealms_hot_cobble.png create mode 100644 textures/caverealms_salty2.png create mode 100644 textures/caverealms_thin_ice.png create mode 100644 textures/fun_caves_algae.png create mode 100644 textures/fun_caves_brain_coral.png create mode 100644 textures/fun_caves_dragon_eye.png create mode 100644 textures/fun_caves_fungal_tree_fruit.png create mode 100644 textures/fun_caves_fungal_tree_leaves.png create mode 100644 textures/fun_caves_lichen.png create mode 100644 textures/fun_caves_lumin_tree.png create mode 100644 textures/fun_caves_moss.png create mode 100644 textures/fun_caves_pillar_coral.png create mode 100644 textures/fun_caves_staghorn_coral.png create mode 100644 textures/vmg_glowing_fungal.png create mode 100644 textures/vmg_glowing_fungus.png create mode 100644 textures/vmg_moon_juice.png create mode 100644 textures/vmg_moon_weed.png create mode 100644 textures/vmg_mushroom_giant_cap.png create mode 100644 textures/vmg_mushroom_giant_stem.png create mode 100644 textures/vmg_mushroom_giant_under.png create mode 100644 textures/vmg_mushroom_steak.png create mode 100644 textures/vmg_small_rocks.png diff --git a/README.md b/README.md index f21d190..e8a9df9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # fun_caves -Fun Caves is an attempt to convert the mapgen V6 caves into a lua mod, so they can be used with any mapgen. I've translated the C++ code into lua in the most mechanical way possible. I honestly have no idea how half of it works, and I don't intend to spend a lot of time on it in the future, so anyone who likes this mod is encouraged to fork and/or tinker with it and submit pull requests. +Fun Caves started as an attempt to convert the mapgen V6 caves into a lua mod, so they could be used with any mapgen. However, I've since turned it into an all cave environment, with no surface at all. ![screenshot](https://github.com/duane-r/fun_caves/raw/master/textures/screenshot.jpg) diff --git a/depends.txt b/depends.txt index 4ad96d5..abb01ae 100644 --- a/depends.txt +++ b/depends.txt @@ -1 +1,2 @@ default +flowers diff --git a/fungal_tree.lua b/fungal_tree.lua new file mode 100644 index 0000000..3a65241 --- /dev/null +++ b/fungal_tree.lua @@ -0,0 +1,358 @@ +------------------- +-- Fungal Tree -- +------------------- + +local light_max = 9 + +local colors = {"^[colorize:#FF00FF:60", "", "^[colorize:#0000FF:60", "^[colorize:#FF4500:80"} +fun_caves.fungal_tree_leaves = {} + +-- all leaves +function fun_caves.make_fungal_tree(data, area, pos, height, leaves, fruit) + for y = 0, height do + local radius = 1 + if y > 1 and y < height - 2 then + radius = 2 + end + local force_x = math.random(1,3) - 2 + local force_y = math.random(1,3) - 2 + for z = -radius,radius do + for x = -radius,radius do + local sr = math.random(1,27) + local i = pos + z*area.zstride + y*area.ystride + x + if force_x == x and force_y == y then + data[i] = leaves + elseif sr == 1 then + data[i] = fruit + elseif sr < 14 then + data[i] = leaves + end + end + end + end +end + +-- multicolored growths +local count = 0 +for _, color in pairs(colors) do + count = count + 1 + local name = "fun_caves:fungal_tree_leaves_"..count + fun_caves.fungal_tree_leaves[#fun_caves.fungal_tree_leaves+1] = name + + minetest.register_node(name, { + description = "Fungal tree growths", + drawtype = "allfaces_optional", + waving = 1, + visual_scale = 1.3, + tiles = {"fun_caves_fungal_tree_leaves.png"..color}, + paramtype = "light", + is_ground_content = false, + groups = {snappy=3, flammable=3, leaves=1, plant=1}, + drop = { + max_items = 1, + items = { + --{items = {"fun_caves:"..tree.name.."_sapling"}, rarity = tree.drop_rarity }, + {items = {name} } + } + }, + sounds = default.node_sound_leaves_defaults(), + after_place_node = default.after_place_leaves, + }) + + minetest.register_craft({ + output = "default:stick", + recipe = { + {name} + } + }) +end + + +local leaves_and_air = table.copy(fun_caves.fungal_tree_leaves) +leaves_and_air[#leaves_and_air+1] = "air" +local good_stone = {} +good_stone["fun_caves:stone_with_lichen"] = true +good_stone["fun_caves:stone_with_algae"] = true + +local function find_ground(pos) + for y1 = 1, 16 do + local node = minetest.get_node_or_nil({x=pos.x, y=pos.y-y1, z=pos.z}) + if node then + if minetest.get_item_group(node.name, "soil") ~= 0 or + good_stone[node.name] then + return y1 + end + end + end + + return 1000 +end + + +-- fungal spread +minetest.register_abm({ + nodenames = fun_caves.fungal_tree_leaves, + interval = 2 * fun_caves.time_factor, + chance = 10, + action = function(pos, node) + if minetest.get_node_light(pos, nil) == 15 then + minetest.remove_node(pos) + return + end + if find_ground(pos) > 16 then + minetest.remove_node(pos) + return + end + + local grow_pos = {x=pos.x, y=pos.y-1, z=pos.z} + local grow_node = minetest.get_node_or_nil(grow_pos) + if grow_node and grow_node.name == "air" then + minetest.set_node(grow_pos, {name = node.name}) + return + end + if math.random(1,3) ~= 1 then + return + end + + local foreign = {} + for _, i in pairs(fun_caves.fungal_tree_leaves) do + if i ~= node.name then + foreign[#foreign+1] = i + end + end + local pos1, count = minetest.find_nodes_in_area(vector.subtract(pos, 3), vector.add(pos, 3), foreign) + if #pos1 > 0 then + minetest.set_node(pos1[math.random(1,#pos1)], {name="air"}) + return + end + + if math.random(1,201) == 1 then + local new = fun_caves.fungal_tree_leaves[math.random(1,#fun_caves.fungal_tree_leaves)] + local pos1, count = minetest.find_nodes_in_area({x=pos.x-8, y=pos.y-16, z=pos.z-8}, {x=pos.x+8, y=pos.y+16, z=pos.z+8}, node.name) + for _, p in pairs(pos1) do + minetest.set_node(p, {name=new}) + end + return + end + + grow_pos = {x = pos.x + math.random(-1,1), y = pos.y + math.random(-1,1), z = pos.z + math.random(-1,1)} + grow_node = minetest.get_node_or_nil(grow_pos) + --if math.random(1,2) == 1 then + minetest.set_node(pos, {name = "air"}) + --end + if not grow_node or not table.contains(leaves_and_air, grow_node.name) or find_ground(grow_pos) > 16 then + return + end + if minetest.get_node_light(grow_pos, nil) <= light_max then + minetest.set_node(pos, {name = "air"}) + if math.random(1,27) == 1 then + minetest.set_node(grow_pos, {name = "fun_caves:fungal_tree_fruit"}) + else + minetest.set_node(grow_pos, {name = node.name}) + end + end + end +}) + +-- Fill a list with data for content IDs, after all nodes are registered +local cid_data = {} +minetest.after(0, function() + for name, def in pairs(minetest.registered_nodes) do + cid_data[minetest.get_content_id(name)] = { + name = name, + --drops = def.drops, + flammable = def.groups.flammable, + choppy = def.groups.choppy, + fleshy = def.groups.fleshy, + snappy = def.groups.snappy, + on_blast = def.on_blast, + } + end +end) + +local function add_effects(pos, radius) + minetest.add_particlespawner({ + amount = 128, + time = 1, + minpos = vector.subtract(pos, radius / 2), + maxpos = vector.add(pos, radius / 2), + minvel = {x=-20, y=-20, z=-20}, + maxvel = {x=20, y=20, z=20}, + minacc = vector.new(), + maxacc = vector.new(), + minexptime = 1, + maxexptime = 3, + minsize = 8, + maxsize = 16, + texture = "tnt_smoke.png", + }) +end + +local function destroy(pos, cid) + if minetest.is_protected(pos, "") then + return + end + local def = cid_data[cid] + if def and def.on_blast then + def.on_blast(vector.new(pos), 1) + return + end + if def.snappy == nil and def.choppy == nil and def.fleshy == nil and def.name ~= "fire:basic_flame" then + return + end + local new = "air" + --if math.random(1,2) == 1 then + if true then + local node_under = minetest.get_node_or_nil({x = pos.x, + y = pos.y - 1, z = pos.z}) + if node_under and node_under.name ~= "air" then + --new = node.name + end + end + minetest.set_node(pos, {name=new}) +end + +local function explode(pos, radius) + local pos = vector.round(pos) + local vm = VoxelManip() + local p1 = vector.subtract(pos, radius) + local p2 = vector.add(pos, radius) + local minp, maxp = vm:read_from_map(p1, p2) + local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) + local data = vm:get_data() + + local drops = {} + local p = {} + + local c_air = minetest.get_content_id("air") + + for z = -radius, radius do + for y = -radius, 4*radius do + local vi = a:index(pos.x + (-radius), pos.y + y, pos.z + z) + for x = -radius, radius do + if (x * x) + (y * y / 4) + (z * z) <= + (radius * radius) + math.random(-radius, radius) then + local cid = data[vi] + p.x = pos.x + x + p.y = pos.y + y + p.z = pos.z + z + if cid ~= c_air then + destroy(p, cid) + end + end + vi = vi + 1 + end + end + end +end + +local function calc_velocity(pos1, pos2, old_vel, power) + local vel = vector.direction(pos1, pos2) + vel = vector.normalize(vel) + vel = vector.multiply(vel, power) + + -- Divide by distance + local dist = vector.distance(pos1, pos2) + dist = math.max(dist, 1) + vel = vector.divide(vel, dist) + + -- Add old velocity + vel = vector.add(vel, old_vel) + return vel +end + +local function entity_physics(pos, radius) + -- Make the damage radius larger than the destruction radius + radius = radius * 2 + local objs = minetest.get_objects_inside_radius(pos, radius) + for _, obj in pairs(objs) do + local obj_pos = obj:getpos() + local obj_vel = obj:getvelocity() + local dist = math.max(1, vector.distance(pos, obj_pos)) + + if obj_vel ~= nil then + obj:setvelocity(calc_velocity(pos, obj_pos, + obj_vel, radius * 10)) + end + + local damage = (4 / dist) * radius + obj:set_hp(obj:get_hp() - damage) + end +end + + +local function boom(pos) + if not pos then + return + end + local node = minetest.get_node_or_nil(pos) + if not node then + return + end + + minetest.sound_play("tnt_explode", {pos=pos, gain=1.5, max_hear_distance=2*64}) + local radius = 5 + minetest.set_node(pos, {name="air"}) + explode(pos, radius) + entity_physics(pos, radius) + add_effects(pos, radius) +end + +local function burn(pos) + minetest.get_node_timer(pos):start(1) +end + + +-- Exploding fruit +minetest.register_abm({ + nodenames = {"fun_caves:fungal_tree_fruit"}, + interval = 3 * fun_caves.time_factor, + chance = 20, + action = function(pos, node) + local pos1, count = minetest.find_nodes_in_area(vector.subtract(pos, 1), vector.add(pos, 1), {"fire:basic_flame"}) + if #pos1 > 0 then + boom(pos) + return + end + + local pos1, count = minetest.find_nodes_in_area(vector.subtract(pos, 1), vector.add(pos, 1), fun_caves.fungal_tree_leaves) + if #pos1 < 3 then + minetest.set_node(pos, {name="air"}) + return + end + + local g = find_ground(pos) + if g > 4 and g < 17 then + if math.random(1,17 - g) == 1 then + boom(pos) + end + elseif math.random(1,2) == 1 then + minetest.set_node(pos, {name="air"}) + end + end +}) + + +minetest.register_node("fun_caves:fungal_tree_fruit", { + description = "Fungal tree fruit", + drawtype = "plantlike", + visual_scale = 0.75, + tiles = {"fun_caves_fungal_tree_fruit.png"}, + --inventory_image = ".png", + paramtype = "light", + sunlight_propagates = true, + light_source = 6, + walkable = false, + is_ground_content = false, + selection_box = { + type = "fixed", + fixed = {-0.2, -0.5, -0.2, 0.2, 0, 0.2} + }, + groups = {fleshy = 3, dig_immediate = 3, flammable = 2}, + --on_use = minetest.item_eat(2), + sounds = default.node_sound_leaves_defaults(), + on_timer = boom, + on_punch = boom, +}) + + diff --git a/init.lua b/init.lua index c75b644..13bf403 100644 --- a/init.lua +++ b/init.lua @@ -2,35 +2,46 @@ fun_caves = {} fun_caves.version = "1.0" fun_caves.path = minetest.get_modpath(minetest.get_current_modname()) fun_caves.world = false +fun_caves.time_factor = 10 -if fun_caves.world then - minetest.register_on_mapgen_init(function(mgparams) - minetest.set_mapgen_params({mgname="singlenode", flags="nolight"}) - end) +minetest.register_on_mapgen_init(function(mgparams) + minetest.set_mapgen_params({mgname="singlenode", flags="nolight"}) +end) - if default then - if default.register_ores then - default.register_ores() - end - if default.register_blobs then - default.register_blobs() - end - if default.register_biomes then - default.register_biomes() - end - if default.register_decorations then - default.register_decorations() - end - if flowers.register_decorations then - flowers.register_decorations() - end +if default then + if default.register_ores then + default.register_ores() + end + if default.register_blobs then + default.register_blobs() + end + if default.register_biomes then + default.register_biomes() + end + if default.register_decorations then + default.register_decorations() + end + if flowers.register_decorations then + flowers.register_decorations() end -else - minetest.set_mapgen_params({flags="nocaves"}) end +-- Check if the table contains an element. +function table.contains(table, element) + for key, value in pairs(table) do + if value == element then + if key then + return key + else + return true + end + end + end + return false +end + -- Modify a node to add a group function minetest.add_group(node, groups) local def = minetest.registered_items[node] @@ -71,14 +82,17 @@ function fun_caves.node(name) end ---dofile(fun_caves.path .. "/nodes.lua") +dofile(fun_caves.path .. "/nodes.lua") +dofile(fun_caves.path .. "/fungal_tree.lua") dofile(fun_caves.path .. "/mapgen.lua") -if fun_caves.world then - minetest.register_on_newplayer(fun_caves.respawn) - minetest.register_on_respawnplayer(fun_caves.respawn) -end +minetest.register_on_newplayer(fun_caves.respawn) +minetest.register_on_respawnplayer(fun_caves.respawn) -- Inserting helps to ensure that fun_caves operates first. table.insert(minetest.registered_on_generateds, 1, fun_caves.generate) + +minetest.register_on_joinplayer(function(player) + player:set_sky("#000000", "plain", {}) +end) diff --git a/mapgen.lua b/mapgen.lua index b8c6702..fd925e6 100644 --- a/mapgen.lua +++ b/mapgen.lua @@ -2,27 +2,31 @@ -- cavegen.cpp, and is likewise distributed under the LGPL2.1 ---local DEBUG = true +local DEBUG = false +-- Cave blend distance near YMIN, YMAX +local massive_cave_blend = 128 +-- noise threshold for massive caves +local massive_cave_threshold = 0.6 +-- mct: 1 = small rare caves, 0.5 1/3rd ground volume, 0 = 1/2 ground volume. + +local seed_noise = {offset = 0, scale = 32768, seed = 5202, spread = {x = 80, y = 80, z = 80}, octaves = 2, persist = 0.4, lacunarity = 2} +local cave_noise_v6 = {offset = 6, scale = 6, seed = 34329, spread = {x = 250, y = 250, z = 250}, octaves = 3, persist = 0.5, lacunarity = 2} +local intersect_cave_noise_1 = {offset = 0, scale = 1, seed = -8402, spread = {x = 64, y = 64, z = 64}, octaves = 3, persist = 0.5, lacunarity = 2} +local intersect_cave_noise_2 = {offset = 0, scale = 1, seed = 3944, spread = {x = 64, y = 64, z = 64}, octaves = 3, persist = 0.5, lacunarity = 2} +local massive_cave_noise = {offset = 0, scale = 1, seed = 59033, spread = {x = 768, y = 256, z = 768}, octaves = 6, persist = 0.63, lacunarity = 2} +local biome_noise = {offset = 0.0, scale = 1.0, spread = {x = 400, y = 400, z = 400}, seed = 903, octaves = 3, persist = 0.5, lacunarity = 2.0} +local biome_blend = {offset = 0.0, scale = 0.1, spread = {x = 8, y = 8, z = 8}, seed = 4023, octaves = 2, persist = 1.0, lacunarity = 2.0} + + + local node = fun_caves.node local data = {} local p2data = {} -- vm rotation data buffer local lightmap = {} -local vm, emin, emax, a, csize, heightmap, biomemap +local vm, emin, emax, area, csize local div_sz_x, div_sz_z, minp, maxp, terrain, cave -local terrain_noise = {offset = 0, -scale = 20, seed = 8829, spread = {x = 40, y = 40, z = 40}, -octaves = 6, persist = 0.4, lacunarity = 2} - -local cave_noise = {offset = 0, scale = 1, -seed = -3977, spread = {x = 30, y = 30, z = 30}, octaves = 3, -persist = 0.8, lacunarity = 2} - -local seed_noise = {offset = 0, scale = 32768, -seed = 5202, spread = {x = 80, y = 80, z = 80}, octaves = 2, -persist = 0.4, lacunarity = 2} - if fun_caves.world then fun_caves.biomes = {} local biomes = fun_caves.biomes @@ -118,7 +122,7 @@ local function place_schematic(pos, schem, center) local dz = pos.z - minp.z + z local dx = pos.x - minp.x + x if pos.x + x > minp.x and pos.x + x < maxp.x and pos.z + z > minp.z and pos.z + z < maxp.z then - local ivm = a:index(pos.x + x, pos.y, pos.z + z) + local ivm = area:index(pos.x + x, pos.y, pos.z + z) local isch = z1 * schem.size.y * schem.size.x + x1 + 1 for y = 0, schem.size.y - 1 do local dy = pos.y - minp.y + y @@ -133,7 +137,7 @@ local function place_schematic(pos, schem, center) end end - ivm = ivm + a.ystride + ivm = ivm + area.ystride isch = isch + schem.size.x end end @@ -157,13 +161,11 @@ local function get_decoration(biome) end -local np_cave = {offset = 6, scale = 6, seed = 34329, spread = {x = 250, y = 250, z = 250}, octaves = 3, persist = 0.5, lacunarity = 2} - local function rangelim(x, y, z) return math.max(math.min(x, z), y) end -local function carveRoute(this, vec, f, randomize_xz, tunnel_above_ground) +local function carveRoute(this, vec, f, randomize_xz) local startp = vector.new(this.orp) startp = vector.add(startp, this.of) @@ -182,52 +184,48 @@ local function carveRoute(this, vec, f, randomize_xz, tunnel_above_ground) for z0 = d0, d1 do local si = this.rs / 2 - math.max(0, math.abs(z0) - this.rs / 7 - 1) for x0 = -si - math.random(0,1), si - 1 + math.random(0,1) do - if (tunnel_above_ground) then - --continue - else - local maxabsxz = math.max(math.abs(x0), math.abs(z0)) - local si2 = this.rs / 2 - math.max(0, maxabsxz - this.rs / 7 - 1) - for y0 = -si2, si2 do - if (this.large_cave_is_flat) then - -- Make large caves not so tall - if (this.rs > 7 and math.abs(y0) >= this.rs / 3) then + local maxabsxz = math.max(math.abs(x0), math.abs(z0)) + local si2 = this.rs / 2 - math.max(0, maxabsxz - this.rs / 7 - 1) + for y0 = -si2, si2 do + if (this.large_cave_is_flat) then + -- Make large caves not so tall + if (this.rs > 7 and math.abs(y0) >= this.rs / 3) then + --continue + else + local p = vector.new(cp.x + x0, cp.y + y0, cp.z + z0) + p = vector.add(p, this.of) + + if not area:containsp(p) then --continue else - local p = vector.new(cp.x + x0, cp.y + y0, cp.z + z0) - p = vector.add(p, this.of) + local i = area:indexp(vector.round(p)) + local c = data[i] + --if (not ndef.get(c).is_ground_content) then + -- ** check for ground content? ** + local donotdig = false + if c == node("default:desert_sand") then + donotdig = true + end - if not a:containsp(p) then + if donotdig then --continue else - local i = a:indexp(vector.round(p)) - local c = data[i] - --if (not ndef.get(c).is_ground_content) then - -- ** check for ground content? ** - local donotdig = false - if c == node("default:desert_sand") then - donotdig = true - end + if (this.large_cave) then + local full_ymin = minp.y - 16 + local full_ymax = maxp.y + 16 - if donotdig then - --continue - else - if (this.large_cave) then - local full_ymin = minp.y - 16 - local full_ymax = maxp.y + 16 - - if this.flooded and not this.lava_cave then - data[i] = (p.y <= this.water_level) and node("default:water_source") or node("air") - elseif this.flooded then - data[i] = (p.y < startp.y - 2) and node("default:lava_source") or node("air") - else - data[i] = node("air") - end + if this.flooded and not this.lava_cave then + data[i] = (p.y <= this.water_level) and node("default:water_source") or node("air") + elseif this.flooded then + data[i] = (p.y < startp.y - 2) and node("default:lava_source") or node("air") else - if (c == node("ignore") or c == node("air")) then - --continue - else - data[i] = node("air") - end + data[i] = node("air") + end + else + if (c == node("ignore") or c == node("air")) then + --continue + else + data[i] = node("air") end end end @@ -239,7 +237,7 @@ local function carveRoute(this, vec, f, randomize_xz, tunnel_above_ground) end end -local function makeTunnel(this, dirswitch) +local function makeV6Tunnel(this, dirswitch) if dirswitch and not this.large_cave then this.main_direction = vector.new( ((math.random() * 20) - 10) / 10, @@ -285,38 +283,6 @@ local function makeTunnel(this, dirswitch) ) end - -- Do not make caves that are entirely above ground, to fix - -- shadow bugs caused by overgenerated large caves. - -- It is only necessary to check the startpoint and endpoint. - local orpi = vector.new(this.orp.x, this.orp.y, this.orp.z) - local veci = vector.new(vec.x, vec.y, vec.z) - local h1 - local h2 - - local p1 = vector.add(orpi, veci, this.of, this.rs / 2) - if (p1.z >= minp.z and p1.z <= maxp.z and - p1.x >= minp.x and p1.x <= maxp.x) then - local index1 = math.floor(p1.z - minp.z + 0.5) * csize.x + math.floor(p1.x - minp.x + 0.5) + 1 - h1 = heightmap[index1] - else - h1 = this.water_level -- If not in heightmap - end - - local p2 = vector.add(orpi, this.of, this.rs / 2) - if (p2.z >= minp.z and p2.z <= maxp.z and - p2.x >= minp.x and p2.x <= maxp.x) then - local index2 = math.floor(p2.z - minp.z + 0.5) * csize.x + math.floor(p2.x - minp.x + 0.5) + 1 - h2 = heightmap[index2] - else - h2 = this.water_level - end - - -- If startpoint and endpoint are above ground, - -- disable placing of nodes in carveRoute while - -- still running all pseudorandom calls to ensure - -- caves consistent with existing worlds. - local tunnel_above_ground = p1.y > h1 and p2.y > h2 - vec = vector.add(vec, this.main_direction) local rp = vector.add(this.orp, vec) @@ -352,16 +318,15 @@ local function makeTunnel(this, dirswitch) -- Carve routes for f = 0, 1, 1.0 / veclen do --print(dump(vec)) - carveRoute(this, vec, f, randomize_xz, tunnel_above_ground) + carveRoute(this, vec, f, randomize_xz) end this.orp = rp end -local function makeCave(this, max_stone_height) - this.max_stone_y = max_stone_height +local function makeV6Cave(this) + this.max_stone_y = 32000 this.main_direction = vector.new(0, 0, 0) - --print(dump(this)) -- Allowed route area size in nodes this.ar = vector.add(vector.subtract(maxp, minp), 1) @@ -409,7 +374,7 @@ local function makeCave(this, max_stone_height) -- Generate some tunnel starting from orp for j = 0, this.tunnel_routepoints do --print(dump(this.orp)) - makeTunnel(this, j % this.dswitchint == 0) + makeV6Tunnel(this, j % this.dswitchint == 0) end end @@ -424,7 +389,7 @@ local function CaveV6(is_large_cave) this.flooded = true this.lava_cave = false - if maxp.y < this.water_level and minp.y / 31000 - math.random() < -0.5 then + if math.random(2) == 1 then this.lava_cave = true end @@ -446,8 +411,8 @@ local function getBiome(x, z) return nil end -local function generateCaves(max_stone_y) - local cave_amount = minetest.get_perlin(np_cave):get2d({x=minp.x, y=minp.y}) +local function generateV6Caves() + local cave_amount = minetest.get_perlin(cave_noise_v6):get2d({x=minp.x, y=minp.y}) local volume_nodes = (maxp.x - minp.x + 1) * (maxp.y - minp.y + 1) * 16 cave_amount = math.max(0.0, cave_amount) local caves_count = cave_amount * volume_nodes / 50000 @@ -457,17 +422,11 @@ local function generateCaves(max_stone_y) bruises_count = math.random(0, math.random(0, 2)) end - if (getBiome(minp.x, minp.z) == "desert") then - caves_count = caves_count / 3 - bruises_count = caves_count / 3 - end - for i = 0, caves_count + bruises_count do local large_cave = (i >= caves_count) local cave = CaveV6(large_cave) - --print(dump(cave)) - makeCave(cave, max_stone_y) + makeV6Cave(cave) end end @@ -477,20 +436,8 @@ function fun_caves.generate(p_minp, p_maxp, seed) vm, emin, emax = minetest.get_mapgen_object("voxelmanip") vm:get_data(data) --p2data = vm:get_param2_data() - a = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) + area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) csize = vector.add(vector.subtract(maxp, minp), 1) - heightmap = minetest.get_mapgen_object("heightmap") - - local max_stone_height = -40000 - local index = 0 - for z = minp.z, maxp.z do - for x = minp.x, maxp.x do - index = index + 1 - if max_stone_height < heightmap[index] then - max_stone_height = heightmap[index] - end - end - end -- Deal with memory issues. This, of course, is supposed to be automatic. local mem = math.floor(collectgarbage("count")/1024) @@ -506,31 +453,209 @@ function fun_caves.generate(p_minp, p_maxp, seed) local px = math.floor((minp.x + 32) / csize.x) local pz = math.floor((minp.z + 32) / csize.z) - generateCaves(max_stone_height) + -- Fill with stone. + for z = minp.z, maxp.z do + for y = minp.y, maxp.y do + local ivm = area:index(minp.x, y, z) + for x = minp.x, maxp.x do + data[ivm] = node("default:stone") + ivm = ivm + 1 + end + end + end - --local index = 0 - --local index3d = 0 - --for z = minp.z, maxp.z do - -- local dz = z - minp.z - -- for x = minp.x, maxp.x do - -- index = index + 1 - -- local dx = x - minp.x - -- index3d = dz * csize.y * csize.x + dx + 1 - -- local ivm = a:index(x, minp.y, z) + local made_a_big_one = false + local massive_cave = minetest.get_perlin_map(massive_cave_noise, csize):get3dMap_flat(minp) + local cave_1 = minetest.get_perlin_map(intersect_cave_noise_1, csize):get3dMap_flat(minp) + local cave_2 = minetest.get_perlin_map(intersect_cave_noise_2, csize):get3dMap_flat(minp) + local biome_n = minetest.get_perlin_map(biome_noise, {x=csize.x, y=csize.z}):get2dMap_flat({x=minp.x, y=minp.z}) + local biome_bn = minetest.get_perlin_map(biome_blend, {x=csize.x, y=csize.z}):get2dMap_flat({x=minp.x, y=minp.z}) - -- for y = minp.y, maxp.y do - -- local dy = y - minp.y + local index = 0 + local index3d = 0 + for z = minp.z, maxp.z do + local dz = z - minp.z + for x = minp.x, maxp.x do + index = index + 1 + local dx = x - minp.x + index3d = dz * csize.y * csize.x + dx + 1 + local ivm = area:index(x, minp.y, z) - -- ivm = ivm + a.ystride - -- index3d = index3d + csize.x - -- end - -- end - --end + for y = minp.y, maxp.y do + local dy = y - minp.y + + if massive_cave[index3d] > massive_cave_threshold then + data[ivm] = node("air") + made_a_big_one = true + else + local n1 = (math.abs(cave_1[index3d]) < 0.08) + local n2 = (math.abs(cave_2[index3d]) < 0.08) + + if n1 and n2 then + local sr = 1000 + if data[ivm] == node("default:stone") then + sr = math.random(1000) + end + + --if sr == 1 then + -- data[ivm] = node("default:lava_source") + --elseif sr == 2 then + -- data[ivm] = node("default:water_source") + --else + data[ivm] = node("air") + --end + end + end + + ivm = ivm + area.ystride + index3d = index3d + csize.x + end + end + end + + if made_a_big_one then + --print("massive cave at "..minp.x..","..minp.y..","..minp.z) + else + generateV6Caves() + end + + local index = 0 + local index3d = 0 + for z = minp.z, maxp.z do + local dz = z - minp.z + for x = minp.x, maxp.x do + index = index + 1 + local dx = x - minp.x + index3d = (dz + 1) * csize.y * csize.x + dx + local air_count = 0 + local ivm = area:index(x, maxp.y, z) + + for y = maxp.y, minp.y, -1 do + local ivm_below = ivm - area.ystride + local ivm_above = ivm + area.ystride + local dy = y - minp.y + + if data[ivm] == node("air") then + ------------------- + local stone_type = node("default:stone") + local stone_depth = 1 + local biome_val = biome_n[index] + biome_bn[index] + if biome_val < -0.8 then + if true then + stone_type = node("default:ice") + stone_depth = 2 + else + stone_type = node("fun_caves:thinice") + stone_depth = 2 + end + elseif biome_val < -0.7 then + stone_type = node("fun_caves:stone_with_lichen") + elseif biome_val < -0.3 then + stone_type = node("fun_caves:stone_with_moss") + elseif biome_val < 0.2 then + stone_type = node("fun_caves:stone_with_lichen") + elseif biome_val < 0.5 then + stone_type = node("fun_caves:stone_with_algae") + elseif biome_val < 0.6 then + stone_type = node("fun_caves:stone_with_salt") + stone_depth = 2 + elseif biome_val < 0.8 then + stone_type = node("default:coalblock") + stone_depth = 2 + else + stone_type = node("fun_caves:hot_cobble") + end + -- "glow" + + -- Change stone per biome. + if data[ivm_below] == node("default:stone") then + data[ivm_below] = stone_type + if stone_depth == 2 then + data[ivm_below - area.ystride] = stone_type + end + end + if data[ivm_above] == node("default:stone") then + data[ivm_above] = stone_type + if stone_depth == 2 then + data[ivm_above + area.ystride] = stone_type + end + end + + if (data[ivm_above] == node("fun_caves:stone_with_lichen") or data[ivm_above] == node("fun_caves:stone_with_moss")) and math.random(1,20) == 1 then + data[ivm_above] = node("fun_caves:glowing_fungal_stone") + end + + if data[ivm] == node("air") then + local sr = math.random(1,1000) + + -- fluids + if (not made_a_big_one) and data[ivm_below] == node("default:stone") and sr < 10 then + data[ivm] = node("default:lava_source") + elseif (not made_a_big_one) and data[ivm_below] == node("fun_caves:stone_with_moss") and sr < 10 then + data[ivm] = node("default:water_source") + -- hanging down + elseif data[ivm_above] == node("default:ice") and sr < 80 then + data[ivm] = node("fun_caves:icicle_down") + elseif (data[ivm_above] == node("fun_caves:stone_with_lichen") or data[ivm_above] == node("fun_caves:stone_with_moss") or data[ivm_above] == node("fun_caves:stone_with_algae") or data[ivm_above] == node("default:stone")) and sr < 80 then + if data[ivm_above] == node("fun_caves:stone_with_algae") then + data[ivm] = node("fun_caves:stalactite_slimy") + elseif data[ivm_above] == node("fun_caves:stone_with_moss") then + data[ivm] = node("fun_caves:stalactite_mossy") + else + data[ivm] = node("fun_caves:stalactite") + end + -- standing up + elseif data[ivm_below] == node("default:coalblock") and sr < 20 then + data[ivm] = node("fun_caves:constant_flame") + elseif data[ivm_below] == node("default:ice") and sr < 80 then + data[ivm] = node("fun_caves:icicle_up") + elseif (data[ivm_below] == node("fun_caves:stone_with_lichen") or data[ivm_below] == node("fun_caves:stone_with_algae") or data[ivm_below] == node("default:stone") or data[ivm_below] == node("fun_caves:stone_with_moss")) and sr < 80 then + if data[ivm_below] == node("fun_caves:stone_with_algae") then + data[ivm] = node("fun_caves:stalagmite_slimy") + elseif data[ivm_below] == node("fun_caves:stone_with_moss") then + data[ivm] = node("fun_caves:stalagmite_mossy") + elseif data[ivm_below] == node("fun_caves:stone_with_lichen") or data[ivm_above] == node("default:stone") then + data[ivm] = node("fun_caves:stalagmite") + end + -- vegetation + elseif (data[ivm_below] == node("fun_caves:stone_with_lichen") or data[ivm_below] == node("fun_caves:stone_with_algae")) and biome_val >= -0.7 then + if sr < 110 then + data[ivm] = node("flowers:mushroom_red") + elseif sr < 140 then + data[ivm] = node("flowers:mushroom_brown") + elseif air_count > 1 and sr < 160 then + data[ivm_above] = node("fun_caves:huge_mushroom_cap") + data[ivm] = node("fun_caves:giant_mushroom_stem") + elseif air_count > 2 and sr < 170 then + data[ivm + 2 * area.ystride] = node("fun_caves:giant_mushroom_cap") + data[ivm_above] = node("fun_caves:giant_mushroom_stem") + data[ivm] = node("fun_caves:giant_mushroom_stem") + elseif made_a_big_one and air_count > 5 and sr < 180 then + fun_caves.make_fungal_tree(data, area, ivm, math.random(2,math.min(air_count, 12)), node(fun_caves.fungal_tree_leaves[math.random(1,#fun_caves.fungal_tree_leaves)]), node("fun_caves:fungal_tree_fruit")) + data[ivm_below] = node("dirt") + elseif sr < 300 then + data[ivm_below] = node("dirt") + end + if data[ivm] ~= node("air") then + data[ivm_below] = node("dirt") + end + end + end + + if data[ivm] == node("air") then + air_count = air_count + 1 + end + end + + ivm = ivm - area.ystride + index3d = index3d - csize.x + end + end + end vm:set_data(data) - --minetest.generate_ores(vm, minp, maxp) - --minetest.generate_decorations(vm, minp, maxp) + minetest.generate_ores(vm, minp, maxp) --vm:set_param2_data(p2data) if DEBUG then vm:set_lighting({day = 15, night = 15}) @@ -541,5 +666,36 @@ function fun_caves.generate(p_minp, p_maxp, seed) vm:update_liquids() vm:write_to_map() - vm, a, lightmap, heightmap, biomemap, terrain, cave = nil, nil, nil, nil, nil, nil, nil + vm, area, lightmap, terrain, cave = nil, nil, nil, nil, nil +end + +function fun_caves.respawn(player) + local pos = {x=0,y=0,z=0} + local massive_cave = minetest.get_perlin(massive_cave_noise):get3d(pos) + local biome_n = minetest.get_perlin(biome_noise):get2d({x=pos.x, y=pos.z}) + local biome_bn = minetest.get_perlin(biome_blend):get2d({x=pos.x, y=pos.z}) + local biome = biome_n + biome_bn + + while biome < 0.3 or biome > 0.5 do + pos.x = pos.x + math.random(20) - 10 + pos.z = pos.z + math.random(20) - 10 + + biome_n = minetest.get_perlin(biome_noise):get2d({x=pos.x, y=pos.z}) + biome_bn = minetest.get_perlin(biome_blend):get2d({x=pos.x, y=pos.z}) + biome = biome_n + biome_bn + end + + while massive_cave <= massive_cave_threshold do + pos.y = pos.y + 80 + massive_cave = minetest.get_perlin(massive_cave_noise):get3d(pos) + end + + while massive_cave > massive_cave_threshold do + pos.y = pos.y - 1 + massive_cave = minetest.get_perlin(massive_cave_noise):get3d(pos) + end + + pos.y = pos.y + 1 + player:setpos(pos) + return true -- Disable default player spawner end diff --git a/nodes.lua b/nodes.lua new file mode 100644 index 0000000..bb8d10f --- /dev/null +++ b/nodes.lua @@ -0,0 +1,544 @@ +---------------------- +-- Cave Decorations -- +---------------------- + +-- Mushrooms and Speleothems +-- These are instantiated by voxel.lua since the decoration manager +-- only works at the surface of the world. + +local light_max = 12 + +minetest.register_node("fun_caves:huge_mushroom_cap", { + description = "Huge Mushroom Cap", + tiles = {"vmg_mushroom_giant_cap.png", "vmg_mushroom_giant_under.png", "vmg_mushroom_giant_cap.png"}, + is_ground_content = false, + paramtype = "light", + drawtype = "nodebox", + node_box = { type = "fixed", + fixed = { + {-0.5, -0.5, -0.33, 0.5, -0.33, 0.33}, + {-0.33, -0.5, 0.33, 0.33, -0.33, 0.5}, + {-0.33, -0.5, -0.33, 0.33, -0.33, -0.5}, + {-0.33, -0.33, -0.33, 0.33, -0.17, 0.33}, + } }, + light_source = 10, + groups = {fleshy=1, dig_immediate=3, flammable=2, plant=1, leafdecay=1}, +}) + +minetest.register_node("fun_caves:giant_mushroom_cap", { + description = "Giant Mushroom Cap", + tiles = {"vmg_mushroom_giant_cap.png", "vmg_mushroom_giant_under.png", "vmg_mushroom_giant_cap.png"}, + is_ground_content = false, + paramtype = "light", + drawtype = "nodebox", + node_box = { type = "fixed", + fixed = { + {-0.4, -0.5, -0.4, 0.4, 0.0, 0.4}, + {-0.75, -0.5, -0.4, -0.4, -0.25, 0.4}, + {0.4, -0.5, -0.4, 0.75, -0.25, 0.4}, + {-0.4, -0.5, -0.75, 0.4, -0.25, -0.4}, + {-0.4, -0.5, 0.4, 0.4, -0.25, 0.75}, + } }, + light_source = 10, + groups = {fleshy=1, dig_immediate=3, flammable=2, plant=1, leafdecay=1}, +}) + +minetest.register_node("fun_caves:giant_mushroom_stem", { + description = "Giant Mushroom Stem", + tiles = {"vmg_mushroom_giant_stem.png", "vmg_mushroom_giant_stem.png", "vmg_mushroom_giant_stem.png"}, + is_ground_content = false, + groups = {tree=1,choppy=2,oddly_breakable_by_hand=1,flammable=2, plant=1}, + sounds = default.node_sound_wood_defaults(), + paramtype = "light", + drawtype = "nodebox", + node_box = { type = "fixed", fixed = { {-0.25, -0.5, -0.25, 0.25, 0.5, 0.25}, }}, +}) + +-- Mushroom stems can be used as wood, ala Journey to the Center of the Earth. +minetest.register_craft({ + output = "default:wood", + recipe = { + {"fun_caves:giant_mushroom_stem"} + } +}) + +-- Caps can be cooked and eaten. +minetest.register_node("fun_caves:mushroom_steak", { + description = "Mushroom Steak", + drawtype = "plantlike", + paramtype = "light", + tiles = {"vmg_mushroom_steak.png"}, + inventory_image = "vmg_mushroom_steak.png", + on_use = minetest.item_eat(4), + groups = {dig_immediate = 3, attached_node = 1}, +}) + +minetest.register_craft({ + type = "cooking", + output = "fun_caves:mushroom_steak", + recipe = "fun_caves:huge_mushroom_cap", + cooktime = 2, +}) + +minetest.register_craft({ + type = "cooking", + output = "fun_caves:mushroom_steak 2", + recipe = "fun_caves:giant_mushroom_cap", + cooktime = 2, +}) + +-- Glowing fungal stone provides an eerie light. +minetest.register_node("fun_caves:glowing_fungal_stone", { + description = "Glowing Fungal Stone", + tiles = {"default_stone.png^vmg_glowing_fungal.png",}, + is_ground_content = true, + light_source = 12, + groups = {cracky=3, stone=1}, + drop = {items={ {items={"default:cobble"},}, {items={"fun_caves:glowing_fungus",},},},}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("fun_caves:glowing_fungus", { + description = "Glowing Fungus", + drawtype = "plantlike", + paramtype = "light", + tiles = {"vmg_glowing_fungus.png"}, + inventory_image = "vmg_glowing_fungus.png", + groups = {dig_immediate = 3, attached_node = 1}, +}) + +-- The fungus can be made into juice and then into glowing glass. +minetest.register_node("fun_caves:moon_juice", { + description = "Moon Juice", + drawtype = "plantlike", + paramtype = "light", + tiles = {"vmg_moon_juice.png"}, + inventory_image = "vmg_moon_juice.png", + groups = {dig_immediate = 3, attached_node = 1}, + sounds = default.node_sound_glass_defaults(), +}) + +minetest.register_node("fun_caves:moon_glass", { + description = "Moon Glass", + drawtype = "glasslike", + tiles = {"default_glass.png",}, + inventory_image = minetest.inventorycube("default_glass.png"), + is_ground_content = true, + light_source = default.LIGHT_MAX, + groups = {cracky=3}, + sounds = default.node_sound_glass_defaults(), +}) + +minetest.register_craft({ + output = "fun_caves:moon_juice", + recipe = { + {"fun_caves:glowing_fungus", "fun_caves:glowing_fungus", "fun_caves:glowing_fungus"}, + {"fun_caves:glowing_fungus", "fun_caves:glowing_fungus", "fun_caves:glowing_fungus"}, + {"fun_caves:glowing_fungus", "vessels:glass_bottle", "fun_caves:glowing_fungus"}, + }, +}) + +minetest.register_craft({ + output = "fun_caves:moon_glass", + type = "shapeless", + recipe = { + "fun_caves:moon_juice", + "fun_caves:moon_juice", + "default:glass", + }, +}) + +-- What's a cave without speleothems? +local spel = { + {type1="stalactite", type2="stalagmite", tile="default_stone.png"}, + {type1="stalactite_slimy", type2="stalagmite_slimy", tile="default_stone.png^fun_caves_algae.png"}, + {type1="stalactite_mossy", type2="stalagmite_mossy", tile="default_stone.png^fun_caves_moss.png"}, + {type1="icicle_down", type2="icicle_up", desc="Icicle", tile="caverealms_thin_ice.png", drop="default:ice"}, +} + +for _, desc in pairs(spel) do + minetest.register_node("fun_caves:"..desc.type1, { + description = (desc.desc or "Stalactite"), + tiles = {desc.tile}, + is_ground_content = true, + walkable = false, + paramtype = "light", + --light_source = 14, + drop = (desc.drop or "fun_caves:stalactite"), + drawtype = "nodebox", + node_box = { type = "fixed", + fixed = { + {-0.07, 0.0, -0.07, 0.07, 0.5, 0.07}, + {-0.04, -0.25, -0.04, 0.04, 0.0, 0.04}, + {-0.02, -0.5, -0.02, 0.02, 0.25, 0.02}, + } }, + groups = {rock=1, cracky=3}, + sounds = default.node_sound_stone_defaults(), + }) + + minetest.register_node("fun_caves:"..desc.type2, { + description = (desc.desc or "Stalagmite"), + tiles = {desc.tile}, + is_ground_content = true, + walkable = false, + paramtype = "light", + --light_source = 14, + drop = "fun_caves:stalagmite", + drawtype = "nodebox", + node_box = { type = "fixed", + fixed = { + {-0.07, -0.5, -0.07, 0.07, 0.0, 0.07}, + {-0.04, 0.0, -0.04, 0.04, 0.25, 0.04}, + {-0.02, 0.25, -0.02, 0.02, 0.5, 0.02}, + } }, + groups = {rock=1, cracky=3}, + sounds = default.node_sound_stone_defaults(), + }) +end + +-- They can be made into cobblestone, to get them out of inventory. +minetest.register_craft({ + output = "default:cobble", + recipe = { + {"", "", ""}, + {"fun_caves:stalactite", "fun_caves:stalactite", ""}, + {"fun_caves:stalactite", "fun_caves:stalactite", ""}, + }, +}) + +minetest.register_craft({ + output = "default:cobble", + recipe = { + {"", "", ""}, + {"fun_caves:stalagmite", "fun_caves:stalagmite", ""}, + {"fun_caves:stalagmite", "fun_caves:stalagmite", ""}, + }, +}) + +minetest.register_node("fun_caves:glowing_dirt", { + description = "Glowing Dirt", + tiles = {"default_dirt.png"}, + groups = {crumbly = 3, soil = 1}, + light_source = default.LIGHT_MAX, + sounds = default.node_sound_dirt_defaults(), + soil = { + base = "fun_caves:glowing_dirt", + dry = "fun_caves:glowing_soil", + wet = "fun_caves:glowing_soil_wet" + }, +}) + +minetest.register_node("fun_caves:glowing_soil", { + description = "Glowing Soil", + tiles = {"default_dirt.png^farming_soil.png", "default_dirt.png"}, + drop = "fun_caves:glowing_dirt", + groups = {crumbly=3, not_in_creative_inventory=1, soil=2, grassland = 1, field = 1}, + sounds = default.node_sound_dirt_defaults(), + light_source = default.LIGHT_MAX, + soil = { + base = "fun_caves:glowing_dirt", + dry = "fun_caves:glowing_soil", + wet = "fun_caves:glowing_soil_wet" + }, +}) + +minetest.register_node("fun_caves:glowing_soil_wet", { + description = "Wet Glowing Soil", + tiles = {"default_dirt.png^farming_soil_wet.png", "default_dirt.png^farming_soil_wet_side.png"}, + drop = "fun_caves:glowing_dirt", + groups = {crumbly=3, not_in_creative_inventory=1, soil=3, wet = 1, grassland = 1, field = 1}, + sounds = default.node_sound_dirt_defaults(), + light_source = default.LIGHT_MAX, + soil = { + base = "fun_caves:glowing_dirt", + dry = "fun_caves:glowing_soil", + wet = "fun_caves:glowing_soil_wet" + }, +}) + +minetest.register_craft({ + output = "fun_caves:glowing_dirt", + type = "shapeless", + recipe = { + "fun_caves:moon_juice", + "default:dirt", + }, +}) + +--thin (transparent) ice +minetest.register_node("fun_caves:thin_ice", { + description = "Thin Ice", + tiles = {"caverealms_thin_ice.png"}, + is_ground_content = true, + groups = {cracky=3}, + sounds = default.node_sound_glass_defaults(), + use_texture_alpha = true, + light_source = 1, + drawtype = "glasslike", + sunlight_propagates = true, + freezemelt = "default:water_source", + paramtype = "light", +}) + +minetest.register_node("fun_caves:stone_with_moss", { + description = "Cave Stone with Moss", + tiles = {"default_stone.png^fun_caves_moss.png"}, + is_ground_content = true, + light_source = 10, + groups = {stone=1, crumbly=3}, + drop = 'default:cobble', + sounds = default.node_sound_dirt_defaults({ + footstep = {name="default_grass_footstep", gain=0.25}, + }), +}) + +minetest.register_node("fun_caves:stone_with_lichen", { + description = "Cave Stone with Lichen", + tiles = {"default_stone.png^fun_caves_lichen.png"}, + is_ground_content = true, + light_source = 10, + groups = {stone=1, crumbly=3}, + drop = 'default:cobble', + sounds = default.node_sound_dirt_defaults({ + footstep = {name="default_grass_footstep", gain=0.25}, + }), +}) + +minetest.register_node("fun_caves:stone_with_algae", { + description = "Cave Stone with Algae", + tiles = {"default_stone.png^fun_caves_algae.png"}, + is_ground_content = true, + light_source = 10, + groups = {stone=1, crumbly=3}, + drop = 'default:cobble', + sounds = default.node_sound_dirt_defaults({ + footstep = {name="default_grass_footstep", gain=0.25}, + }), +}) + +minetest.register_node("fun_caves:stone_with_salt", { + description = "Cave Stone with Salt", + tiles = {"caverealms_salty2.png"},--{"caverealms_salty2.png^caverealms_salty.png", "caverealms_salty2.png", "caverealms_salty2.png^caverealms_salty_side.png"}, + light_source = 9, + paramtype = "light", + use_texture_alpha = true, + drawtype = "glasslike", + sunlight_propagates = true, + is_ground_content = true, + groups = {stone=1, crumbly=3}, + sounds = default.node_sound_glass_defaults(), +}) + +--Glow Obsidian +minetest.register_node("fun_caves:glow_obsidian", { + description = "Glowing Obsidian", + tiles = {"caverealms_glow_obsidian.png"}, + is_ground_content = true, + groups = {stone=2, crumbly=1}, + light_source = 7, + sounds = default.node_sound_stone_defaults({ + footstep = {name="default_stone_footstep", gain=0.25}, + }), +}) + +--Glow Obsidian 2 - has traces of lava +minetest.register_node("fun_caves:glow_obsidian_2", { + description = "Hot Glow Obsidian", + tiles = {"caverealms_glow_obsidian2.png"}, + is_ground_content = true, + groups = {stone=2, crumbly=1, hot=1}, + damage_per_second = 1, + light_source = 9, + sounds = default.node_sound_stone_defaults({ + footstep = {name="default_stone_footstep", gain=0.25}, + }), +}) + + +--minetest.register_node("fun_caves:bright_air", { +-- drawtype = "glasslike", +-- tiles = {"technic_light.png"}, +-- paramtype = "light", +-- groups = {not_in_creative_inventory=1}, +-- drop = "", +-- walkable = false, +-- buildable_to = true, +-- sunlight_propagates = true, +-- light_source = LIGHT_MAX, +-- pointable = false, +--}) + +--define special flame so that it does not expire +minetest.register_node("fun_caves:constant_flame", { + description = "Fire", + drawtype = "plantlike", + tiles = {{ + name="fire_basic_flame_animated.png", + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=1}, + }}, + inventory_image = "fire_basic_flame.png", + light_source = 14, + groups = {igniter=2,dig_immediate=3,hot=3, not_in_creative_inventory=1}, + drop = '', + walkable = false, + buildable_to = true, + damage_per_second = 4, +}) + +--Hot Cobble - cobble with lava instead of mortar XD +minetest.register_node("fun_caves:hot_cobble", { + description = "Hot Cobble", + tiles = {"caverealms_hot_cobble.png"}, + is_ground_content = true, + groups = {crumbly=2, hot=1}, + damage_per_second = 1, + light_source = 6, + sounds = default.node_sound_stone_defaults({ + footstep = {name="default_stone_footstep", gain=0.25}, + }), +}) + +-- mushroom growth +minetest.register_abm({ + nodenames = {"flowers:mushroom_brown", "flowers:mushroom_red"}, + interval = 50 * fun_caves.time_factor, + chance = 100, + action = function(pos, node) + local pos_up = {x=pos.x,y=pos.y+1,z=pos.z} + local node_up = minetest.get_node_or_nil(pos_up) + if not node_up then + return + end + if node_up.name ~= "air" then + return + end + local node_under = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z}) + if not node_under then + return + end + if minetest.get_item_group(node_under.name, "soil") ~= 0 and + minetest.get_node_light(pos_up, nil) <= light_max then + minetest.set_node(pos_up, {name = "fun_caves:huge_mushroom_cap"}) + minetest.set_node(pos, {name = "fun_caves:giant_mushroom_stem"}) + end + end +}) + +-- mushroom growth +minetest.register_abm({ + nodenames = {"fun_caves:huge_mushroom_cap"}, + interval = 100 * fun_caves.time_factor, + chance = 150, + action = function(pos, node) + if minetest.get_node_light(pos, nil) >= 14 then + minetest.set_node(pos, {name = "air"}) + return + end + local pos_up = {x=pos.x,y=pos.y+1,z=pos.z} + local node_up = minetest.get_node_or_nil(pos_up) + if not node_up then + return + end + if node_up.name ~= "air" then + return + end + local node_under = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z}) + if not node_under or node_under.name ~= "fun_caves:giant_mushroom_stem" then + return + end + node_under = minetest.get_node_or_nil({x = pos.x, y = pos.y - 2, z = pos.z}) + if not node_under then + return + end + if minetest.get_item_group(node_under.name, "soil") ~= 0 and + minetest.get_node_light(pos_up, nil) <= light_max then + minetest.set_node(pos_up, {name = "fun_caves:giant_mushroom_cap"}) + minetest.set_node(pos, {name = "fun_caves:giant_mushroom_stem"}) + end + end +}) + +-- mushroom growth +minetest.register_abm({ + nodenames = {"fun_caves:giant_mushroom_stem"}, + interval = 5 * fun_caves.time_factor, + chance = 5, + action = function(pos, node) + local pos_up = {x=pos.x,y=pos.y+1,z=pos.z} + local node_up = minetest.get_node_or_nil(pos_up) + if not node_up then + return + end + if node_up.name ~= "air" then + return + end + if minetest.get_node_light(pos_up, nil) <= light_max then + minetest.set_node(pos_up, {name = "fun_caves:huge_mushroom_cap"}) + end + end +}) + +-- mushroom spread +minetest.register_abm({ + nodenames = {"fun_caves:giant_mushroom_cap", "fun_caves:huge_mushroom_cap"}, + interval = 3 * fun_caves.time_factor, + chance = 40, + action = function(pos, node) + if minetest.get_node_light(pos, nil) >= 14 then + minetest.set_node(pos, {name = "air"}) + return + end + local pos_down = pos + pos_down.y = pos_down.y - 1 + local pos1, count = minetest.find_nodes_in_area_under_air(vector.subtract(pos_down, 4), vector.add(pos_down, 4), {"group:soil"}) + if #pos1 < 1 then + return + end + local random = pos1[math.random(1, #pos1)] + random.y = random.y + 1 + local mushroom_type + if math.random(1,2) == 1 then + mushroom_type = "flowers:mushroom_red" + else + mushroom_type = "flowers:mushroom_brown" + end + if minetest.get_node_light(random, nil) <= light_max then + minetest.set_node(random, {name = mushroom_type}) + end + end +}) + +-- Mushroom spread and death +minetest.register_abm({ + nodenames = {"flowers:mushroom_brown", "flowers:mushroom_red"}, + interval = 3 * fun_caves.time_factor, + chance = 50, + action = function(pos, node) + if minetest.get_node_light(pos, nil) == 15 then + minetest.remove_node(pos) + return + end + local random = { + x = pos.x + math.random(-2, 2), + y = pos.y + math.random(-1, 1), + z = pos.z + math.random(-2, 2) + } + local random_node = minetest.get_node_or_nil(random) + if not random_node or random_node.name ~= "air" then + return + end + local node_under = minetest.get_node_or_nil({x = random.x, + y = random.y - 1, z = random.z}) + if not node_under then + return + end + + if (minetest.get_item_group(node_under.name, "soil") ~= 0 or + minetest.get_item_group(node_under.name, "tree") ~= 0) and + minetest.get_node_light(pos, 0.5) <= light_max and + minetest.get_node_light(random, 0.5) <= light_max then + minetest.set_node(random, {name = node.name}) + end + end +}) + diff --git a/textures/caverealms_algae.png b/textures/caverealms_algae.png new file mode 100644 index 0000000000000000000000000000000000000000..980a4a16ede24c6b4bb917afbbdc1afb6393b3c9 GIT binary patch literal 3094 zcmV+x4C(WUP)()ig*b~6;zM}l#r0&%=5ZGLQ$IEI?;pycv(FAW2t%JXQ~k!HoFx`1c_PvMB7dHeNn2)>U(w} zziODSE;}q+wiRmQ`Old3_&WknRy$S`{xC}_{w^~XjZov2?UQu(&R2<^8_G3T^}=K| z5bu}VGJF(^X1^hcq>C6qQasAyP1oz_Ykp0ybPuh*MuN#C@puxG!%23wjjGl6E&^D+ zF;7>Q9TtECN4F6To&%t2<4@G$aFO08m3ixj=ufWigOo3upc?X`lEmpsFsERb%&r`& zg9qGke~bV4_QCxx;ftnbVxb@l3wKN9%6rx7b`S`35;y#4!UTyBnd!Z;nC-Or&d{&- zAevj+Df`2FviiB})ZNEQGL}L|BuXOGm-FY(J(h@iUT`?=T}QBDbFQY@BQ&4?iu0}Q zhyyh0AUoTHkV-glmO*_-(;obs_D%;9?_}=uy^^c-gm<`fP2j?sAL6lHlIh+%dS z@(atJ*)M*t5DYdF4@IzwiTp?27aM}p#p_*zM z#>!0(YCNPAP5p0Kv}&9tEKyc${DnF!m(bSkB{QQR!A^sZo8F-{+zG&fq9amMm#O;? zzCLlj(Clw!?c9SsE9oAk%g1QnjBJ|Do}#AYfK)E~ zu|_OzO!6i3o;o34fBLrWJ^VLPt$k=X(?C21hABo`n(fMn#EzFd@$z?KR<9hTo-`9S zSHEe!og?a`y6zSY1;J|0;F%fQzc+!xMb~J*zSrXoMu|mQh()}(U746nIy%GY+-J27 z z|E-?wXySZJ3ejjMCQF<_nf-AEF2$RAj7VpM(wRHE7O>)Bttfn17O(uR1|z3%dQu5T z1Ng)3)E0I1gPDu(P^&0u9y8%^Xsg@SYhuy}W7yqp;)X%_v|Zx!wPCV!wa&}jHxo{@ zv#j{9l945-DS$m0C#PVg1e)!boHmxO|Ap2(`-oN)zAW=rkDKU?HsQ)LV^4EXF}+^; zWo6LtkF8p=>=unhf-Eks7cob1+MN?))@BTA5~E=9HgVb_0IVrLEzPapI%m{erQ^p< zmjzP}%k0`aHRelY)vO~jAZru=!-m~~)#M;-bmHmLz~-$v>h*eGshV9c_uMp@f$pyN zPBul^^0&1_ql#gUv*NkmD9Pmg(L{)n$3GO8EgJ(MGu7R5CMh;=aO5=usQL4FUHII1 zO>?ADHR~+_=!k#G%KyAsPX~5mP8H@%t(VqsoV15NB-`nta>-Bi=#jIWJpEDEm9~Ll zwXwW(pJZeVr0~g?B$P01k6);QU^t1?ZkV8cUmF#(xjHEzkW__8)jjFU=Uj$#3?vqhSjYZzenCI&yQie6P|0UVlGN8=5}A=gr2V z21}mWAvG_K*J#L&;=~BY!Wbr{vUaQj)RZ7Eyq2$S%Lrb1y;@JUodTdd_fzTWego-0 zc!a!vU@JB;aEOcCoGntj{w}RpcC+TrxmJ5{UN=hPAq&}-pPd5h z5kkzFlug+q)z99e;Y1U|2VKsC_imTXnI<||(#sCRD zkH-_kEJe%B`eo_%q;w)l^8 zu}|16<_!|JPyMG)1TZS|_enf{o>UnK;a<4t&+Q{-k)1IBfJit&Kg-=*-TP4rAK537 zP$!ugA#5oJak)R`%FClvJ+niu7<@Ska~+wc zWQ^k9|3iNF%fAZ1?;rl7{C_^t+TjDh>2l+;q?2k*K~`-1xjHO;dU$TAL5ueUt>Jc- z&)y*bHFbArFUMd4Q9s`38O-J;il?6X!Fyl6bc|Nc+9i4OM(DcvhkAVC_7VA~@B7)4 z{cG1u(3q)>(%gEfSa-Y1@&9>E4}7-ghj>mzV*DRGC&M~~2PVuHfawcv)PL6}EJhgf zmDm4D{_DjGZSkMREFDBlhq&Sb&kHBLB@5QxrWf2?=Vxp<>iW~r(B`Jvg<-W;)H z&7<1Gb0RV9b_d-&FM0AUDXJZ&X>J=9!$V6;l#6)Ig8aYB(oJ`3A{wD2w_Ymi#%Q-s zc+!T@D?NpaePYd=J+f-!M0Eu&C8uDeR4*T^r89SmQS;oxYO#VkJ18l5QM!3vS~X7l zWo7Wdt+VOu@Dqy!NlJ_hJZJIqKUOg(aHOXL5LYWcUmMj0$7S{tf01sV@TB=!GiQ&? zSbCjy`^3Vk3EJ%w0(_Xp|M4Lefm80pS(*_!?;o`ghNph$p{0pt|n}p zA{K*Q+3A?#=@=TJ&3lI8C-(`!l=&WYIf9c>;M1& literal 0 HcmV?d00001 diff --git a/textures/caverealms_glow_obsidian.png b/textures/caverealms_glow_obsidian.png new file mode 100644 index 0000000000000000000000000000000000000000..a157738249ff0635f2c7b2d6cefd04960552664f GIT binary patch literal 162 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa2=EDUWt7)pRMcZMaA7j_X0i@u za*AaRDPxYP`JkpO1ytke>Eal|F*7+qAfI#~wX;z@Zc*lMo}eBQwXrae?g$Ge!o>K8}PbQ=;2}1~PcM`njxg HN@xNA<>4&= literal 0 HcmV?d00001 diff --git a/textures/caverealms_glow_obsidian2.png b/textures/caverealms_glow_obsidian2.png new file mode 100644 index 0000000000000000000000000000000000000000..2702d59d9db68d98f92a8dc2037f376feb58a23c GIT binary patch literal 661 zcmV;G0&4wYwf9Khipx+n}8 zj15-SjbFQU3+1I$*SfC%*0vjTWt%N!4P|7?Akj>d!iX;c1Oky@h&MGcB+9{X<>-a4 z;Klffd>*j-g=drL#<%H%Z9y?RtXQ2i`I8OI;wWz4@e+0+A|K6FGcV%lOum|kOK&}w zb?Ud`^LL6pik}sug{wr3SUng6a0fTBu;?fr{na7d#HFt7>(M8+F*#%zr?B?9fD=1z z;4tQK5%ZYBbzII^&=IV+JW%me_%6S3}p2sz;eIFhC0JGs_+Agx+IxgTDgg;GV zDx4T{?u{8tjGH4qB5L%WaP1XweBEPMCB8XfiDY_Cb5%<}xH4lA!Px`me)lrAaROJb zIR4h^hD&=c!193jc*j)TY5Xb^Tf}Zejo#jg-s@8DZYc&thgibV`)0r-eu`op6EE#& ze1F>ge+VANPujL{r4r*RV?5LW^rNEHJpcdi1{x~zjW~zXYs=^&*M0r zLej4M*n2|nRUT4ezw|4_KtMo2K|w-7LPJACL_|bIMMX$RNJ&Xa zOG`^kOiWHrPESuyP!bYQP*7A_~T3T9LTU%UQTwN6vWfvE3K>&Fh8;l?zq9i1_ z${3FT007HLL_t&-83n|PqSkzY{2oe>lE*! zc@;Aw2x9lHzy>l6S7TmRHZxOI>FR01OjQp9)Q#l(O8KtGv2FT<^eiuNjt`4d-PL6Y znSh$D-mhi+8tg#yR~6vTtC`s-?RByHFe*UV)fY+9tg!s6>7h84E|w?)W>>ZLcHHlx Z=pXNMAwp|7a`pfK002ovPDHLkV1mVTmd5}9 literal 0 HcmV?d00001 diff --git a/textures/caverealms_salty2.png b/textures/caverealms_salty2.png new file mode 100644 index 0000000000000000000000000000000000000000..7f8b5219e571d9df0d1bbf2e07feb67981202e3a GIT binary patch literal 330 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 VtK^HLaAN=f002ovPDHLkV1jBU)Vu%y literal 0 HcmV?d00001 diff --git a/textures/fun_caves_dragon_eye.png b/textures/fun_caves_dragon_eye.png new file mode 100644 index 0000000000000000000000000000000000000000..ec9294debc406574cb5f16e734ce89d55e074dd7 GIT binary patch literal 2589 zcmV+&3gY#NP)0(qbcn7e~sE1lFeVG658UEoiVBO8)TNQA-fib)onIE{eXJ2%n#OnaPH+K0MGaN z@S{&CwI8#@9TsoDgeiEm4j=Qod+!k(#6b)oX)c4hN}}{JEipzUAQCNP@%0|oQH({#J>w3raXkZ5?k|6VmY5^Dw02fNzh_|^4%L%BGf{)-KSh|CNn-t~gHcoI77}#YJ%XA@bM%1R z(mbYba@zika-~UH$)T$wTwg$TI@}-4pii3wLn-ES8s@%)E7)jpgWBD9DK2Jl2;i3= zpB2y@+W3M%P_pSrQ=)&K($wq3f?=Xp3=~PD?)F$o=BaRu(`_?mh+>AheeGr3PL=l5 zL+}nsC?QT81H_O-1Or{xCgg?Svecdmv5Ekl3&R|pMxIZ~t|@6v02iZc}$36Ra}tSm3E{lGc5 ziJx-7BeiG{y5}vWFZ&9mmV`*OwqPq43k4to{KE>D?$>QH-`f&dv za{6UPfeDS_Ur8*)>DBic9Jxqm5c-r-=MhD9jpW*M`dS~6k01Y6@{FuRMhW?502r$J|IqQ_(c{si0XkP>EDU%bg{w+alpP1@t(m&$}4z!M#iRv0-wI!YYr za|oShG_E4EyMKz+*LnM$e|u)JweAPpT3O|l{439F_4@Kv8Xt6C7&SE*MoJ9n9Na~9 zd_t;^>4*fz2P72bjF>V2X#i`l#m*w>}vGYIs93JTK7JO)i$Xsuk)vBld3l* zrNIHDMQh2@*?5HXTi%_lV`StK)2Vx)+Ve>-^5n(lz+3ww5Na~GF4iPT6Gff7}8Or%t`;4K+7RI6UOPb zF@+J@P-iBh;%F%%g8G8Rj%x`D#WGc?#ZjYtZi;dqPVmPQv}lgjQ;VO-K2B?mp6oGe z?4h!QD98I7x^j!c&9_MseZa9SEvnU~Gw>$WP zL)^{NAKAp(2L0*;-PM>}u~0)zyb}lEc_;++437g5JlCP!6EJKY&#R!j0-4hig;t4_ z-C*x49+HefNbhodxJ7xdfuR`K>OZ8Y?_b6cb&Q&d zkPH)0=(|o0!=;)sv5@b;jJfzK$eb5To3F49l&tlFm~V4iVU)HyNWl zVP3tlLi?nKFJGLZEJ>$RX%R?G&b9b&eeIjvT+Jb_EYEG6r}5*5dj!TJZH}1}isXuK zV;Hv)J)2{5le9X+Xlmiw1|vm9KebSL4u@F>CoyDqYZH_px(BvpaXRT@%WY!eD7O}G z^V-XKBq4xwrt#lnR4VAPSJ`G{kBH}G)|~U~^%_lcm&h>2FjPg8RUV}qsNon|R-ski zWYV<=U-nSdH@N)rwHGLwFT|0hMF7N=HDkkS91!vv^sN&H_9^XdpS4sP35(ph_L||a zRYIOd5N2E^gG1)h3W3OgZo5RI-C%Y}dBJusqNupM8s4~~zRJ}b-zB%OjyjTYm$x9G&4thXYLy)I+#wIu~#Q4&63hXhyfFE{&jx8 z-6oS;zL28QMcdG^{Act*^h;BaQ;xB8XO1Q2UfB13{oDV+3OlsVSyY};RBoN^h8Jx^ z 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 DZ>d-G literal 0 HcmV?d00001 diff --git a/textures/fun_caves_fungal_tree_leaves.png b/textures/fun_caves_fungal_tree_leaves.png new file mode 100644 index 0000000000000000000000000000000000000000..58ebb5313b7d7ac5f596d608fcf40db2a2e637d1 GIT binary patch literal 2135 zcmV-d2&ngoP){!lD!f6=;Ig4-h04h+Prv zQM+eD_ACg>rixf3R5%DLksyjk5RXIR#7TUZ%#7!Jd=K+thZCmZ7uobWU29#XmN`6o2{M zS(!*AXti228Vz(^r(Unq-$!(0iOR5y=Se!{9sowbz=~y1iJpS z_4*EkE!vL3i!c0Ercx;?l?wfS9{^3$*xTEq*+;CLd`>2lNj%S^Uaw=@HoabtUavaPzX)axO?~R7aeJy zeL549V`F2?&(Cx9>Q(yvKGA3t%d*gPT_+liVwxt4i;Lv*c~Yqq#bS}$J2f$Mo6u;Y zn0}^mQJKr-h(sbxPfs&DJBw}GY;JDKAAkIj`}gnHZWkWK``tR|KKyTN+9<&Ev`Sdt{SXq=ujvT?ZZKRas^Le(e|0FEaLK|1Uw{83U#Kgp> zi;IgWih^ZXn5KzonuxdGep@D!Nh*~J@pzntg$1r%yM}3+NGXZMV%WCL#>U3qcT3d| z{Fa4o=x7QEPcrB>XgLnLKfuw6taM!$zu!-<*F#lREXzVs6l~k3u+ot-5bjgrY^c<|tXEEEd3u1h=~M^#nCYp=Z~ zUwP#fve_&L2M650f1m5uufL<~I!;49Z@0U2dp$a)i_|@wwujLlkerH9?)MQxh#E1{ znUD;J!z2<39LFIZk25tjg<%-fYBg@&yh$>dWNvPb-Q8U_Ha5Q4DLpzZ_4OOojrx+F^5YL#95!k=w#}e5AQTRemIlanN-gRaN=sn{NO(efl(pVIYK{*XtpKpj<9<`SN9UZ|#Ye=OBbhFdD!w zRphXb9@BHZ$DMnDsEK%S<^>$#F#cRdwpuM#R#q4r8$;K1zWeSws?{pBT8+bo5S>Pg z;n3xcH(ru&zWFA#T8)j34c6Ay&~=?aAb=2p)zwvYc6Qj`-=|b65s5??4u=$r#V3=z z;W*B{Xf%38y!YOFa%*dg<>h6bdg>{@{`zb7_Vx&cLcIFwtBj3}(QG#9^?KO0&F=0l z)6>&jx^#&1G!`}x!vt{$z(E|K7E?a%}sK-9OZJELZLvpTt-Ss zDwU$w>k*5^5En0Al%sgQx3|YAJt3IY7{&8!Hp?hIAyAJoisyRQ9H}S7#~*(zNAbMT zXuLB@Pl&hPdP|PtxuPhH(i7tH<;!w&bCV~Y?>(yh!gJ{MJ4^(l7fzl$d1h{I?!P>D zU6N$@6$T&L}-0 z<|ZO-AVn@#2ZqkvvbQ z(~Qy+;fXF7$paD;;s zb7ZU4;>@33lKWTN?fB)wsd-nGy8O3u&Q5dBs{sp^J6wKVkikAQY N002ovPDHLkV1f-QCjlD?Pcm2yPAbGl@`2I468^Hq-*7%)gbt!Eetk$1+T&5I66B8VTNXF7uiKE1G8nP zKDjY)@Rj4~#O_*C-GncUG^8A?Itc{AG0>?cFyIcsxz-{0{x$>m?)8CPuMx^Jkl+XF zTe&)>W1Qw;$BN%4-uvvVroc{C&W2}EEXhL>A&AU!AeTy^Jl`T*{H_`Q<*WXus2EX|>H$nXih(d1Kq8&lTwD8#(mY3J2$& zq}zEp9`uD0+g)B7x8I4_4LRl1hT=H)!a55-IZolRKoH^jTk!;sAW0|5xJaggwWSWo zvg+WeHANsHSlCmehmSuz4He6(cq$xtK*+9G#-pm59|vCjX(}|j#Go;^E?-tV_tL@N zaXsU6tE7f(h>P`vYgXco>#JV>`-OWNRv=%po0atY?;OPwBhFFxn48e*#pv6vNkEk= ziZ69`+-0`aX6w6M;q!~0aBie&M0%Kp2dABedN0g3($E zQl;tO-Qljb?MoE5RZ8IJ#$`C@3JMFiW%2hW1SC#wC3>BIV9jX>B$ujj|ET|Rwkdl@ z-PMr5#;S=Rs5mKpMHbOpK-Qf5uxU@-Ff?gjyKEDs+w?>>E@eb4pV9c^V5k3HYo zGdj&Du!Ijr{2(J}2va_Yg?g&rKDb9R>fDxP!rhz9xhEFth z341n|phz6UJhKrXz(dD)aH`>2u<+34!_@ifXY$e#zCa(xv%grbI?E*3>d)I;O+iMw z%c_Vz{F|NCFD$mp9{Kre-vO~@O;Mdc7y_k?0Gn2h7_k`Va54ef3=&*kigbCXWBF%IIXeRbAlu(0%e*^$TDDDWRVlZ=Bk`JF$i$6eTbu(IO=wKQ6Pe$yfhnD z6&t}rk-!mBFsj7RHx}mPs&ri6;yg?e(Z%;YVMm5hi9T-~fKMCmd=L#!H$?mNTsVH+ zT3hn#FEUNlCnhJGq^bq$T?}16kYz+gQ97x{i8&;a$l#~J5D>dJl+-B|5>VMnMyoeI zr}GAAVZ);vQCY4L*pLq{-W(9jwoDX_F(A=d@dr)!-#oVUy^GjLugugZ9^#P95o7_TSu;zq07b+XLq=jd`XQs0rVZszSZqqE)J$le5S}0YpFyRm;kO z;6Pg7<&7{jPD8@K<=BC1)o#Kgu!a%zUgLt|lN zG04G|VFoS{#)klB(1});|*bU|B@V5gM8oPMpqh*e`BfGEw z2ZJ-X)D%MwlM-mG1f5<5I+YCMQuTR>W!NrdjTMG@bzpl+CA-oxDT$#!z(B7@p!BjjqsWGJT37o3useS_Ot6D{;;yICU?@HwpsQDi|*;G6i z1R$8L2Rnbs7u9jWtsv~`2?|QX;xh-o?|`^seFQ%42$Yg@w~Iw+mOm9aH^iC`Uzqt z9#~dnmF5*&q^R4SAkx#s=-IXTFh9c#Wtj-R>==Q_EDOF!3^p&ffl;G?1E(6VELn8= zk(D)$x&p40G`{tqHJQ+_RLSSH)iJ|enPIUe1Wm$<$gs7PqS_rqeG)WW> k_eNeA8yaKoe^12!3v5h8f_0m2jsO4v07*qoM6N<$f8?|q*4e(vXfzluE}z6QGMbRh^b@b~i$ z2ffAb2GarWjNIHGpwl@J=<5wF{eCXpYpDe*E7JV%84#pr^t)+5v_=G2T%PG4?6ds6 z#u^<98`g<@HUzl}baa0PgA-yOd>r4%{#>vBpn0fCaE+gZ$vPY9}*Ix{xz?hotEs!w?{rdv;`&nusA;x z8ylNIvmPm!cZ9kZrt}E-sXo_{iMi<`mCS_B;i<8qEmt@S2pzmjLLTJxrQf-N3Y@#C zP#g&oKT=`&oXeaeP-dJjY^NB#0CxYF6GCI%<_H%T-8>d1v>+GEOEUUXiOfis$kSq#)6qaS)+XmU#6@OH0caeux;2D0|S?XV9hG!Vuw6Yl5te z_#CbK=wRSQLJksZUs7zhu3d4uw^%M>$mZR-q?mD~k|?F3gypgeOxxSt-8Pj>8xys9 z@{jO&Fm1iW=vaxBa5I~&=?Ocb;6vVFCGg_Kf@&hoZ)D~*lO!FR zIZk6GIwR83(=|P5EHKTC6Yxk-tfY4){|#@MXF!F5e}g2<>g?sBZc4bQm8Z0>59v$D z=fYo-%}7%B$ONppQJE!O9)>fCii)~IeAd%*GFP33NxBxDfY8BHUCgUNu(Np~cxn>< zaT?~MOi&H1M$_J>VIa7`g-22W%tJy$UG%j?stY2ypQW~cO&SI{n0gDKi>K-)Eq0&+ zIUG(}T>XOtPow~5=_ju1JJbU($5YSAw*lYOX3aLZrbzXKduG)J_xCyG;;(f>DPd~}vcrlOkl}}-_5mmd#vUX&3nq3|!XS4SXmB7_q)$$yWCIvs6eyYweSlo{Wc``2V z$2%Hh1Mxs*WVoEIg;brmb(V;5~G2&Jm(cTSVD$b0_*8qFw#G@%euDW+Z`4W zxnaXW=~f;oBQNg^i>P}T#4(ztR{sOSkYOsfvWVeSt3-tTy3#~HJoN&r0KnC&MLg1m818VYNxyzi!uBRZ zfy=5@tJqfv_|4|kYpZs{EMNWVJG2Waz)()Ih%n19deN4Aw@|0CqS-k`hlX0tDEt={=mN_3=e%2-WObP(4(Ec_ks32ic8%x8$vz%kSIp|d`a z3ohyzcki=7bd}*o!BND@Q`o{^u^O1ljovkz*vImT$18ty)06Yt=HjjWA0{|M+35@- zZIIVKctFZK;Jbt@dXP|*8D}cxnK*XMeRJqif6y!VHG3G4BKhgDk$l1a!o}X)dn{5+ ziZt@^%g!cw4yr!z8$WWE>ERhC0rfR7Fi@KuC{hh7XV`~9;6SC|WtJ4#Rq>))R&5{c zXE&sr$)@`n`(UwHxX)@l)s8luIhNsB-S$qe*dqJ676H#T1tdyD)Db|*Zt~YGQqCv0 zFK5dzb%fcHwdA-6-1%f&_pQI$NmBN9H(8Q0KL74^4-fhHI0Yc>+;4NSw$|taX19cl z75yQ~pbDFF6GfD#Ne_kfP8G7~6$6D!i!JG%OFM<13@@_moZ{~$+=-o1b}ywLKOQI{ zgH+%i4yCXH%(OLXpO%<9#h+!_$tDqYRz6`@#W7SLMA^cmU;~sl`>Ec3*>nmmq(xsx z%R9{YpGXIw<+j3bd~%pE5Fo$>pD(6lSL|pACY= z@Ul@O7lm6hDdr6iXFkQ*f_@M>L zi!<)tk`?HD(TFo%cB<#ZbZ*t#?^)VA?`L%qK>Qe_dSX-y5`Xua4Yf5o zhbc1I!4h~-O9YKI3b6hB^Cy+hId2LChsJ7TFs?_V_L>~NzV;=L#FGNb+ir3V?n%RJ zf@z-rBt{c%?n^}IPzl$DQ?HR48XDFE8yYK&YK6m%^2d$rBxExQxs@Hzhq$LFbk+yb z0`@)&vji7OTblz!p-|3-hvQ6Wtkw(vwKXgF-|E7Q?RF?j{Ul_RaAW1h^G?lm7>WwB zo=&H8rQd<-s8ku8jt(Fq_K{9&^gdudkByxHM}>PWJNGon%Sp~C?x=qkpEy6bMq9(i z#s++R!R5t^7grVg2IO;dG?egmR~O4xx00Ei-rf=sCuwYI0*dbH>KYp#&mBrJ?w=cC zR%g0-x;7Yqs(AbM?OFLYuB~pfFdu3X$wMEjMDFurPqW`C3d4+bC!O|pEX%Si%Rc{G@BK**vXnyG&^Lv?$u*RN+=~#FV=;@n zJr-k(S&VTPV~jCNvY5pzi&>5%Z9^Ku5eR+RH%CiCXp_z5V(;$RyOJzxWm%S`ku)dYP{dVBlJY@DU|-SyGr0oM;EFQ2!@Yb?Ep^KkrJ;lr6T z-hbN9_piR-JNx78OqI#`5i+R!vLQ)?UGC-j0Jv#X$O^%#m0*4Nn6z$U%Q|YKg@|a> zm5+eGCmv9kJ?!T}Hb<@*#0bT>mS|u(b;`{F3^RtM*i@B(U{XH>;5+-{09ajvy5&=J zecldtxtHtXZu*q<_*2Y|i=lSSnEEannqwKk6?YE;qK zIvXaV_&n)+o0`+4u68i}17?&GZz>IiAHMzx&($f$M2V_Dh28d8dY<6X#3?x^hU_+p zYYuM9#r9gPpI>DqbIv3IZWK*^l>LN)HU*v_!8vsqC+2s!el)`UbQxV&Fhqds2MN|* zYmkvHPykNj)5-ATt6CNGgZJAA#7=K{UE`|S58QFPnpdRP-#T?v=RsC0qwgJC+HoC zP+%@U1iL$36NA@a;xw)9**Y8kyN-hR;Ad6>5$}BAql|dn{{H2hw8TQe3Pmh zV5J=8?pOo$jkg)k|B@F?iDtW4p%@7|*nSXOk;J-^g`+5sCkj~Y5HYPq#rRhi_vS8H zu$IlEx_`=Y`B-53F0VUvZWWR&3|0YfJ1R0DxtY&WaTHd{QSKybK$lqYH&i{3SRg=5 zfFUG8^^jhRs#Ga8x&YX|j-`YtJ0|++JM3hOtYjvif*fLs?qVB6;;RUPRGRNZAUm%RMOBu}U8b4txbIMY2fQ@Jw)p6JwI>vRH2v@M4YEY9w71eE% zj6}g{vQ+v~!E_nqW+C1?bh2^z-jy0&%LX8Rbil?;6io&|b=bN3IkkEc&psooyhB-P zEN6boaxukjw8T;|&Gu_2Xdy|p;i8J5AQ@<}bQ;I?T{cq{mNU&B)$9%n0}pz|1SQ*( zMRumnNNSSBy%@U_b#5FEW1>@cEoxqXTl-TiANO(VWE|b8qstZ>#cyzby%1w}TSuPK;$!DZ8K6Y}LTTc>~-Pj%7qwKiE zjRc+_z!eD=4?{di*Z4(45(_G%!anhUhbMwq5~Sm>dXi>su)^v|Qc&`PSWd6Sk0)|y z;V!n{MjATHqQ60hUm&2&tCXYtXiD_M?gH>$l zqq^s~BEo#G9~pqvlQdgHugEIrd_26TGJjOErA`=tbiaz(*yBGN<47mMqjrLoObvYHg5H9y(Kbu@Fl&id z+$awzJV-z1gVHpAxHblAm}Zw6g8G?CD%{2ns%Y(bV&P4UXpmMrNUP=$ix$Gg{NJ?y z@@v1PW_`kE?LTLw(9d_rTGVlH{RlM)W~YVi2gyVn;>}a$POd1wcj#uOLA~8ZYGC>f zUNDK_9g&U*t{+VD;p8dr9}KWHUL&FSc)nonMIVnQ&arZ7yy!qE`B6KDTdKW7?;oNuuDtcQ>P zEl+F?R5@r%vO-|Q0@!|wmE++aHRh^UXes?9183}x{u5cPCoWYqCi@~}6rcL}@&EAi z^`{1t`XSS?4j;YQzRVLftC@asFmstF0PdV7zQ_|S7W>F3bsk@-DHlR>%>2PHAB{b| z^z)M4K?@q_y29LxL4f2pnXY_u^k+bg+58k6Qyr#*KjXcVvBMyVU+ej~#6NA4}*+V`kO!PpQtf3olHy3An<`ldjTDvXS zooI6VAi?ghUZJ~Z02m>YmIS)3p4ASYpbLQ}1-c$2E?UHbEn01diiooj{x7x%Da^et{5#7Ojo1ytK*rY*+A=iD1>kOkh+=mHbNMv$aSJuz^Wo5O4`ihj z^SOR%T|v3C#fO=b3lb{mLCJhB!_L$hOZz%rN5SwzsKJoRM(PQ1;jsPMF|J6EP#s#I zOMZdmcKi&_>!JpFV6FHLveQ$~M9?OMiXPPY@s$$qK1=g(^b}XNG2{~O7n5wHUa?$? zv03_z$C=+?M|=Q;8pLXsF}?ScKVDA%zb~i%4K$uYw!#LlH2?qr07*qoM6N<$f{GRx Ab^rhX literal 0 HcmV?d00001 diff --git a/textures/fun_caves_pillar_coral.png b/textures/fun_caves_pillar_coral.png new file mode 100644 index 0000000000000000000000000000000000000000..0c5b5153c23be3ee7caaf199ba2c17235223c6fa GIT binary patch literal 2086 zcmV+>2-)|EP)gbyE`V469?GFpWG6uV+#l@-G2Jw=qDmm7TZzgN`FE=j5~ zU1g}&4o17f?(QzP;{irBV?K9L)*k*!5C%Rcy#uz|O>X;_TwkA~s0zp}!l>X~f6ip& zvfq15qqRjz4H2ekG96!`nFTk~SGdccc=++>sJTkpZu7|}k8#}@b-RsL)$j)EjKbX{iu=$P)#7T4D|{O;4wm<`6ns~NSn!P(jOgwcY% zgFS?0wh6O{=GFs7cL_H`hpn2x3qo=Q!Z0C{7GaR5YFWWK5RF42D-Uw=5)7{8fk~o9Oil0zs(+%5;LJMBENWEd3CW zu&WkcFe8YU6jDf0fY5a8+8*NY_!Omi#N=j37Rog2T~>>0E@yAh4TDO>WU&m;N;NF2 ziXw$bN{XtMsM&kSvQ4F0Mm817S;Wd2;HLqtY7Ij-iK3X1H>9F#96tB}ISW~P6QV-K zKt=ief%1hRm#AANLEzA;nY?)MEmh0JZrNyBnf=~F>YaVI8#Y2HL}7%t3du7SMUe@E z1^%+nVDJ-z>o;`jO}0B7CgWSIn#FFXN0Mfgj537`QI_H-8D+hRC`f3wO>Xm7eZB0%Non<6G8FM59)xq(Ogh!OXeC_ty-E zGaSc7C^9S8VKHA|nI@KL0vTFaAxV4`DJ4%+DwQfH4;~?OlW^%FWf|h}$wy!s_(?)z z`v75B=qiN%jQhJGS)5^L7Fn{!s1c~ErY|}E~DWc!~TRc zg;GhyC~L%#M-*nrSjd`=Y{Aj-F5Y6y=;AdZOF7=}v6##lk0*5Z4$-SsS_jWi{`~0X z3s0^S1OaiB;@po=3Yk2IA}?6F3yf-s&Q6#6`xT?nlKzdu-foY2y^J5sFm;(cNoiQy zJbv;CxvC&aWdbke*Ymf0eEO8tV## zZ~6(5hhiho*MYXtC&W&tyOHOcenKR%i!)nNEF$h_myG)Fc(`}WR?Ft~+qYQFHg>(o z+?kRippy4BFiD){r4MsM<`7KFY)oSuHZk>{I!LTu{!;n4>heL_0>`=5$UJeRhcZ1Rc!1G?uL#4>d% QDF6Tf07*qoM6N<$g0#)+(EtDd literal 0 HcmV?d00001 diff --git a/textures/fun_caves_staghorn_coral.png b/textures/fun_caves_staghorn_coral.png new file mode 100644 index 0000000000000000000000000000000000000000..05857aadc5c1cdb51732e14a10063a5a83a41c8b GIT binary patch literal 633 zcmV-<0*3vGP)KXX$;}a?^@GT_%WxN{g z%L(#C0E)qxsv>wsAc{W$RQ}2=(e>I5QWU{60``E=9uP+HA_uZ+WcSLDP=?SR5Xy2O z+EM1HT3ea{u^U7(?59g2p0;xTGh{ctFhQQcXu1l%HKt|yTy=~h){gl?ZjjN?yB?4ZUVE14KJh<)*n1}ML5&>5EeZ2N951LbQUwag@01kVz42ZA1-`OI^d?A2w z9vHbn3jL0HtL7@uJ(y*{GS5{5Mr`3cl?+++hwTQil*_{Ag$edMTa`cI0RTP#_lG&a TX-h#200000NkvXXu0mjfwCosl literal 0 HcmV?d00001 diff --git a/textures/vmg_glowing_fungal.png b/textures/vmg_glowing_fungal.png new file mode 100644 index 0000000000000000000000000000000000000000..d3a713490cbea94503f71a0fcd1de193c1881af0 GIT binary patch literal 1164 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 RQ62yQ002ovPDHLkV1hu`y%_)i literal 0 HcmV?d00001 diff --git a/textures/vmg_mushroom_giant_cap.png b/textures/vmg_mushroom_giant_cap.png new file mode 100644 index 0000000000000000000000000000000000000000..73f4abacf01cd391d39348cd5947b3e61cb9fcf6 GIT binary patch literal 756 zcmV)fJzAYp!gpiVX^w74n!y1^&1Ah=Bg+kG zA(;*DXkUJV)o@YE$pgkRX4LDFt`l@kqbf^uUEnqvRE9xT3X;_ZB{H5~e#@Szu)PD~ zQ4ckK`xZ@<=&HhTJ(B5|h96M3O$0Fb=b9&yfAu>;D0=_C z!V3;rxiNAP&q0}_S;hSQggnofjs{%*@H0lu#64+a*q<@JzG65UWBL2Ezr4V(97?I7 zq-l{A{NLHqv7CTtaD$cQDAQyzxF_2zP(n~_b94oD%S26jHv~t=JDqDzo%`EcYKGkT zq$&zjk>?+Ec4Wmei4hHZ_mk-(a``D|3Ra(ZG8=bM$>9{&+&rhN1v#}_642qenst>^sfFuYC8Qlf8p&vVG)I#o}DotcBu-1 mvD3Dl64UO3JW;q%Wwe%!w~>I2cp zwr$u1L%3ewc|9-WW#RGjO)3TP$z$J$L5WciNeZGQ$+UeVrf?)g zY#;$CD@h_DpXs9^K7`SCkVz^RG)7dFby-jb@p7WK&TN&@8gopD1-Apu7o_eR8Z#0T z(Z7?(GsB*No~ zijdbc0b#Vt`g$X{qrsVGxH{vxV>4jG&~iak0y!6EN(7$-pGeH~R18sCcck zG3dRrZC|tj(c3`}jtnE7PRurV?%(9R((WIm^Oe~uxhxDDSlbyB%#4yx$o}~+W5078 zcL+jQ3Rx4xl`%RRm7wYWC&xxEXObu{%Szuqkhm_?*0A0gt${hjl{qS!FZdK%eS#P< zT~JXZD(jL_4AHXUM0_+)Kw_rtcZN^?1NE|KdE3HLi2wiq07*qoM6N<$f(}$W`~Uy| literal 0 HcmV?d00001 diff --git a/textures/vmg_mushroom_giant_under.png b/textures/vmg_mushroom_giant_under.png new file mode 100644 index 0000000000000000000000000000000000000000..4f51b31717b72621c0df43564a2e50d73aa322b6 GIT binary patch literal 765 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 AKmY&$ literal 0 HcmV?d00001