Added daytime check
Fixed collisionbox check Fixed relative/absolute height check Added (partial) spawndef check Added support for spawning multiple entities at oncemaster
parent
00989dd1c6
commit
3c9262a1ac
14
README.txt
14
README.txt
|
@ -97,8 +97,16 @@ Spawning definition:
|
||||||
deviation = 2, -- maximum number of nodes not matching flat check
|
deviation = 2, -- maximum number of nodes not matching flat check
|
||||||
},
|
},
|
||||||
|
|
||||||
|
daytimes = -- do only spawn within these daytimes
|
||||||
|
{
|
||||||
|
daytime_def_1,
|
||||||
|
daytime_def_2,
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
collisionbox = {}, -- collisionbox of entity to spawn (usually same as used for entiy itself)
|
collisionbox = {}, -- collisionbox of entity to spawn (usually same as used for entiy itself)
|
||||||
spawn_interval = 200, -- [MANDATORY] interval to try to spawn a entity
|
spawn_interval = 200, -- [MANDATORY] interval to try to spawn a entity
|
||||||
|
spawns_per_interval = 1, -- try to spawn multiple mobs (if time available)
|
||||||
custom_check = fct(pos), -- a custom check to be called return true for pass, false for not pass
|
custom_check = fct(pos), -- a custom check to be called return true for pass, false for not pass
|
||||||
cyclic_spawning = true -- spawn per spawner step (defaults to true)
|
cyclic_spawning = true -- spawn per spawner step (defaults to true)
|
||||||
}
|
}
|
||||||
|
@ -152,6 +160,12 @@ spawn_inside definition (list of nodenames):
|
||||||
"default:water_flowing"
|
"default:water_flowing"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Daytime definition:
|
||||||
|
{
|
||||||
|
begin = 0.0, --minimum daytime
|
||||||
|
stop = 0.25, --maximum daytime
|
||||||
|
}
|
||||||
|
|
||||||
Statistics:
|
Statistics:
|
||||||
{
|
{
|
||||||
session =
|
session =
|
||||||
|
|
9
api.lua
9
api.lua
|
@ -15,7 +15,14 @@
|
||||||
function adv_spawning.register(spawner_name,spawning_def)
|
function adv_spawning.register(spawner_name,spawning_def)
|
||||||
if adv_spawning.spawner_definitions[spawner_name] == nil then
|
if adv_spawning.spawner_definitions[spawner_name] == nil then
|
||||||
|
|
||||||
--TODO validate spawning definition
|
|
||||||
|
if not adv_spawning.verify_check_entities_around(spawning_def.entities_around) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if not adv_spawning.verify_check_nodes_around(spawning_def.nodes_around) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
adv_spawning.spawner_definitions[spawner_name] = spawning_def
|
adv_spawning.spawner_definitions[spawner_name] = spawning_def
|
||||||
print("ADV_SPAWNING: registering spawner \"" .. spawner_name .. "\"")
|
print("ADV_SPAWNING: registering spawner \"" .. spawner_name .. "\"")
|
||||||
|
|
3
init.lua
3
init.lua
|
@ -8,7 +8,7 @@
|
||||||
--
|
--
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
local version = "0.0.2"
|
local version = "0.0.3"
|
||||||
|
|
||||||
if adv_spawning ~= nil then
|
if adv_spawning ~= nil then
|
||||||
minetest.log("error","MOD: adv_spawning requires adv_spawning variable to be available")
|
minetest.log("error","MOD: adv_spawning requires adv_spawning variable to be available")
|
||||||
|
@ -22,6 +22,7 @@ adv_spawning = {}
|
||||||
local adv_modpath = minetest.get_modpath("adv_spawning")
|
local adv_modpath = minetest.get_modpath("adv_spawning")
|
||||||
|
|
||||||
dofile (adv_modpath .. "/internal.lua")
|
dofile (adv_modpath .. "/internal.lua")
|
||||||
|
dofile (adv_modpath .. "/spawndef_checks.lua")
|
||||||
dofile (adv_modpath .. "/api.lua")
|
dofile (adv_modpath .. "/api.lua")
|
||||||
dofile (adv_modpath .. "/spawn_seed.lua")
|
dofile (adv_modpath .. "/spawn_seed.lua")
|
||||||
|
|
||||||
|
|
196
internal.lua
196
internal.lua
|
@ -15,6 +15,12 @@
|
||||||
-- @return maximum of a and b
|
-- @return maximum of a and b
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
function MAX(a,b)
|
function MAX(a,b)
|
||||||
|
if a == nil then
|
||||||
|
return b
|
||||||
|
end
|
||||||
|
if b == nil then
|
||||||
|
return a
|
||||||
|
end
|
||||||
if a > b then
|
if a > b then
|
||||||
return a
|
return a
|
||||||
else
|
else
|
||||||
|
@ -29,6 +35,12 @@ end
|
||||||
-- @return minimum of a and b
|
-- @return minimum of a and b
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
function MIN(a,b)
|
function MIN(a,b)
|
||||||
|
if a == nil then
|
||||||
|
return b
|
||||||
|
end
|
||||||
|
if b == nil then
|
||||||
|
return a
|
||||||
|
end
|
||||||
if a > b then
|
if a > b then
|
||||||
return b
|
return b
|
||||||
else
|
else
|
||||||
|
@ -272,6 +284,11 @@ function adv_spawning.handlespawner(spawnername,spawnerpos,minp,maxp)
|
||||||
local permanent_error = false
|
local permanent_error = false
|
||||||
local spawndef = adv_spawning.spawner_definitions[spawnername]
|
local spawndef = adv_spawning.spawner_definitions[spawnername]
|
||||||
|
|
||||||
|
if not adv_spawning.check_daytime(spawndef.daytimes) then
|
||||||
|
adv_spawning.log("info","didn't meet daytime check")
|
||||||
|
return false,nil
|
||||||
|
end
|
||||||
|
|
||||||
local max_x = spawnerpos.x + adv_spawning.spawner_distance/2
|
local max_x = spawnerpos.x + adv_spawning.spawner_distance/2
|
||||||
local min_x = spawnerpos.x - adv_spawning.spawner_distance/2
|
local min_x = spawnerpos.x - adv_spawning.spawner_distance/2
|
||||||
|
|
||||||
|
@ -298,7 +315,7 @@ function adv_spawning.handlespawner(spawnername,spawnerpos,minp,maxp)
|
||||||
new_pos.x = math.random(min_x,max_x)
|
new_pos.x = math.random(min_x,max_x)
|
||||||
new_pos.z = math.random(min_z,max_z)
|
new_pos.z = math.random(min_z,max_z)
|
||||||
|
|
||||||
local continue = false
|
|
||||||
|
|
||||||
--check if entity is configured to spawn at surface
|
--check if entity is configured to spawn at surface
|
||||||
if spawndef.relative_height == nil or
|
if spawndef.relative_height == nil or
|
||||||
|
@ -308,7 +325,9 @@ function adv_spawning.handlespawner(spawnername,spawnerpos,minp,maxp)
|
||||||
spawndef.spawn_inside)
|
spawndef.spawn_inside)
|
||||||
else
|
else
|
||||||
new_pos.y = adv_spawning.get_relative_pos(lower_y,upper_y,new_pos,
|
new_pos.y = adv_spawning.get_relative_pos(lower_y,upper_y,new_pos,
|
||||||
spawndef.spawn_inside,spawndef.relative_height)
|
spawndef.spawn_inside,
|
||||||
|
spawndef.relative_height,
|
||||||
|
spawndef.absolute_height)
|
||||||
end
|
end
|
||||||
|
|
||||||
--check if we did found a position within relative range
|
--check if we did found a position within relative range
|
||||||
|
@ -317,126 +336,112 @@ function adv_spawning.handlespawner(spawnername,spawnerpos,minp,maxp)
|
||||||
adv_spawning.log("info",
|
adv_spawning.log("info",
|
||||||
minetest.pos_to_string(new_pos) .. " didn't find a suitable y pos "
|
minetest.pos_to_string(new_pos) .. " didn't find a suitable y pos "
|
||||||
.. lower_y .. "<-->" .. upper_y )
|
.. lower_y .. "<-->" .. upper_y )
|
||||||
continue = true
|
return false,nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--check absolute height
|
--check absolute height
|
||||||
if not continue and
|
if not adv_spawning.check_absolute_height(new_pos,spawndef.absolute_height) then
|
||||||
not adv_spawning.check_absolute_height(new_pos,spawndef.absolute_height) then
|
|
||||||
adv_spawning.log("info",
|
adv_spawning.log("info",
|
||||||
minetest.pos_to_string(new_pos) .. " didn't meet absolute height check")
|
minetest.pos_to_string(new_pos) .. " didn't meet absolute height check")
|
||||||
continue = true
|
return false,true
|
||||||
permanent_error = true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--check surface
|
--check surface
|
||||||
--NOTE needs to be done before collision box check as y pos may be modified there
|
--NOTE needs to be done before collision box check as y pos may be modified there
|
||||||
if not continue and
|
if not adv_spawning.check_surface(new_pos,
|
||||||
not adv_spawning.check_surface(new_pos,
|
|
||||||
spawndef.surfaces,
|
spawndef.surfaces,
|
||||||
spawndef.relative_height,
|
spawndef.relative_height,
|
||||||
spawndef.spawn_inside) then
|
spawndef.spawn_inside) then
|
||||||
adv_spawning.log("info",
|
adv_spawning.log("info",
|
||||||
minetest.pos_to_string(new_pos) .. " didn't meet surface check")
|
minetest.pos_to_string(new_pos) .. " didn't meet surface check")
|
||||||
continue = true
|
return false,nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--flat area check
|
--flat area check
|
||||||
--NOTE needs to be done before collision box check as y pos may be modified there
|
--NOTE needs to be done before collision box check as y pos may be modified there
|
||||||
if not continue and
|
if not adv_spawning.check_flat_area(new_pos,
|
||||||
not adv_spawning.check_flat_area(new_pos,
|
|
||||||
spawndef.flat_area,
|
spawndef.flat_area,
|
||||||
spawndef.spawn_inside,
|
spawndef.spawn_inside,
|
||||||
spawndef.surfaces) then
|
spawndef.surfaces) then
|
||||||
adv_spawning.log("info",
|
adv_spawning.log("info",
|
||||||
minetest.pos_to_string(new_pos) .. " didn't meet flat area check")
|
minetest.pos_to_string(new_pos) .. " didn't meet flat area check")
|
||||||
continue = true
|
return false,nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--check collisionbox
|
--check collisionbox
|
||||||
if not continue then
|
local checkresult,y_pos =
|
||||||
local checkresult,y_pos =
|
adv_spawning.check_collisionbox(new_pos,
|
||||||
adv_spawning.check_collisionbox(new_pos,
|
spawndef.collisionbox,spawndef.spawn_inside)
|
||||||
spawndef.collisionbox,spawndef.spawn_inside)
|
|
||||||
|
|
||||||
if checkresult and y_pos ~= nil then
|
if checkresult and y_pos ~= nil then
|
||||||
new_pos.y = y_pos
|
new_pos.y = y_pos
|
||||||
end
|
end
|
||||||
|
|
||||||
if not checkresult then
|
if not checkresult then
|
||||||
continue = true
|
adv_spawning.log("info",
|
||||||
end
|
minetest.pos_to_string(new_pos) .. " didn't meet collisionbox check")
|
||||||
|
return false,nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--check entities around
|
--check entities around
|
||||||
if not continue and
|
if not adv_spawning.check_entities_around(new_pos,spawndef.entities_around) then
|
||||||
not adv_spawning.check_entities_around(new_pos,spawndef.entities_around) then
|
|
||||||
adv_spawning.log("info",
|
adv_spawning.log("info",
|
||||||
minetest.pos_to_string(new_pos) .. " didn't meet entities check")
|
minetest.pos_to_string(new_pos) .. " didn't meet entities check")
|
||||||
continue = true
|
return false,nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--check nodes around
|
--check nodes around
|
||||||
if not continue and
|
if not adv_spawning.check_nodes_around(new_pos,spawndef.nodes_around) then
|
||||||
not adv_spawning.check_nodes_around(new_pos,spawndef.nodes_around) then
|
|
||||||
adv_spawning.log("info",
|
adv_spawning.log("info",
|
||||||
minetest.pos_to_string(new_pos) .. " didn't meet nodes check")
|
minetest.pos_to_string(new_pos) .. " didn't meet nodes check")
|
||||||
continue = true
|
return false,nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--check light around
|
--check light around
|
||||||
if not continue and
|
if not adv_spawning.check_light_around(new_pos,spawndef.light_around) then
|
||||||
not adv_spawning.check_light_around(new_pos,spawndef.light_around) then
|
|
||||||
adv_spawning.log("info",
|
adv_spawning.log("info",
|
||||||
minetest.pos_to_string(new_pos) .. " didn't meet light check")
|
minetest.pos_to_string(new_pos) .. " didn't meet light check")
|
||||||
continue = true
|
return false,nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--check humidity
|
--check humidity
|
||||||
if not continue and
|
if not adv_spawning.check_humidity_around(new_pos,spawndef.humidity_around) then
|
||||||
not adv_spawning.check_humidity_around(new_pos,spawndef.humidity_around) then
|
|
||||||
adv_spawning.log("info",
|
adv_spawning.log("info",
|
||||||
minetest.pos_to_string(new_pos) .. " didn't meet humidity check")
|
minetest.pos_to_string(new_pos) .. " didn't meet humidity check")
|
||||||
continue = true
|
return false,nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--check temperature
|
--check temperature
|
||||||
if not continue and
|
if not adv_spawning.check_temperature_around(new_pos,spawndef.temperature_around) then
|
||||||
not adv_spawning.check_temperature_around(new_pos,spawndef.temperature_around) then
|
|
||||||
adv_spawning.log("info",
|
adv_spawning.log("info",
|
||||||
minetest.pos_to_string(new_pos) .. " didn't meet temperature check")
|
minetest.pos_to_string(new_pos) .. " didn't meet temperature check")
|
||||||
continue = true
|
return false,nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--custom check
|
--custom check
|
||||||
if not continue and
|
if (spawndef.custom_check ~= nil and
|
||||||
(spawndef.custom_check ~= nil and
|
|
||||||
type(spawndef.custom_check) == "function") then
|
type(spawndef.custom_check) == "function") then
|
||||||
|
|
||||||
if not spawndef.custom_check(new_pos) then
|
if not spawndef.custom_check(new_pos) then
|
||||||
adv_spawning.log("info",
|
adv_spawning.log("info",
|
||||||
minetest.pos_to_string(new_pos) .. " didn't meet custom check")
|
minetest.pos_to_string(new_pos) .. " didn't meet custom check")
|
||||||
continue = true
|
return false,nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--do spawn
|
--do spawn
|
||||||
if not continue then
|
--print("Now spawning: " .. spawndef.spawnee .. " at " ..
|
||||||
print("Now spawning: " .. spawndef.spawnee .. " at " ..
|
-- minetest.pos_to_string(new_pos))
|
||||||
minetest.pos_to_string(new_pos))
|
|
||||||
|
|
||||||
if type(spawndef.spawnee) == "function" then
|
if type(spawndef.spawnee) == "function" then
|
||||||
spawndef.spawnee(new_pos)
|
spawndef.spawnee(new_pos)
|
||||||
else
|
else
|
||||||
minetest.add_entity(new_pos,spawndef.spawnee)
|
minetest.add_entity(new_pos,spawndef.spawnee)
|
||||||
end
|
|
||||||
|
|
||||||
adv_spawning.statistics.session.entities_created =
|
|
||||||
adv_spawning.statistics.session.entities_created +1
|
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return false,permanent_error
|
adv_spawning.statistics.session.entities_created =
|
||||||
|
adv_spawning.statistics.session.entities_created +1
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
@ -455,14 +460,23 @@ function adv_spawning.get_surface(y_min,y_max,new_pos,spawn_inside)
|
||||||
local spawnable_nodes =
|
local spawnable_nodes =
|
||||||
minetest.find_nodes_in_area(bottom_pos, top_pos, spawn_inside)
|
minetest.find_nodes_in_area(bottom_pos, top_pos, spawn_inside)
|
||||||
|
|
||||||
|
if #spawnable_nodes == 0 then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local spawnable_node_passed = false
|
||||||
|
|
||||||
for i=y_max, y_min, -1 do
|
for i=y_max, y_min, -1 do
|
||||||
local pos = { x=new_pos.x,z=new_pos.z,y=i}
|
local pos = { x=new_pos.x,z=new_pos.z,y=i}
|
||||||
if not adv_spawning.contains_pos(spawnable_nodes,pos) then
|
if not adv_spawning.contains_pos(spawnable_nodes,pos) then
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
|
|
||||||
if node.name ~= "ignore" then
|
if node.name ~= "ignore" and
|
||||||
|
spawnable_node_passed then
|
||||||
return i+1
|
return i+1
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
spawnable_node_passed = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -476,13 +490,19 @@ end
|
||||||
-- @param new_pos position to spawn at
|
-- @param new_pos position to spawn at
|
||||||
-- @param spawn_inside nodes to spawn at
|
-- @param spawn_inside nodes to spawn at
|
||||||
-- @param relative_height
|
-- @param relative_height
|
||||||
|
-- @param absolute_height
|
||||||
-- @return y-value of last spawnable node
|
-- @return y-value of last spawnable node
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
function adv_spawning.get_relative_pos(y_min,y_max,new_pos,spawn_inside,relative_height)
|
function adv_spawning.get_relative_pos(y_min,y_max,new_pos,spawn_inside,relative_height,absolute_height)
|
||||||
local y_val = adv_spawning.get_surface(y_min,y_max,new_pos,spawn_inside)
|
local y_val = adv_spawning.get_surface(y_min,y_max,new_pos,spawn_inside)
|
||||||
|
|
||||||
if y_val == nil then
|
if y_val == nil then
|
||||||
return nil
|
if (relative_height.min ~= nil or
|
||||||
|
relative_height.max ~= nil) then
|
||||||
|
return nil
|
||||||
|
else
|
||||||
|
y_val = y_min
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local top_pos = { x=new_pos.x, z=new_pos.z, y=y_max}
|
local top_pos = { x=new_pos.x, z=new_pos.z, y=y_max}
|
||||||
|
@ -498,12 +518,21 @@ function adv_spawning.get_relative_pos(y_min,y_max,new_pos,spawn_inside,relative
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
top_pos.y = MIN(absolute_height.max,top_pos.y)
|
||||||
|
bottom_pos.y = MAX(absolute_height.min,bottom_pos.y)
|
||||||
|
|
||||||
|
if top_pos.y < bottom_pos.y then
|
||||||
|
--print("Invalid interval: " .. bottom_pos.y .. "<-->" .. top_pos.y)
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
local spawnable_nodes =
|
local spawnable_nodes =
|
||||||
minetest.find_nodes_in_area(bottom_pos, top_pos, spawn_inside)
|
minetest.find_nodes_in_area(bottom_pos, top_pos, spawn_inside)
|
||||||
|
|
||||||
if #spawnable_nodes > 0 then
|
if #spawnable_nodes > 0 then
|
||||||
return spawnable_nodes[math.random(1,#spawnable_nodes)].y
|
return spawnable_nodes[math.random(1,#spawnable_nodes)].y
|
||||||
else
|
else
|
||||||
|
--print("no suitable nodes" .. bottom_pos.y .. "<-->" .. top_pos.y)
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -609,6 +638,46 @@ function adv_spawning.contains(table_to_check,value)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- @function [parent=#adv_spawning] check_daytimes
|
||||||
|
-- @param table_to_check
|
||||||
|
-- @return true/false
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
function adv_spawning.check_daytime(daytimedefs)
|
||||||
|
if daytimedefs == nil then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local current_time = minetest.get_timeofday()
|
||||||
|
local match = false
|
||||||
|
|
||||||
|
for i=1,#daytimedefs,1 do
|
||||||
|
if daytimedefs[i].begin ~= nil and
|
||||||
|
daytimedefs[i].stop ~= nil then
|
||||||
|
|
||||||
|
if current_time < daytimedefs[i].stop and
|
||||||
|
current_time > daytimedefs[i].begin then
|
||||||
|
match = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if daytimedefs[i].begin ~= nil and
|
||||||
|
current_time > daytimedefs[i].begin then
|
||||||
|
match = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
if daytimedefs[i].stop ~= nil and
|
||||||
|
current_time < daytimedefs[i].stop then
|
||||||
|
match = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return match
|
||||||
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- @function [parent=#adv_spawning] check_nodes_around
|
-- @function [parent=#adv_spawning] check_nodes_around
|
||||||
-- @param pos position to validate
|
-- @param pos position to validate
|
||||||
|
@ -632,12 +701,12 @@ function adv_spawning.check_nodes_around(pos,nodes_around)
|
||||||
|
|
||||||
if nodes_around[i].type == "MIN" then
|
if nodes_around[i].type == "MIN" then
|
||||||
if found == nil then
|
if found == nil then
|
||||||
print("not enough: " .. dump(nodes_around[i].name) .. " around")
|
--print("not enough: " .. dump(nodes_around[i].name) .. " around")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if found ~= nil then
|
if found ~= nil then
|
||||||
print("to many: " .. dump(nodes_around[i].name) .. " around " .. dump(found))
|
--print("to many: " .. dump(nodes_around[i].name) .. " around " .. dump(found))
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -654,11 +723,16 @@ function adv_spawning.check_nodes_around(pos,nodes_around)
|
||||||
|
|
||||||
if nodes_around[i].type == "MIN" and
|
if nodes_around[i].type == "MIN" and
|
||||||
#found_nodes < nodes_around[i].threshold then
|
#found_nodes < nodes_around[i].threshold then
|
||||||
|
--print("Found MIN: " .. dump(nodes_around[i].name) ..
|
||||||
|
-- "\n at locations: " .. dump(found_nodes))
|
||||||
|
--print ("Only " .. #found_nodes .. "/" .. nodes_around[i].threshold)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
if nodes_around[i].type == "MAX" and
|
if nodes_around[i].type == "MAX" and
|
||||||
#found_nodes > nodes_around[i].threshold then
|
#found_nodes > nodes_around[i].threshold then
|
||||||
|
--print("Found MAX: " .. dump(nodes_around[i].name) ..
|
||||||
|
-- "\n at locations: " .. dump(found_nodes))
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -682,7 +756,6 @@ function adv_spawning.check_entities_around(pos,entities_around)
|
||||||
local entity_in_range =
|
local entity_in_range =
|
||||||
minetest.get_objects_inside_radius(pos, entities_around[i].distance)
|
minetest.get_objects_inside_radius(pos, entities_around[i].distance)
|
||||||
|
|
||||||
|
|
||||||
if entities_around[i].entityname == nil then
|
if entities_around[i].entityname == nil then
|
||||||
if entities_around[i].type == "MIN" and
|
if entities_around[i].type == "MIN" and
|
||||||
#entity_in_range < entities_around[i].threshold then
|
#entity_in_range < entities_around[i].threshold then
|
||||||
|
@ -942,8 +1015,7 @@ function adv_spawning.check_collisionbox(pos,collisionbox,spawn_inside)
|
||||||
for z=minp.z,maxp.z,1 do
|
for z=minp.z,maxp.z,1 do
|
||||||
for x=minp.x,maxp.x,1 do
|
for x=minp.x,maxp.x,1 do
|
||||||
local checkpos = {x=x,y=y,z=z}
|
local checkpos = {x=x,y=y,z=z}
|
||||||
|
if not adv_spawning.is_same_pos(checkpos,lastpos) then
|
||||||
if adv_spawning.is_same_pos(checkpos,lastpos) then
|
|
||||||
local node = minetest.get_node(checkpos)
|
local node = minetest.get_node(checkpos)
|
||||||
|
|
||||||
if not adv_spawning.contains(spawn_inside,node.name) then
|
if not adv_spawning.contains(spawn_inside,node.name) then
|
||||||
|
|
|
@ -46,28 +46,38 @@ function adv_spawning.seed_step(self,dtime)
|
||||||
local rand_spawner = math.random(1,#self.pending_spawners)
|
local rand_spawner = math.random(1,#self.pending_spawners)
|
||||||
local key = self.pending_spawners[rand_spawner]
|
local key = self.pending_spawners[rand_spawner]
|
||||||
|
|
||||||
|
local tries = 1
|
||||||
|
|
||||||
if adv_spawning.handlespawner(key,self.object:getpos()) then
|
if adv_spawning.spawner_definitions[key].spawns_per_interval ~= nil then
|
||||||
self.spawning_data[key] =
|
tries = adv_spawning.spawner_definitions[key].spawns_per_interval
|
||||||
adv_spawning.spawner_definitions[key].spawn_interval
|
|
||||||
else
|
|
||||||
self.spawning_data[key] =
|
|
||||||
adv_spawning.spawner_definitions[key].spawn_interval/4
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--check quota again
|
while tries > 0 do
|
||||||
adv_spawning.quota_leave()
|
|
||||||
if not adv_spawning.quota_enter() then
|
if adv_spawning.handlespawner(key,self.object:getpos()) then
|
||||||
return
|
self.spawning_data[key] =
|
||||||
|
adv_spawning.spawner_definitions[key].spawn_interval
|
||||||
|
else
|
||||||
|
self.spawning_data[key] =
|
||||||
|
adv_spawning.spawner_definitions[key].spawn_interval/4
|
||||||
|
end
|
||||||
|
|
||||||
|
--check quota again
|
||||||
|
adv_spawning.quota_leave()
|
||||||
|
if not adv_spawning.quota_enter() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
tries = tries -1
|
||||||
end
|
end
|
||||||
|
|
||||||
table.remove(self.pending_spawners,rand_spawner)
|
table.remove(self.pending_spawners,rand_spawner)
|
||||||
per_step_count = per_step_count +1
|
per_step_count = per_step_count +1
|
||||||
end
|
end
|
||||||
|
|
||||||
if (#self.pending_spawners > 0) then
|
-- if (#self.pending_spawners > 0) then
|
||||||
print("Handled " .. per_step_count .. " spawners, spawners left: " .. #self.pending_spawners)
|
-- print("Handled " .. per_step_count .. " spawners, spawners left: " .. #self.pending_spawners)
|
||||||
end
|
-- end
|
||||||
adv_spawning.quota_leave()
|
adv_spawning.quota_leave()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -221,7 +231,7 @@ function adv_spawning.seed_scan_for_applyable_spawners(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
if not continue then
|
if not continue then
|
||||||
self.spawning_data[key] = value.spawn_interval
|
self.spawning_data[key] = value.spawn_interval * math.random()
|
||||||
else
|
else
|
||||||
self.spawning_data[key] = nil
|
self.spawning_data[key] = nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- advanced spawning mod
|
||||||
|
--
|
||||||
|
--@license WTFP
|
||||||
|
--@copyright Sapier
|
||||||
|
--@author Sapier
|
||||||
|
--@date 2013-12-05
|
||||||
|
--
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- @function [parent=#adv_spawning] verify_check_entities_around
|
||||||
|
-- @param entities_around a spawndef entities_around config
|
||||||
|
-- @return true/false
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
function adv_spawning.verify_check_entities_around(entities_around)
|
||||||
|
if entities_around ~= nil then
|
||||||
|
|
||||||
|
for i=1,#entities_around,1 do
|
||||||
|
|
||||||
|
if type(entities_around[i].distance) ~= "number" then
|
||||||
|
print("ADV_SPAWNING: missing distance in entities_around definition")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if entities_around[i].type ~= "MIN" and
|
||||||
|
entities_around[i].type ~= "MAX" then
|
||||||
|
print("ADV_SPAWNING: invalid type \"" ..
|
||||||
|
dump(entities_around[i].type) ..
|
||||||
|
"\" in entities_around definition")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- @function [parent=#adv_spawning] verify_check_nodes_around
|
||||||
|
-- @param nodes_around a spawndef entities_around config
|
||||||
|
-- @return true/false
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
function adv_spawning.verify_check_nodes_around(nodes_around)
|
||||||
|
if nodes_around ~= nil then
|
||||||
|
for i=1,#nodes_around,1 do
|
||||||
|
|
||||||
|
if type(nodes_around[i].distance) ~= "number" then
|
||||||
|
print("ADV_SPAWNING: missing distance in entities_around definition")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if nodes_around[i].type ~= "MIN" and
|
||||||
|
nodes_around[i].type ~= "MAX" then
|
||||||
|
print("ADV_SPAWNING: invalid type \"" ..
|
||||||
|
dump(nodes_around[i].type) ..
|
||||||
|
"\" in entities_around definition")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if nodes_around[i].name == nil or
|
||||||
|
type(nodes_around[i].name) ~= "table" then
|
||||||
|
print("ADV_SPAWNING: invalid type of name \"" ..
|
||||||
|
type(nodes_around[i].name) .. "\"" .. " Data: " ..
|
||||||
|
dump(nodes_around[i].name) ..
|
||||||
|
" in nodes_around definition")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
Loading…
Reference in New Issue