mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-01 11:45:34 +00:00
Add hand-to-hand combat mechanics for bipedal creatures
You can now have a fistfight with vivec, if you so desire.
This commit is contained in:
parent
70d3bfc6ed
commit
e0d083f702
4 changed files with 44 additions and 30 deletions
|
@ -288,7 +288,7 @@ namespace MWClass
|
||||||
}
|
}
|
||||||
|
|
||||||
float damage = min + (max - min) * stats.getAttackStrength();
|
float damage = min + (max - min) * stats.getAttackStrength();
|
||||||
|
bool healthdmg = true;
|
||||||
if (!weapon.isEmpty())
|
if (!weapon.isEmpty())
|
||||||
{
|
{
|
||||||
const unsigned char *attack = NULL;
|
const unsigned char *attack = NULL;
|
||||||
|
@ -321,6 +321,10 @@ namespace MWClass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (isBipedal(ptr))
|
||||||
|
{
|
||||||
|
MWMechanics::getHandToHandDamage(ptr, victim, damage, healthdmg);
|
||||||
|
}
|
||||||
|
|
||||||
MWMechanics::applyElementalShields(ptr, victim);
|
MWMechanics::applyElementalShields(ptr, victim);
|
||||||
|
|
||||||
|
@ -332,7 +336,7 @@ namespace MWClass
|
||||||
|
|
||||||
MWMechanics::diseaseContact(victim, ptr);
|
MWMechanics::diseaseContact(victim, ptr);
|
||||||
|
|
||||||
victim.getClass().onHit(victim, damage, true, weapon, ptr, true);
|
victim.getClass().onHit(victim, damage, healthdmg, weapon, ptr, 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, bool successful) const
|
||||||
|
|
|
@ -577,34 +577,7 @@ namespace MWClass
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Note: MCP contains an option to include Strength in hand-to-hand damage
|
MWMechanics::getHandToHandDamage(ptr, victim, damage, healthdmg);
|
||||||
// calculations. Some mods recommend using it, so we may want to include am
|
|
||||||
// option for it.
|
|
||||||
float minstrike = store.find("fMinHandToHandMult")->getFloat();
|
|
||||||
float maxstrike = store.find("fMaxHandToHandMult")->getFloat();
|
|
||||||
damage = stats.getSkill(weapskill).getModified();
|
|
||||||
damage *= minstrike + ((maxstrike-minstrike)*stats.getAttackStrength());
|
|
||||||
|
|
||||||
healthdmg = (otherstats.getMagicEffects().get(ESM::MagicEffect::Paralyze).getMagnitude() > 0)
|
|
||||||
|| otherstats.getKnockedDown();
|
|
||||||
if(stats.isWerewolf())
|
|
||||||
{
|
|
||||||
healthdmg = true;
|
|
||||||
// GLOB instead of GMST because it gets updated during a quest
|
|
||||||
damage *= world->getGlobalFloat("werewolfclawmult");
|
|
||||||
}
|
|
||||||
if(healthdmg)
|
|
||||||
damage *= store.find("fHandtoHandHealthPer")->getFloat();
|
|
||||||
|
|
||||||
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
|
||||||
if(stats.isWerewolf())
|
|
||||||
{
|
|
||||||
const ESM::Sound *sound = world->getStore().get<ESM::Sound>().searchRandom("WolfHit");
|
|
||||||
if(sound)
|
|
||||||
sndMgr->playSound3D(victim, sound->mId, 1.0f, 1.0f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sndMgr->playSound3D(victim, "Hand To Hand Hit", 1.0f, 1.0f);
|
|
||||||
}
|
}
|
||||||
if(ptr.getRefData().getHandle() == "player")
|
if(ptr.getRefData().getHandle() == "player")
|
||||||
{
|
{
|
||||||
|
|
|
@ -332,4 +332,39 @@ namespace MWMechanics
|
||||||
damage *= (float(weaphealth) / weapmaxhealth);
|
damage *= (float(weaphealth) / weapmaxhealth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void getHandToHandDamage(const MWWorld::Ptr &attacker, const MWWorld::Ptr &victim, float &damage, bool &healthdmg)
|
||||||
|
{
|
||||||
|
// Note: MCP contains an option to include Strength in hand-to-hand damage
|
||||||
|
// calculations. Some mods recommend using it, so we may want to include an
|
||||||
|
// option for it.
|
||||||
|
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||||
|
float minstrike = store.get<ESM::GameSetting>().find("fMinHandToHandMult")->getFloat();
|
||||||
|
float maxstrike = store.get<ESM::GameSetting>().find("fMaxHandToHandMult")->getFloat();
|
||||||
|
damage = attacker.getClass().getSkill(attacker, ESM::Skill::HandToHand);
|
||||||
|
damage *= minstrike + ((maxstrike-minstrike)*attacker.getClass().getCreatureStats(attacker).getAttackStrength());
|
||||||
|
|
||||||
|
MWMechanics::CreatureStats& otherstats = victim.getClass().getCreatureStats(victim);
|
||||||
|
healthdmg = (otherstats.getMagicEffects().get(ESM::MagicEffect::Paralyze).getMagnitude() > 0)
|
||||||
|
|| otherstats.getKnockedDown();
|
||||||
|
bool isWerewolf = (attacker.getClass().isNpc() && attacker.getClass().getNpcStats(attacker).isWerewolf());
|
||||||
|
if(isWerewolf)
|
||||||
|
{
|
||||||
|
healthdmg = true;
|
||||||
|
// GLOB instead of GMST because it gets updated during a quest
|
||||||
|
damage *= MWBase::Environment::get().getWorld()->getGlobalFloat("werewolfclawmult");
|
||||||
|
}
|
||||||
|
if(healthdmg)
|
||||||
|
damage *= store.get<ESM::GameSetting>().find("fHandtoHandHealthPer")->getFloat();
|
||||||
|
|
||||||
|
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
||||||
|
if(isWerewolf)
|
||||||
|
{
|
||||||
|
const ESM::Sound *sound = store.get<ESM::Sound>().searchRandom("WolfHit");
|
||||||
|
if(sound)
|
||||||
|
sndMgr->playSound3D(victim, sound->mId, 1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sndMgr->playSound3D(victim, "Hand To Hand Hit", 1.0f, 1.0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,8 @@ void reduceWeaponCondition (float damage, bool hit, MWWorld::Ptr& weapon, const
|
||||||
/// Adjust weapon damage based on its condition. A used weapon will be less effective.
|
/// Adjust weapon damage based on its condition. A used weapon will be less effective.
|
||||||
void adjustWeaponDamage (float& damage, const MWWorld::Ptr& weapon);
|
void adjustWeaponDamage (float& damage, const MWWorld::Ptr& weapon);
|
||||||
|
|
||||||
|
void getHandToHandDamage (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, float& damage, bool& healthdmg);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue