diff options
author | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2024-09-28 22:50:00 +0200 |
---|---|---|
committer | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2024-09-30 13:40:45 +0200 |
commit | f7bccd4c7abe33c0f435a4c584d196d611f89674 (patch) | |
tree | 1d8646c213922eb0be09f3de48b10d19b5591cd0 /src/being.cpp | |
parent | 61f21c0131bbb6631a16205ce5447e8eea2a2db2 (diff) | |
download | mana-f7bccd4c7abe33c0f435a4c584d196d611f89674.tar.gz mana-f7bccd4c7abe33c0f435a4c584d196d611f89674.tar.bz2 mana-f7bccd4c7abe33c0f435a4c584d196d611f89674.tar.xz mana-f7bccd4c7abe33c0f435a4c584d196d611f89674.zip |
Added support for particle effects on equipment
The effect is also there when the equipment is dropped, because it uses
the same field as the floor item.
Removed unused ItemInfo::particle.
Based roughly on M+ commit 44e5d8bcb7fea443ca9ed3844454b11ac6e4dbed.
Closes #85
Diffstat (limited to 'src/being.cpp')
-rw-r--r-- | src/being.cpp | 97 |
1 files changed, 78 insertions, 19 deletions
diff --git a/src/being.cpp b/src/being.cpp index 0e344873..c9eee2c6 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -91,6 +91,8 @@ Being::~Being() mSpeechBubble = nullptr; mDispName = nullptr; mText = nullptr; + + removeAllSpriteParticles(); } void Being::setSubtype(Uint16 subtype) @@ -765,6 +767,12 @@ void Being::logic() mText = nullptr; } + if (mRestoreSpriteParticlesOnLogic) + { + mRestoreSpriteParticlesOnLogic = false; + restoreAllSpriteParticles(); + } + if ((mAction != DEAD) && !mSpeedPixelsPerTick.isNull()) { const Vector dest = (mPath.empty()) ? @@ -979,6 +987,45 @@ void Being::showName() updateCoords(); } +void Being::addSpriteParticles(SpriteState &spriteState, const SpriteDisplay &display) +{ + if (!spriteState.particles.empty()) + return; + + for (const auto &particle : display.particles) + { + Particle *p = particleEngine->addEffect(particle, 0, 0, 0); + controlParticle(p); + spriteState.particles.push_back(p); + } +} + +void Being::removeSpriteParticles(SpriteState &spriteState) +{ + for (auto particle : spriteState.particles) + mChildParticleEffects.removeLocally(particle); + + spriteState.particles.clear(); +} + +void Being::removeAllSpriteParticles() +{ + for (auto &spriteState : mSpriteStates) + removeSpriteParticles(spriteState); +} + +void Being::restoreAllSpriteParticles() +{ + for (auto &spriteState : mSpriteStates) + { + if (spriteState.id) + { + auto &itemInfo = itemDb->get(spriteState.id); + addSpriteParticles(spriteState, itemInfo.display); + } + } +} + void Being::updateColors() { if (getType() == MONSTER) @@ -1021,20 +1068,25 @@ void Being::updateColors() } } -void Being::setSprite(unsigned int slot, int id, const std::string &color, +void Being::setSprite(unsigned slot, int id, const std::string &color, bool isWeapon) { if (slot >= size()) ensureSize(slot + 1); - if (slot >= mSpriteIDs.size()) - mSpriteIDs.resize(slot + 1); + if (slot >= mSpriteStates.size()) + mSpriteStates.resize(slot + 1); + + auto &spriteState = mSpriteStates[slot]; + + // Clear current particles when the ID changes + if (spriteState.id != id) + removeSpriteParticles(spriteState); - if (slot >= mSpriteColors.size()) - mSpriteColors.resize(slot + 1); + spriteState.id = id; + spriteState.color = color; - // id = 0 means unequip - if (id == 0) + if (id == 0) // id = 0 means unequip { removeSprite(slot); @@ -1043,7 +1095,8 @@ void Being::setSprite(unsigned int slot, int id, const std::string &color, } else { - std::string filename = itemDb->get(id).getSprite(mGender, mSubType); + auto &itemInfo = itemDb->get(id); + std::string filename = itemInfo.getSprite(mGender, mSubType); AnimatedSprite *equipmentSprite = nullptr; if (!filename.empty()) @@ -1060,24 +1113,25 @@ void Being::setSprite(unsigned int slot, int id, const std::string &color, CompoundSprite::setSprite(slot, equipmentSprite); + addSpriteParticles(spriteState, itemInfo.display); + if (isWeapon) - mEquippedWeapon = &itemDb->get(id); + mEquippedWeapon = &itemInfo; setAction(mAction); } - - mSpriteIDs[slot] = id; - mSpriteColors[slot] = color; } -void Being::setSpriteID(unsigned int slot, int id) +void Being::setSpriteID(unsigned slot, int id) { - setSprite(slot, id, mSpriteColors[slot]); + assert(slot < mSpriteStates.size()); + setSprite(slot, id, mSpriteStates[slot].color); } -void Being::setSpriteColor(unsigned int slot, const std::string &color) +void Being::setSpriteColor(unsigned slot, const std::string &color) { - setSprite(slot, mSpriteIDs[slot], color); + assert(slot < mSpriteStates.size()); + setSprite(slot, mSpriteStates[slot].id, color); } int Being::getNumberOfLayers() const @@ -1098,10 +1152,11 @@ void Being::setGender(Gender gender) mGender = gender; // Reload all subsprites - for (unsigned int i = 0; i < mSpriteIDs.size(); i++) + for (size_t i = 0; i < mSpriteStates.size(); i++) { - if (mSpriteIDs.at(i) != 0) - setSprite(i, mSpriteIDs.at(i), mSpriteColors.at(i)); + auto &sprite = mSpriteStates[i]; + if (sprite.id != 0) + setSprite(i, sprite.id, sprite.color); } updateName(); @@ -1155,6 +1210,10 @@ void Being::event(Event::Channel channel, const Event &event) void Being::setMap(Map *map) { + // Remove sprite particles because ActorSprite is going to kill them all + removeAllSpriteParticles(); + mRestoreSpriteParticlesOnLogic = true; + ActorSprite::setMap(map); // Recalculate pixel/tick speed |