summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/lua_api.txt6
-rw-r--r--src/client.h2
-rw-r--r--src/network/clientpackethandler.cpp7
-rw-r--r--src/network/networkprotocol.h2
-rw-r--r--src/particles.cpp39
-rw-r--r--src/particles.h5
-rw-r--r--src/script/lua_api/l_particles.cpp24
-rw-r--r--src/server.cpp19
-rw-r--r--src/server.h12
9 files changed, 84 insertions, 32 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 01763fd73..03f2dad32 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -3885,6 +3885,9 @@ Definition tables
size = 1,
collisiondetection = false,
-- ^ 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: if true faces player using y axis only
texture = "image.png",
@@ -3914,6 +3917,9 @@ Definition tables
-- ^ minsize/maxsize, minexptime/maxexptime (expirationtime)
collisiondetection = false,
-- ^ 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: if true faces player using y axis only
texture = "image.png",
diff --git a/src/client.h b/src/client.h
index cdadb9d3e..a7eb22ad9 100644
--- a/src/client.h
+++ b/src/client.h
@@ -182,6 +182,7 @@ struct ClientEvent
f32 expirationtime;
f32 size;
bool collisiondetection;
+ bool collision_removal;
bool vertical;
std::string *texture;
} spawn_particle;
@@ -199,6 +200,7 @@ struct ClientEvent
f32 minsize;
f32 maxsize;
bool collisiondetection;
+ bool collision_removal;
bool vertical;
std::string *texture;
u32 id;
diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp
index 0498f4048..48c573da5 100644
--- a/src/network/clientpackethandler.cpp
+++ b/src/network/clientpackethandler.cpp
@@ -898,8 +898,10 @@ void Client::handleCommand_SpawnParticle(NetworkPacket* pkt)
bool collisiondetection = readU8(is);
std::string texture = deSerializeLongString(is);
bool vertical = false;
+ bool collision_removal = false;
try {
vertical = readU8(is);
+ collision_removal = readU8(is);
} catch (...) {}
ClientEvent event;
@@ -910,6 +912,7 @@ void Client::handleCommand_SpawnParticle(NetworkPacket* pkt)
event.spawn_particle.expirationtime = expirationtime;
event.spawn_particle.size = size;
event.spawn_particle.collisiondetection = collisiondetection;
+ event.spawn_particle.collision_removal = collision_removal;
event.spawn_particle.vertical = vertical;
event.spawn_particle.texture = new std::string(texture);
@@ -942,8 +945,11 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
*pkt >> id;
bool vertical = false;
+ bool collision_removal = false;
try {
*pkt >> vertical;
+ *pkt >> collision_removal;
+
} catch (...) {}
ClientEvent event;
@@ -961,6 +967,7 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
event.add_particlespawner.minsize = minsize;
event.add_particlespawner.maxsize = maxsize;
event.add_particlespawner.collisiondetection = collisiondetection;
+ event.add_particlespawner.collision_removal = collision_removal;
event.add_particlespawner.vertical = vertical;
event.add_particlespawner.texture = new std::string(texture);
event.add_particlespawner.id = id;
diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h
index 177b97680..3a9483efb 100644
--- a/src/network/networkprotocol.h
+++ b/src/network/networkprotocol.h
@@ -474,6 +474,7 @@ enum ToClientCommand
u8 bool vertical
u32 len
u8[len] texture
+ u8 collision_removal
*/
TOCLIENT_ADD_PARTICLESPAWNER = 0x47,
@@ -495,6 +496,7 @@ enum ToClientCommand
u32 len
u8[len] texture
u32 id
+ u8 collision_removal
*/
TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY = 0x48,
diff --git a/src/particles.cpp b/src/particles.cpp
index 525258a25..ccca691d1 100644
--- a/src/particles.cpp
+++ b/src/particles.cpp
@@ -54,6 +54,7 @@ Particle::Particle(
float expirationtime,
float size,
bool collisiondetection,
+ bool collision_removal,
bool vertical,
video::ITexture *texture,
v2f texpos,
@@ -85,6 +86,7 @@ Particle::Particle(
m_player = player;
m_size = size;
m_collisiondetection = collisiondetection;
+ m_collision_removal = collision_removal;
m_vertical = vertical;
// Irrlicht stuff
@@ -126,20 +128,21 @@ void Particle::render()
void Particle::step(float dtime)
{
m_time += dtime;
- if (m_collisiondetection)
- {
+ if (m_collisiondetection) {
aabb3f box = m_collisionbox;
- v3f p_pos = m_pos*BS;
- v3f p_velocity = m_velocity*BS;
- collisionMoveSimple(m_env, m_gamedef,
- BS*0.5, box,
- 0, dtime,
- &p_pos, &p_velocity, m_acceleration * BS);
- m_pos = p_pos/BS;
- m_velocity = p_velocity/BS;
- }
- else
- {
+ v3f p_pos = m_pos * BS;
+ v3f p_velocity = m_velocity * BS;
+ collisionMoveResult r = collisionMoveSimple(m_env,
+ m_gamedef, BS * 0.5, box, 0, dtime, &p_pos,
+ &p_velocity, m_acceleration * BS);
+ if (m_collision_removal && r.collides) {
+ // force expiration of the particle
+ m_expiration = -1.0;
+ } else {
+ m_pos = p_pos / BS;
+ m_velocity = p_velocity / BS;
+ }
+ } else {
m_velocity += m_acceleration * dtime;
m_pos += m_velocity * dtime;
}
@@ -210,8 +213,8 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr,
u16 amount, float time,
v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc,
float minexptime, float maxexptime, float minsize, float maxsize,
- bool collisiondetection, bool vertical, video::ITexture *texture, u32 id,
- ParticleManager *p_manager) :
+ bool collisiondetection, bool collision_removal, bool vertical,
+ video::ITexture *texture, u32 id, ParticleManager *p_manager) :
m_particlemanager(p_manager)
{
m_gamedef = gamedef;
@@ -230,6 +233,7 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr,
m_minsize = minsize;
m_maxsize = maxsize;
m_collisiondetection = collisiondetection;
+ m_collision_removal = collision_removal;
m_vertical = vertical;
m_texture = texture;
m_time = 0;
@@ -277,6 +281,7 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
exptime,
size,
m_collisiondetection,
+ m_collision_removal,
m_vertical,
m_texture,
v2f(0.0, 0.0),
@@ -317,6 +322,7 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
exptime,
size,
m_collisiondetection,
+ m_collision_removal,
m_vertical,
m_texture,
v2f(0.0, 0.0),
@@ -446,6 +452,7 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef,
event->add_particlespawner.minsize,
event->add_particlespawner.maxsize,
event->add_particlespawner.collisiondetection,
+ event->add_particlespawner.collision_removal,
event->add_particlespawner.vertical,
texture,
event->add_particlespawner.id,
@@ -480,6 +487,7 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef,
event->spawn_particle.expirationtime,
event->spawn_particle.size,
event->spawn_particle.collisiondetection,
+ event->spawn_particle.collision_removal,
event->spawn_particle.vertical,
texture,
v2f(0.0, 0.0),
@@ -555,6 +563,7 @@ void ParticleManager::addNodeParticle(IGameDef* gamedef, scene::ISceneManager* s
visual_size,
true,
false,
+ false,
texture,
texpos,
texsize);
diff --git a/src/particles.h b/src/particles.h
index dda84385c..bc3ca53b7 100644
--- a/src/particles.h
+++ b/src/particles.h
@@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
struct ClientEvent;
class ParticleManager;
+class ClientEnvironment;
class Particle : public scene::ISceneNode
{
@@ -45,6 +46,7 @@ class Particle : public scene::ISceneNode
float expirationtime,
float size,
bool collisiondetection,
+ bool collision_removal,
bool vertical,
video::ITexture *texture,
v2f texpos,
@@ -97,6 +99,7 @@ private:
float m_size;
u8 m_light;
bool m_collisiondetection;
+ bool m_collision_removal;
bool m_vertical;
v3s16 m_camera_offset;
};
@@ -115,6 +118,7 @@ class ParticleSpawner
float minexptime, float maxexptime,
float minsize, float maxsize,
bool collisiondetection,
+ bool collision_removal,
bool vertical,
video::ITexture *texture,
u32 id,
@@ -148,6 +152,7 @@ class ParticleSpawner
video::ITexture *m_texture;
std::vector<float> m_spawntimes;
bool m_collisiondetection;
+ bool m_collision_removal;
bool m_vertical;
};
diff --git a/src/script/lua_api/l_particles.cpp b/src/script/lua_api/l_particles.cpp
index f6c1725de..263e35407 100644
--- a/src/script/lua_api/l_particles.cpp
+++ b/src/script/lua_api/l_particles.cpp
@@ -21,13 +21,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_internal.h"
#include "common/c_converter.h"
#include "server.h"
+#include "particles.h"
// 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}
// expirationtime = num (seconds)
// size = num
// collisiondetection = bool
+// collision_removal = bool
// vertical = bool
// texture = e.g."default_wood.png"
int ModApiParticles::l_add_particle(lua_State *L)
@@ -41,8 +44,8 @@ int ModApiParticles::l_add_particle(lua_State *L)
float expirationtime, size;
expirationtime = size = 1;
- bool collisiondetection, vertical;
- collisiondetection = vertical = false;
+ bool collisiondetection, vertical, collision_removal;
+ collisiondetection = vertical = collision_removal = false;
std::string texture = "";
std::string playername = "";
@@ -94,12 +97,14 @@ int ModApiParticles::l_add_particle(lua_State *L)
size = getfloatfield_default(L, 1, "size", 1);
collisiondetection = getboolfield_default(L, 1,
"collisiondetection", collisiondetection);
+ collision_removal = getboolfield_default(L, 1,
+ "collision_removal", collision_removal);
vertical = getboolfield_default(L, 1, "vertical", vertical);
texture = getstringfield_default(L, 1, "texture", "");
playername = getstringfield_default(L, 1, "playername", "");
}
- getServer(L)->spawnParticle(playername, pos, vel, acc,
- expirationtime, size, collisiondetection, vertical, texture);
+ getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime, size,
+ collisiondetection, collision_removal, vertical, texture);
return 1;
}
@@ -110,6 +115,7 @@ int ModApiParticles::l_add_particle(lua_State *L)
// minexptime=, maxexptime=,
// minsize=, maxsize=,
// collisiondetection=,
+// collision_removal=,
// vertical=,
// texture=,
// player=})
@@ -117,6 +123,7 @@ int ModApiParticles::l_add_particle(lua_State *L)
// minexptime/maxexptime = num (seconds)
// minsize/maxsize = num
// collisiondetection = bool
+// collision_removal = bool
// vertical = bool
// texture = e.g."default_wood.png"
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);
float time, minexptime, maxexptime, minsize, maxsize;
time= minexptime= maxexptime= minsize= maxsize= 1;
- bool collisiondetection, vertical;
- collisiondetection= vertical= false;
+ bool collisiondetection, vertical, collision_removal;
+ collisiondetection = vertical = collision_removal = false;
std::string texture = "";
std::string playername = "";
@@ -189,6 +196,8 @@ int ModApiParticles::l_add_particlespawner(lua_State *L)
maxsize = getfloatfield_default(L, 1, "maxsize", maxsize);
collisiondetection = getboolfield_default(L, 1,
"collisiondetection", collisiondetection);
+ collision_removal = getboolfield_default(L, 1,
+ "collision_removal", collision_removal);
vertical = getboolfield_default(L, 1, "vertical", vertical);
texture = getstringfield_default(L, 1, "texture", "");
playername = getstringfield_default(L, 1, "playername", "");
@@ -201,6 +210,7 @@ int ModApiParticles::l_add_particlespawner(lua_State *L)
minexptime, maxexptime,
minsize, maxsize,
collisiondetection,
+ collision_removal,
vertical,
texture, playername);
lua_pushnumber(L, id);
diff --git a/src/server.cpp b/src/server.cpp
index a3b686c25..ada45dc68 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -1673,7 +1673,8 @@ void Server::SendShowFormspecMessage(u16 peer_id, const std::string &formspec,
// Spawns a particle on peer with peer_id
void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f acceleration,
float expirationtime, float size, bool collisiondetection,
- bool vertical, std::string texture)
+ bool collision_removal,
+ bool vertical, const std::string &texture)
{
DSTACK(FUNCTION_NAME);
@@ -1683,6 +1684,7 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat
<< size << collisiondetection;
pkt.putLongString(texture);
pkt << vertical;
+ pkt << collision_removal;
if (peer_id != PEER_ID_INEXISTENT) {
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
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,
- 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);
@@ -1708,6 +1711,7 @@ void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3
pkt.putLongString(texture);
pkt << id << vertical;
+ pkt << collision_removal;
if (peer_id != PEER_ID_INEXISTENT) {
Send(&pkt);
@@ -3160,7 +3164,8 @@ void Server::notifyPlayers(const std::wstring &msg)
void Server::spawnParticle(const std::string &playername, v3f pos,
v3f velocity, v3f acceleration,
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
if (!m_env)
@@ -3175,13 +3180,15 @@ void Server::spawnParticle(const std::string &playername, v3f pos,
}
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,
v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc,
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)
{
// 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,
minpos, maxpos, minvel, maxvel, minacc, maxacc,
minexptime, maxexptime, minsize, maxsize,
- collisiondetection, vertical, texture, id);
+ collisiondetection, collision_removal, vertical, texture, id);
return id;
}
diff --git a/src/server.h b/src/server.h
index daf51dee1..7ee15a463 100644
--- a/src/server.h
+++ b/src/server.h
@@ -275,7 +275,8 @@ public:
void spawnParticle(const std::string &playername,
v3f pos, v3f velocity, v3f acceleration,
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,
v3f minpos, v3f maxpos,
@@ -283,7 +284,8 @@ public:
v3f minacc, v3f maxacc,
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);
void deleteParticleSpawner(const std::string &playername, u32 id);
@@ -456,7 +458,8 @@ private:
v3f minacc, v3f maxacc,
float minexptime, float maxexptime,
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);
@@ -464,7 +467,8 @@ private:
void SendSpawnParticle(u16 peer_id,
v3f pos, v3f velocity, v3f acceleration,
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);
void SendActiveObjectMessages(u16 peer_id, const std::string &datas, bool reliable = true);