fun_caves/village.lua
2016-07-16 05:32:51 -05:00

304 lines
8 KiB
Lua

local newnode = fun_caves.clone_node("default:dirt")
newnode.drop = "default:dirt"
newnode.groups.soil = 0
minetest.register_node("fun_caves:hut_floor", newnode)
local farming = minetest.get_modpath('farming')
if minetest.get_modpath("mobs") and mobs and mobs.mod == "redo" then
local drops = {
{name = "default:axe_stone", chance = 3, min = 1, max = 1},
{name = "default:hoe_stone", chance = 3, min = 1, max = 1},
{name = "default:sword_stone", chance = 3, min = 1, max = 1},
{name = "default:apple", chance = 2, min = 1, max = 3},
{name = "farming:bread", chance = 3, min = 1, max = 3},
{name = "default:cobble", chance = 2, min = 1, max = 3},
}
if minetest.registered_items['mobs:leather'] then
drops[#drops+1] = {name = "mobs:leather", chance = 4, min = 1, max = 2}
end
local food = {}
for i = 1, 5 do
food[#food+1] = 'default:grass_'..i
end
if farming then
for i = 5, 8 do
food[#food+1] = 'farming:wheat_'..i
end
end
local function savage_gathering(self)
if not (self and fun_caves.custom_ready and fun_caves.search_replace and fun_caves.surface_damage and fun_caves.custom_ready(self)) then
return
end
local pos = self.object:getpos()
fun_caves.search_replace(pos, 5, food, 'air')
if math.random(5) == 1 then
local p1 = vector.subtract(pos, 2)
local p2 = vector.add(pos, 2)
local soil = minetest.find_nodes_in_area_under_air(p1, p2, {'farming:soil_wet'})
if soil and #soil > 0 then
local p = soil[math.random(#soil)]
p.y = p.y + 1
minetest.add_node(p, {name = 'farming:seed_wheat', param2 = 1})
local timer = minetest.get_node_timer(p)
if timer then
timer:start(math.random(166, 286))
end
end
end
fun_caves.surface_damage(self)
end
mobs:register_mob("fun_caves:savage", {
description = "Primitive Savage",
type = "monster",
passive = false,
damage = 1,
attack_type = "dogfight",
attacks_monsters = true,
hp_min = 5,
hp_max = 20,
armor = 100,
fear_height = 4,
collisionbox = {-0.35,-1,-0.35, 0.35,0.9,0.35},
visual = "mesh",
mesh = "character.b3d",
drawtype = "front",
textures = {
{"fun_caves_savage_1.png"},
},
makes_footstep_sound = true,
--sounds = {
-- random = "goblins_goblin_ambient",
-- warcry = "goblins_goblin_attack",
-- attack = "goblins_goblin_attack",
-- damage = "goblins_goblin_damage",
-- death = "goblins_goblin_death",
-- distance = 15,
--},
walk_velocity = 2,
run_velocity = 3,
jump = true,
drops = drops,
water_damage = 1,
lava_damage = 2,
light_damage = 0,
--lifetimer = 360,
view_range = 20,
owner = "",
animation = {
stand_start = 0,
stand_end = 79,
sit_start = 81,
sit_end = 160,
sleep_start = 162,
sleep_end = 166,
walk_start = 168,
walk_end = 187,
mine_start = 189,
mine_end = 198,
walkmine_start = 200,
walkmine_end = 219,
},
animation_speed = 30,
on_rightclick = nil,
do_custom = savage_gathering,
})
--mobs:register_egg("fun_caves:savage", "Primitive Savage", "farming_straw.png", 1)
mobs:register_spawn("fun_caves:savage", {'fun_caves:hut_floor'}, 100, 0, 20, 3, 2000)
end
local function build_hut(data, area, node, pos, turf)
if not (data and area and node and pos and turf and type(data) == 'table') then
return
end
local door = {x = ({2,7})[math.random(2)], z = ({2,7})[math.random(2)]}
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['fun_caves:hut_floor']
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']
if 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 (minp and maxp and data and p2data and area and node and type(data) == 'table' and type(p2data) == 'table') then
return
end
if not biome or math.random(10) ~= 1 then
return
end
local turf
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
elseif farming then
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