mirror of
https://github.com/OpenMW/openmw.git
synced 2026-02-11 01:08:26 +00:00
Changed IRDTstruct (alchemical ingredient magic effects) to use RefIds instead of int for effectId.
Changed various structs (ENAMstruct, EffectKey, SummonKey) to use RefId instead of strict StringRefId to account for null effects.
This commit is contained in:
parent
c581ab3242
commit
3e586ed693
16 changed files with 97 additions and 50 deletions
|
|
@ -646,7 +646,7 @@ namespace MWMechanics
|
|||
purge([=](const ActiveSpellParams& params) { return params.mActiveSpellId == id; }, ptr);
|
||||
}
|
||||
|
||||
void ActiveSpells::purgeEffect(const MWWorld::Ptr& ptr, const ESM::MagicEffectId& effectId, ESM::RefId effectArg)
|
||||
void ActiveSpells::purgeEffect(const MWWorld::Ptr& ptr, const ESM::RefId& effectId, ESM::RefId effectArg)
|
||||
{
|
||||
purge(
|
||||
[=](const ActiveSpellParams&, const ESM::ActiveEffect& effect) {
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ namespace MWMechanics
|
|||
void removeEffectsByActiveSpellId(const MWWorld::Ptr& ptr, const ESM::RefId& id);
|
||||
|
||||
/// Remove all active effects with this effect id
|
||||
void purgeEffect(const MWWorld::Ptr& ptr, const ESM::MagicEffectId& effectId, ESM::RefId effectArg = {});
|
||||
void purgeEffect(const MWWorld::Ptr& ptr, const ESM::RefId& effectId, ESM::RefId effectArg = {});
|
||||
|
||||
void purge(EffectPredicate predicate, const MWWorld::Ptr& ptr);
|
||||
void purge(ParamsPredicate predicate, const MWWorld::Ptr& ptr);
|
||||
|
|
|
|||
|
|
@ -30,12 +30,12 @@ namespace
|
|||
|
||||
std::optional<MWMechanics::EffectKey> toKey(const ESM::Ingredient& ingredient, size_t i)
|
||||
{
|
||||
if (ingredient.mData.mEffectID[i] < 0)
|
||||
if (ingredient.mData.mEffectID[i].empty())
|
||||
return {};
|
||||
ESM::RefId arg = ESM::Skill::indexToRefId(ingredient.mData.mSkills[i]);
|
||||
if (arg.empty())
|
||||
arg = ESM::Attribute::indexToRefId(ingredient.mData.mAttributes[i]);
|
||||
return MWMechanics::EffectKey(ingredient.mData.mEffectID[i], arg);
|
||||
return MWMechanics::EffectKey(*ingredient.mData.mEffectID[i].getIf<ESM::MagicEffectId>(), arg);
|
||||
}
|
||||
|
||||
bool containsEffect(const ESM::Ingredient& ingredient, const MWMechanics::EffectKey& effect)
|
||||
|
|
@ -172,11 +172,11 @@ void MWMechanics::Alchemy::updateEffects()
|
|||
for (const auto& effectKey : effects)
|
||||
{
|
||||
const ESM::MagicEffect* magicEffect
|
||||
= MWBase::Environment::get().getESMStore()->get<ESM::MagicEffect>().find(effectKey.mId);
|
||||
= MWBase::Environment::get().getESMStore()->get<ESM::MagicEffect>().search(effectKey.mId);
|
||||
|
||||
if (magicEffect->mData.mBaseCost <= 0)
|
||||
{
|
||||
const std::string os = "invalid base cost for magic effect " + std::to_string(effectKey.mId);
|
||||
const std::string os = "invalid base cost for magic effect " + std::string(ESM::MagicEffect::refIdToName(effectKey.mId));
|
||||
throw std::runtime_error(os);
|
||||
}
|
||||
|
||||
|
|
@ -217,7 +217,7 @@ void MWMechanics::Alchemy::updateEffects()
|
|||
if (magnitude > 0 && duration > 0)
|
||||
{
|
||||
ESM::ENAMstruct effect;
|
||||
effect.mEffectID = static_cast<int16_t>(effectKey.mId);
|
||||
effect.mEffectID = effectKey.mId;
|
||||
|
||||
effect.mAttribute = -1;
|
||||
effect.mSkill = -1;
|
||||
|
|
@ -621,7 +621,7 @@ std::vector<std::string> MWMechanics::Alchemy::effectsDescription(
|
|||
if (alchemySkill < fWortChanceValue * static_cast<int>(i + 1))
|
||||
break;
|
||||
|
||||
if (effectID != -1)
|
||||
if (!effectID.empty())
|
||||
{
|
||||
const ESM::Attribute* attribute
|
||||
= store->get<ESM::Attribute>().search(ESM::Attribute::indexToRefId(data.mAttributes[i]));
|
||||
|
|
|
|||
|
|
@ -649,7 +649,7 @@ namespace MWMechanics
|
|||
return mTimeOfDeath;
|
||||
}
|
||||
|
||||
std::multimap<ESM::MagicEffectId, ESM::RefNum>& CreatureStats::getSummonedCreatureMap()
|
||||
std::multimap<ESM::RefId, ESM::RefNum>& CreatureStats::getSummonedCreatureMap()
|
||||
{
|
||||
return mSummonedCreatures;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ namespace MWMechanics
|
|||
MWWorld::TimeStamp mTimeOfDeath;
|
||||
|
||||
private:
|
||||
std::multimap<ESM::MagicEffectId, ESM::RefNum> mSummonedCreatures; // <Effect, Actor>
|
||||
std::multimap<ESM::RefId, ESM::RefNum> mSummonedCreatures; // <Effect, Actor>
|
||||
|
||||
float mAwarenessTimer = 0.f;
|
||||
int mAwarenessRoll = -1;
|
||||
|
|
@ -231,7 +231,7 @@ namespace MWMechanics
|
|||
void setBlock(bool value);
|
||||
bool getBlock() const;
|
||||
|
||||
std::multimap<ESM::MagicEffectId, ESM::RefNum>& getSummonedCreatureMap(); // <Effect, summoned creature>
|
||||
std::multimap<ESM::RefId, ESM::RefNum>& getSummonedCreatureMap(); // <Effect, summoned creature>
|
||||
|
||||
enum Flag
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,11 +23,17 @@ namespace MWMechanics
|
|||
{
|
||||
struct EffectKey
|
||||
{
|
||||
ESM::MagicEffectId mId;
|
||||
ESM::RefId mId;
|
||||
ESM::RefId mArg; // skill or ability
|
||||
|
||||
EffectKey();
|
||||
|
||||
EffectKey(ESM::RefId id, ESM::RefId arg = {})
|
||||
: mId(id)
|
||||
, mArg(arg)
|
||||
{
|
||||
}
|
||||
|
||||
EffectKey(ESM::MagicEffectId id, ESM::RefId arg = {})
|
||||
: mId(id)
|
||||
, mArg(arg)
|
||||
|
|
|
|||
|
|
@ -320,8 +320,8 @@ namespace MWMechanics
|
|||
ESM::RefId school = ESM::Skill::Alteration;
|
||||
if (!enchantment->mEffects.mList.empty())
|
||||
{
|
||||
short effectId = enchantment->mEffects.mList.front().mData.mEffectID;
|
||||
const ESM::MagicEffect* magicEffect = store->get<ESM::MagicEffect>().find(effectId);
|
||||
ESM::RefId effectId = enchantment->mEffects.mList.front().mData.mEffectID;
|
||||
const ESM::MagicEffect* magicEffect = store->get<ESM::MagicEffect>().search(effectId);
|
||||
school = magicEffect->mData.mSchool;
|
||||
}
|
||||
|
||||
|
|
@ -509,7 +509,7 @@ namespace MWMechanics
|
|||
MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(mCaster);
|
||||
if (animation)
|
||||
{
|
||||
animation->addEffect(castStaticModel.value(), ESM::MagicEffect::indexToName(effect->mIndex), false, {},
|
||||
animation->addEffect(castStaticModel.value(), ESM::MagicEffect::refIdToName(effect->mId), false, {},
|
||||
effect->mParticle);
|
||||
}
|
||||
else
|
||||
|
|
@ -585,7 +585,7 @@ namespace MWMechanics
|
|||
{
|
||||
const VFS::Path::Normalized castStaticModel
|
||||
= Misc::ResourceHelpers::correctMeshPath(VFS::Path::Normalized(castStatic->mModel));
|
||||
anim->addEffect(castStaticModel.value(), ESM::MagicEffect::indexToName(magicEffect.mIndex), loop, {},
|
||||
anim->addEffect(castStaticModel.value(), ESM::MagicEffect::refIdToName(magicEffect.mId), loop, {},
|
||||
magicEffect.mParticle);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,9 +23,41 @@
|
|||
namespace MWMechanics
|
||||
{
|
||||
|
||||
static const std::map<ESM::MagicEffectId, ESM::RefId>& getSummonMap()
|
||||
bool isSummoningEffect(const ESM::RefId& effectId)
|
||||
{
|
||||
static std::map<ESM::MagicEffectId, ESM::RefId> summonMap;
|
||||
if (effectId.empty())
|
||||
return false;
|
||||
static const std::array<ESM::MagicEffectId, 22> summonEffects{
|
||||
ESM::MagicEffect::SummonAncestralGhost,
|
||||
ESM::MagicEffect::SummonBonelord,
|
||||
ESM::MagicEffect::SummonBonewalker,
|
||||
ESM::MagicEffect::SummonCenturionSphere,
|
||||
ESM::MagicEffect::SummonClannfear,
|
||||
ESM::MagicEffect::SummonDaedroth,
|
||||
ESM::MagicEffect::SummonDremora,
|
||||
ESM::MagicEffect::SummonFabricant,
|
||||
ESM::MagicEffect::SummonFlameAtronach,
|
||||
ESM::MagicEffect::SummonFrostAtronach,
|
||||
ESM::MagicEffect::SummonGoldenSaint,
|
||||
ESM::MagicEffect::SummonGreaterBonewalker,
|
||||
ESM::MagicEffect::SummonHunger,
|
||||
ESM::MagicEffect::SummonScamp,
|
||||
ESM::MagicEffect::SummonSkeletalMinion,
|
||||
ESM::MagicEffect::SummonStormAtronach,
|
||||
ESM::MagicEffect::SummonWingedTwilight,
|
||||
ESM::MagicEffect::SummonWolf,
|
||||
ESM::MagicEffect::SummonBear,
|
||||
ESM::MagicEffect::SummonBonewolf,
|
||||
ESM::MagicEffect::SummonCreature04,
|
||||
ESM::MagicEffect::SummonCreature05,
|
||||
};
|
||||
return (std::find(summonEffects.begin(), summonEffects.end(), *effectId.getIf<ESM::MagicEffectId>())
|
||||
!= summonEffects.end());
|
||||
}
|
||||
|
||||
static const std::map<ESM::RefId, ESM::RefId>& getSummonMap()
|
||||
{
|
||||
static std::map<ESM::RefId, ESM::RefId> summonMap;
|
||||
|
||||
if (summonMap.size() > 0)
|
||||
return summonMap;
|
||||
|
|
@ -63,12 +95,7 @@ namespace MWMechanics
|
|||
return summonMap;
|
||||
}
|
||||
|
||||
bool isSummoningEffect(const ESM::MagicEffectId& effectId)
|
||||
{
|
||||
return getSummonMap().contains(effectId);
|
||||
}
|
||||
|
||||
ESM::RefId getSummonedCreature(const ESM::MagicEffectId& effectId)
|
||||
ESM::RefId getSummonedCreature(const ESM::RefId& effectId)
|
||||
{
|
||||
const auto& summonMap = getSummonMap();
|
||||
auto it = summonMap.find(effectId);
|
||||
|
|
@ -79,7 +106,7 @@ namespace MWMechanics
|
|||
return ESM::RefId();
|
||||
}
|
||||
|
||||
ESM::RefNum summonCreature(const ESM::MagicEffectId& effectId, const MWWorld::Ptr& summoner)
|
||||
ESM::RefNum summonCreature(const ESM::RefId& effectId, const MWWorld::Ptr& summoner)
|
||||
{
|
||||
const ESM::RefId& creatureID = getSummonedCreature(effectId);
|
||||
ESM::RefNum creature;
|
||||
|
|
@ -150,7 +177,7 @@ namespace MWMechanics
|
|||
}
|
||||
}
|
||||
|
||||
void purgeSummonEffect(const MWWorld::Ptr& summoner, const std::pair<ESM::MagicEffectId, ESM::RefNum>& summon)
|
||||
void purgeSummonEffect(const MWWorld::Ptr& summoner, const std::pair<ESM::RefId, ESM::RefNum>& summon)
|
||||
{
|
||||
auto& creatureStats = summoner.getClass().getCreatureStats(summoner);
|
||||
creatureStats.getActiveSpells().purge(
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ namespace ESM
|
|||
{
|
||||
class RefId;
|
||||
class StringRefId;
|
||||
|
||||
using MagicEffectId = StringRefId;
|
||||
}
|
||||
namespace MWWorld
|
||||
{
|
||||
|
|
@ -20,13 +18,13 @@ namespace MWWorld
|
|||
|
||||
namespace MWMechanics
|
||||
{
|
||||
bool isSummoningEffect(const ESM::MagicEffectId& effectId);
|
||||
bool isSummoningEffect(const ESM::RefId& effectId);
|
||||
|
||||
ESM::RefId getSummonedCreature(const ESM::MagicEffectId& effectId);
|
||||
ESM::RefId getSummonedCreature(const ESM::RefId& effectId);
|
||||
|
||||
void purgeSummonEffect(const MWWorld::Ptr& summoner, const std::pair<ESM::MagicEffectId, ESM::RefNum>& summon);
|
||||
void purgeSummonEffect(const MWWorld::Ptr& summoner, const std::pair<ESM::RefId, ESM::RefNum>& summon);
|
||||
|
||||
ESM::RefNum summonCreature(const ESM::MagicEffectId& effectId, const MWWorld::Ptr& summoner);
|
||||
ESM::RefNum summonCreature(const ESM::RefId& effectId, const MWWorld::Ptr& summoner);
|
||||
|
||||
void updateSummons(const MWWorld::Ptr& summoner, bool cleanup);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ namespace
|
|||
iter->mData.mAttribute = -1;
|
||||
Log(Debug::Verbose) << RecordType::getRecordType() << " " << spell.mId
|
||||
<< ": dropping unexpected attribute argument of "
|
||||
<< iter->mData.mEffectID.getRefIdString() << " effect";
|
||||
<< ESM::MagicEffect::refIdToName(iter->mData.mEffectID) << " effect";
|
||||
changed = true;
|
||||
}
|
||||
|
||||
|
|
@ -195,7 +195,7 @@ namespace
|
|||
iter->mData.mSkill = -1;
|
||||
Log(Debug::Verbose) << RecordType::getRecordType() << " " << spell.mId
|
||||
<< ": dropping unexpected skill argument of "
|
||||
<<iter->mData.mEffectID.getRefIdString() << " effect";
|
||||
<< ESM::MagicEffect::refIdToName(iter->mData.mEffectID) << " effect";
|
||||
changed = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace ESM
|
|||
Flag_Invalid = 1 << 5
|
||||
};
|
||||
|
||||
MagicEffectId mEffectId;
|
||||
RefId mEffectId;
|
||||
float mMagnitude;
|
||||
float mMinMagnitude;
|
||||
float mMaxMagnitude;
|
||||
|
|
|
|||
|
|
@ -11,15 +11,13 @@ namespace ESM
|
|||
class ESMReader;
|
||||
class ESMWriter;
|
||||
|
||||
using MagicEffectId = StringRefId;
|
||||
|
||||
/** Defines a spell effect. Shared between SPEL (Spells), ALCH
|
||||
(Potions) and ENCH (Item enchantments) records
|
||||
*/
|
||||
struct ENAMstruct
|
||||
{
|
||||
// Magical effect, serialized to int16
|
||||
ESM::MagicEffectId mEffectID;
|
||||
ESM::RefId mEffectID;
|
||||
|
||||
// Which skills/attributes are affected (for restore/drain spells
|
||||
// etc.)
|
||||
|
|
|
|||
|
|
@ -3,14 +3,26 @@
|
|||
#include "esmreader.hpp"
|
||||
#include "esmwriter.hpp"
|
||||
|
||||
#include <components/esm3/loadmgef.hpp>
|
||||
#include <components/misc/concepts.hpp>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
template <typename T>
|
||||
constexpr bool loading = !std::is_const_v<std::remove_reference_t<T>>;
|
||||
|
||||
template <Misc::SameAsWithoutCvref<Ingredient::IRDTstruct> T>
|
||||
void decompose(T&& v, const auto& f)
|
||||
{
|
||||
f(v.mWeight, v.mValue, v.mEffectID, v.mSkills, v.mAttributes);
|
||||
int32_t ioEffectID[4];
|
||||
std::transform(
|
||||
std::begin(v.mEffectID), std::end(v.mEffectID), std::begin(ioEffectID), ESM::MagicEffect::refIdToIndex);
|
||||
f(v.mWeight, v.mValue, ioEffectID, v.mSkills, v.mAttributes);
|
||||
if constexpr (loading<T>)
|
||||
{
|
||||
std::transform(
|
||||
std::begin(ioEffectID), std::end(ioEffectID), std::begin(v.mEffectID), ESM::MagicEffect::indexToRefId);
|
||||
}
|
||||
}
|
||||
|
||||
void Ingredient::load(ESMReader& esm, bool& isDeleted)
|
||||
|
|
@ -63,15 +75,21 @@ namespace ESM
|
|||
// horrible hack to fix broken data in records
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
if (mData.mEffectID[i] != 85 && mData.mEffectID[i] != 22 && mData.mEffectID[i] != 17
|
||||
&& mData.mEffectID[i] != 79 && mData.mEffectID[i] != 74)
|
||||
if (mData.mEffectID[i] != ESM::MagicEffect::AbsorbAttribute &&
|
||||
mData.mEffectID[i] != ESM::MagicEffect::DamageAttribute &&
|
||||
mData.mEffectID[i] != ESM::MagicEffect::DrainAttribute &&
|
||||
mData.mEffectID[i] != ESM::MagicEffect::FortifyAttribute &&
|
||||
mData.mEffectID[i] != ESM::MagicEffect::RestoreAttribute)
|
||||
{
|
||||
mData.mAttributes[i] = -1;
|
||||
}
|
||||
|
||||
// is this relevant in cycle from 0 to 4?
|
||||
if (mData.mEffectID[i] != 89 && mData.mEffectID[i] != 26 && mData.mEffectID[i] != 21
|
||||
&& mData.mEffectID[i] != 83 && mData.mEffectID[i] != 78)
|
||||
if (mData.mEffectID[i] != ESM::MagicEffect::AbsorbSkill &&
|
||||
mData.mEffectID[i] != ESM::MagicEffect::DamageSkill &&
|
||||
mData.mEffectID[i] != ESM::MagicEffect::DrainSkill &&
|
||||
mData.mEffectID[i] != ESM::MagicEffect::FortifySkill &&
|
||||
mData.mEffectID[i] != ESM::MagicEffect::RestoreSkill)
|
||||
{
|
||||
mData.mSkills[i] = -1;
|
||||
}
|
||||
|
|
@ -102,7 +120,7 @@ namespace ESM
|
|||
mData.mValue = 0;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
mData.mEffectID[i] = 0;
|
||||
mData.mEffectID[i] = ESM::MagicEffect::WaterBreathing;
|
||||
mData.mSkills[i] = 0;
|
||||
mData.mAttributes[i] = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace ESM
|
|||
{
|
||||
float mWeight;
|
||||
int32_t mValue;
|
||||
int32_t mEffectID[4]; // Effect, -1 means none
|
||||
RefId mEffectID[4]; // Effect, EmptyRefId means none
|
||||
int32_t mSkills[4]; // SkillEnum related to effect
|
||||
int32_t mAttributes[4]; // Attribute related to effect
|
||||
};
|
||||
|
|
|
|||
|
|
@ -826,6 +826,8 @@ namespace ESM
|
|||
|
||||
int MagicEffect::refIdToIndex(const RefId& effectId)
|
||||
{
|
||||
if (effectId.empty())
|
||||
return -1;
|
||||
for (size_t i = 0; i < sMagicEffectIds.size(); ++i)
|
||||
if (sMagicEffectIds[i] == effectId)
|
||||
return static_cast<int>(i);
|
||||
|
|
|
|||
|
|
@ -12,13 +12,11 @@ namespace ESM
|
|||
class ESMReader;
|
||||
class ESMWriter;
|
||||
|
||||
using MagicEffectId = StringRefId;
|
||||
|
||||
// format 0, saved games only
|
||||
struct MagicEffects
|
||||
{
|
||||
// <Effect Id, Base value, Modifier>
|
||||
std::map<ESM::MagicEffectId, std::pair<int32_t, float>> mEffects;
|
||||
std::map<ESM::RefId, std::pair<int32_t, float>> mEffects;
|
||||
|
||||
void load(ESMReader& esm);
|
||||
void save(ESMWriter& esm) const;
|
||||
|
|
@ -26,14 +24,14 @@ namespace ESM
|
|||
|
||||
struct SummonKey
|
||||
{
|
||||
SummonKey(const ESM::MagicEffectId& effectId, const ESM::RefId& sourceId, int32_t index)
|
||||
SummonKey(const ESM::RefId& effectId, const ESM::RefId& sourceId, int32_t index)
|
||||
: mEffectId(effectId)
|
||||
, mSourceId(sourceId)
|
||||
, mEffectIndex(index)
|
||||
{
|
||||
}
|
||||
|
||||
ESM::MagicEffectId mEffectId;
|
||||
ESM::RefId mEffectId;
|
||||
ESM::RefId mSourceId;
|
||||
int32_t mEffectIndex;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue