You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw/components/esm3/loadmgef.hpp

287 lines
9.9 KiB
C++

#ifndef OPENMW_ESM_MGEF_H
#define OPENMW_ESM_MGEF_H
#include <array>
#include <map>
#include <string>
#include <string_view>
#include "components/esm/defs.hpp"
#include "components/esm/refid.hpp"
#include "components/misc/strings/algorithm.hpp"
#include <osg/Vec4>
namespace ESM
{
class ESMReader;
class ESMWriter;
struct MagicEffect
{
constexpr static RecNameInts sRecordId = REC_MGEF;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string_view getRecordType() { return "MagicEffect"; }
uint32_t mRecordFlags;
RefId mId;
enum Flags
{
// Originally fixed flags (HardcodedFlags array consists of just these)
TargetSkill = 0x1, // Affects a specific skill, which is specified elsewhere in the effect structure.
TargetAttribute
= 0x2, // Affects a specific attribute, which is specified elsewhere in the effect structure.
NoDuration = 0x4, // Has no duration. Only runs effect once on cast.
NoMagnitude = 0x8, // Has no magnitude.
Harmful = 0x10, // Counts as a negative effect. Interpreted as useful for attack, and is treated as a bad
// effect in alchemy.
ContinuousVfx = 0x20, // The effect's hit particle VFX repeats for the full duration of the spell, rather
// than occuring once on hit.
CastSelf = 0x40, // Allows range - cast on self.
CastTouch = 0x80, // Allows range - cast on touch.
CastTarget = 0x100, // Allows range - cast on target.
AppliedOnce
= 0x1000, // An effect that is applied once it lands, instead of continuously. Allows an effect to reduce an
// attribute below zero; removes the normal minimum effect duration of 1 second.
Stealth = 0x2000, // Unused
NonRecastable = 0x4000, // Does not land if parent spell is already affecting target. Shows "you cannot
// re-cast" message for self target.
IllegalDaedra = 0x8000, // Unused
Unreflectable = 0x10000, // Cannot be reflected, the effect always lands normally.
CasterLinked = 0x20000, // Must quench if caster is dead, or not an NPC/creature. Not allowed in
// containter/door trap spells.
// Originally modifiable flags
AllowSpellmaking = 0x200, // Can be used for spellmaking
AllowEnchanting = 0x400, // Can be used for enchanting
NegativeLight = 0x800 // Inverts the effect's color
};
enum MagnitudeDisplayType
{
MDT_None,
MDT_Feet,
MDT_Level,
MDT_Percentage,
MDT_Points,
MDT_TimesInt
};
struct MEDTstruct
{
RefId mSchool; // Skill id
float mBaseCost;
int32_t mFlags;
// Glow color for enchanted items with this effect
int32_t mRed, mGreen, mBlue;
float mUnknown1; // Called "Size X" in CS
float mSpeed; // Speed of fired projectile
float mUnknown2; // Called "Size Cap" in CS
}; // 36 bytes
/// Returns the effect that provides resistance against \a effect (or -1 if there's none)
static short getResistanceEffect(short effect);
/// Returns the effect that induces weakness against \a effect (or -1 if there's none)
static short getWeaknessEffect(short effect);
MagnitudeDisplayType getMagnitudeDisplayType() const;
MEDTstruct mData;
std::string mIcon, mParticle; // Textures
ESM::RefId mCasting, mHit, mArea; // Static
ESM::RefId mBolt; // Weapon
ESM::RefId mCastSound, mBoltSound, mHitSound, mAreaSound; // Sounds
std::string mDescription;
// Index of this magical effect. Corresponds to one of the
// hard-coded effects in the original engine:
// 0-136 in Morrowind
// 137 in Tribunal
// 138-140 in Bloodmoon (also changes 64?)
// 141-142 are summon effects introduced in bloodmoon, but not used
// there. They can be redefined in mods by setting the name in GMST
// sEffectSummonCreature04/05 creature id in
// sMagicCreature04ID/05ID.
int32_t mIndex;
void load(ESMReader& esm, bool& isDeleted);
void save(ESMWriter& esm, bool isDeleted = false) const;
/// Set record to default state (does not touch the ID/index).
void blank();
osg::Vec4f getColor() const;
enum Effects
{
WaterBreathing = 0,
SwiftSwim = 1,
WaterWalking = 2,
Shield = 3,
FireShield = 4,
LightningShield = 5,
FrostShield = 6,
Burden = 7,
Feather = 8,
Jump = 9,
Levitate = 10,
SlowFall = 11,
Lock = 12,
Open = 13,
FireDamage = 14,
ShockDamage = 15,
FrostDamage = 16,
DrainAttribute = 17,
DrainHealth = 18,
DrainMagicka = 19,
DrainFatigue = 20,
DrainSkill = 21,
DamageAttribute = 22,
DamageHealth = 23,
DamageMagicka = 24,
DamageFatigue = 25,
DamageSkill = 26,
Poison = 27,
WeaknessToFire = 28,
WeaknessToFrost = 29,
WeaknessToShock = 30,
WeaknessToMagicka = 31,
WeaknessToCommonDisease = 32,
WeaknessToBlightDisease = 33,
WeaknessToCorprusDisease = 34,
WeaknessToPoison = 35,
WeaknessToNormalWeapons = 36,
DisintegrateWeapon = 37,
DisintegrateArmor = 38,
Invisibility = 39,
Chameleon = 40,
Light = 41,
Sanctuary = 42,
NightEye = 43,
Charm = 44,
Paralyze = 45,
Silence = 46,
Blind = 47,
Sound = 48,
CalmHumanoid = 49,
CalmCreature = 50,
FrenzyHumanoid = 51,
FrenzyCreature = 52,
DemoralizeHumanoid = 53,
DemoralizeCreature = 54,
RallyHumanoid = 55,
RallyCreature = 56,
Dispel = 57,
Soultrap = 58,
Telekinesis = 59,
Mark = 60,
Recall = 61,
DivineIntervention = 62,
AlmsiviIntervention = 63,
DetectAnimal = 64,
DetectEnchantment = 65,
DetectKey = 66,
SpellAbsorption = 67,
Reflect = 68,
CureCommonDisease = 69,
CureBlightDisease = 70,
CureCorprusDisease = 71,
CurePoison = 72,
CureParalyzation = 73,
RestoreAttribute = 74,
RestoreHealth = 75,
RestoreMagicka = 76,
RestoreFatigue = 77,
RestoreSkill = 78,
FortifyAttribute = 79,
FortifyHealth = 80,
FortifyMagicka = 81,
FortifyFatigue = 82,
FortifySkill = 83,
FortifyMaximumMagicka = 84,
AbsorbAttribute = 85,
AbsorbHealth = 86,
AbsorbMagicka = 87,
AbsorbFatigue = 88,
AbsorbSkill = 89,
ResistFire = 90,
ResistFrost = 91,
ResistShock = 92,
ResistMagicka = 93,
ResistCommonDisease = 94,
ResistBlightDisease = 95,
ResistCorprusDisease = 96,
ResistPoison = 97,
ResistNormalWeapons = 98,
ResistParalysis = 99,
RemoveCurse = 100,
TurnUndead = 101,
SummonScamp = 102,
SummonClannfear = 103,
SummonDaedroth = 104,
SummonDremora = 105,
SummonAncestralGhost = 106,
SummonSkeletalMinion = 107,
SummonBonewalker = 108,
SummonGreaterBonewalker = 109,
SummonBonelord = 110,
SummonWingedTwilight = 111,
SummonHunger = 112,
SummonGoldenSaint = 113,
SummonFlameAtronach = 114,
SummonFrostAtronach = 115,
SummonStormAtronach = 116,
FortifyAttack = 117,
CommandCreature = 118,
CommandHumanoid = 119,
BoundDagger = 120,
BoundLongsword = 121,
BoundMace = 122,
BoundBattleAxe = 123,
BoundSpear = 124,
BoundLongbow = 125,
ExtraSpell = 126,
BoundCuirass = 127,
BoundHelm = 128,
BoundBoots = 129,
BoundShield = 130,
BoundGloves = 131,
Corprus = 132,
Vampirism = 133,
SummonCenturionSphere = 134,
SunDamage = 135,
StuntedMagicka = 136,
// Tribunal only
SummonFabricant = 137,
// Bloodmoon only
SummonWolf = 138,
SummonBear = 139,
SummonBonewolf = 140,
SummonCreature04 = 141,
SummonCreature05 = 142,
Length
};
static const std::array<std::string, Length> sGmstEffectIds;
static const std::array<std::string_view, Length> sIndexNames;
static const std::map<std::string_view, int, Misc::StringUtils::CiComp> sGmstEffectIdToIndexMap;
static const std::map<std::string_view, int, Misc::StringUtils::CiComp> sIndexNameToIndexMap;
static const std::string& indexToGmstString(int effectID);
static std::string_view indexToName(int effectID);
static int indexNameToIndex(std::string_view effect);
static int effectGmstIdToIndex(std::string_view gmstId);
static RefId indexToRefId(int index);
};
}
#endif