Merge branch 'KwarmaQueenCombat' into 'master'
Some checks are pending
Build and test / Ubuntu (push) Waiting to run
Build and test / MacOS (push) Waiting to run
Build and test / Read .env file and expose it as output (push) Waiting to run
Build and test / Windows (2019) (push) Blocked by required conditions
Build and test / Windows (2022) (push) Blocked by required conditions

Prevent immobile creatures from attacking or rotating, but not entering combat

Closes #7871

See merge request OpenMW/openmw!4632
This commit is contained in:
Aussiemon 2025-04-27 19:02:22 -06:00
commit 6cff33f5dd
4 changed files with 16 additions and 16 deletions

View file

@ -360,9 +360,6 @@ namespace MWClass
{ {
stats.setAttacked(true); stats.setAttacked(true);
// No retaliation for totally static creatures (they have no movement or attacks anyway)
if (isMobile(ptr))
{
bool complain = sourceType == MWMechanics::DamageSourceType::Melee; bool complain = sourceType == MWMechanics::DamageSourceType::Melee;
bool supportFriendlyFire = sourceType != MWMechanics::DamageSourceType::Ranged; bool supportFriendlyFire = sourceType != MWMechanics::DamageSourceType::Ranged;
if (supportFriendlyFire && MWMechanics::friendlyHit(attacker, ptr, complain)) if (supportFriendlyFire && MWMechanics::friendlyHit(attacker, ptr, complain))
@ -370,7 +367,6 @@ namespace MWClass
else else
setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker); setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
} }
}
// Attacker and target store each other as hitattemptactor if they have no one stored yet // Attacker and target store each other as hitattemptactor if they have no one stored yet
if (!attacker.isEmpty() && attacker.getClass().isActor()) if (!attacker.isEmpty() && attacker.getClass().isActor())

View file

@ -605,10 +605,6 @@ namespace MWMechanics
void Actors::engageCombat( void Actors::engageCombat(
const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2, SidingCache& cachedAllies, bool againstPlayer) const const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2, SidingCache& cachedAllies, bool againstPlayer) const
{ {
// No combat for totally static creatures
if (!actor1.getClass().isMobile(actor1))
return;
CreatureStats& creatureStats1 = actor1.getClass().getCreatureStats(actor1); CreatureStats& creatureStats1 = actor1.getClass().getCreatureStats(actor1);
if (creatureStats1.isDead() || creatureStats1.getAiSequence().isInCombat(actor2)) if (creatureStats1.isDead() || creatureStats1.getAiSequence().isInCombat(actor2))
return; return;

View file

@ -104,10 +104,10 @@ namespace MWMechanics
bool AiCombat::execute( bool AiCombat::execute(
const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration)
{ {
// get or create temporary storage // Get or create temporary storage
AiCombatStorage& storage = state.get<AiCombatStorage>(); AiCombatStorage& storage = state.get<AiCombatStorage>();
// General description // No combat for dead creatures
if (actor.getClass().getCreatureStats(actor).isDead()) if (actor.getClass().getCreatureStats(actor).isDead())
return true; return true;
@ -231,6 +231,10 @@ namespace MWMechanics
storage.stopFleeing(); storage.stopFleeing();
} }
// No attack actions for totally static creatures
if (!actor.getClass().isMobile(actor))
return false;
bool isRangedCombat = false; bool isRangedCombat = false;
float& rangeAttack = storage.mAttackRange; float& rangeAttack = storage.mAttackRange;

View file

@ -135,6 +135,10 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f&
MWWorld::MovementDirectionFlags supportedMovementDirections, float destTolerance, float endTolerance, MWWorld::MovementDirectionFlags supportedMovementDirections, float destTolerance, float endTolerance,
PathType pathType) PathType pathType)
{ {
// No pathing for totally static creatures
if (!actor.getClass().isMobile(actor))
return false;
const Misc::TimerStatus timerStatus = mReaction.update(duration); const Misc::TimerStatus timerStatus = mReaction.update(duration);
const osg::Vec3f position = actor.getRefData().getPosition().asVec3(); // position of the actor const osg::Vec3f position = actor.getRefData().getPosition().asVec3(); // position of the actor