mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-11-25 20:11:06 +01:00
Add most of the code for sub-node accurate spawning volume check (needs a function to calculate bounding box height of nodes)
This commit is contained in:
parent
d8d39ffd52
commit
fa09b65010
1 changed files with 36 additions and 8 deletions
|
@ -548,19 +548,47 @@ local function has_room(self,pos)
|
||||||
p1.y = math.floor(p1.y)
|
p1.y = math.floor(p1.y)
|
||||||
p1.z = math.floor(p1.z)
|
p1.z = math.floor(p1.z)
|
||||||
|
|
||||||
local p2 = vector.offset(p1,cb[4] - cb[1], cb[5] - cb[2], cb[6] - cb[3])
|
local cb_height = cb[5] - cb[2]
|
||||||
|
local p2 = vector.offset(p1,cb[4] - cb[1], cb_height, cb[6] - cb[3])
|
||||||
p2.x = math.floor(p2.x)
|
p2.x = math.floor(p2.x)
|
||||||
p2.y = math.floor(p2.y)
|
p2.y = math.floor(p2.y)
|
||||||
p2.z = math.floor(p2.z)
|
p2.z = math.floor(p2.z)
|
||||||
|
|
||||||
local r = (p2.x - p1.x + 1) * (p2.y - p1.y + 1) * (p2.z - p1.z + 1)
|
-- Check if the entire spawn volume is free
|
||||||
local found_nodes = minetest.find_nodes_in_area(p1,p2,nodes)
|
local dx = p2.x - p1.x + 1
|
||||||
local n = #found_nodes or 0
|
local dy = p2.y - p1.y + 1
|
||||||
if r > n then
|
local dz = p2.z - p1.z + 1
|
||||||
minetest.log("warning","[mcl_mobs] No room for mob "..self.name.." at "..minetest.pos_to_string(vector.round(pos)))
|
local n = #minetest.find_nodes_in_area(p1,p2,nodes) or 0
|
||||||
return false
|
if n == ( dx * dz * dz ) then return true end
|
||||||
|
|
||||||
|
-- Make sure the entire volume except for the top level is free before checking the top layer
|
||||||
|
if dy > 1 then
|
||||||
|
n = #minetest.find_nodes_in_area(p1, vector.offset(p2, 0, -1, 0), nodes)
|
||||||
|
if n < (dx * dz * ( dy - 1)) then return false end
|
||||||
end
|
end
|
||||||
return true
|
|
||||||
|
-- Check the top layer to see if we have enough space to spawn in
|
||||||
|
local top_layer_height = 1
|
||||||
|
local processed = {}
|
||||||
|
for x = p1.x,p2.x do
|
||||||
|
for z = p1.z,p2.z do
|
||||||
|
local node = minetest.get_node(vector.new(x,p2.y,z)) or { name = "ignore" }
|
||||||
|
if not processed[node.name] then
|
||||||
|
local nodedef = minetest.registered_nodes
|
||||||
|
|
||||||
|
-- TODO: calculate node bounding box and select the lowest y value
|
||||||
|
local lowest_y = 0
|
||||||
|
top_layer_height = math.min(lowest_y, top_layer_height)
|
||||||
|
|
||||||
|
processed[node.name] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if top_layer_height + dy - 1 >= cb_height then return true end
|
||||||
|
|
||||||
|
-- We don't have room
|
||||||
|
mcl_log("No room for mob "..self.name.." at "..minetest.pos_to_string(vector.round(pos)))
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
mcl_mobs.custom_biomecheck = nil
|
mcl_mobs.custom_biomecheck = nil
|
||||||
|
|
Loading…
Reference in a new issue