forked from teamnwah/openmw-tes3coop
Crime and self defense fixes
- NPCs should still shout messages such as "thief" even if they did not report the crime - Fixed self defense for NPCs (they no longer attack the player when they were attacked by a non-player actor) - Fixed self defense for creatures (Fixes #1203)
This commit is contained in:
parent
d2beb814e7
commit
1c8c26072d
5 changed files with 33 additions and 19 deletions
|
@ -337,6 +337,12 @@ namespace MWClass
|
|||
{
|
||||
// NOTE: 'object' and/or 'attacker' may be empty.
|
||||
|
||||
getCreatureStats(ptr).setAttacked(true);
|
||||
|
||||
// Self defense
|
||||
if (!attacker.isEmpty() && ptr.getClass().getCreatureStats(ptr).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() < 80)
|
||||
MWBase::Environment::get().getMechanicsManager()->startCombat(ptr, attacker);
|
||||
|
||||
if(!successful)
|
||||
{
|
||||
// TODO: Handle HitAttemptOnMe script function
|
||||
|
|
|
@ -621,7 +621,7 @@ namespace MWClass
|
|||
// NOTE: 'object' and/or 'attacker' may be empty.
|
||||
|
||||
// Attacking peaceful NPCs is a crime
|
||||
if (!attacker.isEmpty() && ptr.getClass().isNpc() && ptr.getClass().getCreatureStats(ptr).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() <= 30)
|
||||
if (!attacker.isEmpty() && ptr.getClass().getCreatureStats(ptr).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() <= 30)
|
||||
MWBase::Environment::get().getMechanicsManager()->commitCrime(attacker, ptr, MWBase::MechanicsManager::OT_Assault);
|
||||
|
||||
getCreatureStats(ptr).setAttacked(true);
|
||||
|
|
|
@ -788,12 +788,6 @@ namespace MWMechanics
|
|||
}
|
||||
}
|
||||
}
|
||||
// if I didn't report a crime was I attacked?
|
||||
// TODO: this is incorrect, getAttacked also triggers if attacked by other non-player actors.
|
||||
else if (creatureStats.getAttacked() && !creatureStats.isHostile())
|
||||
{
|
||||
MWBase::Environment::get().getMechanicsManager()->startCombat(ptr, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ namespace MWMechanics
|
|||
|
||||
void stack (const AiPackage& package, const MWWorld::Ptr& actor);
|
||||
///< Add \a package to the front of the sequence (suspends current package)
|
||||
/// @param actor The actor that owns this AiSequence
|
||||
|
||||
void queue (const AiPackage& package);
|
||||
///< Add \a package to the end of the sequence (executed after all other packages have been
|
||||
|
|
|
@ -854,27 +854,45 @@ namespace MWMechanics
|
|||
// Innocent until proven guilty
|
||||
bool reported = false;
|
||||
|
||||
// Find all the NPCs within the alarm radius
|
||||
// Find all the actors within the alarm radius
|
||||
std::vector<MWWorld::Ptr> neighbors;
|
||||
mActors.getObjectsInRange(Ogre::Vector3(ptr.getRefData().getPosition().pos),
|
||||
esmStore.get<ESM::GameSetting>().find("fAlarmRadius")->getInt(), neighbors);
|
||||
|
||||
// Find an actor who witnessed the crime
|
||||
int id = MWBase::Environment::get().getWorld()->getPlayer().getNewCrimeId();
|
||||
|
||||
// Find actors who witnessed the crime
|
||||
for (std::vector<MWWorld::Ptr>::iterator it = neighbors.begin(); it != neighbors.end(); ++it)
|
||||
{
|
||||
if ( *it == ptr
|
||||
|| !it->getClass().isNpc()) continue; // not the player and is an NPC
|
||||
if (*it == ptr) continue; // not the player
|
||||
|
||||
// Was the crime seen?
|
||||
if ( ( MWBase::Environment::get().getWorld()->getLOS(ptr, *it) && awarenessCheck(ptr, *it) ) ||
|
||||
type == OT_Assault )
|
||||
if (MWBase::Environment::get().getWorld()->getLOS(ptr, *it) && awarenessCheck(ptr, *it) )
|
||||
{
|
||||
// TODO: Add more messages
|
||||
if (type == OT_Theft)
|
||||
MWBase::Environment::get().getDialogueManager()->say(*it, "thief");
|
||||
|
||||
if (*it == victim)
|
||||
{
|
||||
// Self-defense
|
||||
// The victim is aware of the criminal/assailant. If being assaulted, fight back now
|
||||
// (regardless of whether the assault is reported or not)
|
||||
// This applies to both NPCs and creatures
|
||||
|
||||
// ... except if this is a guard: then the player is given a chance to pay a fine / go to jail instead
|
||||
if (type == OT_Assault && !ptr.getClass().isClass(ptr, "guard"))
|
||||
MWBase::Environment::get().getMechanicsManager()->startCombat(victim, ptr);
|
||||
}
|
||||
|
||||
// Crime reporting only applies to NPCs
|
||||
if (!it->getClass().isNpc())
|
||||
continue;
|
||||
|
||||
// Will the witness report the crime?
|
||||
if (it->getClass().getCreatureStats(*it).getAiSetting(CreatureStats::AI_Alarm).getBase() >= alarm)
|
||||
{
|
||||
reported = true;
|
||||
int id = MWBase::Environment::get().getWorld()->getPlayer().getNewCrimeId();
|
||||
|
||||
// Tell everyone, including yourself
|
||||
for (std::vector<MWWorld::Ptr>::iterator it1 = neighbors.begin(); it1 != neighbors.end(); ++it1)
|
||||
|
@ -882,10 +900,6 @@ namespace MWMechanics
|
|||
if ( *it1 == ptr
|
||||
|| !it1->getClass().isNpc()) continue; // not the player and is an NPC
|
||||
|
||||
// TODO: Add more messages
|
||||
if (type == OT_Theft)
|
||||
MWBase::Environment::get().getDialogueManager()->say(*it1, "thief");
|
||||
|
||||
// Will other witnesses paticipate in crime
|
||||
if ( it1->getClass().getCreatureStats(*it1).getAiSetting(CreatureStats::AI_Alarm).getBase() >= alarm
|
||||
|| type == OT_Assault )
|
||||
|
@ -896,7 +910,6 @@ namespace MWMechanics
|
|||
// Mark as Alarmed for dialogue
|
||||
it1->getClass().getCreatureStats(*it1).setAlarmed(true);
|
||||
}
|
||||
break; // Someone saw the crime and everyone has been told
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue