123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575 |
- cw = cw or {}
- cw.modpath = minetest.get_modpath("cw")
- cw.worldpath = minetest.get_worldpath()
- -- Localize for performance.
- local math_random = math.random
- if not cw.jungletree_registered then
- local _ = {name = "air", prob = 0}
- local L = {name = "default:jungleleaves", prob = 255}
- local N = {name = "default:jungleleaves", prob = 223}
- local M = {name = "default:jungleleaves", prob = 191}
- local B = {name = "default:jungletree", prob = 255, force_place = true}
- local Y = {name = "default:jungletree", prob = 191, force_place = true}
- local U = {name = "default:jungletree", prob = 127, force_place = true}
- local I = {name = "default:jungletree", prob = 255}
- do
- local jungletree_data = {
- size = {x = 5, y = 17, z = 5},
- data = {
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- N, L, N, _, _,
- _, _, N, L, N,
- _, _, _, _, _,
- _, _, _, _, _,
- M, N, N, N, M,
- M, N, N, N, M,
- _, _, _, _, _,
- _, _, B, _, _,
- _, _, B, _, _,
- _, _, U, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- L, B, L, _, _,
- _, _, L, B, L,
- _, _, _, _, _,
- _, _, _, _, _,
- N, B, L, B, N,
- N, L, L, L, N,
- _, N, N, N, _,
- _, B, B, B, _,
- _, B, B, B, _,
- _, U, B, U, _,
- _, _, B, _, _,
- _, _, B, _, _,
- _, _, B, _, _,
- _, _, B, _, _,
- _, _, B, _, _,
- _, _, B, L, N,
- N, L, B, _, _,
- N, L, B, _, _,
- _, _, B, L, N,
- _, _, B, L, N,
- _, _, B, _, _,
- N, L, L, L, N,
- N, L, L, L, N,
- _, N, L, N, _,
- _, _, B, _, _,
- _, _, B, _, _,
- _, _, U, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, L, B, L,
- L, B, L, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, L, B, L,
- _, _, _, _, _,
- N, B, L, B, N,
- N, L, L, L, N,
- _, N, N, N, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, N, L, N,
- N, L, N, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, N, L, N,
- _, _, _, _, _,
- M, N, N, N, M,
- M, N, N, N, M,
- _, _, _, _, _,
- },
- yslice_prob = {
- {ypos=6, prob=191},
- {ypos=7, prob=191},
- {ypos=8, prob=191},
- {ypos=9, prob=191},
- {ypos=10, prob=191},
- },
- }
- local data = minetest.serialize_schematic(jungletree_data, "mts", {})
- local file = io.open(cw.worldpath .. "/cw_jungletree_base.mts", "w")
- file:write(data)
- file:close()
- end
- do
- -- Main difference is the trunk base doesn't have extra nodes around it.
- local jungletree_data = {
- size = {x = 5, y = 17, z = 5},
- data = {
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- N, L, N, _, _,
- _, _, N, L, N,
- _, _, _, _, _,
- _, _, _, _, _,
- M, N, N, N, M,
- M, N, N, N, M,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- L, B, L, _, _,
- _, _, L, B, L,
- _, _, _, _, _,
- _, _, _, _, _,
- N, B, L, B, N,
- N, L, L, L, N,
- _, N, N, N, _,
- _, _, B, _, _,
- _, _, B, _, _,
- _, _, B, _, _,
- _, _, B, _, _,
- _, _, B, _, _,
- _, _, B, _, _,
- _, _, B, _, _,
- _, _, B, _, _,
- _, _, B, L, N,
- N, L, B, _, _,
- N, L, B, _, _,
- _, _, B, L, N,
- _, _, B, L, N,
- _, _, B, _, _,
- N, L, L, L, N,
- N, L, L, L, N,
- _, N, L, N, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, L, B, L,
- L, B, L, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, L, B, L,
- _, _, _, _, _,
- N, B, L, B, N,
- N, L, L, L, N,
- _, N, N, N, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, N, L, N,
- N, L, N, _, _,
- _, _, _, _, _,
- _, _, _, _, _,
- _, _, N, L, N,
- _, _, _, _, _,
- M, N, N, N, M,
- M, N, N, N, M,
- _, _, _, _, _,
- },
- yslice_prob = {
- {ypos=6, prob=191},
- {ypos=7, prob=191},
- {ypos=8, prob=191},
- {ypos=9, prob=191},
- {ypos=10, prob=191},
- },
- }
- local data = minetest.serialize_schematic(jungletree_data, "mts", {})
- local file = io.open(cw.worldpath .. "/cw_jungletree_top.mts", "w")
- file:write(data)
- file:close()
- end
- cw.jungletree_registered = true
- end
- -- A Channelwood-like realm. Endless, shallow water in all directions, with
- -- trees growing out of the ocean. Trees are huge and extremely tall. Water is
- -- dangerious, filled with flesh-eating fish! Trees do not burn (too wet).
- -- Register deadly water.
- if not cw.registered then
- -- Basically just a copy of regular water, with damage_per_second.
- local sdef = table.copy(minetest.registered_nodes["default:water_source"])
- local fdef = table.copy(minetest.registered_nodes["default:water_flowing"])
- sdef.damage_per_second = 1
- fdef.damage_per_second = 1
- sdef.liquid_alternative_flowing = "cw:water_flowing"
- sdef.liquid_alternative_source = "cw:water_source"
- fdef.liquid_alternative_flowing = "cw:water_flowing"
- fdef.liquid_alternative_source = "cw:water_source"
- minetest.register_node("cw:water_source", sdef)
- minetest.register_node("cw:water_flowing", fdef)
- end
- cw.REALM_START = 3050
- cw.BEDROCK_DEPTH = 4
- cw.OCEAN_DEPTH = 16
- cw.GROUND_DEPTH = 11
- cw.GROUND_HEIGHT_VARIATION = 4
- -- Controls land height.
- cw.noise1param2d = {
- offset = 0,
- scale = 1,
- spread = {x=128, y=128, z=128},
- seed = 3717,
- octaves = 5,
- persist = 0.5,
- lacunarity = 2,
- }
- cw.noise2param2d = {
- offset = 0,
- scale = 1,
- spread = {x=32, y=32, z=32},
- seed = 5817,
- octaves = 4,
- persist = 0.8,
- lacunarity = 2,
- }
- -- Content IDs used with the voxel manipulator.
- local c_air = minetest.get_content_id("air")
- local c_ignore = minetest.get_content_id("ignore")
- local c_stone = minetest.get_content_id("default:stone")
- local c_bedrock = minetest.get_content_id("bedrock:bedrock")
- local c_water = minetest.get_content_id("cw:water_source")
- local c_dirt = minetest.get_content_id("darkage:darkdirt")
- local c_silt = minetest.get_content_id("darkage:silt")
- local c_mud = minetest.get_content_id("darkage:mud")
- local c_clay = minetest.get_content_id("default:clay")
- local c_lily = minetest.get_content_id("flowers:waterlily")
- -- Externally located tables for performance.
- local data = {}
- local noisemap1 = {}
- local noisemap2 = {}
- local JUNGLETREE_REPLACEMENTS = {
- ["default:jungletree"] = "basictrees:jungletree_cube",
- ["default:jungleleaves"] = "basictrees:jungletree_leaves2",
- }
- local RANDPOS = {
- {x=1, y=0, z=0},
- {x=-1, y=0, z=0},
- {x=0, y=0, z=1},
- {x=0, y=0, z=-1},
- -- 3 times to increase probability.
- {x=0, y=0, z=0},
- {x=0, y=0, z=0},
- {x=0, y=0, z=0},
- }
- cw.generate_realm = function(minp, maxp, seed)
- local nstart = cw.REALM_START
- minp = table.copy(minp)
- maxp = table.copy(maxp)
- -- Don't run for out-of-bounds mapchunks.
- local nfinish = nstart + 100
- if minp.y > nfinish or maxp.y < nstart then
- return
- end
- -- Generate the full column all at once.
- if minp.y > nstart then
- minp.y = nstart
- end
- if maxp.y < nfinish then
- maxp.y = nfinish
- end
- -- Grab the voxel manipulator.
- -- Read current map data.
- local vm = VoxelManip()
- vm:read_from_map(vector.subtract(minp, 16), vector.add(maxp, 16))
- local emin, emax = vm:get_emerged_area()
- vm:get_data(data)
- local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax})
- local pr = PseudoRandom(seed + 381)
- local x1 = maxp.x
- local y1 = maxp.y
- local z1 = maxp.z
- local x0 = minp.x
- local y0 = minp.y
- local z0 = minp.z
- -- Compute side lengths.
- local side_len_x = ((x1-x0)+1)
- local side_len_z = ((z1-z0)+1)
- local sides2D = {x=side_len_x, y=side_len_z}
- local bp2d = {x=x0, y=z0}
- -- Get noisemaps.
- local perlin1 = minetest.get_perlin_map(cw.noise1param2d, sides2D)
- perlin1:get2dMap_flat(bp2d, noisemap1)
- local perlin2 = minetest.get_perlin_map(cw.noise2param2d, sides2D)
- perlin2:get2dMap_flat(bp2d, noisemap2)
- -- Localize commonly used functions.
- local floor = math.floor
- local ceil = math.ceil
- local abs = math.abs
- local od = cw.OCEAN_DEPTH
- local bd = cw.BEDROCK_DEPTH
- local gd = cw.GROUND_DEPTH
- local ghv = cw.GROUND_HEIGHT_VARIATION
- local tree_positions1 = {}
- local lily_positions1 = {}
- -- First mapgen pass.
- for z = z0, z1 do
- for x = x0, x1 do
- -- Get index into 2D noise arrays.
- local nx = (x-x0)
- local nz = (z-z0)
- local ni2 = (side_len_z*nz+nx)
- -- Lua arrays start indexing at 1, not 0. Urrrrgh.
- ni2 = ni2 + 1
- local n1 = noisemap1[ni2]
- local n2 = noisemap2[ni2]
- -- Randomize height of the bedrock a bit.
- local bedrock_adjust = (nstart + bd + pr:next(0, pr:next(1, 2)))
- local clay_depth = (nstart + bd + pr:next(1, 2))
- -- Fixed ocean height.
- local ocean_depth = (nstart + od)
- local ocean_surface = ocean_depth + 1
- -- Ground height.
- local an1 = abs(n1)
- local ground_depth = (nstart + gd + floor(an1 * ghv))
- local water_depth = (ocean_depth - ground_depth)
- local lily_chance = 1000
- if water_depth <= 2 then
- if pr:next(1, 16) == 1 then
- tree_positions1[#tree_positions1+1] = {x=x, y=ground_depth, z=z, w=an1}
- end
- lily_chance = 50
- elseif water_depth == 3 then
- if pr:next(1, 40) == 1 then
- tree_positions1[#tree_positions1+1] = {x=x, y=ground_depth, z=z, w=an1}
- end
- lily_chance = 150
- elseif water_depth == 4 then
- if pr:next(1, 300) == 1 then
- tree_positions1[#tree_positions1+1] = {x=x, y=ground_depth, z=z, w=an1}
- end
- lily_chance = 200
- end
- -- Enable waterlilies.
- local want_waterlily = false
- if pr:next(1, lily_chance) == 1 then
- want_waterlily = true
- end
- -- First pass through column.
- for y = y0, y1 do
- local vp = area:index(x, y, z)
- if y >= nstart and y <= nfinish then
- -- Get what's already here.
- local cid = data[vp]
- if cid == c_air or cid == c_ignore then
- -- Place bedrock layer.
- if y <= bedrock_adjust then
- data[vp] = c_bedrock
- elseif y <= clay_depth and water_depth >= 5 then
- data[vp] = c_clay
- elseif y < ground_depth then
- data[vp] = c_dirt
- elseif y == ground_depth then
- -- Mud appears when silt rises to water surface and above.
- if ground_depth >= (ocean_depth - 1) then
- data[vp] = c_mud
- else
- data[vp] = c_silt
- end
- elseif y <= ocean_depth then
- data[vp] = c_water
- elseif y == ocean_surface then
- if want_waterlily then
- data[vp] = c_lily
- end
- end
- end
- end
- end
- end
- end
- vm:set_data(data)
- for k, v_orig in ipairs(tree_positions1) do
- local v = table.copy(v_orig)
- local bottom = v.y
- local w = v.w
- if w > 1.0 then
- w = 1.0
- end
- local h = 13 * w
- v.w = nil
- -- Schematic horizontal offset.
- v.x = v.x - 2
- v.z = v.z - 2
- local path = cw.worldpath .. "/cw_jungletree_base.mts"
- local path2 = cw.worldpath .. "/cw_jungletree_top.mts"
- local path3 = path2
- if h > 10 then
- path2 = path
- end
- local force_place = false
- minetest.place_schematic_on_vmanip(vm, v, path, "random", JUNGLETREE_REPLACEMENTS, force_place)
- if pr:next(1, 5) <= 4 then
- v.y = v.y + h
- if h > 10 then
- minetest.place_schematic_on_vmanip(vm, vector.add(v, RANDPOS[math_random(1, #RANDPOS)]), path2, "random", JUNGLETREE_REPLACEMENTS, force_place)
- else
- minetest.place_schematic_on_vmanip(vm, v, path2, "random", JUNGLETREE_REPLACEMENTS, force_place)
- end
- if pr:next(1, 3) <= 2 then
- v.y = v.y + h
- if h > 10 then
- minetest.place_schematic_on_vmanip(vm, vector.add(v, RANDPOS[math_random(1, #RANDPOS)]), path2, "random", JUNGLETREE_REPLACEMENTS, force_place)
- else
- minetest.place_schematic_on_vmanip(vm, v, path2, "random", JUNGLETREE_REPLACEMENTS, force_place)
- end
- if h >= 10 then
- if pr:next(1, 2) == 1 then
- v.y = v.y + 13
- minetest.place_schematic_on_vmanip(vm, v, path3, "random", JUNGLETREE_REPLACEMENTS, force_place)
- if h > 10 and pr:next(1, 3) == 1 then
- v.y = v.y + 13
- minetest.place_schematic_on_vmanip(vm, v, path3, "random", JUNGLETREE_REPLACEMENTS, force_place)
- end
- end
- elseif h >= 8 then
- if pr:next(1, 3) == 1 then
- v.y = v.y + 12
- minetest.place_schematic_on_vmanip(vm, v, path3, "random", JUNGLETREE_REPLACEMENTS, force_place)
- end
- end
- end
- end
- -- Store tree bottom/top.
- v_orig.b = bottom
- v_orig.t = v.y + 17
- end
- -- Finalize voxel manipulator.
- -- Note: we specifically do not generate ores! The value of this realm is in
- -- its trees.
- vm:set_lighting({day=0, night=0})
- vm:calc_lighting()
- -- Liquid is never added in a way that would require flowing update.
- --vm:update_liquids()
- vm:write_to_map()
- for k, v in ipairs(tree_positions1) do
- local bottom = v.y
- local top = v.t
- -- This is somewhat intensive, so don't run for every single tree.
- if math_random(1, 5) == 1 then
- local minp = {x=v.x - 2, y=bottom, z=v.z - 2}
- local maxp = {x=v.x + 2, y=top, z=v.z + 2}
- dryleaves.replace_leaves(minp, maxp, 5)
- end
- end
- end
- if not cw.registered then
- -- Register the mapgen callback.
- minetest.register_on_generated(function(...)
- cw.generate_realm(...)
- end)
- local c = "cw:core"
- local f = cw.modpath .. "/init.lua"
- reload.register_file(c, f, false)
- cw.registered = true
- end
|