mirror of
https://github.com/ElCeejo/animalia.git
synced 2025-03-15 12:21:24 +00:00
316 lines
No EOL
9.3 KiB
Lua
316 lines
No EOL
9.3 KiB
Lua
--------------
|
|
-- Spawning --
|
|
--------------
|
|
|
|
local random = math.random
|
|
|
|
local path = minetest.get_modpath("animalia")
|
|
|
|
local storage = dofile(path .. "/api/storage.lua")
|
|
|
|
animalia.spawn_points = storage.spawn_points
|
|
|
|
-- Get Biomes --
|
|
|
|
local chicken_biomes = {}
|
|
|
|
local frog_biomes = {}
|
|
|
|
local pig_biomes = {}
|
|
|
|
local wolf_biomes = {}
|
|
|
|
local function insert_all(tbl, tbl2)
|
|
for i = 1, #tbl2 do
|
|
table.insert(tbl, tbl2[i])
|
|
end
|
|
end
|
|
|
|
minetest.register_on_mods_loaded(function()
|
|
insert_all(chicken_biomes, animalia.registered_biome_groups["grassland"].biomes)
|
|
insert_all(chicken_biomes, animalia.registered_biome_groups["tropical"].biomes)
|
|
insert_all(pig_biomes, animalia.registered_biome_groups["temperate"].biomes)
|
|
insert_all(pig_biomes, animalia.registered_biome_groups["boreal"].biomes)
|
|
insert_all(frog_biomes, animalia.registered_biome_groups["swamp"].biomes)
|
|
insert_all(frog_biomes, animalia.registered_biome_groups["tropical"].biomes)
|
|
end)
|
|
|
|
creatura.register_mob_spawn("animalia:bat", {
|
|
chance = 2,
|
|
min_radius = 4,
|
|
max_radius = 16,
|
|
min_light = 0,
|
|
min_height = -512,
|
|
max_height = 0,
|
|
min_group = 3,
|
|
max_group = 5,
|
|
biomes = animalia.registered_biome_groups["cave"].biomes,
|
|
spawn_in_nodes = true,
|
|
nodes = {"air", "ignore"}
|
|
})
|
|
|
|
creatura.register_mob_spawn("animalia:chicken", {
|
|
chance = 3,
|
|
min_group = 3,
|
|
max_group = 5,
|
|
biomes = chicken_biomes
|
|
})
|
|
|
|
creatura.register_mob_spawn("animalia:cow", {
|
|
chance = 3,
|
|
min_group = 3,
|
|
max_group = 4,
|
|
biomes = animalia.registered_biome_groups["grassland"].biomes
|
|
})
|
|
|
|
creatura.register_mob_spawn("animalia:frog", {
|
|
chance = 2,
|
|
min_radius = 4,
|
|
max_radius = 16,
|
|
min_light = 0,
|
|
min_height = -32,
|
|
max_height = 8,
|
|
min_group = 2,
|
|
max_group = 6,
|
|
biomes = frog_biomes,
|
|
spawn_cluster = true,
|
|
spawn_in_nodes = true,
|
|
nodes = {"default:water_source"},
|
|
send_debug = true
|
|
})
|
|
|
|
creatura.register_mob_spawn("animalia:horse", {
|
|
chance = 3,
|
|
min_group = 4,
|
|
max_group = 5,
|
|
biomes = animalia.registered_biome_groups["grassland"].biomes
|
|
})
|
|
|
|
creatura.register_mob_spawn("animalia:pig", {
|
|
chance = 3,
|
|
min_group = 2,
|
|
max_group = 4,
|
|
biomes = pig_biomes
|
|
})
|
|
|
|
creatura.register_mob_spawn("animalia:reindeer", {
|
|
chance = 4,
|
|
min_group = 6,
|
|
max_group = 12,
|
|
biomes = animalia.registered_biome_groups["boreal"].biomes
|
|
})
|
|
|
|
creatura.register_mob_spawn("animalia:sheep", {
|
|
chance = 3,
|
|
min_group = 3,
|
|
max_group = 6,
|
|
biomes = animalia.registered_biome_groups["grassland"].biomes
|
|
})
|
|
|
|
creatura.register_mob_spawn("animalia:turkey", {
|
|
chance = 2,
|
|
min_group = 3,
|
|
max_group = 4,
|
|
biomes = animalia.registered_biome_groups["boreal"].biomes
|
|
})
|
|
|
|
creatura.register_mob_spawn("animalia:wolf", {
|
|
chance = 3,
|
|
min_group = 2,
|
|
max_group = 3,
|
|
biomes = animalia.registered_biome_groups["boreal"].biomes
|
|
})
|
|
|
|
creatura.register_mob_spawn("animalia:bird", {
|
|
chance = 4,
|
|
min_light = 0,
|
|
min_group = 12,
|
|
max_group = 16,
|
|
biomes = animalia.registered_biome_groups["common"].biomes,
|
|
spawn_cluster = true,
|
|
spawn_in_nodes = true,
|
|
nodes = {"air", "ignore"}
|
|
})
|
|
|
|
creatura.register_mob_spawn("animalia:tropical_fish", {
|
|
chance = 3,
|
|
min_height = -128,
|
|
max_height = 256,
|
|
min_group = 8,
|
|
max_group = 12,
|
|
spawn_cluster = true,
|
|
spawn_in_nodes = true,
|
|
nodes = {"default:water_source"}
|
|
})
|
|
|
|
---------------------
|
|
-- Mapgen Spawning --
|
|
---------------------
|
|
|
|
local function vec_raise(v, n)
|
|
return {x = v.x, y = v.y + n, z = v.z}
|
|
end
|
|
|
|
function is_value_in_table(tbl, val)
|
|
for _, v in pairs(tbl) do
|
|
if v == val then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
function get_biome_name(pos)
|
|
if not pos then return end
|
|
return minetest.get_biome_name(minetest.get_biome_data(pos).biome)
|
|
end
|
|
|
|
function get_ground_level(pos)
|
|
local node = minetest.get_node(pos)
|
|
local node_def = minetest.registered_nodes[node.name]
|
|
local height = 0
|
|
while node_def.walkable
|
|
and height < 4 do
|
|
height = height + 1
|
|
node = minetest.get_node(vec_raise(pos, height))
|
|
node_def = minetest.registered_nodes[node.name]
|
|
end
|
|
return vec_raise(pos, height)
|
|
end
|
|
|
|
local function dist_to_nearest_player(pos)
|
|
local dist
|
|
for _, player in pairs(minetest.get_connected_players()) do
|
|
local player_pos = player:get_pos()
|
|
if player_pos
|
|
and (not dist
|
|
or dist > vector.distance(pos, player_pos)) then
|
|
dist = vector.distance(pos, player_pos)
|
|
end
|
|
end
|
|
return dist or 100
|
|
end
|
|
|
|
local function get_spawnable_mobs(pos)
|
|
local biome = get_biome_name(pos)
|
|
if not biome then return end
|
|
local spawnable = {}
|
|
for k, v in pairs(creatura.registered_mob_spawns) do
|
|
if (not v.biomes
|
|
or is_value_in_table(v.biomes, biome))
|
|
and k:match("^animalia:")
|
|
and not v.spawn_in_nodes then
|
|
table.insert(spawnable, k)
|
|
end
|
|
end
|
|
return spawnable
|
|
end
|
|
|
|
local mapgen_spawning = minetest.settings:get_bool("animalia_mapgen_spawning") or true
|
|
|
|
animalia.chunks_since_last_spawn = 0
|
|
|
|
local chunk_spawn_add_int = tonumber(minetest.settings:get("chunk_spawn_add_int")) or 6
|
|
|
|
animalia.spawn_queue = {}
|
|
|
|
minetest.register_on_generated(function(minp, maxp)
|
|
if not mapgen_spawning then return end
|
|
animalia.chunks_since_last_spawn = animalia.chunks_since_last_spawn + 1
|
|
local heightmap = minetest.get_mapgen_object("heightmap")
|
|
if not heightmap then return end
|
|
local pos = {
|
|
x = minp.x + math.floor((maxp.x - minp.x) / 2),
|
|
y = minp.y,
|
|
z = minp.z + math.floor((maxp.z - minp.z) / 2)
|
|
}
|
|
local hm_i = (pos.x - minp.x + 1) + (((pos.z - minp.z)) * 80)
|
|
pos.y = heightmap[hm_i]
|
|
if animalia.chunks_since_last_spawn > chunk_spawn_add_int
|
|
and pos.y > 0 then
|
|
local heightmap = minetest.get_mapgen_object("heightmap")
|
|
if not heightmap then return end
|
|
local center = {
|
|
x = math.floor(minp.x + ((maxp.x - minp.x) * 0.5) + 0.5),
|
|
y = minp.y,
|
|
z = math.floor(minp.z + ((maxp.z - minp.z) * 0.5) + 0.5),
|
|
}
|
|
local light = minetest.get_natural_light(center)
|
|
while center.y < maxp.y
|
|
and light < 10 do
|
|
center.y = center.y + 1
|
|
light = minetest.get_natural_light(center)
|
|
end
|
|
local spawnable_mobs = get_spawnable_mobs(center)
|
|
if spawnable_mobs then
|
|
local mob = spawnable_mobs[random(#spawnable_mobs)]
|
|
table.insert(animalia.spawn_queue, {pos = center, mob = mob, group = random(3, 4)})
|
|
table.insert(animalia.spawn_points, center)
|
|
end
|
|
animalia.chunks_since_last_spawn = 0
|
|
end
|
|
end)
|
|
|
|
local respawn_interval = 15
|
|
|
|
minetest.register_globalstep(function(dtime)
|
|
respawn_interval = respawn_interval - dtime
|
|
if respawn_interval <= 0 then
|
|
if #animalia.spawn_points > 0 then
|
|
for i = 1, #animalia.spawn_points do
|
|
local point = animalia.spawn_points[i]
|
|
if dist_to_nearest_player(point) < 48
|
|
and minetest.get_node_or_nil(point) then
|
|
local spawnable_mobs = get_spawnable_mobs(point)
|
|
if spawnable_mobs then
|
|
local mob = spawnable_mobs[random(#spawnable_mobs)]
|
|
local objects = minetest.get_objects_inside_radius(point, 32)
|
|
local spawn = true
|
|
if #objects > 0 then
|
|
for i = 1, #objects do
|
|
local object = objects[i]
|
|
if object:get_luaentity()
|
|
and object:get_luaentity().name:find("animalia:") then
|
|
spawn = false
|
|
break
|
|
end
|
|
end
|
|
end
|
|
if spawn then
|
|
table.insert(animalia.spawn_queue, {pos = point, mob = mob, group = random(3, 4)})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
respawn_interval = 15
|
|
end
|
|
end)
|
|
|
|
local chunk_spawn_queue_int = tonumber(minetest.settings:get("chunk_spawn_queue_int")) or 16
|
|
|
|
local function spawn_queued()
|
|
if not mapgen_spawning then return end
|
|
local queue = animalia.spawn_queue
|
|
if #queue > 0 then
|
|
for i = #queue, 1, -1 do
|
|
if queue[i].mob then
|
|
local pos = queue[i].pos
|
|
for _ = 1, queue[i].group do
|
|
pos = {
|
|
x = pos.x + random(-3, 3),
|
|
y = pos.y,
|
|
z = pos.z + random(-3, 3)
|
|
}
|
|
pos = get_ground_level(pos)
|
|
minetest.add_node(pos, {name = "creatura:spawn_node"})
|
|
local meta = minetest.get_meta(pos)
|
|
meta:set_string("mob", queue[i].mob)
|
|
end
|
|
end
|
|
table.remove(animalia.spawn_queue, i)
|
|
end
|
|
end
|
|
minetest.after(chunk_spawn_queue_int, spawn_queued)
|
|
end
|
|
minetest.after(chunk_spawn_queue_int, spawn_queued) |