diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index ff4ae6148..9e5afb66a 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -164,7 +164,7 @@ namespace MWClass getContainerStore(ptr).fill(ref->mBase->mInventory, ptr.getCellRef().getRefId()); if (hasInventory) - getInventoryStore(ptr).autoEquip(ptr); + getInventoryStore(ptr).autoEquipShield(ptr); } } diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index d1b71bbd5..794832733 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -139,7 +139,7 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::add(const Ptr& itemPtr, // Auto-equip items if an armor/clothing or weapon item is added, but not for the player nor werewolves if (actorPtr != MWMechanics::getPlayer() - && !(actorPtr.getClass().isNpc() && actorPtr.getClass().getNpcStats(actorPtr).isWerewolf())) + && actorPtr.getClass().isNpc() && !actorPtr.getClass().getNpcStats(actorPtr).isWerewolf()) { std::string type = itemPtr.getTypeName(); if (type == typeid(ESM::Armor).name() || type == typeid(ESM::Clothing).name()) @@ -237,10 +237,6 @@ bool MWWorld::InventoryStore::canActorAutoEquip(const MWWorld::Ptr& actor, const void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) { - if (!actor.getClass().isNpc()) - // autoEquip is no-op for creatures - return; - const MWBase::World *world = MWBase::Environment::get().getWorld(); const MWWorld::Store &store = world->getStore().get(); MWMechanics::NpcStats& stats = actor.getClass().getNpcStats(actor); @@ -443,6 +439,50 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) } } +void MWWorld::InventoryStore::autoEquipShield(const MWWorld::Ptr& actor) +{ + bool updated = false; + + mUpdatesEnabled = false; + for (ContainerStoreIterator iter(begin(ContainerStore::Type_Armor)); iter != end(); ++iter) + { + if (iter->get()->mBase->mData.mType != ESM::Armor::Shield) + continue; + + if (iter->getClass().canBeEquipped(*iter, actor).first != 1) + continue; + + if (iter->getClass().getItemHealth(*iter) <= 0) + continue; + + std::pair, bool> shieldSlots = + iter->getClass().getEquipmentSlots(*iter); + + if (shieldSlots.first.empty()) + continue; + + int slot = shieldSlots.first[0]; + const ContainerStoreIterator& shield = mSlots[slot]; + + if (shield != end() + && shield.getType() == Type_Armor && shield->get()->mBase->mData.mType == ESM::Armor::Shield) + { + if (shield->getClass().getItemHealth(*shield) >= iter->getClass().getItemHealth(*iter)) + continue; + } + + equip(slot, iter, actor); + updated = true; + } + mUpdatesEnabled = true; + + if (updated) + { + fireEquipmentChangedEvent(actor); + updateMagicEffects(actor); + } +} + const MWMechanics::MagicEffects& MWWorld::InventoryStore::getMagicEffects() const { return mMagicEffects; @@ -622,7 +662,7 @@ int MWWorld::InventoryStore::remove(const Ptr& item, int count, const Ptr& actor // If an armor/clothing item is removed, try to find a replacement, // but not for the player nor werewolves. if (wasEquipped && (actor != MWMechanics::getPlayer()) - && !(actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf())) + && actor.getClass().isNpc() && !actor.getClass().getNpcStats(actor).isWerewolf()) { std::string type = item.getTypeName(); if (type == typeid(ESM::Armor).name() || type == typeid(ESM::Clothing).name()) diff --git a/apps/openmw/mwworld/inventorystore.hpp b/apps/openmw/mwworld/inventorystore.hpp index 7e6a259c4..f625e4cd1 100644 --- a/apps/openmw/mwworld/inventorystore.hpp +++ b/apps/openmw/mwworld/inventorystore.hpp @@ -162,6 +162,9 @@ namespace MWWorld void autoEquip (const MWWorld::Ptr& actor); ///< Auto equip items according to stats and item value. + void autoEquipShield(const MWWorld::Ptr& actor); + ///< Auto-equip the shield with most health. + const MWMechanics::MagicEffects& getMagicEffects() const; ///< Return magic effects from worn items.