From 191cc76378a71966dda8e11e4933b78034a483bc Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 3 Jun 2018 09:46:12 +0300 Subject: [PATCH 1/3] Consider faction ownerships in item stolen checks (fixes #4293) --- apps/openmw/mwbase/mechanicsmanager.hpp | 2 +- apps/openmw/mwgui/enchantingdialog.cpp | 3 +-- apps/openmw/mwgui/tradewindow.cpp | 3 +-- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 9 +++++++-- apps/openmw/mwmechanics/mechanicsmanagerimp.hpp | 2 +- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index e40bf56bb..f15a86918 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -239,7 +239,7 @@ namespace MWBase virtual std::vector > getStolenItemOwners(const std::string& itemid) = 0; /// Has the player stolen this item from the given owner? - virtual bool isItemStolenFrom(const std::string& itemid, const std::string& ownerid) = 0; + virtual bool isItemStolenFrom(const std::string& itemid, const MWWorld::Ptr& ptr) = 0; virtual bool isBoundItem(const MWWorld::Ptr& item) = 0; virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, MWWorld::Ptr& victim) = 0; diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index 3616b8b62..f7764e0f1 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -339,8 +339,7 @@ namespace MWGui for (int i=0; i<2; ++i) { MWWorld::Ptr item = (i == 0) ? mEnchanting.getOldItem() : mEnchanting.getGem(); - if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom(item.getCellRef().getRefId(), - mPtr.getCellRef().getRefId())) + if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom(item.getCellRef().getRefId(), mPtr)) { std::string msg = MWBase::Environment::get().getWorld()->getStore().get().find("sNotifyMessage49")->getString(); if (msg.find("%s") != std::string::npos) diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 2eeeafe0d..0a9fe1b4a 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -311,8 +311,7 @@ namespace MWGui // check if the player is attempting to sell back an item stolen from this actor for (std::vector::iterator it = merchantBought.begin(); it != merchantBought.end(); ++it) { - if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom(it->mBase.getCellRef().getRefId(), - mPtr.getCellRef().getRefId())) + if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom(it->mBase.getCellRef().getRefId(), mPtr)) { std::string msg = gmst.find("sNotifyMessage49")->getString(); if (msg.find("%s") != std::string::npos) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index df93d875d..25fc5c704 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -992,14 +992,19 @@ namespace MWMechanics } } - bool MechanicsManager::isItemStolenFrom(const std::string &itemid, const std::string &ownerid) + bool MechanicsManager::isItemStolenFrom(const std::string &itemid, const MWWorld::Ptr& ptr) { StolenItemsMap::const_iterator it = mStolenItems.find(Misc::StringUtils::lowerCase(itemid)); if (it == mStolenItems.end()) return false; + const OwnerMap& owners = it->second; + const std::string ownerid = ptr.getCellRef().getRefId(); + const std::string factionid = ptr.getClass().getPrimaryFaction(ptr); OwnerMap::const_iterator ownerFound = owners.find(std::make_pair(Misc::StringUtils::lowerCase(ownerid), false)); - return ownerFound != owners.end(); + OwnerMap::const_iterator factionOwnerFound = owners.find(std::make_pair(Misc::StringUtils::lowerCase(factionid), true)); + + return ownerFound != owners.end() || factionOwnerFound != owners.end(); } void MechanicsManager::confiscateStolenItemToOwner(const MWWorld::Ptr &player, const MWWorld::Ptr &item, const MWWorld::Ptr& victim, int count) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 4bf47cb16..ede83b962 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -205,7 +205,7 @@ namespace MWMechanics virtual std::vector > getStolenItemOwners(const std::string& itemid); /// Has the player stolen this item from the given owner? - virtual bool isItemStolenFrom(const std::string& itemid, const std::string& ownerid); + virtual bool isItemStolenFrom(const std::string& itemid, const MWWorld::Ptr& ptr); virtual bool isBoundItem(const MWWorld::Ptr& item); From 3810ade67a7f473fcc8da9fc20afd8943e74784a Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 3 Jun 2018 10:50:10 +0300 Subject: [PATCH 2/3] Don't make unnecessary faction ID searches --- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 25fc5c704..8da2c86d2 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1000,11 +1000,18 @@ namespace MWMechanics const OwnerMap& owners = it->second; const std::string ownerid = ptr.getCellRef().getRefId(); - const std::string factionid = ptr.getClass().getPrimaryFaction(ptr); OwnerMap::const_iterator ownerFound = owners.find(std::make_pair(Misc::StringUtils::lowerCase(ownerid), false)); - OwnerMap::const_iterator factionOwnerFound = owners.find(std::make_pair(Misc::StringUtils::lowerCase(factionid), true)); + if (ownerFound != owners.end()) + return true; - return ownerFound != owners.end() || factionOwnerFound != owners.end(); + const std::string factionid = ptr.getClass().getPrimaryFaction(ptr); + if (!factionid.empty()) + { + OwnerMap::const_iterator factionOwnerFound = owners.find(std::make_pair(Misc::StringUtils::lowerCase(factionid), true)); + return factionOwnerFound != owners.end(); + } + + return false; } void MechanicsManager::confiscateStolenItemToOwner(const MWWorld::Ptr &player, const MWWorld::Ptr &item, const MWWorld::Ptr& victim, int count) From c14536a399b317d2a2d724333ca17602fbd92307 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 3 Jun 2018 13:02:27 +0300 Subject: [PATCH 3/3] Update faction-owned items confiscation --- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 8da2c86d2..4a773bdc7 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1029,6 +1029,13 @@ namespace MWMechanics owner.first = victim.getCellRef().getRefId(); owner.second = false; + const std::string victimFaction = victim.getClass().getPrimaryFaction(victim); + if (!victimFaction.empty() && Misc::StringUtils::ciEqual(item.getCellRef().getFaction(), victimFaction)) // Is the item faction-owned? + { + owner.first = victimFaction; + owner.second = true; + } + Misc::StringUtils::lowerCaseInPlace(owner.first); // decrease count of stolen items