mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-09-19 01:16:45 -04:00
Merge branch 'suijutsu' into 'master'
Underwater projectile fixes (#7622, #8303) Closes #7622 and #8303 See merge request OpenMW/openmw!4567
This commit is contained in:
commit
2309aeec70
@ -274,8 +274,8 @@ namespace MWWorld
|
|||||||
pos.z() += mPhysics->getRenderingHalfExtents(caster).z() * 2 * Constants::TorsoHeight;
|
pos.z() += mPhysics->getRenderingHalfExtents(caster).z() * 2 * Constants::TorsoHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWorld()->isUnderwater(
|
// Actors can't cast target spells underwater
|
||||||
caster.getCell(), pos)) // Underwater casting not possible
|
if (caster.getClass().isActor() && MWBase::Environment::get().getWorld()->isUnderwater(caster.getCell(), pos))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
osg::Quat orient;
|
osg::Quat orient;
|
||||||
@ -564,15 +564,19 @@ namespace MWWorld
|
|||||||
for (const auto& sound : magicBoltState.mSounds)
|
for (const auto& sound : magicBoltState.mSounds)
|
||||||
sound->setPosition(pos);
|
sound->setPosition(pos);
|
||||||
|
|
||||||
if (projectile->isActive())
|
const Ptr caster = magicBoltState.getCaster();
|
||||||
|
|
||||||
|
const MWBase::World& world = *MWBase::Environment::get().getWorld();
|
||||||
|
const bool active = projectile->isActive();
|
||||||
|
if (active && !world.isUnderwater(caster.getCell(), pos))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto target = projectile->getTarget();
|
const Ptr target = !active ? projectile->getTarget() : Ptr();
|
||||||
const auto caster = magicBoltState.getCaster();
|
|
||||||
assert(target != caster);
|
assert(target != caster);
|
||||||
|
|
||||||
MWMechanics::CastSpell cast(caster, target);
|
MWMechanics::CastSpell cast(caster, target);
|
||||||
cast.mHitPosition = Misc::Convert::toOsg(projectile->getHitPosition());
|
cast.mHitPosition = !active ? Misc::Convert::toOsg(projectile->getHitPosition()) : pos;
|
||||||
cast.mId = magicBoltState.mSpellId;
|
cast.mId = magicBoltState.mSpellId;
|
||||||
cast.mSourceName = magicBoltState.mSourceName;
|
cast.mSourceName = magicBoltState.mSourceName;
|
||||||
cast.mItem = magicBoltState.mItem;
|
cast.mItem = magicBoltState.mItem;
|
||||||
|
@ -3047,27 +3047,30 @@ namespace MWWorld
|
|||||||
// TODO: as a better solutuon we should handle projectiles during physics update, not during world update.
|
// 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;
|
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
|
// For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit
|
||||||
// result.
|
// result.
|
||||||
std::vector<MWWorld::Ptr> targetActors;
|
std::vector<MWWorld::Ptr> targetActors;
|
||||||
if (!actor.isEmpty() && actor.getClass().isActor() && actor != MWMechanics::getPlayer())
|
if (!actor.isEmpty() && actor.getClass().isActor() && actor != MWMechanics::getPlayer())
|
||||||
actor.getClass().getCreatureStats(actor).getAiSequence().getCombatTargets(targetActors);
|
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(
|
MWPhysics::RayCastingResult result = mPhysics->castRay(
|
||||||
sourcePos, worldPos, { actor }, targetActors, 0xff, MWPhysics::CollisionType_Projectile);
|
sourcePos, worldPos, { actor }, targetActors, 0xff, MWPhysics::CollisionType_Projectile);
|
||||||
|
|
||||||
if (result.mHit)
|
if (result.mHit)
|
||||||
|
{
|
||||||
MWMechanics::projectileHit(actor, result.mHitObject, bow, projectile, result.mHitPos, attackStrength);
|
MWMechanics::projectileHit(actor, result.mHitObject, bow, projectile, result.mHitPos, attackStrength);
|
||||||
else
|
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);
|
mProjectileManager->launchProjectile(actor, projectile, worldPos, orient, bow, speed, attackStrength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user