600 lines
17 KiB
Lua
600 lines
17 KiB
Lua
villages = {
|
|
default_area = 12,
|
|
village_size = {3,5},
|
|
buildings = {
|
|
["villages_dubble_balcony"]={chance=15,area=10,height=6},
|
|
["villages_family_curbroof"]={chance=15,area=12,height=8},
|
|
["villages_foodbar"]={chance=15,area=9,height=7},
|
|
["villages_litle_house_balcony"]={chance=10,area=5,height=6},
|
|
["villages_middle_house"]={chance=12,area=7,height=7},
|
|
["villages_storey"]={chance=15,area=8,height=9},
|
|
["villages_tiny_curbroof"]={chance=8,area=7,height=5},
|
|
["villages_tower"]={chance=15,area=6,height=18},
|
|
["villages_cabbage_farm"]={chance=18,area=10,height=2},
|
|
["villages_chicken_farm"]={chance=18,area=10,height=3},
|
|
["villages_cistern"]={chance=18,area=8,height=2},
|
|
["villages_cotton_farm"]={chance=18,area=10,height=2},
|
|
["villages_mine_shaft"]={chance=19,area=5,height=1},
|
|
["villages_pig_farm"]={chance=18,area=10,height=3},
|
|
["villages_sheep_farm"]={chance=18,area=10,height=3},
|
|
["villages_wheat_farm"]={chance=18,area=10,height=2},
|
|
},
|
|
atlantis = {
|
|
{name="atlantis_building1",chance=15,area=31,spawn=function(pos)
|
|
villages.chests_to_treasures_in_area(pos,16)
|
|
end},
|
|
{name="atlantis_building2",chance=15,area=17,spawn=function(pos)
|
|
villages.chests_to_treasures_in_area(pos,16)
|
|
end},
|
|
{name="atlantis_building3",chance=15,area=10,spawn=function(pos)
|
|
protect.add_game_rule_area(apos(pos,6,14,6),apos(pos,-6,-1,-6),"atlantis")
|
|
villages.chests_to_treasures_in_area(pos,17)
|
|
end},
|
|
{name="atlantis_building4",chance=15,area=13},
|
|
{name="atlantis_building5",chance=15,area=16},
|
|
{name="atlantis_building6",chance=15,area=36,spawn=function(pos)
|
|
protect.add_game_rule_area(vector.subtract(pos,18),vector.add(pos,18),"atlantis")
|
|
villages.chests_to_treasures_in_area(pos,18)
|
|
local code = math.random(0,9)..math.random(0,9)..math.random(0,9)..math.random(0,9)
|
|
local nodes = minetest.find_nodes_in_area(vector.subtract(pos,18),vector.add(pos,18),{"exatec:codelock","materials:granite_orb"})
|
|
local I = 0
|
|
for i,v in pairs(nodes) do
|
|
local n = minetest.get_node(v)
|
|
if n.name == "exatec:codelock" then
|
|
minetest.set_node(v,{name="exatec:codelock",param2=n.param2})
|
|
minetest.get_meta(v):set_string("code",code)
|
|
I = i
|
|
break
|
|
end
|
|
end
|
|
table.remove(nodes,I)
|
|
local p = nodes[math.random(1,#nodes)]
|
|
minetest.get_meta(p):set_string("infotext",code)
|
|
end},
|
|
{name="atlantis_building7",chance=15,area=10},
|
|
{name="atlantis_building8",chance=15,area=6},
|
|
{name="atlantis_building9",chance=15,area=10,spawn=function(pos)
|
|
villages.chests_to_treasures_in_area(pos,16)
|
|
end},
|
|
{name="atlantis_building10",chance=15,area=32,spawn=function(pos)
|
|
protect.add_game_rule_area(vector.subtract(pos,16),vector.add(pos,16),"atlantis")
|
|
villages.chests_to_treasures_in_area(pos,16)
|
|
end},
|
|
},
|
|
nodes_reset = {
|
|
"default:paper_compressor",
|
|
"default:craftguide",
|
|
"default:workbench",
|
|
"default:recycling_mill",
|
|
"default:dye_workbench",
|
|
"default:chest",
|
|
"examobs:woodbox",
|
|
"default:furnace",
|
|
"plants:apple_wood_door",
|
|
"clock:clock1",
|
|
"examobs:villager_npc_spawner",
|
|
"examobs:chicken_spawner",
|
|
"examobs:sheep_spawner",
|
|
"examobs:pig_spawner",
|
|
}
|
|
}
|
|
|
|
|
|
minetest.register_tool("villages:biocheck", {
|
|
description = "Biocheck",
|
|
inventory_image = "default_stick.png",
|
|
on_use=function(itemstack, user, pointed_thing)
|
|
local pos = user:get_pos()
|
|
local i = 3
|
|
minetest.place_schematic(pos,minetest.get_modpath("villages").."/schematics/atlantis_building"..i..".mts","random",nil,true,"place_center_x,place_center_z")
|
|
villages.atlantis[i].spawn(pos)
|
|
end
|
|
})
|
|
|
|
villages.chests_to_treasures_in_area=function(pos,rad)
|
|
local nodes = minetest.find_nodes_in_area(vector.subtract(pos,rad),vector.add(pos,rad),"default:chest")
|
|
for i,v in pairs(nodes) do
|
|
default.treasure({level=2,pos=v,node=minetest.get_node(v).name})
|
|
end
|
|
|
|
end
|
|
|
|
villages.set_village=function(pos)
|
|
local s = math.random(villages.village_size[1],villages.village_size[2])
|
|
local cs = 0
|
|
local used_pos = {}
|
|
local node
|
|
|
|
local nodes1 = minetest.find_nodes_in_area(vector.subtract(pos,20),vector.add(pos,20),{"group:tree"})
|
|
if #nodes1 > 0 then
|
|
for i,v in pairs(nodes1) do
|
|
local tree = minetest.registered_nodes[minetest.get_node(v).name].tree
|
|
if tree then
|
|
node = tree
|
|
break
|
|
end
|
|
end
|
|
else
|
|
local nodes2 = minetest.find_nodes_in_area(vector.subtract(pos,10),vector.add(pos,10),{"default:desert_sand"})
|
|
if #nodes2 > 0 then
|
|
node = "default:desert_cobble"
|
|
else
|
|
local nodes3 = minetest.find_nodes_in_area(vector.subtract(pos,10),vector.add(pos,10),{"default:dirt_with_grass"})
|
|
if #nodes3 > 0 then
|
|
node = "default:cobble"
|
|
end
|
|
end
|
|
end
|
|
|
|
for i = 0,math.random(100,1000) do
|
|
if villages.set_building_pos(pos,s,node,used_pos) then
|
|
cs = cs + 1
|
|
if cs >= (s*s)*s then
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
villages.set_atlantis=function(pos)
|
|
if pos.y > -25 or minetest.get_node(apos(pos,0,1)).name ~= "default:salt_water_source" then
|
|
return
|
|
end
|
|
pos.y=pos.y+1
|
|
local dir = {vector.new(pos),vector.new(pos),vector.new(pos),vector.new(pos)}
|
|
local hit = {}
|
|
local h = 0
|
|
|
|
for a=1,200 do
|
|
dir[1] = apos(dir[1],1)
|
|
dir[2] = apos(dir[2],-1)
|
|
dir[3] = apos(dir[3],0,0,1)
|
|
dir[4] = apos(dir[4],0,0,-1)
|
|
for i=1,4 do
|
|
if not hit[i] and minetest.get_node(dir[i]).name ~= "default:salt_water_source" then
|
|
hit[i] = vector.new(dir[i])
|
|
h = h +1
|
|
if h >= 4 then
|
|
break
|
|
end
|
|
end
|
|
end
|
|
if h >= 4 then
|
|
break
|
|
end
|
|
end
|
|
for i=1,4 do
|
|
hit[i] = hit[i] or dir[i]
|
|
end
|
|
local sx = pos.x-hit[1].x + pos.x-hit[2].x
|
|
local sz = pos.z-hit[3].z + pos.z-hit[4].z
|
|
local npos = {x=pos.x-sx/2,y=pos.y,z=pos.z-sz/2} -- center of area
|
|
|
|
local sizex,sizez = hit[1].x-hit[2].x,hit[3].z-hit[4].z
|
|
|
|
|
|
if sizez < 50 or sizez < 50 then
|
|
return
|
|
end
|
|
|
|
|
|
local num = math.random(10,20)
|
|
local list = {}
|
|
local i = 0
|
|
local n = #villages.atlantis
|
|
|
|
for I=0,100 do
|
|
local p = {x=npos.x+math.random(-sizex,sizex),y=npos.y,z=npos.z+math.random(-sizez,sizez)}
|
|
local b = villages.atlantis[math.random(1,n)]
|
|
local able = true
|
|
for i,v in pairs(list) do
|
|
local d = vector.distance(v.pos,npos)
|
|
if (d-b.area)-v.area <= 0 then
|
|
able = false
|
|
break
|
|
end
|
|
end
|
|
if able then
|
|
table.insert(list,{pos=p,area=b.area})
|
|
minetest.place_schematic(p,minetest.get_modpath("villages").."/schematics/"..b.name..".mts","random",nil,true,"place_center_x,place_center_z")
|
|
if b.spawn then
|
|
b.spawn(p)
|
|
end
|
|
num = num -1
|
|
if num <= 0 then
|
|
return
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
villages.set_building_pos=function(pos,size,node,used_pos)
|
|
local p = {x=pos.x,y=pos.y,z=pos.z}
|
|
local up
|
|
for i = 0,10 do
|
|
p.x = pos.x + math.random(-size,size)*villages.default_area
|
|
p.z = pos.z + math.random(-size,size)*villages.default_area
|
|
up = p.x.." "..p.z
|
|
if not used_pos[up] then
|
|
used_pos[up] = up
|
|
local g = villages.find_ground(p)
|
|
if g then
|
|
if villages.set_building(g,node) then
|
|
return true
|
|
end
|
|
|
|
end
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
villages.find_ground=function(pos)
|
|
for i = pos.y-10,pos.y+10 do
|
|
local p1 = {x=pos.x,y=i,z=pos.z}
|
|
local l1 = minetest.get_node_light(p1,0.5)
|
|
local p2 = {x=pos.x,y=i+1,z=pos.z}
|
|
local l2 = minetest.get_node_light(p2,0.5)
|
|
|
|
if l1 == nil then
|
|
minetest.emerge_area(p1,p2)
|
|
l1 = minetest.get_node_light(p1,0.5)
|
|
l2 = minetest.get_node_light(p2,0.5)
|
|
end
|
|
|
|
if i > 0 and (l2 or 0) > 9 and (l1 or 0) == 0 then
|
|
return p1
|
|
end
|
|
end
|
|
end
|
|
|
|
villages.set_building=function(pos,node)
|
|
local s
|
|
local name
|
|
|
|
minetest.emerge_area(vector.subtract(pos,-villages.default_area),vector.add(pos,villages.default_area))
|
|
|
|
local ground = minetest.get_node(pos)
|
|
|
|
for i,v in pairs(villages.buildings) do
|
|
if math.random(1,v.chance) == 1 then
|
|
local a = minetest.find_nodes_in_area(vector.subtract(pos,v.area/2),vector.add(pos,v.area/2),{"group:stone","group:dirt"})
|
|
local c = #a
|
|
local bc = ((v.area*v.area) * v.area)/2 + (v.area*v.area)*2
|
|
if c <= bc and c >bc/1.5 then
|
|
minetest.place_schematic(pos,minetest.get_modpath("villages").."/schematics/"..i..".mts","random",nil,true,"place_center_x,place_center_z")
|
|
name = i
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
if not name then
|
|
return false
|
|
end
|
|
|
|
local prop = villages.buildings[name]
|
|
local a = math.ceil(prop.area/2)
|
|
local h = prop.height
|
|
|
|
local nodes = minetest.find_nodes_in_area({x=pos.x+a,y=pos.y,z=pos.z+a},{x=pos.x-a,y=pos.y+h,z=pos.z-a},villages.nodes_reset)
|
|
for i,v in pairs(nodes) do
|
|
local n = minetest.get_node(v)
|
|
if n.name == "examobs:villager_npc_spawner" then
|
|
minetest.remove_node(v)
|
|
local self = minetest.add_entity(v,"examobs:villager_npc"):get_luaentity()
|
|
self.storage.npc_generated = true
|
|
self.storage.property_area = prop.area
|
|
self.storage.property_area_pos = pos
|
|
elseif n.name == "examobs:chicken_spawner" then
|
|
minetest.remove_node(v)
|
|
minetest.add_entity(v,"examobs:chicken"):set_yaw(math.random(0,6.28))
|
|
elseif n.name == "examobs:sheep_spawner" then
|
|
minetest.remove_node(v)
|
|
minetest.add_entity(v,"examobs:sheep"):set_yaw(math.random(0,6.28))
|
|
elseif n.name == "examobs:pig_spawner" then
|
|
minetest.remove_node(v)
|
|
minetest.add_entity(v,"examobs:pig"):set_yaw(math.random(0,6.28))
|
|
elseif n.name == "default:chest" or n.name == "examobs:woodbox" then
|
|
default.treasure({pos=v,node=n})
|
|
else
|
|
minetest.set_node(v,n)
|
|
end
|
|
end
|
|
|
|
for x = -a,a do
|
|
for z = -a,a do
|
|
local p = {x=pos.x+x,y=pos.y,z=pos.z+z}
|
|
local p2 = {x=pos.x+x,y=pos.y-1,z=pos.z+z}
|
|
if minetest.get_node(p).name == "air" and minetest.get_node(p2).name ~= "air" then
|
|
minetest.set_node(p,ground)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
if not node then
|
|
return true
|
|
end
|
|
|
|
local nodes = minetest.find_nodes_in_area({x=pos.x-a,y=pos.y,z=pos.z-a},{x=pos.x+a,y=pos.y+h,z=pos.z+a},{"group:chair","group:door","group:wood","group:tree","group:fence"})
|
|
|
|
if string.find(node,":") then
|
|
for i,v in pairs(nodes) do
|
|
local n = minetest.get_node(v)
|
|
local na = n.name
|
|
if minetest.get_item_group(na,"wood") > 0 or minetest.get_item_group(na,"tree") > 0 then
|
|
minetest.set_node(v,{name=node})
|
|
else
|
|
minetest.remove_node(v)
|
|
end
|
|
end
|
|
else
|
|
for i,v in pairs(nodes) do
|
|
local n = minetest.get_node(v)
|
|
local na = string.gsub(n.name,"apple",node)
|
|
minetest.set_node(v,{name=na,param2=n.param2})
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
minetest.register_node("villages:spawner", {
|
|
drawtype = "airlike",
|
|
paramtype = "light",
|
|
walkable = false,
|
|
buildable_to = true,
|
|
groups={on_load=1,not_in_creative_inventory=1},
|
|
on_load=function(pos)
|
|
minetest.remove_node(pos)
|
|
local n = minetest.get_node({x=pos.x+math.random(-1,1),y=pos.y,z=pos.z+math.random(-1,1)})
|
|
minetest.set_node(pos,n)
|
|
if math.random(1,10) == 1 then
|
|
villages.set_village(pos)
|
|
end
|
|
end,
|
|
})
|
|
|
|
minetest.register_node("villages:atlantis_spawner", {
|
|
drawtype = "airlike",
|
|
paramtype = "light",
|
|
walkable = false,
|
|
buildable_to = true,
|
|
groups={on_load=1,not_in_creative_inventory=1},
|
|
on_load=function(pos)
|
|
minetest.remove_node(pos)
|
|
local n = minetest.get_node({x=pos.x+math.random(-1,1),y=pos.y,z=pos.z+math.random(-1,1)})
|
|
minetest.set_node(pos,n)
|
|
if math.random(1,10) == 1 then
|
|
villages.set_atlantis(pos)
|
|
end
|
|
end,
|
|
})
|
|
|
|
|
|
minetest.register_ore({
|
|
ore_type = "blob",
|
|
ore= "villages:atlantis_spawner",
|
|
wherein= "default:sand",
|
|
clust_scarcity = 30 * 30 * 30,
|
|
clust_size = 1,
|
|
y_min= -200,
|
|
y_max= -25,
|
|
noise_params = default.ore_noise_params()
|
|
})
|
|
minetest.register_ore({
|
|
ore_type = "blob",
|
|
ore= "villages:spawner",
|
|
wherein= "default:dirt",
|
|
clust_scarcity = 30 * 30 * 30,
|
|
clust_size = 1,
|
|
y_min= 0,
|
|
y_max= 50,
|
|
noise_params = default.ore_noise_params()
|
|
})
|
|
minetest.register_ore({
|
|
ore_type = "blob",
|
|
ore= "villages:spawner",
|
|
wherein= "default:snow",
|
|
clust_scarcity = 30 * 30 * 30,
|
|
clust_size = 1,
|
|
y_min= 0,
|
|
y_max= 50,
|
|
noise_params = default.ore_noise_params()
|
|
})
|
|
minetest.register_ore({
|
|
ore_type = "blob",
|
|
ore= "villages:spawner",
|
|
wherein= "default:desert_sand",
|
|
clust_scarcity = 30 * 30 * 30,
|
|
clust_size = 1,
|
|
y_min= 0,
|
|
y_max= 50,
|
|
noise_params = default.ore_noise_params()
|
|
})
|
|
|
|
minetest.register_node("villages:trader", {
|
|
groups = {attached_node=1,not_in_creative_inventory=1,on_load=1},
|
|
pointable=false,
|
|
paramtype = "light",
|
|
drawtype="airlike",
|
|
drop="",
|
|
walkable=false,
|
|
floodable = true,
|
|
sunlight_propagates = true,
|
|
on_construct=function(pos)
|
|
minetest.get_node_timer(pos):start(3)
|
|
end,
|
|
on_timer = function (pos, elapsed)
|
|
local npc
|
|
local item
|
|
for _, ob in ipairs(minetest.get_objects_inside_radius(pos,10)) do
|
|
local en = ob:get_luaentity()
|
|
if en and en.examob and en.type == "npc" then
|
|
npc = true
|
|
elseif en and en.traderitem and vector.distance(ob:get_pos(),pos) <= 0.3 then
|
|
item = ob
|
|
end
|
|
if npc and item then
|
|
break
|
|
end
|
|
end
|
|
|
|
if minetest.get_meta(pos):get_string("item1") == "" then
|
|
minetest.registered_nodes["villages:trader"].newitem(pos)
|
|
end
|
|
|
|
if not npc then
|
|
if item then
|
|
item:remove()
|
|
end
|
|
elseif not item then
|
|
minetest.registered_nodes["villages:trader"].spawnitem(pos)
|
|
end
|
|
return true
|
|
end,
|
|
on_load=function(pos)
|
|
if math.random(1,5) == 1 or minetest.get_meta(pos):get_string("item1") == "" then
|
|
minetest.get_node_timer(pos):start(3)
|
|
minetest.registered_nodes["villages:trader"].newitem(pos)
|
|
minetest.registered_nodes["villages:trader"].spawnitem(pos)
|
|
for _, ob in ipairs(minetest.get_objects_inside_radius(pos,0.3)) do
|
|
local en = ob:get_luaentity()
|
|
if en and en.traderitem then
|
|
ob:remove()
|
|
end
|
|
end
|
|
end
|
|
end,
|
|
spawnitem=function(pos)
|
|
local e = minetest.add_entity(pos,"villages:traderitem"):get_luaentity()
|
|
e.index = minetest.get_meta(pos):get_int("index")
|
|
e:on_rightclick()
|
|
end,
|
|
newitem=function(pos)
|
|
local items = {}
|
|
local m = minetest.get_meta(pos)
|
|
for i,v in pairs(minetest.registered_items) do
|
|
if minetest.get_item_group(i,"store") > 1 then
|
|
table.insert(items,i)
|
|
end
|
|
end
|
|
for i=1,10 do
|
|
local item = items[math.random(1,#items)]
|
|
local cost = minetest.get_item_group(item,"store")
|
|
m:set_string("item"..i,item)
|
|
m:set_int("index",1)
|
|
m:set_int("count"..i,math.random(1,10))
|
|
m:set_int("cost"..i,cost+math.floor(math.random(cost*0.1,cost*2)))
|
|
end
|
|
end,
|
|
})
|
|
|
|
local trader2 = table.copy(default.def("villages:trader"))
|
|
trader2.on_timer = function(pos, elapsed)
|
|
local item
|
|
for _, ob in ipairs(minetest.get_objects_inside_radius(pos,10)) do
|
|
local en = ob:get_luaentity()
|
|
if en and en.traderitem and vector.distance(ob:get_pos(),pos) <= 0.3 then
|
|
item = ob
|
|
break
|
|
end
|
|
end
|
|
if minetest.get_meta(pos):get_string("item1") == "" then
|
|
minetest.registered_nodes["villages:trader"].newitem(pos)
|
|
end
|
|
if not item then
|
|
minetest.registered_nodes["villages:trader"].spawnitem(pos)
|
|
end
|
|
return true
|
|
end
|
|
minetest.register_node("villages:trader2", trader2)
|
|
|
|
minetest.register_entity("villages:traderitem",{
|
|
hp_max = 1000,
|
|
physical = false,
|
|
collisionbox = {-0.3,-0.3,-0.3,0.3,0.3,0.3},
|
|
visual = "wielditem",
|
|
visual_size = {x=0.3,y=0.3},
|
|
textures = {"default:stick"},
|
|
decoration=true,
|
|
traderitem=true,
|
|
static_save = false,
|
|
automatic_rotate = math.pi/4,
|
|
timer = 0,
|
|
on_step=function(self, dtime)
|
|
self.timer = self.timer -dtime
|
|
if self.timer < 0 then
|
|
self.timer = 1
|
|
local n = minetest.get_node(self.object:get_pos()).name
|
|
if n ~= "villages:trader" and n ~= "villages:trader2" then
|
|
self.object:remove()
|
|
end
|
|
end
|
|
end,
|
|
on_punch=function(self, puncher, time_from_last_punch, tool_capabilities, dir)
|
|
self.object:set_hp(1000)
|
|
if puncher:is_player() then
|
|
local inv = puncher:get_inventory()
|
|
local c = Getcoin(puncher)
|
|
local pos = self.object:get_pos()
|
|
local m2 = minetest.get_meta(pos)
|
|
if c >= self.cost and inv:room_for_item("main",self.item) then
|
|
inv:add_item("main",self.item)
|
|
Coin(puncher,c-self.cost,true)
|
|
local ic = m2:get_int("count"..self.index)-1
|
|
m2:set_int("count"..self.index,ic)
|
|
self.update = true
|
|
self.on_rightclick(self)
|
|
end
|
|
end
|
|
end,
|
|
on_rightclick=function(self)
|
|
local pos = self.object:get_pos()
|
|
local items = {}
|
|
local m = minetest.get_meta(pos)
|
|
local set
|
|
|
|
if self.update == nil or m:get_int("count"..self.index) <= 0 then
|
|
for i = self.index+1,10 do
|
|
if m:get_int("count"..i) > 0 then
|
|
self.index = i
|
|
set = true
|
|
break
|
|
end
|
|
end
|
|
if not set then
|
|
for i = 1,self.index do
|
|
if m:get_int("count"..i) > 0 then
|
|
self.index = i
|
|
set = true
|
|
break
|
|
end
|
|
end
|
|
if not set then
|
|
minetest.registered_nodes["villages:trader"].newitem(pos)
|
|
minetest.registered_nodes["villages:trader"].spawnitem(pos)
|
|
self.object:remove()
|
|
return
|
|
end
|
|
end
|
|
m:set_int("index",self.index)
|
|
end
|
|
self.update = nil
|
|
self.item = m:get_string("item"..self.index)
|
|
self.cost = m:get_int("cost"..self.index)
|
|
local def = minetest.registered_items[self.item]
|
|
|
|
if not def then
|
|
minetest.registered_nodes["villages:trader"].newitem(pos)
|
|
minetest.registered_nodes["villages:trader"].spawnitem(pos)
|
|
self.object:remove()
|
|
return
|
|
end
|
|
|
|
self.object:set_properties(
|
|
{textures={self.item},
|
|
infotext=(def.description or def.name) .. "\nCost: "..self.cost.."\n"..m:get_int("count"..self.index).." left\n"..self.index.."/10\n\nRight click to change"
|
|
})
|
|
end,
|
|
}) |