mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 20:19:57 +00:00
Check for impact immediately when launch a projectile (bug #3059)
This commit is contained in:
parent
78d9787212
commit
3d4f5536d2
5 changed files with 38 additions and 10 deletions
|
@ -16,6 +16,7 @@
|
|||
Bug #2872: Tab completion in console doesn't work with explicit reference
|
||||
Bug #2971: Compiler did not reject lines with naked expressions beginning with x.y
|
||||
Bug #3049: Drain and Fortify effects are not properly applied on health, magicka and fatigue
|
||||
Bug #3059: Unable to hit with marksman weapons when too close to an enemy
|
||||
Bug #3072: Fatal error on AddItem <item> that has a script containing Equip <item>
|
||||
Bug #3249: Fixed revert function not updating views properly
|
||||
Bug #3374: Touch spells not hitting kwama foragers
|
||||
|
|
|
@ -490,8 +490,8 @@ namespace MWBase
|
|||
virtual void castSpell (const MWWorld::Ptr& actor, bool manualSpell=false) = 0;
|
||||
|
||||
virtual void launchMagicBolt (const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection) = 0;
|
||||
virtual void launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile,
|
||||
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength) = 0;
|
||||
virtual void launchProjectile (MWWorld::Ptr& actor, MWWorld::Ptr& projectile,
|
||||
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr& bow, float speed, float attackStrength) = 0;
|
||||
|
||||
virtual void applyLoopingParticles(const MWWorld::Ptr& ptr) = 0;
|
||||
|
||||
|
|
|
@ -123,7 +123,8 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor, float attackStrength)
|
|||
float fThrownWeaponMaxSpeed = gmst.find("fThrownWeaponMaxSpeed")->getFloat();
|
||||
float speed = fThrownWeaponMinSpeed + (fThrownWeaponMaxSpeed - fThrownWeaponMinSpeed) * attackStrength;
|
||||
|
||||
MWBase::Environment::get().getWorld()->launchProjectile(actor, *weapon, launchPos, orient, *weapon, speed, attackStrength);
|
||||
MWWorld::Ptr weaponPtr = *weapon;
|
||||
MWBase::Environment::get().getWorld()->launchProjectile(actor, weaponPtr, launchPos, orient, weaponPtr, speed, attackStrength);
|
||||
|
||||
showWeapon(false);
|
||||
|
||||
|
@ -149,9 +150,11 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor, float attackStrength)
|
|||
float fProjectileMaxSpeed = gmst.find("fProjectileMaxSpeed")->getFloat();
|
||||
float speed = fProjectileMinSpeed + (fProjectileMaxSpeed - fProjectileMinSpeed) * attackStrength;
|
||||
|
||||
MWBase::Environment::get().getWorld()->launchProjectile(actor, *ammo, launchPos, orient, *weapon, speed, attackStrength);
|
||||
MWWorld::Ptr weaponPtr = *weapon;
|
||||
MWWorld::Ptr ammoPtr = *ammo;
|
||||
MWBase::Environment::get().getWorld()->launchProjectile(actor, ammoPtr, launchPos, orient, weaponPtr, speed, attackStrength);
|
||||
|
||||
inv.remove(*ammo, 1, actor);
|
||||
inv.remove(ammoPtr, 1, actor);
|
||||
mAmmunition.reset();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2892,10 +2892,34 @@ namespace MWWorld
|
|||
}
|
||||
}
|
||||
|
||||
void World::launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile,
|
||||
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength)
|
||||
void World::launchProjectile (MWWorld::Ptr& actor, MWWorld::Ptr& projectile,
|
||||
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr& bow, float speed, float attackStrength)
|
||||
{
|
||||
mProjectileManager->launchProjectile(actor, projectile, worldPos, orient, bow, speed, attackStrength);
|
||||
// An initial position of projectile can be outside shooter's collision box, so any object between shooter and launch position will be ignored.
|
||||
// To avoid this issue, we should check for impact immediately before launch the projectile.
|
||||
// So we cast a 1-yard-length ray from shooter to launch position and check if there are collisions in this area.
|
||||
// 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 = MWBase::Environment::get().getWorld()->isUnderwater(MWMechanics::getPlayer().getCell(), worldPos);
|
||||
if (underwater)
|
||||
{
|
||||
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<MWWorld::Ptr> 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
|
||||
MWPhysics::PhysicsSystem::RayResult 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);
|
||||
}
|
||||
|
||||
void World::launchMagicBolt (const std::string &spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection)
|
||||
|
|
|
@ -607,8 +607,8 @@ namespace MWWorld
|
|||
void castSpell (const MWWorld::Ptr& actor, bool manualSpell=false) override;
|
||||
|
||||
void launchMagicBolt (const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection) override;
|
||||
void launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile,
|
||||
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength) override;
|
||||
void launchProjectile (MWWorld::Ptr& actor, MWWorld::Ptr& projectile,
|
||||
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr& bow, float speed, float attackStrength) override;
|
||||
|
||||
void applyLoopingParticles(const MWWorld::Ptr& ptr) override;
|
||||
|
||||
|
|
Loading…
Reference in a new issue