diff --git a/buildings.lua b/buildings.lua index 586da08..f430a8a 100644 --- a/buildings.lua +++ b/buildings.lua @@ -54,6 +54,85 @@ function settlements.build_schematic(pos, building, replace_wall, name) end) end -- +-- placing buildings within lvm +-- +function settlements.place_settlement_lvm(data, va, minp, maxp) + -- find center of chunk + local center = { + x=maxp.x-half_map_chunk_size, + y=maxp.y-half_map_chunk_size, + z=maxp.z-half_map_chunk_size + } + -- find center_surcafe of chunk + local center_surface = settlements.find_surface_lvm(center, data, va) + -- go build settlement around center + if center_surface then + -- add settlement to list + table.insert(settlements_in_world, + center_surface) + -- save list to file + settlements.save() + -- initialize all settlement information + settlements.initialize_settlement() + -- build well in the center + building_all_info = schematic_table[1] + settlements.build_schematic(center_surface, + building_all_info["mts"], + building_all_info["rplc"], + building_all_info["name"]) + -- add to settlement info table + local index = 1 + settlement_info[index] = {pos = center_surface, + name = building_all_info["name"], + hsize = building_all_info["hsize"]} + --increase index for following buildings + index = index + 1 + -- now some buildings around in a circle, radius = size of town center + local x, z, r = center_surface.x, center_surface.z, building_all_info["hsize"] + -- draw j circles around center and increase radius by math.random(2,5) + for j = 1,20 do + if number_built < number_of_buildings then + -- set position on imaginary circle + for j = 0, 360, 15 do + local angle = j * math.pi / 180 + local ptx, ptz = x + r * math.cos( angle ), z + r * math.sin( angle ) + local pos1 = { x=ptx, y=center_surface.y, z=ptz} + -- + local pos_surface = settlements.find_surface(pos1) + if pos_surface + then + if settlements.pick_next_building(pos_surface) + then + settlements.build_schematic(pos_surface, + building_all_info["mts"], + building_all_info["rplc"], + building_all_info["name"]) + number_built = number_built + 1 + settlement_info[index] = {pos = pos_surface, + name = building_all_info["name"], + hsize = building_all_info["hsize"]} + index = index + 1 + if number_of_buildings == number_built + then + break + end + end + else + break + end + end + r = r + math.random(2,5) + end + end + if settlements.debug == true + then + minetest.chat_send_all("really ".. number_built) + end + minetest.after(2, settlements.paths) +-- settlements.paths() + end +end +-- -- placing buildings in circles around center -- function settlements.place_settlement_circle(minp, maxp) diff --git a/const.lua b/const.lua index 70ad1e9..50d97e8 100644 --- a/const.lua +++ b/const.lua @@ -35,18 +35,6 @@ schematic_table = { {name = "blacksmith", mts = schem_path.."blacksmith.mts", hsize = 11, max_num = 0.050, rplc = "n"}, } -- --- baseplate material, to replace dirt with grass and where buildings can be built --- -surface_mat = { - "default:dirt_with_grass", - "default:dirt_with_snow", - "default:dirt_with_dry_grass", - "default:dirt_with_coniferous_litter", - "default:sand", - "default:desert_sand", --- "default:snow" -} --- -- temporary info for currentliy built settlement (position of each building) -- settlement_info = {} diff --git a/init.lua b/init.lua index baf131f..1b78a96 100644 --- a/init.lua +++ b/init.lua @@ -72,9 +72,14 @@ minetest.register_on_generated(function(minp, maxp) return end -- + -- get LVM of current chunk + -- + local vm, data, va, emin, emax = settlements.getlvm(minp, maxp) + -- -- don't build settlements on (too) uneven terrain -- local height_difference = settlements.evaluate_heightmap(minp, maxp) +-- local height_difference = settlements.determine_heightmap(data, va, minp, maxp) if height_difference > max_height_difference then return @@ -82,7 +87,8 @@ minetest.register_on_generated(function(minp, maxp) -- -- if nothing prevents the settlement -> do it -- - settlements.place_settlement_circle(minp, maxp) + --settlements.place_settlement_circle(minp, maxp) + settlements.place_settlement_lvm(data, va, minp, maxp) end end) @@ -130,7 +136,11 @@ minetest.register_craftitem("settlements:tool", { y=center_surface.y+half_map_chunk_size, z=center_surface.z+half_map_chunk_size } - settlements.place_settlement_circle(minp, maxp) + -- + -- get LVM of current chunk + -- + local vm, data, va, emin, emax = settlements.getlvm(minp, maxp) + settlements.place_settlement_lvm(data, va, minp, maxp) end end }) diff --git a/utils.lua b/utils.lua index 187f62a..f78e2af 100644 --- a/utils.lua +++ b/utils.lua @@ -1,3 +1,26 @@ +local c_dirt_with_grass = minetest.get_content_id("default:dirt_with_grass") +local c_dirt_with_snow = minetest.get_content_id("default:dirt_with_snow") +local c_dirt_with_dry_grass = minetest.get_content_id("default:dirt_with_dry_grass") +local c_dirt_with_coniferous_litter = minetest.get_content_id("default:dirt_with_coniferous_litter") +local c_sand = minetest.get_content_id("default:sand") +local c_desert_sand = minetest.get_content_id("default:desert_sand") +-- +local c_air = minetest.get_content_id("air") +local c_snow = minetest.get_content_id("default:snow") +local c_fern_1 = minetest.get_content_id("default:fern_1") +local c_fern_2 = minetest.get_content_id("default:fern_2") +local c_fern_3 = minetest.get_content_id("default:fern_3") +local c_rose = minetest.get_content_id("flowers:rose") +local c_viola = minetest.get_content_id("flowers:viola") +local c_geranium = minetest.get_content_id("flowers:geranium") +local c_tulip = minetest.get_content_id("flowers:tulip") +local c_dandelion_y = minetest.get_content_id("flowers:dandelion_yellow") +local c_dandelion_w = minetest.get_content_id("flowers:dandelion_white") +local c_bush_leaves = minetest.get_content_id("default:bush_leaves") +local c_bush_stem = minetest.get_content_id("default:bush_stem") +local c_a_bush_leaves = minetest.get_content_id("default:acacia_bush_leaves") +local c_a_bush_stem = minetest.get_content_id("default:acacia_bush_stem") +local c_water_source = minetest.get_content_id("default:water_source") -- -- function to copy tables -- @@ -10,10 +33,67 @@ function settlements.shallowCopy(original) end -- -- function to find surface block y coordinate +-- +function settlements.find_surface_lvm(pos, data, va) + local p6 = settlements.shallowCopy(pos) + local surface_mat = { + c_dirt_with_grass, + c_dirt_with_snow , + c_dirt_with_dry_grass, + c_dirt_with_coniferous_litter, + c_sand, + c_desert_sand + } + local cnt = 0 + local itter -- count up or down + local cnt_max = 200 + -- starting point for looking for surface + local vi = va:index(p6.x, p6.y, p6.z) + if data[vi] == c_air then + itter = -1 + else + itter = 1 + end + while cnt < cnt_max do + cnt = cnt+1 + vi = va:index(p6.x, p6.y, p6.z) + if vi == nil + then + return nil + end + for i, mats in ipairs(surface_mat) do + local node_check = va:index(p6.x, p6.y+1, p6.z) + if node_check and vi and data[vi] == mats and + (data[node_check] ~= c_water_source + ) + then +-- local tmp = minetest.get_name_from_content_id(data[node_check]) + return p6 + end + end + p6.y = p6.y + itter + if p6.y < 0 then return nil end + end + return nil +end +-- +-- function to find surface block y coordinate -- returns surface postion -- function settlements.find_surface(pos) local p6 = settlements.shallowCopy(pos) +-- +-- baseplate material, to replace dirt with grass and where buildings can be built +-- + local surface_mat = { + "default:dirt_with_grass", + "default:dirt_with_snow", + "default:dirt_with_dry_grass", + "default:dirt_with_coniferous_litter", + "default:sand", + "default:desert_sand", +-- "default:snow" + } local cnt = 0 local itter -- count up or down local cnt_max = 200 @@ -30,7 +110,6 @@ function settlements.find_surface(pos) s = minetest.get_node_or_nil(p6) if s == nil or s.name == "ignore" then return nil end for i, mats in ipairs(surface_mat) do --- if s and s.name == mats and not string.find(minetest.get_node_or_nil({ x=p6.x, y=p6.y+1, z=p6.z}).name,"water") then local node_check = minetest.get_node_or_nil({ x=p6.x, y=p6.y+1, z=p6.z}) if node_check and s and s.name == mats and (string.find(node_check.name,"air") or @@ -196,7 +275,7 @@ end -- -- get heightmap -- -function settlements.determine_heightmap(minp, maxp) +function settlements.determine_heightmap(data, va, minp, maxp) -- max height and min height, initialize with impossible values for easier first time setting local max_y = -100 local min_y = 100 @@ -218,7 +297,7 @@ function settlements.determine_heightmap(minp, maxp) -- for xi = cminp.x,cmaxp.x do for zi = cminp.z,cmaxp.z do - local pos_surface = settlements.find_surface({x=xi, y=cmaxp.y, z=zi}) + local pos_surface = settlements.find_surface({x=xi, y=cmaxp.y, z=zi}, data, va) -- check, if new found surface is higher or lower stored min_y or max_y if pos_surface then @@ -251,7 +330,7 @@ function settlements.evaluate_heightmap(minp, maxp) for i = square_start, square_end, 1 do -- skip buggy heightmaps, return high value if heightmap[i] == -31000 or - heightmap[i] == 31000 + heightmap[i] == 31000 then return max_height_difference + 1 end @@ -281,4 +360,24 @@ function settlements.evaluate_heightmap(minp, maxp) minetest.chat_send_all("heightdiff ".. height_diff) end return height_diff +end +-- +-- get LVM of current chunk +-- +function settlements.getlvm(minp, maxp) + local vm = minetest.get_voxel_manip() + local emin, emax = vm:read_from_map(minp, maxp) + local va = VoxelArea:new{ + MinEdge = emin, + MaxEdge = emax + } + local data = vm:get_data() + return vm, data, va, emin, emax +end-- +-- get LVM of current chunk +-- +function settlements.setlvm(vm, data) + -- Write data + vm:set_data(data) + vm:write_to_map(true) end \ No newline at end of file