1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-20 23:09:42 +00:00

Merge pull request #2068 from Capostrophic/normalweapons

Make normal weapon resistance behavior closer to vanilla (bug #4384)
This commit is contained in:
Bret Curtis 2019-02-23 08:38:30 +01:00 committed by GitHub
commit df2de8a661
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 77 additions and 18 deletions

View file

@ -8,6 +8,7 @@
Bug #3765: DisableTeleporting makes Mark/Recall/Intervention effects undetectable
Bug #4329: Removed birthsign abilities are restored after reloading the save
Bug #4383: Bow model obscures crosshair when arrow is drawn
Bug #4384: Resist Normal Weapons only checks ammunition for ranged weapons
Bug #4411: Reloading a saved game while falling prevents damage in some cases
Bug #4540: Rain delay when exiting water
Bug #4701: PrisonMarker record is not hardcoded like other markers

View file

@ -80,6 +80,7 @@ bool Launcher::AdvancedPage::loadSettings()
int unarmedFactorsStrengthIndex = mEngineSettings.getInt("strength influences hand to hand", "Game");
if (unarmedFactorsStrengthIndex >= 0 && unarmedFactorsStrengthIndex <= 2)
unarmedFactorsStrengthComboBox->setCurrentIndex(unarmedFactorsStrengthIndex);
loadSettingBool(requireAppropriateAmmunitionCheckBox, "only appropriate ammunition bypasses resistance", "Game");
// Input Settings
loadSettingBool(allowThirdPersonZoomCheckBox, "allow third person zoom", "Input");
@ -139,6 +140,7 @@ void Launcher::AdvancedPage::saveSettings()
int unarmedFactorsStrengthIndex = unarmedFactorsStrengthComboBox->currentIndex();
if (unarmedFactorsStrengthIndex != mEngineSettings.getInt("strength influences hand to hand", "Game"))
mEngineSettings.setInt("strength influences hand to hand", "Game", unarmedFactorsStrengthIndex);
saveSettingBool(requireAppropriateAmmunitionCheckBox, "only appropriate ammunition bypasses resistance", "Game");
// Input Settings
saveSettingBool(allowThirdPersonZoomCheckBox, "allow third person zoom", "Input");

View file

@ -308,6 +308,7 @@ namespace MWClass
{
damage = attack[0] + ((attack[1]-attack[0])*attackStrength);
MWMechanics::adjustWeaponDamage(damage, weapon, ptr);
MWMechanics::resistNormalWeapon(victim, ptr, weapon, damage);
MWMechanics::reduceWeaponCondition(damage, true, weapon, ptr);
}
@ -382,9 +383,6 @@ namespace MWClass
if (!object.isEmpty())
stats.setLastHitObject(object.getCellRef().getRefId());
if (damage > 0.0f && !object.isEmpty())
MWMechanics::resistNormalWeapon(ptr, attacker, object, damage);
if (damage < 0.001f)
damage = 0;

View file

@ -619,6 +619,8 @@ namespace MWClass
damage = attack[0] + ((attack[1]-attack[0])*attackStrength);
}
MWMechanics::adjustWeaponDamage(damage, weapon, ptr);
MWMechanics::resistNormalWeapon(victim, ptr, weapon, damage);
MWMechanics::applyWerewolfDamageMult(victim, weapon, damage);
MWMechanics::reduceWeaponCondition(damage, true, weapon, ptr);
healthdmg = true;
}

View file

@ -148,30 +148,49 @@ namespace MWMechanics
return false;
}
bool isNormalWeapon(const MWWorld::Ptr &weapon)
{
if (weapon.isEmpty())
return false;
const int flags = weapon.get<ESM::Weapon>()->mBase->mData.mFlags;
bool isSilver = flags & ESM::Weapon::Silver;
bool isMagical = flags & ESM::Weapon::Magical;
bool isEnchanted = !weapon.getClass().getEnchantment(weapon).empty();
return !isSilver && !isMagical && (!isEnchanted || !Settings::Manager::getBool("enchanted weapons are magical", "Game"));
}
void resistNormalWeapon(const MWWorld::Ptr &actor, const MWWorld::Ptr& attacker, const MWWorld::Ptr &weapon, float &damage)
{
if (damage == 0 || weapon.isEmpty() || !isNormalWeapon(weapon))
return;
const MWMechanics::MagicEffects& effects = actor.getClass().getCreatureStats(actor).getMagicEffects();
float resistance = std::min(100.f, effects.get(ESM::MagicEffect::ResistNormalWeapons).getMagnitude()
- effects.get(ESM::MagicEffect::WeaknessToNormalWeapons).getMagnitude());
const float resistance = effects.get(ESM::MagicEffect::ResistNormalWeapons).getMagnitude() / 100.f;
const float weakness = effects.get(ESM::MagicEffect::WeaknessToNormalWeapons).getMagnitude() / 100.f;
float multiplier = 1.f - resistance / 100.f;
if (!(weapon.get<ESM::Weapon>()->mBase->mData.mFlags & ESM::Weapon::Silver
|| weapon.get<ESM::Weapon>()->mBase->mData.mFlags & ESM::Weapon::Magical))
{
if (weapon.getClass().getEnchantment(weapon).empty()
|| !Settings::Manager::getBool("enchanted weapons are magical", "Game"))
damage *= multiplier;
}
if ((weapon.get<ESM::Weapon>()->mBase->mData.mFlags & ESM::Weapon::Silver)
&& actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf())
damage *= MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fWereWolfSilverWeaponDamageMult")->mValue.getFloat();
damage *= 1.f - std::min(1.f, resistance-weakness);
if (damage == 0 && attacker == getPlayer())
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicTargetResistsWeapons}");
}
void applyWerewolfDamageMult(const MWWorld::Ptr &actor, const MWWorld::Ptr &weapon, float &damage)
{
if (damage == 0 || weapon.isEmpty() || !actor.getClass().isNpc())
return;
const int flags = weapon.get<ESM::Weapon>()->mBase->mData.mFlags;
bool isSilver = flags & ESM::Weapon::Silver;
if (isSilver && actor.getClass().getNpcStats(actor).isWerewolf())
{
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
damage *= store.get<ESM::GameSetting>().find("fWereWolfSilverWeaponDamageMult")->mValue.getFloat();
}
}
void projectileHit(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, MWWorld::Ptr weapon, const MWWorld::Ptr& projectile,
const osg::Vec3f& hitPosition, float attackStrength)
{
@ -208,6 +227,9 @@ namespace MWMechanics
damage += attack[0] + ((attack[1] - attack[0]) * attackStrength);
adjustWeaponDamage(damage, weapon, attacker);
if (weapon == projectile || Settings::Manager::getBool("only appropriate ammunition bypasses resistance", "Game") || isNormalWeapon(weapon))
resistNormalWeapon(victim, attacker, projectile, damage);
applyWerewolfDamageMult(victim, projectile, damage);
if (attacker == getPlayer())
{

View file

@ -20,8 +20,13 @@ bool applyOnStrikeEnchantment(const MWWorld::Ptr& attacker, const MWWorld::Ptr&
/// @return can we block the attack?
bool blockMeleeAttack (const MWWorld::Ptr& attacker, const MWWorld::Ptr& blocker, const MWWorld::Ptr& weapon, float damage, float attackStrength);
/// @return does normal weapon resistance and weakness apply to the weapon?
bool isNormalWeapon (const MWWorld::Ptr& weapon);
void resistNormalWeapon (const MWWorld::Ptr& actor, const MWWorld::Ptr& attacker, const MWWorld::Ptr& weapon, float& damage);
void applyWerewolfDamageMult (const MWWorld::Ptr& actor, const MWWorld::Ptr& weapon, float &damage);
/// @note for a thrown weapon, \a weapon == \a projectile, for bows/crossbows, \a projectile is the arrow/bolt
/// @note \a victim may be empty (e.g. for a hit on terrain), a non-actor (environment objects) or an actor
void projectileHit (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, MWWorld::Ptr weapon, const MWWorld::Ptr& projectile,

View file

@ -78,7 +78,10 @@ namespace MWMechanics
adjustWeaponDamage(rating, item, actor);
if (weapon->mData.mType != ESM::Weapon::MarksmanBow && weapon->mData.mType != ESM::Weapon::MarksmanCrossbow)
{
resistNormalWeapon(enemy, actor, item, rating);
applyWerewolfDamageMult(enemy, item, rating);
}
else if (weapon->mData.mType == ESM::Weapon::MarksmanBow)
{
if (arrowRating <= 0.f)

View file

@ -211,3 +211,16 @@ disposition change of merchants caused by trading will be permanent and won't be
This imitates the option that Morrowind Code Patch offers.
This setting can be toggled in Advanced tab of the launcher.
only appropriate ammunition bypasses resistance
-----------------------------------------------
:Type: boolean
:Range: True/False
:Default: False
If this setting is true, you will have to use the appropriate ammunition to bypass normal weapon resistance (or weakness).
An enchanted bow with chitin arrows will no longer be enough for the purpose, while a steel longbow with glass arrows will still work.
This was previously the default engine behavior that diverged from Morrowind design.
This setting can be toggled in Advanced tab of the launcher.

View file

@ -242,6 +242,9 @@ strength influences hand to hand = 0
# Render holstered weapons (with quivers and scabbards), requires modded assets
weapon sheathing = false
# Allow non-standard ammunition solely to bypass normal weapon resistance or weakness
only appropriate ammunition bypasses resistance = false
[General]
# Anisotropy reduces distortion in textures at low angles (e.g. 0 to 16).

View file

@ -96,6 +96,16 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="requireAppropriateAmmunitionCheckBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Allow non-standard ammunition solely to bypass normal weapon resistance or weakness.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Only appropriate ammunition bypasses normal weapon resistance</string>
</property>
</widget>
</item>
<item alignment="Qt::AlignLeft">
<widget class="QWidget" name="unarmedFactorsStrengthGroup" native="true">
<property name="toolTip">