-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Attached Particle Spawners #4409
Conversation
if (attached != NULL) | ||
{ | ||
// CAO coordinates in irrlicht units, but particles are | ||
// not. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could use BS there.
If ActiveObjects contained references to the particle spawners, the spawner would be deleted when the object is deleted/unloaded. The class ActiveObject could extend ParticleSpawner to spawn particles. Or ParticleManager could also support ActiveObjects as spawners. Or you could create ParticleSpawner::removeSpawner() which the ActiveObject calls when it is unloaded or deleted. |
bb820a0
to
632398c
Compare
Thanks @juhdanad. I've already started implementing that part, and have gone the route of having the server manage the lifetime of attached particle spawners. |
Server-side lifetime handling implemented. |
I forgot to document this. EDIT: documented |
I love it, seems to work really well. |
I noticed that you can use 0 as a "null object id" so I changed the code to use u16 instead of s32 for sending and handling ids. |
be04e1a
to
990e26d
Compare
Rebased and squashed |
990e26d
to
79b7a3e
Compare
Question: Can we get an interface that is similar to player:set_attach() and player:detach() ? Maybe that will make it easier to avoid the "0" id problem? Just a thought. |
@sofar It would only avoid it in the add_particlespawner packet, which I don't think is a big deal. It could already be avoided in the client by keeping a table of attachments, as it is done on the server, but I didn't do that because handling and tracking the offset of particles logically belongs in the particle spawner code. |
Also using a set_attach would either require an API change to |
@@ -156,6 +156,13 @@ LuaEntitySAO::~LuaEntitySAO() | |||
if(m_registered){ | |||
m_env->getScriptIface()->luaentity_Remove(m_id); | |||
} | |||
|
|||
std::set<u32>::iterator it; | |||
std::set<u32>::iterator begin = m_attached_particle_spawners.begin(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think in most of the code you'll find that begin/end are just omitted and m_attached_particle_spawners.begin()
is just used directly in the for(
loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll put them inline but I'm not going to make a line with 100+ columns
u32 id = addParticleSpawner(exptime); | ||
m_particle_spawner_attachments[id] = attached_id; | ||
ServerActiveObject *obj = getActiveObject(attached_id); | ||
if (obj != NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer if (obj) {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You just said to use iterator methods inline since the rest of the code does it, but in this file the code typically uses != NULL.
v3f attached_offset = v3f(0,0,0); | ||
if (m_attached_id != 0) { | ||
ClientActiveObject *attached = | ||
env->getActiveObject(m_attached_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fits on one line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it goes a bit above 80 columns, but I guess that the style guide says that's ok
if (m_attached_id != 0) { | ||
ClientActiveObject *attached = | ||
env->getActiveObject(m_attached_id); | ||
if (attached != NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (attached) {
@@ -3200,11 +3202,19 @@ u32 Server::addParticleSpawner(u16 amount, float spawntime, | |||
peer_id = player->peer_id; | |||
} | |||
|
|||
u32 id = m_env->addParticleSpawner(spawntime); | |||
u16 attached_id = attached == NULL ? 0 : attached->getId(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
u16 attached_id = attached ? attached->getId() : 0;
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks pretty good.
I've made your changes, just making sure it builds |
79b7a3e
to
36472b4
Compare
actually hold on, I missed one. |
36472b4
to
853511e
Compare
Here is a demo with particles used to add effects to a projectile: https://a.desu.sh/fywvhg.webm |
853511e
to
3765527
Compare
Rebased. |
attached_offset = attached->getPosition() / BS; | ||
} else { | ||
unloaded = true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removal of braces possible:
if (attached)
attached_offset = attached->getPosition() / BS;
else
unloaded = true;
id = m_env->addParticleSpawner(spawntime); | ||
} else { | ||
id = m_env->addParticleSpawner(spawntime, attached_id); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removal of braces possible
I have to say: Really really good job! 👍 |
3765527
to
eadda20
Compare
@sfan5 Thanks, also made the suggested changes. |
👍 from me, very happy to see this patch :) |
{ | ||
u32 id = addParticleSpawner(exptime); | ||
m_particle_spawner_attachments[id] = attached_id; | ||
ServerActiveObject *obj = getActiveObject(attached_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
merge this in the condition
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But I use obj a couple lines later, won't I have to repeat getActiveObject then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no you use it only in the condition before, then you can do this affectation in the condition
@@ -3163,6 +3164,7 @@ void Server::spawnParticle(const std::string &playername, v3f pos, | |||
if (playername != "") { | |||
Player* player = m_env->getPlayer(playername.c_str()); | |||
if (!player) | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you should remove this
@@ -99,3 +99,12 @@ bool ServerActiveObject::setWieldedItem(const ItemStack &item) | |||
return false; | |||
} | |||
|
|||
void ServerActiveObject::attachParticleSpawner(u32 id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please inline this function
m_attached_particle_spawners.insert(id); | ||
} | ||
|
||
void ServerActiveObject::detachParticleSpawner(u32 id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here, inline by moving definition to header
v3f attached_offset = v3f(0,0,0); | ||
if (m_attached_id != 0) { | ||
ClientActiveObject *attached = env->getActiveObject(m_attached_id); | ||
if (attached) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
merge condition & previous line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I use attached in the next line, won't I have to call env->getActiveObject again?
if (sao != NULL && remove_from_object) { | ||
sao->detachParticleSpawner(id); | ||
} | ||
} catch (...) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why there is a try catch here ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "at" method throws an exception if something isn't there. Often there won't be, since particle spawners might not be attached
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please catch the corresponding exception then not all
} | ||
|
||
void ServerEnvironment::deleteParticleSpawner(u32 id, | ||
bool remove_from_object) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can move this on the upper line
eadda20
to
41754cb
Compare
@nerzhul Made some of your requested changes, responded or asked for clarification on others. |
v3f attached_offset = v3f(0,0,0); | ||
if (m_attached_id != 0) { | ||
ClientActiveObject *attached = env->getActiveObject(m_attached_id); | ||
if (attached) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please do the decl/affectation in the condition here too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I use attached on the next line, am I supposed to duplicate the method calls?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no because it's used in the condition, in fact with this method you do the test for the decl/assignment directly without creating a variable out of the needed scope
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't know you could put declarations in the condition, thanks.
41754cb
to
9b9dc0b
Compare
@nerzhul Ok, did the things. |
4c70e11
to
9f60f75
Compare
Switched from using |
sao->detachParticleSpawner(id); | ||
} | ||
} | ||
m_particle_spawner_attachments.erase(id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think this call should be in the condition, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it should, however .erase()
doesn't do anything when the key is not found in the array, so it doesn't matter in practice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, though it didn't do any harm being outside the condition. (Pushed a new version with the erase inside the condition)
9f60f75
to
ce3a428
Compare
Okay for me |
Implements #567 (attached particle spawners).
Here is the code for a test mod implementing rain: http://lpaste.net/174254
The particles in the demo are shown to all players, so you can also use it to test if the spawners get deleted when an object is removed, by entering with multiple clients and logging out of one.