Smarter mapgen spawning, crash fix, more settings

This commit is contained in:
ElCeejo 2021-08-20 20:16:29 -07:00 committed by GitHub
parent 7e240b5bd8
commit 69e96a6b82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 318 additions and 246 deletions

View File

@ -583,7 +583,7 @@ end
local function is_under_solid(pos)
local pos2 = vector.new(pos.x, pos.y + 1, pos.z)
local def = minetest.registered_nodes[minetest.get_node(pos2).name]
return (def.walkable or mobkit.get_node_height(pos2) < 1.5)
return (def.walkable or ((mobkit.get_node_height(pos2) or 0) < 1.5))
end
local function vec_center(vec)

View File

@ -70,12 +70,12 @@ minetest.register_alias_force("better_fauna:beef_cooked", "animalia:beef_cooked"
minetest.register_alias_force("better_fauna:bucket_milk", "animalia:bucket_milk")
minetest.register_alias_force("better_fauna:leather", "animalia:leather")
minetest.register_alias_force("better_fauna:chicken_egg", "animalia:chicken_egg")
minetest.register_alias_force("better_fauna:chicken_raw", "animalia:chicken_raw")
minetest.register_alias_force("better_fauna:chicken_cooked", "animalia:chicken_cooked")
minetest.register_alias_force("better_fauna:chicken_raw", "animalia:poultry_raw")
minetest.register_alias_force("better_fauna:chicken_cooked", "animalia:poultry_cooked")
minetest.register_alias_force("better_fauna:feather", "animalia:feather")
minetest.register_alias_force("better_fauna:mutton_raw", "animalia:mutton_raw")
minetest.register_alias_force("better_fauna:mutton_cooked", "animalia:mutton_cooked")
minetest.register_alias_force("better_fauna:porkchop_raw", "animalia:porkchop_raw")
minetest.register_alias_force("better_fauna:porkchop_cooked", "animalia:porkchop_cooked")
minetest.register_alias_force("better_fauna:turkey_raw", "animalia:turkey_raw")
minetest.register_alias_force("better_fauna:turkey_cooked", "animalia:turkey_cooked")
minetest.register_alias_force("better_fauna:turkey_raw", "animalia:poultry_raw")
minetest.register_alias_force("better_fauna:turkey_cooked", "animalia:poultry_cooked")

275
api/spawn.lua Normal file
View File

@ -0,0 +1,275 @@
animalia.grassland_biomes = {}
animalia.temperate_biomes = {}
animalia.boreal_biomes = {}
animalia.tropical_biomes = {}
local chicken_biomes = {}
local pig_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()
for name in pairs(minetest.registered_biomes) do
local biome = minetest.registered_biomes[name]
if name:find("forest") then
local turf = biome.node_top
local heat = biome.heat_point or 0
local humidity = biome.humidity_point or 50
if turf then
if turf:find("dirt") then
if heat >= 40
and humidity >= 60 then
table.insert(animalia.tropical_biomes, name)
else
table.insert(animalia.boreal_biomes, name)
end
elseif turf:find("grass") then
if heat >= 40 then
table.insert(animalia.boreal_biomes, name)
else
table.insert(animalia.temperate_biomes, name)
end
elseif turf:find("litter") then
if heat >= 40
and humidity >= 60 then
table.insert(animalia.tropical_biomes, name)
else
table.insert(animalia.temperate_biomes, name)
end
elseif turf:find("snow") then
table.insert(animalia.temperate_biomes, name)
end
end
else
local turf = biome.node_top
local heat = biome.heat_point or 0
--local humidity = biome.humidity_point or 50
if turf then
if turf:find("grass")
or (turf:find("dirt")
and heat < 60) then
table.insert(animalia.grassland_biomes, name)
end
end
end
end
insert_all(chicken_biomes, animalia.grassland_biomes)
insert_all(chicken_biomes, animalia.tropical_biomes)
insert_all(pig_biomes, animalia.grassland_biomes)
insert_all(pig_biomes, animalia.temperate_biomes)
insert_all(pig_biomes, animalia.boreal_biomes)
end)
-- Chicken --
mob_core.register_spawn({
name = "animalia:chicken",
min_light = 0,
max_light = 15,
min_height = -31000,
max_height = 31000,
min_rad = 24,
max_rad = 256,
group = 6,
optional = {
biomes = chicken_biomes
}
}, animalia.spawn_interval, 4)
-- Cat --
local house_nodes = {}
minetest.register_on_mods_loaded(function()
for name in pairs(minetest.registered_nodes) do
if minetest.get_item_group(name, "stairs") > 0
or minetest.get_item_group(name, "wood") > 0 then
table.insert(house_nodes, name)
end
end
end)
mob_core.register_spawn({
name = "animalia:cat",
nodes = house_nodes,
min_light = 0,
max_light = 15,
min_height = -31000,
max_height = 31000,
min_rad = 24,
max_rad = 256,
group = 0,
}, animalia.spawn_interval, 6)
-- Cow --
mob_core.register_spawn({
name = "animalia:cow",
min_light = 0,
max_light = 15,
min_height = -31000,
max_height = 31000,
group = 3,
optional = {
biomes = animalia.grassland_biomes
}
}, animalia.spawn_interval, 2)
-- Horse --
mob_core.register_spawn({
name = "animalia:horse",
min_light = 0,
max_light = 15,
min_height = -31000,
max_height = 31000,
group = 6,
optional = {
biomes = animalia.grassland_biomes
}
}, animalia.spawn_interval, 16)
-- Pig --
mob_core.register_spawn({
name = "animalia:pig",
nodes = {"default:dirt_with_grass"},
min_light = 0,
max_light = 15,
min_height = -31000,
max_height = 31000,
group = 3,
optional = {
biomes = pig_biomes
}
}, animalia.spawn_interval, 4)
-- Sheep --
mob_core.register_spawn({
name = "animalia:sheep",
min_light = 0,
max_light = 15,
min_height = -31000,
max_height = 31000,
min_rad = 24,
max_rad = 256,
group = 6,
optional = {
biomes = animalia.grassland_biomes
}
}, animalia.spawn_interval, 4)
-- Turkey --
mob_core.register_spawn({
name = "animalia:turkey",
min_light = 0,
max_light = 15,
min_height = -31000,
max_height = 31000,
min_rad = 24,
max_rad = 256,
group = 6,
optional = {
biomes = animalia.temperate_biomes
}
}, animalia.spawn_interval, 6)
-- Wolf --
mob_core.register_spawn({
name = "animalia:wolf",
min_light = 0,
max_light = 15,
min_height = -31000,
max_height = 31000,
group = 4,
optional = {
biomes = animalia.temperate_biomes
}
}, animalia.spawn_interval, 4)
---------------------
-- Mapgen Spawning --
---------------------
animalia.chunks_since_last_spawn = 0
local chunk_spawn_add_int = tonumber(minetest.settings:get("chunk_spawn_add_int")) or 64
animalia.spawn_queue = {}
minetest.register_on_generated(function(minp, maxp)
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 = {}
for i = 1, #animalia.mobs do
local spawn_def = mob_core.registered_spawns[animalia.mobs[i]].def
if spawn_def.optional
and mob_core.find_val(spawn_def.optional.biomes, mob_core.get_biome_name(center))
and (#animalia.spawn_queue < 1
or animalia.spawn_queue[#animalia.spawn_queue].mob ~= animalia.mobs[i]) then
table.insert(spawnable_mobs, animalia.mobs[i])
end
end
table.insert(animalia.spawn_queue, {pos = center, mob = spawnable_mobs[math.random(#spawnable_mobs)]})
animalia.chunks_since_last_spawn = 0
end
end)
local chunk_spawn_queue_int = tonumber(minetest.settings:get("chunk_spawn_queue_int")) or 16
local function spawn_queued()
local queue = animalia.spawn_queue
if #queue > 0 then
for i = #queue, 1, -1 do
if queue[i].mob then
local def = mob_core.registered_spawns[queue[i].mob].def
mob_core.spawn_at_pos(
queue[i].pos,
def.name,
def.nodes or nil,
def.group or 1,
def.optional or nil
)
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)

134
init.lua
View File

@ -22,61 +22,6 @@ minetest.register_on_mods_loaded(function()
end
end)
animalia.grassland_biomes = {}
animalia.temperate_biomes = {}
animalia.boreal_biomes = {}
animalia.tropical_biomes = {}
minetest.register_on_mods_loaded(function()
for name in pairs(minetest.registered_biomes) do
local biome = minetest.registered_biomes[name]
if name:find("forest") then
local turf = biome.node_top
local heat = biome.heat_point or 0
local humidity = biome.humidity_point or 50
if turf then
if turf:find("dirt") then
if heat >= 40
and humidity >= 60 then
table.insert(animalia.tropical_biomes, name)
else
table.insert(animalia.boreal_biomes, name)
end
elseif turf:find("grass") then
if heat >= 40 then
table.insert(animalia.boreal_biomes, name)
else
table.insert(animalia.temperate_biomes, name)
end
elseif turf:find("litter") then
if heat >= 40
and humidity >= 60 then
table.insert(animalia.tropical_biomes, name)
else
table.insert(animalia.temperate_biomes, name)
end
elseif turf:find("snow") then
table.insert(animalia.temperate_biomes, name)
end
end
else
local turf = biome.node_top
local heat = biome.heat_point or 0
--local humidity = biome.humidity_point or 50
if turf then
if turf:find("grass")
or (turf:find("dirt")
and heat < 60) then
table.insert(animalia.grassland_biomes, name)
end
end
end
end
end)
animalia.frame_blend = 0
if minetest.has_feature("object_step_has_moveresult") then
@ -155,7 +100,12 @@ end
local path = minetest.get_modpath("animalia")
local spawn_mobs = minetest.settings:get_bool("spawn_mobs") or true
dofile(path.."/api/api.lua")
if spawn_mobs then
dofile(path.."/api/spawn.lua")
end
dofile(path.."/craftitems.lua")
dofile(path.."/mobs/cat.lua")
dofile(path.."/mobs/chicken.lua")
@ -167,63 +117,25 @@ dofile(path.."/mobs/turkey.lua")
dofile(path.."/mobs/wolf.lua")
dofile(path.."/api/legacy_convert.lua")
animalia.chunks_since_last_spawn = 0
local convert_redo_items = minetest.settings:get_bool("convert_redo_items") or false
local chunk_spawn_add_int = tonumber(minetest.settings:get("chunk_spawn_add_int")) or 32
animalia.spawn_queue = {}
minetest.register_on_generated(function(minp, maxp)
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
table.insert(animalia.spawn_queue, {pos = center, mob = animalia.mobs[math.random(#animalia.mobs)]})
animalia.chunks_since_last_spawn = 0
end
end)
local chunk_spawn_queue_int = tonumber(minetest.settings:get("chunk_spawn_queue_int")) or 10
local function spawn_queued()
local queue = animalia.spawn_queue
if #queue > 0 then
for i = #queue, 1, -1 do
local def = mob_core.registered_spawns[queue[i].mob].def
mob_core.spawn_at_pos(
queue[i].pos,
def.name,
def.nodes or nil,
def.group or 1,
def.optional or nil
)
table.remove(animalia.spawn_queue, i)
end
end
minetest.after(chunk_spawn_queue_int, spawn_queued)
if convert_redo_items then
minetest.register_alias_force("mobs:lasso","animalia:lasso")
minetest.register_alias_force("mobs:saddle","animalia:saddle")
minetest.register_alias_force("mobs:shears","animalia:shears")
minetest.register_alias_force("mobs_animal:chicken_raw","animalia:poultry_raw")
minetest.register_alias_force("mobs_animal:chicken_feather","animalia:feather")
minetest.register_alias_force("mobs:meat_raw" ,"animalia:beef_raw")
minetest.register_alias_force("mobs:meat","animalia:beef_cooked")
minetest.register_alias_force("mobs_animal:mutton_raw","animalia:mutton_raw")
minetest.register_alias_force("mobs_animal:mutton_cooked","animalia:mutton_cooked")
minetest.register_alias_force("mobs:leather" ,"animalia:leather")
minetest.register_alias_force("mobs_animal:egg","animalia:chicken_egg")
minetest.register_alias_force("mobs_animal:chicken_egg_fried" ,"animalia:chicken_egg_fried")
minetest.register_alias_force("mobs_animal:milk_bucket","animalia:bucket_milk")
minetest.register_alias_force("mobs_animal:chicken_cooked" ,"animalia:poultry_cooked")
minetest.register_alias_force("mobs_animal:pork_raw" ,"animalia:porkchop_raw")
minetest.register_alias_force("mobs_animal:pork_cooked","animalia:porkchop_cooked")
end
minetest.after(chunk_spawn_queue_int, spawn_queued)
minetest.log("action", "[MOD] Animalia [0.2] loaded")

View File

@ -303,27 +303,4 @@ animalia.register_mob("cat", {
end
})
mob_core.register_spawn_egg("animalia:cat", "db9764" ,"cf8d5a")
local house_nodes = {}
minetest.register_on_mods_loaded(function()
for name in pairs(minetest.registered_nodes) do
if minetest.get_item_group(name, "stairs") > 0
or minetest.get_item_group(name, "wood") > 0 then
table.insert(house_nodes, name)
end
end
end)
mob_core.register_spawn({
name = "animalia:cat",
nodes = house_nodes,
min_light = 0,
max_light = 15,
min_height = -31000,
max_height = 31000,
min_rad = 24,
max_rad = 256,
group = 0,
}, animalia.spawn_interval, 1)
mob_core.register_spawn_egg("animalia:cat", "db9764" ,"cf8d5a")

View File

@ -135,7 +135,7 @@ animalia.register_mob("chicken", {
},
drops = {
{name = "animalia:feather", chance = 1, min = 1, max = 2},
{name = "animalia:chicken_raw", chance = 1, min = 1, max = 4}
{name = "animalia:poultry_raw", chance = 1, min = 1, max = 4}
},
-- Functions
head_data = {
@ -161,23 +161,6 @@ animalia.register_mob("chicken", {
mob_core.register_spawn_egg("animalia:chicken", "c6c6c6", "d22222")
mob_core.register_spawn({
name = "animalia:chicken",
min_light = 0,
max_light = 15,
min_height = -31000,
max_height = 31000,
min_rad = 24,
max_rad = 256,
group = 6,
optional = {
biomes = {
unpack(animalia.grassland_biomes),
unpack(animalia.tropical_biomes)
}
}
}, animalia.spawn_interval, 4)
minetest.register_craftitem("animalia:poultry_raw", {
description = "Raw Poultry",
inventory_image = "animalia_poultry_raw.png",

View File

@ -244,16 +244,4 @@ minetest.register_craft({
})
mob_core.register_spawn_egg("animalia:cow", "cac3a1" ,"464438")
mob_core.register_spawn({
name = "animalia:cow",
min_light = 0,
max_light = 15,
min_height = -31000,
max_height = 31000,
group = 3,
optional = {
biomes = animalia.grassland_biomes
}
}, animalia.spawn_interval, 2)
mob_core.register_spawn_egg("animalia:cow", "cac3a1" ,"464438")

View File

@ -280,16 +280,4 @@ animalia.register_mob("horse", {
end
})
mob_core.register_spawn_egg("animalia:horse", "ebdfd8" ,"653818")
mob_core.register_spawn({
name = "animalia:horse",
min_light = 0,
max_light = 15,
min_height = -31000,
max_height = 31000,
group = 6,
optional = {
biomes = animalia.grassland_biomes
}
}, animalia.spawn_interval, 8)
mob_core.register_spawn_egg("animalia:horse", "ebdfd8" ,"653818")

View File

@ -161,21 +161,4 @@ minetest.register_craft({
output = "animalia:porkchop_cooked",
})
mob_core.register_spawn_egg("animalia:pig", "e0b1a7" ,"cc9485")
mob_core.register_spawn({
name = "animalia:pig",
nodes = {"default:dirt_with_grass"},
min_light = 0,
max_light = 15,
min_height = -31000,
max_height = 31000,
group = 3,
optional = {
biomes = {
unpack(animalia.grassland_biomes),
unpack(animalia.temperate_biomes),
unpack(animalia.boreal_biomes)
}
}
}, animalia.spawn_interval, 4)
mob_core.register_spawn_egg("animalia:pig", "e0b1a7" ,"cc9485")

View File

@ -261,20 +261,6 @@ animalia.register_mob("sheep", {
mob_core.register_spawn_egg("animalia:sheep", "f4e6cf", "e1ca9b")
mob_core.register_spawn({
name = "animalia:sheep",
min_light = 0,
max_light = 15,
min_height = -31000,
max_height = 31000,
min_rad = 24,
max_rad = 256,
group = 6,
optional = {
biomes = animalia.grassland_biomes
}
}, animalia.spawn_interval, 4)
minetest.register_craftitem("animalia:mutton_raw", {
description = "Raw Mutton",
inventory_image = "animalia_mutton_raw.png",

View File

@ -143,18 +143,4 @@ animalia.register_mob("turkey", {
end,
})
mob_core.register_spawn_egg("animalia:turkey", "352b22", "2f2721")
mob_core.register_spawn({
name = "animalia:turkey",
min_light = 0,
max_light = 15,
min_height = -31000,
max_height = 31000,
min_rad = 24,
max_rad = 256,
group = 6,
optional = {
biomes = animalia.temperate_biomes
}
}, animalia.spawn_interval, 6)
mob_core.register_spawn_egg("animalia:turkey", "352b22", "2f2721")

View File

@ -222,16 +222,4 @@ animalia.register_mob("wolf", {
end
})
mob_core.register_spawn_egg("animalia:wolf", "a19678" ,"231b13")
mob_core.register_spawn({
name = "animalia:wolf",
min_light = 0,
max_light = 15,
min_height = -31000,
max_height = 31000,
group = 4,
optional = {
biomes = animalia.temperate_biomes
}
}, animalia.spawn_interval, 4)
mob_core.register_spawn_egg("animalia:wolf", "a19678" ,"231b13")

View File

@ -1,5 +1,11 @@
# How many chunks can generate before adding another to spawn queue
chunk_spawn_add_int (Chunk Spawning Addition Interval) float 32
chunk_spawn_add_int (Chunk Spawning Addition Interval) float 64
# How often (in seconds) the spawn queue is executed and cleared
chunk_spawn_queue_int (Chunk Spawning Queue Execution Interval) float 10
chunk_spawn_queue_int (Chunk Spawning Queue Execution Interval) float 16
# If true, mobs will spawn in the wild
spawn_mobs (Spawn Mobs) bool true
# If true, items from mobs_redo and mobs_animal will be converted to Animalia items
convert_redo_items(Convert Mobs Redo Items) bool false