From 84e1a29700169afd0440ccce9f9061e22a69f711 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Fri, 27 Nov 2020 00:34:07 +0300 Subject: [PATCH] Make AI cast self-targeted spells at the ground (bug #5695) --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/aicast.cpp | 32 ++++++++++++++++-------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f0c6dd5ee..2f38ce17f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,7 @@ Bug #5656: Sneaking characters block hits while standing Bug #5661: Region sounds don't play at the right interval Bug #5688: Water shader broken indoors with enable indoor shadows = false + Bug #5695: ExplodeSpell for actors doesn't target the ground Bug #5703: OpenMW-CS menu system crashing on XFCE Feature #390: 3rd person look "over the shoulder" Feature #2386: Distant Statics in the form of Object Paging diff --git a/apps/openmw/mwmechanics/aicast.cpp b/apps/openmw/mwmechanics/aicast.cpp index 9ad7b4c56..af3aac340 100644 --- a/apps/openmw/mwmechanics/aicast.cpp +++ b/apps/openmw/mwmechanics/aicast.cpp @@ -46,26 +46,28 @@ bool MWMechanics::AiCast::execute(const MWWorld::Ptr& actor, MWMechanics::Charac { return false; } + } - osg::Vec3f targetPos = target.getRefData().getPosition().asVec3(); - if (target.getClass().isActor()) - { - osg::Vec3f halfExtents = MWBase::Environment::get().getWorld()->getHalfExtents(target); - targetPos.z() += halfExtents.z() * 2 * 0.75f; - } + osg::Vec3f targetPos = target.getRefData().getPosition().asVec3(); + // If the target of an on-target spell is an actor that is not the caster + // the target position must be adjusted so that it's not casted at the actor's feet. + if (target != actor && target.getClass().isActor()) + { + osg::Vec3f halfExtents = MWBase::Environment::get().getWorld()->getHalfExtents(target); + targetPos.z() += halfExtents.z() * 2 * 0.75f; + } - osg::Vec3f actorPos = actor.getRefData().getPosition().asVec3(); - osg::Vec3f halfExtents = MWBase::Environment::get().getWorld()->getHalfExtents(actor); - actorPos.z() += halfExtents.z() * 2 * 0.75f; + osg::Vec3f actorPos = actor.getRefData().getPosition().asVec3(); + osg::Vec3f halfExtents = MWBase::Environment::get().getWorld()->getHalfExtents(actor); + actorPos.z() += halfExtents.z() * 2 * 0.75f; - osg::Vec3f dir = targetPos - actorPos; + osg::Vec3f dir = targetPos - actorPos; - bool turned = smoothTurn(actor, getZAngleToDir(dir), 2, osg::DegreesToRadians(3.f)); - turned &= smoothTurn(actor, getXAngleToDir(dir), 0, osg::DegreesToRadians(3.f)); + bool turned = smoothTurn(actor, getZAngleToDir(dir), 2, osg::DegreesToRadians(3.f)); + turned &= smoothTurn(actor, getXAngleToDir(dir), 0, osg::DegreesToRadians(3.f)); - if (!turned) - return false; - } + if (!turned) + return false; // Check if the actor is already casting another spell bool isCasting = MWBase::Environment::get().getMechanicsManager()->isCastingSpell(actor);