From f08151d4249d72c5e3c415185e68300b15e27ce7 Mon Sep 17 00:00:00 2001 From: Aussiemon Date: Tue, 15 Apr 2025 00:42:22 -0600 Subject: [PATCH 1/5] Remove obsolete combat block for immobile creatures and autoformat --- apps/openmw/mwmechanics/actors.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index bb3273981d..77f0950fcd 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -184,7 +184,7 @@ namespace MWWorld::ContainerStoreIterator gem = container.end(); float gemCapacity = std::numeric_limits::max(); for (auto it = container.begin(MWWorld::ContainerStore::Type_Miscellaneous); it != container.end(); - ++it) + ++it) { if (it->getClass().isSoulGem(*it)) { @@ -605,10 +605,6 @@ namespace MWMechanics void Actors::engageCombat( 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); if (creatureStats1.isDead() || creatureStats1.getAiSequence().isInCombat(actor2)) return; @@ -1153,8 +1149,7 @@ namespace MWMechanics if (playerStats.getBounty() >= cutoff * iCrimeThresholdMultiplier) { mechanicsManager->startCombat(ptr, player, &cachedAllies.getActorsSidingWith(player)); - creatureStats.setHitAttemptActorId( - playerClass.getCreatureStats(player) + creatureStats.setHitAttemptActorId(playerClass.getCreatureStats(player) .getActorId()); // Stops the guard from quitting combat if player is unreachable } else From 30e8e0e83421e4e858c339117f9e236e976f9987 Mon Sep 17 00:00:00 2001 From: Aussiemon Date: Tue, 15 Apr 2025 17:25:58 -0600 Subject: [PATCH 2/5] Immobile creatures should enter combat, but not act --- apps/openmw/mwmechanics/aicombat.cpp | 8 +++++--- apps/openmw/mwmechanics/aipackage.cpp | 4 ++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 2399961a3a..a96270c2e3 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -104,10 +104,10 @@ namespace MWMechanics bool AiCombat::execute( const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) { - // get or create temporary storage + // Get or create temporary storage AiCombatStorage& storage = state.get(); - // General description + // No combat for dead creatures if (actor.getClass().getCreatureStats(actor).isDead()) return true; @@ -245,7 +245,9 @@ namespace MWMechanics float distToTarget = getDistanceToBounds(actor, target); - storage.mReadyToAttack = (currentAction->isAttackingOrSpell() && distToTarget <= rangeAttack && storage.mLOS); + // Must be attacking, within range, have line of sight, and not be immobile + storage.mReadyToAttack = (currentAction->isAttackingOrSpell() && distToTarget <= rangeAttack && storage.mLOS + && actor.getClass().isMobile(actor)); if (isRangedCombat) { diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index 4bcfc7dedd..24792b5bbc 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -135,6 +135,10 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& MWWorld::MovementDirectionFlags supportedMovementDirections, float destTolerance, float endTolerance, PathType pathType) { + // No pathing for totally static creatures + if (!actor.getClass().isMobile(actor)) + return false; + const Misc::TimerStatus timerStatus = mReaction.update(duration); const osg::Vec3f position = actor.getRefData().getPosition().asVec3(); // position of the actor From 9c22d382439e6f437e1dfedd9bce3e70dd365da7 Mon Sep 17 00:00:00 2001 From: Aussiemon Date: Tue, 15 Apr 2025 17:56:48 -0600 Subject: [PATCH 3/5] Revert autoformat changes --- apps/openmw/mwmechanics/actors.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 77f0950fcd..8188146fce 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -184,7 +184,7 @@ namespace MWWorld::ContainerStoreIterator gem = container.end(); float gemCapacity = std::numeric_limits::max(); for (auto it = container.begin(MWWorld::ContainerStore::Type_Miscellaneous); it != container.end(); - ++it) + ++it) { if (it->getClass().isSoulGem(*it)) { @@ -1149,7 +1149,8 @@ namespace MWMechanics if (playerStats.getBounty() >= cutoff * iCrimeThresholdMultiplier) { mechanicsManager->startCombat(ptr, player, &cachedAllies.getActorsSidingWith(player)); - creatureStats.setHitAttemptActorId(playerClass.getCreatureStats(player) + creatureStats.setHitAttemptActorId( + playerClass.getCreatureStats(player) .getActorId()); // Stops the guard from quitting combat if player is unreachable } else From 09075ee14a66c9f582f243e5412005a3d8252b4b Mon Sep 17 00:00:00 2001 From: Aussiemon Date: Tue, 15 Apr 2025 18:38:53 -0600 Subject: [PATCH 4/5] Found better place for early return --- apps/openmw/mwmechanics/aicombat.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index a96270c2e3..82fc9a67a1 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -231,6 +231,10 @@ namespace MWMechanics storage.stopFleeing(); } + // No attack actions for totally static creatures + if (!actor.getClass().isMobile(actor)) + return false; + bool isRangedCombat = false; float& rangeAttack = storage.mAttackRange; @@ -245,9 +249,7 @@ namespace MWMechanics float distToTarget = getDistanceToBounds(actor, target); - // Must be attacking, within range, have line of sight, and not be immobile - storage.mReadyToAttack = (currentAction->isAttackingOrSpell() && distToTarget <= rangeAttack && storage.mLOS - && actor.getClass().isMobile(actor)); + storage.mReadyToAttack = (currentAction->isAttackingOrSpell() && distToTarget <= rangeAttack && storage.mLOS); if (isRangedCombat) { From 82ba325ddfbf473431d561c44e3e3898c2633c06 Mon Sep 17 00:00:00 2001 From: Aussiemon Date: Tue, 15 Apr 2025 20:02:24 -0600 Subject: [PATCH 5/5] Allow immobile actors to initiate combat when attacked --- apps/openmw/mwclass/creature.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 9224f6f0d8..b10d5485b1 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -360,16 +360,12 @@ namespace MWClass { 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 supportFriendlyFire = sourceType != MWMechanics::DamageSourceType::Ranged; - if (supportFriendlyFire && MWMechanics::friendlyHit(attacker, ptr, complain)) - setOnPcHitMe = false; - else - setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker); - } + bool complain = sourceType == MWMechanics::DamageSourceType::Melee; + bool supportFriendlyFire = sourceType != MWMechanics::DamageSourceType::Ranged; + if (supportFriendlyFire && MWMechanics::friendlyHit(attacker, ptr, complain)) + setOnPcHitMe = false; + else + setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker); } // Attacker and target store each other as hitattemptactor if they have no one stored yet