From 61f3bd007d5d608e42eeebbc8f865a6e82089eac Mon Sep 17 00:00:00 2001 From: Duane Robertson Date: Sun, 22 May 2016 07:17:20 -0500 Subject: [PATCH] Continuing rewrite. Add plants. --- deco.lua | 7 +- deco_caves.lua | 220 ++++-------------------- deco_coral.lua | 97 ----------- deco_plants.lua | 209 ++++++++++++++++++++++ deco_water.lua | 102 +++++++++++ init.lua | 1 + mapgen.lua | 84 ++++++--- textures/fun_caves_bird_of_paradise.png | Bin 0 -> 352 bytes textures/fun_caves_gerbera.png | Bin 0 -> 683 bytes textures/fun_caves_hibiscus.png | Bin 0 -> 1152 bytes textures/fun_caves_orchid.png | Bin 0 -> 1103 bytes textures/fun_caves_water_plant_1.png | Bin 0 -> 2888 bytes 12 files changed, 408 insertions(+), 312 deletions(-) delete mode 100644 deco_coral.lua create mode 100644 deco_plants.lua create mode 100644 deco_water.lua create mode 100644 textures/fun_caves_bird_of_paradise.png create mode 100644 textures/fun_caves_gerbera.png create mode 100644 textures/fun_caves_hibiscus.png create mode 100644 textures/fun_caves_orchid.png create mode 100644 textures/fun_caves_water_plant_1.png diff --git a/deco.lua b/deco.lua index 62a7a23..dbcb2f5 100644 --- a/deco.lua +++ b/deco.lua @@ -34,12 +34,9 @@ minetest.register_craft({ minetest.add_group("default:cactus", {oddly_breakable_by_hand=1}) dofile(fun_caves.path.."/deco_caves.lua") ---dofile(fun_caves.path.."/deco_coral.lua") --dofile(fun_caves.path.."/deco_dirt.lua") ---dofile(fun_caves.path.."/deco_trees.lua") ---dofile(fun_caves.path.."/deco_plants.lua") +dofile(fun_caves.path.."/deco_plants.lua") --dofile(fun_caves.path.."/deco_rocks.lua") ---dofile(fun_caves.path.."/deco_fungal_tree.lua") --dofile(fun_caves.path.."/deco_ferns.lua") --dofile(fun_caves.path.."/deco_ferns_tree.lua") ---dofile(fun_caves.path.."/deco_water.lua") +dofile(fun_caves.path.."/deco_water.lua") diff --git a/deco_caves.lua b/deco_caves.lua index 4fc8d95..be8c57c 100644 --- a/deco_caves.lua +++ b/deco_caves.lua @@ -2,6 +2,10 @@ local node = fun_caves.node local min_surface = -80 function fun_caves.decorate_cave(data, area, minp, y, ivm, biome_val_in) + if not (data[ivm] == node("air") or data[ivm] == node("default:stone")) then + return + end + local ivm_below = ivm - area.ystride local ivm_above = ivm + area.ystride local biome_val = biome_val_in @@ -9,7 +13,6 @@ function fun_caves.decorate_cave(data, area, minp, y, ivm, biome_val_in) ------------------- local stone_type = node("default:stone") local stone_depth = 1 - local air_count = 0 if y > -500 then biome_val = biome_val / math.max(1, math.log(500 + y)) @@ -34,9 +37,6 @@ function fun_caves.decorate_cave(data, area, minp, y, ivm, biome_val_in) elseif biome_val < 0.35 then stone_type = node("fun_caves:stone_with_salt") stone_depth = 2 - if data[ivm] == node("default:stone") then - return stone_type - end elseif biome_val < 0.5 then stone_type = node("default:sand") stone_depth = 2 @@ -54,45 +54,44 @@ function fun_caves.decorate_cave(data, area, minp, y, ivm, biome_val_in) end local node_above = data[ivm + area.ystride] - local air_above = false - for i = 1, stone_depth do - if data[ivm + area.ystride * i] == node("air") then - air_above = true + if data[ivm] == node("default:stone") then + local air_above = false + for i = 1, stone_depth do + if data[ivm + area.ystride * i] == node("air") then + air_above = true + end end - end - if data[ivm] == node("default:stone") and (stone_type == node("fun_caves:stone_with_algae") or stone_type == node("fun_caves:stone_with_lichen")) and node_above == node("air") and math.random(3) == 1 then - return node("dirt") - end - - if data[ivm] == node("default:stone") and air_above then - if stone_type == node("fun_caves:stone_with_salt") and math.random(500) == 1 then - return node("fun_caves:radioactive_ore") - else - return stone_type + if node_above == node("air") and (stone_type == node("fun_caves:stone_with_algae") or stone_type == node("fun_caves:stone_with_lichen")) and math.random(4) == 1 then + return node("dirt") end - end - local air_below = false - for i = 1, stone_depth do - if data[ivm - area.ystride * i] == node("air") then - air_below = true + if air_above then + if stone_type == node("fun_caves:stone_with_salt") and math.random(500) == 1 then + return node("fun_caves:radioactive_ore") + elseif node_above == node("air") and stone_type == node("fun_caves:stone_with_moss") and math.random(50) == 1 then + return node("fun_caves:glowing_fungal_stone") + else + return stone_type + end end - end - if data[ivm] == node("default:stone") and air_below then - if stone_type == node("fun_caves:stone_with_salt") and math.random(500) == 1 then - return node("fun_caves:radioactive_ore") - else - return stone_type + local air_below = false + for i = 1, stone_depth do + if data[ivm - area.ystride * i] == node("air") then + air_below = true + end end - end - if node_below == node("air") and (data[ivm] == node("fun_caves:stone_with_lichen") or data[ivm] == node("fun_caves:stone_with_moss")) and math.random(50) == 1 then - return node("fun_caves:glowing_fungal_stone") - end - if node_above == node("air") and data[ivm] == node("fun_caves:stone_with_moss") and math.random(50) == 1 then - return node("fun_caves:glowing_fungal_stone") + if data[ivm] == node("default:stone") and air_below then + if stone_type == node("fun_caves:stone_with_salt") and math.random(500) == 1 then + return node("fun_caves:radioactive_ore") + elseif node_below == node("air") and (stone_type == node("fun_caves:stone_with_lichen") or stone_type == node("fun_caves:stone_with_moss")) and math.random(50) == 1 then + return node("fun_caves:glowing_fungal_stone") + else + return stone_type + end + end end if data[ivm] == node("air") then @@ -114,11 +113,11 @@ function fun_caves.decorate_cave(data, area, minp, y, ivm, biome_val_in) end -- fluids - --if y < min_surface and (node_below == node("default:stone") or node_below == node("fun_caves:hot_cobble")) and sr < 3 then if y > minp.y and (node_below == node("default:stone") or node_below == node("fun_caves:hot_cobble")) and sr < 3 then return node("default:lava_source") elseif node_below == node("fun_caves:stone_with_moss") and sr < 3 then return node("default:water_source") + -- standing up elseif node_below == node("default:ice") and sr < 80 then return node("fun_caves:icicle_up") @@ -138,6 +137,7 @@ function fun_caves.decorate_cave(data, area, minp, y, ivm, biome_val_in) end elseif node_below == node("default:coalblock") and sr < 20 then return node("fun_caves:constant_flame") + -- vegetation elseif node_below == node("default:dirt") and (stone_type == node("fun_caves:stone_with_lichen") or stone_type == node("fun_caves:stone_with_algae")) and biome_val >= -0.5 then if sr < 110 then @@ -147,6 +147,7 @@ function fun_caves.decorate_cave(data, area, minp, y, ivm, biome_val_in) elseif node_above == node("air") and sr < 330 then return node("fun_caves:giant_mushroom_stem") elseif sr < 360 then + local air_count = 0 for i = 1, 12 do local j = ivm + area.ystride * i if j <= #data and data[j] == node("air") then @@ -155,7 +156,6 @@ function fun_caves.decorate_cave(data, area, minp, y, ivm, biome_val_in) end if air_count > 5 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")) - --node_below = node("dirt") end end elseif node_below == node("fun_caves:giant_mushroom_stem") and data[ivm - area.ystride * 2] == node("fun_caves:giant_mushroom_stem") then @@ -167,151 +167,5 @@ function fun_caves.decorate_cave(data, area, minp, y, ivm, biome_val_in) return node("fun_caves:huge_mushroom_cap") end end - - if data[ivm] == node("air") then - air_count = air_count + 1 - end end end - ---function original_fun_caves_decorate_cave(data, area) --- local ivm_below = ivm - area.ystride --- local ivm_above = ivm + area.ystride --- local dy = y - minp.y --- --- ------------------- --- local stone_type = node("default:stone") --- local stone_depth = 1 --- local biome_val = biome_n[index3d] --- if y > -500 then --- biome_val = biome_val / math.max(1, math.log(500 + y)) --- end --- ------------------- --- --biome_val = 0.7 --- ------------------- --- if biome_val < -0.6 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.5 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.0 then --- stone_type = node("fun_caves:stone_with_lichen") --- elseif biome_val < 0.2 then --- stone_type = node("fun_caves:stone_with_algae") --- elseif biome_val < 0.35 then --- stone_type = node("fun_caves:stone_with_salt") --- stone_depth = 2 --- if data[ivm] == node("default:stone") then --- data[ivm] = stone_type --- end --- elseif biome_val < 0.5 then --- stone_type = node("default:sand") --- stone_depth = 2 --- elseif biome_val < 0.6 then --- stone_type = node("default:coalblock") --- stone_depth = 2 --- else --- stone_type = node("fun_caves:hot_cobble") --- end --- -- "glow" --- --- if data[ivm] == node("air") then --- -- Change stone per biome. --- if data[ivm_below] == node("default:stone") or (stone_type == node("fun_caves:stone_with_salt") and data[ivm_below] ~= node("fun_caves:stone_with_salt") and data[ivm_below] ~= node("air")) then --- data[ivm_below] = stone_type --- if stone_type == node("fun_caves:stone_with_salt") and math.random(500) == 1 then --- data[ivm_below - area.ystride] = node("fun_caves:radioactive_ore") --- elseif stone_depth == 2 then --- data[ivm_below - area.ystride] = stone_type --- end --- end --- if data[ivm_above] == node("default:stone") or (stone_type == node("fun_caves:stone_with_salt") and data[ivm_above] ~= node("fun_caves:stone_with_salt") and data[ivm_above] ~= node("air")) then --- data[ivm_above] = stone_type --- if stone_type == node("fun_caves:stone_with_salt") and math.random(500) == 1 then --- data[ivm_above - area.ystride] = node("fun_caves:radioactive_ore") --- elseif 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,50) == 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 (data[ivm_below] == node("default:stone") or data[ivm_below] == node("fun_caves:hot_cobble")) and sr < 3 then --- data[ivm] = node("default:lava_source") --- elseif data[ivm_below] == node("fun_caves:stone_with_moss") and sr < 3 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("fun_caves:hot_cobble") and sr < 20 then --- if sr < 10 then --- data[ivm] = node("fun_caves:hot_spike") --- else --- data[ivm] = node("fun_caves:hot_spike_"..(math.ceil(sr / 3) - 2)) --- end --- 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 --- elseif data[ivm_below] == node("fun_caves:stone_with_moss") and sr < 90 then --- data[ivm_below] = node("fun_caves:glowing_fungal_stone") --- -- 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.5 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 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 ---end diff --git a/deco_coral.lua b/deco_coral.lua deleted file mode 100644 index 7968ce3..0000000 --- a/deco_coral.lua +++ /dev/null @@ -1,97 +0,0 @@ - -minetest.register_node("fun_caves:pillar_coral", { - description = "Pillar Coral", - tiles = {"fun_caves_pillar_coral.png"}, - paramtype = "light", - light_source = 2, - groups = {cracky = 3, stone=1}, - sounds = default.node_sound_stone_defaults(), -}) - - -minetest.register_node("fun_caves:brain_coral", { - description = "Brain Coral", - tiles = {"fun_caves_brain_coral.png"}, - light_source = 4, - groups = {cracky = 3, stone=1,}, - sounds = default.node_sound_stone_defaults(), -}) - - -minetest.register_node("fun_caves:dragon_eye", { - description = "Dragon Eye", - tiles = {"fun_caves_dragon_eye.png"}, - light_source = 4, - groups = {cracky = 3, stone=1,}, - sounds = default.node_sound_stone_defaults(), -}) - - -minetest.register_node("fun_caves:staghorn_coral", { - description = "Staghorn Coral", - drawtype = "plantlike", - tiles = {"fun_caves_staghorn_coral.png"}, - waving = false, - sunlight_propagates = true, - paramtype = "light", - light_source = 2, - walkable = false, - groups = {cracky = 3, stone=1, attached_node=1, sea=1}, - sounds = default.node_sound_stone_defaults(), - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}, - }, -}) - -function fun_caves.sea_plants() - if y >= light_depth and (data[index_3d] == node["sand"] or data[index_3d] == node["dirt"]) and (data[index_3d_above] == node["water_source"] or data[index_3d_above] == node["river_water_source"]) then - -- Check the biomes and plant water plants, if called for. - biome = valc.biome_ids[biomemap[index_2d]] - if y < water_level and data[index_3d_above + ystride] == node["water_source"] and table.contains(coral_biomes, biome) and n21[index_2d] < -0.1 and math_random(1,3) ~= 1 then - sr = math_random(1,100) - if sr < 4 then - data[index_3d_above] = node["brain_coral"] - elseif sr < 6 then - data[index_3d_above] = node["dragon_eye"] - elseif sr < 35 then - data[index_3d_above] = node["staghorn_coral"] - elseif sr < 100 then - data[index_3d_above] = node["pillar_coral"] - end - elseif surround then - for _, desc in pairs(valc.water_plants) do - placeable = false - - if not node_match_cache[desc] then - node_match_cache[desc] = {} - end - - if node_match_cache[desc][data[index_3d]] then - placeable = node_match_cache[desc][data[index_3d]] - else - -- This is a great way to match all node type strings - -- against a given node (or nodes). However, it's slow. - -- To speed it up, we cache the results for each plant - -- on each node, and avoid calling find_nodes every time. - pos, count = minetest.find_nodes_in_area({x=x,y=y,z=z}, {x=x,y=y,z=z}, desc.place_on) - if #pos > 0 then - placeable = true - end - node_match_cache[desc][data[index_3d]] = placeable - end - - if placeable and desc.fill_ratio and desc.content_id then - biome = valc.biome_ids[biomemap[index_2d]] - - if not desc.biomes or (biome and desc.biomes and table.contains(desc.biomes, biome)) then - if math_random() <= desc.fill_ratio then - data[index_3d] = desc.content_id - write = true - end - end - end - end - end - end -end diff --git a/deco_plants.lua b/deco_plants.lua new file mode 100644 index 0000000..e01270d --- /dev/null +++ b/deco_plants.lua @@ -0,0 +1,209 @@ +fun_caves.water_plants = {} +function fun_caves.register_water_plant(desc) + fun_caves.water_plants[#fun_caves.water_plants+1] = desc +end + + +minetest.register_node("fun_caves:pillar_coral", { + description = "Pillar Coral", + tiles = {"fun_caves_pillar_coral.png"}, + paramtype = "light", + light_source = 2, + groups = {cracky = 3, stone=1}, + sounds = default.node_sound_stone_defaults(), +}) + + +minetest.register_node("fun_caves:brain_coral", { + description = "Brain Coral", + tiles = {"fun_caves_brain_coral.png"}, + light_source = 4, + groups = {cracky = 3, stone=1,}, + sounds = default.node_sound_stone_defaults(), +}) + + +minetest.register_node("fun_caves:dragon_eye", { + description = "Dragon Eye", + tiles = {"fun_caves_dragon_eye.png"}, + light_source = 4, + groups = {cracky = 3, stone=1,}, + sounds = default.node_sound_stone_defaults(), +}) + + +fun_caves.plantlist = { + {name="staghorn_coral", + desc="Staghorn Coral", + water=true, + light_source=1, + coral=true, + sounds = default.node_sound_stone_defaults(), + }, + + {name="water_plant_1", + desc="Water Plant", + water=true, + }, + + {name="bird_of_paradise", + desc="Bird of Paradise", + light=true, + groups={flower=1}, + }, + + {name="gerbera", + desc="Gerbera", + light=true, + groups={flower=1, color_pink=1}, + }, + + {name="hibiscus", + desc="Hibiscus", + wave=true, + groups={flower=1, color_white=1}, + }, + + {name="orchid", + desc="Orchid", + wave=true, + light=true, + groups={flower=1, color_white=1}, + }, +} + + +for _, plant in ipairs(fun_caves.plantlist) do + if plant.coral then + groups = {cracky=3, stone=1, attached_node=1} + else + groups = {snappy=3,flammable=2,flora=1,attached_node=1} + end + if plant.groups then + for k,v in pairs(plant.groups) do + groups[k] = v + end + end + + minetest.register_node("fun_caves:"..plant.name, { + description = plant.desc, + drawtype = "plantlike", + tiles = {"fun_caves_"..plant.name..".png"}, + waving = plant.wave, + sunlight_propagates = plant.light, + paramtype = "light", + walkable = false, + groups = groups, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}, + }, + }) + + if plant.water then + local def = { + description = plant.desc, + drawtype = "nodebox", + node_box = {type='fixed', fixed={{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, {-0.5, 0.5, -0.001, 0.5, 1.5, 0.001}, {-0.001, 0.5, -0.5, 0.001, 1.5, 0.5}}}, + drop = {max_items=2, items={{items={"fun_caves:"..plant.name}, rarity=1}, {items={"default:sand"}, rarity=1}}}, + tiles = { "default_sand.png", "fun_caves_"..plant.name..".png",}, + --tiles = { "default_dirt.png", "fun_caves_"..plant.name..".png",}, + sunlight_propagates = plant.light, + --light_source = 14, + paramtype = "light", + light_source = plant.light_source, + walkable = false, + groups = groups, + selection_box = { + type = "fixed", + fixed = {-0.5, 0.5, -0.5, 0.5, 11/16, 0.5}, + }, + sounds = plant.sounds or default.node_sound_leaves_defaults(), + } + minetest.register_node("fun_caves:"..plant.name.."_water_sand", def) + def2 = table.copy(def) + def2.tiles = { "default_dirt.png", "fun_caves_"..plant.name..".png",} + def2.drop = {max_items=2, items={{items={"fun_caves:"..plant.name}, rarity=1}, {items={"default:dirt"}, rarity=1}}} + minetest.register_node("fun_caves:"..plant.name.."_water_soil", def2) + end +end + + +local function register_flower(name, seed, biomes) + local param = { + deco_type = "simple", + place_on = {"default:dirt_with_grass"}, + sidelen = 16, + noise_params = { + offset = -0.02, + scale = 0.03, + spread = {x = 200, y = 200, z = 200}, + seed = seed, + octaves = 3, + persist = 0.6 + }, + biomes = biomes, + y_min = 6, + y_max = 31000, + decoration = "fun_caves:"..name, + } + + -- Let rainforest plants show up more often. + local key1 = table.contains(biomes, "rainforest") + --local key2 = table.contains(biomes, "desertstone_grassland") + --if key1 or key2 then + if key1 then + if key1 then + table.remove(param.biomes, key1) + --else + -- table.remove(param.biomes, key2) + end + if #param.biomes > 0 then + minetest.register_decoration(param) + end + + local param2 = table.copy(param) + --param2.biomes = {"rainforest", "desertstone_grassland", } + param2.biomes = {"rainforest", } + param2.noise_params.seed = param2.noise_params.seed + 20 + param2.noise_params.offset = param2.noise_params.offset + 0.01 + minetest.register_decoration(param2) + else + minetest.register_decoration(param) + end +end + +register_flower("bird_of_paradise", 8402, {"rainforest", }) +register_flower("orchid", 3944, {"sandstone_grassland", "tundra", "taiga", "stone_grassland", "coniferous_forest", "deciduous_forest", "savanna", "rainforest", "rainforest_swamp", }) +register_flower("hibiscus", 7831, {"sandstone_grassland", "deciduous_forest", "savanna", "rainforest", "rainforest_swamp", }) +--register_flower("calla_lily", 7985, {"sandstone_grassland", "stone_grassland", "deciduous_forest", "rainforest", }) +register_flower("gerbera", 1976, {"savanna", "rainforest", }) + +do + -- Water Plant + local water_plant_1_def_sand = { + fill_ratio = 0.05, + place_on = {"group:sand"}, + decoration = {"fun_caves:water_plant_1_water_sand"}, + --biomes = {"sandstone_grassland", "stone_grassland", "coniferous_forest", "deciduous_forest", "desert", "savanna", "rainforest", "rainforest_swamp", }, + biomes = {"sandstone_grassland", "stone_grassland", "coniferous_forest", "deciduous_forest", "savanna", "rainforest", "rainforest_swamp","sandstone_grassland_ocean", "stone_grassland_ocean", "coniferous_forest_ocean", "deciduous_forest_ocean", "desert_ocean", "savanna_ocean", }, + y_max = 60, + } + local water_plant_1_def_soil = table.copy(water_plant_1_def_sand) + water_plant_1_def_soil.place_on = {"group:soil"} + water_plant_1_def_soil.decoration = {"fun_caves:water_plant_1_water_soil",} + + fun_caves.register_water_plant(water_plant_1_def_sand) + fun_caves.register_water_plant(water_plant_1_def_soil) +end + + +-- Get the content ids for all registered water plants. +for _, desc in pairs(fun_caves.water_plants) do + if type(desc.decoration) == 'string' then + desc.content_id = minetest.get_content_id(desc.decoration) + elseif type(desc.decoration) == 'table' then + desc.content_id = minetest.get_content_id(desc.decoration[1]) + end +end diff --git a/deco_water.lua b/deco_water.lua new file mode 100644 index 0000000..5a39de9 --- /dev/null +++ b/deco_water.lua @@ -0,0 +1,102 @@ +local node = fun_caves.node +local light_depth = -13 +local water_level = 1 + +local water_lily_biomes = {} +for _, i in pairs({"rainforest_swamp", "rainforest", "savanna_swamp", "savanna", "deciduous_forest_swamp", "deciduous_forest", }) do + water_lily_biomes[i] = true +end +local coral_biomes = {} +for _, i in pairs({"desert_ocean", "savanna_ocean", "rainforest_ocean", }) do + coral_biomes[i] = true +end + +plant_noise = {offset = 0.0, scale = 1.0, spread = {x = 200, y = 200, z = 200}, seed = 33, octaves = 3, persist = 0.7, lacunarity = 2.0} + +local function surround(data, area, ivm) + local n + + -- Check to make sure that a plant root is fully surrounded. + -- This is due to the kludgy way you have to make water plants + -- in minetest, to avoid bubbles. + for x1 = -1,1,2 do + n = data[ivm+x1] + if n == node("default:river_water_source") or n == node("default:water_source") or n == node("air") then + return false + end + end + for z1 = -area.zstride,area.zstride,2*area.zstride do + n = data[ivm+z1] + if n == node("default:river_water_source") or n == node("default:water_source") or n == node("air") then + return false + end + end + + return true +end + +function fun_caves.decorate_water(data, area, minp, maxp, pos, ivm, biome_in, pn) + if pos.y < light_depth then + return + end + + local biome = biome_in + + local node_below = data[ivm - area.ystride] + local node_above = data[ivm + area.ystride] + + local inside = false + if pos.x < maxp.x and pos.y < maxp.y and pos.z < maxp.z and pos.x > minp.x and pos.y > minp.y and pos.z > minp.z then + inside = true + end + + if pos.y < water_level and data[ivm] == node("default:sand") and node_above == node("default:water_source") and data[ivm + area.ystride * 2] == node("default:water_source") and coral_biomes[biome] and pn < -0.1 and math.random(5) == 1 and surround(data, area, ivm) then + return node("fun_caves:staghorn_coral_water_sand") + elseif pos.y < water_level and node_below == node("default:sand") and node_above == node("default:water_source") and data[ivm] == node("default:water_source") and coral_biomes[biome] and pn < -0.1 and math.random(5) < 3 then + local sr = math.random(65) + if sr < 4 then + return node("fun_caves:brain_coral") + elseif sr < 6 then + return node("fun_caves:dragon_eye") + elseif sr < 65 then + return node("fun_caves:pillar_coral") + end + elseif inside and (node_above == node("default:water_source") or node_above == node("default:river_water_source")) and (data[ivm] == node("default:sand") or data[ivm] == node("default:dirt")) then + -- Check the biomes and plant water plants, if called for. + if not surround(data, area, ivm) then + return + end + + for _, desc in pairs(fun_caves.water_plants) do + if desc.content_id then + if not fun_caves.node_match_cache[desc.content_id] then + fun_caves.node_match_cache[desc.content_id] = {} + end + + if not fun_caves.node_match_cache[desc.content_id][data[ivm]] then + -- This is a great way to match all node type strings + -- against a given node (or nodes). However, it's slow. + -- To speed it up, we cache the results for each plant + -- on each node, and avoid calling find_nodes every time. + local posm, count = minetest.find_nodes_in_area(pos, pos, desc.place_on) + if #posm > 0 then + fun_caves.node_match_cache[desc.content_id][data[ivm]] = "good" + else + fun_caves.node_match_cache[desc.content_id][data[ivm]] = "bad" + end + end + + if fun_caves.node_match_cache[desc.content_id][data[ivm]] == "good" and desc.fill_ratio and (not desc.biomes or (biome and desc.biomes and table.contains(desc.biomes, biome))) and math.random() <= desc.fill_ratio then + return desc.content_id + end + end + end + elseif pos.y > minp.y and node_below == node("default:river_water_source") and data[ivm] == node("air") then + -- on top of the water + -- I haven't figured out what the decoration manager is + -- doing with the noise functions, but this works ok. + if water_lily_biomes[biome] and pn > 0.5 and math.random(15) == 1 then + return node("flowers:waterlily") + end + end +end diff --git a/init.lua b/init.lua index 71fc024..b57de02 100644 --- a/init.lua +++ b/init.lua @@ -3,6 +3,7 @@ fun_caves.version = "1.0" fun_caves.path = minetest.get_modpath(minetest.get_current_modname()) fun_caves.world = false fun_caves.time_factor = 10 +fun_caves.node_match_cache = {} minetest.register_on_mapgen_init(function(mgparams) diff --git a/mapgen.lua b/mapgen.lua index 2ffe364..f2ca6bd 100644 --- a/mapgen.lua +++ b/mapgen.lua @@ -16,6 +16,15 @@ local data = {} local vm, emin, emax, area, noise_area, csize local minp, maxp +-- Create a table of biome ids, so I can use the biomemap. +if not fun_caves.biome_ids then + fun_caves.biome_ids = {} + for name, desc in pairs(minetest.registered_biomes) do + local i = minetest.get_biome_id(desc.name) + fun_caves.biome_ids[i] = desc.name + end +end + local function place_schematic(pos, schem, center) local rot = math.random(4) - 1 local yslice = {} @@ -84,37 +93,44 @@ local function get_decoration(biome) end +local function detect_bull(heightmap, csize) + local j = -31000 + local k = 0 + local cutoff = (csize.x * csize.z) * 0.3 + for i = 1, #heightmap do + if j == heightmap[i] then + k = k + 1 + if k > cutoff then + return true + end + else + k = 0 + end + j = heightmap[i] + end + + return false +end + + function fun_caves.generate(p_minp, p_maxp, seed) minp, maxp = p_minp, p_maxp vm, emin, emax = minetest.get_mapgen_object("voxelmanip") vm:get_data(data) --p2data = vm:get_param2_data() local heightmap = minetest.get_mapgen_object("heightmap") + local biomemap = minetest.get_mapgen_object("biomemap") area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) csize = vector.add(vector.subtract(maxp, minp), 1) noise_area = VoxelArea:new({MinEdge={x=0,y=0,z=0}, MaxEdge=vector.subtract(csize, 1)}) -- There's a bug in the heightmap from valleys_c. Check for it. - local bullshit_heightmap = false - do - local j = -31000 - local k = 0 - for i = 1, #heightmap do - if j == heightmap[i] then - k = k + 1 - if k > (csize.x ^ 2) * 0.5 then - bullshit_heightmap = true - end - else - k = 0 - end - j = heightmap[i] - end - end + local bullshit_heightmap = detect_bull(heightmap, csize) + local write = false -- Deal with memory issues. This, of course, is supposed to be automatic. local mem = math.floor(collectgarbage("count")/1024) - if mem > 300 then + if mem > 200 then print("Fun Caves: Manually collecting garbage...") collectgarbage("collect") end @@ -138,9 +154,11 @@ function fun_caves.generate(p_minp, p_maxp, seed) local ivm = area:index(x, minp.y, z) for y = minp.y, maxp.y do - if (y < min_surface or bullshit_heightmap or y < heightmap[index] - cave_3[index]) and cave_1[index3d] * cave_2[index3d] > 0.05 then + if (y < min_surface or (bullshit_heightmap and y < 0) or y < heightmap[index] - cave_3[index]) and cave_1[index3d] * cave_2[index3d] > 0.05 then data[ivm] = node("air") - if y > min_surface and cave_3[index] < 1 and heightmap[index] == y and y > 0 then + write = true + + if y > 0 and cave_3[index] < 1 and heightmap[index] == y then local ivm2 = ivm for y2 = y + 1, maxp.y + 8 do ivm2 = ivm2 + area.ystride @@ -157,6 +175,7 @@ function fun_caves.generate(p_minp, p_maxp, seed) end end + -- Air needs to be placed prior to decorations. local index = 0 local index3d = 0 for z = minp.z, maxp.z do @@ -172,12 +191,21 @@ function fun_caves.generate(p_minp, p_maxp, seed) local i = fun_caves.decorate_cave(data, area, minp, y, ivm, biome_n[index3d]) if i then data[ivm] = i + write = true end elseif y < heightmap[index] and not bullshit_heightmap then local ivm_below = ivm - area.ystride if data[ivm] == node("air") and data[ivm_below] ~= node('air') then data[ivm_below] = node("dirt") end + else + local pn = minetest.get_perlin(plant_noise):get2d({x=x, y=z}) + local biome = fun_caves.biome_ids[biomemap[index]] + local i = fun_caves.decorate_water(data, area, minp, maxp, {x=x,y=y,z=z}, ivm, biome, pn) + if i then + data[ivm] = i + write = true + end end ivm = ivm + area.ystride @@ -187,15 +215,17 @@ function fun_caves.generate(p_minp, p_maxp, seed) end - vm:set_data(data) - --vm:set_param2_data(p2data) - if DEBUG then - vm:set_lighting({day = 15, night = 15}) - else - vm:calc_lighting() + if write then + vm:set_data(data) + --vm:set_param2_data(p2data) + if DEBUG then + vm:set_lighting({day = 15, night = 15}) + else + vm:calc_lighting() + end + vm:update_liquids() + vm:write_to_map() end - vm:update_liquids() - vm:write_to_map() vm, area, noise_area = nil, nil, nil end diff --git a/textures/fun_caves_bird_of_paradise.png b/textures/fun_caves_bird_of_paradise.png new file mode 100644 index 0000000000000000000000000000000000000000..e0534c080564e4db3e1d3bddbdec198df2e30d79 GIT binary patch literal 352 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?3oVGw3ym^DWND9B#o z>Fdh=fRT?w-LmITO9@cuzo(01NW|f{S8cft8Hlids6Voih3k@^UThVM`oZ7|ZuRB! z76hy3KYYQ-vRv-q((2tJP1SQ2IVSJR5;Vjzy6W(!wJH-sr{;|No`^L=k2+bxUYcP(>fOyyke>b{3z3zO$>x9)`0LxN9F zJ>T-8LvQC-u^9rNe%=nzJ$}U^LbT(w%ndcMk6%7!?R~&daOe7yLgiZ)&bQ3JGm0J- zeHtgdfaL^-Ad_-=Q<%c`&->@h)xORY!l9Znjb~LH_XS6W2L|gE1@>KyX7mxbx~GTf uLSq}lp8Ug#p8FqL@ij1TfY5%%7{=48MGYUf6@LT<1%s!npUXO@geCx@@QG*u literal 0 HcmV?d00001 diff --git a/textures/fun_caves_gerbera.png b/textures/fun_caves_gerbera.png new file mode 100644 index 0000000000000000000000000000000000000000..3fae697d7441acfc896b68837d78ba6ce07333f6 GIT binary patch literal 683 zcmV;c0#yBpP)qw2EG7D z-H@onKqN{9?NW(AY&TBq$Bsx7~w<3(W0C4-fr)|f0KwqabXe`)yrL16CR`kuVGln8WNZrMi3`=n`i zY?Q2gLzwq8Iv0L48^yMrb}znLJHV%AxSjdB zkoo$$Nk`~hc%?E96>J8I%|P*0L8uf%tug87>7+jDjX<~MB9{zYlIQf4@HkL(y|H>b z7oMbo2V7GcfE#J1YK?$P1`fbC=G66LU{1z9e=W?~0Ad>+#Wsu^!x5ptMk=)P@wJf( zEg8cNwJzGS_BMQL(ov^)XbEhlS*GuIvU6rvEn8UgRnw{mbUlL@nNu)EwBQed+_&i zbI&=y^ZTCP`ToAY1OImuJ9S764;}zs2F?H>pb=OA62KS0mwGrdUv&Vf;lV~=0Ejq_ z#4cG_rj27dD4K$|uBLqXAkeLcBMVglkQyG;f$@$1)tk9Z^NOnA^Lxo<^0+hwPpt=` z2!M7y97%1rw^Bjy05EP_Hmf&tNJrw*T$|Qt9u>!SkWylmY;sF^Y|921U-#cV0N}iI zBx~6M0J)_+T8)b8z5_zI6pFdhCa1M*0qID9^Lqtwu2e8L4HQ<2xP5Lkj|zaa9cK_aPK94?L-dBWqO^qSWx3l%0f&STBi?;AsBRZR2)z4h&}y_BLWsA3hDw9)N{Y*}@fq-3 znG~PU!;zW)w2?%++GSsNNbY41B^qlEL}Sf$533uhz&9>c(ck@`)hXo7i$E$ z$2uDwJ=pNi)I_#^Y9jkO@D30J-UMC+evihQU))K69;4-8kI~Y!trW+NbO|^WjWvgS zb?y;8*s!X3T)v;i{#F3=VBiLTWjeEtEk6eysW5mK@FDOs@X~#CAa0}+`IS<=W!mpM zj$=O4(J*)XM3Z$TwM;6R!R=9>sH?B>R~Y;ipg)z&1hy;pdxR)%q%Fsm(`zf{CxyH< zX%?(MpKh-&9_wsezIh8|=V$OB!KNO4tcqcpc7=K}@M*Bz2O4ZLR#+{K4oKWr2pvi%DKc9zo8 S%kWYF0000 zL#&9mt4tTKlEwW!Uq`+%<4>$4pE*47(gxKTm&z2}&meN@b3?M1NHt|Ph9v<7wUBa9 zQPU)YJBCM5k#v;BG7EUy5@usCvp=4HIo)PgiI77fF4PR??o-1%)1E1Gs6o-Kdtl3S zab2T=>Z;wyqqxw}J8*7aV$UP|;V*1D(=@y017Ro-b!fY5B%Xcid*@HbX2aqN`CQOB zvcAHLo$2SkYG?~eq?&R=vWuMhxSv5PQ*2P3@m?Zhwm)6nJl2<7vgeLpqSuohw0*ka zV>mx_>Z6AW-ZunJLEjz)|KK%luaerdXF+^sEMjSrOr1a;#RZLFQPikm%XD$*l;r4& znD$IH4@4IRCSC~K_IznD0_>I?#9`lk z2hpL*E?5PTB>`#A6moP$gieVq)5S%N8XCi5!$Gtj2{%S$!zzfFSrTr^2mc}=W4IPR z6WNXt%=V|N-ItFfFNDWKOUAF>Zu;asfryzVA(!k1=dOz1fa?|og)`pUBBT5Aks1JW zj)z~rZy*YI+Y)85%qo%&$M7gL$>0tuYKJPjEQ5%dC1D%$F1l3O&N5xb?>Z$pS|ERt zuqhkSdL*1tj}0|tBkG{-)0gP=EnMI|^I0ij7lp z^b=Bh|5X^IhMS)J$D#P%H~$kLvLxVi`62@E?Qj;{#RI?1JVuJVB;2CQM|$8SG?cK~bxa1p@Py8Q}(0mPJfb0@G`!C3%B0RFlVTU`tVutE&9 zZ~;%$?cV~(*S)=KB4q)D09-{(dGz0p;i{lL0Gkrj) V-PG%;QRDys002ovPDHLkV1ff9_Obu~ literal 0 HcmV?d00001 diff --git a/textures/fun_caves_water_plant_1.png b/textures/fun_caves_water_plant_1.png new file mode 100644 index 0000000000000000000000000000000000000000..225f11fe12c226de48fa6c8cf19fc8859046d312 GIT binary patch literal 2888 zcmV-O3%B%%P)569IlZe3}3N3e`zO zK~z}7ZI@qc9M^Tmf6Kdb=^c%<;_O1=A|Ze3$SrIKGLS?? znp8sL0&UV*LR}O_;k1?vL@!CJs(@O@Y2?;!YfGvBL`Fm>rXOh7lpuoC%3M}jI@%$< zJLHn1S@F(ZP9J6^+dwZcn1_4kp6{IVo$s7Ue5>~{1QLy6B~)}8uo5U5+iZUESNW8v z`;pFALSWe12qVlj&D;-1^YdBtP5SbGPR*|}>%K!F|FTG1O`VlXRK4GlmMawOP6B>! z?X&L5)cI)u1d{nDdtPF1|G%=N#*)I2=upuD1kef+7dO-JD;QG*Om*lvl^T^m9J?Kp8f*q+sK9QQK017dB@t69* z;3;Ni&n9UbRZXA8UYm*i`Dp$tMT$Qhg|m~)SJhuL)bm}+Uaq>m2a#U$03kWj3IM|P z+mJbVdJ=VL5W+B*JUf<1Rp*%BnUAQu1jBx`_!k3YvPCwG&2ha_MvhO@5d@0ljA!Uj z@%nxhRozMSi8H8~%2Ck(&CRFvte3;}!30clv0)(ep~)Q}+Vs&`z%-!Gj^y?&6yKB! z>nj`+22l4{9KFExLIq(+#P+Qun`zd)e)-_><$`rcG(0$X908PT?lXOvJ$#t9S*dvd zsF662xNiKOnS+!8NH9HA;BoIaFD1%DeiQ)9!!r8Ph?Ph=b~I6NVaZ2iCGw%2aAl4S zf$^&ZuY5P+iVH;>(E!FSA`3mJhX&E1521wcCNeZ2@1W0IfLSjNea#0$#Q?Gv`oJ!j ztw0DOQv?(Gk6cQ8P^d)9Lr(lnF^{<7LfRT3Z9SOa>90nVDiDS+wzm%a9=S#UvVMlpsVFO=@9n~#%U>E0>grtN_@89Ahz{GN**L_ z{WK}+ZG$y0_Bc=wSYY_^Wl0HjMV-o#_X`{$2tOtsZSRXt>~$z%#zmu`H5CK-@*o%z zU2jLNsnCJ1g<;K^*?yAuj;TcKr9;_Vh?L<&&4n6ZT9CCMP&7-^C<8>HAJQ@=UtET< zhoORO7os!`D0EUm5`J0t??yBfnvkJUD|z|pFRl$xiDYqtwm`tO$NRx)Uxoxz zu|BX_Hi;vWwc*vVIOMdW5cp7SbD=Mf?tK^x6-UDW#wM#%C`9i7KnX)3YV!9FK0Eh6 zCm%P`Nr6NMKH4NERp@;jTGL{AorD=5*0o7jy9w#G=Xc7n4aW7s@T={ef5)VoVBuvE z$|f~`3Ah1jv7UFlf6h+dEi2ASQUJoV5Qe0g_7F86Oc@)?OGqimNT|1UV7MPDRa zyFbE0*(aaAwq=+fj~8Npaw*shA|bUX%nO+odK*E40HMoM9Quw z|LXwJ)$Krimg1PlhFQg~l#|egWJ8eW^gb2o@kyj1S!-A<4(~yaU4;5HS zeW-J2fXyQwmof^SwGoD5IdCDcuncHbTqrn7JN9Rj`$w(BzZh;*PfN;pq>?w8GTmtE zp{>yHVB{ieO$$4e=$fM5oQAZ8xUB<*jDa*1lw6=ffW`Zv2NP{^tNGB^0|sm`i&WQn zNO%mVcq924vwN>x@&KRpRi8yuGS!%ZC*O#P)|+R!w!kuTP*Sje4~NH{#7U+iaa$>! zt{6x|p@TVS&BX%N0s@5wSn?qyx%x;C;{4l)B|fVg@BX(a?G)vYRvUD*G`A`>I+{Mw z3eadms9}wSmV%as0O-D(TPyxk^S_;?qbm(UfGJ`^3Pp7N1}ylHQ1Kmir4c!YXvK#G zkEqc^e_P!CO}+FLhoYf6xD5W$sV^;roAQCi`~o zL5Dt~rRc0pzN#CZByB}3EqtDa>Lu^Sp?9ob)8Y)5r$a7J7btApANK5Gn)w|Ur@HZaVzGw4;kN^1m*PcK6{Y4bw4~O@XG9;((Qzs|7R=*Uj z$h%sr&0j>F>DN0xx9v5S{MVTG&avt4cQI49FjED5|K~JrZjKFyu+)r8F`WjjZ+HGk{UYAx}tO}j6@wKUOrH7|d&v>L8SX42L(XR_{*>+3-Eb)##Q z{TGWz{_X3PbNePrV>g7sEsX@%vqjo^l+jCniL)_BsS-2aka7M)VktJcOh^L4FVf)8 zFeEy3(G!yw$v6XJ!C2{q%p5;62M-I=zCZEo$sb2A<~#_Y-dLdg{BykbgO?IJ-ucN5 zosuOzTj6keXwPE7;)U6Zkw~?r_oY$D*)afsB#_+*y-pQVJ`X%WZxKPr?p!xRfpsXA zwom=^^m9>vZ%^XI(%X@6>}ulNnU}WwsxiIk#LOG#*M4~y;>3UQ?L$xSlXMvsDlog^ zPB~GI#i!sPPMk$g%tCMXr+Y%)Vpm~^#hS~M*{=WbY1SIBoVCy?0LhIf&K|oqJ6U+( zm8Ty~-2bERMDK?lGHat>cmwHl(KJ3WY?Nl9*6x0RLJajoF%M@h!~oI~W)@-)hR?yh zk0q|v-RP~6bLfzGKco#(Lc=3^yPi-$=kZ6PWM|z+h8`It^Xn{{jhlRGW$gHYSdhY- z=!SBIw17)!TC^40G>617V1i@O63CI4pk!+(@A z?6X_)#f9!SKOgBk^WOizbfrRZsGoB1ZhWc1onJ29@=*;Hch68kGoCd_%6OCy6zto= zxnn<1jGZ6l#Nj_7*;nj;E@&)Jt(N)6AN(ls$7fGOB5lQ9-JXy$HZ**2U9=(DY&ewp zcn}e^IndqBh64lC(-xE~@eq@WD@D=|KyxOpp7lA2YATZR} z$aMh{5vus2nujROA-Xs6dVLyUfN0&0fP&CR2Wt=^h*!tr2|H&)OR~X`9PHakA?qwO z`doDAVVV{?gk(CGN26G-%~D8NoO=9k4{dSsr<$S1_r@7LS$V&VP8)G*J~fm|bO^rdB6ALF8$M6&e)yQgI-1GZQ8RE+ mfzSG^Llch_lD^@=E&m6*4m~zNjLyIS0000