From 695316ea2adc9cab113e5bfa10fc1ddaa5b6a6e1 Mon Sep 17 00:00:00 2001 From: Duane Date: Wed, 29 Jun 2016 12:25:05 -0500 Subject: [PATCH] Add primitive villages. --- mapgen.lua | 9 ++- village.lua | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 186 insertions(+), 2 deletions(-) create mode 100644 village.lua diff --git a/mapgen.lua b/mapgen.lua index 106a9f6..164cc0d 100644 --- a/mapgen.lua +++ b/mapgen.lua @@ -389,7 +389,7 @@ local function generate(p_minp, p_maxp, seed) fun_caves.fortress(minp, maxp, data, area, node) write = true else - local write1, write2, write3, write4, h2 + local write1, write2, write3, write4, write5, h2 write1, h2 = fun_caves.cavegen(minp, maxp, data, area, node, heightmap, underzone) if h2 then heightmap = h2 @@ -405,7 +405,11 @@ local function generate(p_minp, p_maxp, seed) if not write3 then write4, write_p4, true_casket = fun_caves.pyramid(minp, maxp, data, p2data, area, biomemap, biome_ids, node, heightmap) end - write = write1 or write2 or write3 or write4 + if biomemap and not (write3 or write4) then + local biome = biome_ids[biomemap[40*80+40]] + write5 = fun_caves.village(minp, maxp, data, p2data, area, node, biome, heightmap) + end + write = write1 or write2 or write3 or write4 or write5 end @@ -453,6 +457,7 @@ dofile(fun_caves.path .. "/decogen.lua") dofile(fun_caves.path .. "/fortress.lua") dofile(fun_caves.path .. "/pyramid.lua") dofile(fun_caves.path .. "/treegen.lua") +dofile(fun_caves.path .. "/village.lua") dofile(fun_caves.path .. "/skyseagen.lua") diff --git a/village.lua b/village.lua new file mode 100644 index 0000000..06e1463 --- /dev/null +++ b/village.lua @@ -0,0 +1,179 @@ +local function build_hut(data, area, node, pos, turf) + local door = {x = ({2,7})[math.random(2)], z = ({2,7})[math.random(2)]} + if math.random(2) == 1 then + door.x = nil + else + door.z = nil + end + + for z = 1, 8 do + for x = 1, 8 do + local ivm = area:index(pos.x + x - 1, pos.y, pos.z + z - 1) + if x > 1 and x < 8 and z > 1 and z < 8 then + data[ivm] = node['default:dirt'] + ivm = ivm + area.ystride + for y = 2, 4 do + if x == 2 or x == 7 or z == 2 or z == 7 then + if y <= 3 and ((z == 4 and x == door.x) or (x == 4 and z == door.z)) then + data[ivm] = node['air'] + elseif y == 3 and ((z % 3 == 0 and (x == 2 or x == 7)) or (x % 3 == 0 and (z == 2 or z == 7))) then + data[ivm] = node['air'] + else + data[ivm] = node['default:wood'] + end + else + data[ivm] = node['air'] + end + ivm = ivm + area.ystride + end + data[ivm] = node['fun_caves:dry_fiber'] + else + data[ivm] = node[turf] + ivm = ivm + area.ystride + for y = 2, 5 do + data[ivm] = node['air'] + ivm = ivm + area.ystride + end + end + end + end +end + +fun_caves.village = function(minp, maxp, data, p2data, area, node, biome, heightmap) + if not biome or math.random(10) ~= 1 then + return + end + if biome:find('grass') or biome:find('forest') then + turf = 'default:dirt_with_grass' + elseif biome:find('taiga') or biome:find('tundra') then + turf = 'default:dirt_with_snow' + elseif biome:find('savanna') then + turf = 'default:dirt_with_dry_grass' + else + return + end + + local height_avg = 0 + local height_max = -31000 + local height_min = 31000 + for i = 1, #heightmap do + height_avg = height_avg + heightmap[i] + if heightmap[i] > height_max then + height_max = heightmap[i] + end + if heightmap[i] < height_min then + height_min = heightmap[i] + end + end + height_avg = height_avg / #heightmap + + if height_max - height_min > 20 or height_avg < 1 or height_max > maxp.y - 10 or height_min < minp.y + 10 or height_avg < minp.y or height_avg > maxp.y then + return + end + + local write = true + + local plots = {} + for z = 1, 10 do + plots[z] = {} + for x = 1, 10 do + if x == 1 or x == 10 or z == 1 or z == 10 then + -- nop + --elseif (x == 5 or x == 6) and (z == 5 or z == 6) then + -- plots[z][x] = 0 + elseif math.random(5) == 1 and x > 2 and x < 9 and z > 2 and z < 9 then + plots[z][x] = 2 + elseif math.random(2) == 1 then + plots[z][x] = 1 + else + plots[z][x] = 0 + end + end + end + + local index = 0 + for z = minp.z, maxp.z do + local dz = z - minp.z + local pz = math.ceil(dz / 8) + for x = minp.x, maxp.x do + local dx = x - minp.x + local px = math.ceil(dx / 8) + index = index + 1 + + local radius = math.max(math.abs(40 - dx), math.abs(40 - dz)) / 40 + heightmap[index] = math.floor(heightmap[index] * radius ^ 2 + height_avg * (1 - radius ^ 2) + 0.5) + + if radius <= 0.8 + math.random(10) / 100 then + local irrigate + if plots[pz][px] == 1 then + if (dz % 8 == 3 or dz % 8 == 6) and (dx % 8 == 3 or dx % 8 == 6) then + irrigate = true + end + end + + local ivm = area:index(x, minp.y, z) + for y = minp.y, maxp.y do + local dy = y - minp.y + + if y > heightmap[index] and y < 1 then + data[ivm] = node['default:water_source'] + elseif y == heightmap[index] + 1 and plots[pz][px] == 1 and not irrigate then + if turf == 'default:dirt_with_snow' then + if math.random(10) == 1 then + data[ivm] = node['default:dry_shrub'] + end + else + data[ivm] = node['farming:wheat_'..math.random(7)] + end + elseif y > heightmap[index] then + data[ivm] = node['air'] + elseif y == heightmap[index] and plots[pz][px] == 1 and irrigate then + if turf == 'default:dirt_with_snow' then + data[ivm] = node['default:ice'] + else + data[ivm] = node['default:water_source'] + end + elseif y == heightmap[index] and plots[pz][px] == 1 then + if turf == 'default:dirt_with_snow' then + data[ivm] = node[turf] + else + data[ivm] = node['farming:soil_wet'] + end + elseif y == heightmap[index] then + data[ivm] = node[turf] + elseif y > heightmap[index] - 4 then + data[ivm] = node['default:dirt'] + elseif y > heightmap[index] - 10 then + data[ivm] = node['default:stone'] + end + + ivm = ivm + area.ystride + end + end + end + end + + for z = 1, 10 do + for x = 1, 10 do + if plots[z][x] == 2 then + local pos = { + x = (x - 1) * 8 + 1, + z = (z - 1) * 8 + 1, + } + local avg = 0 + for hz = pos.z, pos.z + 7 do + for hx = pos.x, pos.x + 7 do + avg = avg + heightmap[(hz - 1) * 80 + hx] + end + end + pos.y = math.floor(avg / 64 + 0.5) + pos.x = pos.x + minp.x + pos.z = pos.z + minp.z + build_hut(data, area, node, pos, turf) + end + end + end + + -- -702, -466 + return write +end