From b995617559389991d93da94a4715a14b528d2521 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 11 Jan 2018 21:08:11 +0400 Subject: [PATCH 1/2] implement rateAmmo() function --- apps/openmw/mwmechanics/aicombataction.cpp | 42 +++------------------- apps/openmw/mwmechanics/weaponpriority.cpp | 28 +++++++++++++++ apps/openmw/mwmechanics/weaponpriority.hpp | 5 +++ 3 files changed, 37 insertions(+), 38 deletions(-) diff --git a/apps/openmw/mwmechanics/aicombataction.cpp b/apps/openmw/mwmechanics/aicombataction.cpp index df636dd56..0ccd0b6ec 100644 --- a/apps/openmw/mwmechanics/aicombataction.cpp +++ b/apps/openmw/mwmechanics/aicombataction.cpp @@ -182,29 +182,11 @@ namespace MWMechanics } } - float bestArrowRating = 0; MWWorld::Ptr bestArrow; - for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) - { - float rating = rateWeapon(*it, actor, enemy, ESM::Weapon::Arrow); - if (rating > bestArrowRating) - { - bestArrowRating = rating; - bestArrow = *it; - } - } + float bestArrowRating = rateAmmo(actor, enemy, bestArrow, ESM::Weapon::Arrow); - float bestBoltRating = 0; MWWorld::Ptr bestBolt; - for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) - { - float rating = rateWeapon(*it, actor, enemy, ESM::Weapon::Bolt); - if (rating > bestBoltRating) - { - bestBoltRating = rating; - bestBolt = *it; - } - } + float bestBoltRating = rateAmmo(actor, enemy, bestBolt, ESM::Weapon::Bolt); for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) { @@ -277,25 +259,9 @@ namespace MWMechanics } } - float bestArrowRating = 0; - for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) - { - float rating = rateWeapon(*it, actor, enemy, ESM::Weapon::Arrow); - if (rating > bestArrowRating) - { - bestArrowRating = rating; - } - } + float bestArrowRating = rateAmmo(actor, enemy, ESM::Weapon::Arrow); - float bestBoltRating = 0; - for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) - { - float rating = rateWeapon(*it, actor, enemy, ESM::Weapon::Bolt); - if (rating > bestBoltRating) - { - bestBoltRating = rating; - } - } + float bestBoltRating = rateAmmo(actor, enemy, ESM::Weapon::Bolt); for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) { diff --git a/apps/openmw/mwmechanics/weaponpriority.cpp b/apps/openmw/mwmechanics/weaponpriority.cpp index d06e73c93..5a0bd9c15 100644 --- a/apps/openmw/mwmechanics/weaponpriority.cpp +++ b/apps/openmw/mwmechanics/weaponpriority.cpp @@ -8,6 +8,7 @@ #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/inventorystore.hpp" #include "npcstats.hpp" #include "combat.hpp" @@ -111,6 +112,33 @@ namespace MWMechanics return rating + bonus; } + float rateAmmo(const MWWorld::Ptr &actor, const MWWorld::Ptr &enemy, MWWorld::Ptr &bestAmmo, ESM::Weapon::Type ammoType) + { + float bestAmmoRating = 0.f; + if (!actor.getClass().hasInventoryStore(actor)) + return bestAmmoRating; + + MWWorld::InventoryStore& store = actor.getClass().getInventoryStore(actor); + + for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) + { + float rating = rateWeapon(*it, actor, enemy, ammoType); + if (rating > bestAmmoRating) + { + bestAmmoRating = rating; + bestAmmo = *it; + } + } + + return bestAmmoRating; + } + + float rateAmmo(const MWWorld::Ptr &actor, const MWWorld::Ptr &enemy, ESM::Weapon::Type ammoType) + { + MWWorld::Ptr emptyPtr; + return rateAmmo(actor, enemy, emptyPtr, ammoType); + } + float vanillaRateWeaponAndAmmo(const MWWorld::Ptr& weapon, const MWWorld::Ptr& ammo, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy) { const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); diff --git a/apps/openmw/mwmechanics/weaponpriority.hpp b/apps/openmw/mwmechanics/weaponpriority.hpp index 90a767c4a..f5c9a1159 100644 --- a/apps/openmw/mwmechanics/weaponpriority.hpp +++ b/apps/openmw/mwmechanics/weaponpriority.hpp @@ -1,6 +1,8 @@ #ifndef OPENMW_WEAPON_PRIORITY_H #define OPENMW_WEAPON_PRIORITY_H +#include + #include "../mwworld/ptr.hpp" namespace MWMechanics @@ -8,6 +10,9 @@ namespace MWMechanics float rateWeapon (const MWWorld::Ptr& item, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, int type=-1, float arrowRating=0.f, float boltRating=0.f); + float rateAmmo(const MWWorld::Ptr &actor, const MWWorld::Ptr &enemy, MWWorld::Ptr &bestAmmo, ESM::Weapon::Type ammoType); + float rateAmmo(const MWWorld::Ptr &actor, const MWWorld::Ptr &enemy, ESM::Weapon::Type ammoType); + float vanillaRateWeaponAndAmmo(const MWWorld::Ptr& weapon, const MWWorld::Ptr& ammo, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); } From eccb49da18b6ddef273f08264775fcbe524186ca Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 11 Jan 2018 21:08:30 +0400 Subject: [PATCH 2/2] Do not summon the bound bow if there is no suitable ammo --- apps/openmw/mwmechanics/spellpriority.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/openmw/mwmechanics/spellpriority.cpp b/apps/openmw/mwmechanics/spellpriority.cpp index 3a730fbeb..7aef54007 100644 --- a/apps/openmw/mwmechanics/spellpriority.cpp +++ b/apps/openmw/mwmechanics/spellpriority.cpp @@ -1,4 +1,5 @@ #include "spellpriority.hpp" +#include "weaponpriority.hpp" #include #include @@ -335,6 +336,12 @@ namespace MWMechanics return 0.f; break; + case ESM::MagicEffect::BoundLongbow: + // AI should not summon the bow if there is no suitable ammo. + if (rateAmmo(actor, enemy, ESM::Weapon::Arrow) <= 0.f) + return 0.f; + break; + case ESM::MagicEffect::RestoreHealth: case ESM::MagicEffect::RestoreMagicka: case ESM::MagicEffect::RestoreFatigue: