From 85bb4a76f6d7020c4fabce652826d0c62527d89a Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Mon, 16 Sep 2019 14:20:43 +0400 Subject: [PATCH] Improve faction items handling (bug #5164) --- CHANGELOG.md | 1 + apps/openmw/mwbase/mechanicsmanager.hpp | 4 +-- apps/openmw/mwgui/tooltips.cpp | 19 +++++++++++--- .../mwmechanics/mechanicsmanagerimp.cpp | 25 ++++++++++++------- .../mwmechanics/mechanicsmanagerimp.hpp | 4 +-- 5 files changed, 37 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1422eee75..ebf884d86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -141,6 +141,7 @@ Bug #5149: Failing lock pick attempts isn't always a crime Bug #5159: NiMaterialColorController can only control the diffuse color Bug #5161: Creature companions can't be activated when they are knocked down + Bug #5164: Faction owned items handling is incorrect Bug #5188: Objects without a name don't fallback to their ID Feature #1774: Handle AvoidNode Feature #2229: Improve pathfinding AI diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index aecff2cc6..d1bb5a83d 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -130,8 +130,8 @@ namespace MWBase * If this parameter is false, it will be determined by a line-of-sight and awareness check. * @return was the crime seen? */ - virtual bool commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, - OffenseType type, int arg=0, bool victimAware=false) = 0; + virtual bool commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, OffenseType type, + const std::string& factionId="", int arg=0, bool victimAware=false) = 0; /// @return false if the attack was considered a "friendly hit" and forgiven virtual bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) = 0; diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 3891cf8a2..d6d51d446 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -651,9 +651,22 @@ namespace MWGui { std::string ret; ret += getMiscString(cellref.getOwner(), "Owner"); - ret += getMiscString(cellref.getFaction(), "Faction"); - if (cellref.getFactionRank() > 0) - ret += getValueString(cellref.getFactionRank(), "Rank"); + const std::string factionId = cellref.getFaction(); + ret += getMiscString(factionId, "Faction"); + if (!factionId.empty() && cellref.getFactionRank() >= 0) + { + const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + const ESM::Faction *fact = store.get().search(factionId); + if (fact != nullptr) + { + int rank = cellref.getFactionRank(); + const std::string rankName = fact->mRanks[rank]; + if (rankName.empty()) + ret += getValueString(cellref.getFactionRank(), "Rank"); + else + ret += getMiscString(rankName, "Rank"); + } + } std::vector > itemOwners = MWBase::Environment::get().getMechanicsManager()->getStolenItemOwners(cellref.getRefId()); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 6a35224bc..de1780ce7 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -950,7 +950,6 @@ namespace MWMechanics return true; const MWWorld::CellRef& cellref = target.getCellRef(); - // there is no harm to use unlocked doors int lockLevel = cellref.getLockLevel(); if (target.getClass().isDoor() && @@ -1030,7 +1029,7 @@ namespace MWMechanics if (isAllowedToUse(ptr, bed, victim)) return false; - if(commitCrime(ptr, victim, OT_SleepingInOwnedBed)) + if(commitCrime(ptr, victim, OT_SleepingInOwnedBed, bed.getCellRef().getFaction())) { MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage64}"); return true; @@ -1044,7 +1043,7 @@ namespace MWMechanics MWWorld::Ptr victim; if (isAllowedToUse(ptr, item, victim)) return; - commitCrime(ptr, victim, OT_Trespassing); + commitCrime(ptr, victim, OT_Trespassing, item.getCellRef().getFaction()); } std::vector > MechanicsManager::getStolenItemOwners(const std::string& itemid) @@ -1125,7 +1124,7 @@ namespace MWMechanics // move items from player to owner and report about theft victim.getClass().getContainerStore(victim).add(item, toRemove, victim); store.remove(item, toRemove, player); - commitCrime(player, victim, OT_Theft, item.getClass().getValue(item) * toRemove); + commitCrime(player, victim, OT_Theft, item.getCellRef().getFaction(), item.getClass().getValue(item) * toRemove); } void MechanicsManager::confiscateStolenItems(const MWWorld::Ptr &player, const MWWorld::Ptr &targetContainer) @@ -1212,11 +1211,11 @@ namespace MWMechanics mStolenItems[Misc::StringUtils::lowerCase(item.getCellRef().getRefId())][owner] += count; } if (alarm) - commitCrime(ptr, victim, OT_Theft, item.getClass().getValue(item) * count); + commitCrime(ptr, victim, OT_Theft, ownerCellRef->getFaction(), item.getClass().getValue(item) * count); } - bool MechanicsManager::commitCrime(const MWWorld::Ptr &player, const MWWorld::Ptr &victim, OffenseType type, int arg, bool victimAware) + bool MechanicsManager::commitCrime(const MWWorld::Ptr &player, const MWWorld::Ptr &victim, OffenseType type, const std::string& factionId, int arg, bool victimAware) { // NOTE: victim may be empty @@ -1263,13 +1262,13 @@ namespace MWMechanics } if (crimeSeen) - reportCrime(player, victim, type, arg); + reportCrime(player, victim, type, factionId, arg); else if (type == OT_Assault && !victim.isEmpty()) { bool reported = false; if (victim.getClass().isClass(victim, "guard") && !victim.getClass().getCreatureStats(victim).getAiSequence().hasPackage(AiPackage::TypeIdPursue)) - reported = reportCrime(player, victim, type, arg); + reported = reportCrime(player, victim, type, std::string(), arg); if (!reported) startCombat(victim, player); // TODO: combat should be started with an "unaware" flag, which makes the victim flee? @@ -1300,7 +1299,7 @@ namespace MWMechanics return true; } - bool MechanicsManager::reportCrime(const MWWorld::Ptr &player, const MWWorld::Ptr &victim, OffenseType type, int arg) + bool MechanicsManager::reportCrime(const MWWorld::Ptr &player, const MWWorld::Ptr &victim, OffenseType type, const std::string& factionId, int arg) { const MWWorld::Store& store = MWBase::Environment::get().getWorld()->getStore().get(); @@ -1471,6 +1470,14 @@ namespace MWMechanics player.getClass().getNpcStats(player).expell(factionID); } } + else if (!factionId.empty()) + { + const std::map& playerRanks = player.getClass().getNpcStats(player).getFactionRanks(); + if (playerRanks.find(Misc::StringUtils::lowerCase(factionId)) != playerRanks.end()) + { + player.getClass().getNpcStats(player).expell(factionId); + } + } if (type == OT_Assault && !victim.isEmpty() && !victim.getClass().getCreatureStats(victim).getAiSequence().isInCombat(player) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 5a8826a6a..9e8ce87d1 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -130,7 +130,7 @@ namespace MWMechanics * @return was the crime seen? */ virtual bool commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, - OffenseType type, int arg=0, bool victimAware=false) override; + OffenseType type, const std::string& factionId="", int arg=0, bool victimAware=false) override; /// @return false if the attack was considered a "friendly hit" and forgiven virtual bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) override; @@ -247,7 +247,7 @@ namespace MWMechanics bool canReportCrime(const MWWorld::Ptr &actor, const MWWorld::Ptr &victim, std::set &playerFollowers); bool reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, - OffenseType type, int arg=0); + OffenseType type, const std::string& factionId, int arg=0); }; }