diff options
Diffstat (limited to 'src/being/actorsprite.cpp')
-rw-r--r-- | src/being/actorsprite.cpp | 602 |
1 files changed, 0 insertions, 602 deletions
diff --git a/src/being/actorsprite.cpp b/src/being/actorsprite.cpp deleted file mode 100644 index 6594c7e3c..000000000 --- a/src/being/actorsprite.cpp +++ /dev/null @@ -1,602 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2010 The Mana Developers - * Copyright (C) 2011-2017 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "being/actorsprite.h" - -#include "configuration.h" -#include "settings.h" -#include "statuseffect.h" - -#include "being/localplayer.h" - -#include "const/utils/timer.h" - -#include "gui/theme.h" - -#include "listeners/debugmessagelistener.h" - -#include "particle/particle.h" - -#include "resources/db/statuseffectdb.h" - -#include "resources/loaders/imageloader.h" - -#include "resources/sprite/animatedsprite.h" -#include "resources/sprite/imagesprite.h" -#include "resources/sprite/spritereference.h" - -#include "utils/checkutils.h" -#include "utils/delete2.h" -#include "utils/foreach.h" -#include "utils/timer.h" - -#include "debug.h" - -#define for_each_cursors() \ - for (int size = CAST_S32(TargetCursorSize::SMALL); \ - size < CAST_S32(TargetCursorSize::NUM_TC); \ - size ++) \ - { \ - for (int type = CAST_S32(TargetCursorType::NORMAL); \ - type < CAST_S32(TargetCursorType::NUM_TCT); \ - type ++) \ - -#define end_foreach } - -static const unsigned int STATUS_EFFECTS = 32; - -AnimatedSprite *ActorSprite::targetCursor - [CAST_SIZE(TargetCursorType::NUM_TCT)] - [CAST_SIZE(TargetCursorSize::NUM_TC)]; -bool ActorSprite::loaded = false; - -ActorSprite::ActorSprite(const BeingId id) : - CompoundSprite(), - Actor(), - mStatusEffects(), - mStatusParticleEffects(), - mChildParticleEffects(&mStatusParticleEffects, false), - mHorseId(0), - mId(id), - mUsedTargetCursor(nullptr), - mActorSpriteListeners(), - mCursorPaddingX(0), - mCursorPaddingY(0), - mMustResetParticles(false), - mPoison(false), - mHaveCart(false), - mTrickDead(false) -{ -} - -ActorSprite::~ActorSprite() -{ - mChildParticleEffects.clear(); - mMustResetParticles = true; - - mUsedTargetCursor = nullptr; - - if (localPlayer != nullptr && - localPlayer != this && - localPlayer->getTarget() == this) - { - localPlayer->setTarget(nullptr); - } - - // Notify listeners of the destruction. - FOR_EACH (ActorSpriteListenerIterator, iter, mActorSpriteListeners) - { - if (reportFalse(*iter)) - (*iter)->actorSpriteDestroyed(*this); - } -} - -void ActorSprite::logic() -{ - BLOCK_START("ActorSprite::logic") - // Update sprite animations - update(tick_time * MILLISECONDS_IN_A_TICK); - - // Restart status/particle effects, if needed - if (mMustResetParticles) - { - mMustResetParticles = false; - FOR_EACH (std::set<int32_t>::const_iterator, it, mStatusEffects) - { - const StatusEffect *const effect - = StatusEffectDB::getStatusEffect(*it, Enable_true); - if (effect != nullptr && - effect->mIsPersistent) - { - updateStatusEffect(*it, - Enable_true, - IsStart_false); - } - } - } - - // Update particle effects - mChildParticleEffects.moveTo(mPos.x, mPos.y); - BLOCK_END("ActorSprite::logic") -} - -void ActorSprite::setMap(Map *const map) -{ - Actor::setMap(map); - - // Clear particle effect list because child particles became invalid - mChildParticleEffects.clear(); - mMustResetParticles = true; // Reset status particles on next redraw -} - -void ActorSprite::controlAutoParticle(Particle *const particle) -{ - if (particle != nullptr) - { - particle->setActor(mId); - mChildParticleEffects.addLocally(particle); - } -} - -void ActorSprite::controlCustomParticle(Particle *const particle) -{ - if (particle != nullptr) - { - // The effect may not die without the beings permission or we segfault - particle->disableAutoDelete(); - mChildParticleEffects.addLocally(particle); - } -} - -void ActorSprite::controlParticleDeleted(const Particle *const particle) -{ - if (particle != nullptr) - mChildParticleEffects.removeLocally(particle); -} - -void ActorSprite::setTargetType(const TargetCursorTypeT type) -{ - if (type == TargetCursorType::NONE) - { - untarget(); - } - else - { - const size_t sz = CAST_SIZE(getTargetCursorSize()); - mUsedTargetCursor = targetCursor[CAST_S32(type)][sz]; - if (mUsedTargetCursor != nullptr) - { - static const int targetWidths[CAST_SIZE( - TargetCursorSize::NUM_TC)] - = {0, 0, 0}; - static const int targetHeights[CAST_SIZE( - TargetCursorSize::NUM_TC)] - = {-mapTileSize / 2, -mapTileSize / 2, -mapTileSize}; - - mCursorPaddingX = CAST_S32(targetWidths[sz]); - mCursorPaddingY = CAST_S32(targetHeights[sz]); - } - } -} - -void ActorSprite::setStatusEffect(const int32_t index, - const Enable active, - const IsStart start) -{ - const Enable wasActive = fromBool( - mStatusEffects.find(index) != mStatusEffects.end(), Enable); - - if (active != wasActive) - { - updateStatusEffect(index, active, start); - if (active == Enable_true) - { - mStatusEffects.insert(index); - } - else - { - mStatusEffects.erase(index); - } - } -} - -// function for legacy configs only. Must be removed in future -void ActorSprite::setStatusEffectBlock(const int offset, - const uint16_t newEffects) -{ - for (unsigned i = 0; i < STATUS_EFFECTS; i++) - { - const bool val = (newEffects & (1 << i)) > 0; - const int32_t index = StatusEffectDB::blockIdToId( - offset + i); // block-id (offset + i) to id (index) - - if (index != -1) - { - setStatusEffect(index, - fromBool(val, Enable), - IsStart_true); - } - else if (val && config.getBoolValue("unimplimentedLog")) - { - const std::string str = strprintf( - "Error: unknown effect by block-index. " - "Offset: %d, effect int: %d, i: %u", - offset, CAST_S32(newEffects), i); - logger->log(str); - DebugMessageListener::distributeEvent(str); - } - } -} - -static void applyEffectByOption(ActorSprite *const actor, - uint32_t option, - const char *const name, - const OptionsMap& options) -{ - FOR_EACH (OptionsMapCIter, it, options) - { - const uint32_t opt = (*it).first; - const int32_t id = (*it).second; - const Enable enable = (opt & option) != 0 ? Enable_true : Enable_false; - option |= opt; - option ^= opt; - actor->setStatusEffect(id, - enable, - IsStart_false); - } - if (option != 0U && - config.getBoolValue("unimplimentedLog")) - { - const std::string str = strprintf( - "Error: unknown effect by %s. " - "Left value: %u", - name, - option); - logger->log(str); - DebugMessageListener::distributeEvent(str); - } -} - -static void applyEffectByOption1(ActorSprite *const actor, - uint32_t option, - const char *const name, - const OptionsMap& options) -{ - FOR_EACH (OptionsMapCIter, it, options) - { - const uint32_t opt = (*it).first; - const int32_t id = (*it).second; - if (opt == option) - { - actor->setStatusEffect(id, - Enable_true, - IsStart_false); - option = 0U; - } - else - { - actor->setStatusEffect(id, - Enable_false, - IsStart_false); - } - } - if (option != 0 && - config.getBoolValue("unimplimentedLog")) - { - const std::string str = strprintf( - "Error: unknown effect by %s. " - "Left value: %u", - name, - option); - logger->log(str); - DebugMessageListener::distributeEvent(str); - } -} - -void ActorSprite::setStatusEffectOpitons(const uint32_t option, - const uint32_t opt1, - const uint32_t opt2, - const uint32_t opt3) -{ - if (settings.legacyEffects == false) - { - applyEffectByOption(this, option, "option", - StatusEffectDB::getOptionMap()); - applyEffectByOption1(this, opt1, "opt1", - StatusEffectDB::getOpt1Map()); - applyEffectByOption(this, opt2, "opt2", - StatusEffectDB::getOpt2Map()); - applyEffectByOption(this, opt3, "opt3", - StatusEffectDB::getOpt3Map()); - } - else - { - uint32_t statusEffects = opt2; - statusEffects |= option << 16; - setStatusEffectBlock(0, - CAST_U16((statusEffects >> 16) & 0xffffU)); - setStatusEffectBlock(16, - CAST_U16(statusEffects & 0xffffU)); - setStatusEffectBlock(32, - CAST_U16(opt3)); - } -} - -void ActorSprite::setStatusEffectOpitons(const uint32_t option, - const uint32_t opt1, - const uint32_t opt2) -{ - if (settings.legacyEffects == false) - { - applyEffectByOption(this, option, "option", - StatusEffectDB::getOptionMap()); - applyEffectByOption1(this, opt1, "opt1", - StatusEffectDB::getOpt1Map()); - applyEffectByOption(this, opt2, "opt2", - StatusEffectDB::getOpt2Map()); - } - else - { - uint32_t statusEffects = opt2; - statusEffects |= option << 16; - setStatusEffectBlock(0, - CAST_U16((statusEffects >> 16) & 0xffffU)); - setStatusEffectBlock(16, - CAST_U16(statusEffects & 0xffffU)); - } -} - -void ActorSprite::setStatusEffectOpiton0(const uint32_t option) -{ - if (settings.legacyEffects == false) - { - applyEffectByOption(this, option, "option", - StatusEffectDB::getOptionMap()); - } - else - { - const uint32_t statusEffects = option << 16; - setStatusEffectBlock(0, - CAST_U16((statusEffects >> 16) & 0xffff)); - } -} - -void ActorSprite::updateStatusEffect(const int32_t index, - const Enable newStatus, - const IsStart start) -{ - StatusEffect *const effect = StatusEffectDB::getStatusEffect( - index, newStatus); - if (effect == nullptr) - return; - if (effect->mIsPoison && getType() == ActorType::Player) - setPoison(newStatus == Enable_true); - else if (effect->mIsCart && localPlayer == this) - setHaveCart(newStatus == Enable_true); - else if (effect->mIsRiding) - setRiding(newStatus == Enable_true); - else if (effect->mIsTrickDead) - setTrickDead(newStatus == Enable_true); - else if (effect->mIsPostDelay) - stopCast(newStatus == Enable_true); - handleStatusEffect(effect, index, newStatus, start); -} - -void ActorSprite::handleStatusEffect(const StatusEffect *const effect, - const int32_t effectId, - const Enable newStatus, - const IsStart start) -{ - if (effect == nullptr) - return; - - if (newStatus == Enable_true) - { - if (effectId >= 0) - { - Particle *particle = nullptr; - if (start == IsStart_true) - particle = effect->getStartParticle(); - if (particle == nullptr) - particle = effect->getParticle(); - if (particle != nullptr) - mStatusParticleEffects.setLocally(effectId, particle); - } - } - else - { - mStatusParticleEffects.delLocally(effectId); - } -} - -void ActorSprite::setupSpriteDisplay(const SpriteDisplay &display, - const ForceDisplay forceDisplay, - const DisplayTypeT displayType, - const std::string &color) -{ - clear(); - - FOR_EACH (SpriteRefs, it, display.sprites) - { - if (*it == nullptr) - continue; - const std::string file = pathJoin(paths.getStringValue("sprites"), - combineDye3((*it)->sprite, color)); - - const int variant = (*it)->variant; - addSprite(AnimatedSprite::delayedLoad(file, variant)); - } - - // Ensure that something is shown, if desired - if (mSprites.empty() && forceDisplay == ForceDisplay_true) - { - if (display.image.empty()) - { - addSprite(AnimatedSprite::delayedLoad(pathJoin( - paths.getStringValue("sprites"), - paths.getStringValue("spriteErrorFile")))); - } - else - { - std::string imagePath; - switch (displayType) - { - case DisplayType::Item: - default: - imagePath = pathJoin(paths.getStringValue("itemIcons"), - display.image); - break; - case DisplayType::Floor: - imagePath = pathJoin(paths.getStringValue("itemIcons"), - display.floor); - break; - } - imagePath = combineDye2(imagePath, color); - Image *img = Loader::getImage(imagePath); - - if (img == nullptr) - img = Theme::getImageFromTheme("unknown-item.png"); - - addSprite(new ImageSprite(img)); - if (img != nullptr) - img->decRef(); - } - } - - mChildParticleEffects.clear(); - - // setup particle effects - if (ParticleEngine::enabled && (particleEngine != nullptr)) - { - FOR_EACH (StringVectCIter, itr, display.particles) - { - Particle *const p = particleEngine->addEffect(*itr, 0, 0); - controlAutoParticle(p); - } - } - - mMustResetParticles = true; -} - -void ActorSprite::load() -{ - if (loaded) - unload(); - - initTargetCursor(); - - loaded = true; -} - -void ActorSprite::unload() -{ - if (reportTrue(!loaded)) - return; - - cleanupTargetCursors(); - loaded = false; -} - -void ActorSprite::addActorSpriteListener(ActorSpriteListener *const listener) -{ - mActorSpriteListeners.push_front(listener); -} - -void ActorSprite::removeActorSpriteListener(ActorSpriteListener *const - listener) -{ - mActorSpriteListeners.remove(listener); -} - -static const char *cursorType(const TargetCursorTypeT type) -{ - switch (type) - { - case TargetCursorType::IN_RANGE: - return "in-range"; - default: - case TargetCursorType::NONE: - case TargetCursorType::NUM_TCT: - case TargetCursorType::NORMAL: - return "normal"; - } -} - -static const char *cursorSize(const TargetCursorSizeT size) -{ - switch (size) - { - case TargetCursorSize::LARGE: - return "l"; - case TargetCursorSize::MEDIUM: - return "m"; - default: - case TargetCursorSize::NUM_TC: - case TargetCursorSize::SMALL: - return "s"; - } -} - -void ActorSprite::initTargetCursor() -{ - static const std::string targetCursorFile("target-cursor-%s-%s.xml"); - - // Load target cursors - for_each_cursors() - { - targetCursor[type][size] = AnimatedSprite::load( - Theme::resolveThemePath(strprintf( - targetCursorFile.c_str(), - cursorType(static_cast<TargetCursorTypeT>(type)), - cursorSize(static_cast<TargetCursorSizeT>(size))))); - } - end_foreach -} - -void ActorSprite::cleanupTargetCursors() -{ - for_each_cursors() - { - delete2(targetCursor[type][size]) - } - end_foreach -} - -std::string ActorSprite::getStatusEffectsString() const -{ - std::string effectsStr; - if (!mStatusEffects.empty()) - { - FOR_EACH (std::set<int32_t>::const_iterator, it, mStatusEffects) - { - const StatusEffect *const effect = - StatusEffectDB::getStatusEffect( - *it, - Enable_true); - if (effect == nullptr) - continue; - if (!effectsStr.empty()) - effectsStr.append(", "); - effectsStr.append(effect->mName); - } - } - return effectsStr; -} |