1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-15 19:19:55 +00:00
openmw-tes3mp/apps/openmw/mwmechanics/spells.hpp
scrawl 783594033a Optimize MWMechanics::Spells
Use pointers as map keys instead of string IDs. Resolves a nasty performance bottleneck on functions like hasCommonDisease() that previously had to look up all contained spells from the ESM store on every call. hasCommonDisease() is called hundreds of times per frame by the AI target update since it's used to calculate target disposition.

The total cost of hasCommonDisease() was 2.7% of the frame loop, now it's negligible.
2015-11-27 01:07:15 +01:00

121 lines
3.7 KiB
C++

#ifndef GAME_MWMECHANICS_SPELLS_H
#define GAME_MWMECHANICS_SPELLS_H
#include <map>
#include <string>
#include <components/misc/stringops.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwworld/timestamp.hpp"
#include "magiceffects.hpp"
namespace ESM
{
struct Spell;
struct SpellState;
}
namespace MWMechanics
{
class MagicEffects;
/// \brief Spell list
///
/// This class manages known spells as well as abilities, powers and permanent negative effects like
/// diseases. It also keeps track of used powers (which can only be used every 24h).
class Spells
{
public:
typedef const ESM::Spell* SpellKey;
typedef std::map<SpellKey, std::map<const int, float> > TContainer; // ID, <effect index, normalised random magnitude>
typedef TContainer::const_iterator TIterator;
struct CorprusStats
{
static const int sWorseningPeriod = 24;
int mWorsenings;
MWWorld::TimeStamp mNextWorsening;
};
private:
TContainer mSpells;
// spell-tied effects that will be applied even after removing the spell (currently used to keep positive effects when corprus is removed)
std::map<SpellKey, MagicEffects> mPermanentSpellEffects;
// Note: this is the spell that's about to be cast, *not* the spell selected in the GUI (which may be different)
std::string mSelectedSpell;
std::map<SpellKey, MWWorld::TimeStamp> mUsedPowers;
std::map<SpellKey, CorprusStats> mCorprusSpells;
/// Get spell from ID, throws exception if not found
const ESM::Spell* getSpell(const std::string& id) const;
public:
void worsenCorprus(const ESM::Spell* spell);
static bool hasCorprusEffect(const ESM::Spell *spell);
const std::map<SpellKey, CorprusStats> & getCorprusSpells() const;
bool canUsePower (const ESM::Spell* spell) const;
void usePower (const ESM::Spell* spell);
void purgeCommonDisease();
void purgeBlightDisease();
void purgeCorprusDisease();
void purgeCurses();
TIterator begin() const;
TIterator end() const;
bool hasSpell(const std::string& spell) const;
bool hasSpell(const ESM::Spell* spell) const;
void add (const std::string& spell);
///< Adding a spell that is already listed in *this is a no-op.
void add (const ESM::Spell* spell);
///< Adding a spell that is already listed in *this is a no-op.
void remove (const std::string& spell);
///< If the spell to be removed is the selected spell, the selected spell will be changed to
/// no spell (empty string).
MagicEffects getMagicEffects() const;
///< Return sum of magic effects resulting from abilities, blights, deseases and curses.
void clear();
///< Remove all spells of al types.
void setSelectedSpell (const std::string& spellId);
///< This function does not verify, if the spell is available.
const std::string getSelectedSpell() const;
///< May return an empty string.
bool isSpellActive(const std::string& id) const;
///< Are we under the effects of the given spell ID?
bool hasCommonDisease() const;
bool hasBlightDisease() const;
void visitEffectSources (MWMechanics::EffectSourceVisitor& visitor) const;
void readState (const ESM::SpellState& state);
void writeState (ESM::SpellState& state) const;
};
}
#endif