193 changes: 148 additions & 45 deletions src/script/lua_api/l_particles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,93 +22,196 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common/c_converter.h"
#include "server.h"

// add_particle(pos, velocity, acceleration, expirationtime,
// size, collisiondetection, texture, player)
// add_particle({pos=, velocity=, acceleration=, expirationtime=,
// size=, collisiondetection=, vertical=, texture=, player=})
// pos/velocity/acceleration = {x=num, y=num, z=num}
// expirationtime = num (seconds)
// size = num
// collisiondetection = bool
// vertical = bool
// texture = e.g."default_wood.png"
int ModApiParticles::l_add_particle(lua_State *L)
{
// Get parameters
v3f pos = check_v3f(L, 1);
v3f vel = check_v3f(L, 2);
v3f acc = check_v3f(L, 3);
float expirationtime = luaL_checknumber(L, 4);
float size = luaL_checknumber(L, 5);
bool collisiondetection = lua_toboolean(L, 6);
std::string texture = luaL_checkstring(L, 7);
v3f pos, vel, acc;
pos= vel= acc= v3f(0, 0, 0);
float expirationtime, size;
expirationtime= size= 1;
bool collisiondetection, vertical;
collisiondetection= vertical= false;
std::string texture = "";
const char *playername = "";

if (lua_gettop(L) == 8) // only spawn for a single player
if (lua_gettop(L) > 1) // deprecated
{
const char *playername = luaL_checkstring(L, 8);
getServer(L)->spawnParticle(playername,
pos, vel, acc, expirationtime,
size, collisiondetection, texture);
pos = check_v3f(L, 1);
vel = check_v3f(L, 2);
acc = check_v3f(L, 3);
expirationtime = luaL_checknumber(L, 4);
size = luaL_checknumber(L, 5);
collisiondetection = lua_toboolean(L, 6);
texture = luaL_checkstring(L, 7);
if (lua_gettop(L) == 8) // only spawn for a single player
playername = luaL_checkstring(L, 8);
}
else if (lua_istable(L, 1))
{
int table = lua_gettop(L);
lua_pushnil(L);
while (lua_next(L, table) != 0)
{
const char *key = lua_tostring(L, -2);
if(strcmp(key,"pos")==0){
pos=check_v3f(L, -1);
}else if(strcmp(key,"vel")==0){
vel=check_v3f(L, -1);
}else if(strcmp(key,"acc")==0){
acc=check_v3f(L, -1);
}else if(strcmp(key,"expirationtime")==0){
expirationtime=luaL_checknumber(L, -1);
}else if(strcmp(key,"size")==0){
size=luaL_checknumber(L, -1);
}else if(strcmp(key,"collisiondetection")==0){
collisiondetection=lua_toboolean(L, -1);
}else if(strcmp(key,"vertical")==0){
vertical=lua_toboolean(L, -1);
}else if(strcmp(key,"texture")==0){
texture=luaL_checkstring(L, -1);
}else if(strcmp(key,"playername")==0){
playername=luaL_checkstring(L, -1);
}
lua_pop(L, 1);
}
}
else // spawn for all players
if (strcmp(playername, "")==0) // spawn for all players
{
getServer(L)->spawnParticleAll(pos, vel, acc,
expirationtime, size, collisiondetection, texture);
expirationtime, size, collisiondetection, vertical, texture);
}
else
{
getServer(L)->spawnParticle(playername,
pos, vel, acc, expirationtime,
size, collisiondetection, vertical, texture);
}
return 1;
}

// add_particlespawner(amount, time,
// minpos, maxpos,
// minvel, maxvel,
// minacc, maxacc,
// minexptime, maxexptime,
// minsize, maxsize,
// collisiondetection,
// texture,
// player)
// add_particlespawner({amount=, time=,
// minpos=, maxpos=,
// minvel=, maxvel=,
// minacc=, maxacc=,
// minexptime=, maxexptime=,
// minsize=, maxsize=,
// collisiondetection=,
// vertical=,
// texture=,
// player=})
// minpos/maxpos/minvel/maxvel/minacc/maxacc = {x=num, y=num, z=num}
// minexptime/maxexptime = num (seconds)
// minsize/maxsize = num
// collisiondetection = bool
// vertical = bool
// texture = e.g."default_wood.png"
int ModApiParticles::l_add_particlespawner(lua_State *L)
{
// Get parameters
u16 amount = luaL_checknumber(L, 1);
float time = luaL_checknumber(L, 2);
v3f minpos = check_v3f(L, 3);
v3f maxpos = check_v3f(L, 4);
v3f minvel = check_v3f(L, 5);
v3f maxvel = check_v3f(L, 6);
v3f minacc = check_v3f(L, 7);
v3f maxacc = check_v3f(L, 8);
float minexptime = luaL_checknumber(L, 9);
float maxexptime = luaL_checknumber(L, 10);
float minsize = luaL_checknumber(L, 11);
float maxsize = luaL_checknumber(L, 12);
bool collisiondetection = lua_toboolean(L, 13);
std::string texture = luaL_checkstring(L, 14);
u16 amount = 1;
v3f minpos, maxpos, minvel, maxvel, minacc, maxacc;
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;
std::string texture = "";
const char *playername = "";

if (lua_gettop(L) == 15) // only spawn for a single player
if (lua_gettop(L) > 1) //deprecated
{
const char *playername = luaL_checkstring(L, 15);
u32 id = getServer(L)->addParticleSpawner(playername,
amount, time,
amount = luaL_checknumber(L, 1);
time = luaL_checknumber(L, 2);
minpos = check_v3f(L, 3);
maxpos = check_v3f(L, 4);
minvel = check_v3f(L, 5);
maxvel = check_v3f(L, 6);
minacc = check_v3f(L, 7);
maxacc = check_v3f(L, 8);
minexptime = luaL_checknumber(L, 9);
maxexptime = luaL_checknumber(L, 10);
minsize = luaL_checknumber(L, 11);
maxsize = luaL_checknumber(L, 12);
collisiondetection = lua_toboolean(L, 13);
texture = luaL_checkstring(L, 14);
if (lua_gettop(L) == 15) // only spawn for a single player
playername = luaL_checkstring(L, 15);
}
else if (lua_istable(L, 1))
{
int table = lua_gettop(L);
lua_pushnil(L);
while (lua_next(L, table) != 0)
{
const char *key = lua_tostring(L, -2);
if(strcmp(key,"amount")==0){
amount=luaL_checknumber(L, -1);
}else if(strcmp(key,"time")==0){
time=luaL_checknumber(L, -1);
}else if(strcmp(key,"minpos")==0){
minpos=check_v3f(L, -1);
}else if(strcmp(key,"maxpos")==0){
maxpos=check_v3f(L, -1);
}else if(strcmp(key,"minvel")==0){
minvel=check_v3f(L, -1);
}else if(strcmp(key,"maxvel")==0){
maxvel=check_v3f(L, -1);
}else if(strcmp(key,"minacc")==0){
minacc=check_v3f(L, -1);
}else if(strcmp(key,"maxacc")==0){
maxacc=check_v3f(L, -1);
}else if(strcmp(key,"minexptime")==0){
minexptime=luaL_checknumber(L, -1);
}else if(strcmp(key,"maxexptime")==0){
maxexptime=luaL_checknumber(L, -1);
}else if(strcmp(key,"minsize")==0){
minsize=luaL_checknumber(L, -1);
}else if(strcmp(key,"maxsize")==0){
maxsize=luaL_checknumber(L, -1);
}else if(strcmp(key,"collisiondetection")==0){
collisiondetection=lua_toboolean(L, -1);
}else if(strcmp(key,"vertical")==0){
vertical=lua_toboolean(L, -1);
}else if(strcmp(key,"texture")==0){
texture=luaL_checkstring(L, -1);
}else if(strcmp(key,"playername")==0){
playername=luaL_checkstring(L, -1);
}
lua_pop(L, 1);
}
}
if (strcmp(playername, "")==0) //spawn for all players
{
u32 id = getServer(L)->addParticleSpawnerAll( amount, time,
minpos, maxpos,
minvel, maxvel,
minacc, maxacc,
minexptime, maxexptime,
minsize, maxsize,
collisiondetection,
vertical,
texture);
lua_pushnumber(L, id);
}
else // spawn for all players
else
{
u32 id = getServer(L)->addParticleSpawnerAll( amount, time,
u32 id = getServer(L)->addParticleSpawner(playername,
amount, time,
minpos, maxpos,
minvel, maxvel,
minacc, maxacc,
minexptime, maxexptime,
minsize, maxsize,
collisiondetection,
vertical,
texture);
lua_pushnumber(L, id);
}
Expand Down
30 changes: 16 additions & 14 deletions src/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3573,7 +3573,7 @@ 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,
std::string texture)
bool vertical, std::string texture)
{
DSTACK(__FUNCTION_NAME);

Expand All @@ -3586,6 +3586,7 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat
writeF1000(os, size);
writeU8(os, collisiondetection);
os<<serializeLongString(texture);
writeU8(os, vertical);

// Make data buffer
std::string s = os.str();
Expand All @@ -3597,7 +3598,7 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat
// Spawns a particle on all peers
void Server::SendSpawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
float expirationtime, float size, bool collisiondetection,
std::string texture)
bool vertical, std::string texture)
{
for(std::map<u16, RemoteClient*>::iterator
i = m_clients.begin();
Expand All @@ -3610,14 +3611,14 @@ void Server::SendSpawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
continue;

SendSpawnParticle(client->peer_id, pos, velocity, acceleration,
expirationtime, size, collisiondetection, texture);
expirationtime, size, collisiondetection, vertical, texture);
}
}

// 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, std::string texture, u32 id)
float minsize, float maxsize, bool collisiondetection, bool vertical, std::string texture, u32 id)
{
DSTACK(__FUNCTION_NAME);

Expand All @@ -3639,6 +3640,7 @@ void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3
writeU8(os, collisiondetection);
os<<serializeLongString(texture);
writeU32(os, id);
writeU8(os, vertical);

// Make data buffer
std::string s = os.str();
Expand All @@ -3650,7 +3652,7 @@ void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3
// Adds a ParticleSpawner on all peers
void Server::SendAddParticleSpawnerAll(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, std::string texture, u32 id)
float minsize, float maxsize, bool collisiondetection, bool vertical, std::string texture, u32 id)
{
for(std::map<u16, RemoteClient*>::iterator
i = m_clients.begin();
Expand All @@ -3664,7 +3666,7 @@ void Server::SendAddParticleSpawnerAll(u16 amount, float spawntime, v3f minpos,

SendAddParticleSpawner(client->peer_id, amount, spawntime,
minpos, maxpos, minvel, maxvel, minacc, maxacc,
minexptime, maxexptime, minsize, maxsize, collisiondetection, texture, id);
minexptime, maxexptime, minsize, maxsize, collisiondetection, vertical, texture, id);
}
}

Expand Down Expand Up @@ -5051,21 +5053,21 @@ void Server::notifyPlayers(const std::wstring msg)
void Server::spawnParticle(const char *playername, v3f pos,
v3f velocity, v3f acceleration,
float expirationtime, float size, bool
collisiondetection, std::string texture)
collisiondetection, bool vertical, std::string texture)
{
Player *player = m_env->getPlayer(playername);
if(!player)
return;
SendSpawnParticle(player->peer_id, pos, velocity, acceleration,
expirationtime, size, collisiondetection, texture);
expirationtime, size, collisiondetection, vertical, texture);
}

void Server::spawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
float expirationtime, float size,
bool collisiondetection, std::string texture)
bool collisiondetection, bool vertical, std::string texture)
{
SendSpawnParticleAll(pos, velocity, acceleration,
expirationtime, size, collisiondetection, texture);
expirationtime, size, collisiondetection, vertical, texture);
}

u32 Server::addParticleSpawner(const char *playername,
Expand All @@ -5075,7 +5077,7 @@ u32 Server::addParticleSpawner(const char *playername,
v3f minacc, v3f maxacc,
float minexptime, float maxexptime,
float minsize, float maxsize,
bool collisiondetection, std::string texture)
bool collisiondetection, bool vertical, std::string texture)
{
Player *player = m_env->getPlayer(playername);
if(!player)
Expand All @@ -5097,7 +5099,7 @@ u32 Server::addParticleSpawner(const char *playername,
SendAddParticleSpawner(player->peer_id, amount, spawntime,
minpos, maxpos, minvel, maxvel, minacc, maxacc,
minexptime, maxexptime, minsize, maxsize,
collisiondetection, texture, id);
collisiondetection, vertical, texture, id);

return id;
}
Expand All @@ -5108,7 +5110,7 @@ u32 Server::addParticleSpawnerAll(u16 amount, float spawntime,
v3f minacc, v3f maxacc,
float minexptime, float maxexptime,
float minsize, float maxsize,
bool collisiondetection, std::string texture)
bool collisiondetection, bool vertical, std::string texture)
{
u32 id = 0;
for(;;) // look for unused particlespawner id
Expand All @@ -5126,7 +5128,7 @@ u32 Server::addParticleSpawnerAll(u16 amount, float spawntime,
SendAddParticleSpawnerAll(amount, spawntime,
minpos, maxpos, minvel, maxvel, minacc, maxacc,
minexptime, maxexptime, minsize, maxsize,
collisiondetection, texture, id);
collisiondetection, vertical, texture, id);

return id;
}
Expand Down
16 changes: 8 additions & 8 deletions src/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,11 +389,11 @@ class Server : public con::PeerHandler, public MapEventReceiver,
void spawnParticle(const char *playername,
v3f pos, v3f velocity, v3f acceleration,
float expirationtime, float size,
bool collisiondetection, std::string texture);
bool collisiondetection, bool vertical, std::string texture);

void spawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
float expirationtime, float size,
bool collisiondetection, std::string texture);
bool collisiondetection, bool vertical, std::string texture);

u32 addParticleSpawner(const char *playername,
u16 amount, float spawntime,
Expand All @@ -402,15 +402,15 @@ class Server : public con::PeerHandler, public MapEventReceiver,
v3f minacc, v3f maxacc,
float minexptime, float maxexptime,
float minsize, float maxsize,
bool collisiondetection, std::string texture);
bool collisiondetection, bool vertical, std::string texture);

u32 addParticleSpawnerAll(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, std::string texture);
bool collisiondetection, bool vertical, std::string texture);

void deleteParticleSpawner(const char *playername, u32 id);
void deleteParticleSpawnerAll(u32 id);
Expand Down Expand Up @@ -556,7 +556,7 @@ class Server : public con::PeerHandler, public MapEventReceiver,
v3f minacc, v3f maxacc,
float minexptime, float maxexptime,
float minsize, float maxsize,
bool collisiondetection, std::string texture, u32 id);
bool collisiondetection, bool vertical, std::string texture, u32 id);

// Adds a ParticleSpawner on all peers
void SendAddParticleSpawnerAll(u16 amount, float spawntime,
Expand All @@ -565,7 +565,7 @@ class Server : public con::PeerHandler, public MapEventReceiver,
v3f minacc, v3f maxacc,
float minexptime, float maxexptime,
float minsize, float maxsize,
bool collisiondetection, std::string texture, u32 id);
bool collisiondetection, bool vertical, std::string texture, u32 id);

// Deletes ParticleSpawner on a single client
void SendDeleteParticleSpawner(u16 peer_id, u32 id);
Expand All @@ -577,12 +577,12 @@ class Server : public con::PeerHandler, public MapEventReceiver,
void SendSpawnParticle(u16 peer_id,
v3f pos, v3f velocity, v3f acceleration,
float expirationtime, float size,
bool collisiondetection, std::string texture);
bool collisiondetection, bool vertical, std::string texture);

// Spawns particle on all clients
void SendSpawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
float expirationtime, float size,
bool collisiondetection, std::string texture);
bool collisiondetection, bool vertical, std::string texture);

/*
Something random
Expand Down