diff --git a/src/client/game.cpp b/src/client/game.cpp index f133c634c6..0cb89cf0b3 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -3740,8 +3740,7 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos, } else { runData.dig_time_complete = params.time; - client->getParticleManager()->addNodeParticle(client, - player, nodepos, n, features); + client->getParticleManager()->addNodeParticle(player, nodepos, n); } if (!runData.digging) { @@ -3826,8 +3825,7 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos, client->interact(INTERACT_DIGGING_COMPLETED, pointed); - client->getParticleManager()->addDiggingParticles(client, - player, nodepos, n, features); + client->getParticleManager()->addDiggingParticles(player, nodepos, n); // Send event to trigger sound client->getEventManager()->put(new NodeDugEvent(nodepos, n)); diff --git a/src/client/particles.cpp b/src/client/particles.cpp index 7b86e8a680..9f734631f9 100644 --- a/src/client/particles.cpp +++ b/src/client/particles.cpp @@ -37,6 +37,18 @@ ClientParticleTexture::ClientParticleTexture(const ServerParticleTexture& p, ITe ref = tsrc->getTexture("no_texture.png"); } +static video::ITexture *extractTexture(const TileDef &def, const TileLayer &layer, + ITextureSource *tsrc) +{ + // If animated take first frame from tile layer (so we don't have to handle + // that manually), otherwise look up by name. + if (!layer.empty() && (layer.material_flags & MATERIAL_FLAG_ANIMATION)) + return (*layer.frames)[0].texture; + if (!def.name.empty()) + return tsrc->getTexture(def.name); + return nullptr; +} + /* Particle */ @@ -451,10 +463,8 @@ void ParticleSpawner::spawnParticle(ClientEnvironment *env, float radius, video::SColor color(0xFFFFFFFF); if (p.node.getContent() != CONTENT_IGNORE) { - const ContentFeatures &f = - m_particlemanager->m_env->getGameDef()->ndef()->get(p.node); - if (!ParticleManager::getNodeParticleParams(p.node, f, pp, &texture.ref, - texpos, texsize, &color, p.node_tile)) + if (!ParticleManager::getNodeParticleParams(env->getGameDef(), p.node, + pp, &texture.ref, texpos, texsize, &color, p.node_tile)) return; } else { if (m_texpool.size() == 0) @@ -830,9 +840,8 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, Client *client, f32 oldsize = p.size; if (p.node.getContent() != CONTENT_IGNORE) { - const ContentFeatures &f = m_env->getGameDef()->ndef()->get(p.node); - getNodeParticleParams(p.node, f, p, &texture.ref, texpos, - texsize, &color, p.node_tile); + getNodeParticleParams(m_env->getGameDef(), p.node, p, + &texture.ref, texpos, texsize, &color, p.node_tile); } else { /* with no particlespawner to own the texture, we need * to save it on the heap. it will be freed when the @@ -861,28 +870,29 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, Client *client, } } -bool ParticleManager::getNodeParticleParams(const MapNode &n, - const ContentFeatures &f, ParticleParameters &p, video::ITexture **texture, +bool ParticleManager::getNodeParticleParams(Client *client, const MapNode &n, + ParticleParameters &p, video::ITexture **texture, v2f &texpos, v2f &texsize, video::SColor *color, u8 tilenum) { + const ContentFeatures &f = client->ndef()->get(n); + // No particles for "airlike" nodes if (f.drawtype == NDT_AIRLIKE) return false; // Texture + // Note: we ignore the overlay here, oh well u8 texid; if (tilenum > 0 && tilenum <= 6) texid = tilenum - 1; else texid = myrand_range(0,5); - const TileLayer &tile = f.tiles[texid].layers[0]; - p.animation.type = TAT_NONE; - // Only use first frame of animated texture - if (tile.material_flags & MATERIAL_FLAG_ANIMATION) - *texture = (*tile.frames)[0].texture; - else - *texture = tile.texture; + const TileLayer &tile = f.tiles[texid].layers[0]; + *texture = extractTexture(f.tiledef[texid], tile, client->tsrc()); + p.texture.blendmode = f.alpha == ALPHAMODE_BLEND + ? BlendMode::alpha : BlendMode::clip; + p.animation.type = TAT_NONE; float size = (myrand_range(0,8)) / 64.0f; p.size = BS * size; @@ -903,35 +913,26 @@ bool ParticleManager::getNodeParticleParams(const MapNode &n, // The final burst of particles when a node is finally dug, *not* particles // spawned during the digging of a node. -void ParticleManager::addDiggingParticles(IGameDef *gamedef, - LocalPlayer *player, v3s16 pos, const MapNode &n, const ContentFeatures &f) +void ParticleManager::addDiggingParticles(LocalPlayer *player, v3s16 pos, const MapNode &n) { - // No particles for "airlike" nodes - if (f.drawtype == NDT_AIRLIKE) - return; - for (u16 j = 0; j < 16; j++) { - addNodeParticle(gamedef, player, pos, n, f); + addNodeParticle(player, pos, n); } } // During the digging of a node particles are spawned individually by this // function, called from Game::handleDigging() in game.cpp. -void ParticleManager::addNodeParticle(IGameDef *gamedef, - LocalPlayer *player, v3s16 pos, const MapNode &n, const ContentFeatures &f) +void ParticleManager::addNodeParticle(LocalPlayer *player, v3s16 pos, const MapNode &n) { ParticleParameters p; video::ITexture *ref = nullptr; v2f texpos, texsize; video::SColor color; - if (!getNodeParticleParams(n, f, p, &ref, texpos, texsize, &color)) + if (!getNodeParticleParams(m_env->getGameDef(), n, p, &ref, texpos, texsize, &color)) return; - p.texture.blendmode = f.alpha == ALPHAMODE_BLEND - ? BlendMode::alpha : BlendMode::clip; - p.expirationtime = myrand_range(0, 100) / 100.0f; // Physics diff --git a/src/client/particles.h b/src/client/particles.h index 43acac8ee5..f0b3b6a12a 100644 --- a/src/client/particles.h +++ b/src/client/particles.h @@ -219,11 +219,11 @@ public: void handleParticleEvent(ClientEvent *event, Client *client, LocalPlayer *player); - void addDiggingParticles(IGameDef *gamedef, LocalPlayer *player, v3s16 pos, - const MapNode &n, const ContentFeatures &f); + void addDiggingParticles(LocalPlayer *player, v3s16 pos, + const MapNode &n); - void addNodeParticle(IGameDef *gamedef, LocalPlayer *player, v3s16 pos, - const MapNode &n, const ContentFeatures &f); + void addNodeParticle(LocalPlayer *player, v3s16 pos, + const MapNode &n); void reserveParticleSpace(size_t max_estimate); @@ -240,7 +240,7 @@ public: } protected: - static bool getNodeParticleParams(const MapNode &n, const ContentFeatures &f, + static bool getNodeParticleParams(Client *client, const MapNode &n, ParticleParameters &p, video::ITexture **texture, v2f &texpos, v2f &texsize, video::SColor *color, u8 tilenum = 0);