mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-19 22:53:53 +00:00
Make rateWeapon more sensible and account for weapon speed
This commit is contained in:
parent
78a84042ad
commit
374e98d665
1 changed files with 30 additions and 41 deletions
|
@ -21,13 +21,19 @@ namespace MWMechanics
|
|||
float rateWeapon (const MWWorld::Ptr &item, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, int type,
|
||||
float arrowRating, float boltRating)
|
||||
{
|
||||
if (item.getTypeName() != typeid(ESM::Weapon).name())
|
||||
if (enemy.isEmpty() || item.getTypeName() != typeid(ESM::Weapon).name())
|
||||
return 0.f;
|
||||
|
||||
if (item.getClass().hasItemHealth(item) && item.getClass().getItemHealth(item) == 0)
|
||||
return 0.f;
|
||||
|
||||
const ESM::Weapon* weapon = item.get<ESM::Weapon>()->mBase;
|
||||
|
||||
if (type != -1 && weapon->mData.mType != type)
|
||||
return 0.f;
|
||||
|
||||
const MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
const MWWorld::Store<ESM::GameSetting>& gmst = world->getStore().get<ESM::GameSetting>();
|
||||
|
||||
if (type == -1 && (weapon->mData.mType == ESM::Weapon::Arrow || weapon->mData.mType == ESM::Weapon::Bolt))
|
||||
return 0.f;
|
||||
|
@ -37,54 +43,34 @@ namespace MWMechanics
|
|||
|
||||
if (weapon->mData.mType >= ESM::Weapon::MarksmanBow && weapon->mData.mType <= ESM::Weapon::MarksmanThrown)
|
||||
{
|
||||
// Range weapon is useless under water
|
||||
if (MWBase::Environment::get().getWorld()->isUnderwater(MWWorld::ConstPtr(actor), 0.75f))
|
||||
return 0.f;
|
||||
|
||||
if (enemy.isEmpty())
|
||||
return 0.f;
|
||||
|
||||
if (MWBase::Environment::get().getWorld()->isUnderwater(MWWorld::ConstPtr(enemy), 0.75f))
|
||||
// Underwater ranged combat is impossible
|
||||
if (world->isUnderwater(MWWorld::ConstPtr(actor), 0.75f)
|
||||
|| world->isUnderwater(MWWorld::ConstPtr(enemy), 0.75f))
|
||||
return 0.f;
|
||||
|
||||
if (getDistanceMinusHalfExtents(actor, enemy) >= getMaxAttackDistance(enemy))
|
||||
rangedMult = 1.5f;
|
||||
{
|
||||
static const float fAIMeleeWeaponMult = gmst.find("fAIMeleeWeaponMult")->mValue.getFloat();
|
||||
static const float fAIRangeMeleeWeaponMult = gmst.find("fAIRangeMeleeWeaponMult")->mValue.getFloat();
|
||||
rangedMult = fAIRangeMeleeWeaponMult / fAIMeleeWeaponMult;
|
||||
}
|
||||
}
|
||||
|
||||
const float chop = (weapon->mData.mChop[0] + weapon->mData.mChop[1]) / 2.f;
|
||||
if (weapon->mData.mType >= ESM::Weapon::MarksmanBow)
|
||||
{
|
||||
float rangedDamage = weapon->mData.mChop[0] + weapon->mData.mChop[1];
|
||||
MWMechanics::adjustWeaponDamage(rangedDamage, item, actor);
|
||||
|
||||
rating = rangedDamage / 2.f;
|
||||
|
||||
if (weapon->mData.mType >= ESM::Weapon::MarksmanThrown)
|
||||
MWMechanics::resistNormalWeapon(enemy, actor, item, rating);
|
||||
}
|
||||
rating = chop;
|
||||
else
|
||||
{
|
||||
float meleeDamage = 0.f;
|
||||
|
||||
for (int i=0; i<2; ++i)
|
||||
{
|
||||
meleeDamage += weapon->mData.mSlash[i];
|
||||
meleeDamage += weapon->mData.mThrust[i];
|
||||
meleeDamage += weapon->mData.mChop[i];
|
||||
}
|
||||
|
||||
MWMechanics::adjustWeaponDamage(meleeDamage, item, actor);
|
||||
rating = meleeDamage / 6.f;
|
||||
|
||||
MWMechanics::resistNormalWeapon(enemy, actor, item, rating);
|
||||
const float slash = (weapon->mData.mSlash[0] + weapon->mData.mSlash[1]) / 2.f;
|
||||
const float thrust = (weapon->mData.mThrust[0] + weapon->mData.mThrust[1]) / 2.f;
|
||||
rating = (slash * slash + thrust * thrust + chop * chop) / (slash + thrust + chop);
|
||||
}
|
||||
|
||||
if (item.getClass().hasItemHealth(item))
|
||||
{
|
||||
if (item.getClass().getItemHealth(item) == 0)
|
||||
return 0.f;
|
||||
}
|
||||
adjustWeaponDamage(rating, item, actor);
|
||||
|
||||
if (weapon->mData.mType == ESM::Weapon::MarksmanBow)
|
||||
if (weapon->mData.mType != ESM::Weapon::MarksmanBow && weapon->mData.mType != ESM::Weapon::MarksmanCrossbow)
|
||||
resistNormalWeapon(enemy, actor, item, rating);
|
||||
else if (weapon->mData.mType == ESM::Weapon::MarksmanBow)
|
||||
{
|
||||
if (arrowRating <= 0.f)
|
||||
rating = 0.f;
|
||||
|
@ -101,7 +87,7 @@ namespace MWMechanics
|
|||
|
||||
if (!weapon->mEnchant.empty())
|
||||
{
|
||||
const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(weapon->mEnchant);
|
||||
const ESM::Enchantment* enchantment = world->getStore().get<ESM::Enchantment>().find(weapon->mEnchant);
|
||||
if (enchantment->mData.mType == ESM::Enchantment::WhenStrikes)
|
||||
{
|
||||
int castCost = getEffectiveEnchantmentCastCost(static_cast<float>(enchantment->mData.mCost), actor);
|
||||
|
@ -111,19 +97,22 @@ namespace MWMechanics
|
|||
}
|
||||
}
|
||||
|
||||
if (weapon->mData.mType <= ESM::Weapon::MarksmanThrown)
|
||||
rating *= weapon->mData.mSpeed;
|
||||
|
||||
if (actor.getClass().isNpc())
|
||||
{
|
||||
int skill = item.getClass().getEquipmentSkill(item);
|
||||
if (skill != -1)
|
||||
{
|
||||
int value = actor.getClass().getSkill(actor, skill);
|
||||
rating *= MWMechanics::getHitChance(actor, enemy, value) / 100.f;
|
||||
rating *= getHitChance(actor, enemy, value) / 100.f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Creature> *ref = actor.get<ESM::Creature>();
|
||||
rating *= MWMechanics::getHitChance(actor, enemy, ref->mBase->mData.mCombat) / 100.f;
|
||||
rating *= getHitChance(actor, enemy, ref->mBase->mData.mCombat) / 100.f;
|
||||
}
|
||||
|
||||
return rating * rangedMult;
|
||||
|
|
Loading…
Reference in a new issue