From 42f3c73c7540006d48d5190d2d1354cfbed1d26e Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sat, 3 Jun 2017 13:16:44 +0400 Subject: [PATCH 1/2] Spell priority: dispel usage improvements --- apps/openmw/mwmechanics/aicombataction.cpp | 59 ++++++++++++++++++---- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwmechanics/aicombataction.cpp b/apps/openmw/mwmechanics/aicombataction.cpp index d0464418b..1acf2f041 100644 --- a/apps/openmw/mwmechanics/aicombataction.cpp +++ b/apps/openmw/mwmechanics/aicombataction.cpp @@ -61,7 +61,7 @@ float suggestCombatRange(int rangeTypes) } } -int numEffectsToCure (const MWWorld::Ptr& actor, int effectFilter=-1) +int numEffectsToDispel (const MWWorld::Ptr& actor, int effectFilter=-1, bool negative = true) { int toCure=0; const MWMechanics::ActiveSpells& activeSpells = actor.getClass().getCreatureStats(actor).getActiveSpells(); @@ -75,9 +75,14 @@ int numEffectsToCure (const MWWorld::Ptr& actor, int effectFilter=-1) if (effectFilter != -1 && effectId != effectFilter) continue; const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find(effectId); - if (magicEffect->mData.mFlags & ESM::MagicEffect::Harmful - && effectIt->mDuration > 3 // Don't attempt to cure if effect runs out shortly anyway - ) + + if (effectIt->mDuration <= 3) // Don't attempt to dispel if effect runs out shortly anyway + continue; + + if (negative && magicEffect->mData.mFlags & ESM::MagicEffect::Harmful) + ++toCure; + + if (!negative && !(magicEffect->mData.mFlags & ESM::MagicEffect::Harmful)) ++toCure; } } @@ -400,14 +405,49 @@ namespace MWMechanics } break; - // Prefer Cure effects over Dispel, because Dispel also removes positive effects case ESM::MagicEffect::Dispel: - return 1000.f * numEffectsToCure(actor); + { + int numPositive = 0; + int numNegative = 0; + int diff = 0; + + if (effect.mRange == ESM::RT_Self) + { + numPositive = numEffectsToDispel(actor, -1, false); + numNegative = numEffectsToDispel(actor); + + diff = numNegative - numPositive; + } + else + { + if (enemy.isEmpty()) + return 0.f; + + numPositive = numEffectsToDispel(enemy, -1, false); + numNegative = numEffectsToDispel(enemy); + + diff = numPositive - numNegative; + + // if rating < 0 here, the spell will be considered as negative later + rating *= -1; + } + + if (diff <= 0) + return 0.f; + + int magnitude = (effect.mMagnMin + effect.mMagnMax) / 2; + + rating *= (diff) / 5.f; + + break; + } + + // Prefer Cure effects over Dispel, because Dispel also removes positive effects case ESM::MagicEffect::CureParalyzation: - return 1001.f * numEffectsToCure(actor, ESM::MagicEffect::Paralyze); - case ESM::MagicEffect::CurePoison: - return 1001.f * numEffectsToCure(actor, ESM::MagicEffect::Poison); + return 1001.f * numEffectsToDispel(actor, ESM::MagicEffect::Paralyze); + case ESM::MagicEffect::CurePoison: + return 1001.f * numEffectsToDispel(actor, ESM::MagicEffect::Poison); case ESM::MagicEffect::DisintegrateArmor: { if (enemy.isEmpty()) @@ -555,6 +595,7 @@ namespace MWMechanics // Combat AI is egoistic, so doesn't consider applying positive effects to friendly actors. if (effect.mRange != ESM::RT_Self) rating *= -1.f; + return rating; } From 00402b71545c0957eb91cf2cc5c87320c3503111 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sun, 4 Jun 2017 14:09:23 +0400 Subject: [PATCH 2/2] Removed unused variable --- apps/openmw/mwmechanics/aicombataction.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/openmw/mwmechanics/aicombataction.cpp b/apps/openmw/mwmechanics/aicombataction.cpp index 1acf2f041..37b67c9b2 100644 --- a/apps/openmw/mwmechanics/aicombataction.cpp +++ b/apps/openmw/mwmechanics/aicombataction.cpp @@ -435,8 +435,6 @@ namespace MWMechanics if (diff <= 0) return 0.f; - int magnitude = (effect.mMagnMin + effect.mMagnMax) / 2; - rating *= (diff) / 5.f; break;