1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-08-11 17:51:04 +00:00

Allow spawning particles from the server, from lua

Spawn single particles or make use of ParticleSpawner for many randomly spawned particles.
Accessible in Lua using minetest.spawn_particle and minetest.add_particlespawner.
Increase Protocol Version to 17.

Conflicts:
	src/clientserver.h
This commit is contained in:
Jeija 2013-01-23 18:32:02 +01:00 committed by PilzAdam
parent ab57fdac44
commit e1ff5b1361
13 changed files with 1060 additions and 56 deletions

View file

@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "server.h"
#include <iostream>
#include <queue>
#include <algorithm>
#include "clientserver.h"
#include "map.h"
#include "jmutexautolock.h"
@ -3474,6 +3475,132 @@ void Server::SendShowFormspecMessage(u16 peer_id, const std::string formspec, co
m_con.Send(peer_id, 0, data, true);
}
// 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)
{
DSTACK(__FUNCTION_NAME);
std::ostringstream os(std::ios_base::binary);
writeU16(os, TOCLIENT_SPAWN_PARTICLE);
writeV3F1000(os, pos);
writeV3F1000(os, velocity);
writeV3F1000(os, acceleration);
writeF1000(os, expirationtime);
writeF1000(os, size);
writeU8(os, collisiondetection);
os<<serializeLongString(texture);
// Make data buffer
std::string s = os.str();
SharedBuffer<u8> data((u8*)s.c_str(), s.size());
// Send as reliable
m_con.Send(peer_id, 0, data, true);
}
// Spawns a particle on all peers
void Server::SendSpawnParticleAll(v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, std::string texture)
{
for(std::map<u16, RemoteClient*>::iterator
i = m_clients.begin();
i != m_clients.end(); i++)
{
// Get client and check that it is valid
RemoteClient *client = i->second;
assert(client->peer_id == i->first);
if(client->serialization_version == SER_FMT_VER_INVALID)
continue;
SendSpawnParticle(client->peer_id, pos, velocity, acceleration,
expirationtime, size, collisiondetection, 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)
{
DSTACK(__FUNCTION_NAME);
std::ostringstream os(std::ios_base::binary);
writeU16(os, TOCLIENT_ADD_PARTICLESPAWNER);
writeU16(os, amount);
writeF1000(os, spawntime);
writeV3F1000(os, minpos);
writeV3F1000(os, maxpos);
writeV3F1000(os, minvel);
writeV3F1000(os, maxvel);
writeV3F1000(os, minacc);
writeV3F1000(os, maxacc);
writeF1000(os, minexptime);
writeF1000(os, maxexptime);
writeF1000(os, minsize);
writeF1000(os, maxsize);
writeU8(os, collisiondetection);
os<<serializeLongString(texture);
writeU32(os, id);
// Make data buffer
std::string s = os.str();
SharedBuffer<u8> data((u8*)s.c_str(), s.size());
// Send as reliable
m_con.Send(peer_id, 0, data, true);
}
// 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)
{
for(std::map<u16, RemoteClient*>::iterator
i = m_clients.begin();
i != m_clients.end(); i++)
{
// Get client and check that it is valid
RemoteClient *client = i->second;
assert(client->peer_id == i->first);
if(client->serialization_version == SER_FMT_VER_INVALID)
continue;
SendAddParticleSpawner(client->peer_id, amount, spawntime,
minpos, maxpos, minvel, maxvel, minacc, maxacc,
minexptime, maxexptime, minsize, maxsize, collisiondetection, texture, id);
}
}
void Server::SendDeleteParticleSpawner(u16 peer_id, u32 id)
{
DSTACK(__FUNCTION_NAME);
std::ostringstream os(std::ios_base::binary);
writeU16(os, TOCLIENT_DELETE_PARTICLESPAWNER);
writeU16(os, id);
// Make data buffer
std::string s = os.str();
SharedBuffer<u8> data((u8*)s.c_str(), s.size());
// Send as reliable
m_con.Send(peer_id, 0, data, true);
}
void Server::SendDeleteParticleSpawnerAll(u32 id)
{
for(std::map<u16, RemoteClient*>::iterator
i = m_clients.begin();
i != m_clients.end(); i++)
{
// Get client and check that it is valid
RemoteClient *client = i->second;
assert(client->peer_id == i->first);
if(client->serialization_version == SER_FMT_VER_INVALID)
continue;
SendDeleteParticleSpawner(client->peer_id, id);
}
}
void Server::BroadcastChatMessage(const std::wstring &message)
{
for(std::map<u16, RemoteClient*>::iterator
@ -4432,6 +4559,111 @@ void Server::notifyPlayers(const std::wstring msg)
BroadcastChatMessage(msg);
}
void Server::spawnParticle(const char *playername, v3f pos,
v3f velocity, v3f acceleration,
float expirationtime, float size, bool
collisiondetection, std::string texture)
{
Player *player = m_env->getPlayer(playername);
if(!player)
return;
SendSpawnParticle(player->peer_id, pos, velocity, acceleration,
expirationtime, size, collisiondetection, texture);
}
void Server::spawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
float expirationtime, float size,
bool collisiondetection, std::string texture)
{
SendSpawnParticleAll(pos, velocity, acceleration,
expirationtime, size, collisiondetection, texture);
}
u32 Server::addParticleSpawner(const char *playername,
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)
{
Player *player = m_env->getPlayer(playername);
if(!player)
return -1;
u32 id = 0;
for(;;) // look for unused particlespawner id
{
id++;
if (std::find(m_particlespawner_ids.begin(),
m_particlespawner_ids.end(), id)
== m_particlespawner_ids.end())
{
m_particlespawner_ids.push_back(id);
break;
}
}
SendAddParticleSpawner(player->peer_id, amount, spawntime,
minpos, maxpos, minvel, maxvel, minacc, maxacc,
minexptime, maxexptime, minsize, maxsize,
collisiondetection, texture, id);
return id;
}
u32 Server::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)
{
u32 id = 0;
for(;;) // look for unused particlespawner id
{
id++;
if (std::find(m_particlespawner_ids.begin(),
m_particlespawner_ids.end(), id)
== m_particlespawner_ids.end())
{
m_particlespawner_ids.push_back(id);
break;
}
}
SendAddParticleSpawnerAll(amount, spawntime,
minpos, maxpos, minvel, maxvel, minacc, maxacc,
minexptime, maxexptime, minsize, maxsize,
collisiondetection, texture, id);
return id;
}
void Server::deleteParticleSpawner(const char *playername, u32 id)
{
Player *player = m_env->getPlayer(playername);
if(!player)
return;
m_particlespawner_ids.erase(
std::remove(m_particlespawner_ids.begin(),
m_particlespawner_ids.end(), id),
m_particlespawner_ids.end());
SendDeleteParticleSpawner(player->peer_id, id);
}
void Server::deleteParticleSpawnerAll(u32 id)
{
m_particlespawner_ids.erase(
std::remove(m_particlespawner_ids.begin(),
m_particlespawner_ids.end(), id),
m_particlespawner_ids.end());
SendDeleteParticleSpawnerAll(id);
}
void Server::queueBlockEmerge(v3s16 blockpos, bool allow_generate)
{
m_emerge->enqueueBlockEmerge(PEER_ID_INEXISTENT, blockpos, allow_generate);