2023-04-24 17:56:28 +03:00
--[[
Let the player craft Mob Spawners . Mobs are spawning randomly in a short intervals , giving the option of creating mob farms and grinders .
Copyright ( C ) 2016 - 2023 SaKeL < juraj.vajda @ gmail.com >
This library is free software ; you can redistribute it and / or
modify it pos the terms of the GNU Lesser General Public
License as published by the Free Software Foundation ; either
version 2.1 of the License , or ( at your option ) any later version .
This library is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public
License along with this library ; if not , write to juraj.vajda @ gmail.com
--]]
2016-10-08 21:54:26 +03:00
-- main tables
2023-04-24 17:56:28 +03:00
spawners_mobs = {
2023-04-25 07:34:49 +03:00
registered_spawners = { }
2023-04-24 17:56:28 +03:00
}
2023-04-25 07:34:49 +03:00
2023-04-24 17:56:28 +03:00
local max_obj_per_mapblock = tonumber ( minetest.settings : get ( ' max_objects_per_block ' ) )
local enable_particles = minetest.settings : get_bool ( ' enable_particles ' )
local tick_max = 30
local tick_short_max = 20
2016-10-08 21:54:26 +03:00
2023-04-25 07:34:49 +03:00
function spawners_mobs . register_spawner ( name , def )
def.mod_prefix = name : split ( ' : ' ) [ 1 ]
def.mob_name = name : split ( ' : ' ) [ 2 ]
-- Entity inside the spawner
local ent_name = ' spawners_mobs:dummy_ ' .. def.mod_prefix .. ' _ ' .. def.mob_name
local ent_def = {
hp_max = 1 ,
visual = def.dummy_visual or ' mesh ' ,
visual_size = def.dummy_size ,
collisionbox = { 0 , 0 , 0 , 0 , 0 , 0 } ,
mesh = def.dummy_mesh ,
textures = def.dummy_texture ,
physical = false ,
makes_footstep_sound = false ,
automatic_rotate = math.pi * - 3 ,
static_save = false ,
timer = 0 ,
on_activate = function ( self , staticdata , dtime_s )
self.object : set_velocity ( { x = 0 , y = 0 , z = 0 } )
self.object : set_acceleration ( { x = 0 , y = 0 , z = 0 } )
self.object : set_armor_groups ( { immortal = 1 } )
2023-04-24 17:56:28 +03:00
end
2023-04-25 07:34:49 +03:00
}
minetest.register_entity ( ent_name , ent_def )
-- Default spawner (active)
local node_def = { }
node_def.description = def.mod_prefix .. ' _ ' .. def.mob_name .. ' spawner '
node_def.paramtype = ' light '
node_def.paramtype2 = ' glasslikeliquidlevel '
node_def.drawtype = ' glasslike_framed_optional '
node_def.walkable = true
node_def.sounds = default.node_sound_metal_defaults ( )
node_def.sunlight_propagates = true
node_def.tiles = { ' spawners_mobs_spawner_16.png ' }
node_def.is_ground_content = false
node_def.groups = {
-- MTG
cracky = 1 ,
level = 2
}
node_def.stack_max = 1
node_def.light_source = 6
node_def.on_timer = spawners_mobs.on_timer
node_def.on_construct = function ( pos )
-- set meta
local meta = minetest.get_meta ( pos )
meta : set_int ( ' tick ' , 0 )
meta : set_int ( ' tick_short ' , 0 )
spawners_mobs.set_status ( pos , ' active ' )
spawners_mobs.tick_short ( pos )
end
node_def.after_place_node = function ( pos , placer , itemstack , pointed_thing )
local meta = minetest.get_meta ( pos )
meta : set_string ( ' owner ' , placer : get_player_name ( ) )
meta : set_string ( ' infotext ' , def.mob_name .. ' spawner \n owner: ' .. placer : get_player_name ( ) .. ' \n spawner is active ' )
end
node_def.on_destruct = function ( pos )
-- delete particles and remove dummy
spawners_mobs.set_status ( pos , ' waiting ' )
2023-04-24 17:56:28 +03:00
end
2023-04-25 07:34:49 +03:00
local node_name = ' spawners_mobs: ' .. def.mod_prefix .. ' _ ' .. def.mob_name .. ' _spawner '
minetest.register_node ( node_name , node_def )
spawners_mobs.registered_spawners [ node_name ] = def
-- Waiting spawner
local node_def_waiting = table.copy ( node_def )
node_name = ' spawners_mobs: ' .. def.mod_prefix .. ' _ ' .. def.mob_name .. ' _spawner_waiting '
node_def_waiting.description = def.mod_prefix .. ' _ ' .. def.mob_name .. ' spawner waiting '
node_def_waiting.tiles = {
{
name = ' spawners_mobs_spawner_waiting_animated_16.png ' ,
animation = {
type = ' vertical_frames ' ,
aspect_w = 16 ,
aspect_h = 16 ,
length = 2.0
}
}
}
node_def_waiting.groups = { cracky = 1 , level = 2 , not_in_creative_inventory = 1 }
node_def_waiting.light_source = 4
node_def_waiting.drop = ' spawners_mobs: ' .. def.mod_prefix .. ' _ ' .. def.mob_name .. ' _spawner '
node_def_waiting.on_timer = spawners_mobs.on_timer
node_def_waiting.on_construct = nil
node_def_waiting.after_place_node = nil
node_def_waiting.on_destruct = nil
minetest.register_node ( node_name , node_def_waiting )
spawners_mobs.registered_spawners [ node_name ] = def
-- Rusty spawner
local node_def_rusty = table.copy ( node_def )
node_name = ' spawners_mobs: ' .. def.mod_prefix .. ' _ ' .. def.mob_name .. ' _spawner_rusty '
node_def_rusty.description = def.mod_prefix .. ' _ ' .. def.mob_name .. ' spawner rusty '
node_def_rusty.tiles = { ' spawners_mobs_spawner_rusty.png ' }
node_def_rusty.groups = { cracky = 1 , level = 2 , not_in_creative_inventory = 1 }
node_def_rusty.drop = ' spawners_mobs: ' .. def.mod_prefix .. ' _ ' .. def.mob_name .. ' _spawner '
node_def_rusty.on_timer = nil
node_def_rusty.on_construct = nil
node_def_rusty.after_place_node = nil
node_def_rusty.on_destruct = nil
minetest.register_node ( node_name , node_def_rusty )
spawners_mobs.registered_spawners [ node_name ] = def
-- Recipes
local mob_egg = name
if def.egg_name_custom and def.egg_name_custom ~= ' ' then
mob_egg = def.egg_name_custom
end
if minetest.registered_items [ mob_egg ] then
-- recipes
minetest.register_craft ( {
output = ' spawners_mobs: ' .. def.mod_prefix .. ' _ ' .. def.mob_name .. ' _spawner ' ,
recipe = {
{ ' default:diamondblock ' , ' fire:flint_and_steel ' , ' default:diamondblock ' } ,
{ ' xpanes:bar_flat ' , mob_egg , ' xpanes:bar_flat ' } ,
{ ' default:diamondblock ' , ' xpanes:bar_flat ' , ' default:diamondblock ' } ,
}
} )
end
--
-- LBM
--
minetest.register_lbm ( {
name = ' spawners_mobs:start_nodetimer_ ' .. def.mod_prefix .. ' _ ' .. def.mob_name .. ' _spawner ' ,
nodenames = ' spawners_mobs: ' .. def.mod_prefix .. ' _ ' .. def.mob_name .. ' _spawner ' ,
action = function ( pos )
spawners_mobs.tick_short ( pos )
end ,
} )
2016-10-08 21:54:26 +03:00
end
2018-10-18 04:25:16 +03:00
--
2018-01-07 07:31:21 +03:00
-- Particles
2018-10-18 04:25:16 +03:00
--
2016-10-12 22:57:06 +03:00
function spawners_mobs . cloud_booom ( pos )
2023-04-25 07:34:49 +03:00
if not enable_particles then
return
end
2023-04-24 17:56:28 +03:00
minetest.add_particlespawner ( {
amount = 5 ,
time = 2 ,
minpos = vector.subtract ( { x = pos.x - 0.3 , y = pos.y , z = pos.z - 0.3 } , 0.3 ) ,
maxpos = vector.add ( { x = pos.x + 0.3 , y = pos.y , z = pos.z + 0.3 } , 0.3 ) ,
minvel = { x = 0.1 , y = 0.1 , z = 0.1 } ,
maxvel = { x = 0.2 , y = 0.2 , z = 0.2 } ,
minacc = vector.new ( { x = - 0.1 , y = 0.3 , z = - 0.1 } ) ,
maxacc = vector.new ( { x = 0.1 , y = 0.6 , z = 0.1 } ) ,
minexptime = 2 ,
maxexptime = 3 ,
minsize = 16 ,
maxsize = 24 ,
texture = ' spawners_mobs_smoke_particle_2.png ' ,
animation = {
type = ' vertical_frames ' ,
-- Width of a frame in pixels
aspect_w = 16 ,
-- Height of a frame in pixels
aspect_h = 16 ,
-- Full loop length
length = 2.0 ,
} ,
} )
2016-10-12 22:57:06 +03:00
end
function spawners_mobs . add_flame_effects ( pos )
2023-04-25 07:34:49 +03:00
if not enable_particles then
return
end
2023-04-24 17:56:28 +03:00
return minetest.add_particlespawner ( {
amount = 6 ,
time = 0 ,
minpos = vector.subtract ( { x = pos.x - 0.001 , y = pos.y - 0.001 , z = pos.z - 0.001 } , 0.5 ) ,
maxpos = vector.add ( { x = pos.x + 0.001 , y = pos.y + 0.001 , z = pos.z + 0.001 } , 0.5 ) ,
minvel = { x = - 0.1 , y = - 0.1 , z = - 0.1 } ,
maxvel = { x = 0.1 , y = 0.1 , z = 0.1 } ,
minacc = vector.new ( ) ,
maxacc = vector.new ( ) ,
minexptime = 1 ,
maxexptime = 5 ,
minsize = 0.5 ,
maxsize = 2.5 ,
texture = ' spawners_mobs_flame_particle_2.png ' ,
} )
2016-10-12 22:57:06 +03:00
end
function spawners_mobs . add_smoke_effects ( pos )
2023-04-25 07:34:49 +03:00
if not enable_particles then
return
end
2023-04-24 17:56:28 +03:00
return minetest.add_particlespawner ( {
amount = 1 ,
time = 0 ,
minpos = vector.subtract ( { x = pos.x - 0.001 , y = pos.y - 0.001 , z = pos.z - 0.001 } , 0.5 ) ,
maxpos = vector.add ( { x = pos.x + 0.001 , y = pos.y + 0.001 , z = pos.z + 0.001 } , 0.5 ) ,
minvel = { x = - 0.5 , y = 0.5 , z = - 0.5 } ,
maxvel = { x = 0.5 , y = 1.5 , z = 0.5 } ,
minacc = vector.new ( { x = - 0.1 , y = 0.1 , z = - 0.1 } ) ,
maxacc = vector.new ( { x = 0.1 , y = 0.3 , z = 0.1 } ) ,
minexptime = 0.5 ,
maxexptime = 2 ,
minsize = 0.5 ,
maxsize = 2 ,
texture = ' spawners_mobs_smoke_particle.png^[transform ' .. math.random ( 0 , 3 ) ,
} )
2016-10-12 22:57:06 +03:00
end
2018-10-18 04:25:16 +03:00
--
2018-01-07 07:31:21 +03:00
-- Timers
2018-10-18 04:25:16 +03:00
--
2018-01-07 07:31:21 +03:00
-- how often node timers for spawners will tick, +/- some random value
function spawners_mobs . tick ( pos )
2023-04-24 17:56:28 +03:00
local meta = minetest.get_meta ( pos )
local tick_counter = meta : get_int ( ' tick ' )
local owner = meta : get_string ( ' owner ' )
local privs = minetest.get_player_privs ( owner ) ;
-- not for admin
if not privs.privs then
tick_counter = tick_counter + 1
meta : set_int ( ' tick ' , tick_counter )
end
-- print('tick_counter: ' .. tick_counter .. ' at ' .. minetest.pos_to_string(pos))
-- rusty spawner
if tick_counter >= tick_max then
spawners_mobs.set_status ( pos , ' rusty ' )
return
end
2023-07-12 18:54:12 +03:00
minetest.get_node_timer ( pos ) : start ( math.random ( 5 , 15 ) )
2018-01-07 07:31:21 +03:00
end
-- how often a spawn failure tick is retried (e.g. too dark)
function spawners_mobs . tick_short ( pos )
2023-04-24 17:56:28 +03:00
local meta = minetest.get_meta ( pos )
local tick_short_counter = meta : get_int ( ' tick_short ' )
if tick_short_counter >= tick_short_max then
spawners_mobs.tick ( pos )
return
else
tick_short_counter = tick_short_counter + 1
meta : set_int ( ' tick_short ' , tick_short_counter )
-- print('tick_short_counter: ' .. tick_short_counter .. ' at ' .. minetest.pos_to_string(pos))
end
2023-07-12 18:54:12 +03:00
minetest.get_node_timer ( pos ) : start ( math.random ( 5 , 10 ) )
2023-04-24 17:56:28 +03:00
-- minetest.get_node_timer(pos):start(math.random(10, 20))
2018-01-07 07:31:21 +03:00
end
2018-10-18 04:25:16 +03:00
--
2018-01-07 07:31:21 +03:00
-- Core Functions
2018-10-18 04:25:16 +03:00
--
2016-10-08 21:54:26 +03:00
-- start spawning mobs
2018-01-07 07:31:21 +03:00
function spawners_mobs . start_spawning ( spawn_area_random_pos , mob_name , mod_prefix , sound_custom )
2023-04-24 17:56:28 +03:00
if not ( spawn_area_random_pos or mob_name ) then
return
end
local sound_name = mod_prefix .. ' _ ' .. mob_name
-- use custom sounds
if sound_custom ~= ' ' then
sound_name = sound_custom
end
-- use random colors for sheeps
if mob_name == ' sheep_white ' then
local sheep_colors = { ' black ' , ' blue ' , ' brown ' , ' cyan ' , ' dark_green ' , ' dark_grey ' , ' green ' , ' grey ' , ' magenta ' , ' orange ' , ' pink ' , ' red ' , ' violet ' , ' white ' , ' yellow ' }
2023-04-25 07:34:49 +03:00
mob_name = ' sheep_ ' .. sheep_colors [ math.random ( 1 , # sheep_colors ) ]
2023-04-24 17:56:28 +03:00
end
for i = 1 , # spawn_area_random_pos do
-- spawn a bit more above the block - prevent spawning inside the block
spawn_area_random_pos [ i ] . y = spawn_area_random_pos [ i ] . y + 0.5
spawners_mobs.cloud_booom ( spawn_area_random_pos [ i ] )
minetest.after ( 1 , function ( )
-- minetest.set_node(spawn_area_random_pos[i], {name = 'default:apple' })
local obj = minetest.add_entity ( spawn_area_random_pos [ i ] , mod_prefix .. ' : ' .. mob_name )
if obj then
if sound_name then
minetest.sound_play ( sound_name , {
pos = spawn_area_random_pos [ i ] ,
max_hear_distance = 16 ,
gain = 0.5
} )
end
end
end )
end
2016-10-08 21:54:26 +03:00
end
2018-01-07 07:31:21 +03:00
function spawners_mobs . on_timer ( pos , elapsed )
2023-04-24 17:56:28 +03:00
local meta = minetest.get_meta ( pos )
2023-04-25 07:34:49 +03:00
local node = minetest.get_node ( pos )
local mob_table = spawners_mobs.registered_spawners [ node.name ]
2023-04-24 17:56:28 +03:00
2023-04-25 07:34:49 +03:00
if not mob_table then
return
end
2023-04-24 17:56:28 +03:00
local posmin = { x = pos.x - 3 , y = pos.y - 1 , z = pos.z - 3 }
local posmax = { x = pos.x + 4 , y = pos.y + 1 , z = pos.z + 4 }
local player_near = false
local entities_near = 0
local entities_max = 6
local node_light_min = 13
local owner = meta : get_string ( ' owner ' ) or ' '
local mod_prefix = mob_table.mod_prefix
2023-04-25 07:34:49 +03:00
local mob_name = mob_table.mob_name
2023-04-24 17:56:28 +03:00
local sound_custom = mob_table.sound_custom
local night_only = mob_table.night_only
local max_objects = max_obj_per_mapblock / 4
2023-04-25 06:16:05 +03:00
local offset = mob_table.dummy_offset
local has_dummy = false
local objects_inside_radius = minetest.get_objects_inside_radius ( pos , 0.5 )
for _ , obj in ipairs ( objects_inside_radius ) do
local lua_ent = obj : get_luaentity ( )
if lua_ent then
if lua_ent.name == ' spawners_mobs:dummy_ ' .. mod_prefix .. ' _ ' .. mob_name then
has_dummy = true
end
end
end
if not has_dummy and meta : get_string ( ' status ' ) == ' active ' then
minetest.add_entity ( { x = pos.x , y = pos.y + offset , z = pos.z } , ' spawners_mobs:dummy_ ' .. mod_prefix .. ' _ ' .. mob_name )
end
2023-04-24 17:56:28 +03:00
-- check spawner light
local node_light = minetest.get_node_light ( pos )
-- dark
if ( not node_light or node_light < node_light_min ) and not night_only then
-- print('Too dark for mob ( ' .. mob_name .. ' ) to spawn. Waiting for day .. .')
spawners_mobs.set_status ( pos , ' waiting ' )
-- set infotext
meta : set_string ( ' infotext ' , mob_name .. ' spawner \n owner: ' .. owner .. ' \n Too dark for mob to spawn. Waiting for day .. . ' )
spawners_mobs.tick_short ( pos )
return
elseif node_light >= node_light_min and night_only then
-- light
-- print('Too much light for mob ( ' .. mob_name .. ' ) to spawn. Waiting for night .. .')
spawners_mobs.set_status ( pos , ' waiting ' )
-- set infotext
meta : set_string ( ' infotext ' , mob_name .. ' spawner \n owner: ' .. owner .. ' \n Too much light for mob to spawn. Waiting for night .. . ' )
spawners_mobs.tick_short ( pos )
return
end
-- positions where mobs can spawn
local spawn_area_pos = minetest.find_nodes_in_area ( posmin , posmax , ' air ' )
-- check if there is enough place to spawn mob
if # spawn_area_pos < 1 then
spawners_mobs.set_status ( pos , ' waiting ' )
-- set infotext
meta : set_string ( ' infotext ' , mob_name .. ' spawner \n owner: ' .. owner .. ' \n Not enough place to spawn mob. Find more space! ' )
spawners_mobs.tick ( pos )
return
end
-- spawn 2 mobs on 2 different positions by chance
2023-04-25 06:16:05 +03:00
local how_many = math.random ( 1 , 2 )
2023-04-24 17:56:28 +03:00
local spawn_area_random_pos = { }
-- get random spawn position from spawn area
for i = 1 , how_many do
while # spawn_area_random_pos < how_many and # spawn_area_pos > 0 do
local random_pos = spawn_area_pos [ math.random ( # spawn_area_pos ) ]
local random_pos_above = minetest.get_node ( { x = random_pos.x , y = random_pos.y + 1 , z = random_pos.z } ) . name
if random_pos_above == ' air ' and not minetest.is_protected ( random_pos , owner ) then
table.insert ( spawn_area_random_pos , random_pos )
-- print('spawn_area_random_pos: ' .. #spawn_area_random_pos)
else
table.remove ( spawn_area_pos , i )
-- print('spawn_area_pos: ' .. #spawn_area_pos)
end
end
end
-- print(dump(spawn_area_random_pos))
-- check if there is still enough place to spawn mob
if # spawn_area_random_pos < 1 then
spawners_mobs.set_status ( pos , ' waiting ' )
-- set infotext
meta : set_string ( ' infotext ' , mob_name .. ' spawner \n owner: ' .. owner .. ' \n Not enough place to spawn mob. Searching for new location .. . ' )
spawners_mobs.tick_short ( pos )
return
end
-- area where player and entity count will be detected
local activation_area = minetest.get_objects_inside_radius ( pos , 16 )
-- prevent object clutter on the map
if # activation_area > max_objects then
spawners_mobs.set_status ( pos , ' waiting ' )
-- set infotext
meta : set_string ( ' infotext ' , mob_name .. ' spawner \n owner: ' .. owner .. ' \n Too many objects in the area ( ' .. # activation_area .. ' / ' .. max_objects .. ' ), clean-up dropped objects first! ' )
spawners_mobs.tick_short ( pos )
return
end
for k , object in ipairs ( activation_area ) do
-- find player inside activation area
if object : is_player ( ) then
player_near = true
-- print('found player: ' .. object:get_player_name())
end
-- find entities inside activation area
if not object : is_player ( )
and object : get_luaentity ( )
and object : get_luaentity ( ) . name ~= ' __builtin:item '
then
local tmp_mob_name = string.split ( object : get_luaentity ( ) . name , ' : ' ) [ 2 ]
if tmp_mob_name ~= nil then
-- sheeps have colors in names
if string.find ( tmp_mob_name , ' sheep ' ) and string.find ( mob_name , ' sheep ' ) and not string.find ( tmp_mob_name , ' dummy ' ) then
-- print('found entity: ' .. tmp_mob_name)
entities_near = entities_near + 1
elseif tmp_mob_name == mob_name then
-- print('found entity: ' .. tmp_mob_name)
entities_near = entities_near + 1
end
else
minetest.log ( ' warning ' , ' [spawners_mobs] tmp_mob_name was nil, luaentity name was: ' .. object : get_luaentity ( ) . name .. ' at: ' .. minetest.pos_to_string ( object : get_pos ( ) ) )
end
end
-- stop looping when met all conditions
if entities_near >= entities_max and player_near then
-- print('max entities reached ' .. entities_max .. ' and player_near found, breaking .. ')
break
end
end
-- don't do anything and try again later when player not near or max entities reached
if entities_near >= entities_max or not player_near then
spawners_mobs.set_status ( pos , ' waiting ' )
-- sheeps have color in the name
-- local name = mob_name
-- if string.find(mob_name, 'sheep') then
-- name = 'sheep'
-- end
meta : set_string ( ' infotext ' , mob_name .. ' spawner \n owner: ' .. owner .. ' \n max mobs reached: ' .. entities_near .. ' / ' .. entities_max ) -- or player not near
spawners_mobs.tick_short ( pos )
return
end
-- start spawning
spawners_mobs.start_spawning ( spawn_area_random_pos , mob_name , mod_prefix , sound_custom )
spawners_mobs.set_status ( pos , ' active ' )
meta : set_string ( ' infotext ' , mob_name .. ' spawner \n owner: ' .. owner .. ' \n spawner is active reached: ' .. entities_near .. ' / ' .. entities_max )
meta : set_int ( ' tick ' , 0 )
meta : set_int ( ' tick_short ' , 0 )
spawners_mobs.tick ( pos )
2018-01-07 07:31:21 +03:00
end
--
-- Status Manager
--
function spawners_mobs . set_status ( pos , set_status )
2023-04-24 17:56:28 +03:00
local meta = minetest.get_meta ( pos )
2023-04-25 07:34:49 +03:00
local node = minetest.get_node ( pos )
local mob_table = spawners_mobs.registered_spawners [ node.name ]
2023-04-24 17:56:28 +03:00
2023-04-25 07:34:49 +03:00
if not mob_table then
return
end
2023-04-24 17:56:28 +03:00
local mod_prefix = mob_table.mod_prefix
2023-04-25 07:34:49 +03:00
local mob_name = mob_table.mob_name
2023-04-24 17:56:28 +03:00
local offset = mob_table.dummy_offset
-- get meta
local owner = meta : get_string ( ' owner ' )
local meta_status = meta : get_string ( ' status ' )
local id_flame = meta : get_int ( ' id_flame ' )
local id_smoke = meta : get_int ( ' id_smoke ' )
--
-- active
--
if set_status == ' active ' then
-- remove particles and add them again - keeps particles after server restart
-- delete particles
if id_flame ~= - 1 and id_smoke ~= - 1 then
-- print('#1 delete id_flame: ' .. id_flame .. ' at ' .. minetest.pos_to_string(pos))
-- print('#1 delete id_smoke: ' .. id_smoke .. ' at ' .. minetest.pos_to_string(pos))
minetest.delete_particlespawner ( id_flame )
minetest.delete_particlespawner ( id_smoke )
meta : set_int ( ' id_flame ' , - 1 )
meta : set_int ( ' id_smoke ' , - 1 )
end
-- add particles
id_flame = spawners_mobs.add_flame_effects ( pos )
id_smoke = spawners_mobs.add_smoke_effects ( pos )
meta : set_int ( ' id_flame ' , id_flame )
meta : set_int ( ' id_smoke ' , id_smoke )
-- print('#1 add id_flame: ' .. id_flame .. ' at ' .. minetest.pos_to_string(pos))
-- print('#1 add id_smoke: ' .. id_smoke .. ' at ' .. minetest.pos_to_string(pos))
if meta_status ~= set_status then
-- add dummy entity
2023-04-25 06:16:05 +03:00
minetest.add_entity ( { x = pos.x , y = pos.y + offset , z = pos.z } , ' spawners_mobs:dummy_ ' .. mod_prefix .. ' _ ' .. mob_name )
2023-04-24 17:56:28 +03:00
meta : set_string ( ' status ' , ' active ' )
minetest.swap_node ( pos , { name = ' spawners_mobs: ' .. mod_prefix .. ' _ ' .. mob_name .. ' _spawner ' } )
end
elseif set_status == ' waiting ' and meta_status ~= set_status then
--
-- waiting
--
-- delete particles
if id_flame ~= - 1 and id_smoke ~= - 1 then
-- print('#2 delete id_flame: ' .. id_flame .. ' at ' .. minetest.pos_to_string(pos))
-- print('#2 delete id_smoke: ' .. id_smoke .. ' at ' .. minetest.pos_to_string(pos))
minetest.delete_particlespawner ( id_flame )
minetest.delete_particlespawner ( id_smoke )
meta : set_int ( ' id_flame ' , - 1 )
meta : set_int ( ' id_smoke ' , - 1 )
end
-- remove dummy
local objs = minetest.get_objects_inside_radius ( pos , 0.5 )
if objs then
for _ , obj in ipairs ( objs ) do
if obj and obj : get_luaentity ( ) and obj : get_luaentity ( ) . name == ' spawners_mobs:dummy_ ' .. mod_prefix .. ' _ ' .. mob_name then
obj : remove ( )
end
end
end
meta : set_string ( ' status ' , ' waiting ' )
minetest.swap_node ( pos , { name = ' spawners_mobs: ' .. mod_prefix .. ' _ ' .. mob_name .. ' _spawner_waiting ' } )
elseif set_status == ' rusty ' and meta_status ~= set_status then
--
-- rusty
--
-- delete particles
if id_flame ~= - 1 and id_smoke ~= - 1 then
-- print('#3 delete id_flame: ' .. id_flame .. ' at ' .. minetest.pos_to_string(pos))
-- print('#3 delete id_smoke: ' .. id_smoke .. ' at ' .. minetest.pos_to_string(pos))
minetest.delete_particlespawner ( id_flame )
minetest.delete_particlespawner ( id_smoke )
meta : set_int ( ' id_flame ' , - 1 )
meta : set_int ( ' id_smoke ' , - 1 )
end
-- remove dummy
local objs = minetest.get_objects_inside_radius ( pos , 0.5 )
if objs then
for _ , obj in ipairs ( objs ) do
if obj and obj : get_luaentity ( ) and obj : get_luaentity ( ) . name == ' spawners_mobs:dummy_ ' .. mod_prefix .. ' _ ' .. mob_name then
obj : remove ( )
end
end
end
meta : set_string ( ' status ' , ' rusty ' )
minetest.swap_node ( pos , { name = ' spawners_mobs: ' .. mod_prefix .. ' _ ' .. mob_name .. ' _spawner_rusty ' } )
-- set infotext
meta : set_string ( ' infotext ' , mob_name .. ' spawner \n owner: ' .. owner .. ' \n Spawner was searching for too long and got rusted! Dig up the spawner and place it again. ' )
return
end
2016-10-08 21:54:26 +03:00
end