Directly apply On Target 'When Strikes' enchantments instead of launching a projectile (Fixes #3212)

move
scrawl 9 years ago
parent 5cdee454ef
commit d05603c7fe

@ -306,18 +306,7 @@ namespace MWClass
} }
// Apply "On hit" enchanted weapons // Apply "On hit" enchanted weapons
std::string enchantmentName = !weapon.isEmpty() ? weapon.getClass().getEnchantment(weapon) : ""; MWMechanics::applyOnStrikeEnchantment(ptr, victim, weapon, hitPosition);
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);
}
}
} }
else if (isBipedal(ptr)) else if (isBipedal(ptr))
{ {

@ -637,18 +637,7 @@ namespace MWClass
damage *= store.find("fCombatKODamageMult")->getFloat(); damage *= store.find("fCombatKODamageMult")->getFloat();
// Apply "On hit" enchanted weapons // Apply "On hit" enchanted weapons
std::string enchantmentName = !weapon.isEmpty() ? weapon.getClass().getEnchantment(weapon) : ""; MWMechanics::applyOnStrikeEnchantment(ptr, victim, weapon, hitPosition);
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::applyElementalShields(ptr, victim); 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)); 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( std::string enchantmentName = !object.isEmpty() ? object.getClass().getEnchantment(object) : "";
enchantmentName); if (!enchantmentName.empty())
if (enchantment->mData.mType == ESM::Enchantment::WhenStrikes)
{ {
MWMechanics::CastSpell cast(attacker, victim); const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(
cast.mHitPosition = hitPosition; enchantmentName);
cast.cast(object); if (enchantment->mData.mType == ESM::Enchantment::WhenStrikes)
return true; {
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) 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(); damage *= gmst.find("fCombatKODamageMult")->getFloat();
// Apply "On hit" effect of the weapon // Apply "On hit" effect of the weapon
bool appliedEnchantment = applyEnchantment(attacker, victim, weapon, hitPosition); bool appliedEnchantment = applyOnStrikeEnchantment(attacker, victim, weapon, hitPosition);
if (weapon != projectile) if (weapon != projectile)
appliedEnchantment = applyEnchantment(attacker, victim, projectile, hitPosition); appliedEnchantment = applyOnStrikeEnchantment(attacker, victim, projectile, hitPosition);
if (damage > 0) if (damage > 0)
MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition); MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition);

@ -6,6 +6,8 @@
namespace MWMechanics 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? /// @return can we block the attack?
bool blockMeleeAttack (const MWWorld::Ptr& attacker, const MWWorld::Ptr& blocker, const MWWorld::Ptr& weapon, float damage, float attackStrength); 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"); 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); std::string enchantmentName = item.getClass().getEnchantment(item);
if (enchantmentName.empty()) if (enchantmentName.empty())
@ -754,15 +754,20 @@ namespace MWMechanics
inflict(mTarget, mCaster, enchantment->mEffects, ESM::RT_Touch); inflict(mTarget, mCaster, enchantment->mEffects, ESM::RT_Touch);
} }
std::string projectileModel; if (launchProjectile)
std::string sound; {
float speed = 0; std::string projectileModel;
getProjectileInfo(enchantment->mEffects, projectileModel, sound, speed); std::string sound;
if (!projectileModel.empty()) float speed = 0;
MWBase::Environment::get().getWorld()->launchMagicBolt(projectileModel, sound, mId, speed, getProjectileInfo(enchantment->mEffects, projectileModel, sound, speed);
false, enchantment->mEffects, mCaster, mSourceName, if (!projectileModel.empty())
// Not needed, enchantments can only be cast by actors MWBase::Environment::get().getWorld()->launchMagicBolt(projectileModel, sound, mId, speed,
osg::Vec3f(1,0,0)); 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; return true;
} }

@ -81,7 +81,8 @@ namespace MWMechanics
bool cast (const ESM::Spell* spell); bool cast (const ESM::Spell* spell);
/// @note mCaster must be an actor /// @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 /// @note mCaster must be an NPC
bool cast (const ESM::Ingredient* ingredient); bool cast (const ESM::Ingredient* ingredient);

Loading…
Cancel
Save