Merge branch 'master' into weaponpriority

pull/469/head
Capostrophic 6 years ago committed by GitHub
commit 4c7f3cf626
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -12,6 +12,7 @@
Bug #2835: Player able to slowly move when overencumbered Bug #2835: Player able to slowly move when overencumbered
Bug #2852: No murder bounty when a player follower commits murder Bug #2852: No murder bounty when a player follower commits murder
Bug #2862: [macOS] Can't quit launcher using Command-Q or OpenMW->Quit Bug #2862: [macOS] Can't quit launcher using Command-Q or OpenMW->Quit
Bug #2872: Tab completion in console doesn't work with explicit reference
Bug #2971: Compiler did not reject lines with naked expressions beginning with x.y Bug #2971: Compiler did not reject lines with naked expressions beginning with x.y
Bug #3249: Fixed revert function not updating views properly Bug #3249: Fixed revert function not updating views properly
Bug #3374: Touch spells not hitting kwama foragers Bug #3374: Touch spells not hitting kwama foragers
@ -74,11 +75,13 @@
Bug #4510: Division by zero in MWMechanics::CreatureStats::setAttribute Bug #4510: Division by zero in MWMechanics::CreatureStats::setAttribute
Bug #4519: Knockdown does not discard movement in the 1st-person mode Bug #4519: Knockdown does not discard movement in the 1st-person mode
Bug #4539: Paper Doll is affected by GUI scaling Bug #4539: Paper Doll is affected by GUI scaling
Bug #4545: Creatures flee from werewolves
Bug #4548: Weapon priority: use the actual chance to hit the target instead of weapon skill Bug #4548: Weapon priority: use the actual chance to hit the target instead of weapon skill
Bug #4549: Weapon priority: use the actual damage in weapon rating calculations Bug #4549: Weapon priority: use the actual damage in weapon rating calculations
Bug #4550: Weapon priority: make ranged weapon bonus more sensible Bug #4550: Weapon priority: make ranged weapon bonus more sensible
Feature #2606: Editor: Implemented (optional) case sensitive global search Feature #2606: Editor: Implemented (optional) case sensitive global search
Feature #3083: Play animation when NPC is casting spell via script Feature #3083: Play animation when NPC is casting spell via script
Feature #3103: Provide option for disposition to get increased by successful trade
Feature #3276: Editor: Search- Show number of (remaining) search results and indicate a search without any results Feature #3276: Editor: Search- Show number of (remaining) search results and indicate a search without any results
Feature #3641: Editor: Limit FPS in 3d preview window Feature #3641: Editor: Limit FPS in 3d preview window
Feature #3703: Ranged sneak attack criticals Feature #3703: Ranged sneak attack criticals

@ -75,6 +75,7 @@ bool Launcher::AdvancedPage::loadSettings()
loadSettingBool(rebalanceSoulGemValuesCheckBox, "rebalance soul gem values", "Game"); loadSettingBool(rebalanceSoulGemValuesCheckBox, "rebalance soul gem values", "Game");
loadSettingBool(chargeForEveryFollowerCheckBox, "charge for every follower travelling", "Game"); loadSettingBool(chargeForEveryFollowerCheckBox, "charge for every follower travelling", "Game");
loadSettingBool(enchantedWeaponsMagicalCheckBox, "enchanted weapons are magical", "Game"); loadSettingBool(enchantedWeaponsMagicalCheckBox, "enchanted weapons are magical", "Game");
loadSettingBool(permanentBarterDispositionChangeCheckBox, "barter disposition change is permanent", "Game");
// Input Settings // Input Settings
loadSettingBool(allowThirdPersonZoomCheckBox, "allow third person zoom", "Input"); loadSettingBool(allowThirdPersonZoomCheckBox, "allow third person zoom", "Input");
@ -129,6 +130,7 @@ void Launcher::AdvancedPage::saveSettings()
saveSettingBool(rebalanceSoulGemValuesCheckBox, "rebalance soul gem values", "Game"); saveSettingBool(rebalanceSoulGemValuesCheckBox, "rebalance soul gem values", "Game");
saveSettingBool(chargeForEveryFollowerCheckBox, "charge for every follower travelling", "Game"); saveSettingBool(chargeForEveryFollowerCheckBox, "charge for every follower travelling", "Game");
saveSettingBool(enchantedWeaponsMagicalCheckBox, "enchanted weapons are magical", "Game"); saveSettingBool(enchantedWeaponsMagicalCheckBox, "enchanted weapons are magical", "Game");
saveSettingBool(permanentBarterDispositionChangeCheckBox, "barter disposition change is permanent", "Game");
// Input Settings // Input Settings
saveSettingBool(allowThirdPersonZoomCheckBox, "allow third person zoom", "Input"); saveSettingBool(allowThirdPersonZoomCheckBox, "allow third person zoom", "Input");

@ -75,8 +75,8 @@ namespace MWBase
virtual void persuade (int type, ResponseCallback* callback) = 0; virtual void persuade (int type, ResponseCallback* callback) = 0;
virtual int getTemporaryDispositionChange () const = 0; virtual int getTemporaryDispositionChange () const = 0;
/// @note This change is temporary and gets discarded when dialogue ends. /// @note Controlled by an option, gets discarded when dialogue ends by default
virtual void applyDispositionChange (int delta) = 0; virtual void applyBarterDispositionChange (int delta) = 0;
virtual int countSavedGameRecords() const = 0; virtual int countSavedGameRecords() const = 0;

@ -22,6 +22,8 @@
#include <components/interpreter/interpreter.hpp> #include <components/interpreter/interpreter.hpp>
#include <components/interpreter/defines.hpp> #include <components/interpreter/defines.hpp>
#include <components/settings/settings.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/journal.hpp" #include "../mwbase/journal.hpp"
@ -508,9 +510,11 @@ namespace MWDialogue
return static_cast<int>(mTemporaryDispositionChange); return static_cast<int>(mTemporaryDispositionChange);
} }
void DialogueManager::applyDispositionChange(int delta) void DialogueManager::applyBarterDispositionChange(int delta)
{ {
mTemporaryDispositionChange += delta; mTemporaryDispositionChange += delta;
if (Settings::Manager::getBool("barter disposition change is permanent", "Game"))
mPermanentDispositionChange += delta;
} }
bool DialogueManager::checkServiceRefused(ResponseCallback* callback) bool DialogueManager::checkServiceRefused(ResponseCallback* callback)

@ -94,8 +94,8 @@ namespace MWDialogue
virtual void persuade (int type, ResponseCallback* callback); virtual void persuade (int type, ResponseCallback* callback);
virtual int getTemporaryDispositionChange () const; virtual int getTemporaryDispositionChange () const;
/// @note This change is temporary and gets discarded when dialogue ends. /// @note Controlled by an option, gets discarded when dialogue ends by default
virtual void applyDispositionChange (int delta); virtual void applyBarterDispositionChange (int delta);
virtual int countSavedGameRecords() const; virtual int countSavedGameRecords() const;

@ -303,6 +303,14 @@ namespace MWGui
bool has_front_quote = false; bool has_front_quote = false;
/* Does the input string contain things that don't have to be completed? If yes erase them. */ /* Does the input string contain things that don't have to be completed? If yes erase them. */
/* Erase a possible call to an explicit reference. */
size_t explicitPos = tmp.find("->");
if (explicitPos != std::string::npos)
{
tmp.erase(0, explicitPos+2);
}
/* Are there quotation marks? */ /* Are there quotation marks? */
if( tmp.find('"') != std::string::npos ) { if( tmp.find('"') != std::string::npos ) {
int numquotes=0; int numquotes=0;
@ -339,6 +347,7 @@ namespace MWGui
} }
} }
} }
/* Erase the input from the output string so we can easily append the completed form later. */ /* Erase the input from the output string so we can easily append the completed form later. */
output.erase(output.end()-tmp.length(), output.end()); output.erase(output.end()-tmp.length(), output.end());

@ -334,7 +334,7 @@ namespace MWGui
? gmst.find("iBarterSuccessDisposition")->getInt() ? gmst.find("iBarterSuccessDisposition")->getInt()
: gmst.find("iBarterFailDisposition")->getInt(); : gmst.find("iBarterFailDisposition")->getInt();
MWBase::Environment::get().getDialogueManager()->applyDispositionChange(dispositionDelta); MWBase::Environment::get().getDialogueManager()->applyBarterDispositionChange(dispositionDelta);
} }
// display message on haggle failure // display message on haggle failure

@ -494,10 +494,13 @@ namespace MWMechanics
static const int iWereWolfLevelToAttack = gmst.find("iWereWolfLevelToAttack")->getInt(); static const int iWereWolfLevelToAttack = gmst.find("iWereWolfLevelToAttack")->getInt();
if (enemy.getClass().isNpc() && enemy.getClass().getNpcStats(enemy).isWerewolf() && stats.getLevel() < iWereWolfLevelToAttack) if (actor.getClass().isNpc() && enemy.getClass().isNpc())
{ {
static const int iWereWolfFleeMod = gmst.find("iWereWolfFleeMod")->getInt(); if (enemy.getClass().getNpcStats(enemy).isWerewolf() && stats.getLevel() < iWereWolfLevelToAttack)
rating = iWereWolfFleeMod; {
static const int iWereWolfFleeMod = gmst.find("iWereWolfFleeMod")->getInt();
rating = iWereWolfFleeMod;
}
} }
if (rating != 0.0f) if (rating != 0.0f)

@ -1221,11 +1221,11 @@ bool CharacterController::updateWeaponState()
bool isStillWeapon = weaptype > WeapType_HandToHand && weaptype < WeapType_Spell && bool isStillWeapon = weaptype > WeapType_HandToHand && weaptype < WeapType_Spell &&
mWeaponType > WeapType_HandToHand && mWeaponType < WeapType_Spell; mWeaponType > WeapType_HandToHand && mWeaponType < WeapType_Spell;
if(weaptype != mWeaponType && !isKnockedOut() && if(!isKnockedOut() && !isKnockedDown() && !isRecovery())
!isKnockedDown() && !isRecovery())
{ {
std::string weapgroup; std::string weapgroup;
if ((!isWerewolf || mWeaponType != WeapType_Spell) if ((!isWerewolf || mWeaponType != WeapType_Spell)
&& weaptype != mWeaponType
&& mUpperBodyState != UpperCharState_UnEquipingWeap && mUpperBodyState != UpperCharState_UnEquipingWeap
&& !isStillWeapon) && !isStillWeapon)
{ {
@ -1250,49 +1250,60 @@ bool CharacterController::updateWeaponState()
float complete; float complete;
bool animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete); bool animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete);
if (!animPlaying || complete >= 1.0f) if (!animPlaying || complete >= 1.0f)
{ {
forcestateupdate = true; // Weapon is changed, no current animation (e.g. unequipping or attack).
mAnimation->showCarriedLeft(updateCarriedLeftVisible(weaptype)); // Start equipping animation now.
if (weaptype != mWeaponType)
{
forcestateupdate = true;
mAnimation->showCarriedLeft(updateCarriedLeftVisible(weaptype));
getWeaponGroup(weaptype, weapgroup); getWeaponGroup(weaptype, weapgroup);
mAnimation->setWeaponGroup(weapgroup); mAnimation->setWeaponGroup(weapgroup);
if (!isStillWeapon) if (!isStillWeapon)
{
if (weaptype == WeapType_None)
{ {
// Disable current weapon animation manually
mAnimation->disable(mCurrentWeapon); mAnimation->disable(mCurrentWeapon);
if (weaptype != WeapType_None)
{
mAnimation->showWeapons(false);
mAnimation->play(weapgroup, priorityWeapon,
MWRender::Animation::BlendMask_All, true,
1.0f, "equip start", "equip stop", 0.0f, 0);
mUpperBodyState = UpperCharState_EquipingWeap;
}
} }
else
if(isWerewolf)
{ {
mAnimation->showWeapons(false); const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
mAnimation->play(weapgroup, priorityWeapon, const ESM::Sound *sound = store.get<ESM::Sound>().searchRandom("WolfEquip");
MWRender::Animation::BlendMask_All, true, if(sound)
1.0f, "equip start", "equip stop", 0.0f, 0); {
mUpperBodyState = UpperCharState_EquipingWeap; MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
sndMgr->playSound3D(mPtr, sound->mId, 1.0f, 1.0f);
}
} }
}
if(isWerewolf) mWeaponType = weaptype;
{ getWeaponGroup(mWeaponType, mCurrentWeapon);
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const ESM::Sound *sound = store.get<ESM::Sound>().searchRandom("WolfEquip"); if(!upSoundId.empty() && !isStillWeapon)
if(sound)
{ {
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
sndMgr->playSound3D(mPtr, sound->mId, 1.0f, 1.0f); sndMgr->playSound3D(mPtr, upSoundId, 1.0f, 1.0f);
} }
} }
mWeaponType = weaptype; // Make sure that we disabled unequipping animation
getWeaponGroup(mWeaponType, mCurrentWeapon); if (mUpperBodyState == UpperCharState_UnEquipingWeap)
if(!upSoundId.empty() && !isStillWeapon)
{ {
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); mUpperBodyState = UpperCharState_Nothing;
sndMgr->playSound3D(mPtr, upSoundId, 1.0f, 1.0f); mAnimation->disable(mCurrentWeapon);
mWeaponType = WeapType_None;
getWeaponGroup(mWeaponType, mCurrentWeapon);
} }
} }
} }

@ -315,14 +315,14 @@ namespace MWMechanics
return true; return true;
} }
CastSpell::CastSpell(const MWWorld::Ptr &caster, const MWWorld::Ptr &target, const bool fromProjectile, const bool isScripted) CastSpell::CastSpell(const MWWorld::Ptr &caster, const MWWorld::Ptr &target, const bool fromProjectile, const bool manualSpell)
: mCaster(caster) : mCaster(caster)
, mTarget(target) , mTarget(target)
, mStack(false) , mStack(false)
, mHitPosition(0,0,0) , mHitPosition(0,0,0)
, mAlwaysSucceed(false) , mAlwaysSucceed(false)
, mFromProjectile(fromProjectile) , mFromProjectile(fromProjectile)
, mIsScripted(isScripted) , mManualSpell(manualSpell)
{ {
} }
@ -864,7 +864,7 @@ namespace MWMechanics
bool godmode = mCaster == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState(); bool godmode = mCaster == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState();
if (mCaster.getClass().isActor() && !mAlwaysSucceed && !mIsScripted) if (mCaster.getClass().isActor() && !mAlwaysSucceed && !mManualSpell)
{ {
school = getSpellSchool(spell, mCaster); school = getSpellSchool(spell, mCaster);
@ -1037,7 +1037,7 @@ namespace MWMechanics
bool CastSpell::spellIncreasesSkill() bool CastSpell::spellIncreasesSkill()
{ {
if (mIsScripted) if (mManualSpell)
return false; return false;
return MWMechanics::spellIncreasesSkill(mId); return MWMechanics::spellIncreasesSkill(mId);

@ -88,10 +88,10 @@ namespace MWMechanics
osg::Vec3f mHitPosition; // Used for spawning area orb osg::Vec3f mHitPosition; // Used for spawning area orb
bool mAlwaysSucceed; // Always succeed spells casted by NPCs/creatures regardless of their chance (default: false) bool mAlwaysSucceed; // Always succeed spells casted by NPCs/creatures regardless of their chance (default: false)
bool mFromProjectile; // True if spell is cast by enchantment of some projectile (arrow, bolt or thrown weapon) bool mFromProjectile; // True if spell is cast by enchantment of some projectile (arrow, bolt or thrown weapon)
bool mIsScripted; // True if spell is casted from script and ignores some checks (mana level, success chance, etc.) bool mManualSpell; // True if spell is casted from script and ignores some checks (mana level, success chance, etc.)
public: public:
CastSpell(const MWWorld::Ptr& caster, const MWWorld::Ptr& target, const bool fromProjectile=false, const bool isScripted=false); CastSpell(const MWWorld::Ptr& caster, const MWWorld::Ptr& target, const bool fromProjectile=false, const bool manualSpell=false);
bool cast (const ESM::Spell* spell); bool cast (const ESM::Spell* spell);

@ -130,7 +130,7 @@ enchanted weapons are magical
:Range: True/False :Range: True/False
:Default: True :Default: True
Makes enchanted weapons without Magical flag bypass normal weapons resistance (and weakness) certain creatures have. Make enchanted weapons without Magical flag bypass normal weapons resistance (and weakness) certain creatures have.
This is how original Morrowind behaves. This is how original Morrowind behaves.
This setting can only be configured by editing the settings configuration file. This setting can only be configured by editing the settings configuration file.
@ -142,7 +142,7 @@ prevent merchant equipping
:Range: True/False :Range: True/False
:Default: False :Default: False
Prevents merchants from equipping items that are sold to them. Prevent merchants from equipping items that are sold to them.
This setting can only be configured by editing the settings configuration file. This setting can only be configured by editing the settings configuration file.
@ -153,7 +153,7 @@ followers attack on sight
:Range: True/False :Range: True/False
:Default: False :Default: False
Makes player followers and escorters start combat with enemies who have started combat with them or the player. Make player followers and escorters start combat with enemies who have started combat with them or the player.
Otherwise they wait for the enemies or the player to do an attack first. Otherwise they wait for the enemies or the player to do an attack first.
Please note this setting has not been extensively tested and could have side effects with certain quests. Please note this setting has not been extensively tested and could have side effects with certain quests.
@ -171,3 +171,15 @@ For example, if the main animation mesh has name Meshes/x.nif, an engine will lo
Can be useful if you want to use several animation replacers without merging them. Can be useful if you want to use several animation replacers without merging them.
Attention: animations from AnimKit have own format and are not supposed to be directly loaded in-game! Attention: animations from AnimKit have own format and are not supposed to be directly loaded in-game!
This setting can only be configured by editing the settings configuration file. This setting can only be configured by editing the settings configuration file.
barter disposition change is permanent
--------------------------------------
:Type: boolean
:Range: True/False
:Default: False
If this setting is true, disposition change of merchants caused by trading will be permanent and won't be discarded upon exiting dialogue with them.
This imitates the option Morrowind Code Patch offers.
This setting can be toggled with a checkbox in Advanced tab of the launcher.

@ -203,25 +203,28 @@ show effect duration = false
# Account for the first follower in fast travel cost calculations. # Account for the first follower in fast travel cost calculations.
charge for every follower travelling = false charge for every follower travelling = false
# Prevents merchants from equipping items that are sold to them. # Prevent merchants from equipping items that are sold to them.
prevent merchant equipping = false prevent merchant equipping = false
# Make enchanted weaponry without Magical flag bypass normal weapons resistance # Make enchanted weaponry without Magical flag bypass normal weapons resistance
enchanted weapons are magical = true enchanted weapons are magical = true
# Makes player followers and escorters start combat with enemies who have started combat with them # Make player followers and escorters start combat with enemies who have started combat with them
# or the player. Otherwise they wait for the enemies or the player to do an attack first. # or the player. Otherwise they wait for the enemies or the player to do an attack first.
followers attack on sight = false followers attack on sight = false
# Can loot non-fighting actors during death animation # Can loot non-fighting actors during death animation
can loot during death animation = true can loot during death animation = true
# Makes the value of filled soul gems dependent only on soul magnitude (with formula from the Morrowind Code Patch) # Make the value of filled soul gems dependent only on soul magnitude (with formula from the Morrowind Code Patch)
rebalance soul gem values = false rebalance soul gem values = false
# Allow to load per-group KF-files from Animations folder # Allow to load per-group KF-files from Animations folder
use additional anim sources = false use additional anim sources = false
# Make the disposition change of merchants caused by barter dealings permanent
barter disposition change is permanent = 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).

@ -22,7 +22,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>641</width> <width>641</width>
<height>968</height> <height>998</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="scrollAreaVerticalLayout"> <layout class="QVBoxLayout" name="scrollAreaVerticalLayout">
@ -45,7 +45,7 @@
<item> <item>
<widget class="QCheckBox" name="followersAttackOnSightCheckBox"> <widget class="QCheckBox" name="followersAttackOnSightCheckBox">
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Makes player followers and escorters start combat with enemies who have started combat with them or the player. Otherwise they wait for the enemies or the player to do an attack first.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Make player followers and escorters start combat with enemies who have started combat with them or the player. Otherwise they wait for the enemies or the player to do an attack first.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Followers attack on sight</string> <string>Followers attack on sight</string>
@ -65,7 +65,7 @@
<item> <item>
<widget class="QCheckBox" name="rebalanceSoulGemValuesCheckBox"> <widget class="QCheckBox" name="rebalanceSoulGemValuesCheckBox">
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If this setting is true, the value of filled soul gems is dependent only on soul magnitude.&lt;/p&gt;&lt;p&gt;The default value is false.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Make the value of filled soul gems dependent only on soul magnitude.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Rebalance soul gem values</string> <string>Rebalance soul gem values</string>
@ -89,6 +89,16 @@
</property> </property>
<property name="text"> <property name="text">
<string>Enchanted weapons are magical</string> <string>Enchanted weapons are magical</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="permanentBarterDispositionChangeCheckBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Make disposition change of merchants caused by trading permanent.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Barter disposition change is permanent</string>
</property> </property>
</widget> </widget>
</item> </item>

Loading…
Cancel
Save