Add coord safe infinite particlespawners api for mobs
This commit is contained in:
parent
dc873f4de2
commit
ef4b243a30
@ -68,6 +68,7 @@ local disable_blood = minetest.settings:get_bool("mobs_disable_blood")
|
||||
local mobs_drop_items = minetest.settings:get_bool("mobs_drop_items") ~= false
|
||||
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
|
||||
local spawn_protected = minetest.settings:get_bool("mobs_spawn_protected") ~= false
|
||||
local player_transfer_distance = minetest.settings:get("player_transfer_distance") or 128
|
||||
local remove_far = true
|
||||
local difficulty = tonumber(minetest.settings:get("mob_difficulty")) or 1.0
|
||||
local show_health = false
|
||||
@ -84,6 +85,8 @@ if minetest.settings:get_bool("only_peaceful_mobs", false) then
|
||||
end)
|
||||
end
|
||||
|
||||
local active_particlespawners = {}
|
||||
|
||||
|
||||
local function dir_to_pitch(dir)
|
||||
--local dir2 = vector.normalize(dir)
|
||||
@ -121,6 +124,60 @@ minetest.register_chatcommand("clearmobs",{
|
||||
end
|
||||
end})
|
||||
|
||||
local function remove_particlespawners(pn,self)
|
||||
if not active_particlespawners[pn] then return end
|
||||
if not active_particlespawners[pn][self.object] then return end
|
||||
for k,v in pairs(active_particlespawners[pn][self.object]) do
|
||||
minetest.delete_particlespawner(v)
|
||||
end
|
||||
end
|
||||
|
||||
local function add_particlespawners(pn,self)
|
||||
if not active_particlespawners[pn] then active_particlespawners[pn] = {} end
|
||||
if not active_particlespawners[pn][object] then active_particlespawners[pn][self.object] = {} end
|
||||
for _,ps in pairs(self.particlespawners) do
|
||||
ps.attached = self.object
|
||||
ps.playername = pn
|
||||
table.insert(active_particlespawners[pn][self.object],minetest.add_particlespawner(ps))
|
||||
end
|
||||
end
|
||||
|
||||
local function particlespawner_check(self,dtime)
|
||||
if not self.particlespawners then return end
|
||||
--minetest.log(dump(active_particlespawners))
|
||||
if self._particle_timer and self._particle_timer >= 1 then
|
||||
self._particle_timer = 0
|
||||
local players = {}
|
||||
for _,player in pairs(minetest.get_connected_players()) do
|
||||
local pn = player:get_player_name()
|
||||
table.insert(players,pn)
|
||||
if not active_particlespawners[pn] then
|
||||
active_particlespawners[pn] = {} end
|
||||
|
||||
local dst = vector.distance(player:get_pos(),self.object:get_pos())
|
||||
if dst < player_transfer_distance and not active_particlespawners[pn][self.object] then
|
||||
add_particlespawners(pn,self)
|
||||
elseif dst >= player_transfer_distance and active_particlespawners[pn][self.object] then
|
||||
remove_particlespawners(pn,self)
|
||||
end
|
||||
end
|
||||
elseif not self._particle_timer then
|
||||
self._particle_timer = 0
|
||||
end
|
||||
self._particle_timer = self._particle_timer + dtime
|
||||
end
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
local pn = player:get_player_name()
|
||||
if not active_particlespawners[pn] then return end
|
||||
for _,m in pairs(active_particlespawners[pn]) do
|
||||
for k,v in pairs(m) do
|
||||
minetest.delete_particlespawner(v)
|
||||
end
|
||||
end
|
||||
active_particlespawners[pn] = nil
|
||||
end)
|
||||
|
||||
----For Water Flowing:
|
||||
local enable_physics = function(object, luaentity, ignore_check)
|
||||
if luaentity.physical_state == false or ignore_check == true then
|
||||
@ -3477,7 +3534,9 @@ end
|
||||
-- get entity staticdata
|
||||
local mob_staticdata = function(self)
|
||||
|
||||
|
||||
for _,p in pairs(minetest.get_connected_players()) do
|
||||
remove_particlespawners(p:get_player_name(),self)
|
||||
end
|
||||
-- remove mob when out of range unless tamed
|
||||
if remove_far
|
||||
and self.can_despawn
|
||||
@ -3711,6 +3770,7 @@ local mob_step = function(self, dtime)
|
||||
self.lifetimer = self.lifetimer - dtime
|
||||
check_item_pickup(self)
|
||||
check_aggro(self,dtime)
|
||||
particlespawner_check(self,dtime)
|
||||
if not self.fire_resistant then
|
||||
mcl_burning.tick(self.object, dtime, self)
|
||||
-- mcl_burning.tick may remove object immediately
|
||||
@ -4226,6 +4286,7 @@ minetest.register_entity(name, {
|
||||
spawn_in_group = def.spawn_in_group,
|
||||
spawn_in_group_min = def.spawn_in_group_min,
|
||||
noyaw = def.noyaw or false,
|
||||
particlespawners = def.particlespawners,
|
||||
-- End of MCL2 extensions
|
||||
|
||||
on_spawn = def.on_spawn,
|
||||
|
@ -260,6 +260,8 @@ functions needed for the mob to work properly which contains the following:
|
||||
'pick_up' table of itemstrings the mob will pick up (e.g. for breeding)
|
||||
'on_pick_up' function that will be called on item pickup - return true to not pickup the item
|
||||
'custom_visual_size' will not reset visual_size from the base class on reload
|
||||
'noyaw' If true this mob will not automatically change yaw
|
||||
'particlespawners' Table of particlespawners attached to the mob. This is implemented in a coord safe manner i.e. spawners are only sent to players within the player_transfer_distance (and automatically removed). This enables infinitely lived particlespawners.
|
||||
|
||||
mobs:gopath(self,target,callback_arrived) pathfind a way to target and run callback on arrival
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user