mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-21 07:09:42 +00:00
Allow bound effects to be recast if they're attached to a recastable effect
This commit is contained in:
parent
2091a81e1b
commit
5448338b21
1 changed files with 38 additions and 33 deletions
|
@ -163,68 +163,73 @@ namespace MWMechanics
|
|||
|
||||
// If none of the effects need to apply, we can early-out
|
||||
bool found = false;
|
||||
bool containsRecastable = false;
|
||||
std::vector<const ESM::MagicEffect*> magicEffects;
|
||||
magicEffects.reserve(effects.mList.size());
|
||||
const auto& store = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>();
|
||||
for (const ESM::ENAMstruct& effect : effects.mList)
|
||||
{
|
||||
if (effect.mRange == range)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
const ESM::MagicEffect* magicEffect = store.find(effect.mEffectID);
|
||||
// caster needs to be an actor for linked effects (e.g. Absorb)
|
||||
if (magicEffect->mData.mFlags & ESM::MagicEffect::CasterLinked
|
||||
&& (mCaster.isEmpty() || !mCaster.getClass().isActor()))
|
||||
{
|
||||
magicEffects.push_back(nullptr);
|
||||
continue;
|
||||
}
|
||||
if (!(magicEffect->mData.mFlags & ESM::MagicEffect::NonRecastable))
|
||||
containsRecastable = true;
|
||||
magicEffects.push_back(magicEffect);
|
||||
}
|
||||
else
|
||||
magicEffects.push_back(nullptr);
|
||||
}
|
||||
if (!found)
|
||||
return;
|
||||
|
||||
ActiveSpells::ActiveSpellParams params(*this, mCaster);
|
||||
|
||||
bool castByPlayer = (!mCaster.isEmpty() && mCaster == getPlayer());
|
||||
|
||||
const ActiveSpells* targetSpells = nullptr;
|
||||
if (targetIsActor)
|
||||
targetSpells = &target.getClass().getCreatureStats(target).getActiveSpells();
|
||||
|
||||
bool canCastAnEffect = false; // For bound equipment.If this remains false
|
||||
// throughout the iteration of this spell's
|
||||
// effects, we display a "can't re-cast" message
|
||||
|
||||
int currentEffectIndex = 0;
|
||||
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt(effects.mList.begin());
|
||||
!target.isEmpty() && effectIt != effects.mList.end(); ++effectIt, ++currentEffectIndex)
|
||||
// Re-casting a bound equipment effect has no effect if the spell is still active
|
||||
if (!containsRecastable && targetSpells && targetSpells->isSpellActive(mId))
|
||||
{
|
||||
if (effectIt->mRange != range)
|
||||
if (castByPlayer)
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicCannotRecast}");
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t currentEffectIndex = 0; !target.isEmpty() && currentEffectIndex < effects.mList.size();
|
||||
++currentEffectIndex)
|
||||
{
|
||||
const ESM::ENAMstruct& enam = effects.mList[currentEffectIndex];
|
||||
if (enam.mRange != range)
|
||||
continue;
|
||||
|
||||
const ESM::MagicEffect* magicEffect
|
||||
= MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(effectIt->mEffectID);
|
||||
|
||||
// Re-casting a bound equipment effect has no effect if the spell is still active
|
||||
if (magicEffect->mData.mFlags & ESM::MagicEffect::NonRecastable && targetSpells
|
||||
&& targetSpells->isSpellActive(mId))
|
||||
{
|
||||
if (effectIt == (effects.mList.end() - 1) && !canCastAnEffect && castByPlayer)
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicCannotRecast}");
|
||||
continue;
|
||||
}
|
||||
canCastAnEffect = true;
|
||||
|
||||
// caster needs to be an actor for linked effects (e.g. Absorb)
|
||||
if (magicEffect->mData.mFlags & ESM::MagicEffect::CasterLinked
|
||||
&& (mCaster.isEmpty() || !mCaster.getClass().isActor()))
|
||||
const ESM::MagicEffect* magicEffect = magicEffects[currentEffectIndex];
|
||||
if (!magicEffect)
|
||||
continue;
|
||||
|
||||
ActiveSpells::ActiveEffect effect;
|
||||
effect.mEffectId = effectIt->mEffectID;
|
||||
effect.mArg = MWMechanics::EffectKey(*effectIt).mArg;
|
||||
effect.mEffectId = enam.mEffectID;
|
||||
effect.mArg = MWMechanics::EffectKey(enam).mArg;
|
||||
effect.mMagnitude = 0.f;
|
||||
effect.mMinMagnitude = effectIt->mMagnMin;
|
||||
effect.mMaxMagnitude = effectIt->mMagnMax;
|
||||
effect.mMinMagnitude = enam.mMagnMin;
|
||||
effect.mMaxMagnitude = enam.mMagnMax;
|
||||
effect.mTimeLeft = 0.f;
|
||||
effect.mEffectIndex = currentEffectIndex;
|
||||
effect.mEffectIndex = static_cast<int>(currentEffectIndex);
|
||||
effect.mFlags = ESM::ActiveEffect::Flag_None;
|
||||
if (mManualSpell)
|
||||
effect.mFlags |= ESM::ActiveEffect::Flag_Ignore_Reflect;
|
||||
|
||||
bool hasDuration = !(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration);
|
||||
effect.mDuration = hasDuration ? static_cast<float>(effectIt->mDuration) : 1.f;
|
||||
effect.mDuration = hasDuration ? static_cast<float>(enam.mDuration) : 1.f;
|
||||
|
||||
bool appliedOnce = magicEffect->mData.mFlags & ESM::MagicEffect::AppliedOnce;
|
||||
if (!appliedOnce)
|
||||
|
@ -236,7 +241,7 @@ namespace MWMechanics
|
|||
params.getEffects().emplace_back(effect);
|
||||
|
||||
bool effectAffectsHealth = magicEffect->mData.mFlags & ESM::MagicEffect::Harmful
|
||||
|| effectIt->mEffectID == ESM::MagicEffect::RestoreHealth;
|
||||
|| enam.mEffectID == ESM::MagicEffect::RestoreHealth;
|
||||
if (castByPlayer && target != mCaster && targetIsActor && effectAffectsHealth)
|
||||
{
|
||||
// If player is attempting to cast a harmful spell on or is healing a living target, show the target's
|
||||
|
|
Loading…
Reference in a new issue