mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-23 10:39:42 +00:00
Merge pull request #2525 from akortunov/factionowner
Improve faction items handling
This commit is contained in:
commit
d3284c0331
6 changed files with 46 additions and 17 deletions
|
@ -9,6 +9,7 @@
|
||||||
Bug #3109: SetPos/Position handles actors differently
|
Bug #3109: SetPos/Position handles actors differently
|
||||||
Bug #3282: Unintended behaviour when assigning F3 and Windows keys
|
Bug #3282: Unintended behaviour when assigning F3 and Windows keys
|
||||||
Bug #3550: Companion from mod attacks the air after combat has ended
|
Bug #3550: Companion from mod attacks the air after combat has ended
|
||||||
|
Bug #3609: Items from evidence chest are not considered to be stolen if player is allowed to use the chest
|
||||||
Bug #3623: Display scaling breaks mouse recognition
|
Bug #3623: Display scaling breaks mouse recognition
|
||||||
Bug #3725: Using script function in a non-conditional expression breaks script compilation
|
Bug #3725: Using script function in a non-conditional expression breaks script compilation
|
||||||
Bug #3733: Normal maps are inverted on mirrored UVs
|
Bug #3733: Normal maps are inverted on mirrored UVs
|
||||||
|
@ -140,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;
|
||||||
|
|
||||||
|
|
|
@ -275,9 +275,11 @@ namespace MWClass
|
||||||
if (ptr.getCellRef().getTrap() != "")
|
if (ptr.getCellRef().getTrap() != "")
|
||||||
text += "\n#{sTrapped}";
|
text += "\n#{sTrapped}";
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||||
text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
{ text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||||
|
if (Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "stolen_goods"))
|
||||||
|
text += "\nYou can not use evidence chests";
|
||||||
}
|
}
|
||||||
|
|
||||||
info.text = text;
|
info.text = text;
|
||||||
|
|
|
@ -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");
|
||||||
ret += getValueString(cellref.getFactionRank(), "Rank");
|
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");
|
||||||
|
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());
|
||||||
|
|
|
@ -1005,6 +1005,10 @@ namespace MWMechanics
|
||||||
if (!cellref.getOwner().empty())
|
if (!cellref.getOwner().empty())
|
||||||
victim = MWBase::Environment::get().getWorld()->searchPtr(cellref.getOwner(), true, false);
|
victim = MWBase::Environment::get().getWorld()->searchPtr(cellref.getOwner(), true, false);
|
||||||
|
|
||||||
|
// A special case for evidence chest - we should not allow to take items even if it is technically permitted
|
||||||
|
if (Misc::StringUtils::ciEqual(cellref.getRefId(), "stolen_goods"))
|
||||||
|
return false;
|
||||||
|
|
||||||
return (!isOwned && !isFactionOwned);
|
return (!isOwned && !isFactionOwned);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1025,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;
|
||||||
|
@ -1039,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)
|
||||||
|
@ -1120,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)
|
||||||
|
@ -1207,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
|
||||||
|
|
||||||
|
@ -1258,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?
|
||||||
|
@ -1295,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>();
|
||||||
|
|
||||||
|
@ -1466,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…
Reference in a new issue