Don't play blood effects for resisted hits

pull/55/head
Allofich 8 years ago
parent fa11dad525
commit bce0166931

@ -264,7 +264,7 @@ namespace MWClass
if(Misc::Rng::roll0to99() >= hitchance) if(Misc::Rng::roll0to99() >= hitchance)
{ {
victim.getClass().onHit(victim, 0.0f, false, MWWorld::Ptr(), ptr, false); victim.getClass().onHit(victim, 0.0f, false, MWWorld::Ptr(), ptr, osg::Vec3f(), false);
MWMechanics::reduceWeaponCondition(0.f, false, weapon, ptr); MWMechanics::reduceWeaponCondition(0.f, false, weapon, ptr);
return; return;
} }
@ -318,15 +318,12 @@ namespace MWClass
if (MWMechanics::blockMeleeAttack(ptr, victim, weapon, damage, attackStrength)) if (MWMechanics::blockMeleeAttack(ptr, victim, weapon, damage, attackStrength))
damage = 0; damage = 0;
if (damage > 0)
MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition);
MWMechanics::diseaseContact(victim, ptr); MWMechanics::diseaseContact(victim, ptr);
victim.getClass().onHit(victim, damage, healthdmg, weapon, ptr, true); victim.getClass().onHit(victim, damage, healthdmg, weapon, ptr, hitPosition, true);
} }
void Creature::onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, bool successful) const void Creature::onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, osg::Vec3f hitPosition, bool successful) const
{ {
// NOTE: 'object' and/or 'attacker' may be empty. // NOTE: 'object' and/or 'attacker' may be empty.
@ -342,10 +339,10 @@ namespace MWClass
setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker); setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
} }
if(!object.isEmpty()) if (!object.isEmpty())
getCreatureStats(ptr).setLastHitAttemptObject(object.getCellRef().getRefId()); getCreatureStats(ptr).setLastHitAttemptObject(object.getCellRef().getRefId());
if(setOnPcHitMe && !attacker.isEmpty() && attacker == MWMechanics::getPlayer()) if (setOnPcHitMe && !attacker.isEmpty() && attacker == MWMechanics::getPlayer())
{ {
const std::string &script = ptr.get<ESM::Creature>()->mBase->mScript; const std::string &script = ptr.get<ESM::Creature>()->mBase->mScript;
/* Set the OnPCHitMe script variable. The script is responsible for clearing it. */ /* Set the OnPCHitMe script variable. The script is responsible for clearing it. */
@ -353,14 +350,14 @@ namespace MWClass
ptr.getRefData().getLocals().setVarByInt(script, "onpchitme", 1); ptr.getRefData().getLocals().setVarByInt(script, "onpchitme", 1);
} }
if(!successful) if (!successful)
{ {
// Missed // Missed
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, "miss", 1.0f, 1.0f); MWBase::Environment::get().getSoundManager()->playSound3D(ptr, "miss", 1.0f, 1.0f);
return; return;
} }
if(!object.isEmpty()) if (!object.isEmpty())
getCreatureStats(ptr).setLastHitObject(object.getCellRef().getRefId()); getCreatureStats(ptr).setLastHitObject(object.getCellRef().getRefId());
if (damage > 0.0f && !object.isEmpty()) if (damage > 0.0f && !object.isEmpty())
@ -391,7 +388,10 @@ namespace MWClass
if(ishealth) if(ishealth)
{ {
if (!attacker.isEmpty()) if (!attacker.isEmpty())
{
damage = scaleDamage(damage, attacker, ptr); damage = scaleDamage(damage, attacker, ptr);
MWBase::Environment::get().getWorld()->spawnBloodEffect(ptr, hitPosition);
}
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, "Health Damage", 1.0f, 1.0f); MWBase::Environment::get().getSoundManager()->playSound3D(ptr, "Health Damage", 1.0f, 1.0f);

@ -58,7 +58,7 @@ namespace MWClass
virtual void hit(const MWWorld::Ptr& ptr, float attackStrength, int type) const; virtual void hit(const MWWorld::Ptr& ptr, float attackStrength, int type) const;
virtual void onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, bool successful) const; virtual void onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, osg::Vec3f hitPosition, bool successful) const;
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr, virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor) const; const MWWorld::Ptr& actor) const;

@ -591,7 +591,7 @@ namespace MWClass
if (Misc::Rng::roll0to99() >= hitchance) if (Misc::Rng::roll0to99() >= hitchance)
{ {
othercls.onHit(victim, 0.0f, false, weapon, ptr, false); othercls.onHit(victim, 0.0f, false, weapon, ptr, osg::Vec3f(), false);
MWMechanics::reduceWeaponCondition(0.f, false, weapon, ptr); MWMechanics::reduceWeaponCondition(0.f, false, weapon, ptr);
return; return;
} }
@ -646,15 +646,12 @@ namespace MWClass
if (MWMechanics::blockMeleeAttack(ptr, victim, weapon, damage, attackStrength)) if (MWMechanics::blockMeleeAttack(ptr, victim, weapon, damage, attackStrength))
damage = 0; damage = 0;
if (healthdmg && damage > 0)
MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition);
MWMechanics::diseaseContact(victim, ptr); MWMechanics::diseaseContact(victim, ptr);
othercls.onHit(victim, damage, healthdmg, weapon, ptr, true); othercls.onHit(victim, damage, healthdmg, weapon, ptr, hitPosition, true);
} }
void Npc::onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, bool successful) const void Npc::onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, osg::Vec3f hitPosition, bool successful) const
{ {
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
@ -671,10 +668,10 @@ namespace MWClass
setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker); setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
} }
if(!object.isEmpty()) if (!object.isEmpty())
getCreatureStats(ptr).setLastHitAttemptObject(object.getCellRef().getRefId()); getCreatureStats(ptr).setLastHitAttemptObject(object.getCellRef().getRefId());
if(setOnPcHitMe && !attacker.isEmpty() && attacker == MWMechanics::getPlayer()) if (setOnPcHitMe && !attacker.isEmpty() && attacker == MWMechanics::getPlayer())
{ {
const std::string &script = ptr.getClass().getScript(ptr); const std::string &script = ptr.getClass().getScript(ptr);
/* Set the OnPCHitMe script variable. The script is responsible for clearing it. */ /* Set the OnPCHitMe script variable. The script is responsible for clearing it. */
@ -682,14 +679,14 @@ namespace MWClass
ptr.getRefData().getLocals().setVarByInt(script, "onpchitme", 1); ptr.getRefData().getLocals().setVarByInt(script, "onpchitme", 1);
} }
if(!successful) if (!successful)
{ {
// Missed // Missed
sndMgr->playSound3D(ptr, "miss", 1.0f, 1.0f); sndMgr->playSound3D(ptr, "miss", 1.0f, 1.0f);
return; return;
} }
if(!object.isEmpty()) if (!object.isEmpty())
getCreatureStats(ptr).setLastHitObject(object.getCellRef().getRefId()); getCreatureStats(ptr).setLastHitObject(object.getCellRef().getRefId());
@ -699,7 +696,7 @@ namespace MWClass
if (damage < 0.001f) if (damage < 0.001f)
damage = 0; damage = 0;
if(damage > 0.0f && !attacker.isEmpty()) if (damage > 0.0f && !attacker.isEmpty())
{ {
// 'ptr' is losing health. Play a 'hit' voiced dialog entry if not already saying // 'ptr' is losing health. Play a 'hit' voiced dialog entry if not already saying
// something, alert the character controller, scripts, etc. // something, alert the character controller, scripts, etc.
@ -725,7 +722,7 @@ namespace MWClass
else else
getCreatureStats(ptr).setHitRecovery(true); // Is this supposed to always occur? getCreatureStats(ptr).setHitRecovery(true); // Is this supposed to always occur?
if(damage > 0 && ishealth) if (damage > 0 && ishealth)
{ {
// Hit percentages: // Hit percentages:
// cuirass = 30% // cuirass = 30%
@ -787,16 +784,18 @@ namespace MWClass
} }
} }
if(ishealth) if (ishealth)
{ {
if (!attacker.isEmpty()) if (!attacker.isEmpty())
damage = scaleDamage(damage, attacker, ptr); damage = scaleDamage(damage, attacker, ptr);
if(damage > 0.0f) if (damage > 0.0f)
{ {
sndMgr->playSound3D(ptr, "Health Damage", 1.0f, 1.0f); sndMgr->playSound3D(ptr, "Health Damage", 1.0f, 1.0f);
if (ptr == MWMechanics::getPlayer()) if (ptr == MWMechanics::getPlayer())
MWBase::Environment::get().getWindowManager()->activateHitOverlay(); MWBase::Environment::get().getWindowManager()->activateHitOverlay();
if (!attacker.isEmpty())
MWBase::Environment::get().getWorld()->spawnBloodEffect(ptr, hitPosition);
} }
MWMechanics::DynamicStat<float> health(getCreatureStats(ptr).getHealth()); MWMechanics::DynamicStat<float> health(getCreatureStats(ptr).getHealth());
health.setCurrent(health.getCurrent() - damage); health.setCurrent(health.getCurrent() - damage);

@ -73,7 +73,7 @@ namespace MWClass
virtual void hit(const MWWorld::Ptr& ptr, float attackStrength, int type) const; virtual void hit(const MWWorld::Ptr& ptr, float attackStrength, int type) const;
virtual void onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, bool successful) const; virtual void onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, osg::Vec3f hitPosition, bool successful) const;
virtual void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector<std::string>& models) const; virtual void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector<std::string>& models) const;
///< Get a list of models to preload that this object may use (directly or indirectly). default implementation: list getModel(). ///< Get a list of models to preload that this object may use (directly or indirectly). default implementation: list getModel().

@ -1771,7 +1771,7 @@ void CharacterController::update(float duration)
float realHealthLost = static_cast<float>(healthLost * (1.0f - 0.25f * fatigueTerm)); float realHealthLost = static_cast<float>(healthLost * (1.0f - 0.25f * fatigueTerm));
health.setCurrent(health.getCurrent() - realHealthLost); health.setCurrent(health.getCurrent() - realHealthLost);
cls.getCreatureStats(mPtr).setHealth(health); cls.getCreatureStats(mPtr).setHealth(health);
cls.onHit(mPtr, realHealthLost, true, MWWorld::Ptr(), MWWorld::Ptr(), true); cls.onHit(mPtr, realHealthLost, true, MWWorld::Ptr(), MWWorld::Ptr(), osg::Vec3f(), true);
const int acrobaticsSkill = cls.getSkill(mPtr, ESM::Skill::Acrobatics); const int acrobaticsSkill = cls.getSkill(mPtr, ESM::Skill::Acrobatics);
if (healthLost > (acrobaticsSkill * fatigueTerm)) if (healthLost > (acrobaticsSkill * fatigueTerm))

@ -190,7 +190,7 @@ namespace MWMechanics
if (Misc::Rng::roll0to99() >= getHitChance(attacker, victim, skillValue)) if (Misc::Rng::roll0to99() >= getHitChance(attacker, victim, skillValue))
{ {
victim.getClass().onHit(victim, 0.0f, false, projectile, attacker, false); victim.getClass().onHit(victim, 0.0f, false, projectile, attacker, osg::Vec3f(), false);
MWMechanics::reduceWeaponCondition(0.f, false, weapon, attacker); MWMechanics::reduceWeaponCondition(0.f, false, weapon, attacker);
return; return;
} }
@ -218,9 +218,6 @@ namespace MWMechanics
if (weapon != projectile) if (weapon != projectile)
appliedEnchantment = applyOnStrikeEnchantment(attacker, victim, projectile, hitPosition); appliedEnchantment = applyOnStrikeEnchantment(attacker, victim, projectile, hitPosition);
if (damage > 0)
MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition);
// Non-enchanted arrows shot at enemies have a chance to turn up in their inventory // Non-enchanted arrows shot at enemies have a chance to turn up in their inventory
if (victim != getPlayer() if (victim != getPlayer()
&& !appliedEnchantment) && !appliedEnchantment)
@ -230,7 +227,7 @@ namespace MWMechanics
victim.getClass().getContainerStore(victim).add(projectile, 1, victim); victim.getClass().getContainerStore(victim).add(projectile, 1, victim);
} }
victim.getClass().onHit(victim, damage, true, projectile, attacker, true); victim.getClass().onHit(victim, damage, true, projectile, attacker, hitPosition, true);
} }
float getHitChance(const MWWorld::Ptr &attacker, const MWWorld::Ptr &victim, int skillValue) float getHitChance(const MWWorld::Ptr &attacker, const MWWorld::Ptr &victim, int skillValue)

@ -569,7 +569,7 @@ namespace MWMechanics
// Notify the target actor they've been hit // Notify the target actor they've been hit
if (anyHarmfulEffect && target.getClass().isActor() && target != caster && !caster.isEmpty() && caster.getClass().isActor()) if (anyHarmfulEffect && target.getClass().isActor() && target != caster && !caster.isEmpty() && caster.getClass().isActor())
target.getClass().onHit(target, 0.f, true, MWWorld::Ptr(), caster, true); target.getClass().onHit(target, 0.0f, true, MWWorld::Ptr(), caster, osg::Vec3f(), true);
} }
bool CastSpell::applyInstantEffect(const MWWorld::Ptr &target, const MWWorld::Ptr &caster, const MWMechanics::EffectKey& effect, float magnitude) bool CastSpell::applyInstantEffect(const MWWorld::Ptr &target, const MWWorld::Ptr &caster, const MWMechanics::EffectKey& effect, float magnitude)

@ -98,7 +98,7 @@ namespace MWWorld
throw std::runtime_error("class cannot block"); throw std::runtime_error("class cannot block");
} }
void Class::onHit(const Ptr& ptr, float damage, bool ishealth, const Ptr& object, const Ptr& attacker, bool successful) const void Class::onHit(const Ptr& ptr, float damage, bool ishealth, const Ptr& object, const Ptr& attacker, osg::Vec3f hitPosition, bool successful) const
{ {
throw std::runtime_error("class cannot be hit"); throw std::runtime_error("class cannot be hit");
} }

@ -120,7 +120,7 @@ namespace MWWorld
/// enums. ignored for creature attacks. /// enums. ignored for creature attacks.
/// (default implementation: throw an exception) /// (default implementation: throw an exception)
virtual void onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, bool successful) const; virtual void onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, osg::Vec3f hitPosition, bool successful) const;
///< Alerts \a ptr that it's being hit for \a damage points to health if \a ishealth is ///< 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 /// 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 /// actor responsible for the attack, and \a successful specifies if the hit is

Loading…
Cancel
Save