forked from VoxeLibre/VoxeLibre
Compare commits
8 Commits
master
...
fix-has_ro
Author | SHA1 | Date |
---|---|---|
teknomunk | a17c6b0745 | |
teknomunk | d42043a7cf | |
teknomunk | c7fd065f2f | |
teknomunk | 41c3524646 | |
teknomunk | e2636f6cc9 | |
teknomunk | bea6a9fd06 | |
teknomunk | 377c507529 | |
teknomunk | ce0a34d667 |
|
@ -737,7 +737,7 @@ local function get_water_spawn(p)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function has_room(self,pos)
|
local function has_room(self,pos)
|
||||||
local cb = self.collisionbox
|
local cb = self.spawnbox or self.collisionbox
|
||||||
local nodes = {}
|
local nodes = {}
|
||||||
if self.fly_in then
|
if self.fly_in then
|
||||||
local t = type(self.fly_in)
|
local t = type(self.fly_in)
|
||||||
|
@ -748,18 +748,73 @@ local function has_room(self,pos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
table.insert(nodes,"air")
|
table.insert(nodes,"air")
|
||||||
local x = cb[4] - cb[1]
|
|
||||||
local y = cb[5] - cb[2]
|
local p1 = vector.offset(pos,cb[1],cb[2] + 1,cb[3])
|
||||||
local z = cb[6] - cb[3]
|
p1.x = math.floor(p1.x)
|
||||||
local r = math.ceil(x * y * z)
|
p1.y = math.floor(p1.y)
|
||||||
local p1 = vector.offset(pos,cb[1],cb[2],cb[3])
|
p1.z = math.floor(p1.z)
|
||||||
local p2 = vector.offset(pos,cb[4],cb[5],cb[6])
|
|
||||||
local n = #minetest.find_nodes_in_area(p1,p2,nodes) or 0
|
local cb_height = cb[5] - cb[2]
|
||||||
if r > n then
|
local p2 = vector.offset(p1,cb[4] - cb[1], cb_height, cb[6] - cb[3])
|
||||||
minetest.log("warning","[mcl_mobs] No room for mob "..self.name.." at "..minetest.pos_to_string(vector.round(pos)))
|
p2.x = math.ceil(p2.x) - 1
|
||||||
return false
|
p2.y = math.ceil(p2.y) - 1
|
||||||
|
p2.z = math.ceil(p2.z) - 1
|
||||||
|
|
||||||
|
-- Check if the entire spawn volume is free
|
||||||
|
local dx = p2.x - p1.x + 1
|
||||||
|
local dy = p2.y - p1.y + 1
|
||||||
|
local dz = p2.z - p1.z + 1
|
||||||
|
local found_nodes = minetest.find_nodes_in_area(p1,p2,nodes) or 0
|
||||||
|
local n = #found_nodes
|
||||||
|
if n == ( dx * dy * dz ) then return true end
|
||||||
|
|
||||||
|
-- If we don't have an implementation of get_node_boxes, we can't check for sub-node space
|
||||||
|
if not minetest.get_node_boxes then return false end
|
||||||
|
|
||||||
|
-- Check if it's possible for a sub-node space check to succeed
|
||||||
|
local needed_in_bottom_section = (dx * dz * ( dy - 1))
|
||||||
|
if n < needed_in_bottom_section then return false end
|
||||||
|
|
||||||
|
-- Make sure the entire volume except for the top level is free before checking the top layer
|
||||||
|
if dy > 1 then
|
||||||
|
-- Remove nodes in the top layer from the count
|
||||||
|
for i = 1,#found_nodes do
|
||||||
|
if found_nodes[i].y == p2.y then
|
||||||
|
n = n - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If the entire volume except the top layer isn't air (or nodes) then we can't spawn this mob here
|
||||||
|
if n < needed_in_bottom_section 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 test_pos = vector.new(x,p2.y,z)
|
||||||
|
local node = minetest.get_node(test_pos) or { name = "ignore" }
|
||||||
|
local cache_name = string.format("%s-%d", node.name, node.param2)
|
||||||
|
if not processed[cache_name] then
|
||||||
|
-- Calculate node bounding box and select the lowest y value
|
||||||
|
local boxes = minetest.get_node_boxes("collision_box", test_pos, node)
|
||||||
|
for i = 1,#boxes do
|
||||||
|
local box = boxes[i]
|
||||||
|
local y_test = box[2] + 0.5
|
||||||
|
if y_test < top_layer_height then top_layer_height = y_test end
|
||||||
|
|
||||||
|
local y_test = box[5] + 0.5
|
||||||
|
if y_test < top_layer_height then top_layer_height = y_test end
|
||||||
|
end
|
||||||
|
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
|
||||||
|
|
|
@ -67,6 +67,7 @@ local spider = {
|
||||||
curiosity = 10,
|
curiosity = 10,
|
||||||
head_yaw="z",
|
head_yaw="z",
|
||||||
collisionbox = {-0.7, -0.01, -0.7, 0.7, 0.89, 0.7},
|
collisionbox = {-0.7, -0.01, -0.7, 0.7, 0.89, 0.7},
|
||||||
|
spawnbox = {-1.2, -0.01, -1.2, 1.2, 0.89, 1.2},
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_mc_spider.b3d",
|
mesh = "mobs_mc_spider.b3d",
|
||||||
textures = {
|
textures = {
|
||||||
|
|
Loading…
Reference in New Issue