diff --git a/df_caverns/level2.lua b/df_caverns/level2.lua index 731fd57..6ae6497 100644 --- a/df_caverns/level2.lua +++ b/df_caverns/level2.lua @@ -18,6 +18,8 @@ local wall_vein_perlin_params = { flags = "eased", } +local c_pearls = minetest.get_content_id("df_mapitems:cave_pearls") + local subsea_level = df_caverns.config.level2_min - (df_caverns.config.level2_min - df_caverns.config.level1_min) * 0.33 -- "sea level" for the flooded caverns. local flooding_threshold = math.min(df_caverns.config.tunnel_flooding_threshold, df_caverns.config.cavern_threshold) -- cavern value out to which we're flooding tunnels and warrens @@ -259,7 +261,10 @@ local decorate_level_2 = function(minp, maxp, seed, vm, node_arrays, area, data) if not flooded_caverns and (biome_name == "barren" or biome_name == "sporetree") and nvals_cracks[index2d] > 0.5 then for i= 1, 4 do if math.random() > 0.5 then - df_mapitems.place_wall_pearls(vi-i*ystride, area, data, data_param2) + local index = vi-i*ystride + if data[index] == c_air then + df_mapitems.place_against_surface_vm(c_pearls, index, area, data, data_param2) + end end end end @@ -314,7 +319,10 @@ local decorate_level_2 = function(minp, maxp, seed, vm, node_arrays, area, data) if not flooded_caverns and (biome_name == "barren" or biome_name == "sporetree") and nvals_cracks[index2d] > 0.5 then for i= 1, 4 do if math.random() > 0.5 then - df_mapitems.place_wall_pearls(vi-i*ystride, area, data, data_param2) + local index = vi-i*ystride + if data[index] == c_air then + df_mapitems.place_against_surface_vm(c_pearls, index, area, data, data_param2) + end end end end diff --git a/df_caverns/level3.lua b/df_caverns/level3.lua index 02a7074..e402d3b 100644 --- a/df_caverns/level3.lua +++ b/df_caverns/level3.lua @@ -20,6 +20,9 @@ local c_dry_flowstone = minetest.get_content_id("df_mapitems:dry_flowstone") local c_glow_ore = minetest.get_content_id("df_mapitems:glow_ruby_ore") +local c_salty_cobble = minetest.get_content_id("df_mapitems:salty_cobble") +local c_salt_crystal = minetest.get_content_id("df_mapitems:salt_crystal") + local c_sprite if minetest.get_modpath("ice_sprites") then c_sprite = minetest.get_content_id("ice_sprites:ice_sprite") @@ -157,20 +160,28 @@ local nether_cap_cavern_ceiling = function(abs_cracks, vert_rand, vi, area, data end local blood_thorn_cavern_floor = function(abs_cracks, vert_rand, vi, area, data, data_param2) + local ai = vi+area.ystride + if abs_cracks < 0.075 then if vert_rand < 0.004 then - subterrane.big_stalagmite(vi+area.ystride, area, data, 6, 15, c_dry_flowstone, c_dry_flowstone, c_dry_flowstone) + subterrane.big_stalagmite(ai, area, data, 6, 15, c_dry_flowstone, c_dry_flowstone, c_dry_flowstone) + elseif data[vi] ~= air and math.random() < 0.5 then + data[vi] = c_salty_cobble + if data[ai] == c_air and math.random() < 0.25 then + data[ai] = c_salt_crystal + data_param2[ai] = math.random(1,4)-1 + end else local param2 = abs_cracks*1000000 - math.floor(abs_cracks*1000000/4)*4 local height = math.floor(abs_cracks * 66) - subterrane.stalagmite(vi+area.ystride, area, data, data_param2, param2, height, df_mapitems.dry_stalagmite_ids) + subterrane.stalagmite(ai, area, data, data_param2, param2, height, df_mapitems.dry_stalagmite_ids) end elseif math.random() > abs_cracks + 0.66 then - df_trees.spawn_blood_thorn_vm(vi+area.ystride, area, data, data_param2) + df_trees.spawn_blood_thorn_vm(ai, area, data, data_param2) data[vi] = c_desert_sand else if math.random() < 0.1 then - df_caverns.place_shrub(vi+area.ystride, area, data, data_param2, blood_thorn_shrublist) + df_caverns.place_shrub(ai, area, data, data_param2, blood_thorn_shrublist) data[vi] = c_desert_sand elseif math.random() > 0.25 then data[vi] = c_desert_sand @@ -310,7 +321,16 @@ local decorate_level_3 = function(minp, maxp, seed, vm, node_arrays, area, data) else -- bloodthorn ceiling if abs_cracks < 0.075 then - df_caverns.stalactites(abs_cracks, vert_rand, vi, area, data, data_param2, false) + if data[vi] ~= air and math.random() < 0.5 then + data[vi] = c_salty_cobble + local bi = vi - area.ystride + if data[bi] == c_air and math.random() < 0.25 then + data[bi] = c_salt_crystal + data_param2[bi] = 19 + math.random(1,4) + end + else + df_caverns.stalactites(abs_cracks, vert_rand, vi, area, data, data_param2, false) + end elseif abs_cracks > 0.75 and math.random() < 0.05 then data[vi] = c_glow_ore df_mapitems.place_big_crystal(data, data_param2, vi-area.ystride, true) diff --git a/df_mapitems/cave_pearls.lua b/df_mapitems/cave_pearls.lua index 611fb1c..2d4b4ee 100644 --- a/df_mapitems/cave_pearls.lua +++ b/df_mapitems/cave_pearls.lua @@ -2,77 +2,6 @@ local MP = minetest.get_modpath(minetest.get_current_modname()) local S, NS = dofile(MP.."/intllib.lua") -local pearl_on_place = function(itemstack, placer, pointed_thing) - local pt = pointed_thing - -- check if pointing at a node - if not pt then - return itemstack - end - if pt.type ~= "node" then - return itemstack - end - - local under_pos = pt.under - local above_pos = pt.above - - local under_node = minetest.get_node(under_pos) - local above_node = minetest.get_node(above_pos) - - if minetest.is_protected(above_pos, placer:get_player_name()) then - minetest.record_protection_violation(above_pos, placer:get_player_name()) - return - end - - local under_name = under_node.name - local above_name = above_node.name - local under_def = minetest.registered_nodes[under_name] - local above_def = minetest.registered_nodes[above_name] - - -- return if any of the nodes is not registered - if not under_def or not above_def then - return itemstack - end - -- check if you can replace the node above the pointed node - if not above_def.buildable_to then - return itemstack - end - - local dir = vector.subtract(under_pos, above_pos) - local param2 - if dir.x > 0 then - --facing +x: 16, 17, 18, 19, - param2 = 15 + math.random(1,4) - elseif dir.x < 0 then - --facing -x: 12, 13, 14, 15 - param2 = 11 + math.random(1,4) - elseif dir.z > 0 then - --facing +z: 8, 9, 10, 11 - param2 = 7 + math.random(1,4) - elseif dir.z < 0 then - --facing -z: 4, 5, 6, 7 - param2 = 3 + math.random(1,4) - elseif dir.y > 0 then - --facing -y: 20, 21, 22, 23 (ceiling) - param2 = 19 + math.random(1,4) - else - --facing +y: 0, 1, 2, 3 (floor) - param2 = math.random(1,4) - 1 - end - - -- add the node and remove 1 item from the itemstack - minetest.add_node(above_pos, {name = itemstack:get_name(), param2 = param2}) - if not minetest.setting_getbool("creative_mode") and not minetest.check_player_privs(placer, "creative") then - itemstack:take_item() - end - return itemstack -end - -local add_to_table = function(dest, source) - for _, val in ipairs(source) do - table.insert(dest, val) - end -end - minetest.register_node("df_mapitems:cave_pearls", { description = S("Cave Pearls"), tiles = {"dfcaverns_cave_pearl.png"}, @@ -93,69 +22,5 @@ minetest.register_node("df_mapitems:cave_pearls", { {-0.125, -0.5, 0.25, 0.0625, -0.375, 0.4375}, -- NodeBox3 } }, - on_place = pearl_on_place, + on_place = df_mapitems.place_against_surface, }) - -local c_air = minetest.get_content_id("air") -local c_pearls = minetest.get_content_id("df_mapitems:cave_pearls") - -local valid_nodes = {} -- cache values -local is_valid_mounting_node = function(c_node) - if valid_nodes[c_node] ~= nil then - return valid_nodes[c_node] - end - local def = minetest.registered_nodes[minetest.get_name_from_content_id(c_node)] - if def ~= nil - and (def.drawtype == "normal" or def.drawtype == nil) - and not def.buildable_to - and not (def.groups and def.groups.falling_node) then - valid_nodes[c_node] = true - return true - end - valid_nodes[c_node] = false - return false -end - ---facing +x: 16, 17, 18, 19, ---facing -x: 12, 13, 14, 15 ---facing +z: 8, 9, 10, 11 ---facing -z: 4, 5, 6, 7 ---facing -y: 20, 21, 22, 23, (ceiling) ---facing +y: 0, 1, 2, 3 - -local get_valid_facedirs_vm = function(vi, area, data) - local dirs = {} - local ystride = area.ystride - local zstride = area.zstride - if is_valid_mounting_node(data[vi+1]) then - add_to_table(dirs, {16, 17, 18, 19}) - end - if is_valid_mounting_node(data[vi-1]) then - add_to_table(dirs, {12, 13, 14, 15}) - end - if is_valid_mounting_node(data[vi-ystride]) then - add_to_table(dirs, {0, 1, 2, 3}) - end - if is_valid_mounting_node(data[vi+ystride]) then - add_to_table(dirs, {20, 21, 22, 23}) - end - if is_valid_mounting_node(data[vi+zstride]) then - add_to_table(dirs, {8, 9, 10, 11}) - end - if is_valid_mounting_node(data[vi-zstride]) then - add_to_table(dirs, {4, 5, 6, 7}) - end - return dirs -end - -df_mapitems.place_wall_pearls = function(vi, area, data, data_param2) - if data[vi] == c_air then - local facedirs = get_valid_facedirs_vm(vi, area, data) - local count = #facedirs - if count > 0 then - data[vi] = c_pearls - data_param2[vi] = facedirs[math.random(1, count)] - end - end -end - diff --git a/df_mapitems/crystals_mese.lua b/df_mapitems/crystals_mese.lua index dd2970b..b44f48e 100644 --- a/df_mapitems/crystals_mese.lua +++ b/df_mapitems/crystals_mese.lua @@ -40,6 +40,7 @@ minetest.register_node("df_mapitems:mese_crystal", { sounds = default.node_sound_glass_defaults(), use_texture_alpha = true, sunlight_propagates = true, + on_place = df_mapitems.place_against_surface, }) minetest.register_craft({ diff --git a/df_mapitems/crystals_salt.lua b/df_mapitems/crystals_salt.lua new file mode 100644 index 0000000..cc1fdb7 --- /dev/null +++ b/df_mapitems/crystals_salt.lua @@ -0,0 +1,33 @@ +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +minetest.register_node("df_mapitems:salt_crystal", { + description = S("Luminous Salt Crystal"), + _doc_items_longdesc = df_mapitems.doc.salt_desc, + _doc_items_usagehelp = df_mapitems.doc.salt_usage, + tiles = {"dfcaverns_salt_crystal.png"}, + groups = {cracky = 2}, + paramtype = "light", + paramtype2 = "facedir", + drawtype = "mesh", + mesh = "underch_crystal.obj", + light_source = 6, + sounds = default.node_sound_glass_defaults(), + use_texture_alpha = true, + sunlight_propagates = true, + on_place = df_mapitems.place_against_surface, +}) + +minetest.register_node("df_mapitems:salty_cobble", { + description = S("Salty Cobble"), + _doc_items_longdesc = df_mapitems.doc.salt_desc, + _doc_items_usagehelp = df_mapitems.doc.salt_desc, + tiles = {"default_cobble.png^dfcaverns_salty.png"}, + groups = {cracky = 3, stone = 1, lava_heatable = 1}, + _magma_conduits_heats_to = "default:cobble", + is_ground_content = true, + light_source = 2, + drop = 'default:cobble', + sounds = default.node_sound_stone_defaults(), +}) \ No newline at end of file diff --git a/df_mapitems/init.lua b/df_mapitems/init.lua index e4650a2..7f0040f 100644 --- a/df_mapitems/init.lua +++ b/df_mapitems/init.lua @@ -7,6 +7,7 @@ local modpath = minetest.get_modpath(minetest.get_current_modname()) dofile(modpath.."/config.lua") dofile(modpath.."/doc.lua") dofile(modpath.."/aliases.lua") +dofile(modpath.."/util.lua") dofile(modpath.."/ground_cover.lua") dofile(modpath.."/glow_worms.lua") @@ -16,6 +17,7 @@ dofile(modpath.."/cave_coral.lua") dofile(modpath.."/crystals_mese.lua") dofile(modpath.."/crystals_ruby.lua") +dofile(modpath.."/crystals_salt.lua") dofile(modpath.."/veinstone.lua") dofile(modpath.."/cave_pearls.lua") diff --git a/df_mapitems/textures/dfcaverns_salt_crystal.png b/df_mapitems/textures/dfcaverns_salt_crystal.png new file mode 100644 index 0000000..dde96fc Binary files /dev/null and b/df_mapitems/textures/dfcaverns_salt_crystal.png differ diff --git a/df_mapitems/textures/dfcaverns_salty.png b/df_mapitems/textures/dfcaverns_salty.png new file mode 100644 index 0000000..01e4e2a Binary files /dev/null and b/df_mapitems/textures/dfcaverns_salty.png differ diff --git a/df_mapitems/textures/license.txt b/df_mapitems/textures/license.txt index 627dd5a..b77b0e1 100644 --- a/df_mapitems/textures/license.txt +++ b/df_mapitems/textures/license.txt @@ -5,3 +5,5 @@ dfcaverns_glow_worm_animated - glow worm texture overlaid with rippling animatio dfcaverns_glow_mese - from caverealms glow_mese dfcaverns_glow_ruby, dfcaverns_glow_ruby4x, dfcaverns_glow_ruby_quarter - from caverealms glow_ruby dfcaverns_glow_ruby_ore - from caverealms glow_ruby_ore +dfcaverns_salt_crystal - from caverealms +dfcaverns_salty - from caverealms with modified alpha channel \ No newline at end of file diff --git a/df_mapitems/util.lua b/df_mapitems/util.lua new file mode 100644 index 0000000..ea876c3 --- /dev/null +++ b/df_mapitems/util.lua @@ -0,0 +1,132 @@ +-- Used by cave pearls and crystal clusters +-- These methods simulate "wallmounted" nodes using regular facedir, randomizing the rotation around the wallmounted direction. +-- Useful for naturalistic objects you want to have look irregular + +df_mapitems.place_against_surface = function(itemstack, placer, pointed_thing) + -- check if pointing at a node + if not pointed_thing then + return itemstack + end + if pointed_thing.type ~= "node" then + return itemstack + end + + local under_pos = pointed_thing.under + local above_pos = pointed_thing.above + + local under_node = minetest.get_node(under_pos) + local above_node = minetest.get_node(above_pos) + + if minetest.is_protected(above_pos, placer:get_player_name()) then + minetest.record_protection_violation(above_pos, placer:get_player_name()) + return + end + + local under_name = under_node.name + local above_name = above_node.name + local under_def = minetest.registered_nodes[under_name] + local above_def = minetest.registered_nodes[above_name] + + -- return if any of the nodes is not registered + if not under_def or not above_def then + return itemstack + end + -- check if you can replace the node above the pointed node + if not above_def.buildable_to then + return itemstack + end + + local dir = vector.subtract(under_pos, above_pos) + local param2 + if dir.x > 0 then + --facing +x: 16, 17, 18, 19, + param2 = 15 + math.random(1,4) + elseif dir.x < 0 then + --facing -x: 12, 13, 14, 15 + param2 = 11 + math.random(1,4) + elseif dir.z > 0 then + --facing +z: 8, 9, 10, 11 + param2 = 7 + math.random(1,4) + elseif dir.z < 0 then + --facing -z: 4, 5, 6, 7 + param2 = 3 + math.random(1,4) + elseif dir.y > 0 then + --facing -y: 20, 21, 22, 23 (ceiling) + param2 = 19 + math.random(1,4) + else + --facing +y: 0, 1, 2, 3 (floor) + param2 = math.random(1,4) - 1 + end + -- add the node and remove 1 item from the itemstack + minetest.add_node(above_pos, {name = itemstack:get_name(), param2 = param2}) + if not minetest.setting_getbool("creative_mode") and not minetest.check_player_privs(placer, "creative") then + itemstack:take_item() + end + return itemstack +end + +-- Mapgen version of the above + +local add_to_table = function(dest, source) + for _, val in ipairs(source) do + table.insert(dest, val) + end +end + +local valid_nodes = {} -- cache values +local is_valid_mounting_node = function(c_node) + if valid_nodes[c_node] ~= nil then + return valid_nodes[c_node] + end + local def = minetest.registered_nodes[minetest.get_name_from_content_id(c_node)] + if def ~= nil + and (def.drawtype == "normal" or def.drawtype == nil) + and not def.buildable_to + and not (def.groups and def.groups.falling_node) then + valid_nodes[c_node] = true + return true + end + valid_nodes[c_node] = false + return false +end + +--facing +x: 16, 17, 18, 19, +--facing -x: 12, 13, 14, 15 +--facing +z: 8, 9, 10, 11 +--facing -z: 4, 5, 6, 7 +--facing -y: 20, 21, 22, 23, (ceiling) +--facing +y: 0, 1, 2, 3 + +local get_valid_facedirs_vm = function(vi, area, data) + local dirs = {} + local ystride = area.ystride + local zstride = area.zstride + if is_valid_mounting_node(data[vi+1]) then + add_to_table(dirs, {16, 17, 18, 19}) + end + if is_valid_mounting_node(data[vi-1]) then + add_to_table(dirs, {12, 13, 14, 15}) + end + if is_valid_mounting_node(data[vi-ystride]) then + add_to_table(dirs, {0, 1, 2, 3}) + end + if is_valid_mounting_node(data[vi+ystride]) then + add_to_table(dirs, {20, 21, 22, 23}) + end + if is_valid_mounting_node(data[vi+zstride]) then + add_to_table(dirs, {8, 9, 10, 11}) + end + if is_valid_mounting_node(data[vi-zstride]) then + add_to_table(dirs, {4, 5, 6, 7}) + end + return dirs +end + +df_mapitems.place_against_surface_vm = function(c_node, vi, area, data, data_param2) + local facedirs = get_valid_facedirs_vm(vi, area, data) + local count = #facedirs + if count > 0 then + data[vi] = c_node + data_param2[vi] = facedirs[math.random(1, count)] + end +end \ No newline at end of file