mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-24 18:39:59 +00:00
Check for impact immediately when launch a projectile (bug #3059)
This commit is contained in:
parent
78d9787212
commit
3d4f5536d2
@ -16,6 +16,7 @@
|
|||||||
Bug #2872: Tab completion in console doesn't work with explicit reference
|
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 #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 #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 #3072: Fatal error on AddItem <item> that has a script containing Equip <item>
|
||||||
Bug #3249: Fixed revert function not updating views properly
|
Bug #3249: Fixed revert function not updating views properly
|
||||||
Bug #3374: Touch spells not hitting kwama foragers
|
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 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 launchMagicBolt (const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection) = 0;
|
||||||
virtual void launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile,
|
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;
|
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr& bow, float speed, float attackStrength) = 0;
|
||||||
|
|
||||||
virtual void applyLoopingParticles(const MWWorld::Ptr& ptr) = 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 fThrownWeaponMaxSpeed = gmst.find("fThrownWeaponMaxSpeed")->getFloat();
|
||||||
float speed = fThrownWeaponMinSpeed + (fThrownWeaponMaxSpeed - fThrownWeaponMinSpeed) * attackStrength;
|
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);
|
showWeapon(false);
|
||||||
|
|
||||||
@ -149,9 +150,11 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor, float attackStrength)
|
|||||||
float fProjectileMaxSpeed = gmst.find("fProjectileMaxSpeed")->getFloat();
|
float fProjectileMaxSpeed = gmst.find("fProjectileMaxSpeed")->getFloat();
|
||||||
float speed = fProjectileMinSpeed + (fProjectileMaxSpeed - fProjectileMinSpeed) * attackStrength;
|
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();
|
mAmmunition.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2892,10 +2892,34 @@ namespace MWWorld
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile,
|
void World::launchProjectile (MWWorld::Ptr& actor, MWWorld::Ptr& projectile,
|
||||||
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength)
|
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)
|
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 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 launchMagicBolt (const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection) override;
|
||||||
void launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile,
|
void launchProjectile (MWWorld::Ptr& actor, MWWorld::Ptr& projectile,
|
||||||
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength) override;
|
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr& bow, float speed, float attackStrength) override;
|
||||||
|
|
||||||
void applyLoopingParticles(const MWWorld::Ptr& ptr) override;
|
void applyLoopingParticles(const MWWorld::Ptr& ptr) override;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user