mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-03 18:15:35 +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
|
// 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,7 +29,12 @@ 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
|
||||||
|
{
|
||||||
|
|
||||||
|
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) : "";
|
std::string enchantmentName = !object.isEmpty() ? object.getClass().getEnchantment(object) : "";
|
||||||
if (!enchantmentName.empty())
|
if (!enchantmentName.empty())
|
||||||
|
@ -40,18 +45,13 @@ bool applyEnchantment (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim,
|
||||||
{
|
{
|
||||||
MWMechanics::CastSpell cast(attacker, victim);
|
MWMechanics::CastSpell cast(attacker, victim);
|
||||||
cast.mHitPosition = hitPosition;
|
cast.mHitPosition = hitPosition;
|
||||||
cast.cast(object);
|
cast.cast(object, false);
|
||||||
return true;
|
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)
|
||||||
{
|
{
|
||||||
if (!blocker.getClass().hasInventoryStore(blocker))
|
if (!blocker.getClass().hasInventoryStore(blocker))
|
||||||
|
@ -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,6 +754,8 @@ namespace MWMechanics
|
||||||
inflict(mTarget, mCaster, enchantment->mEffects, ESM::RT_Touch);
|
inflict(mTarget, mCaster, enchantment->mEffects, ESM::RT_Touch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (launchProjectile)
|
||||||
|
{
|
||||||
std::string projectileModel;
|
std::string projectileModel;
|
||||||
std::string sound;
|
std::string sound;
|
||||||
float speed = 0;
|
float speed = 0;
|
||||||
|
@ -763,6 +765,9 @@ namespace MWMechanics
|
||||||
false, enchantment->mEffects, mCaster, mSourceName,
|
false, enchantment->mEffects, mCaster, mSourceName,
|
||||||
// Not needed, enchantments can only be cast by actors
|
// Not needed, enchantments can only be cast by actors
|
||||||
osg::Vec3f(1,0,0));
|
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…
Reference in a new issue