From be13b1d0851737a977237962e07fe8404bcdbce9 Mon Sep 17 00:00:00 2001 From: Alexei Kotov Date: Tue, 4 Mar 2025 00:08:33 +0300 Subject: [PATCH] Handle instant projectile impact before underwater logic (#7622) --- apps/openmw/mwworld/worldimp.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 57d794c535..c642d14b16 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -3047,28 +3047,31 @@ namespace MWWorld // TODO: as a better solutuon we should handle projectiles during physics update, not during world update. const osg::Vec3f sourcePos = worldPos + orient * osg::Vec3f(0, -1, 0) * 64.f; - // Early out if the launch position is underwater - bool underwater = isUnderwater(MWMechanics::getPlayer().getCell(), worldPos); - if (underwater) - { - MWMechanics::projectileHit(actor, Ptr(), bow, projectile, worldPos, attackStrength); - mRendering->emitWaterRipple(worldPos); - return; - } - // For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit // result. std::vector targetActors; if (!actor.isEmpty() && actor.getClass().isActor() && actor != MWMechanics::getPlayer()) actor.getClass().getCreatureStats(actor).getAiSequence().getCombatTargets(targetActors); - // Check for impact, if yes, handle hit, if not, launch projectile + // Check for impact, if yes, handle hit MWPhysics::RayCastingResult result = mPhysics->castRay( sourcePos, worldPos, { actor }, targetActors, 0xff, MWPhysics::CollisionType_Projectile); + if (result.mHit) + { MWMechanics::projectileHit(actor, result.mHitObject, bow, projectile, result.mHitPos, attackStrength); - else - mProjectileManager->launchProjectile(actor, projectile, worldPos, orient, bow, speed, attackStrength); + return; + } + + // Bail out if the launch position is underwater + if (isUnderwater(MWMechanics::getPlayer().getCell(), worldPos)) + { + MWMechanics::projectileHit(actor, Ptr(), bow, projectile, worldPos, attackStrength); + mRendering->emitWaterRipple(worldPos); + return; + } + + mProjectileManager->launchProjectile(actor, projectile, worldPos, orient, bow, speed, attackStrength); } void World::launchMagicBolt(