Particles: Add option to remove particles on collision

Adds the particle option `collision_removal = bool`

Some particles are hard to use right now since they either go through
solid blocks (without collision detection), and with collision
detection enabled they (e.g. raindrops) would just stop dead on the
floor and sit there until they expire, or worse, scrape along a wall
or ceiling.

We can solve the problem by adding a boolean flag that tells the
particle to be removed if it ever collides with something. This will
make it easier to add rain that doesn't fall through your roof or stick
on the top of it. Or clouds and smoke that don't go through trees.

Particles that collide with this flag are marked expired
unconditionally, causing them to be treated like normal expired
particles and cleaned up normally.

Documentation is adjusted accordingly.

An added bonus of this patch is that particles can potentially collide
many times with nodes, and this reduces the amount of collisions to 1
(max), which may end up reducing particle load on the client.
This commit is contained in:
Auke Kok 2016-05-27 21:08:23 -07:00 committed by kwolekr
parent 62d15ac7c1
commit d499ec4838
9 changed files with 84 additions and 32 deletions

View File

@ -3885,6 +3885,9 @@ Definition tables
size = 1, size = 1,
collisiondetection = false, collisiondetection = false,
-- ^ collisiondetection: if true collides with physical objects -- ^ collisiondetection: if true collides with physical objects
collision_removal = false,
-- ^ collision_removal: if true then particle is removed when it collides,
-- ^ requires collisiondetection = true to have any effect
vertical = false, vertical = false,
-- ^ vertical: if true faces player using y axis only -- ^ vertical: if true faces player using y axis only
texture = "image.png", texture = "image.png",
@ -3914,6 +3917,9 @@ Definition tables
-- ^ minsize/maxsize, minexptime/maxexptime (expirationtime) -- ^ minsize/maxsize, minexptime/maxexptime (expirationtime)
collisiondetection = false, collisiondetection = false,
-- ^ collisiondetection: if true uses collision detection -- ^ collisiondetection: if true uses collision detection
collision_removal = false,
-- ^ collision_removal: if true then particle is removed when it collides,
-- ^ requires collisiondetection = true to have any effect
vertical = false, vertical = false,
-- ^ vertical: if true faces player using y axis only -- ^ vertical: if true faces player using y axis only
texture = "image.png", texture = "image.png",

View File

@ -182,6 +182,7 @@ struct ClientEvent
f32 expirationtime; f32 expirationtime;
f32 size; f32 size;
bool collisiondetection; bool collisiondetection;
bool collision_removal;
bool vertical; bool vertical;
std::string *texture; std::string *texture;
} spawn_particle; } spawn_particle;
@ -199,6 +200,7 @@ struct ClientEvent
f32 minsize; f32 minsize;
f32 maxsize; f32 maxsize;
bool collisiondetection; bool collisiondetection;
bool collision_removal;
bool vertical; bool vertical;
std::string *texture; std::string *texture;
u32 id; u32 id;

View File

@ -898,8 +898,10 @@ void Client::handleCommand_SpawnParticle(NetworkPacket* pkt)
bool collisiondetection = readU8(is); bool collisiondetection = readU8(is);
std::string texture = deSerializeLongString(is); std::string texture = deSerializeLongString(is);
bool vertical = false; bool vertical = false;
bool collision_removal = false;
try { try {
vertical = readU8(is); vertical = readU8(is);
collision_removal = readU8(is);
} catch (...) {} } catch (...) {}
ClientEvent event; ClientEvent event;
@ -910,6 +912,7 @@ void Client::handleCommand_SpawnParticle(NetworkPacket* pkt)
event.spawn_particle.expirationtime = expirationtime; event.spawn_particle.expirationtime = expirationtime;
event.spawn_particle.size = size; event.spawn_particle.size = size;
event.spawn_particle.collisiondetection = collisiondetection; event.spawn_particle.collisiondetection = collisiondetection;
event.spawn_particle.collision_removal = collision_removal;
event.spawn_particle.vertical = vertical; event.spawn_particle.vertical = vertical;
event.spawn_particle.texture = new std::string(texture); event.spawn_particle.texture = new std::string(texture);
@ -942,8 +945,11 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
*pkt >> id; *pkt >> id;
bool vertical = false; bool vertical = false;
bool collision_removal = false;
try { try {
*pkt >> vertical; *pkt >> vertical;
*pkt >> collision_removal;
} catch (...) {} } catch (...) {}
ClientEvent event; ClientEvent event;
@ -961,6 +967,7 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
event.add_particlespawner.minsize = minsize; event.add_particlespawner.minsize = minsize;
event.add_particlespawner.maxsize = maxsize; event.add_particlespawner.maxsize = maxsize;
event.add_particlespawner.collisiondetection = collisiondetection; event.add_particlespawner.collisiondetection = collisiondetection;
event.add_particlespawner.collision_removal = collision_removal;
event.add_particlespawner.vertical = vertical; event.add_particlespawner.vertical = vertical;
event.add_particlespawner.texture = new std::string(texture); event.add_particlespawner.texture = new std::string(texture);
event.add_particlespawner.id = id; event.add_particlespawner.id = id;

View File

@ -474,6 +474,7 @@ enum ToClientCommand
u8 bool vertical u8 bool vertical
u32 len u32 len
u8[len] texture u8[len] texture
u8 collision_removal
*/ */
TOCLIENT_ADD_PARTICLESPAWNER = 0x47, TOCLIENT_ADD_PARTICLESPAWNER = 0x47,
@ -495,6 +496,7 @@ enum ToClientCommand
u32 len u32 len
u8[len] texture u8[len] texture
u32 id u32 id
u8 collision_removal
*/ */
TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY = 0x48, TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY = 0x48,

View File

@ -54,6 +54,7 @@ Particle::Particle(
float expirationtime, float expirationtime,
float size, float size,
bool collisiondetection, bool collisiondetection,
bool collision_removal,
bool vertical, bool vertical,
video::ITexture *texture, video::ITexture *texture,
v2f texpos, v2f texpos,
@ -85,6 +86,7 @@ Particle::Particle(
m_player = player; m_player = player;
m_size = size; m_size = size;
m_collisiondetection = collisiondetection; m_collisiondetection = collisiondetection;
m_collision_removal = collision_removal;
m_vertical = vertical; m_vertical = vertical;
// Irrlicht stuff // Irrlicht stuff
@ -126,20 +128,21 @@ void Particle::render()
void Particle::step(float dtime) void Particle::step(float dtime)
{ {
m_time += dtime; m_time += dtime;
if (m_collisiondetection) if (m_collisiondetection) {
{
aabb3f box = m_collisionbox; aabb3f box = m_collisionbox;
v3f p_pos = m_pos*BS; v3f p_pos = m_pos * BS;
v3f p_velocity = m_velocity*BS; v3f p_velocity = m_velocity * BS;
collisionMoveSimple(m_env, m_gamedef, collisionMoveResult r = collisionMoveSimple(m_env,
BS*0.5, box, m_gamedef, BS * 0.5, box, 0, dtime, &p_pos,
0, dtime, &p_velocity, m_acceleration * BS);
&p_pos, &p_velocity, m_acceleration * BS); if (m_collision_removal && r.collides) {
m_pos = p_pos/BS; // force expiration of the particle
m_velocity = p_velocity/BS; m_expiration = -1.0;
} } else {
else m_pos = p_pos / BS;
{ m_velocity = p_velocity / BS;
}
} else {
m_velocity += m_acceleration * dtime; m_velocity += m_acceleration * dtime;
m_pos += m_velocity * dtime; m_pos += m_velocity * dtime;
} }
@ -210,8 +213,8 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr,
u16 amount, float time, u16 amount, float time,
v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc,
float minexptime, float maxexptime, float minsize, float maxsize, float minexptime, float maxexptime, float minsize, float maxsize,
bool collisiondetection, bool vertical, video::ITexture *texture, u32 id, bool collisiondetection, bool collision_removal, bool vertical,
ParticleManager *p_manager) : video::ITexture *texture, u32 id, ParticleManager *p_manager) :
m_particlemanager(p_manager) m_particlemanager(p_manager)
{ {
m_gamedef = gamedef; m_gamedef = gamedef;
@ -230,6 +233,7 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr,
m_minsize = minsize; m_minsize = minsize;
m_maxsize = maxsize; m_maxsize = maxsize;
m_collisiondetection = collisiondetection; m_collisiondetection = collisiondetection;
m_collision_removal = collision_removal;
m_vertical = vertical; m_vertical = vertical;
m_texture = texture; m_texture = texture;
m_time = 0; m_time = 0;
@ -277,6 +281,7 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
exptime, exptime,
size, size,
m_collisiondetection, m_collisiondetection,
m_collision_removal,
m_vertical, m_vertical,
m_texture, m_texture,
v2f(0.0, 0.0), v2f(0.0, 0.0),
@ -317,6 +322,7 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
exptime, exptime,
size, size,
m_collisiondetection, m_collisiondetection,
m_collision_removal,
m_vertical, m_vertical,
m_texture, m_texture,
v2f(0.0, 0.0), v2f(0.0, 0.0),
@ -446,6 +452,7 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef,
event->add_particlespawner.minsize, event->add_particlespawner.minsize,
event->add_particlespawner.maxsize, event->add_particlespawner.maxsize,
event->add_particlespawner.collisiondetection, event->add_particlespawner.collisiondetection,
event->add_particlespawner.collision_removal,
event->add_particlespawner.vertical, event->add_particlespawner.vertical,
texture, texture,
event->add_particlespawner.id, event->add_particlespawner.id,
@ -480,6 +487,7 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef,
event->spawn_particle.expirationtime, event->spawn_particle.expirationtime,
event->spawn_particle.size, event->spawn_particle.size,
event->spawn_particle.collisiondetection, event->spawn_particle.collisiondetection,
event->spawn_particle.collision_removal,
event->spawn_particle.vertical, event->spawn_particle.vertical,
texture, texture,
v2f(0.0, 0.0), v2f(0.0, 0.0),
@ -555,6 +563,7 @@ void ParticleManager::addNodeParticle(IGameDef* gamedef, scene::ISceneManager* s
visual_size, visual_size,
true, true,
false, false,
false,
texture, texture,
texpos, texpos,
texsize); texsize);

View File

@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
struct ClientEvent; struct ClientEvent;
class ParticleManager; class ParticleManager;
class ClientEnvironment;
class Particle : public scene::ISceneNode class Particle : public scene::ISceneNode
{ {
@ -45,6 +46,7 @@ class Particle : public scene::ISceneNode
float expirationtime, float expirationtime,
float size, float size,
bool collisiondetection, bool collisiondetection,
bool collision_removal,
bool vertical, bool vertical,
video::ITexture *texture, video::ITexture *texture,
v2f texpos, v2f texpos,
@ -97,6 +99,7 @@ private:
float m_size; float m_size;
u8 m_light; u8 m_light;
bool m_collisiondetection; bool m_collisiondetection;
bool m_collision_removal;
bool m_vertical; bool m_vertical;
v3s16 m_camera_offset; v3s16 m_camera_offset;
}; };
@ -115,6 +118,7 @@ class ParticleSpawner
float minexptime, float maxexptime, float minexptime, float maxexptime,
float minsize, float maxsize, float minsize, float maxsize,
bool collisiondetection, bool collisiondetection,
bool collision_removal,
bool vertical, bool vertical,
video::ITexture *texture, video::ITexture *texture,
u32 id, u32 id,
@ -148,6 +152,7 @@ class ParticleSpawner
video::ITexture *m_texture; video::ITexture *m_texture;
std::vector<float> m_spawntimes; std::vector<float> m_spawntimes;
bool m_collisiondetection; bool m_collisiondetection;
bool m_collision_removal;
bool m_vertical; bool m_vertical;
}; };

View File

@ -21,13 +21,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_internal.h" #include "lua_api/l_internal.h"
#include "common/c_converter.h" #include "common/c_converter.h"
#include "server.h" #include "server.h"
#include "particles.h"
// add_particle({pos=, velocity=, acceleration=, expirationtime=, // add_particle({pos=, velocity=, acceleration=, expirationtime=,
// size=, collisiondetection=, vertical=, texture=, player=}) // size=, collisiondetection=, collision_removal=, vertical=,
// texture=, player=})
// pos/velocity/acceleration = {x=num, y=num, z=num} // pos/velocity/acceleration = {x=num, y=num, z=num}
// expirationtime = num (seconds) // expirationtime = num (seconds)
// size = num // size = num
// collisiondetection = bool // collisiondetection = bool
// collision_removal = bool
// vertical = bool // vertical = bool
// texture = e.g."default_wood.png" // texture = e.g."default_wood.png"
int ModApiParticles::l_add_particle(lua_State *L) int ModApiParticles::l_add_particle(lua_State *L)
@ -41,8 +44,8 @@ int ModApiParticles::l_add_particle(lua_State *L)
float expirationtime, size; float expirationtime, size;
expirationtime = size = 1; expirationtime = size = 1;
bool collisiondetection, vertical; bool collisiondetection, vertical, collision_removal;
collisiondetection = vertical = false; collisiondetection = vertical = collision_removal = false;
std::string texture = ""; std::string texture = "";
std::string playername = ""; std::string playername = "";
@ -94,12 +97,14 @@ int ModApiParticles::l_add_particle(lua_State *L)
size = getfloatfield_default(L, 1, "size", 1); size = getfloatfield_default(L, 1, "size", 1);
collisiondetection = getboolfield_default(L, 1, collisiondetection = getboolfield_default(L, 1,
"collisiondetection", collisiondetection); "collisiondetection", collisiondetection);
collision_removal = getboolfield_default(L, 1,
"collision_removal", collision_removal);
vertical = getboolfield_default(L, 1, "vertical", vertical); vertical = getboolfield_default(L, 1, "vertical", vertical);
texture = getstringfield_default(L, 1, "texture", ""); texture = getstringfield_default(L, 1, "texture", "");
playername = getstringfield_default(L, 1, "playername", ""); playername = getstringfield_default(L, 1, "playername", "");
} }
getServer(L)->spawnParticle(playername, pos, vel, acc, getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime, size,
expirationtime, size, collisiondetection, vertical, texture); collisiondetection, collision_removal, vertical, texture);
return 1; return 1;
} }
@ -110,6 +115,7 @@ int ModApiParticles::l_add_particle(lua_State *L)
// minexptime=, maxexptime=, // minexptime=, maxexptime=,
// minsize=, maxsize=, // minsize=, maxsize=,
// collisiondetection=, // collisiondetection=,
// collision_removal=,
// vertical=, // vertical=,
// texture=, // texture=,
// player=}) // player=})
@ -117,6 +123,7 @@ int ModApiParticles::l_add_particle(lua_State *L)
// minexptime/maxexptime = num (seconds) // minexptime/maxexptime = num (seconds)
// minsize/maxsize = num // minsize/maxsize = num
// collisiondetection = bool // collisiondetection = bool
// collision_removal = bool
// vertical = bool // vertical = bool
// texture = e.g."default_wood.png" // texture = e.g."default_wood.png"
int ModApiParticles::l_add_particlespawner(lua_State *L) int ModApiParticles::l_add_particlespawner(lua_State *L)
@ -129,8 +136,8 @@ int ModApiParticles::l_add_particlespawner(lua_State *L)
minpos= maxpos= minvel= maxvel= minacc= maxacc= v3f(0, 0, 0); minpos= maxpos= minvel= maxvel= minacc= maxacc= v3f(0, 0, 0);
float time, minexptime, maxexptime, minsize, maxsize; float time, minexptime, maxexptime, minsize, maxsize;
time= minexptime= maxexptime= minsize= maxsize= 1; time= minexptime= maxexptime= minsize= maxsize= 1;
bool collisiondetection, vertical; bool collisiondetection, vertical, collision_removal;
collisiondetection= vertical= false; collisiondetection = vertical = collision_removal = false;
std::string texture = ""; std::string texture = "";
std::string playername = ""; std::string playername = "";
@ -189,6 +196,8 @@ int ModApiParticles::l_add_particlespawner(lua_State *L)
maxsize = getfloatfield_default(L, 1, "maxsize", maxsize); maxsize = getfloatfield_default(L, 1, "maxsize", maxsize);
collisiondetection = getboolfield_default(L, 1, collisiondetection = getboolfield_default(L, 1,
"collisiondetection", collisiondetection); "collisiondetection", collisiondetection);
collision_removal = getboolfield_default(L, 1,
"collision_removal", collision_removal);
vertical = getboolfield_default(L, 1, "vertical", vertical); vertical = getboolfield_default(L, 1, "vertical", vertical);
texture = getstringfield_default(L, 1, "texture", ""); texture = getstringfield_default(L, 1, "texture", "");
playername = getstringfield_default(L, 1, "playername", ""); playername = getstringfield_default(L, 1, "playername", "");
@ -201,6 +210,7 @@ int ModApiParticles::l_add_particlespawner(lua_State *L)
minexptime, maxexptime, minexptime, maxexptime,
minsize, maxsize, minsize, maxsize,
collisiondetection, collisiondetection,
collision_removal,
vertical, vertical,
texture, playername); texture, playername);
lua_pushnumber(L, id); lua_pushnumber(L, id);

View File

@ -1673,7 +1673,8 @@ void Server::SendShowFormspecMessage(u16 peer_id, const std::string &formspec,
// Spawns a particle on peer with peer_id // Spawns a particle on peer with peer_id
void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f acceleration, void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f acceleration,
float expirationtime, float size, bool collisiondetection, float expirationtime, float size, bool collisiondetection,
bool vertical, std::string texture) bool collision_removal,
bool vertical, const std::string &texture)
{ {
DSTACK(FUNCTION_NAME); DSTACK(FUNCTION_NAME);
@ -1683,6 +1684,7 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat
<< size << collisiondetection; << size << collisiondetection;
pkt.putLongString(texture); pkt.putLongString(texture);
pkt << vertical; pkt << vertical;
pkt << collision_removal;
if (peer_id != PEER_ID_INEXISTENT) { if (peer_id != PEER_ID_INEXISTENT) {
Send(&pkt); Send(&pkt);
@ -1695,7 +1697,8 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat
// Adds a ParticleSpawner on peer with peer_id // Adds a ParticleSpawner on peer with peer_id
void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3f minpos, v3f maxpos, void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3f minpos, v3f maxpos,
v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime,
float minsize, float maxsize, bool collisiondetection, bool vertical, std::string texture, u32 id) float minsize, float maxsize, bool collisiondetection, bool collision_removal,
bool vertical, const std::string &texture, u32 id)
{ {
DSTACK(FUNCTION_NAME); DSTACK(FUNCTION_NAME);
@ -1708,6 +1711,7 @@ void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3
pkt.putLongString(texture); pkt.putLongString(texture);
pkt << id << vertical; pkt << id << vertical;
pkt << collision_removal;
if (peer_id != PEER_ID_INEXISTENT) { if (peer_id != PEER_ID_INEXISTENT) {
Send(&pkt); Send(&pkt);
@ -3160,7 +3164,8 @@ void Server::notifyPlayers(const std::wstring &msg)
void Server::spawnParticle(const std::string &playername, v3f pos, void Server::spawnParticle(const std::string &playername, v3f pos,
v3f velocity, v3f acceleration, v3f velocity, v3f acceleration,
float expirationtime, float size, bool float expirationtime, float size, bool
collisiondetection, bool vertical, const std::string &texture) collisiondetection, bool collision_removal,
bool vertical, const std::string &texture)
{ {
// m_env will be NULL if the server is initializing // m_env will be NULL if the server is initializing
if (!m_env) if (!m_env)
@ -3175,13 +3180,15 @@ void Server::spawnParticle(const std::string &playername, v3f pos,
} }
SendSpawnParticle(peer_id, pos, velocity, acceleration, SendSpawnParticle(peer_id, pos, velocity, acceleration,
expirationtime, size, collisiondetection, vertical, texture); expirationtime, size, collisiondetection,
collision_removal, vertical, texture);
} }
u32 Server::addParticleSpawner(u16 amount, float spawntime, u32 Server::addParticleSpawner(u16 amount, float spawntime,
v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc,
float minexptime, float maxexptime, float minsize, float maxsize, float minexptime, float maxexptime, float minsize, float maxsize,
bool collisiondetection, bool vertical, const std::string &texture, bool collisiondetection, bool collision_removal,
bool vertical, const std::string &texture,
const std::string &playername) const std::string &playername)
{ {
// m_env will be NULL if the server is initializing // m_env will be NULL if the server is initializing
@ -3200,7 +3207,7 @@ u32 Server::addParticleSpawner(u16 amount, float spawntime,
SendAddParticleSpawner(peer_id, amount, spawntime, SendAddParticleSpawner(peer_id, amount, spawntime,
minpos, maxpos, minvel, maxvel, minacc, maxacc, minpos, maxpos, minvel, maxvel, minacc, maxacc,
minexptime, maxexptime, minsize, maxsize, minexptime, maxexptime, minsize, maxsize,
collisiondetection, vertical, texture, id); collisiondetection, collision_removal, vertical, texture, id);
return id; return id;
} }

View File

@ -275,7 +275,8 @@ public:
void spawnParticle(const std::string &playername, void spawnParticle(const std::string &playername,
v3f pos, v3f velocity, v3f acceleration, v3f pos, v3f velocity, v3f acceleration,
float expirationtime, float size, float expirationtime, float size,
bool collisiondetection, bool vertical, const std::string &texture); bool collisiondetection, bool collision_removal,
bool vertical, const std::string &texture);
u32 addParticleSpawner(u16 amount, float spawntime, u32 addParticleSpawner(u16 amount, float spawntime,
v3f minpos, v3f maxpos, v3f minpos, v3f maxpos,
@ -283,7 +284,8 @@ public:
v3f minacc, v3f maxacc, v3f minacc, v3f maxacc,
float minexptime, float maxexptime, float minexptime, float maxexptime,
float minsize, float maxsize, float minsize, float maxsize,
bool collisiondetection, bool vertical, const std::string &texture, bool collisiondetection, bool collision_removal,
bool vertical, const std::string &texture,
const std::string &playername); const std::string &playername);
void deleteParticleSpawner(const std::string &playername, u32 id); void deleteParticleSpawner(const std::string &playername, u32 id);
@ -456,7 +458,8 @@ private:
v3f minacc, v3f maxacc, v3f minacc, v3f maxacc,
float minexptime, float maxexptime, float minexptime, float maxexptime,
float minsize, float maxsize, float minsize, float maxsize,
bool collisiondetection, bool vertical, std::string texture, u32 id); bool collisiondetection, bool collision_removal,
bool vertical, const std::string &texture, u32 id);
void SendDeleteParticleSpawner(u16 peer_id, u32 id); void SendDeleteParticleSpawner(u16 peer_id, u32 id);
@ -464,7 +467,8 @@ private:
void SendSpawnParticle(u16 peer_id, void SendSpawnParticle(u16 peer_id,
v3f pos, v3f velocity, v3f acceleration, v3f pos, v3f velocity, v3f acceleration,
float expirationtime, float size, float expirationtime, float size,
bool collisiondetection, bool vertical, std::string texture); bool collisiondetection, bool collision_removal,
bool vertical, const std::string &texture);
u32 SendActiveObjectRemoveAdd(u16 peer_id, const std::string &datas); u32 SendActiveObjectRemoveAdd(u16 peer_id, const std::string &datas);
void SendActiveObjectMessages(u16 peer_id, const std::string &datas, bool reliable = true); void SendActiveObjectMessages(u16 peer_id, const std::string &datas, bool reliable = true);