mirror of
https://github.com/TES3MP/TES3MP.git
synced 2025-09-28 07:32:00 -04:00
Merge pull request #2068 from Capostrophic/normalweapons
Make normal weapon resistance behavior closer to vanilla (bug #4384)
This commit is contained in:
commit
df2de8a661
@ -8,6 +8,7 @@
|
|||||||
Bug #3765: DisableTeleporting makes Mark/Recall/Intervention effects undetectable
|
Bug #3765: DisableTeleporting makes Mark/Recall/Intervention effects undetectable
|
||||||
Bug #4329: Removed birthsign abilities are restored after reloading the save
|
Bug #4329: Removed birthsign abilities are restored after reloading the save
|
||||||
Bug #4383: Bow model obscures crosshair when arrow is drawn
|
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 #4411: Reloading a saved game while falling prevents damage in some cases
|
||||||
Bug #4540: Rain delay when exiting water
|
Bug #4540: Rain delay when exiting water
|
||||||
Bug #4701: PrisonMarker record is not hardcoded like other markers
|
Bug #4701: PrisonMarker record is not hardcoded like other markers
|
||||||
|
@ -80,6 +80,7 @@ bool Launcher::AdvancedPage::loadSettings()
|
|||||||
int unarmedFactorsStrengthIndex = mEngineSettings.getInt("strength influences hand to hand", "Game");
|
int unarmedFactorsStrengthIndex = mEngineSettings.getInt("strength influences hand to hand", "Game");
|
||||||
if (unarmedFactorsStrengthIndex >= 0 && unarmedFactorsStrengthIndex <= 2)
|
if (unarmedFactorsStrengthIndex >= 0 && unarmedFactorsStrengthIndex <= 2)
|
||||||
unarmedFactorsStrengthComboBox->setCurrentIndex(unarmedFactorsStrengthIndex);
|
unarmedFactorsStrengthComboBox->setCurrentIndex(unarmedFactorsStrengthIndex);
|
||||||
|
loadSettingBool(requireAppropriateAmmunitionCheckBox, "only appropriate ammunition bypasses resistance", "Game");
|
||||||
|
|
||||||
// Input Settings
|
// Input Settings
|
||||||
loadSettingBool(allowThirdPersonZoomCheckBox, "allow third person zoom", "Input");
|
loadSettingBool(allowThirdPersonZoomCheckBox, "allow third person zoom", "Input");
|
||||||
@ -139,6 +140,7 @@ void Launcher::AdvancedPage::saveSettings()
|
|||||||
int unarmedFactorsStrengthIndex = unarmedFactorsStrengthComboBox->currentIndex();
|
int unarmedFactorsStrengthIndex = unarmedFactorsStrengthComboBox->currentIndex();
|
||||||
if (unarmedFactorsStrengthIndex != mEngineSettings.getInt("strength influences hand to hand", "Game"))
|
if (unarmedFactorsStrengthIndex != mEngineSettings.getInt("strength influences hand to hand", "Game"))
|
||||||
mEngineSettings.setInt("strength influences hand to hand", "Game", unarmedFactorsStrengthIndex);
|
mEngineSettings.setInt("strength influences hand to hand", "Game", unarmedFactorsStrengthIndex);
|
||||||
|
saveSettingBool(requireAppropriateAmmunitionCheckBox, "only appropriate ammunition bypasses resistance", "Game");
|
||||||
|
|
||||||
// Input Settings
|
// Input Settings
|
||||||
saveSettingBool(allowThirdPersonZoomCheckBox, "allow third person zoom", "Input");
|
saveSettingBool(allowThirdPersonZoomCheckBox, "allow third person zoom", "Input");
|
||||||
|
@ -308,6 +308,7 @@ namespace MWClass
|
|||||||
{
|
{
|
||||||
damage = attack[0] + ((attack[1]-attack[0])*attackStrength);
|
damage = attack[0] + ((attack[1]-attack[0])*attackStrength);
|
||||||
MWMechanics::adjustWeaponDamage(damage, weapon, ptr);
|
MWMechanics::adjustWeaponDamage(damage, weapon, ptr);
|
||||||
|
MWMechanics::resistNormalWeapon(victim, ptr, weapon, damage);
|
||||||
MWMechanics::reduceWeaponCondition(damage, true, weapon, ptr);
|
MWMechanics::reduceWeaponCondition(damage, true, weapon, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,9 +383,6 @@ namespace MWClass
|
|||||||
if (!object.isEmpty())
|
if (!object.isEmpty())
|
||||||
stats.setLastHitObject(object.getCellRef().getRefId());
|
stats.setLastHitObject(object.getCellRef().getRefId());
|
||||||
|
|
||||||
if (damage > 0.0f && !object.isEmpty())
|
|
||||||
MWMechanics::resistNormalWeapon(ptr, attacker, object, damage);
|
|
||||||
|
|
||||||
if (damage < 0.001f)
|
if (damage < 0.001f)
|
||||||
damage = 0;
|
damage = 0;
|
||||||
|
|
||||||
|
@ -619,6 +619,8 @@ namespace MWClass
|
|||||||
damage = attack[0] + ((attack[1]-attack[0])*attackStrength);
|
damage = attack[0] + ((attack[1]-attack[0])*attackStrength);
|
||||||
}
|
}
|
||||||
MWMechanics::adjustWeaponDamage(damage, weapon, ptr);
|
MWMechanics::adjustWeaponDamage(damage, weapon, ptr);
|
||||||
|
MWMechanics::resistNormalWeapon(victim, ptr, weapon, damage);
|
||||||
|
MWMechanics::applyWerewolfDamageMult(victim, weapon, damage);
|
||||||
MWMechanics::reduceWeaponCondition(damage, true, weapon, ptr);
|
MWMechanics::reduceWeaponCondition(damage, true, weapon, ptr);
|
||||||
healthdmg = true;
|
healthdmg = true;
|
||||||
}
|
}
|
||||||
|
@ -148,30 +148,49 @@ namespace MWMechanics
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void resistNormalWeapon(const MWWorld::Ptr &actor, const MWWorld::Ptr& attacker, const MWWorld::Ptr &weapon, float &damage)
|
bool isNormalWeapon(const MWWorld::Ptr &weapon)
|
||||||
{
|
{
|
||||||
const MWMechanics::MagicEffects& effects = actor.getClass().getCreatureStats(actor).getMagicEffects();
|
if (weapon.isEmpty())
|
||||||
float resistance = std::min(100.f, effects.get(ESM::MagicEffect::ResistNormalWeapons).getMagnitude()
|
return false;
|
||||||
- effects.get(ESM::MagicEffect::WeaknessToNormalWeapons).getMagnitude());
|
|
||||||
|
|
||||||
float multiplier = 1.f - resistance / 100.f;
|
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();
|
||||||
|
|
||||||
if (!(weapon.get<ESM::Weapon>()->mBase->mData.mFlags & ESM::Weapon::Silver
|
return !isSilver && !isMagical && (!isEnchanted || !Settings::Manager::getBool("enchanted weapons are magical", "Game"));
|
||||||
|| 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)
|
void resistNormalWeapon(const MWWorld::Ptr &actor, const MWWorld::Ptr& attacker, const MWWorld::Ptr &weapon, float &damage)
|
||||||
&& actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf())
|
{
|
||||||
damage *= MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fWereWolfSilverWeaponDamageMult")->mValue.getFloat();
|
if (damage == 0 || weapon.isEmpty() || !isNormalWeapon(weapon))
|
||||||
|
return;
|
||||||
|
|
||||||
|
const MWMechanics::MagicEffects& effects = actor.getClass().getCreatureStats(actor).getMagicEffects();
|
||||||
|
const float resistance = effects.get(ESM::MagicEffect::ResistNormalWeapons).getMagnitude() / 100.f;
|
||||||
|
const float weakness = effects.get(ESM::MagicEffect::WeaknessToNormalWeapons).getMagnitude() / 100.f;
|
||||||
|
|
||||||
|
damage *= 1.f - std::min(1.f, resistance-weakness);
|
||||||
|
|
||||||
if (damage == 0 && attacker == getPlayer())
|
if (damage == 0 && attacker == getPlayer())
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicTargetResistsWeapons}");
|
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,
|
void projectileHit(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, MWWorld::Ptr weapon, const MWWorld::Ptr& projectile,
|
||||||
const osg::Vec3f& hitPosition, float attackStrength)
|
const osg::Vec3f& hitPosition, float attackStrength)
|
||||||
{
|
{
|
||||||
@ -208,6 +227,9 @@ namespace MWMechanics
|
|||||||
damage += attack[0] + ((attack[1] - attack[0]) * attackStrength);
|
damage += attack[0] + ((attack[1] - attack[0]) * attackStrength);
|
||||||
|
|
||||||
adjustWeaponDamage(damage, weapon, attacker);
|
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())
|
if (attacker == getPlayer())
|
||||||
{
|
{
|
||||||
|
@ -20,8 +20,13 @@ bool applyOnStrikeEnchantment(const MWWorld::Ptr& attacker, const MWWorld::Ptr&
|
|||||||
/// @return can we block the attack?
|
/// @return can we block the attack?
|
||||||
bool blockMeleeAttack (const MWWorld::Ptr& attacker, const MWWorld::Ptr& blocker, const MWWorld::Ptr& weapon, float damage, float attackStrength);
|
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 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 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
|
/// @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,
|
void projectileHit (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, MWWorld::Ptr weapon, const MWWorld::Ptr& projectile,
|
||||||
|
@ -78,7 +78,10 @@ namespace MWMechanics
|
|||||||
adjustWeaponDamage(rating, item, actor);
|
adjustWeaponDamage(rating, item, actor);
|
||||||
|
|
||||||
if (weapon->mData.mType != ESM::Weapon::MarksmanBow && weapon->mData.mType != ESM::Weapon::MarksmanCrossbow)
|
if (weapon->mData.mType != ESM::Weapon::MarksmanBow && weapon->mData.mType != ESM::Weapon::MarksmanCrossbow)
|
||||||
|
{
|
||||||
resistNormalWeapon(enemy, actor, item, rating);
|
resistNormalWeapon(enemy, actor, item, rating);
|
||||||
|
applyWerewolfDamageMult(enemy, item, rating);
|
||||||
|
}
|
||||||
else if (weapon->mData.mType == ESM::Weapon::MarksmanBow)
|
else if (weapon->mData.mType == ESM::Weapon::MarksmanBow)
|
||||||
{
|
{
|
||||||
if (arrowRating <= 0.f)
|
if (arrowRating <= 0.f)
|
||||||
|
@ -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 imitates the option that Morrowind Code Patch offers.
|
||||||
|
|
||||||
This setting can be toggled in Advanced tab of the launcher.
|
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.
|
||||||
|
@ -242,6 +242,9 @@ strength influences hand to hand = 0
|
|||||||
# Render holstered weapons (with quivers and scabbards), requires modded assets
|
# Render holstered weapons (with quivers and scabbards), requires modded assets
|
||||||
weapon sheathing = false
|
weapon sheathing = false
|
||||||
|
|
||||||
|
# Allow non-standard ammunition solely to bypass normal weapon resistance or weakness
|
||||||
|
only appropriate ammunition bypasses resistance = false
|
||||||
|
|
||||||
[General]
|
[General]
|
||||||
|
|
||||||
# Anisotropy reduces distortion in textures at low angles (e.g. 0 to 16).
|
# Anisotropy reduces distortion in textures at low angles (e.g. 0 to 16).
|
||||||
|
@ -96,6 +96,16 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="requireAppropriateAmmunitionCheckBox">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>Allow non-standard ammunition solely to bypass normal weapon resistance or weakness.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Only appropriate ammunition bypasses normal weapon resistance</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item alignment="Qt::AlignLeft">
|
<item alignment="Qt::AlignLeft">
|
||||||
<widget class="QWidget" name="unarmedFactorsStrengthGroup" native="true">
|
<widget class="QWidget" name="unarmedFactorsStrengthGroup" native="true">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user