Improve faction items handling (bug #5164)

pull/541/head
Andrei Kortunov 5 years ago
parent 4a6d2cbaff
commit 85bb4a76f6

@ -141,6 +141,7 @@
Bug #5149: Failing lock pick attempts isn't always a crime Bug #5149: Failing lock pick attempts isn't always a crime
Bug #5159: NiMaterialColorController can only control the diffuse color Bug #5159: NiMaterialColorController can only control the diffuse color
Bug #5161: Creature companions can't be activated when they are knocked down 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 Bug #5188: Objects without a name don't fallback to their ID
Feature #1774: Handle AvoidNode Feature #1774: Handle AvoidNode
Feature #2229: Improve pathfinding AI Feature #2229: Improve pathfinding AI

@ -130,8 +130,8 @@ namespace MWBase
* If this parameter is false, it will be determined by a line-of-sight and awareness check. * If this parameter is false, it will be determined by a line-of-sight and awareness check.
* @return was the crime seen? * @return was the crime seen?
*/ */
virtual bool commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, virtual bool commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, OffenseType type,
OffenseType type, int arg=0, bool victimAware=false) = 0; const std::string& factionId="", int arg=0, bool victimAware=false) = 0;
/// @return false if the attack was considered a "friendly hit" and forgiven /// @return false if the attack was considered a "friendly hit" and forgiven
virtual bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) = 0; virtual bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) = 0;

@ -651,9 +651,22 @@ namespace MWGui
{ {
std::string ret; std::string ret;
ret += getMiscString(cellref.getOwner(), "Owner"); ret += getMiscString(cellref.getOwner(), "Owner");
ret += getMiscString(cellref.getFaction(), "Faction"); const std::string factionId = cellref.getFaction();
if (cellref.getFactionRank() > 0) 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<ESM::Faction>().search(factionId);
if (fact != nullptr)
{
int rank = cellref.getFactionRank();
const std::string rankName = fact->mRanks[rank];
if (rankName.empty())
ret += getValueString(cellref.getFactionRank(), "Rank"); ret += getValueString(cellref.getFactionRank(), "Rank");
else
ret += getMiscString(rankName, "Rank");
}
}
std::vector<std::pair<std::string, int> > itemOwners = std::vector<std::pair<std::string, int> > itemOwners =
MWBase::Environment::get().getMechanicsManager()->getStolenItemOwners(cellref.getRefId()); MWBase::Environment::get().getMechanicsManager()->getStolenItemOwners(cellref.getRefId());

@ -950,7 +950,6 @@ namespace MWMechanics
return true; return true;
const MWWorld::CellRef& cellref = target.getCellRef(); const MWWorld::CellRef& cellref = target.getCellRef();
// there is no harm to use unlocked doors // there is no harm to use unlocked doors
int lockLevel = cellref.getLockLevel(); int lockLevel = cellref.getLockLevel();
if (target.getClass().isDoor() && if (target.getClass().isDoor() &&
@ -1030,7 +1029,7 @@ namespace MWMechanics
if (isAllowedToUse(ptr, bed, victim)) if (isAllowedToUse(ptr, bed, victim))
return false; return false;
if(commitCrime(ptr, victim, OT_SleepingInOwnedBed)) if(commitCrime(ptr, victim, OT_SleepingInOwnedBed, bed.getCellRef().getFaction()))
{ {
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage64}"); MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage64}");
return true; return true;
@ -1044,7 +1043,7 @@ namespace MWMechanics
MWWorld::Ptr victim; MWWorld::Ptr victim;
if (isAllowedToUse(ptr, item, victim)) if (isAllowedToUse(ptr, item, victim))
return; return;
commitCrime(ptr, victim, OT_Trespassing); commitCrime(ptr, victim, OT_Trespassing, item.getCellRef().getFaction());
} }
std::vector<std::pair<std::string, int> > MechanicsManager::getStolenItemOwners(const std::string& itemid) std::vector<std::pair<std::string, int> > MechanicsManager::getStolenItemOwners(const std::string& itemid)
@ -1125,7 +1124,7 @@ namespace MWMechanics
// move items from player to owner and report about theft // move items from player to owner and report about theft
victim.getClass().getContainerStore(victim).add(item, toRemove, victim); victim.getClass().getContainerStore(victim).add(item, toRemove, victim);
store.remove(item, toRemove, player); 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) 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; mStolenItems[Misc::StringUtils::lowerCase(item.getCellRef().getRefId())][owner] += count;
} }
if (alarm) 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 // NOTE: victim may be empty
@ -1263,13 +1262,13 @@ namespace MWMechanics
} }
if (crimeSeen) if (crimeSeen)
reportCrime(player, victim, type, arg); reportCrime(player, victim, type, factionId, arg);
else if (type == OT_Assault && !victim.isEmpty()) else if (type == OT_Assault && !victim.isEmpty())
{ {
bool reported = false; bool reported = false;
if (victim.getClass().isClass(victim, "guard") if (victim.getClass().isClass(victim, "guard")
&& !victim.getClass().getCreatureStats(victim).getAiSequence().hasPackage(AiPackage::TypeIdPursue)) && !victim.getClass().getCreatureStats(victim).getAiSequence().hasPackage(AiPackage::TypeIdPursue))
reported = reportCrime(player, victim, type, arg); reported = reportCrime(player, victim, type, std::string(), arg);
if (!reported) if (!reported)
startCombat(victim, player); // TODO: combat should be started with an "unaware" flag, which makes the victim flee? 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; 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<ESM::GameSetting>& store = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>(); const MWWorld::Store<ESM::GameSetting>& store = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
@ -1471,6 +1470,14 @@ namespace MWMechanics
player.getClass().getNpcStats(player).expell(factionID); player.getClass().getNpcStats(player).expell(factionID);
} }
} }
else if (!factionId.empty())
{
const std::map<std::string, int>& 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() if (type == OT_Assault && !victim.isEmpty()
&& !victim.getClass().getCreatureStats(victim).getAiSequence().isInCombat(player) && !victim.getClass().getCreatureStats(victim).getAiSequence().isInCombat(player)

@ -130,7 +130,7 @@ namespace MWMechanics
* @return was the crime seen? * @return was the crime seen?
*/ */
virtual bool commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, 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 /// @return false if the attack was considered a "friendly hit" and forgiven
virtual bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) override; 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<MWWorld::Ptr> &playerFollowers); bool canReportCrime(const MWWorld::Ptr &actor, const MWWorld::Ptr &victim, std::set<MWWorld::Ptr> &playerFollowers);
bool reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, bool reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim,
OffenseType type, int arg=0); OffenseType type, const std::string& factionId, int arg=0);
}; };
} }

Loading…
Cancel
Save