mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-04-15 14:42:35 +00:00
Merged merge request !36
This commit is contained in:
commit
20c53594de
@ -173,6 +173,7 @@ Programmers
|
||||
vocollapse
|
||||
Yohaulticetl
|
||||
zelurker
|
||||
James Carty (MrTopCat)
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "aicombataction.hpp"
|
||||
#include "aipursue.hpp"
|
||||
#include "actorutil.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
@ -122,6 +123,20 @@ bool AiSequence::isInCombat() const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AiSequence::isEngagedWithActor() const
|
||||
{
|
||||
for (std::list<AiPackage *>::const_iterator it = mPackages.begin(); it != mPackages.end(); ++it)
|
||||
{
|
||||
if ((*it)->getTypeId() == AiPackage::TypeIdCombat)
|
||||
{
|
||||
MWWorld::Ptr target2 = (*it)->getTarget();
|
||||
if (!target2.isEmpty() && target2.getClass().isNpc())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AiSequence::hasPackage(int typeId) const
|
||||
{
|
||||
for (std::list<AiPackage*>::const_iterator it = mPackages.begin(); it != mPackages.end(); ++it)
|
||||
|
@ -88,6 +88,9 @@ namespace MWMechanics
|
||||
/// Is there any combat package?
|
||||
bool isInCombat () const;
|
||||
|
||||
/// Are we in combat with any other actor, who's also engaging us?
|
||||
bool isEngagedWithActor () const;
|
||||
|
||||
/// Does this AI sequence have the given package type?
|
||||
bool hasPackage(int typeId) const;
|
||||
|
||||
|
@ -1462,24 +1462,11 @@ namespace MWMechanics
|
||||
}
|
||||
}
|
||||
|
||||
// Attacking an NPC that is already in combat with any other NPC is not a crime
|
||||
AiSequence& seq = statsTarget.getAiSequence();
|
||||
bool isFightingNpc = false;
|
||||
for (std::list<AiPackage*>::const_iterator it = seq.begin(); it != seq.end(); ++it)
|
||||
{
|
||||
if ((*it)->getTypeId() == AiPackage::TypeIdCombat)
|
||||
{
|
||||
MWWorld::Ptr target2 = (*it)->getTarget();
|
||||
if (!target2.isEmpty() && target2.getClass().isNpc())
|
||||
isFightingNpc = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (target.getClass().isNpc() && !attacker.isEmpty() && !seq.isInCombat(attacker)
|
||||
&& !isAggressive(target, attacker) && !isFightingNpc
|
||||
&& !target.getClass().getCreatureStats(target).getAiSequence().hasPackage(AiPackage::TypeIdPursue))
|
||||
if (canCommitCrimeAgainst(target, attacker))
|
||||
commitCrime(attacker, target, MWBase::MechanicsManager::OT_Assault);
|
||||
|
||||
AiSequence& seq = statsTarget.getAiSequence();
|
||||
|
||||
if (!attacker.isEmpty() && (attacker.getClass().getCreatureStats(attacker).getAiSequence().isInCombat(target)
|
||||
|| attacker == getPlayer())
|
||||
&& !seq.isInCombat(attacker))
|
||||
@ -1506,6 +1493,14 @@ namespace MWMechanics
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MechanicsManager::canCommitCrimeAgainst(const MWWorld::Ptr &target, const MWWorld::Ptr &attacker)
|
||||
{
|
||||
MWMechanics::AiSequence seq = target.getClass().getCreatureStats(target).getAiSequence();
|
||||
return target.getClass().isNpc() && !attacker.isEmpty() && !seq.isInCombat(attacker)
|
||||
&& !isAggressive(target, attacker) && !seq.isEngagedWithActor()
|
||||
&& !target.getClass().getCreatureStats(target).getAiSequence().hasPackage(AiPackage::TypeIdPursue);
|
||||
}
|
||||
|
||||
void MechanicsManager::actorKilled(const MWWorld::Ptr &victim, const MWWorld::Ptr &attacker)
|
||||
{
|
||||
if (attacker.isEmpty() || victim.isEmpty())
|
||||
@ -1518,11 +1513,10 @@ namespace MWMechanics
|
||||
return; // TODO: implement animal rights
|
||||
|
||||
const MWMechanics::NpcStats& victimStats = victim.getClass().getNpcStats(victim);
|
||||
if (victimStats.getCrimeId() == -1)
|
||||
return;
|
||||
const MWWorld::Ptr &player = getPlayer();
|
||||
bool canCommit = attacker == player && canCommitCrimeAgainst(victim, attacker);
|
||||
|
||||
// For now we report only about crimes of player and player's followers
|
||||
const MWWorld::Ptr &player = getPlayer();
|
||||
if (attacker != player)
|
||||
{
|
||||
std::set<MWWorld::Ptr> playerFollowers;
|
||||
@ -1531,6 +1525,9 @@ namespace MWMechanics
|
||||
return;
|
||||
}
|
||||
|
||||
if (!canCommit && victimStats.getCrimeId() == -1)
|
||||
return;
|
||||
|
||||
// Simple check for who attacked first: if the player attacked first, a crimeId should be set
|
||||
// Doesn't handle possible edge case where no one reported the assault, but in such a case,
|
||||
// for bystanders it is not possible to tell who attacked first, anyway.
|
||||
|
@ -132,6 +132,12 @@ namespace MWMechanics
|
||||
/// @note No-op for non-player attackers
|
||||
virtual void actorKilled (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker);
|
||||
|
||||
/// Checks if commiting a crime is currently valid
|
||||
/// @param victim The actor being attacked
|
||||
/// @param attacker The actor commiting the crime
|
||||
/// @return true if the victim is a valid target for crime
|
||||
virtual bool canCommitCrimeAgainst(const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker);
|
||||
|
||||
/// Utility to check if taking this item is illegal and calling commitCrime if so
|
||||
/// @param container The container the item is in; may be empty for an item in the world
|
||||
virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, const MWWorld::Ptr& container,
|
||||
|
Loading…
x
Reference in New Issue
Block a user