1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-29 08:15:35 +00:00

Outlaw vampires and werewolves (bugs #7723, #7724)

This commit is contained in:
Alexei Kotov 2023-12-15 21:28:09 +03:00
parent 46dc290b75
commit 82982bbc05
3 changed files with 31 additions and 17 deletions

View file

@ -105,6 +105,8 @@
Bug #7679: Scene luminance value flashes when toggling shaders Bug #7679: Scene luminance value flashes when toggling shaders
Bug #7685: Corky sometimes doesn't follow Llovyn Andus Bug #7685: Corky sometimes doesn't follow Llovyn Andus
Bug #7712: Casting doesn't support spells and enchantments with no effects Bug #7712: Casting doesn't support spells and enchantments with no effects
Bug #7723: Assaulting vampires and werewolves shouldn't be a crime
Bug #7724: Guards don't help vs werewolves
Feature #3537: Shader-based water ripples Feature #3537: Shader-based water ripples
Feature #5173: Support for NiFogProperty Feature #5173: Support for NiFogProperty
Feature #5492: Let rain and snow collide with statics Feature #5492: Let rain and snow collide with statics

View file

@ -707,10 +707,9 @@ namespace MWMechanics
} }
} }
// Make guards go aggressive with creatures that are in combat, unless the creature is a follower or escorter // Make guards go aggressive with creatures and werewolves that are in combat
const auto world = MWBase::Environment::get().getWorld(); const auto world = MWBase::Environment::get().getWorld();
if (!aggressive && actor1.getClass().isClass(actor1, "Guard") && !actor2.getClass().isNpc() if (!aggressive && actor1.getClass().isClass(actor1, "Guard") && creatureStats2.getAiSequence().isInCombat())
&& creatureStats2.getAiSequence().isInCombat())
{ {
// Check if the creature is too far // Check if the creature is too far
static const float fAlarmRadius static const float fAlarmRadius
@ -718,20 +717,30 @@ namespace MWMechanics
if (sqrDist > fAlarmRadius * fAlarmRadius) if (sqrDist > fAlarmRadius * fAlarmRadius)
return; return;
bool followerOrEscorter = false; bool targetIsCreature = !actor2.getClass().isNpc();
for (const auto& package : creatureStats2.getAiSequence()) if (targetIsCreature || actor2.getClass().getNpcStats(actor2).isWerewolf())
{ {
// The follow package must be first or have nothing but combat before it bool followerOrEscorter = false;
if (package->sideWithTarget()) // ...unless the creature has allies
if (targetIsCreature)
{ {
followerOrEscorter = true; for (const auto& package : creatureStats2.getAiSequence())
break; {
// The follow package must be first or have nothing but combat before it
if (package->sideWithTarget())
{
followerOrEscorter = true;
break;
}
else if (package->getTypeId() != MWMechanics::AiPackageTypeId::Combat)
break;
}
} }
else if (package->getTypeId() != MWMechanics::AiPackageTypeId::Combat) // Morrowind also checks "known werewolf" flag, but the player is never in combat
break; // so this code is unreachable for the player
if (!followerOrEscorter)
aggressive = true;
} }
if (!followerOrEscorter)
aggressive = true;
} }
// If any of the above conditions turned actor1 aggressive towards actor2, do an awareness check. If it passes, // If any of the above conditions turned actor1 aggressive towards actor2, do an awareness check. If it passes,

View file

@ -1466,10 +1466,13 @@ namespace MWMechanics
bool MechanicsManager::canCommitCrimeAgainst(const MWWorld::Ptr& target, const MWWorld::Ptr& attacker) bool MechanicsManager::canCommitCrimeAgainst(const MWWorld::Ptr& target, const MWWorld::Ptr& attacker)
{ {
const MWMechanics::AiSequence& seq = target.getClass().getCreatureStats(target).getAiSequence(); const MWWorld::Class& cls = target.getClass();
return target.getClass().isNpc() && !attacker.isEmpty() && !seq.isInCombat(attacker) const MWMechanics::CreatureStats& stats = cls.getCreatureStats(target);
&& !isAggressive(target, attacker) && !seq.isEngagedWithActor() const MWMechanics::AiSequence& seq = stats.getAiSequence();
&& !target.getClass().getCreatureStats(target).getAiSequence().isInPursuit(); return cls.isNpc() && !attacker.isEmpty() && !seq.isInCombat(attacker) && !isAggressive(target, attacker)
&& !seq.isEngagedWithActor() && !stats.getAiSequence().isInPursuit()
&& !cls.getNpcStats(target).isWerewolf()
&& stats.getMagicEffects().getOrDefault(ESM::MagicEffect::Vampirism).getMagnitude() <= 0;
} }
void MechanicsManager::actorKilled(const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) void MechanicsManager::actorKilled(const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker)