916ddcba93
Change dynamic_data now containing pointer to current state instead of name Remove __<state> suffix for all entities
214 lines
6.8 KiB
Lua
214 lines
6.8 KiB
Lua
-------------------------------------------------------------------------------
|
|
-- Mob Framework Mod by Sapier
|
|
--
|
|
-- You may copy, use, modify or do nearly anything except removing this
|
|
-- copyright notice.
|
|
-- And of course you are NOT allow to pretend you have written it.
|
|
--
|
|
--! @file shadows.lua
|
|
--! @brief spawn algorithm for in shadow spawning
|
|
--! @copyright Sapier
|
|
--! @author Sapier
|
|
--! @date 2012-08-09
|
|
--
|
|
--! @addtogroup spawn_algorithms
|
|
--! @{
|
|
-- Contact sapier a t gmx net
|
|
-------------------------------------------------------------------------------
|
|
|
|
local SHADOWS_SPAWNER_SURFACES = { "default:stone",
|
|
"default:gravel",
|
|
"default:dirt",
|
|
"default:sand" }
|
|
local SHADOWS_SPAWNER_SUFFIX = "_shadows"
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- name: mobf_spawner_in_shadows_spawner_spawnfunc(spawning_data,pos,min_y,max_y)
|
|
--
|
|
--! @brief function to spawn a spawner entity
|
|
--
|
|
--! @param spawning_data spawning configuration
|
|
--! @param pos position do spawn
|
|
--! @param min_y minimum y value of generated chunk
|
|
--! @param max_y maximum y value of generated chunk
|
|
-------------------------------------------------------------------------------
|
|
function mobf_spawner_in_shadows_spawner_spawnfunc(spawning_data,pos,min_y,max_y)
|
|
local starttime = mobf_get_time_ms()
|
|
pos.y = math.floor(math.random(min_y,max_y) + 0.5)
|
|
|
|
local min_light_around = mobf_min_light_around(pos,2,0.5)
|
|
local air_around_list = minetest.find_nodes_in_area(
|
|
{ x=pos.x-2,y=pos.y-2,z=pos.z-2 },
|
|
{ x=pos.x+2,y=pos.y+2,z=pos.z+2},
|
|
{ "air","ignore" } )
|
|
local air_around = 0
|
|
|
|
if air_around_list ~= nil then
|
|
air_around = #air_around_list
|
|
end
|
|
|
|
|
|
--if there's only sunlight around and we're not submerged
|
|
if min_light_around > 6 and
|
|
air_around > 60 then
|
|
mobf_warn_long_fct(starttime,"on_mapgen_shadows_spawner_spawnfunc","user_2")
|
|
return false
|
|
end
|
|
--mobf_print("MLA:" .. min_light_around .. " AA: " .. air_around .. " POS: " .. printpos(pos))
|
|
|
|
spawning.spawn_and_check(spawning_data.name .. "_spawner" .. SHADOWS_SPAWNER_SUFFIX,
|
|
pos,
|
|
"shadows_spawner")
|
|
mobf_warn_long_fct(starttime,"on_mapgen_shadows_spawner_spawnfunc","user_2")
|
|
return true
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- name: mobf_spawner_in_shadows_spawnfunc(spawning_data,pos)
|
|
--
|
|
--! @brief function to spawn a mob entity
|
|
--
|
|
--! @param spawning_data spawning configuration
|
|
--! @param pos position do spawn
|
|
-------------------------------------------------------------------------------
|
|
function mobf_spawner_in_shadows_spawnfunc(spawning_data,pos)
|
|
local node = minetest.get_node(pos)
|
|
|
|
if not mobf_contains(SHADOWS_SPAWNER_SURFACES,node.name) then
|
|
dbg_mobf.spawning_lvl3(
|
|
"MOBF: node ain't of correct type: " .. node.name)
|
|
return false
|
|
end
|
|
|
|
local pos_above = { x=pos.x,y=pos.y+1,z=pos.z }
|
|
|
|
--check if its always in shadows
|
|
for i=0.0,1,0.1 do
|
|
if mobf_max_light_around(pos_above,1,i) > 6 then
|
|
return false
|
|
end
|
|
end
|
|
|
|
spawning.spawn_and_check(spawning_data.name,pos_above,"shadows")
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- name: mobf_spawn_in_shadows(spawning_data)
|
|
--
|
|
--! @brief find a place with low light to spawn an mob
|
|
--
|
|
--! @param spawning_data spawning configuration
|
|
-------------------------------------------------------------------------------
|
|
|
|
function mobf_spawner_initialize_in_shadows_abm(spawning_data)
|
|
|
|
minetest.log(LOGLEVEL_INFO,
|
|
"MOBF:\tregistering shadow spawn abm callback for mob "..
|
|
spawning_data.name)
|
|
|
|
local media = nil
|
|
|
|
if spawning_data.environment ~= nil and
|
|
spawning_data.environment.media ~= nil then
|
|
media = spawning_data.environment.media
|
|
end
|
|
|
|
minetest.register_abm({
|
|
nodenames = SHADOWS_SPAWNER_SURFACES,
|
|
neighbors = media,
|
|
interval = 60,
|
|
chance = math.floor(1/spawning_data.rate),
|
|
action = function(pos, node, active_object_count, active_object_count_wider)
|
|
local starttime = mobf_get_time_ms()
|
|
local pos_above = {
|
|
x = pos.x,
|
|
y = pos.y + 1,
|
|
z = pos.z
|
|
}
|
|
|
|
--never try to spawn an mob at pos (0,0,0) it's initial entity spawnpos and
|
|
--used to find bugs in initial spawnpoint setting code
|
|
if mobf_pos_is_zero(pos) then
|
|
dbg_mobf.spawning_lvl1("MOBF: not spawning due to 0 pos")
|
|
mobf_warn_long_fct(starttime,"mobf_spawn_in_shadows")
|
|
return
|
|
end
|
|
|
|
--check if there s enough space above to place mob
|
|
if spawning_data.height ~= nil and mobf_air_above(pos,spawning_data.height) ~= true then
|
|
dbg_mobf.spawning_lvl3("MOBF: height requirement not met")
|
|
mobf_warn_long_fct(starttime,"mobf_spawn_in_shadows")
|
|
return
|
|
end
|
|
|
|
--check if pos is ok
|
|
if not environment.evaluate_state(
|
|
spawning.pos_quality(spawning_data,pos_above),
|
|
LT_SAFE_POS) then
|
|
mobf_warn_long_fct(starttime,"mobf_spawn_in_shadows")
|
|
return
|
|
end
|
|
|
|
--check population density
|
|
if mobf_mob_around(spawning_data.name,
|
|
spawning_data.name_secondary,
|
|
pos_above,spawning_data.density,true) > 0 then
|
|
mobf_warn_long_fct(starttime,"mobf_spawn_in_shadows")
|
|
return
|
|
end
|
|
|
|
mobf_spawner_in_shadows_spawner_spawnfunc(spawning_data,pos)
|
|
mobf_warn_long_fct(starttime,"mobf_spawn_in_shadows")
|
|
end,
|
|
})
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- name: mobf_spawner_initialize_in_shadows_mapgen(spawning_data)
|
|
--
|
|
--! @brief initialize in shadows spawner
|
|
--
|
|
--! @param spawning_data spawning configuration
|
|
-------------------------------------------------------------------------------
|
|
function mobf_spawner_initialize_in_shadows_mapgen(spawning_data)
|
|
|
|
spawning.register_spawner_entity(
|
|
spawning_data,
|
|
mobf_spawner_in_shadows_spawnfunc,
|
|
nil,
|
|
SHADOWS_SPAWNER_SUFFIX
|
|
)
|
|
|
|
if minetest.world_setting_get("mobf_delayed_spawning") then
|
|
minetest.register_on_generated(function(minp, maxp, seed)
|
|
local job = {
|
|
callback = spawning.divide_mapgen_entity_jobfunc,
|
|
data = {
|
|
minp = minp,
|
|
maxp = maxp,
|
|
spawning_data = spawning_data,
|
|
spawnfunc = mobf_spawner_in_shadows_spawner_spawnfunc,
|
|
maxtries = 5,
|
|
func = spawning.divide_mapgen_entity_jobfunc,
|
|
}
|
|
}
|
|
mobf_job_queue.add_job(job)
|
|
end)
|
|
else
|
|
--add mob spawner on map generation
|
|
minetest.register_on_generated(function(minp, maxp, seed)
|
|
local starttime = mobf_get_time_ms()
|
|
spawning.divide_mapgen_entity(minp,maxp,
|
|
spawning_data,
|
|
mobf_spawner_in_shadows_spawner_spawnfunc)
|
|
mobf_warn_long_fct(starttime,"on_mapgen " .. spawning_data.name,"mapgen")
|
|
end) --register mapgen
|
|
end
|
|
end
|
|
|
|
--!@}
|
|
|
|
spawning.register_spawn_algorithm("shadows", mobf_spawner_initialize_in_shadows_abm)
|
|
spawning.register_spawn_algorithm( "shadows_spawner",
|
|
mobf_spawner_initialize_in_shadows_mapgen,
|
|
spawning.register_cleanup_spawner) |