diff --git a/apps/openmw/mwbase/luamanager.hpp b/apps/openmw/mwbase/luamanager.hpp index e4b16ff725..6db85d77ca 100644 --- a/apps/openmw/mwbase/luamanager.hpp +++ b/apps/openmw/mwbase/luamanager.hpp @@ -61,7 +61,8 @@ namespace MWBase // TODO: notify LuaManager about other events // virtual void objectOnHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, - // const MWWorld::Ptr &attacker, const osg::Vec3f &hitPosition, bool successful) = 0; + // const MWWorld::Ptr &attacker, const osg::Vec3f &hitPosition, bool successful, + // DamageSourceType sourceType) = 0; struct InputEvent { diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 8b80b9336b..cbf5a3d63d 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -284,7 +284,8 @@ namespace MWClass if (!success) { - victim.getClass().onHit(victim, 0.0f, false, MWWorld::Ptr(), ptr, osg::Vec3f(), false); + victim.getClass().onHit( + victim, 0.0f, false, MWWorld::Ptr(), ptr, osg::Vec3f(), false, MWMechanics::DamageSourceType::Melee); MWMechanics::reduceWeaponCondition(0.f, false, weapon, ptr); return; } @@ -345,11 +346,13 @@ namespace MWClass MWMechanics::diseaseContact(victim, ptr); - victim.getClass().onHit(victim, damage, healthdmg, weapon, ptr, hitPosition, true); + victim.getClass().onHit( + victim, damage, healthdmg, weapon, ptr, hitPosition, true, MWMechanics::DamageSourceType::Melee); } void Creature::onHit(const MWWorld::Ptr& ptr, float damage, bool ishealth, const MWWorld::Ptr& object, - const MWWorld::Ptr& attacker, const osg::Vec3f& hitPosition, bool successful) const + const MWWorld::Ptr& attacker, const osg::Vec3f& hitPosition, bool successful, + const MWMechanics::DamageSourceType sourceType) const { MWMechanics::CreatureStats& stats = getCreatureStats(ptr); diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index bd7101e93d..b407852242 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -67,7 +67,8 @@ namespace MWClass const osg::Vec3f& hitPosition, bool success) const override; void onHit(const MWWorld::Ptr& ptr, float damage, bool ishealth, const MWWorld::Ptr& object, - const MWWorld::Ptr& attacker, const osg::Vec3f& hitPosition, bool successful) const override; + const MWWorld::Ptr& attacker, const osg::Vec3f& hitPosition, bool successful, + const MWMechanics::DamageSourceType sourceType) const override; std::unique_ptr activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const override; ///< Generate action for activation diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 0295d3600f..df074ec8bf 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -599,7 +599,8 @@ namespace MWClass float damage = 0.0f; if (!success) { - othercls.onHit(victim, damage, false, weapon, ptr, osg::Vec3f(), false); + othercls.onHit( + victim, damage, false, weapon, ptr, osg::Vec3f(), false, MWMechanics::DamageSourceType::Melee); MWMechanics::reduceWeaponCondition(damage, false, weapon, ptr); MWMechanics::resistNormalWeapon(victim, ptr, weapon, damage); return; @@ -672,11 +673,12 @@ namespace MWClass MWMechanics::diseaseContact(victim, ptr); - othercls.onHit(victim, damage, healthdmg, weapon, ptr, hitPosition, true); + othercls.onHit(victim, damage, healthdmg, weapon, ptr, hitPosition, true, MWMechanics::DamageSourceType::Melee); } void Npc::onHit(const MWWorld::Ptr& ptr, float damage, bool ishealth, const MWWorld::Ptr& object, - const MWWorld::Ptr& attacker, const osg::Vec3f& hitPosition, bool successful) const + const MWWorld::Ptr& attacker, const osg::Vec3f& hitPosition, bool successful, + const MWMechanics::DamageSourceType sourceType) const { MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); MWMechanics::CreatureStats& stats = getCreatureStats(ptr); diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index eb8cafc9d1..ca0d0ac95d 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -82,7 +82,8 @@ namespace MWClass const osg::Vec3f& hitPosition, bool success) const override; void onHit(const MWWorld::Ptr& ptr, float damage, bool ishealth, const MWWorld::Ptr& object, - const MWWorld::Ptr& attacker, const osg::Vec3f& hitPosition, bool successful) const override; + const MWWorld::Ptr& attacker, const osg::Vec3f& hitPosition, bool successful, + const MWMechanics::DamageSourceType sourceType) const override; void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector& models) const override; ///< Get a list of models to preload that this object may use (directly or indirectly). default implementation: diff --git a/apps/openmw/mwmechanics/combat.cpp b/apps/openmw/mwmechanics/combat.cpp index 3ce55f8f6c..3f17df96fd 100644 --- a/apps/openmw/mwmechanics/combat.cpp +++ b/apps/openmw/mwmechanics/combat.cpp @@ -231,7 +231,8 @@ namespace MWMechanics if (Misc::Rng::roll0to99(world->getPrng()) >= getHitChance(attacker, victim, skillValue)) { - victim.getClass().onHit(victim, damage, false, projectile, attacker, osg::Vec3f(), false); + victim.getClass().onHit(victim, damage, false, projectile, attacker, osg::Vec3f(), false, + MWMechanics::DamageSourceType::Ranged); MWMechanics::reduceWeaponCondition(damage, false, weapon, attacker); return; } @@ -287,7 +288,8 @@ namespace MWMechanics victim.getClass().getContainerStore(victim).add(projectile, 1); } - victim.getClass().onHit(victim, damage, true, projectile, attacker, hitPosition, true); + victim.getClass().onHit( + victim, damage, true, projectile, attacker, hitPosition, true, MWMechanics::DamageSourceType::Ranged); } } diff --git a/apps/openmw/mwmechanics/damagesourcetype.hpp b/apps/openmw/mwmechanics/damagesourcetype.hpp new file mode 100644 index 0000000000..e140a8106f --- /dev/null +++ b/apps/openmw/mwmechanics/damagesourcetype.hpp @@ -0,0 +1,15 @@ +#ifndef OPENMW_MWMECHANICS_DAMAGESOURCETYPE_H +#define OPENMW_MWMECHANICS_DAMAGESOURCETYPE_H + +namespace MWMechanics +{ + enum class DamageSourceType + { + Unspecified, + Melee, + Ranged, + Magical, + }; +} + +#endif diff --git a/apps/openmw/mwmechanics/spelleffects.cpp b/apps/openmw/mwmechanics/spelleffects.cpp index db9ec3e588..88d978733c 100644 --- a/apps/openmw/mwmechanics/spelleffects.cpp +++ b/apps/openmw/mwmechanics/spelleffects.cpp @@ -356,7 +356,8 @@ namespace // Notify the target actor they've been hit bool isHarmful = magicEffect->mData.mFlags & ESM::MagicEffect::Harmful; if (target.getClass().isActor() && target != caster && !caster.isEmpty() && isHarmful) - target.getClass().onHit(target, 0.0f, true, MWWorld::Ptr(), caster, osg::Vec3f(), true); + target.getClass().onHit( + target, 0.0f, true, MWWorld::Ptr(), caster, osg::Vec3f(), true, MWMechanics::DamageSourceType::Magical); // Apply resistances if (!(effect.mFlags & ESM::ActiveEffect::Flag_Ignore_Resistances)) { diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index e6080ce447..5fbda6d570 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -124,7 +124,7 @@ namespace MWWorld } void Class::onHit(const Ptr& ptr, float damage, bool ishealth, const Ptr& object, const Ptr& attacker, - const osg::Vec3f& hitPosition, bool successful) const + const osg::Vec3f& hitPosition, bool successful, const MWMechanics::DamageSourceType sourceType) const { throw std::runtime_error("class cannot be hit"); } diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 7b7e9135ba..87e70b3198 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -13,6 +13,8 @@ #include "ptr.hpp" #include "../mwmechanics/aisetting.hpp" +#include "../mwmechanics/damagesourcetype.hpp" + #include #include @@ -142,11 +144,12 @@ namespace MWWorld /// (default implementation: throw an exception) virtual void onHit(const MWWorld::Ptr& ptr, float damage, bool ishealth, const MWWorld::Ptr& object, - const MWWorld::Ptr& attacker, const osg::Vec3f& hitPosition, bool successful) const; + const MWWorld::Ptr& attacker, const osg::Vec3f& hitPosition, bool successful, + const MWMechanics::DamageSourceType sourceType) const; ///< Alerts \a ptr that it's being hit for \a damage points to health if \a ishealth is /// true (else fatigue) by \a object (sword, arrow, etc). \a attacker specifies the - /// actor responsible for the attack, and \a successful specifies if the hit is - /// successful or not. + /// actor responsible for the attack. \a successful specifies if the hit is + /// successful or not. \a sourceType classifies the damage source. virtual void block(const Ptr& ptr) const; ///< Play the appropriate sound for a blocked attack, depending on the currently equipped shield