From 441fe855e4447ce4d99beac76612532c2bb551c7 Mon Sep 17 00:00:00 2001 From: paramat Date: Wed, 24 Sep 2014 09:55:23 +0100 Subject: [PATCH] Water range 2. New pines. Rainforest, taiga biomes. Blend tunnels to fissures at ridges. Snowblocks on stone. Narrow rainforest paths --- README.txt | 2 +- functions.lua | 140 +++++++++++++++++++++++++++++++++++++++++--- init.lua | 156 +++++++++++++++++++++++++++++++++++++++++--------- nodes.lua | 57 ++++++++++++++++-- 4 files changed, 315 insertions(+), 40 deletions(-) diff --git a/README.txt b/README.txt index 772d645..00365fe 100644 --- a/README.txt +++ b/README.txt @@ -1,4 +1,4 @@ -riverdev 0.4.6 by paramat +riverdev 0.5.0 by paramat For latest stable Minetest back to 0.4.8 Depends default Licenses: code WTFPL diff --git a/functions.lua b/functions.lua index 1da6aa3..e1e9c4d 100644 --- a/functions.lua +++ b/functions.lua @@ -44,13 +44,16 @@ function riverdev_pinetree(x, y, z, area, data) for k = -2, 2 do local vi = area:index(x - 2, y + j, z + k) for i = -2, 2 do - if math.abs(i) == 2 or math.abs(k) == 2 then + if math.abs(i) == 1 and math.abs(k) == 1 then + data[vi] = c_pinetree + elseif math.abs(i) + math.abs(k) == 2 + or math.abs(i) + math.abs(k) == 3 then data[vi] = c_needles end vi = vi + 1 end end - elseif j == 4 or j == 7 or j == 10 then + elseif j == 4 or j == 7 or j == 10 or j == 13 then for k = -1, 1 do local vi = area:index(x - 1, y + j, z + k) for i = -1, 1 do @@ -60,17 +63,14 @@ function riverdev_pinetree(x, y, z, area, data) vi = vi + 1 end end - elseif j == 13 then + elseif j == 14 then for k = -1, 1 do local vi = area:index(x - 1, y + j, z + k) - local via = area:index(x - 1, y + j + 1, z + k) for i = -1, 1 do - if not (i == 0 and j == 0) then + if math.abs(i) + math.abs(k) == 1 then data[vi] = c_needles - data[via] = c_needles end vi = vi + 1 - via = via + 1 end end end @@ -83,6 +83,105 @@ function riverdev_pinetree(x, y, z, area, data) data[via] = c_needles end +function riverdev_snowypine(x, y, z, area, data) + local c_pinetree = minetest.get_content_id("riverdev:pinetree") + local c_needles = minetest.get_content_id("riverdev:needles") + local c_snowblock = minetest.get_content_id("default:snowblock") + for j = -4, 14 do + if j == 3 or j == 6 or j == 9 or j == 12 then + for i = -2, 2 do + for k = -2, 2 do + if math.abs(i) == 2 or math.abs(k) == 2 then + if math.random(7) ~= 2 then + local vil = area:index(x + i, y + j, z + k) + data[vil] = c_needles + local vila = area:index(x + i, y + j + 1, z + k) + data[vila] = c_snowblock + end + end + end + end + elseif j == 4 or j == 7 or j == 10 then + for i = -1, 1 do + for k = -1, 1 do + if not (i == 0 and j == 0) then + if math.random(11) ~= 2 then + local vil = area:index(x + i, y + j, z + k) + data[vil] = c_needles + local vila = area:index(x + i, y + j + 1, z + k) + data[vila] = c_snowblock + end + end + end + end + elseif j == 13 then + for i = -1, 1 do + for k = -1, 1 do + if not (i == 0 and j == 0) then + local vil = area:index(x + i, y + j, z + k) + data[vil] = c_needles + local vila = area:index(x + i, y + j + 1, z + k) + data[vila] = c_needles + local vilaa = area:index(x + i, y + j + 2, z + k) + data[vilaa] = c_snowblock + end + end + end + end + local vit = area:index(x, y + j, z) + data[vit] = c_pinetree + end + local vil = area:index(x, y + 15, z) + local vila = area:index(x, y + 16, z) + local vilaa = area:index(x, y + 17, z) + data[vil] = c_needles + data[vila] = c_needles + data[vilaa] = c_snowblock +end + +function riverdev_jungletree(x, y, z, area, data) + local c_juntree = minetest.get_content_id("default:jungletree") + local c_junleaf = minetest.get_content_id("riverdev:jungleleaf") + local c_vine = minetest.get_content_id("riverdev:vine") + local top = math.random(17,23) + local branch = math.floor(top * 0.6) + for j = -5, top do + if j == top or j == top - 1 or j == branch + 1 or j == branch + 2 then + for i = -2, 2 do -- leaves + for k = -2, 2 do + local vi = area:index(x + i, y + j, z + k) + if math.random(5) ~= 2 then + data[vi] = c_junleaf + end + end + end + elseif j == top - 2 or j == branch then -- branches + for i = -1, 1 do + for k = -1, 1 do + if math.abs(i) + math.abs(k) == 2 then + local vi = area:index(x + i, y + j, z + k) + data[vi] = c_juntree + end + end + end + end + if j >= 0 and j <= top - 3 then -- climbable nodes + for i = -1, 1 do + for k = -1, 1 do + if math.abs(i) + math.abs(k) == 1 then + local vi = area:index(x + i, y + j, z + k) + data[vi] = c_vine + end + end + end + end + if j <= top - 3 then -- trunk + local vi = area:index(x, y + j, z) + data[vi] = c_juntree + end + end +end + function riverdev_flower(data, vi) local c_danwhi = minetest.get_content_id("flowers:dandelion_white") local c_danyel = minetest.get_content_id("flowers:dandelion_yellow") @@ -145,7 +244,7 @@ minetest.register_abm({ local z = pos.z local vm = minetest.get_voxel_manip() local pos1 = {x=x-2, y=y-4, z=z-2} - local pos2 = {x=x+2, y=y+16, z=z+2} + local pos2 = {x=x+2, y=y+17, z=z+2} local emin, emax = vm:read_from_map(pos1, pos2) local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax}) local data = vm:get_data() @@ -158,6 +257,31 @@ minetest.register_abm({ end, }) +-- Jungletree sapling + +minetest.register_abm({ + nodenames = {"riverdev:jungling"}, + interval = 63, + chance = 3, + action = function(pos, node) + local x = pos.x + local y = pos.y + local z = pos.z + local vm = minetest.get_voxel_manip() + local pos1 = {x=x-2, y=y-5, z=z-2} + local pos2 = {x=x+2, y=y+23, z=z+2} + local emin, emax = vm:read_from_map(pos1, pos2) + local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax}) + local data = vm:get_data() + -- check temp/humid + riverdev_jungletree(x, y, z, area, data) + + vm:set_data(data) + vm:write_to_map() + vm:update_map() + end, +}) + -- Set mapgen parameters minetest.register_on_mapgen_init(function(mgparams) diff --git a/init.lua b/init.lua index 9dce9dd..01e4fef 100644 --- a/init.lua +++ b/init.lua @@ -1,14 +1,23 @@ --- riverdev 0.4.6 by paramat +-- riverdev 0.5.0 by paramat -- For latest stable Minetest and back to 0.4.8 -- Depends default -- License: code WTFPL --- spawnplayer function +-- liquid range 2 +-- improved pines with branches +-- rainforest, taiga biomes +-- blend tunnels to fissures at ridge +-- snowblocks on stone +-- path clearings narrow in rainforest +-- TODO +-- magma tunnels +-- 3D noise boulders spawning at surface level +-- packed snow above paths -- Parameters local YMIN = -33000 -local YMAX = 33000 +local YMAX = 1024 local YWATER = 1 local YSAND = 4 -- Top of beach y local YTER = -64 -- Deepest seabed y @@ -27,8 +36,11 @@ local TTUN = 0.02 -- Tunnel width local ORECHA = 1 / 5 ^ 3 -- Ore chance per stone node. 1 / n ^ 3 where n = average distance between ores local APPCHA = 1 / 5 ^ 2 -- Appletree maximum chance per grass node. 1 / n ^ 2 where n = average minimum distance between flora local PINCHA = 1 / 6 ^ 2 -- Pinetree maximum chance per grass node +local JUNCHA = 1 / 4 ^ 2 -- Jungletree maximum chance per grass node local GRACHA = 1 / 5 ^ 2 -- Grasses maximum chance per grass node -local FLOCHA = 1 / 41 ^ 2 -- Flower chance per grass node +local FLOCHA = 1 / 47 ^ 2 -- Flower chance per grass node +local LOTET = -0.4 +local HITET = 0.6 -- 3D noise for highland terrain @@ -85,6 +97,17 @@ local np_pathb = { persist = 0.4 } +-- 2D noise for temperature + +local np_temp = { + offset = 0, + scale = 1, + spread = {x=536, y=536, z=536}, + seed = 18882, + octaves = 3, + persist = 0.4 +} + -- 2D noise for trees local np_tree = { @@ -141,7 +164,7 @@ minetest.register_on_generated(function(minp, maxp, seed) return end - local t1 = os.clock() + local t0 = os.clock() local x1 = maxp.x local y1 = maxp.y local z1 = maxp.z @@ -149,7 +172,7 @@ minetest.register_on_generated(function(minp, maxp, seed) local y0 = minp.y local z0 = minp.z - print ("[riverdev] chunk minp ("..x0.." "..y0.." "..z0..")") + print ("[riverdev] generate chunk minp ("..x0.." "..y0.." "..z0..")") local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax} @@ -160,7 +183,9 @@ minetest.register_on_generated(function(minp, maxp, seed) local c_water = minetest.get_content_id("default:water_source") local c_sand = minetest.get_content_id("default:sand") local c_wood = minetest.get_content_id("default:wood") + local c_snowblock = minetest.get_content_id("default:snowblock") local c_grass5 = minetest.get_content_id("default:grass_5") + local c_jungrass = minetest.get_content_id("default:junglegrass") local c_stodiam = minetest.get_content_id("default:stone_with_diamond") local c_stomese = minetest.get_content_id("default:stone_with_mese") local c_stogold = minetest.get_content_id("default:stone_with_gold") @@ -194,9 +219,13 @@ minetest.register_on_generated(function(minp, maxp, seed) local nvals_base = minetest.get_perlin_map(np_base, chulensxz):get2dMap_flat(minposxz) local nvals_patha = minetest.get_perlin_map(np_patha, chulensxz):get2dMap_flat(minposxz) local nvals_pathb = minetest.get_perlin_map(np_pathb, chulensxz):get2dMap_flat(minposxz) + local nvals_temp = minetest.get_perlin_map(np_temp, chulensxz):get2dMap_flat(minposxz) local nvals_tree = minetest.get_perlin_map(np_tree, chulensxz):get2dMap_flat(minposxz) local nvals_grass = minetest.get_perlin_map(np_grass, chulensxz):get2dMap_flat(minposxz) + --local noiset = math.ceil((os.clock() - t0) * 1000) + --print ("[riverdev] noise "..noiset.." ms") + local viu = area:index(x0, y0-1, z0) local ungen = data[viu] == c_ignore @@ -215,6 +244,8 @@ minetest.register_on_generated(function(minp, maxp, seed) local nodid = data[vi] local nodidu = data[viu] local chunkxz = x >= x0 and z >= z0 + + local n_temp = nvals_temp[nixz] local n_tree = math.min(math.max(nvals_tree[nixz], 0), 1) local n_grass = math.min(math.max(nvals_grass[nixz], 0), 1) @@ -230,7 +261,7 @@ minetest.register_on_generated(function(minp, maxp, seed) local n_absmid = (math.abs(nvals_mid[nixz])) ^ 0.8 local n_absbase = (math.abs(nvals_base[nixz])) ^ 0.8 - local n_invbase = (1 - n_absbase) + local n_invbase = math.max(1 - n_absbase, 0) local grad = (YTER - y) / TERSCA local densitybase = n_invbase * BASAMP + grad local densitymid = n_absmid * MIDAMP + densitybase @@ -241,7 +272,7 @@ minetest.register_on_generated(function(minp, maxp, seed) local trsand = TRSAND * n_absbase local weba = math.abs(nvals_weba[nixyz]) < TTUN - local webb = math.abs(nvals_webb[nixyz]) < TTUN + local webb = math.abs(nvals_webb[nixyz]) < TTUN + n_invbase ^ 8 * 4 -- blend tunnel into fissure at ridge local novoid = not (weba and webb) local wood = densitybase > trsand * 2 and density < 0 @@ -290,7 +321,7 @@ minetest.register_on_generated(function(minp, maxp, seed) data[vi] = c_stone -- stone end stable[si] = stable[si] + 1 - under[si] = 0 + under[si] = 5 elseif y > YSAND and ((not wood and density < 0 and under[si] ~= 0) or (wood and densitybase > trsand * 2 and densitybase < trsand * 2 + 0.002)) @@ -298,10 +329,14 @@ minetest.register_on_generated(function(minp, maxp, seed) or ((n_patha >= 0 and n_zprepatha < 0) or (n_patha < 0 and n_zprepatha >= 0)) or ((n_pathb >= 0 and n_xprepathb < 0) or (n_pathb < 0 and n_xprepathb >= 0)) -- pathb or ((n_pathb >= 0 and n_zprepathb < 0) or (n_pathb < 0 and n_zprepathb >= 0))) then - if wood and math.random() < 0.1 then + if wood and math.random() < 0.125 then local vi = area:index(x, y-2, z) - for j = 1, 16 do - data[vi] = c_wood + for j = 1, (16 + y - y0) do + if data[vi] == c_stone then + break + else + data[vi] = c_wood + end vi = vi - emerlen end end @@ -322,10 +357,16 @@ minetest.register_on_generated(function(minp, maxp, seed) if y <= YSAND + math.random(0, 1) or densitybase >= trsand + math.random() * 0.002 then data[vi] = c_sand - under[si] = 2 - else - data[vi] = c_dirt under[si] = 1 + elseif n_temp < LOTET then -- taiga/snowyplains + data[vi] = c_dirt + under[si] = 3 + elseif n_temp > HITET then -- rainforest + data[vi] = c_dirt + under[si] = 4 + else + data[vi] = c_dirt -- deciduous forest/grassland + under[si] = 2 end elseif y <= YWATER and density < tstone then -- sea water data[vi] = c_water @@ -339,9 +380,10 @@ minetest.register_on_generated(function(minp, maxp, seed) end stable[si] = 0 under[si] = 0 - elseif density < 0 and under[si] ~= 0 then -- air above surface - if under[si] == 1 and nodid ~= c_path and nodidu ~= c_path - and nodid ~= c_wood and nodidu ~= c_wood then + elseif density < 0 and under[si] ~= 0 -- air above surface + and nodid ~= c_path and nodidu ~= c_path + and nodid ~= c_wood and nodidu ~= c_wood then + if under[si] == 2 then -- forest/grassland if math.random() < APPCHA * n_tree and y < YPINE and n_abspatha > TPFLO and n_abspathb > TPFLO then riverdev_appletree(x, y, z, area, data) @@ -352,10 +394,30 @@ minetest.register_on_generated(function(minp, maxp, seed) data[viu] = c_grass if math.random() < FLOCHA then riverdev_flower(data, vi) - elseif math.random() < GRACHA * n_grass then -- grasses + elseif math.random() < GRACHA * n_grass then data[vi] = c_grass5 end end + elseif under[si] == 3 then -- taiga + if math.random() < PINCHA * n_tree + and n_abspatha > TPFLO and n_abspathb > TPFLO then + riverdev_snowypine(x, y, z, area, data) + else + data[viu] = c_grass + data[vi] = c_snowblock + end + elseif under[si] == 4 then -- rainforest + if math.random() < JUNCHA + and n_abspatha > TPFLO / 2 and n_abspathb > TPFLO / 2 then + riverdev_jungletree(x, y, z, area, data) + else + data[viu] = c_grass + if math.random() < GRACHA then + data[vi] = c_jungrass + end + end + elseif under[si] == 5 and n_temp < LOTET then + data[vi] = c_snowblock end stable[si] = 0 under[si] = 0 @@ -371,10 +433,14 @@ minetest.register_on_generated(function(minp, maxp, seed) or ((n_patha >= 0 and n_zprepatha < 0) or (n_patha < 0 and n_zprepatha >= 0)) or ((n_pathb >= 0 and n_xprepathb < 0) or (n_pathb < 0 and n_xprepathb >= 0)) -- pathb or ((n_pathb >= 0 and n_zprepathb < 0) or (n_pathb < 0 and n_zprepathb >= 0))) then - if wood and math.random() < 0.1 then + if wood and math.random() < 0.125 then local vi = area:index(x, y-2, z) - for j = 1, 16 do - data[vi] = c_wood + for j = 1, (16 + y - y0) do + if data[vi] == c_stone then + break + else + data[vi] = c_wood + end vi = vi - emerlen end end @@ -389,10 +455,44 @@ minetest.register_on_generated(function(minp, maxp, seed) vi = vi + 1 end end - elseif density < 0 and under[si] ~= 0 then - if under[si] == 1 and nodid ~= c_path and nodidu ~= c_path - and nodid ~= c_wood and nodidu ~= c_wood then - data[viu] = c_grass + elseif density < 0 and under[si] ~= 0 + and nodid ~= c_path and nodidu ~= c_path + and nodid ~= c_wood and nodidu ~= c_wood then + if under[si] == 2 then -- forest/grassland + if math.random() < APPCHA * n_tree and y < YPINE + and n_abspatha > TPFLO and n_abspathb > TPFLO then + riverdev_appletree(x, y, z, area, data) + elseif math.random() < PINCHA * n_tree and y >= YPINE + and n_abspatha > TPFLO and n_abspathb > TPFLO then + riverdev_pinetree(x, y, z, area, data) + else + data[viu] = c_grass + if math.random() < FLOCHA then + riverdev_flower(data, vi) + elseif math.random() < GRACHA * n_grass then + data[vi] = c_grass5 + end + end + elseif under[si] == 3 then -- taiga + if math.random() < PINCHA * n_tree + and n_abspatha > TPFLO and n_abspathb > TPFLO then + riverdev_snowypine(x, y, z, area, data) + else + data[viu] = c_grass + data[vi] = c_snowblock + end + elseif under[si] == 4 then -- rainforest + if math.random() < JUNCHA + and n_abspatha > TPFLO / 2 and n_abspathb > TPFLO / 2 then + riverdev_jungletree(x, y, z, area, data) + else + data[viu] = c_grass + if math.random() < GRACHA then + data[vi] = c_jungrass + end + end + elseif under[si] == 5 and n_temp < LOTET then + data[vi] = c_snowblock end end end @@ -414,7 +514,9 @@ minetest.register_on_generated(function(minp, maxp, seed) vm:set_lighting({day=0, night=0}) vm:calc_lighting() vm:write_to_map(data) - local chugent = math.ceil((os.clock() - t1) * 1000) + vm:update_liquids() + + local chugent = math.ceil((os.clock() - t0) * 1000) print ("[riverdev] "..chugent.." ms") end) diff --git a/nodes.lua b/nodes.lua index b3729be..6aabafe 100644 --- a/nodes.lua +++ b/nodes.lua @@ -125,6 +125,55 @@ minetest.register_node("riverdev:pinewood", { sounds = default.node_sound_wood_defaults(), }) +minetest.register_node("riverdev:jungleleaf", { + description = "Jungletree leaves", + drawtype = "allfaces_optional", + visual_scale = 1.3, + tiles = {"default_jungleleaves.png"}, + paramtype = "light", + is_ground_content = false, + groups = {snappy=3, flammable=2, leaves=1}, + drop = { + max_items = 1, + items = { + {items = {"riverdev:jungling"},rarity = 20}, + {items = {"riverdev:jungleleaf"}} + } + }, + sounds = default.node_sound_leaves_defaults(), +}) + +minetest.register_node("riverdev:vine", { + description = "Jungletree vine", + drawtype = "airlike", + paramtype = "light", + walkable = false, + climbable = true, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + groups = {not_in_creative_inventory=1}, +}) + +minetest.register_node("riverdev:jungling", { + description = "Jungletree sapling", + drawtype = "plantlike", + visual_scale = 1.0, + tiles = {"default_junglesapling.png"}, + inventory_image = "default_junglesapling.png", + wield_image = "default_junglesapling.png", + paramtype = "light", + walkable = false, + is_ground_content = false, + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} + }, + groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1}, + sounds = default.node_sound_leaves_defaults(), +}) + minetest.register_node("riverdev:freshwater", { description = "Fresh Water Source", inventory_image = minetest.inventorycube("riverdev_freshwater.png"), @@ -158,7 +207,7 @@ minetest.register_node("riverdev:freshwater", { liquid_alternative_source = "riverdev:freshwater", liquid_viscosity = WATER_VISC, liquid_renewable = false, - liquid_range = 0, + liquid_range = 2, post_effect_color = {a=64, r=100, g=150, b=200}, groups = {water=3, liquid=3, puts_out_fire=1}, }) @@ -195,7 +244,7 @@ minetest.register_node("riverdev:freshwaterflow", { liquid_alternative_source = "riverdev:freshwater", liquid_viscosity = WATER_VISC, liquid_renewable = false, - liquid_range = 0, + liquid_range = 2, post_effect_color = {a=64, r=100, g=130, b=200}, groups = {water=3, liquid=3, puts_out_fire=1, not_in_creative_inventory=1}, }) @@ -233,7 +282,7 @@ minetest.register_node("riverdev:mixwater", { liquid_alternative_source = "riverdev:mixwater", liquid_viscosity = WATER_VISC, liquid_renewable = false, - liquid_range = 0, + liquid_range = 2, post_effect_color = {a=64, r=100, g=115, b=200}, groups = {water=3, liquid=3, puts_out_fire=1}, }) @@ -270,7 +319,7 @@ minetest.register_node("riverdev:mixwaterflow", { liquid_alternative_source = "riverdev:mixwater", liquid_viscosity = WATER_VISC, liquid_renewable = false, - liquid_range = 0, + liquid_range = 2, post_effect_color = {a=64, r=100, g=115, b=200}, groups = {water=3, liquid=3, puts_out_fire=1, not_in_creative_inventory=1}, })