Commit d05603c7 authored by scrawl's avatar scrawl

Directly apply On Target 'When Strikes' enchantments instead of launching a...

Directly apply On Target 'When Strikes' enchantments instead of launching a projectile (Fixes #3212)
parent 5cdee454
......@@ -306,18 +306,7 @@ namespace MWClass
}
// Apply "On hit" enchanted weapons
std::string enchantmentName = !weapon.isEmpty() ? weapon.getClass().getEnchantment(weapon) : "";
if (!enchantmentName.empty())
{
const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(
enchantmentName);
if (enchantment->mData.mType == ESM::Enchantment::WhenStrikes)
{
MWMechanics::CastSpell cast(ptr, victim);
cast.mHitPosition = hitPosition;
cast.cast(weapon);
}
}
MWMechanics::applyOnStrikeEnchantment(ptr, victim, weapon, hitPosition);
}
else if (isBipedal(ptr))
{
......
......@@ -637,18 +637,7 @@ namespace MWClass
damage *= store.find("fCombatKODamageMult")->getFloat();
// Apply "On hit" enchanted weapons
std::string enchantmentName = !weapon.isEmpty() ? weapon.getClass().getEnchantment(weapon) : "";
if (!enchantmentName.empty())
{
const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(
enchantmentName);
if (enchantment->mData.mType == ESM::Enchantment::WhenStrikes)
{
MWMechanics::CastSpell cast(ptr, victim);
cast.mHitPosition = hitPosition;
cast.cast(weapon);
}
}
MWMechanics::applyOnStrikeEnchantment(ptr, victim, weapon, hitPosition);
MWMechanics::applyElementalShields(ptr, victim);
......
......@@ -29,28 +29,28 @@ float signedAngleRadians (const osg::Vec3f& v1, const osg::Vec3f& v2, const osg:
return std::atan2((normal * (v1 ^ v2)), (v1 * v2));
}
bool applyEnchantment (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, const MWWorld::Ptr& object, const osg::Vec3f& hitPosition)
}
namespace MWMechanics
{
std::string enchantmentName = !object.isEmpty() ? object.getClass().getEnchantment(object) : "";
if (!enchantmentName.empty())
bool applyOnStrikeEnchantment (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, const MWWorld::Ptr& object, const osg::Vec3f& hitPosition)
{
const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(
enchantmentName);
if (enchantment->mData.mType == ESM::Enchantment::WhenStrikes)
std::string enchantmentName = !object.isEmpty() ? object.getClass().getEnchantment(object) : "";
if (!enchantmentName.empty())
{
MWMechanics::CastSpell cast(attacker, victim);
cast.mHitPosition = hitPosition;
cast.cast(object);
return true;
const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(
enchantmentName);
if (enchantment->mData.mType == ESM::Enchantment::WhenStrikes)
{
MWMechanics::CastSpell cast(attacker, victim);
cast.mHitPosition = hitPosition;
cast.cast(object, false);
return true;
}
}
return false;
}
return false;
}
}
namespace MWMechanics
{
bool blockMeleeAttack(const MWWorld::Ptr &attacker, const MWWorld::Ptr &blocker, const MWWorld::Ptr &weapon, float damage, float attackStrength)
{
......@@ -215,9 +215,9 @@ namespace MWMechanics
damage *= gmst.find("fCombatKODamageMult")->getFloat();
// Apply "On hit" effect of the weapon
bool appliedEnchantment = applyEnchantment(attacker, victim, weapon, hitPosition);
bool appliedEnchantment = applyOnStrikeEnchantment(attacker, victim, weapon, hitPosition);
if (weapon != projectile)
appliedEnchantment = applyEnchantment(attacker, victim, projectile, hitPosition);
appliedEnchantment = applyOnStrikeEnchantment(attacker, victim, projectile, hitPosition);
if (damage > 0)
MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition);
......
......@@ -6,6 +6,8 @@
namespace MWMechanics
{
bool applyOnStrikeEnchantment(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, const MWWorld::Ptr& object, const osg::Vec3f& hitPosition);
/// @return can we block the attack?
bool blockMeleeAttack (const MWWorld::Ptr& attacker, const MWWorld::Ptr& blocker, const MWWorld::Ptr& weapon, float damage, float attackStrength);
......
......@@ -687,7 +687,7 @@ namespace MWMechanics
throw std::runtime_error("ID type cannot be casted");
}
bool CastSpell::cast(const MWWorld::Ptr &item)
bool CastSpell::cast(const MWWorld::Ptr &item, bool launchProjectile)
{
std::string enchantmentName = item.getClass().getEnchantment(item);
if (enchantmentName.empty())
......@@ -754,15 +754,20 @@ namespace MWMechanics
inflict(mTarget, mCaster, enchantment->mEffects, ESM::RT_Touch);
}
std::string projectileModel;
std::string sound;
float speed = 0;
getProjectileInfo(enchantment->mEffects, projectileModel, sound, speed);
if (!projectileModel.empty())
MWBase::Environment::get().getWorld()->launchMagicBolt(projectileModel, sound, mId, speed,
false, enchantment->mEffects, mCaster, mSourceName,
// Not needed, enchantments can only be cast by actors
osg::Vec3f(1,0,0));
if (launchProjectile)
{
std::string projectileModel;
std::string sound;
float speed = 0;
getProjectileInfo(enchantment->mEffects, projectileModel, sound, speed);
if (!projectileModel.empty())
MWBase::Environment::get().getWorld()->launchMagicBolt(projectileModel, sound, mId, speed,
false, enchantment->mEffects, mCaster, mSourceName,
// Not needed, enchantments can only be cast by actors
osg::Vec3f(1,0,0));
}
else if (!mTarget.isEmpty())
inflict(mTarget, mCaster, enchantment->mEffects, ESM::RT_Target);
return true;
}
......
......@@ -81,7 +81,8 @@ namespace MWMechanics
bool cast (const ESM::Spell* spell);
/// @note mCaster must be an actor
bool cast (const MWWorld::Ptr& item);
/// @param launchProjectile If set to false, "on target" effects are directly applied instead of being launched as projectile originating from the caster.
bool cast (const MWWorld::Ptr& item, bool launchProjectile=true);
/// @note mCaster must be an NPC
bool cast (const ESM::Ingredient* ingredient);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment