diff --git a/README.md b/README.md new file mode 100644 index 0000000..652420b --- /dev/null +++ b/README.md @@ -0,0 +1,26 @@ +amgmt +===== + +Another Map Generator mod for Minetest (fork from amg) + +Still experimental! + + +##Feature +- 12 biome +- Biomes, Trees, Nodes, etc. are modifyable +- Experimental water lakes! + +##List of Biomes +- Ice Plains +- Ice Plains Spikes +- Cold Taiga +- Stone Plain +- Extreme Hills +- Taiga +- Plains +- Flower Plains +- River +- Forest +- Savanna +- Desert diff --git a/biome.lua b/biome.lua new file mode 100644 index 0000000..faeedfa --- /dev/null +++ b/biome.lua @@ -0,0 +1,350 @@ +biome = biome or {} +local gci = minetest.get_content_id +local badd = biome.add + +-- node id? +local c_air = gci("air") +local c_water = gci("default:water_source") +local c_ice = gci("default:ice") +local c_stone = gci("default:stone") +local c_dirt = gci("default:dirt") +local c_dirt_grass = gci("default:dirt_with_grass") +local c_dirt_snow = gci("default:dirt_with_snow") +local c_sand = gci("default:sand") +local c_sandstone = gci("default:sandstone") + +local c_dirt_savanna = gci("amgmt:dirt_at_savanna") + +--listing biome from cold to hot +-- cold +badd({ + name = "Ice Plains", + mint = 0, + maxt = 0.2, + minh = 0, + maxh = 50, + trees = {{"pine",225}}, + get_block = function(temp, humi, base, wl, y) + if y > base and y > wl then + return c_air + elseif y > base and y <= wl then + if base < wl - 1 then + return c_water + elseif base < wl then + return c_ice + elseif base >= wl then + return c_air + end + elseif y < base - 2 then + return c_stone + elseif y < base and y > base - 3 then + return c_dirt + else + if y < wl then + return c_dirt + else + return c_dirt_snow + end + end + end +}) +badd({ + name = "Ice Plains Spikes", + mint = 0, + maxt = 0.2, + minh = 50, + maxh = 100, + trees = {{"ice_spike",25}}, + get_block = function(temp, humi, base, wl, y) + if y > base and y > wl then + return c_air + elseif y > base and y <= wl then + if base < wl - 1 then + return c_water + elseif base < wl then + return c_ice + elseif base >= wl then + return c_air + end + elseif y < base - 2 then + return c_stone + elseif y < base and y > base - 3 then + return c_dirt + else + if y < wl then + return c_dirt + else + return c_dirt_snow + end + end + end +}) +badd({ + name = "Cold Taiga", + mint = 0.2, + maxt = 0.4, + trees = {{"pine_cold",25}}, + get_block = function(temp, humi, base, wl, y) + if y > base and y > wl then + return c_air + elseif y > base and y <= wl then + if base < wl - 1 then + return c_water + elseif base < wl then + return c_ice + elseif base >= wl then + return c_air + end + elseif y < base - 2 then + return c_stone + elseif y < base and y > base - 3 then + return c_dirt + else + if y < wl then + return c_dirt + else + return c_dirt_snow + end + end + end +}) +badd({ + name = "Stone Plain", + mint = 0.4, + maxt = 0.5, + get_block = function(temp, humi, base, wl, y) + if y > base and y > wl then + return c_air + elseif y > base and y <= wl then + if base < wl then + return c_water + elseif base >= wl then + return c_air + end + elseif y <= base then + return c_stone + end + end +}) +badd({ + name = "Extreme Hills", + mint = 0.5, + maxt = 0.7, + trees = {{"grass14",30}}, + get_block = function(temp, humi, base_, wl, y) + local base = base_ + math.ceil(math.abs(base_ - wl) * 2/5) + if y > base and y > wl then + return c_air + elseif y > base and y <= wl then + if base < wl then + return c_water + elseif base >= wl then + return c_air + end + elseif y < base - 2 then + return c_stone + elseif y < base and y > base - 3 then + return c_dirt + else + if y < wl then + return c_dirt + elseif y >= 95 then + return c_dirt_snow + else + return c_dirt_grass + end + end + end +}) +badd({ + name = "Taiga", + mint = 0.7, + maxt = 0.9, + trees = {{"pine_taiga",25}}, + get_block = function(temp, humi, base, wl, y) + if y > base and y > wl then + return c_air + elseif y > base and y <= wl then + if base < wl then + return c_water + elseif base >= wl then + return c_air + end + elseif y < base - 2 then + return c_stone + elseif y < base and y > base - 3 then + return c_dirt + else + if y < wl then + return c_dirt + else + return c_dirt_grass + end + end + end +}) +-- medium/lush +badd({ + name = "Plains", + mint = 0.9, + maxt = 1.15, + minh = 0, + maxh = 50, + trees = {{"grass14",30}, {"grass35",5},{"papyrus",15},{"flowers",15}}, + get_block = function(temp, humi, base, wl, y) + if y > base and y > wl then + return c_air + elseif y > base and y <= wl then + if base < wl then + return c_water + elseif base >= wl then + return c_air + end + elseif y < base - 2 then + return c_stone + elseif y < base and y > base - 3 then + return c_dirt + else + if y < wl then + return c_dirt + else + if temp > 1 and (base == wl or base == wl+1) then + return c_sand + else + return c_dirt_grass + end + end + end + end +}) +badd({ + name = "Flower Plains", + mint = 0.9, + maxt = 1.15, + minh = 50, + maxh = 100, + trees = {{"flowers",5},{"flowers",5},{"flowers",5}}, + get_block = function(temp, humi, base, wl, y) + if y > base and y > wl then + return c_air + elseif y > base and y <= wl then + if base < wl then + return c_water + elseif base >= wl then + return c_air + end + elseif y < base - 2 then + return c_stone + elseif y < base and y > base - 3 then + return c_dirt + else + if y < wl then + return c_dirt + else + return c_dirt_grass + end + end + end +}) +badd({ + name = "River", + mint = 1.15, + maxt = 1.25, + get_block = function(temp, humi, base_, wl, y) + local base = wl - math.ceil(math.abs(base_ - wl) * 1/3) - 1 + if y > base and y > wl then + return c_air + elseif y > base and y <= wl then + return c_water + elseif y < base - 2 then + return c_stone + elseif y < base and y > base - 3 then + return c_sandstone + else + return c_sand + end + end +}) +badd({ + name = "Forest", + mint = 1.25, + maxt = 1.5, + trees = {{"normal",15},{"grass14",60},{"grass35",5},{"papyrus",15},{"flowers",15}}, + get_block = function(temp, humi, base, wl, y) + if y > base and y > wl then + return c_air + elseif y > base and y <= wl then + if base < wl then + return c_water + elseif base >= wl then + return c_air + end + elseif y < base - 2 then + return c_stone + elseif y < base and y > base - 3 then + return c_dirt + else + if y < wl then + return c_dirt + else + return c_dirt_grass + end + end + end +}) +-- dry +badd({ + name = "Savanna", + mint = 1.5, + maxt = 1.75, + trees = {{"savanna",225},{"grass35",5}}, + get_block = function(temp, humi, base, wl, y) + if y > base and y > wl then + return c_air + elseif y > base and y <= wl then + if base < wl then + return c_water + elseif base >= wl then + return c_air + end + elseif y < base - 2 then + return c_stone + elseif y < base and y > base - 3 then + return c_dirt + else + if y < wl then + return c_dirt + else + if temp > 1.7 and base == wl then + return c_sand + else + return c_dirt_savanna + end + end + end + end +}) +-- hot +badd({ + name = "Desert", + mint = 1.75, + maxt = 2, + trees = {{"cactus",50},{"dry_shrub",50}}, + get_block = function(temp, humi, base, wl, y) + if y > base and y > wl then + return c_air + elseif y > base and y <= wl then + if base < wl then + return c_water + elseif base >= wl then + return c_air + end + elseif y < base - 2 then + return c_sandstone + elseif y < base and y > base - 3 then + return c_sand + else + return c_sand + end + end +}) \ No newline at end of file diff --git a/biomemgr.lua b/biomemgr.lua new file mode 100644 index 0000000..01fff3f --- /dev/null +++ b/biomemgr.lua @@ -0,0 +1,52 @@ +biome = biome or {} + +biome.list = {} +function biome.add(p) + biome.list[#biome.list+1] = { + name = p.name, + mint = p.mint, -- min temperature + maxt = p.maxt, -- max + minh = p.minh or 0, -- min humidity + maxh = p.maxh or 100, -- max + trees = p.trees or {{"nil",1024}}, + get_block = p.get_block + } +end + +-- testing purpose only! +biome.add({ + name = "NIL (Biome?)", + mint = -5, + maxt = -3, + get_block = function() return minetest.get_content_id("air") end +}) +--]] + +function biome.get_by_temp_humi(t,h) + t = math.min(t, 2) + h = math.min(h, 100) + local bl = biome.list + local found = {} + for i = 1, #bl do + if t >= bl[i].mint and t <= bl[i].maxt then + found[#found+1] = {i,bl[i].name} + end + end + for i = 1, #found do + local u = found[i][1] + local o = found[i][2] + if h >= bl[u].minh and h <= bl[u].maxh then + return {u,bl[u].name} + end + end + return {0,"NIL (Biome?)"} +end + +function biome.get_block_by_temp_humi(temp,humi,base,wl,y,x,z) + temp = math.min(temp, 2) + humi = math.min(humi, 100) + base = math.min(base, 255) + return biome.list[biome.get_by_temp_humi(temp,humi)[1]].get_block(temp,humi,base,wl,y,x,z) or 0 +end + +dofile(minetest.get_modpath(minetest.get_current_modname()).."/biome.lua") \ No newline at end of file diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..df07aca --- /dev/null +++ b/depends.txt @@ -0,0 +1,2 @@ +default +flowers \ No newline at end of file diff --git a/hud.lua b/hud.lua new file mode 100644 index 0000000..1ed091d --- /dev/null +++ b/hud.lua @@ -0,0 +1,52 @@ +amgmt.hud = {} + +local bedrock_timer = 0 +minetest.register_globalstep(function(dtime) + if dtime < 0.1 then return end + for _,player in ipairs(minetest.get_connected_players()) do + local pos = player:getpos() + local name = player:get_player_name() + + local base = minetest.get_perlin(np.b.s, np.b.o, np.b.p, np.b.c):get2d({x=pos.x,y=pos.z}) + local moun = minetest.get_perlin(np.m.s, np.m.o, np.m.p, np.m.c):get2d({x=pos.x,y=pos.z}) + local base = math.ceil((base * -30) + wl + 10 + (moun * 15)) + local temp = 0 + local humi = 0 + if base > 95 then + temp = 0.05 + humi = 0.9 + else + temp = minetest.get_perlin(np.t.s, np.t.o, np.t.p, np.t.c):get2d({x=pos.x,y=pos.z}) + humi = minetest.get_perlin(np.h.s, np.h.o, np.h.p, np.h.c):get2d({x=pos.x,y=pos.z}) + end + + local biometext = biome.get_by_temp_humi(math.abs(temp*2),math.abs(humi*100))[2] + + if not amgmt.hud[name] then + amgmt.hud[name] = {} + + amgmt.hud[name].BiomeId = player:hud_add({ + hud_elem_type = "text", + name = "Biome", + number = 0xFFFFFF, + position = {x=0, y=0.5}, + offset = {x=13, y=-20}, + direction = 0, + text = "Biome: "..biometext, + scale = {x=200, y=-60}, + alignment = {x=1, y=1}, + }) + + amgmt.hud[name].oldBiome = biometext + return + elseif amgmt.hud[name].oldBiome ~= biometext then + player:hud_change(amgmt.hud[name].BiomeId, "text", + "Biome: "..biometext) + amgmt.hud[name].oldBiome = biometext + end + end +end) + +minetest.register_on_leaveplayer(function(player) + amgmt.hud[player:get_player_name()] = nil +end) \ No newline at end of file diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..9b8786a --- /dev/null +++ b/init.lua @@ -0,0 +1,226 @@ +amgmt = amgmt or {} +amgmt.seed = nil + +minetest.register_on_mapgen_init(function(mgparams) + minetest.set_mapgen_params({mgname="singlenode"}) + amgmt.seed = mgparams.seed +end) + +--param? +wl = 0 +HMAX = 300 +HMIN = -6000 +BEDROCK = -5000 +BEDROCK2 = -6000 + +biome = {} +tree = {} +dofile(minetest.get_modpath(minetest.get_current_modname()).."/nodes.lua") +dofile(minetest.get_modpath(minetest.get_current_modname()).."/trees.lua") +dofile(minetest.get_modpath(minetest.get_current_modname()).."/biomemgr.lua") + +local function get_perlin_map(seed, octaves, persistance, scale, minp, maxp) + local sidelen = maxp.x - minp.x +1 + local pm = minetest.get_perlin_map( + {offset=0, scale=1, spread={x=scale, y=scale, z=scale}, seed=seed, octaves=octaves, persist=persistance}, + {x=sidelen, y=sidelen, z=sidelen} + ) + return pm:get2dMap_flat({x = minp.x, y = minp.z, z = 0}) +end + +-- noiseparam +np = { +-- s = seed, o = octaves, p = persistance, c = scale + b = {s = 1234, o = 6, p = 0.5, c = 512}, + m = {s = 4321, o = 6, p = 0.5, c = 256}, + t = {s = 5678, o = 7, p = 0.5, c = 512}, + h = {s = 8765, o = 7, p = 0.5, c = 512}, + s1 = {s = 125, o = 6, p = 0.5, c = 256}, +} + +--node id? +local gci = minetest.get_content_id +local c_air = gci("air") +local c_bedrock = gci("amgmt:bedrock") +local c_sand = gci("default:sand") +local c_sandstone = gci("default:sandstone") +local c_water = gci("default:water_source") +local c_lava_source = gci("default:lava_source") + +local function amgmt_generate(minp, maxp, seed, vm, emin, emax) + local t1 = os.clock() + local pr = PseudoRandom(seed) + print("[amgmt]:"..minp.x..","..minp.y..","..minp.z) + local area = VoxelArea:new{ + MinEdge={x=emin.x, y=emin.y, z=emin.z}, + MaxEdge={x=emax.x, y=emax.y, z=emax.z}, + } + local data = vm:get_data() + local sidelen = maxp.x - minp.x + 1 + local base = get_perlin_map(np.b.s, np.b.o, np.b.p, np.b.c, minp, maxp) -- base height + local moun = get_perlin_map(np.m.s, np.m.o, np.m.p, np.m.c, minp, maxp) -- addition + local temp = get_perlin_map(np.t.s, np.t.o, np.t.p, np.t.c, minp, maxp) -- temperature (0-2) + local humi = get_perlin_map(np.h.s, np.h.o, np.h.p, np.h.c, minp, maxp) -- humidity (0-100) + local spc1 = get_perlin_map(np.h.s, np.h.o, np.h.p, np.h.c, minp, maxp) -- special1 + local cave = minetest.get_perlin(3456, 6, 0.5, 360) -- cave + --local laca = minetest.get_perlin(1278, 6, 0.5, 360) -- lava cave + print("[amgmt]:terrain generation") + local nizx = 0 + for z = minp.z, maxp.z do + for x = minp.x, maxp.x do + nizx = nizx + 1 + local base_ = math.ceil((base[nizx] * -50) + wl + 16.67 + (moun[nizx] * 15)) + local temp_ = 0 + local humi_ = 0 + if base_ > 95 then + temp_ = 0.10 + humi_ = 90 + else + temp_ = math.abs(temp[nizx] * 2) + humi_ = math.abs(humi[nizx] * 100) + end + --print(x..","..z.." : "..temp_) + for y_ = minp.y, maxp.y do + local vi = area:index(x,y_,z) + -- world height limit :( + if y_ < HMIN or y_ > HMAX then + data[vi] = c_air + elseif y_ == BEDROCK or y_ == BEDROCK2 then + data[vi] = c_bedrock + -- + -- cave + elseif math.abs(cave:get3d({x=x,y=y_,z=z})) < 0.005 then + data[vi] = c_air + --]] + --[[ + -- lava cave + elseif math.abs(laca:get3d({x=x,y=y_,z=z})) > 350 and y_ < wl * 2/3 then + data[vi] = c_lava_source + --]] + -- biome + else + data[vi] = c_air + --data[vi] = biome.get_block_by_temp_humi(temp_, humi_, base_, wl, y_, x, z) + end + end + + end + end + + --forming lake + print("[amgmt]:forming lake") + local found_lake = false + local chulen = (maxp.x - minp.x + 1) / 16 + for cz = 0, chulen-1 do + for cx = 0, chulen-1 do + local nizx = 0 + for z = minp.z + cz*16, minp.z + (cz+1)*16 do + if found_lake == true then break end + for x = minp.x + cx*16, minp.x + (cx+1)*16 do + if found_lake == true then break end + nizx = nizx + 1 + local base_ = math.ceil((base[nizx] * -50) + wl + 16.67 + (moun[nizx] * 15)) + local lake_ = math.abs(spc1[nizx]) + if lake_ < 0.001 then + print("[amgmt] lake found! "..x..","..base_..","..z.."("..lake_..")") + found_lake = true + for u = -2, 2 do + for i = -2, 2 do + local vi = area:index(x+u,base_-2,z+i) + data[vi] = c_sandstone + for o = -1, 0 do + local vi = area:index(x+u,base_+o,z+i) + if u > -2 and u < 2 and i > -2 and i < 2 and o == 0 then + data[vi] = c_water + else + data[vi] = c_sand + end + end + end + end + + for ii = 1, 10 do + local xx = pr:next(-1,1) + local zz = pr:next(-1,1) + + local vi = area:index(x+xx,base_-1,z+zz) + data[vi] = c_water + end + end + end + end + end + end + + --ore generation + --print("[amgmt]:generating ore") + + --tree planting + print("[amgmt]:planting tree") + local nizx = 0 + for z = minp.z, maxp.z do + for x = minp.x, maxp.x do + nizx = nizx + 1 + local base_ = math.ceil((base[nizx] * -50) + wl + 16.67 + (moun[nizx] * 15)) + local temp_ = 0 + local humi_ = 0 + if base_ > 95 then + temp_ = 0.10 + humi_ = 90 + else + temp_ = math.abs(temp[nizx] * 2) + humi_ = math.abs(humi[nizx] * 100) + end + local biome__ = biome.list[biome.get_by_temp_humi(temp_,humi_)[1]] + local tr = biome__.trees + local filled = false + --print("done. "..biome__.name.." Biome. spawning "..#tr.." type of floras ...") + for i = 1, #tr do + if filled == true then break end + local tri = tree.registered[tr[i][1]] or tree.registered["nil"] + local chance = tr[i][2] or 1024 + --[[ + print( + "try to spawn "..tr[i][1].. + " at "..x..","..(base_+1)..","..z.. + " in "..biome__.name.." biome" + ) + --]] + if + pr:next(1,chance) == 1 and + base_+1 >= tri.minh and base_+1 <= tri.maxh and + data[area:index(x,base_,z)] == gci(tri.grows_on) + then + tree.spawn({x=x,y=base_+1,z=z},tr[i][1],data,area,seed,minp,maxp,pr) + filled = true + --[[ + print( + "spawned "..tr[i][1].. + " at "..x..","..(base_+1)..","..z.. + " in "..biome__.name.." biome" + ) + --]] + end + end + end + end + + print("[amgmt]:applying map data") + vm:set_data(data) + vm:set_lighting({day=0, night=0}) + vm:update_liquids() + vm:calc_lighting() + vm:write_to_map(data) + local chugent = math.ceil((os.clock() - t1) * 100000)/100 + print("[amgmt]:Done in "..chugent.."ms") +end + +minetest.register_on_generated(function(minp, maxp, seed) + if minp.y > HMAX or maxp.y < HMIN then return end + local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") + amgmt_generate(minp, maxp, seed, vm, emin, emax) +end) + +dofile(minetest.get_modpath(minetest.get_current_modname()).."/hud.lua") + +print("[amgmt] (Another Map Generator for Minetest) Loaded") \ No newline at end of file diff --git a/nodes.lua b/nodes.lua new file mode 100644 index 0000000..49151d9 --- /dev/null +++ b/nodes.lua @@ -0,0 +1,17 @@ +minetest.register_node("amgmt:bedrock", { + description = "amgmt's BEDROCK", + tiles ={"default_cobble.png"}, + groups = {unbreakable = 1, not_in_creative_inventory = 1}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("amgmt:dirt_at_savanna", { + description = "Dirt with Grass at Savanna", + tiles = {"amgmt_savanna_grass.png", "default_dirt.png", "default_dirt.png^amgmt_savanna_grass_side.png"}, + is_ground_content = true, + groups = {crumbly=3,soil=1}, + drop = 'default:dirt', + sounds = default.node_sound_dirt_defaults({ + footstep = {name="default_grass_footstep", gain=0.25}, + }), +}) \ No newline at end of file diff --git a/textures/amgmt_savanna_grass.png b/textures/amgmt_savanna_grass.png new file mode 100644 index 0000000..a43fda0 Binary files /dev/null and b/textures/amgmt_savanna_grass.png differ diff --git a/textures/amgmt_savanna_grass_side.png b/textures/amgmt_savanna_grass_side.png new file mode 100644 index 0000000..a5c53a3 Binary files /dev/null and b/textures/amgmt_savanna_grass_side.png differ diff --git a/trees.lua b/trees.lua new file mode 100644 index 0000000..dd39382 --- /dev/null +++ b/trees.lua @@ -0,0 +1,365 @@ +tree = tree or {} +tree.registered = {} + +function tree.spawn(pos,name,data,area,seed,minp,maxp,pr) + tree.registered[name].grow(pos, data, area, seed, minp, maxp, pr) +end + +function tree.register(def) + tree.registered[def.name] = { + chance = def.chance or 1024, + minh = def.minh or 0, + maxh = def.maxh or HMAX, + grows_on = def.grows_on or "default:dirt_with_grass", + grow = def.grow or function() return nil end + } +end + +tree.register({ + name = "nil", + grow = function() end +}) + +--node id? +local gci = minetest.get_content_id +local c_air = gci("air") +local c_ignore = gci("ignore") +local c_tree = gci("default:tree") +local c_leaves = gci("default:leaves") +local c_snow = gci("default:snow") + +--add leaves function +local function add_leaves(data, vi, c_leaf, other) + local other = other or c_leaf + if data[vi]==c_air or data[vi]==c_ignore or data[vi] == other then + data[vi] = c_leaf + end +end + +--normal tree +tree.register({ + name = "normal", + chance = 15, + minh = 1, + maxh = 85, + grows_on = "default:dirt_with_grass", + grow = function(pos, data, area, seed, minp, maxp, pr) + local x, y, z = pos.x, pos.y, pos.z + local th = pr:next(4,5) + + for yy = math.max(y,minp.y), math.min(y+th,maxp.y) do + local vi = area:index(x, yy, z) + data[vi] = c_tree + end + + local y = y + th - 1 + + for xx = math.max(x-1,minp.x), math.min(x+1,maxp.x) do + for yy = math.max(y-1,minp.y), math.min(y+1,maxp.y) do + for zz = math.max(z-1,minp.z), math.min(z+1,maxp.z) do + local vi = area:index(xx, yy, zz) + add_leaves(data, vi, c_leaves) + end + end + end + + for ii = 1, 8 do + local xx = x + pr:next(-2,2) + local yy = y + pr:next(-2,2) + local zz = z + pr:next(-2,2) + local vi = area:index(xx, yy, zz) + add_leaves(data, vi, c_leaves, c_leaves) + end + + --print("normal tree spawned at:"..x..","..y..","..z) + end +}) + +--savanna tree +tree.register({ + name = "savanna", + chance = 225, + minh = 1, + maxh = 85, + grows_on = "amgmt:dirt_at_savanna", + grow = function(pos, data, area, seed, minp, maxp, pr) + local x, y, z = pos.x, pos.y, pos.z + local th = pr:next(7,11) + + for yy = math.max(y,minp.y), math.min(y+th,maxp.y) do + local vi = area:index(x, yy, z) + data[vi] = c_tree + end + y = y+th-1 + + for xx = math.max(x-1,minp.x), math.min(x+1,maxp.x) do + for yy = math.max(y-1,minp.y), math.min(y+1,maxp.y) do + for zz = math.max(z-1,minp.z), math.min(z+1,maxp.z) do + local vi = area:index(xx, yy, zz) + add_leaves(data, vi, c_leaves) + end + end + end + + for ii = 1, 12 do + local xx = x + pr:next(-2,2) + local yy = y + pr:next(-2,2) + local zz = z + pr:next(-2,2) + + local vi = area:index(xx, yy, zz) + add_leaves(data, vi, c_leaves, c_leaves) + end + + --print("savanna tree spawned at:"..x..","..y..","..z) + end +}) + +--pine tree at cold taiga +tree.register({ + name = "pine_cold", + chance = 40, + minh = 1, + maxh = 100, + grows_on = "default:dirt_with_snow", + grow = function(pos, data, area, seed, minp, maxp, pr) + local x, y, z = pos.x, pos.y, pos.z + local th = pr:next(5,8) + + for yy = math.max(y,minp.y), math.min(y+th,maxp.y) do + local vi = area:index(x, yy, z) + data[vi] = c_tree + end + + for xx = math.max(x-2,minp.x), math.min(x+2,maxp.x) do + for zz = math.max(z-2,minp.z), math.min(z+2,maxp.z) do + local vi = area:index(xx, y+3, zz) + add_leaves(data, vi, c_leaves) + local vi = area:index(xx, y+4, zz) + add_leaves(data, vi, c_snow) + end + end + + local vi = area:index(x, y+th+1, z) + add_leaves(data, vi, c_leaves) + local vi = area:index(x, y+th+2, z) + add_leaves(data, vi, c_snow) + + for xx = math.max(x-1,minp.x), math.min(x+1,maxp.x) do + for zz = math.max(z-1,minp.z), math.min(z+1,maxp.z) do + local vi = area:index(xx, y+th, zz) + add_leaves(data, vi, c_leaves) + local vi = area:index(xx, y+th+1, zz) + add_leaves(data, vi, c_snow) + end + end + + --print("pine tree spawned at:"..x..","..y..","..z) + end +}) + +--pine tree at taiga +tree.register({ + name = "pine_taiga", + chance = 40, + minh = 1, + maxh = 100, + grows_on = "default:dirt_with_grass", + grow = function(pos, data, area, seed, minp, maxp, pr) + local x, y, z = pos.x, pos.y, pos.z + local th = pr:next(5,8) + + for yy = math.max(y,minp.y), math.min(y+th,maxp.y) do + local vi = area:index(x, yy, z) + data[vi] = c_tree + end + + for xx = math.max(x-2,minp.x), math.min(x+2,maxp.x) do + for zz = math.max(z-2,minp.z), math.min(z+2,maxp.z) do + local vi = area:index(xx, y+3, zz) + add_leaves(data, vi, c_leaves) + end + end + + for xx = math.max(x-1,minp.x), math.min(x+1,maxp.x) do + for zz = math.max(z-1,minp.z), math.min(z+1,maxp.z) do + local vi = area:index(xx, y+th, zz) + add_leaves(data, vi, c_leaves) + end + end + + local vi = area:index(x, y+th+1, z) + add_leaves(data, vi, c_leaves) + + --print("pine tree spawned at:"..x..","..y..","..z) + end +}) + +--decoration + +local c_cactus = gci("default:cactus") +local c_dry_shrub = gci("default:dry_shrub") +local c_papyrus = gci("default:papyrus") +local c_grass_1 = gci("default:grass_1") +local c_grass_2 = gci("default:grass_2") +local c_grass_3 = gci("default:grass_3") +local c_grass_4 = gci("default:grass_4") +local c_grass_5 = gci("default:grass_5") +local c_grasses = {c_grass_1, c_grass_2, c_grass_3, c_grass_4, c_grass_5} + +--dry shrub +tree.register({ + name = "dry_shrub", + chance = 50, + minh = 1, + maxh = 90, + grows_on = "default:sand", + grow = function(pos, data, area, seed, minp, maxp, pr) + local x, y, z = pos.x, pos.y, pos.z + local vi = area:index(x, y, z) + if data[vi] == c_air or data[vi] == c_ignore then + data[vi] = c_dry_shrub + end + + --print("dry shrub spawned at:"..x..","..y..","..z) + end +}) + +--cactus +tree.register({ + name = "cactus", + chance = 50, + minh = 1, + maxh = 90, + grows_on = "default:sand", + grow = function(pos, data, area, seed, minp, maxp, pr) + local x, y, z = pos.x, pos.y, pos.z + for yy = math.max(y,minp.y), math.min(y+pr:next(1,4),maxp.y) do + data[area:index(x, yy, z)] = c_cactus + end + + --print("cactus spawned at:"..x..","..y..","..z) + end +}) + +--papyrus +tree.register({ + name = "papyrus", + chance = 10, + minh = wl+1, + maxh = wl+1, + grows_on = "default:dirt_with_grass", + grow = function(pos, data, area, seed, minp, maxp, pr) + local x, y, z = pos.x, pos.y, pos.z + for yy = math.max(y,minp.y), math.min(y+pr:next(2,4),maxp.y) do + data[area:index(x, yy, z)] = c_papyrus + end + + --print("papyrus spawned at:"..x..","..y..","..z) + end +}) + +--grass 1-4 +tree.register({ + name = "grass14", + chance = 60, + minh = 1, + maxh = 105, + grows_on = "default:dirt_with_grass", + grow = function(pos, data, area, seed, minp, maxp, pr) + local x, y, z = pos.x, pos.y, pos.z + local vi = area:index(x, y, z) + if data[vi] == c_air or data[vi] == c_ignore then + data[vi] = c_grasses[pr:next(1,4)] + end + + --print("grass spawned at:"..x..","..y..","..z) + end +}) + +--grass 3-5 +tree.register({ + name = "grass35", + chance = 5, + minh = 4, + maxh = 105, + grows_on = "default:dirt_with_grass", + grow = function(pos, data, area, seed, minp, maxp, pr) + local x, y, z = pos.x, pos.y, pos.z + local vi = area:index(x, y, z) + if data[vi] == c_air or data[vi] == c_ignore then + data[vi] = c_grasses[pr:next(3,5)] + end + + --print("grass spawned at:"..x..","..y..","..z) + end +}) + + +local c_dandelion_white = gci("flowers:dandelion_white") +local c_dandelion_yellow = gci("flowers:dandelion_yellow") +local c_geranium = gci("flowers:geranium") +local c_rose = gci("flowers:rose") +local c_tulip = gci("flowers:tulip") +local c_viola = gci("flowers:viola") +local c_flowers = {c_dandelion_white, c_dandelion_yellow, c_geranium, c_rose, c_tulip, c_viola} + +--flower +tree.register({ + name = "flowers", + chance = 3, + minh = 4, + maxh = 90, + grows_on = "default:dirt_with_grass", + grow = function(pos, data, area, seed, minp, maxp, pr) + local x, y, z = pos.x, pos.y, pos.z + local vi = area:index(x, y, z) + if data[vi] == c_air or data[vi] == c_ignore then + data[vi] = c_flowers[pr:next(1,6)] + end + + --print("flowers spawned at:"..x..","..y..","..z) + end +}) + +local c_ice = gci("default:ice") + +--ice spikes +tree.register({ + name = "ice_spike", + chance = 25, + minh = 4, + maxh = 120, + grows_on = "default:dirt_with_snow", + grow = function(pos, data, area, seed, minp, maxp, pr) + local x, y, z = pos.x, pos.y, pos.z + local vi = area:index(x, y, z) + if data[vi] == c_air or data[vi] == c_ignore then + local h = pr:next(4,7) + for u = -1, 1 do + for i = -1, 1 do + for o = 0, h do + if data[area:index(x+u, y-1, z+i)] == c_dirt_with_snow then + local vi = area:index(x+u, y+o, z+i) + data[vi] = c_ice + end + end + end + end + j = h + pr:next(2,3) + for u = 0, 1 do + for i = -1, 0 do + for o = h, j do + if data[area:index(x+u, y-1, z+i)] == c_dirt_with_snow then + local vi = area:index(x+u, y+o, z+i) + data[vi] = c_ice + end + end + end + end + local vi = area:index(x, y+j, z) + data[vi] = c_ice + end + + --print("ice spikes spawned at:"..x..","..y..","..z) + end +}) \ No newline at end of file