#ifndef GAME_MWMECHANICS_MAGICEFFECTS_H #define GAME_MWMECHANICS_MAGICEFFECTS_H #include #include #include #include namespace ESM { struct Attribute; struct ENAMstruct; struct EffectList; struct MagicEffect; struct MagicEffects; struct Skill; } namespace MWMechanics { struct EffectKey { int mId; ESM::RefId mArg; // skill or ability EffectKey(); EffectKey(int id, ESM::RefId arg = {}) : mId(id) , mArg(arg) { } EffectKey(const ESM::ENAMstruct& effect); std::string toString() const; }; bool operator<(const EffectKey& left, const EffectKey& right); bool operator==(const EffectKey& left, const EffectKey& right); struct EffectParam { private: // Note usually this would be int, but applying partial resistance might introduce a decimal point. float mModifier; int mBase; public: /// Get the total magnitude including base and modifier. float getMagnitude() const; void setModifier(float mod); float getModifier() const; /// Change mBase by \a diff void modifyBase(int diff); void setBase(int base); int getBase() const; EffectParam(); EffectParam(float magnitude) : mModifier(magnitude) , mBase(0) { } EffectParam& operator+=(const EffectParam& param); EffectParam& operator-=(const EffectParam& param); }; inline EffectParam operator+(const EffectParam& left, const EffectParam& right) { EffectParam param(left); return param += right; } inline EffectParam operator-(const EffectParam& left, const EffectParam& right) { EffectParam param(left); return param -= right; } /// \brief Effects currently affecting a NPC or creature class MagicEffects { public: typedef std::map Collection; private: Collection mCollection; public: Collection::const_iterator begin() const { return mCollection.begin(); } Collection::const_iterator end() const { return mCollection.end(); } void readState(const ESM::MagicEffects& state); void writeState(ESM::MagicEffects& state) const; void add(const EffectKey& key, const EffectParam& param); void remove(const EffectKey& key); void modifyBase(const EffectKey& key, int diff); /// Copy Modifier values from \a effects, but keep original mBase values. void setModifiers(const MagicEffects& effects); EffectParam getOrDefault(const EffectKey& key) const; std::optional get(const EffectKey& key) const; ///< This function can safely be used for keys that are not present. static MagicEffects diff(const MagicEffects& prev, const MagicEffects& now); ///< Return changes from \a prev to \a now. }; std::string getMagicEffectString( const ESM::MagicEffect& effect, const ESM::Attribute* attribute, const ESM::Skill* skill); } #endif