From 9408876b5891a38fbf7757cc9f3d4a48cf5f633f Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Thu, 6 Sep 2018 17:17:30 +0300 Subject: [PATCH] Utilize AI GMSTs for priority rating (feature #4632) Fix on-target effect rating calculation --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/spellpriority.cpp | 12 +++++++++--- apps/openmw/mwmechanics/weaponpriority.cpp | 12 +++++------- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03036e1e4..c11d92900 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -141,6 +141,7 @@ Feature #4624: Spell priority: don't cast hit chance-affecting spells if the enemy is not in respective stance at the moment Feature #4625: Weapon priority: use weighted mean for melee damage rating Feature #4626: Weapon priority: account for weapon speed + Feature #4632: AI priority: utilize vanilla AI GMSTs for priority rating Task #2490: Don't open command prompt window on Release-mode builds automatically Task #4545: Enable is_pod string test Task #4605: Optimize skinning diff --git a/apps/openmw/mwmechanics/spellpriority.cpp b/apps/openmw/mwmechanics/spellpriority.cpp index f9d19ca28..807b56608 100644 --- a/apps/openmw/mwmechanics/spellpriority.cpp +++ b/apps/openmw/mwmechanics/spellpriority.cpp @@ -617,13 +617,19 @@ namespace MWMechanics float rateEffects(const ESM::EffectList &list, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy) { // NOTE: enemy may be empty + float rating = 0.f; + float ratingMult = 1.f; // NB: this multiplier is applied to the effect rating, not the final rating + + const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + static const float fAIMagicSpellMult = gmst.find("fAIMagicSpellMult")->mValue.getFloat(); + static const float fAIRangeMagicSpellMult = gmst.find("fAIRangeMagicSpellMult")->mValue.getFloat(); + for (std::vector::const_iterator it = list.mList.begin(); it != list.mList.end(); ++it) { - rating += rateEffect(*it, actor, enemy); + ratingMult = (it->mRange == ESM::RT_Target) ? fAIRangeMagicSpellMult : fAIMagicSpellMult; - if (it->mRange == ESM::RT_Target) - rating *= 1.5f; + rating += rateEffect(*it, actor, enemy) * ratingMult; } return rating; } diff --git a/apps/openmw/mwmechanics/weaponpriority.cpp b/apps/openmw/mwmechanics/weaponpriority.cpp index 6ce064fe4..818065ae4 100644 --- a/apps/openmw/mwmechanics/weaponpriority.cpp +++ b/apps/openmw/mwmechanics/weaponpriority.cpp @@ -39,7 +39,8 @@ namespace MWMechanics return 0.f; float rating=0.f; - float rangedMult=1.f; + static const float fAIMeleeWeaponMult = gmst.find("fAIMeleeWeaponMult")->mValue.getFloat(); + float ratingMult = fAIMeleeWeaponMult; if (weapon->mData.mType >= ESM::Weapon::MarksmanBow && weapon->mData.mType <= ESM::Weapon::MarksmanThrown) { @@ -48,14 +49,11 @@ namespace MWMechanics || world->isUnderwater(MWWorld::ConstPtr(enemy), 0.75f)) return 0.f; + // Use a higher rating multiplier if the actor is out of enemy's reach, use the normal mult otherwise if (getDistanceMinusHalfExtents(actor, enemy) >= getMaxAttackDistance(enemy)) { - static const float fAIMeleeWeaponMult = gmst.find("fAIMeleeWeaponMult")->mValue.getFloat(); static const float fAIRangeMeleeWeaponMult = gmst.find("fAIRangeMeleeWeaponMult")->mValue.getFloat(); - if (fAIMeleeWeaponMult != 0) - rangedMult = fAIRangeMeleeWeaponMult / fAIMeleeWeaponMult; - else - rangedMult = fAIRangeMeleeWeaponMult; + ratingMult = fAIRangeMeleeWeaponMult; } } @@ -124,7 +122,7 @@ namespace MWMechanics if (weapon->mData.mType < ESM::Weapon::MarksmanBow) rating *= weapon->mData.mSpeed; - return rating * rangedMult; + return rating * ratingMult; } float rateAmmo(const MWWorld::Ptr &actor, const MWWorld::Ptr &enemy, MWWorld::Ptr &bestAmmo, ESM::Weapon::Type ammoType)