From 9b7e71c675a8158cb6c7c226f49ce20e7c92b12f Mon Sep 17 00:00:00 2001 From: FaceDeer Date: Sun, 28 Mar 2021 15:20:52 -0600 Subject: [PATCH] Chasms (#19) * initial chasms mod * tweak default chasm settings * prevent chasms from breaching oil and magma seas, make veinstone actually do something * overgenerate caverns to eliminate floating stalactites * make veinstone punchable instead of right-clickable * ensure dfcaverns get carved before chasms this has an unfortunate tradeoff. Chasms will no longer have floating giant columns in them, but will also no longer have smaller stalactites and stalagmites. Also will carve chasms through lake water. Not sure if this is ideal. * add rare big webs to the chasms, to give them a unique feature * reverse the dependencies for df_caverns and chasms, let chasms go first. * fix web generator * add webs to level 3 tunnels, fix sunless sea chasms * fix up tunnel webs * make webs snappy * make webs slightly more prevalent * add chasms to the guide * final touch-ups before merging * allow anchoring against unloaded blocks --- README.md | 2 +- big_webs/LICENSE.txt | 24 ++++ big_webs/init.lua | 198 ++++++++++++++++++++++++++++ big_webs/locale/template.txt | 12 ++ big_webs/mod.conf | 2 + big_webs/textures/big_webs.png | Bin 0 -> 309 bytes big_webs/textures/big_webs_item.png | Bin 0 -> 380 bytes chasms/LICENSE.txt | 21 +++ chasms/init.lua | 169 ++++++++++++++++++++++++ chasms/mod.conf | 3 + chasms/settingtypes.txt | 5 + df_caverns/level1.lua | 14 ++ df_caverns/level2.lua | 16 +++ df_caverns/level3.lua | 29 +++- df_caverns/mod.conf | 2 +- df_caverns/node_ids.lua | 5 + df_caverns/screenshots/chasm.jpg | Bin 0 -> 55019 bytes df_caverns/shared.lua | 33 +++-- df_caverns/sunless_sea.lua | 13 ++ df_mapitems/veinstone.lua | 54 +++++++- guide.md | 14 +- hunter_statue/init.lua | 2 +- subterrane | 2 +- 23 files changed, 598 insertions(+), 22 deletions(-) create mode 100644 big_webs/LICENSE.txt create mode 100644 big_webs/init.lua create mode 100644 big_webs/locale/template.txt create mode 100644 big_webs/mod.conf create mode 100644 big_webs/textures/big_webs.png create mode 100644 big_webs/textures/big_webs_item.png create mode 100644 chasms/LICENSE.txt create mode 100644 chasms/init.lua create mode 100644 chasms/mod.conf create mode 100644 chasms/settingtypes.txt create mode 100644 df_caverns/screenshots/chasm.jpg diff --git a/README.md b/README.md index 2b73de9..587e98a 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ Some of the other cave decorations provide dim bioluminescent lighting in some c The "[doc](https://forum.minetest.net/viewtopic.php?f=9&t=15912&p=240152)" mod is supported to provide in-game documentation for all of the new items and nodes this mod adds. -"[ropes](https://github.com/minetest-mods/ropes)" are very useful for navigating some of the large open spaces this mod provides. +"[ropes](https://github.com/minetest-mods/ropes)" are very useful for navigating some of the large open spaces this mod provides. Some are large enough that a [glider](https://github.com/CBugDCoder/glider) may be well suited. "[radiant damage](https://github.com/FaceDeer/radiant_damage)" greatly increases the danger of the Magma Sea if heat radiance is enabled, as well as several of the rare crystals in the deeper layers that emit Mese radiation if that damage type is enabled. diff --git a/big_webs/LICENSE.txt b/big_webs/LICENSE.txt new file mode 100644 index 0000000..6bf46b1 --- /dev/null +++ b/big_webs/LICENSE.txt @@ -0,0 +1,24 @@ +Sounds and textures are under various licenses, see the license.txt file in the /sounds and /textures directories for details. + +License for Code +---------------- + +Copyright (C) 2021 FaceDeer + +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. \ No newline at end of file diff --git a/big_webs/init.lua b/big_webs/init.lua new file mode 100644 index 0000000..986e2df --- /dev/null +++ b/big_webs/init.lua @@ -0,0 +1,198 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) + +local default_path = minetest.get_modpath("default") + +local get_node_box = function(connector_thickness) + return { + type = "connected", + --fixed = {-hub_thickness,-hub_thickness,-hub_thickness,hub_thickness,hub_thickness,hub_thickness}, + connect_top = {-connector_thickness, 0, -connector_thickness, connector_thickness, 0.5, connector_thickness}, + connect_bottom = {-connector_thickness, -0.5, -connector_thickness, connector_thickness, 0, connector_thickness}, + connect_back = {-connector_thickness, -connector_thickness, 0, connector_thickness, connector_thickness, 0.5}, + connect_right = {0, -connector_thickness, -connector_thickness, 0.5, connector_thickness, connector_thickness}, + connect_front = {-connector_thickness, -connector_thickness, -0.5, connector_thickness, connector_thickness, 0}, + connect_left = {-0.5, -connector_thickness, -connector_thickness, 0, connector_thickness, connector_thickness}, + disconnected = {-connector_thickness, -connector_thickness, -connector_thickness, connector_thickness, connector_thickness, connector_thickness}, + } +end + +local in_anchor_group = function(name) + return + minetest.get_item_group(name, "soil") > 0 or + minetest.get_item_group(name, "stone") > 0 or + minetest.get_item_group(name, "tree") > 0 or + minetest.get_item_group(name, "leaves") > 0 or + minetest.get_item_group(name, "sand") > 0 or + minetest.get_item_group(name, "wood") > 0 or + name == "ignore" +end + +local cardinal_directions = { + {x=1,y=0,z=0}, + {x=-1,y=0,z=0}, + {x=0,y=1,z=0}, + {x=0,y=-1,z=0}, + {x=0,y=0,z=1}, + {x=0,y=0,z=-1} +} + +local cardinal_planes = { + {3,5}, + {3,5}, + {1,5}, + {1,5}, + {1,3}, + {1,3}, +} + +local insert_if_not_in_hashtable = function(pos, insert_into, if_not_in) + local hash = minetest.hash_node_position(pos) + if if_not_in[hash] then + return + end + table.insert(insert_into, pos) +end + +-- flood fill through the web to get all web and anchor locations +local get_web_nodes = function(pos, webs, anchors) + local to_check = {} + table.insert(to_check, pos) + while next(to_check) ~= nil do + local check_pos = table.remove(to_check) + local check_node = minetest.get_node(check_pos) + if minetest.get_item_group(check_node.name, "webbing") > 0 then + webs[minetest.hash_node_position(check_pos)] = true + for _, dir in pairs(cardinal_directions) do + insert_if_not_in_hashtable(vector.add(check_pos, dir), to_check, webs) + end + elseif in_anchor_group(check_node.name) then + anchors[minetest.hash_node_position(check_pos)] = true + end + end +end + +local sound +if default_path then + sound = default.node_sound_leaves_defaults() +end + + +local web_line = function(pos, dir, distance) + local web_spine = {} + for i = 0, distance do + local web_pos = vector.add(pos, vector.multiply(dir,i)) + local node_name = minetest.get_node(web_pos).name + if node_name == "air" or node_name == "big_webs:webbing" then + table.insert(web_spine, web_pos) + elseif in_anchor_group(node_name) then + anchored=true + break + else + anchored=false + break + end + end + + if anchored then + for _, web_pos in pairs(web_spine) do + if math.random() < 0.9 then + minetest.set_node(web_pos, {name="big_webs:webbing"}) + end + end + return web_spine + end + return nil +end + +local generate_web = function(pos) + local dir_choice = math.random(1, 6) + local dir = cardinal_directions[dir_choice] + local web_spine = web_line(pos, dir, 30) + if web_spine then + local dir2 = cardinal_directions[cardinal_planes[dir_choice][math.random(1, 2)]] + local dir2_opposite = vector.multiply(dir2, -1) + for _, web_pos in pairs(web_spine) do + web_line(web_pos, dir2, 15) + web_line(web_pos, dir2_opposite, 15) + end + end +end + +minetest.register_node("big_webs:webbing", { + description = S("Giant Cave Spider Webbing"), + _doc_items_longdesc = S("Thick ropes of sticky, springy silk, strung between cavern walls in hopes of catching bats and even larger beasts."), + _doc_items_usagehelp = S("Webbing can be collected and re-strung elsewhere to aid in climbing. It absorbs all falling damage when you land on it."), + tiles = { + {name="big_webs.png"}, + }, + use_texture_alpha = "blend", + connects_to = {"group:soil", "group:stone", "group:tree", "group:leaves", "group:sand", "group:wood", "group:webbing"}, + connect_sides = { "top", "bottom", "front", "left", "back", "right" }, + drawtype = "nodebox", + node_box = get_node_box(0.0625), + collision_box = get_node_box(0.0625), + inventory_image = "big_webs_item.png", + wield_image = "big_webs_item.png", + paramtype = "light", + is_ground_content = false, + climbable = true, + floodable = true, + groups = {snappy = 2, choppy = 2, webbing = 1, flammable=1, fall_damage_add_percent=-100, bouncy=20}, + sounds = sound, + on_construct = function(pos) + minetest.get_node_timer(pos):start(30) + end, + on_destruct = function(pos) + for _, dir in pairs(cardinal_directions) do + local neighbor_pos = vector.add(pos, dir) + if minetest.get_item_group(minetest.get_node(neighbor_pos).name, "webbing") > 0 then + minetest.get_node_timer(neighbor_pos):start(30) + end + end + minetest.get_node_timer(pos):stop() + end, + on_timer = function(pos, elapsed) + local webs = {} + local anchors = {} + get_web_nodes(pos, webs, anchors) + local first_anchor = next(anchors) + for hash, _ in pairs(webs) do + local web_pos = minetest.get_position_from_hash(hash) + if first_anchor == nil then + -- unsupported web + minetest.set_node(web_pos, {name="air"}) + minetest.item_drop(ItemStack("big_webs:webbing"), nil, web_pos) + end + minetest.get_node_timer(web_pos):stop() -- no need to recheck + end + end, +}) + +minetest.register_node("big_webs:web_egg", { + description = S("Giant Cave Spider Web Generator"), + tiles = { + {name="big_webs.png"}, + }, + use_texture_alpha = "blend", + connects_to = {"group:soil", "group:stone", "group:tree", "group:leaves", "group:sand", "group:wood", "group:webbing"}, + connect_sides = { "top", "bottom", "front", "left", "back", "right" }, + drawtype = "nodebox", + node_box = get_node_box(0.0625), + collision_box = get_node_box(0.0625), + inventory_image = "big_webs_item.png", + wield_image = "big_webs_item.png", + paramtype = "light", + is_ground_content = false, + climbable = true, + floodable = true, + groups = {snappy = 2, choppy = 2, webbing = 1, flammable=1, fall_damage_add_percent=-100, bouncy=20}, + sounds = sound, + on_construct = function(pos) + minetest.get_node_timer(pos):start(1) + end, + on_timer = function(pos, elapsed) + minetest.set_node(pos, {name="air"}) + generate_web(pos) + end, +}) \ No newline at end of file diff --git a/big_webs/locale/template.txt b/big_webs/locale/template.txt new file mode 100644 index 0000000..22bfe9d --- /dev/null +++ b/big_webs/locale/template.txt @@ -0,0 +1,12 @@ +# textdomain: big_webs + + +### init.lua ### + +Giant Cave Spider Web Generator= +Giant Cave Spider Webbing= + +Thick ropes of sticky, springy silk, strung between cavern walls in hopes of catching bats and even larger beasts.= + +Webbing can be collected and re-strung elsewhere to aid in climbing. It absorbs all falling damage when you land on it.= + diff --git a/big_webs/mod.conf b/big_webs/mod.conf new file mode 100644 index 0000000..bd7de62 --- /dev/null +++ b/big_webs/mod.conf @@ -0,0 +1,2 @@ +name=big_webs +optional_depends=default \ No newline at end of file diff --git a/big_webs/textures/big_webs.png b/big_webs/textures/big_webs.png new file mode 100644 index 0000000000000000000000000000000000000000..5e82942d25c33b5d4800f058e9e0622a3b54ef30 GIT binary patch literal 309 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}LV!<*E08{Q>eT=L|KTK%asU4P zJ9q9tL@r*uc;UhYpn`ATz5&S>FJ3%;{1`~yx^)Yv;P&m?K*8_dzrTF>5~%XsyLXo_ zUw-i5!G{kYo;-O1R941sd82s7YG)msHugVQbTjA|IgTe~DWM4fi)@@G literal 0 HcmV?d00001 diff --git a/big_webs/textures/big_webs_item.png b/big_webs/textures/big_webs_item.png new file mode 100644 index 0000000000000000000000000000000000000000..8dc021d971320923fd5a28e581d3c39e37dbf79c GIT binary patch literal 380 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}et=JiE0F&G|NoOGPk`iu2M>UZ zuV25ud-o2=28v(;h?+-_9s!lXbphExm2mA4y+BzY1E>-x1u+)L6_P1A475_QB*-tA zK}RPN1PTkwCNJ84;V}rjc=7rz5WN5X=g*(NrfjuKfr@8)x;TbZ#JQfn9pq#v;Bv9I z_(PxVVucFMTb}>^OS{%utp1f5Zu)OWYU$UmzdPFAu-*O~9h9^Abte0d>^Z@vyPFR) zetBl_;Su}drplbPleD6e)p|NQbtFFMz0hHv-y)>4PCZfhe?9x@AF>{i28uHO?%bZ| zuIPB<&9~EMmDr~i maxy then + return 0 + end + if y <= maxfalloff and y >= minfalloff then + return 1 + end + if y < minfalloff then + return (y-miny)/falloff + end +-- if y > maxfalloff then + return (maxy-y)/falloff +-- end +end + +local c_air = minetest.get_content_id("air") +local c_web + +local big_webs_path = minetest.get_modpath("big_webs") +if big_webs_path then + c_web = minetest.get_content_id("big_webs:webbing") +end + +local z_displace = 10000 + + +local calculate_web_array = function(minp, maxp) + local seed = math.random()*10000000 + math.randomseed(minp.y + z_displace*minp.z) -- use consistent seeds across the x axis + local webs = {} + for count = 1, math.random(5,20) do + local width = math.random(5, 25) + local direction_vertical = math.random() > 0.5 + local web_y = math.random(minp.y+8, maxp.y-8) + local web_z = math.random(minp.z+8, maxp.z-8) + for i = -math.floor(width/2), math.ceil(width/2) do + if direction_vertical then + webs[(web_y+i) + web_z*z_displace] = true + else + webs[web_y + (web_z+i)*z_displace] = true + end + end + end + math.randomseed(seed) + return webs +end + +minetest.register_on_generated(function(minp, maxp, seed) + if minp.y >= maxy or maxp.y <= miny then + return + end + + -- check if webs are present + local webs + local webs_present = false + if big_webs_path then + local seed = math.random()*10000000 + math.randomseed(minp.y + z_displace*minp.z) -- use consistent seeds across the x axis + if math.random() < web_probability then + webs_present = true + end + math.randomseed(seed) + end + + local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") + vm:get_data(data) + + nobj_chasm = nobj_chasm or minetest.get_perlin_map(np_chasms, {x = emax.x - emin.x + 1 + waver_strength*2, y = emax.y - emin.y + 1, z = emax.z - emin.z + 1}) + nobj_chasm:get_3d_map_flat(vector.subtract(emin, waver_vector), chasm_data) + + nobj_waver = nobj_waver or minetest.get_perlin_map(np_waver, {x = emax.x - emin.x + 1, y = emax.y - emin.y + 1, z = emax.z - emin.z + 1}) + nobj_waver:get_3d_map_flat(emin, waver_data) + + local chasm_area = VoxelArea:new{MinEdge = vector.subtract(emin, waver_vector), MaxEdge = vector.add(emax, waver_vector)} + local data_area = VoxelArea:new{MinEdge = emin, MaxEdge = emax} + + for i, x, y, z in data_area:iterp_xyz(emin, emax) do + local waver = math.min(math.max(math.floor(waver_data[i]+0.5), -waver_strength), waver_strength) + local intensity = get_intensity(y) + if chasm_data[chasm_area:index(x+waver, y, z)]*intensity > chasms_threshold then + if webs_present then + webs = webs or calculate_web_array(minp, maxp) -- only calculate webs when we know we're in a chasm + if webs[y + z*z_displace] and math.random() < 0.85 then -- random holes in the web + data[i] = c_web + minetest.get_node_timer({x=x,y=y,z=z}):start(1) -- this timer will check for unsupported webs + else + data[i] = c_air + end + else + data[i] = c_air + end + end + end + + vm:set_data(data) + vm:calc_lighting() + vm:write_to_map() +end) + +local nobj_local_chasm = minetest.get_perlin(np_chasms) +local nobj_local_waver = minetest.get_perlin(np_waver) + +chasms.is_in_chasm = function(pos) + nobj_local_chasm = nobj_local_chasm or minetest.get_perlin(np_chasms) + nobj_local_waver = nobj_local_waver or minetest.get_perlin(np_waver) + local waver = math.min(math.max(math.floor(nobj_local_waver:get_3d(pos)+0.5), -waver_strength), waver_strength) + local chasm_value = nobj_local_chasm:get_3d({x=pos.x+waver, y=pos.y, z=pos.z}) + return chasm_value*get_intensity(pos.y) > chasms_threshold +end + +-- A little cheaper to run, for mapgens that know they don't have to worry about the tops and bottoms of chasms +chasms.is_in_chasm_without_taper = function(pos) + nobj_local_chasm = nobj_local_chasm or minetest.get_perlin(np_chasms) + nobj_local_waver = nobj_local_waver or minetest.get_perlin(np_waver) + local waver = math.min(math.max(math.floor(nobj_local_waver:get_3d(pos)+0.5), -waver_strength), waver_strength) + local chasm_value = nobj_local_chasm:get_3d({x=pos.x+waver, y=pos.y, z=pos.z}) + return chasm_value > chasms_threshold +end \ No newline at end of file diff --git a/chasms/mod.conf b/chasms/mod.conf new file mode 100644 index 0000000..f0464dc --- /dev/null +++ b/chasms/mod.conf @@ -0,0 +1,3 @@ +name=chasms +depends=mapgen_helper +optional_depends=big_webs \ No newline at end of file diff --git a/chasms/settingtypes.txt b/chasms/settingtypes.txt new file mode 100644 index 0000000..f3995a8 --- /dev/null +++ b/chasms/settingtypes.txt @@ -0,0 +1,5 @@ +chasms_params (Noise params for chasms) noise_params_3d 0, 1, (50, 1000, 3000), 94586, 2, 0.63, 2.0 +chasms_threshold (Noise threshold for chasms) float 0.9 +chasms_maxy (Maximum Y) int -50 +chasms_miny (Minimum Y) int -2500 +chasms_falloff (Taper range when approaching max or min) int 100 \ No newline at end of file diff --git a/df_caverns/level1.lua b/df_caverns/level1.lua index 801501c..774079f 100644 --- a/df_caverns/level1.lua +++ b/df_caverns/level1.lua @@ -10,6 +10,8 @@ local c_spindlestem_white = df_caverns.node_id.spindlestem_white local tower_cap_shrublist local fungiwood_shrublist +local chasms_path = minetest.get_modpath("chasms") + if minetest.get_modpath("df_farming") then tower_cap_shrublist = { df_farming.spawn_plump_helmet_vm, @@ -273,6 +275,18 @@ local decorate_level_1 = function(minp, maxp, seed, vm, node_arrays, area, data) if dry and data[vi] == c_wet_flowstone then data[vi] = c_dry_flowstone end + + if chasms_path then + local pos = area:position(vi) + if chasms.is_in_chasm_without_taper(pos) then + local flooded_caverns = nvals_cave[vi] < 0 -- this indicates if we're in the "flooded" set of caves or not. + if flooded_caverns and pos.y < subsea_level then + data[vi] = c_water + else + data[vi] = c_air + end + end + end end vm:set_param2_data(data_param2) diff --git a/df_caverns/level2.lua b/df_caverns/level2.lua index c503e72..732a214 100644 --- a/df_caverns/level2.lua +++ b/df_caverns/level2.lua @@ -14,6 +14,9 @@ local c_dry_flowstone = df_caverns.node_id.dry_flowstone local c_veinstone = df_caverns.node_id.veinstone local c_pearls = df_caverns.node_id.pearls +local chasms_path = minetest.get_modpath("chasms") + + local wall_vein_perlin_params = { offset = 0, scale = 1, @@ -354,6 +357,19 @@ local decorate_level_2 = function(minp, maxp, seed, vm, node_arrays, area, data) if dry and data[vi] == c_wet_flowstone then data[vi] = c_dry_flowstone end + + if chasms_path then + local pos = area:position(vi) + if chasms.is_in_chasm_without_taper(pos) then + local flooded_caverns = nvals_cave[vi] < 0 -- this indicates if we're in the "flooded" set of caves or not. + if flooded_caverns and pos.y < subsea_level then + data[vi] = c_water + else + data[vi] = c_air + end + end + end + end vm:set_param2_data(data_param2) diff --git a/df_caverns/level3.lua b/df_caverns/level3.lua index 5997a21..f7766e0 100644 --- a/df_caverns/level3.lua +++ b/df_caverns/level3.lua @@ -17,6 +17,9 @@ local c_glow_ore = df_caverns.node_id.glow_ore local c_salty_cobble = df_caverns.node_id.salty_cobble local c_salt_crystal = df_caverns.node_id.salt_crystal local c_sprite = df_caverns.node_id.sprite +local c_webs_egg = df_caverns.node_id.big_webs_egg + +local chasms_path = minetest.get_modpath("chasms") local subsea_level = math.floor(df_caverns.config.level3_min - (df_caverns.config.level3_min - df_caverns.config.level2_min) * 0.33) local flooding_threshold = math.min(df_caverns.config.tunnel_flooding_threshold, df_caverns.config.cavern_threshold) @@ -355,6 +358,7 @@ local decorate_level_3 = function(minp, maxp, seed, vm, node_arrays, area, data) local index2d = mapgen_helper.index2di(minp, maxp, area, vi) local biome_name = get_biome(heatmap[index2d], humiditymap[index2d]) local flooded_caverns = nvals_cave[vi] < 0 -- this indicates if we're in the "flooded" set of caves or not. + local ystride = area.ystride if not (flooded_caverns and minp.y < subsea_level and area:get_y(vi) < subsea_level) then if flooded_caverns or biome_name == "blackcap" then @@ -363,9 +367,15 @@ local decorate_level_3 = function(minp, maxp, seed, vm, node_arrays, area, data) else df_caverns.tunnel_ceiling(minp, maxp, area, vi, nvals_cracks, data, data_param2, false) end + if c_webs_egg and (biome_name == "barren" or biome_name == "blackcap") and nvals_cracks[index2d] > 0.5 and math.random() < 0.1 then + local index = vi-ystride + if data[index] == c_air then + data[index] = c_webs_egg + minetest.get_node_timer(area:position(index)):start(1) + end + end else -- air pockets - local ystride = area.ystride local cracks = nvals_cracks[index2d] if cracks > 0.5 and data[vi-ystride] == c_water then data[vi-ystride] = c_air @@ -459,7 +469,7 @@ local decorate_level_3 = function(minp, maxp, seed, vm, node_arrays, area, data) end ---------------------------------------------- - -- Column material override for dry biome + -- Column material override for dry and icy biomes for _, vi in ipairs(node_arrays.column_nodes) do local index2d = mapgen_helper.index2di(minp, maxp, area, vi) local biome_name = get_biome(heatmap[index2d], humiditymap[index2d]) @@ -476,7 +486,7 @@ local decorate_level_3 = function(minp, maxp, seed, vm, node_arrays, area, data) -- with the full blown generated array rigamarole. hoar_moss_generator = hoar_moss_generator or minetest.get_perlin(hoar_moss_perlin_params) local pos = area:position(vi) - if hoar_moss_generator.get_3d and hoar_moss_generator:get_3d({x=pos.z, y=pos.y, z=pos.x}) > 0.5 then -- TODO: version 0.4.16 gets no hoar moss + if hoar_moss_generator:get_3d({x=pos.z, y=pos.y, z=pos.x}) > 0.5 then data[vi] = c_hoar_moss else data[vi] = c_ice @@ -491,6 +501,19 @@ local decorate_level_3 = function(minp, maxp, seed, vm, node_arrays, area, data) elseif biome_name == "barren" and not flooded_caverns and data[vi] == c_wet_flowstone then data[vi] = c_dry_flowstone end + + if chasms_path then + local pos = area:position(vi) + if chasms.is_in_chasm_without_taper(pos) then + if flooded_caverns and pos.y < subsea_level then + data[vi] = c_water -- this puts a crack in the ice of icy biomes, but why not? A crack in the ice is interesting. + else + data[vi] = c_air + end + end + end + + end vm:set_param2_data(data_param2) diff --git a/df_caverns/mod.conf b/df_caverns/mod.conf index 6ff8691..0c3b855 100644 --- a/df_caverns/mod.conf +++ b/df_caverns/mod.conf @@ -1,4 +1,4 @@ name = df_caverns description = Adds vast underground caverns in the style of Dwarf Fortress, complete with underground flora in diverse biomes. Also adds stalactite/stalagmite decorations in the smaller tunnels. depends = default, subterrane, df_trees, df_mapitems -optional_depends = df_farming, ice_sprites, oil, df_underworld_items, magma_conduits, bones_loot, named_waypoints, name_generator, fireflies \ No newline at end of file +optional_depends = df_farming, ice_sprites, oil, df_underworld_items, magma_conduits, bones_loot, named_waypoints, name_generator, fireflies, chasms, big_webs \ No newline at end of file diff --git a/df_caverns/node_ids.lua b/df_caverns/node_ids.lua index 1cd8de6..f71d708 100644 --- a/df_caverns/node_ids.lua +++ b/df_caverns/node_ids.lua @@ -14,6 +14,11 @@ if minetest.get_modpath("df_farming") then df_caverns.node_id.dead_fungus = minetest.get_content_id("df_farming:dead_fungus") end +if minetest.get_modpath("big_webs") then + df_caverns.node_id.big_webs = minetest.get_content_id("big_webs:webbing") + df_caverns.node_id.big_webs_egg = minetest.get_content_id("big_webs:web_egg") +end + df_caverns.node_id.air = minetest.get_content_id("air") df_caverns.node_id.cobble = minetest.get_content_id("default:cobble") diff --git a/df_caverns/screenshots/chasm.jpg b/df_caverns/screenshots/chasm.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c349f935c9a3d7b1b4fdadf32623e27b49dadc74 GIT binary patch literal 55019 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 z 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 -30 then wet = false @@ -135,7 +146,7 @@ df_caverns.tunnel_floor = function(minp, maxp, area, vi, nvals_cracks, data, dat local abs_cracks = math.abs(cracks) if wet then - if abs_cracks < 0.05 and data[vi+ystride] == c_air and not content_in_list(data[vi], df_mapitems.wet_stalagmite_ids) then -- make sure data[vi] is not already flowstone. Stalagmites from lower levels are acting as base for further stalagmites + if abs_cracks < 0.05 and data[vi+ystride] == c_air and not dont_build_speleothems_on[data[vi]] then -- make sure data[vi] is not already flowstone. Stalagmites from lower levels are acting as base for further stalagmites local param2 = abs_cracks*1000000 - math.floor(abs_cracks*1000000/4)*4 local height = math.floor(abs_cracks * 100) subterrane.stalagmite(vi+ystride, area, data, data_param2, param2, height, df_mapitems.wet_stalagmite_ids) @@ -144,7 +155,7 @@ df_caverns.tunnel_floor = function(minp, maxp, area, vi, nvals_cracks, data, dat data[vi] = dirt_node end else - if abs_cracks < 0.025 and data[vi+ystride] == c_air and not content_in_list(data[vi], df_mapitems.dry_stalagmite_ids) then -- make sure data[vi] is not already flowstone. Stalagmites from lower levels are acting as base for further stalagmites + if abs_cracks < 0.025 and data[vi+ystride] == c_air and not dont_build_speleothems_on[data[vi]] then -- make sure data[vi] is not already flowstone. Stalagmites from lower levels are acting as base for further stalagmites local param2 = abs_cracks*1000000 - math.floor(abs_cracks*1000000/4)*4 local height = math.floor(abs_cracks * 100) subterrane.stalagmite(vi+ystride, area, data, data_param2, param2, height, df_mapitems.dry_stalagmite_ids) @@ -165,14 +176,14 @@ df_caverns.tunnel_ceiling = function(minp, maxp, area, vi, nvals_cracks, data, d local abs_cracks = math.abs(cracks) if wet then - if abs_cracks < 0.05 and data[vi-ystride] == c_air and not content_in_list(data[vi], df_mapitems.wet_stalagmite_ids) then -- make sure data[vi] is not already flowstone. Stalagmites from lower levels are acting as base for further stalagmites + if abs_cracks < 0.05 and data[vi-ystride] == c_air and not dont_build_speleothems_on[data[vi]] then -- make sure data[vi] is not already flowstone. Stalagmites from lower levels are acting as base for further stalagmites local param2 = abs_cracks*1000000 - math.floor(abs_cracks*1000000/4)*4 local height = math.floor(abs_cracks * 100) subterrane.stalactite(vi-ystride, area, data, data_param2, param2, height, df_mapitems.wet_stalagmite_ids) data[vi] = c_wet_flowstone end else - if abs_cracks < 0.025 and data[vi-ystride] == c_air and not content_in_list(data[vi], df_mapitems.dry_stalagmite_ids) then -- make sure data[vi] is not already flowstone. Stalagmites from lower levels are acting as base for further stalagmites + if abs_cracks < 0.025 and data[vi-ystride] == c_air and not dont_build_speleothems_on[data[vi]] then -- make sure data[vi] is not already flowstone. Stalagmites from lower levels are acting as base for further stalagmites local param2 = abs_cracks*1000000 - math.floor(abs_cracks*1000000/4)*4 local height = math.floor(abs_cracks * 100) subterrane.stalactite(vi-ystride, area, data, data_param2, param2, height, df_mapitems.dry_stalagmite_ids) diff --git a/df_caverns/sunless_sea.lua b/df_caverns/sunless_sea.lua index 8a8e0b6..4625ccc 100644 --- a/df_caverns/sunless_sea.lua +++ b/df_caverns/sunless_sea.lua @@ -9,6 +9,8 @@ local c_dry_flowstone = df_caverns.node_id.dry_flowstone local c_lava = df_caverns.node_id.lava local c_obsidian = df_caverns.node_id.obsidian +local chasms_path = minetest.get_modpath("chasms") + local c_coral_table = {} for node_name, node_def in pairs(minetest.registered_nodes) do if minetest.get_item_group(node_name, "dfcaverns_cave_coral") > 0 then @@ -383,6 +385,17 @@ local decorate_sunless_sea = function(minp, maxp, seed, vm, node_arrays, area, d data_param2[vi] = math.random(1,4)-1 minetest.get_node_timer(area:position(vi)):start(math.random(10, 60)) end + + if chasms_path then + local pos = area:position(vi) + if chasms.is_in_chasm(pos) then + if pos.y <= sea_level then + data[vi] = c_water + else + data[vi] = c_air + end + end + end end end diff --git a/df_mapitems/veinstone.lua b/df_mapitems/veinstone.lua index db95d4c..291dd0e 100644 --- a/df_mapitems/veinstone.lua +++ b/df_mapitems/veinstone.lua @@ -9,6 +9,58 @@ minetest.register_node("df_mapitems:veinstone", { _magma_conduits_heats_to = df_mapitems.node_name.cobble, is_ground_content = false, light_source = 2, - drop = df_mapitems.node_name.cobble, + drop = "df_mapitems:veinstone", sounds = df_mapitems.sounds.stone, + on_punch = function(pos, node, puncher, pointed_thing) + minetest.node_punch(pos, node, puncher, pointed_thing) + minetest.swap_node(pos, {name="df_mapitems:veinstone_pulse"}) + minetest.get_node_timer(pos):start(2) + end, +}) + +minetest.register_node("df_mapitems:veinstone_pulse", { + description = S("Veinstone"), + _doc_items_longdesc = df_mapitems.doc.veinstone_desc, + _doc_items_usagehelp = df_mapitems.doc.veinstone_usage, + tiles = {df_mapitems.texture.stone .. "^dfcaverns_veins.png"}, + groups = {cracky = 3, stone = 1, lava_heatable = 1, not_in_creative_inventory = 1}, + _magma_conduits_heats_to = df_mapitems.node_name.cobble, + is_ground_content = false, + light_source = 8, + drop = "df_mapitems:veinstone", + sounds = df_mapitems.sounds.stone, + on_timer = function(pos, elapsed) + local positions, count = minetest.find_nodes_in_area(vector.add(pos,1), vector.subtract(pos,1), "df_mapitems:veinstone") + if count["df_mapitems:veinstone"] == 0 then + positions, count = minetest.find_nodes_in_area(vector.add(pos,2), vector.subtract(pos,2), "df_mapitems:veinstone") + end + if count["df_mapitems:veinstone"] == 0 then + positions = {[1] = minetest.find_node_near(pos, 3, "df_mapitems:veinstone")} + end + if positions[1] == nil then + positions = {[1] = minetest.find_node_near(pos, 4, "df_mapitems:veinstone")} + end + for _, neighbor_pos in pairs(positions) do + minetest.swap_node(neighbor_pos, {name="df_mapitems:veinstone_pulse"}) + minetest.get_node_timer(neighbor_pos):start(2) + end + minetest.swap_node(pos, {name="df_mapitems:veinstone_refractory"}) + minetest.get_node_timer(pos):start(12) + end, +}) + +minetest.register_node("df_mapitems:veinstone_refractory", { + description = S("Veinstone"), + _doc_items_longdesc = df_mapitems.doc.veinstone_desc, + _doc_items_usagehelp = df_mapitems.doc.veinstone_usage, + tiles = {df_mapitems.texture.stone .. "^dfcaverns_veins.png"}, + groups = {cracky = 3, stone = 1, lava_heatable = 1, not_in_creative_inventory = 1}, + _magma_conduits_heats_to = df_mapitems.node_name.cobble, + is_ground_content = false, + light_source = 1, + drop = "df_mapitems:veinstone", + sounds = df_mapitems.sounds.stone, + on_timer = function(pos, elapsed) + minetest.swap_node(pos, {name="df_mapitems:veinstone"}) + end, }) \ No newline at end of file diff --git a/guide.md b/guide.md index 6eda6dc..4cb6df4 100644 --- a/guide.md +++ b/guide.md @@ -160,6 +160,14 @@ Quarry bushes can be found here. On the third cavern layer the dry barren caverns will sprout clusters of enormous hexagonal red crystals from their floors and ceilings, providing light. These crystals have no particular use but are rare and beautiful to look at. +# Chasms + +![A chasm](./df_caverns/screenshots/chasm.jpg) + +Not all vast open spaces underground are the result of aeons of erosion by water or magma. The foundations of the world shift from time to time, causing deep faults to split open in the rock. Yawning chasms can be found oriented along the north-south axis, some of them stretching for kilometers both in length and depth. They cross through multiple cavern layers and are an environment in their own right. Chasms can be a convenient way of traveling long distances and also a convenient way of falling to your death. + +The great extent of chasms makes them hospitable to small flying creatures, and their narrowness makes the hospitable to creatures that feed on them - giant cave spider webs can be found strung across them here and there. A dubious salvation for anyone falling from above. + # Sunless Sea ![Sunless river](./df_caverns/screenshots/sunless_river.jpg) @@ -174,7 +182,7 @@ The distinguishing feature of the Sunless Sea is the vast expanse of water to be Below the surface of the water Snareweed can be found, a dangerous kelp-like growth that uses bioluminescence and reflective patches to lure cave fish close enough to snag with their barbs. Swimming through Snareweed is a painful experience. Deeper down are craggy towers of softly glowing Cave Coral. -This is the last stop for the living world, however. Caverns continue to stretch below but nothing grows down there. +This is the last stop for the living world. Caverns continue to stretch below but nothing grows below. # Lakes of Oil @@ -200,9 +208,9 @@ The Magma Sea is not without its treasures, however. In the most infernal region ![There are older and fouler things than orcs in the deep places of the world](./df_caverns/screenshots/underworld.jpg) -The foundations of the world lie at -3100 meters, under a default configuration. The diggable rock of the world ends at a rippling layer of invulnerable Slade, a material of unparalleled density. There is a cavern layer at the seam between rock and Slade, however, as if the earth itself was reluctant to touch the strange matter below. The crevices of the ceiling have strange glowing rocks in them, producing a surprisingly bright ambiance. Don't attempt to disturb those rocks. +The foundations of the world lie at -3100 meters. The diggable rock of the world ends at a rippling layer of invulnerable Slade, a material of unparalleled density. There is a cavern layer at the seam between rock and Slade, however, as if the earth itself was reluctant to touch the strange matter below. The crevices of the ceiling have strange glowing rocks in them, producing a surprisingly bright ambiance. Don't attempt to disturb those rocks. -There is no native life in the Underworld. It appears there once _was_, however. Occasional clusters of vacant buildings can be found, impossibly crafted from bricks of Slade and empty of any furnishings. Around those clusters of vacant buildings are fields filled with sealed pits lined with flawless Slade blocks. It is unclear whether these pits are as vacant as the buildings, though. The seals capping them are engraved with ancient words in lost tongues, but one phrase can be translated from the oldest known languages: "This Place is Not a Place of Honor." +There is no native life in the Underworld. It appears there once _was_, however. Occasional clusters of vacant buildings can be found, impossibly crafted from bricks of Slade and empty of any furnishings. Around those clusters of vacant buildings are fields filled with sealed pits that are lined with flawless Slade blocks. It is unclear whether these pits are as vacant as the buildings, though. The seals capping them are engraved with ancient words in lost tongues, but one phrase can be translated from the oldest known languages: "This Place is Not a Place of Honor." Just as ominously, the ancient bones of long-dead warriors are scattered amidst the buildings. They contain loot for those willing to risk disturbing them. There are no traces of who - or what - they died fighting, but their ancient sentinels still lurk nearby to guard them. diff --git a/hunter_statue/init.lua b/hunter_statue/init.lua index d3642bd..92f733a 100644 --- a/hunter_statue/init.lua +++ b/hunter_statue/init.lua @@ -114,7 +114,7 @@ hunter_statue.register_hunter_statue = function(node_name, statue_def) if fleshy_armour then armour_multiplier = fleshy_armour/100 end - nearest_player:add_player_velocity(vector.multiply(vector.direction(pos, nearest_pos), knockback)) + nearest_player:add_velocity(vector.multiply(vector.direction(pos, nearest_pos), knockback)) nearest_player:set_hp(math.max(nearest_player:get_hp() - damage*armour_multiplier, 0)) minetest.sound_play({name="hunter_statue_thud"}, {pos = nearest_pos}) return diff --git a/subterrane b/subterrane index 6439ca5..6cc2fe8 160000 --- a/subterrane +++ b/subterrane @@ -1 +1 @@ -Subproject commit 6439ca59bfe8e3e4c5ed0826f41d2c49b862fb75 +Subproject commit 6cc2fe8faea4026101dc9f462a7594edfc26ca7f