mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-03 13:45:34 +00:00
Directly apply On Target 'When Strikes' enchantments instead of launching a projectile (Fixes #3212)
This commit is contained in:
parent
5cdee454ef
commit
d05603c7fe
6 changed files with 41 additions and 55 deletions
|
@ -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,29 +29,29 @@ 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)
|
||||
{
|
||||
std::string enchantmentName = !object.isEmpty() ? object.getClass().getEnchantment(object) : "";
|
||||
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(attacker, victim);
|
||||
cast.mHitPosition = hitPosition;
|
||||
cast.cast(object);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
|
||||
bool applyOnStrikeEnchantment (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, const MWWorld::Ptr& object, const osg::Vec3f& hitPosition)
|
||||
{
|
||||
std::string enchantmentName = !object.isEmpty() ? object.getClass().getEnchantment(object) : "";
|
||||
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(attacker, victim);
|
||||
cast.mHitPosition = hitPosition;
|
||||
cast.cast(object, false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool blockMeleeAttack(const MWWorld::Ptr &attacker, const MWWorld::Ptr &blocker, const MWWorld::Ptr &weapon, float damage, float attackStrength)
|
||||
{
|
||||
if (!blocker.getClass().hasInventoryStore(blocker))
|
||||
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue