From b1dfb0bc294b5b5580671961e6b6829d852a73b7 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 24 Jul 2018 12:57:09 +0200 Subject: [PATCH 01/44] stage1: priorities for event music and other minor improvements to the music system --- docs/openmw-stage1.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/openmw-stage1.md b/docs/openmw-stage1.md index 4707a4435..4290080b8 100644 --- a/docs/openmw-stage1.md +++ b/docs/openmw-stage1.md @@ -1383,9 +1383,9 @@ We add several new script instructions: * PlayBackgroundMusic (t) * PlaylistBackgroundMusic (pl) * StopBackgroundMusic -* PlayEventMusic (t, loop=0, force=0) -* PlaylistEventMusic (pl, loop=0, force=0) -* StopEventMusic +* PlayEventMusic (t, priority, loop=0, force=0) +* PlaylistEventMusic (pl, priority, loop=0, force=0) +* StopEventMusic (priority) Arguments: @@ -1393,8 +1393,14 @@ Arguments: * pl (string): a playlist (specified by its ID) * loop (integer): looping or not * force (integer): Terminate any other running event music first. If this flag is 0 and there is already event music playing the new event music is ignored. Event music provided by content developers will usually not set this flag. +* priority (integer): Priority for event music. If there are multiple instances of active event music only the one with the highest priority will play. There can only ever be one instance of event music for any priority level. If event music of higher priority stops and there is event music of lower priority the event music of lower priority starts to play. -Note: An attempt to play a track or playlist that is currently playing is ignored. In this case the track or playlist does not restart. +Note: An attempt to play a track or playlist that is currently playing is ignored. In this case the track or playlist does not restart. Changes in looping behaviour are considered though. + +New games starting with a new format omwgame file can use priorities as the developer sees fit. For old games where automatic injection of scripts and music records take place we define the following priorities: + +* 10: Combat music +* 0: Basic event music ### Transition of Existing System From a06c9c767d1beb2cc1222e3d2ed61a4c8f2cf4e4 Mon Sep 17 00:00:00 2001 From: Capostrophic <21265616+Capostrophic@users.noreply.github.com> Date: Sun, 19 Aug 2018 18:36:43 +0300 Subject: [PATCH 02/44] Treat <> and << operators as < and >< and >> as > in scripts (bug #4597) --- CHANGELOG.md | 1 + components/compiler/scanner.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6d8df78e..4b573766a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -98,6 +98,7 @@ Bug #4575: Weird result of attack animation blending with movement animations Bug #4576: Reset of idle animations when attack can not be started Bug #4591: Attack strength should be 0 if player did not hold the attack button + Bug #4597: <> operator causes a compile error Feature #1645: Casting effects from objects Feature #2606: Editor: Implemented (optional) case sensitive global search Feature #3083: Play animation when NPC is casting spell via script diff --git a/components/compiler/scanner.cpp b/components/compiler/scanner.cpp index bb0fb9374..f159b8b8b 100644 --- a/components/compiler/scanner.cpp +++ b/components/compiler/scanner.cpp @@ -502,6 +502,11 @@ namespace Compiler if (get (c) && c!='=') // <== is a allowed as an alternative to <= :( putback (c); } + else if (c == '<' || c == '>') // Treat <> and << as < + { + special = S_cmpLT; + mErrorHandler.warning (std::string("invalid operator <") + c + ", treating it as <", mLoc); + } else { putback (c); @@ -525,6 +530,11 @@ namespace Compiler if (get (c) && c!='=') // >== is a allowed as an alternative to >= :( putback (c); } + else if (c == '<' || c == '>') // Treat >< and >> as > + { + special = S_cmpGT; + mErrorHandler.warning (std::string("invalid operator >") + c + ", treating it as >", mLoc); + } else { putback (c); From e1afa1c2c38a5b18e4fd493b7b9682569aab7792 Mon Sep 17 00:00:00 2001 From: Thunderforge Date: Mon, 20 Aug 2018 12:49:26 -0500 Subject: [PATCH 03/44] Adding common problems that were previous on the site FAQ The [OpenMW FAQ](https://openmw.org/faq/) currently has two problems on it: a black screen and pink textures due to ST3C issues. Given that these are less common now, and that we have a dedicated space for "common problems" anyway, I figure that we should just move this to these questions to there. --- .../manuals/installation/common-problems.rst | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/docs/source/manuals/installation/common-problems.rst b/docs/source/manuals/installation/common-problems.rst index 543b8ec9b..a44f2d581 100644 --- a/docs/source/manuals/installation/common-problems.rst +++ b/docs/source/manuals/installation/common-problems.rst @@ -47,4 +47,33 @@ Installing game files via Steam on macOS: DISK WRITE ERROR [other entries] } - Restart the Steam client. The download should now proceed. \ No newline at end of file + Restart the Steam client. The download should now proceed. + +In-game textures show up as pink +################################ + +:Symptoms: + Some textures don't show up and are replaced by pink "filler" textures. + +:Cause: + Textures shipped with Morrowind are compressed with S3TC, a texture compression algorithm that was patented in + the United States until October 2017. Software drivers and operating system distributions released before that date + may not include support for this algorithm. + +:Fix: + Upgrade your graphics drivers and/or operating system the latest version. + +Music plays, but only a black screen is shown +############################################# + +:Symptoms: + When launching OpenMW, audio is heard but there is only a black screen. + +:Cause: + This can occur when you did not import the Morrowind.ini file when the launcher asked for it. + +:Fix: + To fix it, you need to delete the `launcher.cfg` file from your configuration path + ([Path description on Wiki](https://wiki.openmw.org/index.php?title=Paths)), then start the launcher, select your + Morrowind installation, and when the launcher asks whether the `Morrowind.ini` file should be imported, make sure + to select "Yes". \ No newline at end of file From 74229490e44e74f9b59cd49f02895091acfce825 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Mon, 20 Aug 2018 21:38:57 +0300 Subject: [PATCH 04/44] Use the correct skill for creature AI weapon hit chance rating --- apps/openmw/mwmechanics/weaponpriority.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwmechanics/weaponpriority.cpp b/apps/openmw/mwmechanics/weaponpriority.cpp index 26c784c4d..9030d6254 100644 --- a/apps/openmw/mwmechanics/weaponpriority.cpp +++ b/apps/openmw/mwmechanics/weaponpriority.cpp @@ -108,11 +108,19 @@ namespace MWMechanics } } - int skill = item.getClass().getEquipmentSkill(item); - if (skill != -1) + if (actor.getClass().isNpc()) { - int value = actor.getClass().getSkill(actor, skill); - rating *= MWMechanics::getHitChance(actor, enemy, value) / 100.f; + int skill = item.getClass().getEquipmentSkill(item); + if (skill != -1) + { + int value = actor.getClass().getSkill(actor, skill); + rating *= MWMechanics::getHitChance(actor, enemy, value) / 100.f; + } + } + else + { + MWWorld::LiveCellRef *ref = actor.get(); + rating *= MWMechanics::getHitChance(actor, enemy, ref->mBase->mData.mCombat) / 100.f; } return rating * rangedMult; From 9b10fe0edb0bc940eea8addecacc696b7f6b2869 Mon Sep 17 00:00:00 2001 From: Thunderforge Date: Tue, 21 Aug 2018 07:03:55 -0500 Subject: [PATCH 05/44] Addiong missing "to" word --- docs/source/manuals/installation/common-problems.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/manuals/installation/common-problems.rst b/docs/source/manuals/installation/common-problems.rst index a44f2d581..0967ea9ef 100644 --- a/docs/source/manuals/installation/common-problems.rst +++ b/docs/source/manuals/installation/common-problems.rst @@ -61,7 +61,7 @@ In-game textures show up as pink may not include support for this algorithm. :Fix: - Upgrade your graphics drivers and/or operating system the latest version. + Upgrade your graphics drivers and/or operating system to the latest version. Music plays, but only a black screen is shown ############################################# From b77d733c3eb50623e8f7ab0407b6feca1be16e3c Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Tue, 21 Aug 2018 16:47:29 +0300 Subject: [PATCH 06/44] Fix freeze in getActorsSidingWith --- apps/openmw/mwmechanics/actors.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 6f5b4eeb8..c28f6df28 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1790,14 +1790,13 @@ namespace MWMechanics // Actors that are targeted by this actor's Follow or Escort packages also side with them for (auto package = stats.getAiSequence().begin(); package != stats.getAiSequence().end(); ++package) { - const MWWorld::Ptr &target = (*package)->getTarget(); - if ((*package)->sideWithTarget() && !target.isEmpty()) + if ((*package)->sideWithTarget() && !(*package)->getTarget().isEmpty()) { if (iteratedActor == actor) { - list.push_back(target); + list.push_back((*package)->getTarget()); } - else if (target == actor) + else if ((*package)->getTarget() == actor) { list.push_back(iteratedActor); } From 910065f38fffce09f8db68d6598e262ad9b25c86 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Tue, 21 Aug 2018 17:02:56 +0300 Subject: [PATCH 07/44] Make some more optimizations to actor processing loops --- apps/openmw/mwmechanics/actors.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index c28f6df28..d203dccf4 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1782,6 +1782,8 @@ namespace MWMechanics if (iteratedActor == getPlayer()) continue; + const bool sameActor = (iteratedActor == actor); + const CreatureStats &stats = iteratedActor.getClass().getCreatureStats(iteratedActor); if (stats.isDead()) continue; @@ -1792,7 +1794,7 @@ namespace MWMechanics { if ((*package)->sideWithTarget() && !(*package)->getTarget().isEmpty()) { - if (iteratedActor == actor) + if (sameActor) { list.push_back((*package)->getTarget()); } @@ -1815,7 +1817,7 @@ namespace MWMechanics for(PtrActorMap::iterator iter(mActors.begin());iter != mActors.end();++iter) { const MWWorld::Ptr &iteratedActor = iter->first; - if (iteratedActor == getPlayer()) + if (iteratedActor == getPlayer() || iteratedActor == actor) continue; const CreatureStats &stats = iteratedActor.getClass().getCreatureStats(iteratedActor); @@ -1878,7 +1880,7 @@ namespace MWMechanics for(PtrActorMap::iterator iter(mActors.begin());iter != mActors.end();++iter) { const MWWorld::Ptr &iteratedActor = iter->first; - if (iteratedActor == getPlayer()) + if (iteratedActor == getPlayer() || iteratedActor == actor) continue; const CreatureStats &stats = iteratedActor.getClass().getCreatureStats(iteratedActor); @@ -1908,8 +1910,11 @@ namespace MWMechanics getObjectsInRange(position, aiProcessingDistance, neighbors); for(auto neighbor = neighbors.begin(); neighbor != neighbors.end(); ++neighbor) { + if (*neighbor == actor) + continue; + const CreatureStats &stats = neighbor->getClass().getCreatureStats(*neighbor); - if (stats.isDead() || *neighbor == actor) + if (stats.isDead()) continue; if (stats.getAiSequence().isInCombat(actor)) From 2b45fd84ead5ee55aa5e00e6bddf61d24ea4bacb Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 19 Aug 2018 20:41:09 +0300 Subject: [PATCH 08/44] Play landing sound manually and ignore land soundgen textkeys (bug #2256) --- CHANGELOG.md | 1 + apps/openmw/mwclass/npc.cpp | 7 +++---- apps/openmw/mwmechanics/character.cpp | 10 ++++++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6d8df78e..a01948943 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ Bug #1990: Sunrise/sunset not set correct Bug #2131: Lustidrike's spell misses the player every time Bug #2222: Fatigue's effect on selling price is backwards + Bug #2256: Landing sound not playing when jumping immediately after landing Bug #2326: After a bound item expires the last equipped item of that type is not automatically re-equipped Bug #2455: Creatures attacks degrade armor Bug #2562: Forcing AI to activate a teleport door sometimes causes a crash diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index c06c3f67c..95d7fa66d 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -1241,11 +1241,10 @@ namespace MWClass { MWBase::World *world = MWBase::Environment::get().getWorld(); osg::Vec3f pos(ptr.getRefData().getPosition().asVec3()); - if(world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr)) + if (world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr)) return "DefaultLandWater"; - if(world->isOnGround(ptr)) - return "DefaultLand"; - return ""; + + return "DefaultLand"; } if(name == "swimleft") return "Swim Left"; diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index c7c6b57d0..be9daee88 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -939,10 +939,10 @@ void CharacterController::handleTextKey(const std::string &groupname, const std: } std::string sound = mPtr.getClass().getSoundIdFromSndGen(mPtr, soundgen); - if(!sound.empty()) + if(!sound.empty() && evt.compare(10, evt.size()-10, "land") != 0) // Don't play landing sounds here { MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); - if(evt.compare(10, evt.size()-10, "left") == 0 || evt.compare(10, evt.size()-10, "right") == 0 || evt.compare(10, evt.size()-10, "land") == 0) + if(evt.compare(10, evt.size()-10, "left") == 0 || evt.compare(10, evt.size()-10, "right") == 0) { // Don't make foot sounds local for the player, it makes sense to keep them // positioned on the ground. @@ -2027,6 +2027,12 @@ void CharacterController::update(float duration) cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1); } } + + // Play landing sound + MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); + std::string sound = cls.getSoundIdFromSndGen(mPtr, "land"); + if (!sound.empty()) + sndMgr->playSound3D(mPtr, sound, 1.f, 1.f, MWSound::Type::Foot, MWSound::PlayMode::NoPlayerLocal); } else { From 5a2e9868c1e65862f6c139da338de41f9e30aa98 Mon Sep 17 00:00:00 2001 From: Thunderforge Date: Tue, 21 Aug 2018 22:13:05 -0500 Subject: [PATCH 09/44] Fixes #3681 This changes the way that the popup works to use [`QtColorDialog::getColor()`](http://doc.qt.io/archives/qt-4.8/qcolordialog.html#getColor) instead of the problematic open() function. Also makes the button change to create the modal dialog when pushed, rather than being a checkbox of sorts --- apps/opencs/view/widget/coloreditor.cpp | 19 +------------------ apps/opencs/view/widget/coloreditor.hpp | 1 - apps/opencs/view/widget/colorpickerpopup.cpp | 13 +++---------- apps/opencs/view/widget/colorpickerpopup.hpp | 2 -- 4 files changed, 4 insertions(+), 31 deletions(-) diff --git a/apps/opencs/view/widget/coloreditor.cpp b/apps/opencs/view/widget/coloreditor.cpp index 5f82f8e26..82ca2b0c9 100644 --- a/apps/opencs/view/widget/coloreditor.cpp +++ b/apps/opencs/view/widget/coloreditor.cpp @@ -1,11 +1,9 @@ #include "coloreditor.hpp" #include -#include #include #include #include -#include #include #include "colorpickerpopup.hpp" @@ -27,9 +25,7 @@ CSVWidget::ColorEditor::ColorEditor(QWidget *parent, const bool popupOnStart) mColorPicker(new ColorPickerPopup(this)), mPopupOnStart(popupOnStart) { - setCheckable(true); connect(this, SIGNAL(clicked()), this, SLOT(showPicker())); - connect(mColorPicker, SIGNAL(hid()), this, SLOT(pickerHid())); connect(mColorPicker, SIGNAL(colorChanged(const QColor &)), this, SLOT(pickerColorChanged(const QColor &))); } @@ -85,20 +81,7 @@ void CSVWidget::ColorEditor::setColor(const int colorInt) void CSVWidget::ColorEditor::showPicker() { - if (isChecked()) - { - mColorPicker->showPicker(calculatePopupPosition(), mColor); - } - else - { - mColorPicker->hide(); - } -} - -void CSVWidget::ColorEditor::pickerHid() -{ - setChecked(false); - emit pickingFinished(); + mColorPicker->showPicker(calculatePopupPosition(), mColor); } void CSVWidget::ColorEditor::pickerColorChanged(const QColor &color) diff --git a/apps/opencs/view/widget/coloreditor.hpp b/apps/opencs/view/widget/coloreditor.hpp index 668f22cc9..368896e42 100644 --- a/apps/opencs/view/widget/coloreditor.hpp +++ b/apps/opencs/view/widget/coloreditor.hpp @@ -45,7 +45,6 @@ namespace CSVWidget private slots: void showPicker(); - void pickerHid(); void pickerColorChanged(const QColor &color); signals: diff --git a/apps/opencs/view/widget/colorpickerpopup.cpp b/apps/opencs/view/widget/colorpickerpopup.cpp index 8e71ce39e..47aab8981 100644 --- a/apps/opencs/view/widget/colorpickerpopup.cpp +++ b/apps/opencs/view/widget/colorpickerpopup.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include @@ -19,7 +18,6 @@ CSVWidget::ColorPickerPopup::ColorPickerPopup(QWidget *parent) mColorPicker->setWindowFlags(Qt::Widget); mColorPicker->setOptions(QColorDialog::NoButtons | QColorDialog::DontUseNativeDialog); mColorPicker->installEventFilter(this); - mColorPicker->open(); connect(mColorPicker, SIGNAL(currentColorChanged(const QColor &)), this, @@ -39,8 +37,9 @@ void CSVWidget::ColorPickerPopup::showPicker(const QPoint &position, const QColo geometry.moveTo(position); setGeometry(geometry); - mColorPicker->setCurrentColor(initialColor); - show(); + // Calling getColor() creates a blocking dialog that will continue execution once the user chooses OK or Cancel + QColor color = mColorPicker->getColor(initialColor); + mColorPicker->setCurrentColor(color); } void CSVWidget::ColorPickerPopup::mousePressEvent(QMouseEvent *event) @@ -63,12 +62,6 @@ void CSVWidget::ColorPickerPopup::mousePressEvent(QMouseEvent *event) QFrame::mousePressEvent(event); } -void CSVWidget::ColorPickerPopup::hideEvent(QHideEvent *event) -{ - QFrame::hideEvent(event); - emit hid(); -} - bool CSVWidget::ColorPickerPopup::eventFilter(QObject *object, QEvent *event) { if (object == mColorPicker && event->type() == QEvent::KeyPress) diff --git a/apps/opencs/view/widget/colorpickerpopup.hpp b/apps/opencs/view/widget/colorpickerpopup.hpp index 602bbdb6d..eb5653f46 100644 --- a/apps/opencs/view/widget/colorpickerpopup.hpp +++ b/apps/opencs/view/widget/colorpickerpopup.hpp @@ -20,11 +20,9 @@ namespace CSVWidget protected: virtual void mousePressEvent(QMouseEvent *event); - virtual void hideEvent(QHideEvent *event); virtual bool eventFilter(QObject *object, QEvent *event); signals: - void hid(); void colorChanged(const QColor &color); }; } From ae0a6a22b3a0cdcfda40dec66e1963e90fdb1930 Mon Sep 17 00:00:00 2001 From: Capostrophic <21265616+Capostrophic@users.noreply.github.com> Date: Wed, 22 Aug 2018 14:43:12 +0300 Subject: [PATCH 10/44] Move "land" check earlier --- apps/openmw/mwmechanics/character.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index be9daee88..686d0924a 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -913,7 +913,8 @@ void CharacterController::handleTextKey(const std::string &groupname, const std: sndMgr->playSound3D(mPtr, evt.substr(7), 1.0f, 1.0f); return; } - if(evt.compare(0, 10, "soundgen: ") == 0) + if(evt.compare(0, 10, "soundgen: ") == 0 + && evt.compare(10, evt.size()-10, "land") != 0) // Morrowind ignores land soundgen for some reason { std::string soundgen = evt.substr(10); @@ -939,7 +940,7 @@ void CharacterController::handleTextKey(const std::string &groupname, const std: } std::string sound = mPtr.getClass().getSoundIdFromSndGen(mPtr, soundgen); - if(!sound.empty() && evt.compare(10, evt.size()-10, "land") != 0) // Don't play landing sounds here + if(!sound.empty()) { MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); if(evt.compare(10, evt.size()-10, "left") == 0 || evt.compare(10, evt.size()-10, "right") == 0) From f74ebb64af6e9d64e6d180de9b49badc424762da Mon Sep 17 00:00:00 2001 From: Capostrophic <21265616+Capostrophic@users.noreply.github.com> Date: Wed, 22 Aug 2018 15:26:21 +0300 Subject: [PATCH 11/44] Correct special case soundgen comparisons --- apps/openmw/mwmechanics/character.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 686d0924a..49e2c4e6d 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -913,8 +913,7 @@ void CharacterController::handleTextKey(const std::string &groupname, const std: sndMgr->playSound3D(mPtr, evt.substr(7), 1.0f, 1.0f); return; } - if(evt.compare(0, 10, "soundgen: ") == 0 - && evt.compare(10, evt.size()-10, "land") != 0) // Morrowind ignores land soundgen for some reason + if(evt.compare(0, 10, "soundgen: ") == 0) { std::string soundgen = evt.substr(10); @@ -939,11 +938,14 @@ void CharacterController::handleTextKey(const std::string &groupname, const std: } } + if (soundgen == "land") // Morrowind ignores land soundgen for some reason + return; + std::string sound = mPtr.getClass().getSoundIdFromSndGen(mPtr, soundgen); if(!sound.empty()) { MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); - if(evt.compare(10, evt.size()-10, "left") == 0 || evt.compare(10, evt.size()-10, "right") == 0) + if(soundgen == "left" || soundgen == "right") { // Don't make foot sounds local for the player, it makes sense to keep them // positioned on the ground. From 3f76f1d3ed4d45e53fb72fdc923dd5389e79a69b Mon Sep 17 00:00:00 2001 From: Capostrophic <21265616+Capostrophic@users.noreply.github.com> Date: Wed, 22 Aug 2018 22:30:46 +0300 Subject: [PATCH 12/44] Fix gold count calculation in pickupObject (bug #4604) --- CHANGELOG.md | 1 + apps/openmw/mwgui/inventorywindow.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b573766a..cf1bf91d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -99,6 +99,7 @@ Bug #4576: Reset of idle animations when attack can not be started Bug #4591: Attack strength should be 0 if player did not hold the attack button Bug #4597: <> operator causes a compile error + Bug #4604: Picking up gold from the ground only makes 1 grabbed Feature #1645: Casting effects from objects Feature #2606: Editor: Implemented (optional) case sensitive global search Feature #3083: Play animation when NPC is casting spell via script diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 0b35bd9de..523409ceb 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -681,6 +681,8 @@ namespace MWGui return; int count = object.getRefData().getCount(); + if (object.getClass().isGold(object)) + count *= object.getClass().getValue(object); MWWorld::Ptr player = MWMechanics::getPlayer(); MWBase::Environment::get().getWorld()->breakInvisibility(player); From 3d4f5536d238d0957e8e53843af4a55eb76f3ee6 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 24 Aug 2018 15:03:54 +0400 Subject: [PATCH 13/44] Check for impact immediately when launch a projectile (bug #3059) --- CHANGELOG.md | 1 + apps/openmw/mwbase/world.hpp | 4 ++-- apps/openmw/mwrender/weaponanimation.cpp | 9 ++++--- apps/openmw/mwworld/worldimp.cpp | 30 +++++++++++++++++++++--- apps/openmw/mwworld/worldimp.hpp | 4 ++-- 5 files changed, 38 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c4c96cf9..1b8afe14b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ 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 #3049: Drain and Fortify effects are not properly applied on health, magicka and fatigue + Bug #3059: Unable to hit with marksman weapons when too close to an enemy Bug #3072: Fatal error on AddItem that has a script containing Equip Bug #3249: Fixed revert function not updating views properly Bug #3374: Touch spells not hitting kwama foragers diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 3c46298b0..5561d13ca 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -490,8 +490,8 @@ namespace MWBase virtual void castSpell (const MWWorld::Ptr& actor, bool manualSpell=false) = 0; virtual void launchMagicBolt (const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection) = 0; - virtual void launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile, - const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength) = 0; + virtual void launchProjectile (MWWorld::Ptr& actor, MWWorld::Ptr& projectile, + const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr& bow, float speed, float attackStrength) = 0; virtual void applyLoopingParticles(const MWWorld::Ptr& ptr) = 0; diff --git a/apps/openmw/mwrender/weaponanimation.cpp b/apps/openmw/mwrender/weaponanimation.cpp index 0b3d000f3..054ce1b1d 100644 --- a/apps/openmw/mwrender/weaponanimation.cpp +++ b/apps/openmw/mwrender/weaponanimation.cpp @@ -123,7 +123,8 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor, float attackStrength) float fThrownWeaponMaxSpeed = gmst.find("fThrownWeaponMaxSpeed")->getFloat(); float speed = fThrownWeaponMinSpeed + (fThrownWeaponMaxSpeed - fThrownWeaponMinSpeed) * attackStrength; - MWBase::Environment::get().getWorld()->launchProjectile(actor, *weapon, launchPos, orient, *weapon, speed, attackStrength); + MWWorld::Ptr weaponPtr = *weapon; + MWBase::Environment::get().getWorld()->launchProjectile(actor, weaponPtr, launchPos, orient, weaponPtr, speed, attackStrength); showWeapon(false); @@ -149,9 +150,11 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor, float attackStrength) float fProjectileMaxSpeed = gmst.find("fProjectileMaxSpeed")->getFloat(); float speed = fProjectileMinSpeed + (fProjectileMaxSpeed - fProjectileMinSpeed) * attackStrength; - MWBase::Environment::get().getWorld()->launchProjectile(actor, *ammo, launchPos, orient, *weapon, speed, attackStrength); + MWWorld::Ptr weaponPtr = *weapon; + MWWorld::Ptr ammoPtr = *ammo; + MWBase::Environment::get().getWorld()->launchProjectile(actor, ammoPtr, launchPos, orient, weaponPtr, speed, attackStrength); - inv.remove(*ammo, 1, actor); + inv.remove(ammoPtr, 1, actor); mAmmunition.reset(); } } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index c2ebac8fc..ae00595bb 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2892,10 +2892,34 @@ namespace MWWorld } } - void World::launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile, - const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength) + void World::launchProjectile (MWWorld::Ptr& actor, MWWorld::Ptr& projectile, + const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr& bow, float speed, float attackStrength) { - mProjectileManager->launchProjectile(actor, projectile, worldPos, orient, bow, speed, attackStrength); + // An initial position of projectile can be outside shooter's collision box, so any object between shooter and launch position will be ignored. + // To avoid this issue, we should check for impact immediately before launch the projectile. + // So we cast a 1-yard-length ray from shooter to launch position and check if there are collisions in this area. + // TODO: as a better solutuon we should handle projectiles during physics update, not during world update. + const osg::Vec3f sourcePos = worldPos + orient * osg::Vec3f(0,-1,0) * 64.f; + + // Early out if the launch position is underwater + bool underwater = MWBase::Environment::get().getWorld()->isUnderwater(MWMechanics::getPlayer().getCell(), worldPos); + if (underwater) + { + mRendering->emitWaterRipple(worldPos); + return; + } + + // For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit result. + std::vector targetActors; + if (!actor.isEmpty() && actor.getClass().isActor() && actor != MWMechanics::getPlayer()) + actor.getClass().getCreatureStats(actor).getAiSequence().getCombatTargets(targetActors); + + // Check for impact, if yes, handle hit, if not, launch projectile + MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(sourcePos, worldPos, actor, targetActors, 0xff, MWPhysics::CollisionType_Projectile); + if (result.mHit) + MWMechanics::projectileHit(actor, result.mHitObject, bow, projectile, result.mHitPos, attackStrength); + else + mProjectileManager->launchProjectile(actor, projectile, worldPos, orient, bow, speed, attackStrength); } void World::launchMagicBolt (const std::string &spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection) diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 432991059..1c055cbf7 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -607,8 +607,8 @@ namespace MWWorld void castSpell (const MWWorld::Ptr& actor, bool manualSpell=false) override; void launchMagicBolt (const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection) override; - void launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile, - const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength) override; + void launchProjectile (MWWorld::Ptr& actor, MWWorld::Ptr& projectile, + const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr& bow, float speed, float attackStrength) override; void applyLoopingParticles(const MWWorld::Ptr& ptr) override; From a560a9e00d93b1bdd00f4971a72b0645c969944c Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sat, 18 Aug 2018 16:12:01 +0400 Subject: [PATCH 14/44] Allow messageboxes arguments to have newline characters (bug #3836) --- CHANGELOG.md | 1 + components/compiler/scanner.cpp | 32 +++++++++++++++++++++++++++----- components/compiler/scanner.hpp | 6 ++++++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c016ca82f..945d114b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ Bug #3591: Angled hit distance too low Bug #3629: DB assassin attack never triggers creature spawning Bug #3788: GetPCInJail and GetPCTraveling do not work as in vanilla + Bug #3836: Script fails to compile when command argument contains "\n" Bug #3876: Landscape texture painting is misaligned Bug #3897: Have Goodbye give all choices the effects of Goodbye Bug #3911: [macOS] Typing in the "Content List name" dialog box produces double characters diff --git a/components/compiler/scanner.cpp b/components/compiler/scanner.cpp index bb0fb9374..257c3314e 100644 --- a/components/compiler/scanner.cpp +++ b/components/compiler/scanner.cpp @@ -306,10 +306,22 @@ namespace Compiler int i = 0; std::string lowerCase = Misc::StringUtils::lowerCase(name); - + bool isKeyword = false; for (; sKeywords[i]; ++i) if (lowerCase==sKeywords[i]) + { + isKeyword = true; break; + } + + // Russian localization and some mods use a quirk - add newline character directly + // to compiled bytecode via HEX-editor to implement multiline messageboxes. + // Of course, original editor will not compile such script. + // Allow messageboxes to bybass the "incomplete string or name" error. + if (lowerCase == "messagebox") + enableIgnoreNewlines(); + else if (isKeyword) + mIgnoreNewline = false; if (sKeywords[i]) { @@ -357,9 +369,14 @@ namespace Compiler // } else if (c=='\n') { - error = true; - mErrorHandler.error ("incomplete string or name", mLoc); - break; + if (mIgnoreNewline) + mErrorHandler.warning ("string contains newline character, make sure that it is intended", mLoc); + else + { + error = true; + mErrorHandler.error ("incomplete string or name", mLoc); + break; + } } } else if (!(c=='"' && name.empty())) @@ -578,7 +595,7 @@ namespace Compiler const Extensions *extensions) : mErrorHandler (errorHandler), mStream (inputStream), mExtensions (extensions), mPutback (Putback_None), mPutbackCode(0), mPutbackInteger(0), mPutbackFloat(0), - mStrictKeywords (false), mTolerantNames (false) + mStrictKeywords (false), mTolerantNames (false), mIgnoreNewline(false) { } @@ -631,6 +648,11 @@ namespace Compiler mExtensions->listKeywords (keywords); } + void Scanner::enableIgnoreNewlines() + { + mIgnoreNewline = true; + } + void Scanner::enableStrictKeywords() { mStrictKeywords = true; diff --git a/components/compiler/scanner.hpp b/components/compiler/scanner.hpp index 49fbaa96a..a431cabb2 100644 --- a/components/compiler/scanner.hpp +++ b/components/compiler/scanner.hpp @@ -39,6 +39,7 @@ namespace Compiler TokenLoc mPutbackLoc; bool mStrictKeywords; bool mTolerantNames; + bool mIgnoreNewline; public: @@ -126,6 +127,11 @@ namespace Compiler void listKeywords (std::vector& keywords); ///< Append all known keywords to \a keywords. + /// Treat newline character as a part of script command. + /// + /// \attention This mode lasts only until the next keyword is reached. + void enableIgnoreNewlines(); + /// Do not accept keywords in quotation marks anymore. /// /// \attention This mode lasts only until the next newline is reached. From 4dd9386c4f04e1e45c1d377e9ac560d9ac0539e2 Mon Sep 17 00:00:00 2001 From: Sophie Kirschner Date: Fri, 24 Aug 2018 16:41:52 +0300 Subject: [PATCH 15/44] Fix error: member access into incomplete type 'SceneUtil::UnrefWorkItem' Fixes compile error encountered on OSX 10.9 with g++ sophie:build pineapple$ g++ --version Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn) Target: x86_64-apple-darwin13.4.0 Thread model: posix The compilation error: [ 24%] Building CXX object apps/openmw/CMakeFiles/openmw.dir/mwrender/renderingmanager.cpp.o In file included from /Users/pineapple/git/openmw/apps/openmw/mwrender/renderingmanager.cpp:1: In file included from /Users/pineapple/git/openmw/apps/openmw/mwrender/renderingmanager.hpp:4: /Users/pineapple/git/openmw/openmw-deps/include/osg/ref_ptr:35:36: error: member access into incomplete type 'SceneUtil::UnrefWorkItem' ~ref_ptr() { if (_ptr) _ptr->unref(); _ptr = 0; } ^ /Users/pineapple/git/openmw/./components/sceneutil/unrefqueue.hpp:14:11: note: in instantiation of member function 'osg::ref_ptr::~ref_ptr' requested here class UnrefQueue : public osg::Referenced ^ /Users/pineapple/git/openmw/./components/sceneutil/unrefqueue.hpp:10:11: note: forward declaration of 'SceneUtil::UnrefWorkItem' class UnrefWorkItem; --- components/sceneutil/unrefqueue.cpp | 22 ++++++---------------- components/sceneutil/unrefqueue.hpp | 12 +++++++++++- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/components/sceneutil/unrefqueue.cpp b/components/sceneutil/unrefqueue.cpp index 42ea31133..271c17af2 100644 --- a/components/sceneutil/unrefqueue.cpp +++ b/components/sceneutil/unrefqueue.cpp @@ -1,28 +1,18 @@ #include "unrefqueue.hpp" -#include - //#include //#include -#include namespace SceneUtil { - - class UnrefWorkItem : public SceneUtil::WorkItem + void UnrefWorkItem::doWork() { - public: - std::deque > mObjects; - - virtual void doWork() - { - //osg::Timer timer; - //size_t objcount = mObjects.size(); - mObjects.clear(); - //Log(Debug::Verbose) << "cleared " << objcount << " objects in " << timer.time_m(); - } - }; + //osg::Timer timer; + //size_t objcount = mObjects.size(); + mObjects.clear(); + //Log(Debug::Verbose) << "cleared " << objcount << " objects in " << timer.time_m(); + } UnrefQueue::UnrefQueue() { diff --git a/components/sceneutil/unrefqueue.hpp b/components/sceneutil/unrefqueue.hpp index 4a2724927..7155e669c 100644 --- a/components/sceneutil/unrefqueue.hpp +++ b/components/sceneutil/unrefqueue.hpp @@ -1,13 +1,23 @@ #ifndef OPENMW_COMPONENTS_UNREFQUEUE_H #define OPENMW_COMPONENTS_UNREFQUEUE_H +#include + #include #include +#include + namespace SceneUtil { class WorkQueue; - class UnrefWorkItem; + + class UnrefWorkItem : public SceneUtil::WorkItem + { + public: + std::deque > mObjects; + virtual void doWork(); + }; /// @brief Handles unreferencing of objects through the WorkQueue. Typical use scenario /// would be the main thread pushing objects that are no longer needed, and the background thread deleting them. From 67055b18c41a2599128f9e7bac1348467dd18a27 Mon Sep 17 00:00:00 2001 From: Thunderforge Date: Fri, 24 Aug 2018 12:51:18 -0500 Subject: [PATCH 16/44] Adding Changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6d8df78e..b77c5be1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ Bug #3533: GetSpellEffects should detect effects with zero duration Bug #3591: Angled hit distance too low Bug #3629: DB assassin attack never triggers creature spawning + Bug #3681: OpenMW-CS: Clicking Scripts in Preferences spawns many color pickers Bug #3788: GetPCInJail and GetPCTraveling do not work as in vanilla Bug #3876: Landscape texture painting is misaligned Bug #3897: Have Goodbye give all choices the effects of Goodbye From de08c1cb1b024761671a00a27621268d66c0fef6 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sat, 25 Aug 2018 10:34:33 +0400 Subject: [PATCH 17/44] Make Move and MoveWorld console commands move actors standing on moving object (bug #2274) --- CHANGELOG.md | 1 + apps/openmw/mwbase/world.hpp | 1 + .../mwscript/transformationextensions.cpp | 35 +++++++++++++------ apps/openmw/mwworld/worldimp.cpp | 5 +++ apps/openmw/mwworld/worldimp.hpp | 1 + 5 files changed, 33 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c4c96cf9..0fe2edb0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Bug #2131: Lustidrike's spell misses the player every time Bug #2222: Fatigue's effect on selling price is backwards Bug #2256: Landing sound not playing when jumping immediately after landing + Bug #2274: Thin platform clips through player character instead of lifting Bug #2326: After a bound item expires the last equipped item of that type is not automatically re-equipped Bug #2455: Creatures attacks degrade armor Bug #2562: Forcing AI to activate a teleport door sometimes causes a crash diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 3c46298b0..115d2a217 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -412,6 +412,7 @@ namespace MWBase /// @note throws an exception when invoked on a teleport door virtual void activateDoor(const MWWorld::Ptr& door, int state) = 0; + virtual void getActorsStandingOn (const MWWorld::ConstPtr& object, std::vector &actors) = 0; ///< get a list of actors standing on \a object virtual bool getPlayerStandingOn (const MWWorld::ConstPtr& object) = 0; ///< @return true if the player is standing on \a object virtual bool getActorStandingOn (const MWWorld::ConstPtr& object) = 0; ///< @return true if any actor is standing on \a object virtual bool getPlayerCollidingWith(const MWWorld::ConstPtr& object) = 0; ///< @return true if the player is colliding with \a object diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 8f0c72519..16d7e8036 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -29,6 +29,18 @@ namespace MWScript { namespace Transformation { + void moveStandingActors(const MWWorld::Ptr &ptr, const osg::Vec3f& diff) + { + std::vector actors; + MWBase::Environment::get().getWorld()->getActorsStandingOn (ptr, actors); + for (auto& actor : actors) + { + osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3()); + actorPos += diff; + MWBase::Environment::get().getWorld()->moveObject(actor, actorPos.x(), actorPos.y(), actorPos.z()); + } + } + template class OpSetScale : public Interpreter::Opcode0 { @@ -666,6 +678,10 @@ namespace MWScript osg::Vec3f diff = ptr.getRefData().getBaseNode()->getAttitude() * posChange; osg::Vec3f worldPos(ptr.getRefData().getPosition().asVec3()); worldPos += diff; + + // We should move actors, standing on moving object, too. + // This approach can be used to create elevators. + moveStandingActors(ptr, diff); MWBase::Environment::get().getWorld()->moveObject(ptr, worldPos.x(), worldPos.y(), worldPos.z()); } }; @@ -688,22 +704,21 @@ namespace MWScript runtime.pop(); const float *objPos = ptr.getRefData().getPosition().pos; + osg::Vec3f diff; - MWWorld::Ptr updated; if (axis == "x") - { - updated = MWBase::Environment::get().getWorld()->moveObject(ptr, objPos[0]+movement, objPos[1], objPos[2]); - } + diff.x() += movement; else if (axis == "y") - { - updated = MWBase::Environment::get().getWorld()->moveObject(ptr, objPos[0], objPos[1]+movement, objPos[2]); - } + diff.y() += movement; else if (axis == "z") - { - updated = MWBase::Environment::get().getWorld()->moveObject(ptr, objPos[0], objPos[1], objPos[2]+movement); - } + diff.z() += movement; else throw std::runtime_error ("invalid movement axis: " + axis); + + // We should move actors, standing on moving object, too. + // This approach can be used to create elevators. + moveStandingActors(ptr, diff); + MWBase::Environment::get().getWorld()->moveObject(ptr, objPos[0]+diff.x(), objPos[1]+diff.y(), objPos[2]+diff.z()); } }; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index c2ebac8fc..3ae5fd317 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2377,6 +2377,11 @@ namespace MWWorld return !actors.empty(); } + void World::getActorsStandingOn (const MWWorld::ConstPtr& object, std::vector &actors) + { + mPhysics->getActorsStandingOn(object, actors); + } + bool World::getPlayerCollidingWith (const MWWorld::ConstPtr& object) { MWWorld::Ptr player = getPlayerPtr(); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 432991059..ca87ae5e3 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -525,6 +525,7 @@ namespace MWWorld /// @note throws an exception when invoked on a teleport door void activateDoor(const MWWorld::Ptr& door, int state) override; + void getActorsStandingOn (const MWWorld::ConstPtr& object, std::vector &actors); ///< get a list of actors standing on \a object bool getPlayerStandingOn (const MWWorld::ConstPtr& object) override; ///< @return true if the player is standing on \a object bool getActorStandingOn (const MWWorld::ConstPtr& object) override; ///< @return true if any actor is standing on \a object bool getPlayerCollidingWith(const MWWorld::ConstPtr& object) override; ///< @return true if the player is colliding with \a object From 4e3ae85c110591094745f7197cc445d913ec6dc3 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 24 Aug 2018 01:54:50 -0700 Subject: [PATCH 18/44] Set the OpenAL source offset after setting the buffer This is to work around a bug in the Rapture3D driver. --- apps/openmw/mwsound/openal_output.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp index 3569cd3da..076162fde 100644 --- a/apps/openmw/mwsound/openal_output.cpp +++ b/apps/openmw/mwsound/openal_output.cpp @@ -1145,14 +1145,24 @@ bool OpenAL_Output::playSound(Sound *sound, Sound_Handle data, float offset) initCommon2D(source, sound->getPosition(), sound->getRealVolume(), sound->getPitch(), sound->getIsLooping(), sound->getUseEnv()); + alSourcei(source, AL_BUFFER, GET_PTRID(data)); alSourcef(source, AL_SEC_OFFSET, offset); if(getALError() != AL_NO_ERROR) + { + alSourceRewind(source); + alSourcei(source, AL_BUFFER, 0); + alGetError(); return false; + } - alSourcei(source, AL_BUFFER, GET_PTRID(data)); alSourcePlay(source); if(getALError() != AL_NO_ERROR) + { + alSourceRewind(source); + alSourcei(source, AL_BUFFER, 0); + alGetError(); return false; + } mFreeSources.pop_front(); sound->mHandle = MAKE_PTRID(source); @@ -1175,14 +1185,24 @@ bool OpenAL_Output::playSound3D(Sound *sound, Sound_Handle data, float offset) initCommon3D(source, sound->getPosition(), sound->getMinDistance(), sound->getMaxDistance(), sound->getRealVolume(), sound->getPitch(), sound->getIsLooping(), sound->getUseEnv()); + alSourcei(source, AL_BUFFER, GET_PTRID(data)); alSourcef(source, AL_SEC_OFFSET, offset); if(getALError() != AL_NO_ERROR) + { + alSourceRewind(source); + alSourcei(source, AL_BUFFER, 0); + alGetError(); return false; + } - alSourcei(source, AL_BUFFER, GET_PTRID(data)); alSourcePlay(source); if(getALError() != AL_NO_ERROR) + { + alSourceRewind(source); + alSourcei(source, AL_BUFFER, 0); + alGetError(); return false; + } mFreeSources.pop_front(); sound->mHandle = MAKE_PTRID(source); From c2b3ca9638199a50f4d2f50cc3fdbdc26496088a Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 24 Aug 2018 05:48:14 -0700 Subject: [PATCH 19/44] Update some comments It wasn't actually a bug in OSX like the comment said, but intended behavior. --- apps/openmw/mwsound/openal_output.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp index 076162fde..42dd6b5fd 100644 --- a/apps/openmw/mwsound/openal_output.cpp +++ b/apps/openmw/mwsound/openal_output.cpp @@ -1217,9 +1217,8 @@ void OpenAL_Output::finishSound(Sound *sound) ALuint source = GET_PTRID(sound->mHandle); sound->mHandle = 0; - // Rewind the stream instead of stopping it, this puts the source into an AL_INITIAL state, - // which works around a bug in the MacOS OpenAL implementation which would otherwise think - // the initial queue already played when it hasn't. + // Rewind the stream to put the source back into an AL_INITIAL state, for + // the next time it's used. alSourceRewind(source); alSourcei(source, AL_BUFFER, 0); getALError(); @@ -1322,9 +1321,8 @@ void OpenAL_Output::finishStream(Stream *sound) sound->mHandle = 0; mStreamThread->remove(stream); - // Rewind the stream instead of stopping it, this puts the source into an AL_INITIAL state, - // which works around a bug in the MacOS OpenAL implementation which would otherwise think - // the initial queue already played when it hasn't. + // Rewind the stream to put the source back into an AL_INITIAL state, for + // the next time it's used. alSourceRewind(source); alSourcei(source, AL_BUFFER, 0); getALError(); From 77bdd0ea662d34f75bb4291e46de55b0e08a5b58 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 25 Aug 2018 01:24:19 -0700 Subject: [PATCH 20/44] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfb77be8d..ef417facb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -129,6 +129,7 @@ Feature #4581: Use proper logging system Task #2490: Don't open command prompt window on Release-mode builds automatically Task #4545: Enable is_pod string test + Task #4606: Support Rapture3D's OpenAL driver 0.44.0 ------ From dd01c4d2240acc21a220f1fd60ac6e6081b1cb05 Mon Sep 17 00:00:00 2001 From: Sophie Kirschner Date: Sat, 25 Aug 2018 11:53:43 +0300 Subject: [PATCH 21/44] Fix: 'sizeof' to an incomplete type 'Video::VideoPlayer' Alternate solution to same problem reported in https://github.com/OpenMW/openmw/pull/1888 --- apps/openmw/mwgui/videowidget.cpp | 2 ++ apps/openmw/mwgui/videowidget.hpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/apps/openmw/mwgui/videowidget.cpp b/apps/openmw/mwgui/videowidget.cpp index 516f5cfcc..28432b811 100644 --- a/apps/openmw/mwgui/videowidget.cpp +++ b/apps/openmw/mwgui/videowidget.cpp @@ -22,6 +22,8 @@ VideoWidget::VideoWidget() setNeedKeyFocus(true); } +VideoWidget::~VideoWidget() = default; + void VideoWidget::setVFS(const VFS::Manager *vfs) { mVFS = vfs; diff --git a/apps/openmw/mwgui/videowidget.hpp b/apps/openmw/mwgui/videowidget.hpp index ac240e69d..20af579a2 100644 --- a/apps/openmw/mwgui/videowidget.hpp +++ b/apps/openmw/mwgui/videowidget.hpp @@ -25,6 +25,8 @@ namespace MWGui MYGUI_RTTI_DERIVED(VideoWidget) VideoWidget(); + + ~VideoWidget(); /// Set the VFS (virtual file system) to find the videos on. void setVFS(const VFS::Manager* vfs); From c6dcfd1fcec013b32f47c60d64e2d0aebeab669e Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sat, 25 Aug 2018 17:26:17 +0400 Subject: [PATCH 22/44] Do not apply scale twice for animated collision nodes (bug #4607) --- CHANGELOG.md | 1 + apps/openmw/mwphysics/physicssystem.cpp | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfb77be8d..735d7683d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -104,6 +104,7 @@ Bug #4591: Attack strength should be 0 if player did not hold the attack button Bug #4597: <> operator causes a compile error Bug #4604: Picking up gold from the ground only makes 1 grabbed + Bug #4607: Scaling for animated collision shapes is applied twice Feature #1645: Casting effects from objects Feature #2606: Editor: Implemented (optional) case sensitive global search Feature #3083: Play animation when NPC is casting spell via script diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 13a0f23ac..2a7b65cac 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -650,7 +650,6 @@ namespace MWPhysics osg::NodePath& nodePath = nodePathFound->second; osg::Matrixf matrix = osg::computeLocalToWorld(nodePath); - osg::Vec3f scale = matrix.getScale(); matrix.orthoNormalize(matrix); btTransform transform; @@ -659,8 +658,8 @@ namespace MWPhysics for (int j=0; j<3; ++j) transform.getBasis()[i][j] = matrix(j,i); // NB column/row major difference - if (compound->getLocalScaling() * toBullet(scale) != compound->getChildShape(shapeIndex)->getLocalScaling()) - compound->getChildShape(shapeIndex)->setLocalScaling(compound->getLocalScaling() * toBullet(scale)); + // Note: we can not apply scaling here for now since we treat scaled shapes + // as new shapes (btScaledBvhTriangleMeshShape) with 1.0 scale for now if (!(transform == compound->getChildTransform(shapeIndex))) compound->updateChildTransform(shapeIndex, transform); } From ff241fb7873ce412282eba10cc6c42a5b87b017e Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 22 Aug 2018 12:48:05 +0400 Subject: [PATCH 23/44] Optimize skinning (task #4605) --- CHANGELOG.md | 1 + components/sceneutil/riggeometry.cpp | 77 ++++++++++++++-------------- 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b573766a..b7f3272d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -124,6 +124,7 @@ Feature #4581: Use proper logging system Task #2490: Don't open command prompt window on Release-mode builds automatically Task #4545: Enable is_pod string test + Task #4605: Optimize skinning 0.44.0 ------ diff --git a/components/sceneutil/riggeometry.cpp b/components/sceneutil/riggeometry.cpp index ee30f1c85..c409bcd5c 100644 --- a/components/sceneutil/riggeometry.cpp +++ b/components/sceneutil/riggeometry.cpp @@ -8,6 +8,31 @@ #include "skeleton.hpp" #include "util.hpp" +namespace +{ + inline void accumulateMatrix(const osg::Matrixf& invBindMatrix, const osg::Matrixf& matrix, const float weight, osg::Matrixf& result) + { + osg::Matrixf m = invBindMatrix * matrix; + float* ptr = m.ptr(); + float* ptrresult = result.ptr(); + ptrresult[0] += ptr[0] * weight; + ptrresult[1] += ptr[1] * weight; + ptrresult[2] += ptr[2] * weight; + + ptrresult[4] += ptr[4] * weight; + ptrresult[5] += ptr[5] * weight; + ptrresult[6] += ptr[6] * weight; + + ptrresult[8] += ptr[8] * weight; + ptrresult[9] += ptr[9] * weight; + ptrresult[10] += ptr[10] * weight; + + ptrresult[12] += ptr[12] * weight; + ptrresult[13] += ptr[13] * weight; + ptrresult[14] += ptr[14] * weight; + } +} + namespace SceneUtil { @@ -141,28 +166,6 @@ bool RigGeometry::initFromParentSkeleton(osg::NodeVisitor* nv) return true; } -void accumulateMatrix(const osg::Matrixf& invBindMatrix, const osg::Matrixf& matrix, float weight, osg::Matrixf& result) -{ - osg::Matrixf m = invBindMatrix * matrix; - float* ptr = m.ptr(); - float* ptrresult = result.ptr(); - ptrresult[0] += ptr[0] * weight; - ptrresult[1] += ptr[1] * weight; - ptrresult[2] += ptr[2] * weight; - - ptrresult[4] += ptr[4] * weight; - ptrresult[5] += ptr[5] * weight; - ptrresult[6] += ptr[6] * weight; - - ptrresult[8] += ptr[8] * weight; - ptrresult[9] += ptr[9] * weight; - ptrresult[10] += ptr[10] * weight; - - ptrresult[12] += ptr[12] * weight; - ptrresult[13] += ptr[13] * weight; - ptrresult[14] += ptr[14] * weight; -} - void RigGeometry::cull(osg::NodeVisitor* nv) { if (!mSkeleton) @@ -173,7 +176,8 @@ void RigGeometry::cull(osg::NodeVisitor* nv) return; } - if ((!mSkeleton->getActive() && mLastFrameNumber != 0) || mLastFrameNumber == nv->getTraversalNumber()) + unsigned int traversalNumber = nv->getTraversalNumber(); + if (mLastFrameNumber == traversalNumber || (mLastFrameNumber != 0 && !mSkeleton->getActive())) { osg::Geometry& geom = *getGeometry(mLastFrameNumber); nv->pushOntoNodePath(&geom); @@ -181,10 +185,10 @@ void RigGeometry::cull(osg::NodeVisitor* nv) nv->popFromNodePath(); return; } - mLastFrameNumber = nv->getTraversalNumber(); + mLastFrameNumber = traversalNumber; osg::Geometry& geom = *getGeometry(mLastFrameNumber); - mSkeleton->updateBoneMatrices(nv->getTraversalNumber()); + mSkeleton->updateBoneMatrices(traversalNumber); // skinning const osg::Vec3Array* positionSrc = static_cast(mSourceGeometry->getVertexArray()); @@ -195,34 +199,31 @@ void RigGeometry::cull(osg::NodeVisitor* nv) osg::Vec3Array* normalDst = static_cast(geom.getNormalArray()); osg::Vec4Array* tangentDst = static_cast(geom.getTexCoordArray(7)); - for (Bone2VertexMap::const_iterator it = mBone2VertexMap.begin(); it != mBone2VertexMap.end(); ++it) + for (auto &pair : mBone2VertexMap) { - osg::Matrixf resultMat (0, 0, 0, 0, + osg::Matrixf resultMat (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1); - for (std::vector::const_iterator weightIt = it->first.begin(); weightIt != it->first.end(); ++weightIt) + for (auto &weight : pair.first) { - Bone* bone = weightIt->first.first; - const osg::Matrix& invBindMatrix = weightIt->first.second; - float weight = weightIt->second; - const osg::Matrixf& boneMatrix = bone->mMatrixInSkeletonSpace; - accumulateMatrix(invBindMatrix, boneMatrix, weight, resultMat); + accumulateMatrix(weight.first.second, weight.first.first->mMatrixInSkeletonSpace, weight.second, resultMat); } + if (mGeomToSkelMatrix) resultMat *= (*mGeomToSkelMatrix); - for (std::vector::const_iterator vertexIt = it->second.begin(); vertexIt != it->second.end(); ++vertexIt) + for (auto &vertex : pair.second) { - unsigned short vertex = *vertexIt; (*positionDst)[vertex] = resultMat.preMult((*positionSrc)[vertex]); if (normalDst) - (*normalDst)[vertex] = osg::Matrix::transform3x3((*normalSrc)[vertex], resultMat); + (*normalDst)[vertex] = osg::Matrixf::transform3x3((*normalSrc)[vertex], resultMat); + if (tangentDst) { - osg::Vec4f srcTangent = (*tangentSrc)[vertex]; - osg::Vec3f transformedTangent = osg::Matrix::transform3x3(osg::Vec3f(srcTangent.x(), srcTangent.y(), srcTangent.z()), resultMat); + const osg::Vec4f& srcTangent = (*tangentSrc)[vertex]; + osg::Vec3f transformedTangent = osg::Matrixf::transform3x3(osg::Vec3f(srcTangent.x(), srcTangent.y(), srcTangent.z()), resultMat); (*tangentDst)[vertex] = osg::Vec4f(transformedTangent, srcTangent.w()); } } From c412f99963f03a4305271dfe00bfd03b500ba274 Mon Sep 17 00:00:00 2001 From: Sophie Kirschner Date: Sun, 26 Aug 2018 11:08:06 +0300 Subject: [PATCH 24/44] Remove commented lines in UnrefWorkItem::doWork --- components/sceneutil/unrefqueue.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/components/sceneutil/unrefqueue.cpp b/components/sceneutil/unrefqueue.cpp index 271c17af2..21ba836c0 100644 --- a/components/sceneutil/unrefqueue.cpp +++ b/components/sceneutil/unrefqueue.cpp @@ -8,10 +8,7 @@ namespace SceneUtil { void UnrefWorkItem::doWork() { - //osg::Timer timer; - //size_t objcount = mObjects.size(); mObjects.clear(); - //Log(Debug::Verbose) << "cleared " << objcount << " objects in " << timer.time_m(); } UnrefQueue::UnrefQueue() From dc68b2ff2681e64d9e4ae61289562b7e1f88065d Mon Sep 17 00:00:00 2001 From: Sophie Kirschner Date: Sun, 26 Aug 2018 11:10:25 +0300 Subject: [PATCH 25/44] Add Sophie Kirschner (me) to AUTHORS.md --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index 3422f28a9..5320a2462 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -153,6 +153,7 @@ Programmers Siimacore sir_herrbatka smbas + Sophie Kirschner (pineapplemachine) spycrab Stefan Galowicz (bogglez) Stanislav Bobrov (Jiub) From 9e253f6a46263f92e8a5939459d66a2d541b4e4c Mon Sep 17 00:00:00 2001 From: Sophie Kirschner Date: Sun, 26 Aug 2018 12:02:49 +0300 Subject: [PATCH 26/44] Add issue #4613 to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6d8df78e..a8a072105 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -123,6 +123,7 @@ Feature #4581: Use proper logging system Task #2490: Don't open command prompt window on Release-mode builds automatically Task #4545: Enable is_pod string test + Task #4613: Incomplete type errors when compiling with g++ on OSX 10.9 0.44.0 ------ From 60698e6f8aab18b612653dc7acd4c242cdf3b3d1 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sun, 26 Aug 2018 21:02:14 +0400 Subject: [PATCH 27/44] Optimize new magic effects update system --- apps/openmw/mwmechanics/actors.cpp | 2 +- apps/openmw/mwmechanics/character.cpp | 3 --- apps/openmw/mwrender/animation.cpp | 32 ++++++++++++++++++++++----- apps/openmw/mwrender/animation.hpp | 3 ++- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index d203dccf4..ba8f62e2f 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1679,7 +1679,7 @@ namespace MWMechanics MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(iter->first); if (animation) - animation->updateEffects(duration); + animation->updateEffects(); } diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 49e2c4e6d..9d5db08b0 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -2219,9 +2219,6 @@ void CharacterController::update(float duration) moved *= (l / newLength); } - if (mSkipAnim) - mAnimation->updateEffects(duration); - if (mFloatToSurface && cls.isActor() && cls.getCreatureStats(mPtr).isDead() && cls.canSwim(mPtr)) moved.z() = 1.0; diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 4da3ec4a8..1ace2f8b4 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -208,8 +208,11 @@ namespace class RemoveFinishedCallbackVisitor : public RemoveVisitor { public: + bool mHasMagicEffects; + RemoveFinishedCallbackVisitor() : RemoveVisitor() + , mHasMagicEffects(false) , mEffectId(-1) { } @@ -234,11 +237,14 @@ namespace { // We should remove empty transformation nodes and finished callbacks here MWRender::UpdateVfxCallback* vfxCallback = dynamic_cast(callback); - bool finished = vfxCallback && vfxCallback->mFinished; - bool toRemove = vfxCallback && mEffectId >= 0 && vfxCallback->mParams.mEffectId == mEffectId; - if (finished || toRemove) + if (vfxCallback) { - mToRemove.push_back(std::make_pair(group.asNode(), group.getParent(0))); + bool finished = vfxCallback->mFinished; + bool toRemove = mEffectId >= 0 && vfxCallback->mParams.mEffectId == mEffectId; + if (finished || toRemove) + mToRemove.push_back(std::make_pair(group.asNode(), group.getParent(0))); + else + mHasMagicEffects = true; } } } @@ -610,6 +616,7 @@ namespace MWRender , mTextKeyListener(NULL) , mHeadYawRadians(0.f) , mHeadPitchRadians(0.f) + , mHasMagicEffects(false) , mAlpha(1.f) { for(size_t i = 0;i < sNumBlendMasks;i++) @@ -1321,7 +1328,7 @@ namespace MWRender ++stateiter; } - updateEffects(duration); + updateEffects(); if (mHeadController) { @@ -1633,6 +1640,9 @@ namespace MWRender SceneUtil::AssignControllerSourcesVisitor assignVisitor(std::shared_ptr(params.mAnimTime)); node->accept(assignVisitor); + // Notify that this animation has attached magic effects + mHasMagicEffects = true; + overrideFirstRootTexture(texture, mResourceSystem, node); } @@ -1641,10 +1651,14 @@ namespace MWRender RemoveFinishedCallbackVisitor visitor(effectId); mInsert->accept(visitor); visitor.remove(); + mHasMagicEffects = visitor.mHasMagicEffects; } void Animation::getLoopingEffects(std::vector &out) const { + if (!mHasMagicEffects) + return; + FindVfxCallbacksVisitor visitor; mInsert->accept(visitor); @@ -1657,13 +1671,19 @@ namespace MWRender } } - void Animation::updateEffects(float duration) + void Animation::updateEffects() { + // We do not need to visit scene every frame. + // We can use a bool flag to check in spellcasting effect found. + if (!mHasMagicEffects) + return; + // TODO: objects without animation still will have // transformation nodes with finished callbacks RemoveFinishedCallbackVisitor visitor; mInsert->accept(visitor); visitor.remove(); + mHasMagicEffects = visitor.mHasMagicEffects; } bool Animation::upperBodyReady() const diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 1da1fe4ef..e10d2c995 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -263,6 +263,7 @@ protected: osg::ref_ptr mHeadController; float mHeadYawRadians; float mHeadPitchRadians; + bool mHasMagicEffects; osg::ref_ptr mGlowLight; osg::ref_ptr mGlowUpdater; @@ -450,7 +451,7 @@ public: void setLoopingEnabled(const std::string &groupname, bool enabled); /// This is typically called as part of runAnimation, but may be called manually if needed. - void updateEffects(float duration); + void updateEffects(); /// Return a node with the specified name, or NULL if not existing. /// @note The matching is case-insensitive. From d448b802ef28d8a5343db3c79a0388490720c1f4 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sun, 26 Aug 2018 22:57:08 +0400 Subject: [PATCH 28/44] Add a small threshold for player turning animations --- apps/openmw/mwmechanics/character.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 49e2c4e6d..46676c076 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -2045,6 +2045,12 @@ void CharacterController::update(float duration) inJump = false; + // Do not play turning animation for player if rotation speed is very slow. + // Actual threshold should take framerate in account. + float rotationThreshold = 0; + if (mPtr == getPlayer()) + rotationThreshold = 0.015 * 60 * duration; + if(std::abs(vec.x()/2.0f) > std::abs(vec.y())) { if(vec.x() > 0.0f) @@ -2069,9 +2075,9 @@ void CharacterController::update(float duration) } else if(rot.z() != 0.0f && !sneak && !(mPtr == getPlayer() && MWBase::Environment::get().getWorld()->isFirstPerson())) { - if(rot.z() > 0.0f) + if(rot.z() > rotationThreshold) movestate = inwater ? CharState_SwimTurnRight : CharState_TurnRight; - else if(rot.z() < 0.0f) + else if(rot.z() < -rotationThreshold) movestate = inwater ? CharState_SwimTurnLeft : CharState_TurnLeft; } } From 8fa6c6f726ac27b54b621795d27208d17c7c7b1d Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Mon, 27 Aug 2018 09:37:08 +0400 Subject: [PATCH 29/44] Update pinned windows in-game (bug #4560) --- CHANGELOG.md | 1 + apps/openmw/mwgui/inventorywindow.cpp | 17 +++++++++++++++++ apps/openmw/mwgui/inventorywindow.hpp | 1 + apps/openmw/mwgui/spellwindow.cpp | 4 ++++ 4 files changed, 23 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34f4dbbad..91e11fb80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -96,6 +96,7 @@ Bug #4553: Forcegreeting on non-actor opens a dialogue window which cannot be closed Bug #4557: Topics with reserved names are handled differently from vanilla Bug #4558: Mesh optimizer: check for reserved node name is case-sensitive + Bug #4560: OpenMW does not update pinned windows properly Bug #4563: Fast travel price logic checks destination cell instead of service actor cell Bug #4565: Underwater view distance should be limited Bug #4573: Player uses headtracking in the 1st-person mode diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 523409ceb..0d37bbff3 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -68,6 +68,7 @@ namespace MWGui , mPreview(new MWRender::InventoryPreview(parent, resourceSystem, MWMechanics::getPlayer())) , mTrading(false) , mScaleFactor(1.0f) + , mUpdateTimer(0.f) { float uiScale = Settings::Manager::getFloat("scaling factor", "GUI"); if (uiScale > 1.0) @@ -631,6 +632,22 @@ namespace MWGui void InventoryWindow::onFrame(float dt) { updateEncumbranceBar(); + + if (mPinned) + { + mUpdateTimer += dt; + if (0.1f < mUpdateTimer) + { + mUpdateTimer = 0; + + // Update pinned inventory in-game + if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) + { + mItemView->update(); + notifyContentChanged(); + } + } + } } void InventoryWindow::setTrading(bool trading) diff --git a/apps/openmw/mwgui/inventorywindow.hpp b/apps/openmw/mwgui/inventorywindow.hpp index d9cf6870c..c60e37363 100644 --- a/apps/openmw/mwgui/inventorywindow.hpp +++ b/apps/openmw/mwgui/inventorywindow.hpp @@ -102,6 +102,7 @@ namespace MWGui bool mTrading; float mScaleFactor; + float mUpdateTimer; void onItemSelected(int index); void onItemSelectedFromSourceModel(int index); diff --git a/apps/openmw/mwgui/spellwindow.cpp b/apps/openmw/mwgui/spellwindow.cpp index 3fe171e4e..38de9288b 100644 --- a/apps/openmw/mwgui/spellwindow.cpp +++ b/apps/openmw/mwgui/spellwindow.cpp @@ -86,6 +86,10 @@ namespace MWGui mUpdateTimer = 0; mSpellView->incrementalUpdate(); } + + // Update effects in-game too if the window is pinned + if (mPinned && !MWBase::Environment::get().getWindowManager()->isGuiMode()) + mSpellIcons->updateWidgets(mEffectBox, false); } void SpellWindow::updateSpells() From 2564fcc37e810a4e9314946172c9c65b454aeabc Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Tue, 28 Aug 2018 03:29:00 +0300 Subject: [PATCH 30/44] Apply sneaking offset to camera while the character is in air (bug #4617) --- CHANGELOG.md | 1 + apps/openmw/mwworld/worldimp.cpp | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0584445c8..023ec4937 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -105,6 +105,7 @@ Bug #4591: Attack strength should be 0 if player did not hold the attack button Bug #4597: <> operator causes a compile error Bug #4604: Picking up gold from the ground only makes 1 grabbed + Bug #4617: First person sneaking offset is not applied while the character is in air Feature #1645: Casting effects from objects Feature #2606: Editor: Implemented (optional) case sensitive global search Feature #3083: Play animation when NPC is casting spell via script diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index a3d7873d7..6194e831f 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1706,11 +1706,10 @@ namespace MWWorld // Sink the camera while sneaking bool sneaking = player.getClass().getCreatureStats(getPlayerPtr()).getStance(MWMechanics::CreatureStats::Stance_Sneak); - bool inair = !isOnGround(player); bool swimming = isSwimming(player); static const float i1stPersonSneakDelta = getStore().get().find("i1stPersonSneakDelta")->getFloat(); - if (sneaking && !(swimming || inair)) + if (sneaking && !swimming) mRendering->getCamera()->setSneakOffset(i1stPersonSneakDelta); else mRendering->getCamera()->setSneakOffset(0.f); From c677f7ca2768262164531385d81b6d2ac29d6f60 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 28 Aug 2018 12:05:27 +0400 Subject: [PATCH 31/44] Rework pulsing light sources (bug #4615) --- CHANGELOG.md | 1 + components/sceneutil/lightcontroller.cpp | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34f4dbbad..f5c990b4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -105,6 +105,7 @@ Bug #4591: Attack strength should be 0 if player did not hold the attack button Bug #4597: <> operator causes a compile error Bug #4604: Picking up gold from the ground only makes 1 grabbed + Bug #4615: Flicker effects for light sources are handled incorrectly Feature #1645: Casting effects from objects Feature #2606: Editor: Implemented (optional) case sensitive global search Feature #3083: Play animation when NPC is casting spell via script diff --git a/components/sceneutil/lightcontroller.cpp b/components/sceneutil/lightcontroller.cpp index e3ea93843..b89cfc4bc 100644 --- a/components/sceneutil/lightcontroller.cpp +++ b/components/sceneutil/lightcontroller.cpp @@ -73,17 +73,15 @@ namespace SceneUtil float cycle_time; float time_distortion; - const float pi = 3.14159265359; - if(mType == LT_Pulse || mType == LT_PulseSlow) { - cycle_time = 2.0f * pi; - time_distortion = mType == LT_Pulse ? 20.0f : 4.f; + cycle_time = 2.0f * osg::PI; + time_distortion = 3.0f; } else { - static const float fa = 0.785398f; - static const float phase_wavelength = 120.0f * pi / fa; + static const float fa = osg::PI / 4.0f; + static const float phase_wavelength = 120.0f * osg::PI / fa; cycle_time = 500.0f; mPhase = std::fmod(mPhase + dt, phase_wavelength); @@ -94,12 +92,14 @@ namespace SceneUtil if(mDirection > 0 && mDeltaCount > +cycle_time) { mDirection = -1.0f; - mDeltaCount = 2.0f*cycle_time - mDeltaCount; + float extra = mDeltaCount - cycle_time; + mDeltaCount -= 2*extra; } if(mDirection < 0 && mDeltaCount < -cycle_time) { mDirection = +1.0f; - mDeltaCount = -2.0f*cycle_time - mDeltaCount; + float extra = cycle_time - mDeltaCount; + mDeltaCount += 2*extra; } static const float fast = 4.0f/1.0f; From 0ddd0e4edc7f5fc9c5cff13117518453965aff47 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 28 Aug 2018 13:41:44 +0400 Subject: [PATCH 32/44] Fix light flicker amplitude calculation --- components/sceneutil/lightcontroller.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/sceneutil/lightcontroller.cpp b/components/sceneutil/lightcontroller.cpp index b89cfc4bc..199b408d7 100644 --- a/components/sceneutil/lightcontroller.cpp +++ b/components/sceneutil/lightcontroller.cpp @@ -26,7 +26,7 @@ namespace float v = 0.0f; for(int i = 0;i < 3;++i) - v += std::sin(fb*time*f[i] + o[1])*m[i]; + v += std::sin(fb*time*f[i] + o[i])*m[i]; return v * s; } From 079b60c1ea25e78445c82edad83af5616303430c Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Tue, 28 Aug 2018 14:28:27 +0300 Subject: [PATCH 33/44] Don't allow actors to use sneaking while flying (bug #4618) --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/character.cpp | 4 ++-- apps/openmw/mwworld/worldimp.cpp | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 023ec4937..e34dee833 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -106,6 +106,7 @@ Bug #4597: <> operator causes a compile error Bug #4604: Picking up gold from the ground only makes 1 grabbed Bug #4617: First person sneaking offset is not applied while the character is in air + Bug #4618: Sneaking is possible while the character is flying Feature #1645: Casting effects from objects Feature #2606: Editor: Implemented (optional) case sensitive global search Feature #3083: Play animation when NPC is casting spell via script diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 49e2c4e6d..a7ef7c816 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1825,9 +1825,9 @@ void CharacterController::update(float duration) { bool onground = world->isOnGround(mPtr); bool inwater = world->isSwimming(mPtr); - bool sneak = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Sneak); bool flying = world->isFlying(mPtr); - // Can't run while flying (see speed formula in Npc/Creature::getSpeed) + // Can't run and sneak while flying (see speed formula in Npc/Creature::getSpeed) + bool sneak = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Sneak) && !flying; bool isrunning = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Run) && !flying; CreatureStats &stats = cls.getCreatureStats(mPtr); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 6194e831f..0bc952e89 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1707,9 +1707,10 @@ namespace MWWorld // Sink the camera while sneaking bool sneaking = player.getClass().getCreatureStats(getPlayerPtr()).getStance(MWMechanics::CreatureStats::Stance_Sneak); bool swimming = isSwimming(player); + bool flying = isFlying(player); static const float i1stPersonSneakDelta = getStore().get().find("i1stPersonSneakDelta")->getFloat(); - if (sneaking && !swimming) + if (sneaking && !swimming && !flying) mRendering->getCamera()->setSneakOffset(i1stPersonSneakDelta); else mRendering->getCamera()->setSneakOffset(0.f); From 7f459f06108b651012daff256e680aa07f0bfbf3 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Tue, 28 Aug 2018 16:42:15 +0300 Subject: [PATCH 34/44] Knockdown and godmode fixes Make sure an incapacitated player is not able to jump Cleanup of redundant player and godmode checks in creature class Make sure the player is not knocked down while in godmode --- apps/openmw/mwclass/creature.cpp | 12 ++---------- apps/openmw/mwclass/npc.cpp | 6 +++++- apps/openmw/mwmechanics/character.cpp | 6 ++++-- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 161711751..7f4694af2 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -253,7 +253,7 @@ namespace MWClass // For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit result. std::vector targetActors; - if (!ptr.isEmpty() && ptr.getClass().isActor() && ptr != MWMechanics::getPlayer()) + if (!ptr.isEmpty() && ptr.getClass().isActor()) ptr.getClass().getCreatureStats(ptr).getAiSequence().getCombatTargets(targetActors); std::pair result = MWBase::Environment::get().getWorld()->getHitContact(ptr, dist, targetActors); @@ -325,9 +325,6 @@ namespace MWClass if (MWMechanics::blockMeleeAttack(ptr, victim, weapon, damage, attackStrength)) damage = 0; - if (victim == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState()) - damage = 0; - MWMechanics::diseaseContact(victim, ptr); victim.getClass().onHit(victim, damage, healthdmg, weapon, ptr, hitPosition, true); @@ -376,11 +373,6 @@ namespace MWClass ptr.getRefData().getLocals().setVarByInt(script, "onpchitme", 1); } - bool godmode = object == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState(); - - if (godmode) - damage = 0; - if (!successful) { // Missed @@ -415,7 +407,7 @@ namespace MWClass if(ishealth) { - if (!attacker.isEmpty() && !godmode) + if (!attacker.isEmpty()) { damage = scaleDamage(damage, attacker, ptr); MWBase::Environment::get().getWorld()->spawnBloodEffect(ptr, hitPosition); diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 95d7fa66d..0b8b60feb 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -992,6 +992,10 @@ namespace MWClass if(getEncumbrance(ptr) > getCapacity(ptr)) return 0.f; + const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); + if (stats.isParalyzed() || stats.getKnockedDown() || stats.isDead()) + return 0.f; + const NpcCustomData *npcdata = static_cast(ptr.getRefData().getCustomData()); const GMST& gmst = getGmst(); const MWMechanics::MagicEffects &mageffects = npcdata->mNpcStats.getMagicEffects(); @@ -1013,7 +1017,7 @@ namespace MWClass x += mageffects.get(ESM::MagicEffect::Jump).getMagnitude() * 64; x *= encumbranceTerm; - if(ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run)) + if(stats.getStance(MWMechanics::CreatureStats::Stance_Run)) x *= gmst.fJumpRunMultiplier->getFloat(); x *= npcdata->mNpcStats.getFatigueTerm(); x -= -627.2f;/*gravity constant*/ diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 49e2c4e6d..2bd3dadac 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1824,6 +1824,7 @@ void CharacterController::update(float duration) else if(!cls.getCreatureStats(mPtr).isDead()) { bool onground = world->isOnGround(mPtr); + bool incapacitated = (cls.getCreatureStats(mPtr).isParalyzed() || cls.getCreatureStats(mPtr).getKnockedDown()); bool inwater = world->isSwimming(mPtr); bool sneak = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Sneak); bool flying = world->isFlying(mPtr); @@ -1942,7 +1943,7 @@ void CharacterController::update(float duration) cls.getCreatureStats(mPtr).setFatigue(fatigue); } - if(sneak || inwater || flying) + if(sneak || inwater || flying || incapacitated) vec.z() = 0.0f; bool inJump = true; @@ -2021,7 +2022,8 @@ void CharacterController::update(float duration) const int acrobaticsSkill = cls.getSkill(mPtr, ESM::Skill::Acrobatics); if (healthLost > (acrobaticsSkill * fatigueTerm)) { - cls.getCreatureStats(mPtr).setKnockedDown(true); + if (!godmode) + cls.getCreatureStats(mPtr).setKnockedDown(true); } else { From 6c47f95677e748e1e2aea4324ab6f1d95824a72a Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Mon, 27 Aug 2018 02:17:49 +0300 Subject: [PATCH 35/44] Make RemoveSpellEffects affect permanent spells (bug #3920) Also make it remove the effects but not the spells themselves --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/activespells.cpp | 8 ++++++-- apps/openmw/mwmechanics/spells.cpp | 13 +++++++++++++ apps/openmw/mwmechanics/spells.hpp | 2 ++ apps/openmw/mwscript/statsextensions.cpp | 1 + 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5453ffb49..f147c7536 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ Bug #3876: Landscape texture painting is misaligned Bug #3897: Have Goodbye give all choices the effects of Goodbye Bug #3911: [macOS] Typing in the "Content List name" dialog box produces double characters + Bug #3920: RemoveSpellEffects doesn't remove constant effects Bug #3948: AiCombat moving target aiming uses incorrect speed for magic projectiles Bug #3950: FLATTEN_STATIC_TRANSFORMS optimization breaks animated collision shapes Bug #3993: Terrain texture blending map is not upscaled diff --git a/apps/openmw/mwmechanics/activespells.cpp b/apps/openmw/mwmechanics/activespells.cpp index 90d29f686..9e523a845 100644 --- a/apps/openmw/mwmechanics/activespells.cpp +++ b/apps/openmw/mwmechanics/activespells.cpp @@ -197,8 +197,12 @@ namespace MWMechanics void ActiveSpells::removeEffects(const std::string &id) { - mSpells.erase(Misc::StringUtils::lowerCase(id)); - mSpellsChanged = true; + TContainer::iterator spell(mSpells.find(id)); + if (spell != end()); + { + spell->second.mEffects.clear(); + mSpellsChanged = true; + } } void ActiveSpells::visitEffectSources(EffectSourceVisitor &visitor) const diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp index ff397f69d..25f301118 100644 --- a/apps/openmw/mwmechanics/spells.cpp +++ b/apps/openmw/mwmechanics/spells.cpp @@ -279,6 +279,19 @@ namespace MWMechanics } } + void Spells::removeEffects(const std::string &id) + { + if (isSpellActive(id)) + { + TContainer::iterator spellIt = mSpells.find(getSpell(id)); + for (long unsigned int i = 0; i != spellIt->first->mEffects.mList.size(); i++) + { + spellIt->second.mPurgedEffects.insert(i); + mSpellsChanged = true; + } + } + } + void Spells::visitEffectSources(EffectSourceVisitor &visitor) const { if (mSpellsChanged) { diff --git a/apps/openmw/mwmechanics/spells.hpp b/apps/openmw/mwmechanics/spells.hpp index c1705b38a..e635f4f56 100644 --- a/apps/openmw/mwmechanics/spells.hpp +++ b/apps/openmw/mwmechanics/spells.hpp @@ -124,6 +124,8 @@ namespace MWMechanics bool hasBlightDisease() const; + void removeEffects(const std::string& id); + void visitEffectSources (MWMechanics::EffectSourceVisitor& visitor) const; void readState (const ESM::SpellState& state); diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 5df767da8..29160d47e 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -501,6 +501,7 @@ namespace MWScript runtime.pop(); ptr.getClass().getCreatureStats (ptr).getActiveSpells().removeEffects(spellid); + ptr.getClass().getCreatureStats (ptr).getSpells().removeEffects(spellid); } }; From ed1f8f7be7b43d1ca6b1154c7b9f33633835d6c6 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Wed, 29 Aug 2018 13:40:37 +0300 Subject: [PATCH 36/44] Remove effects from all active spells with the same ID --- apps/openmw/mwmechanics/activespells.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwmechanics/activespells.cpp b/apps/openmw/mwmechanics/activespells.cpp index 9e523a845..57b009689 100644 --- a/apps/openmw/mwmechanics/activespells.cpp +++ b/apps/openmw/mwmechanics/activespells.cpp @@ -197,11 +197,13 @@ namespace MWMechanics void ActiveSpells::removeEffects(const std::string &id) { - TContainer::iterator spell(mSpells.find(id)); - if (spell != end()); + for (TContainer::iterator spell = mSpells.begin(); spell != mSpells.end(); ++spell) { - spell->second.mEffects.clear(); - mSpellsChanged = true; + if (spell->first == id) + { + spell->second.mEffects.clear(); + mSpellsChanged = true; + } } } From b8ba9092cb1657df934ece8c7d93dae135dab6ea Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Wed, 29 Aug 2018 14:09:43 +0300 Subject: [PATCH 37/44] Purge effects from all permanent spells with the same ID --- apps/openmw/mwmechanics/spells.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp index 25f301118..0a11ed641 100644 --- a/apps/openmw/mwmechanics/spells.cpp +++ b/apps/openmw/mwmechanics/spells.cpp @@ -283,12 +283,18 @@ namespace MWMechanics { if (isSpellActive(id)) { - TContainer::iterator spellIt = mSpells.find(getSpell(id)); - for (long unsigned int i = 0; i != spellIt->first->mEffects.mList.size(); i++) + for (TContainer::iterator spell = mSpells.begin(); spell != mSpells.end(); ++spell) { - spellIt->second.mPurgedEffects.insert(i); - mSpellsChanged = true; + if (spell->first == getSpell(id)) + { + for (long unsigned int i = 0; i != spell->first->mEffects.mList.size(); i++) + { + spell->second.mPurgedEffects.insert(i); + } + } } + + mSpellsChanged = true; } } From 23834b5ed81123fc1426c1490d5bb884d2e437f4 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Wed, 29 Aug 2018 15:09:03 +0300 Subject: [PATCH 38/44] Don't apply falling damage twice (bug #4608) --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/character.cpp | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5453ffb49..528e8963a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -107,6 +107,7 @@ Bug #4597: <> operator causes a compile error Bug #4604: Picking up gold from the ground only makes 1 grabbed Bug #4607: Scaling for animated collision shapes is applied twice + Bug #4608: Falling damage is applied twice Bug #4615: Flicker effects for light sources are handled incorrectly Bug #4617: First person sneaking offset is not applied while the character is in air Bug #4618: Sneaking is possible while the character is flying diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index aca3dde7f..79527f886 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -2012,10 +2012,7 @@ void CharacterController::update(float duration) // inflict fall damages if (!godmode) { - DynamicStat health = cls.getCreatureStats(mPtr).getHealth(); float realHealthLost = static_cast(healthLost * (1.0f - 0.25f * fatigueTerm)); - health.setCurrent(health.getCurrent() - realHealthLost); - cls.getCreatureStats(mPtr).setHealth(health); cls.onHit(mPtr, realHealthLost, true, MWWorld::Ptr(), MWWorld::Ptr(), osg::Vec3f(), true); } From b0ac0b0b225355066a8ba66deb0109efd0d32d55 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Mon, 27 Aug 2018 13:33:50 +0400 Subject: [PATCH 39/44] Do not initialize map every call --- CHANGELOG.md | 1 + components/esm/loadmgef.cpp | 133 +++++++++++++++++++----------------- 2 files changed, 70 insertions(+), 64 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5453ffb49..fec409d48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -138,6 +138,7 @@ Task #4605: Optimize skinning Task #4606: Support Rapture3D's OpenAL driver Task #4613: Incomplete type errors when compiling with g++ on OSX 10.9 + Task #4621: Optimize combat AI 0.44.0 ------ diff --git a/components/esm/loadmgef.cpp b/components/esm/loadmgef.cpp index 9f8ad94e1..75a94f828 100644 --- a/components/esm/loadmgef.cpp +++ b/components/esm/loadmgef.cpp @@ -274,42 +274,45 @@ short MagicEffect::getResistanceEffect(short effect) // Source https://wiki.openmw.org/index.php?title=Research:Magic#Effect_attribute // - std::map effects; - effects[DisintegrateArmor] = Sanctuary; - effects[DisintegrateWeapon] = Sanctuary; - - for (int i=0; i<5; ++i) - effects[DrainAttribute+i] = ResistMagicka; - for (int i=0; i<5; ++i) - effects[DamageAttribute+i] = ResistMagicka; - for (int i=0; i<5; ++i) - effects[AbsorbAttribute+i] = ResistMagicka; - for (int i=0; i<10; ++i) - effects[WeaknessToFire+i] = ResistMagicka; - - effects[Burden] = ResistMagicka; - effects[Charm] = ResistMagicka; - effects[Silence] = ResistMagicka; - effects[Blind] = ResistMagicka; - effects[Sound] = ResistMagicka; - - for (int i=0; i<2; ++i) + static std::map effects; + if (effects.empty()) { - effects[CalmHumanoid+i] = ResistMagicka; - effects[FrenzyHumanoid+i] = ResistMagicka; - effects[DemoralizeHumanoid+i] = ResistMagicka; - effects[RallyHumanoid+i] = ResistMagicka; - } + effects[DisintegrateArmor] = Sanctuary; + effects[DisintegrateWeapon] = Sanctuary; + + for (int i=0; i<5; ++i) + effects[DrainAttribute+i] = ResistMagicka; + for (int i=0; i<5; ++i) + effects[DamageAttribute+i] = ResistMagicka; + for (int i=0; i<5; ++i) + effects[AbsorbAttribute+i] = ResistMagicka; + for (int i=0; i<10; ++i) + effects[WeaknessToFire+i] = ResistMagicka; + + effects[Burden] = ResistMagicka; + effects[Charm] = ResistMagicka; + effects[Silence] = ResistMagicka; + effects[Blind] = ResistMagicka; + effects[Sound] = ResistMagicka; + + for (int i=0; i<2; ++i) + { + effects[CalmHumanoid+i] = ResistMagicka; + effects[FrenzyHumanoid+i] = ResistMagicka; + effects[DemoralizeHumanoid+i] = ResistMagicka; + effects[RallyHumanoid+i] = ResistMagicka; + } - effects[TurnUndead] = ResistMagicka; + effects[TurnUndead] = ResistMagicka; - effects[FireDamage] = ResistFire; - effects[FrostDamage] = ResistFrost; - effects[ShockDamage] = ResistShock; - effects[Vampirism] = ResistCommonDisease; - effects[Corprus] = ResistCorprusDisease; - effects[Poison] = ResistPoison; - effects[Paralyze] = ResistParalysis; + effects[FireDamage] = ResistFire; + effects[FrostDamage] = ResistFrost; + effects[ShockDamage] = ResistShock; + effects[Vampirism] = ResistCommonDisease; + effects[Corprus] = ResistCorprusDisease; + effects[Poison] = ResistPoison; + effects[Paralyze] = ResistParalysis; + } if (effects.find(effect) != effects.end()) return effects[effect]; @@ -319,41 +322,43 @@ short MagicEffect::getResistanceEffect(short effect) short MagicEffect::getWeaknessEffect(short effect) { - std::map effects; - - for (int i=0; i<5; ++i) - effects[DrainAttribute+i] = WeaknessToMagicka; - for (int i=0; i<5; ++i) - effects[DamageAttribute+i] = WeaknessToMagicka; - for (int i=0; i<5; ++i) - effects[AbsorbAttribute+i] = WeaknessToMagicka; - for (int i=0; i<10; ++i) - effects[WeaknessToFire+i] = WeaknessToMagicka; - - effects[Burden] = WeaknessToMagicka; - effects[Charm] = WeaknessToMagicka; - effects[Silence] = WeaknessToMagicka; - effects[Blind] = WeaknessToMagicka; - effects[Sound] = WeaknessToMagicka; - - for (int i=0; i<2; ++i) + static std::map effects; + if (effects.empty()) { - effects[CalmHumanoid+i] = WeaknessToMagicka; - effects[FrenzyHumanoid+i] = WeaknessToMagicka; - effects[DemoralizeHumanoid+i] = WeaknessToMagicka; - effects[RallyHumanoid+i] = WeaknessToMagicka; - } + for (int i=0; i<5; ++i) + effects[DrainAttribute+i] = WeaknessToMagicka; + for (int i=0; i<5; ++i) + effects[DamageAttribute+i] = WeaknessToMagicka; + for (int i=0; i<5; ++i) + effects[AbsorbAttribute+i] = WeaknessToMagicka; + for (int i=0; i<10; ++i) + effects[WeaknessToFire+i] = WeaknessToMagicka; + + effects[Burden] = WeaknessToMagicka; + effects[Charm] = WeaknessToMagicka; + effects[Silence] = WeaknessToMagicka; + effects[Blind] = WeaknessToMagicka; + effects[Sound] = WeaknessToMagicka; + + for (int i=0; i<2; ++i) + { + effects[CalmHumanoid+i] = WeaknessToMagicka; + effects[FrenzyHumanoid+i] = WeaknessToMagicka; + effects[DemoralizeHumanoid+i] = WeaknessToMagicka; + effects[RallyHumanoid+i] = WeaknessToMagicka; + } - effects[TurnUndead] = WeaknessToMagicka; + effects[TurnUndead] = WeaknessToMagicka; - effects[FireDamage] = WeaknessToFire; - effects[FrostDamage] = WeaknessToFrost; - effects[ShockDamage] = WeaknessToShock; - effects[Vampirism] = WeaknessToCommonDisease; - effects[Corprus] = WeaknessToCorprusDisease; - effects[Poison] = WeaknessToPoison; + effects[FireDamage] = WeaknessToFire; + effects[FrostDamage] = WeaknessToFrost; + effects[ShockDamage] = WeaknessToShock; + effects[Vampirism] = WeaknessToCommonDisease; + effects[Corprus] = WeaknessToCorprusDisease; + effects[Poison] = WeaknessToPoison; - effects[Paralyze] = -1; + effects[Paralyze] = -1; + } if (effects.find(effect) != effects.end()) return effects[effect]; From 4c0ef4ddb6b1739d3fc614c877519cf316a21840 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 29 Aug 2018 17:19:31 +0400 Subject: [PATCH 40/44] Do not initialize magic schools map every time we access it --- apps/openmw/mwmechanics/spellcasting.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 76140013d..77b5bc123 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -34,13 +34,17 @@ namespace MWMechanics { ESM::Skill::SkillEnum spellSchoolToSkill(int school) { - std::map schoolSkillMap; // maps spell school to skill id - schoolSkillMap[0] = ESM::Skill::Alteration; - schoolSkillMap[1] = ESM::Skill::Conjuration; - schoolSkillMap[3] = ESM::Skill::Illusion; - schoolSkillMap[2] = ESM::Skill::Destruction; - schoolSkillMap[4] = ESM::Skill::Mysticism; - schoolSkillMap[5] = ESM::Skill::Restoration; + static std::map schoolSkillMap; // maps spell school to skill id + if (schoolSkillMap.empty()) + { + schoolSkillMap[0] = ESM::Skill::Alteration; + schoolSkillMap[1] = ESM::Skill::Conjuration; + schoolSkillMap[3] = ESM::Skill::Illusion; + schoolSkillMap[2] = ESM::Skill::Destruction; + schoolSkillMap[4] = ESM::Skill::Mysticism; + schoolSkillMap[5] = ESM::Skill::Restoration; + } + assert(schoolSkillMap.find(school) != schoolSkillMap.end()); return schoolSkillMap[school]; } From 2cac8b59b1b70d166315d79e26c81ca53fb131dd Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Mon, 27 Aug 2018 13:35:49 +0400 Subject: [PATCH 41/44] Use square distance to target --- apps/openmw/mwmechanics/aisequence.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwmechanics/aisequence.cpp b/apps/openmw/mwmechanics/aisequence.cpp index b64b3568f..cf572abc0 100644 --- a/apps/openmw/mwmechanics/aisequence.cpp +++ b/apps/openmw/mwmechanics/aisequence.cpp @@ -228,7 +228,7 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac { if ((*it)->getTypeId() != AiPackage::TypeIdCombat) break; - MWWorld::Ptr target = static_cast(*it)->getTarget(); + MWWorld::Ptr target = (*it)->getTarget(); // target disappeared (e.g. summoned creatures) if (target.isEmpty()) @@ -242,11 +242,11 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac const ESM::Position &targetPos = target.getRefData().getPosition(); - float distTo = (targetPos.asVec3() - vActorPos).length(); + float distTo = (targetPos.asVec3() - vActorPos).length2(); // Small threshold for changing target if (it == mPackages.begin()) - distTo = std::max(0.f, distTo - 50.f); + distTo = std::max(0.f, distTo - 2500.f); // if a target has higher priority than current target or has same priority but closer if (rating > bestRating || ((distTo < nearestDist) && rating == bestRating)) From 5d54214acb18b92afb676466d61966068c7d8258 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Mon, 27 Aug 2018 13:38:53 +0400 Subject: [PATCH 42/44] Optimize combat action iteration --- apps/openmw/mwmechanics/aicombataction.cpp | 22 ++++------------------ apps/openmw/mwmechanics/spellcasting.cpp | 4 ++++ apps/openmw/mwmechanics/spellcasting.hpp | 2 ++ apps/openmw/mwmechanics/spellpriority.cpp | 5 ++--- apps/openmw/mwmechanics/weaponpriority.cpp | 3 +++ 5 files changed, 15 insertions(+), 21 deletions(-) diff --git a/apps/openmw/mwmechanics/aicombataction.cpp b/apps/openmw/mwmechanics/aicombataction.cpp index 2685e0e0c..421e5a99f 100644 --- a/apps/openmw/mwmechanics/aicombataction.cpp +++ b/apps/openmw/mwmechanics/aicombataction.cpp @@ -190,11 +190,6 @@ namespace MWMechanics for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) { - std::vector equipmentSlots = it->getClass().getEquipmentSlots(*it).first; - if (std::find(equipmentSlots.begin(), equipmentSlots.end(), (int)MWWorld::InventoryStore::Slot_CarriedRight) - == equipmentSlots.end()) - continue; - float rating = rateWeapon(*it, actor, enemy, -1, bestArrowRating, bestBoltRating); if (rating > bestActionRating) { @@ -215,14 +210,12 @@ namespace MWMechanics for (Spells::TIterator it = spells.begin(); it != spells.end(); ++it) { - const ESM::Spell* spell = it->first; - - float rating = rateSpell(spell, actor, enemy); + float rating = rateSpell(it->first, actor, enemy); if (rating > bestActionRating) { bestActionRating = rating; - bestAction.reset(new ActionSpell(spell->mId)); - antiFleeRating = vanillaRateSpell(spell, actor, enemy); + bestAction.reset(new ActionSpell(it->first->mId)); + antiFleeRating = vanillaRateSpell(it->first, actor, enemy); } } @@ -265,11 +258,6 @@ namespace MWMechanics for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) { - std::vector equipmentSlots = it->getClass().getEquipmentSlots(*it).first; - if (std::find(equipmentSlots.begin(), equipmentSlots.end(), (int)MWWorld::InventoryStore::Slot_CarriedRight) - == equipmentSlots.end()) - continue; - float rating = rateWeapon(*it, actor, enemy, -1, bestArrowRating, bestBoltRating); if (rating > bestActionRating) { @@ -280,9 +268,7 @@ namespace MWMechanics for (Spells::TIterator it = spells.begin(); it != spells.end(); ++it) { - const ESM::Spell* spell = it->first; - - float rating = rateSpell(spell, actor, enemy); + float rating = rateSpell(it->first, actor, enemy); if (rating > bestActionRating) { bestActionRating = rating; diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 77b5bc123..1d7b1783e 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -52,7 +52,11 @@ namespace MWMechanics float calcEffectCost(const ESM::ENAMstruct& effect) { const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find(effect.mEffectID); + return calcEffectCost(effect, magicEffect); + } + float calcEffectCost(const ESM::ENAMstruct& effect, const ESM::MagicEffect* magicEffect) + { int minMagn = 1; int maxMagn = 1; if (!(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) diff --git a/apps/openmw/mwmechanics/spellcasting.hpp b/apps/openmw/mwmechanics/spellcasting.hpp index 72f6a1f4a..2844e7f23 100644 --- a/apps/openmw/mwmechanics/spellcasting.hpp +++ b/apps/openmw/mwmechanics/spellcasting.hpp @@ -3,6 +3,7 @@ #include #include +#include #include "../mwworld/ptr.hpp" @@ -25,6 +26,7 @@ namespace MWMechanics ESM::Skill::SkillEnum spellSchoolToSkill(int school); float calcEffectCost(const ESM::ENAMstruct& effect); + float calcEffectCost(const ESM::ENAMstruct& effect, const ESM::MagicEffect* magicEffect); bool isSummoningEffect(int effectId); diff --git a/apps/openmw/mwmechanics/spellpriority.cpp b/apps/openmw/mwmechanics/spellpriority.cpp index 7bedb1e37..afe6329a2 100644 --- a/apps/openmw/mwmechanics/spellpriority.cpp +++ b/apps/openmw/mwmechanics/spellpriority.cpp @@ -515,8 +515,6 @@ namespace MWMechanics return 0.f; } - const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find(effect.mEffectID); - // Underwater casting not possible if (effect.mRange == ESM::RT_Target) { @@ -530,6 +528,7 @@ namespace MWMechanics return 0.f; } + const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find(effect.mEffectID); if (magicEffect->mData.mFlags & ESM::MagicEffect::Harmful) { rating *= -1.f; @@ -565,7 +564,7 @@ namespace MWMechanics } } - rating *= calcEffectCost(effect); + rating *= calcEffectCost(effect, magicEffect); // Currently treating all "on target" or "on touch" effects to target the enemy actor. // Combat AI is egoistic, so doesn't consider applying positive effects to friendly actors. diff --git a/apps/openmw/mwmechanics/weaponpriority.cpp b/apps/openmw/mwmechanics/weaponpriority.cpp index 9030d6254..81bd08626 100644 --- a/apps/openmw/mwmechanics/weaponpriority.cpp +++ b/apps/openmw/mwmechanics/weaponpriority.cpp @@ -29,6 +29,9 @@ namespace MWMechanics if (type != -1 && weapon->mData.mType != type) return 0.f; + if (type == -1 && (weapon->mData.mType == ESM::Weapon::Arrow || weapon->mData.mType == ESM::Weapon::Bolt)) + return 0.f; + float rating=0.f; float rangedMult=1.f; From 7ef6fa9f61ad174bbc74c3cbce19756608e183c9 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Wed, 29 Aug 2018 18:38:12 +0300 Subject: [PATCH 43/44] Remove deprecated GMST get* functions --- apps/openmw/mwclass/armor.cpp | 8 +- apps/openmw/mwclass/creature.cpp | 22 ++-- apps/openmw/mwclass/creaturelevlist.cpp | 4 +- apps/openmw/mwclass/ingredient.cpp | 2 +- apps/openmw/mwclass/npc.cpp | 64 +++++------ apps/openmw/mwclass/weapon.cpp | 6 +- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 4 +- apps/openmw/mwgui/dialogue.cpp | 40 +++---- apps/openmw/mwgui/enchantingdialog.cpp | 2 +- apps/openmw/mwgui/hud.cpp | 4 +- apps/openmw/mwgui/jailscreen.cpp | 10 +- apps/openmw/mwgui/merchantrepair.cpp | 4 +- apps/openmw/mwgui/recharge.cpp | 2 +- apps/openmw/mwgui/spellbuyingwindow.cpp | 2 +- apps/openmw/mwgui/spellcreationdialog.cpp | 10 +- apps/openmw/mwgui/spellicons.cpp | 2 +- apps/openmw/mwgui/statswindow.cpp | 4 +- apps/openmw/mwgui/tradewindow.cpp | 6 +- apps/openmw/mwgui/trainingwindow.cpp | 4 +- apps/openmw/mwgui/travelwindow.cpp | 6 +- apps/openmw/mwgui/waitdialog.cpp | 6 +- apps/openmw/mwgui/windowmanagerimp.cpp | 2 +- apps/openmw/mwinput/inputmanagerimp.cpp | 2 +- apps/openmw/mwmechanics/actors.cpp | 52 ++++----- apps/openmw/mwmechanics/aibreathe.cpp | 2 +- apps/openmw/mwmechanics/aicombat.cpp | 18 +-- apps/openmw/mwmechanics/aicombataction.cpp | 28 ++--- apps/openmw/mwmechanics/aiwander.cpp | 6 +- apps/openmw/mwmechanics/alchemy.cpp | 12 +- apps/openmw/mwmechanics/autocalcspell.cpp | 18 +-- apps/openmw/mwmechanics/character.cpp | 34 +++--- apps/openmw/mwmechanics/combat.cpp | 54 ++++----- apps/openmw/mwmechanics/creaturestats.cpp | 4 +- apps/openmw/mwmechanics/difficultyscaling.cpp | 2 +- apps/openmw/mwmechanics/disease.hpp | 4 +- apps/openmw/mwmechanics/enchanting.cpp | 14 +-- .../mwmechanics/mechanicsmanagerimp.cpp | 106 +++++++++--------- apps/openmw/mwmechanics/npcstats.cpp | 28 ++--- apps/openmw/mwmechanics/pickpocket.cpp | 6 +- apps/openmw/mwmechanics/repair.cpp | 4 +- apps/openmw/mwmechanics/security.cpp | 4 +- apps/openmw/mwmechanics/spellcasting.cpp | 14 +-- apps/openmw/mwmechanics/spellpriority.cpp | 4 +- apps/openmw/mwmechanics/trading.cpp | 6 +- apps/openmw/mwmechanics/weaponpriority.cpp | 6 +- apps/openmw/mwphysics/physicssystem.cpp | 8 +- apps/openmw/mwrender/weaponanimation.cpp | 8 +- apps/openmw/mwsound/soundmanagerimp.cpp | 16 +-- apps/openmw/mwworld/cellstore.cpp | 4 +- apps/openmw/mwworld/inventorystore.cpp | 6 +- apps/openmw/mwworld/player.cpp | 8 +- apps/openmw/mwworld/projectilemanager.cpp | 2 +- apps/openmw/mwworld/weather.cpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 16 +-- components/esm/loadgmst.cpp | 15 --- components/esm/loadgmst.hpp | 11 -- 56 files changed, 356 insertions(+), 382 deletions(-) diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index 0d267046f..b90c1ec58 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -142,14 +142,14 @@ namespace MWClass const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); - float iWeight = floor(gmst.find(typeGmst)->getFloat()); + float iWeight = floor(gmst.find(typeGmst)->mValue.getFloat()); float epsilon = 0.0005f; - if (ref->mBase->mData.mWeight <= iWeight * gmst.find ("fLightMaxMod")->getFloat() + epsilon) + if (ref->mBase->mData.mWeight <= iWeight * gmst.find ("fLightMaxMod")->mValue.getFloat() + epsilon) return ESM::Skill::LightArmor; - if (ref->mBase->mData.mWeight <= iWeight * gmst.find ("fMedMaxMod")->getFloat() + epsilon) + if (ref->mBase->mData.mWeight <= iWeight * gmst.find ("fMedMaxMod")->mValue.getFloat() + epsilon) return ESM::Skill::MediumArmor; else @@ -285,7 +285,7 @@ namespace MWClass int armorSkill = actor.getClass().getSkill(actor, armorSkillType); const MWBase::World *world = MWBase::Environment::get().getWorld(); - int iBaseArmorSkill = world->getStore().get().find("iBaseArmorSkill")->getInt(); + int iBaseArmorSkill = world->getStore().get().find("iBaseArmorSkill")->mValue.getInteger(); if(ref->mBase->mData.mWeight == 0) return ref->mBase->mData.mArmor; diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 7f4694af2..6999558ae 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -247,7 +247,7 @@ namespace MWClass MWMechanics::applyFatigueLoss(ptr, weapon, attackStrength); - float dist = gmst.find("fCombatDistance")->getFloat(); + float dist = gmst.find("fCombatDistance")->mValue.getFloat(); if (!weapon.isEmpty()) dist *= weapon.get()->mBase->mData.mReach; @@ -394,9 +394,9 @@ namespace MWClass if (!attacker.isEmpty()) { // Check for knockdown - float agilityTerm = stats.getAttribute(ESM::Attribute::Agility).getModified() * getGmst().fKnockDownMult->getFloat(); + float agilityTerm = stats.getAttribute(ESM::Attribute::Agility).getModified() * getGmst().fKnockDownMult->mValue.getFloat(); float knockdownTerm = stats.getAttribute(ESM::Attribute::Agility).getModified() - * getGmst().iKnockDownOddsMult->getInt() * 0.01f + getGmst().iKnockDownOddsBase->getInt(); + * getGmst().iKnockDownOddsMult->mValue.getInteger() * 0.01f + getGmst().iKnockDownOddsBase->mValue.getInteger(); if (ishealth && agilityTerm <= damage && knockdownTerm <= Misc::Rng::roll0to99()) stats.setKnockedDown(true); else @@ -516,8 +516,8 @@ namespace MWClass const GMST& gmst = getGmst(); - float walkSpeed = gmst.fMinWalkSpeedCreature->getFloat() + 0.01f * stats.getAttribute(ESM::Attribute::Speed).getModified() - * (gmst.fMaxWalkSpeedCreature->getFloat() - gmst.fMinWalkSpeedCreature->getFloat()); + float walkSpeed = gmst.fMinWalkSpeedCreature->mValue.getFloat() + 0.01f * stats.getAttribute(ESM::Attribute::Speed).getModified() + * (gmst.fMaxWalkSpeedCreature->mValue.getFloat() - gmst.fMinWalkSpeedCreature->mValue.getFloat()); const MWBase::World *world = MWBase::Environment::get().getWorld(); const MWMechanics::MagicEffects &mageffects = stats.getMagicEffects(); @@ -536,9 +536,9 @@ namespace MWClass { float flySpeed = 0.01f*(stats.getAttribute(ESM::Attribute::Speed).getModified() + mageffects.get(ESM::MagicEffect::Levitate).getMagnitude()); - flySpeed = gmst.fMinFlySpeed->getFloat() + flySpeed*(gmst.fMaxFlySpeed->getFloat() - gmst.fMinFlySpeed->getFloat()); + flySpeed = gmst.fMinFlySpeed->mValue.getFloat() + flySpeed*(gmst.fMaxFlySpeed->mValue.getFloat() - gmst.fMinFlySpeed->mValue.getFloat()); const float normalizedEncumbrance = getNormalizedEncumbrance(ptr); - flySpeed *= 1.0f - gmst.fEncumberedMoveEffect->getFloat() * normalizedEncumbrance; + flySpeed *= 1.0f - gmst.fEncumberedMoveEffect->mValue.getFloat() * normalizedEncumbrance; flySpeed = std::max(0.0f, flySpeed); moveSpeed = flySpeed; } @@ -548,8 +548,8 @@ namespace MWClass if(running) swimSpeed = runSpeed; swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).getMagnitude(); - swimSpeed *= gmst.fSwimRunBase->getFloat() + 0.01f*getSkill(ptr, ESM::Skill::Athletics) * - gmst.fSwimRunAthleticsMult->getFloat(); + swimSpeed *= gmst.fSwimRunBase->mValue.getFloat() + 0.01f*getSkill(ptr, ESM::Skill::Athletics) * + gmst.fSwimRunAthleticsMult->mValue.getFloat(); moveSpeed = swimSpeed; } else if(running) @@ -814,8 +814,8 @@ namespace MWClass return; const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); - static const float fCorpseRespawnDelay = gmst.find("fCorpseRespawnDelay")->getFloat(); - static const float fCorpseClearDelay = gmst.find("fCorpseClearDelay")->getFloat(); + static const float fCorpseRespawnDelay = gmst.find("fCorpseRespawnDelay")->mValue.getFloat(); + static const float fCorpseClearDelay = gmst.find("fCorpseClearDelay")->mValue.getFloat(); float delay = ptr.getRefData().getCount() == 0 ? fCorpseClearDelay : std::min(fCorpseRespawnDelay, fCorpseClearDelay); diff --git a/apps/openmw/mwclass/creaturelevlist.cpp b/apps/openmw/mwclass/creaturelevlist.cpp index 4a4d9793e..b8c4cbb62 100644 --- a/apps/openmw/mwclass/creaturelevlist.cpp +++ b/apps/openmw/mwclass/creaturelevlist.cpp @@ -56,8 +56,8 @@ namespace MWClass else if (creatureStats.isDead()) { const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); - static const float fCorpseRespawnDelay = gmst.find("fCorpseRespawnDelay")->getFloat(); - static const float fCorpseClearDelay = gmst.find("fCorpseClearDelay")->getFloat(); + static const float fCorpseRespawnDelay = gmst.find("fCorpseRespawnDelay")->mValue.getFloat(); + static const float fCorpseClearDelay = gmst.find("fCorpseClearDelay")->mValue.getFloat(); float delay = std::min(fCorpseRespawnDelay, fCorpseClearDelay); if (creatureStats.getTimeOfDeath() + delay <= MWBase::Environment::get().getWorld()->getTimeStamp()) diff --git a/apps/openmw/mwclass/ingredient.cpp b/apps/openmw/mwclass/ingredient.cpp index df7c61ebf..c133b6a26 100644 --- a/apps/openmw/mwclass/ingredient.cpp +++ b/apps/openmw/mwclass/ingredient.cpp @@ -138,7 +138,7 @@ namespace MWClass int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase(); static const float fWortChanceValue = - MWBase::Environment::get().getWorld()->getStore().get().find("fWortChanceValue")->getFloat(); + MWBase::Environment::get().getWorld()->getStore().get().find("fWortChanceValue")->mValue.getFloat(); MWGui::Widgets::SpellEffectList list; for (int i=0; i<4; ++i) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 0b8b60feb..c247ee543 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -372,9 +372,9 @@ namespace MWClass if (!ref->mBase->mFaction.empty()) { static const int iAutoRepFacMod = MWBase::Environment::get().getWorld()->getStore().get() - .find("iAutoRepFacMod")->getInt(); + .find("iAutoRepFacMod")->mValue.getInteger(); static const int iAutoRepLevMod = MWBase::Environment::get().getWorld()->getStore().get() - .find("iAutoRepLevMod")->getInt(); + .find("iAutoRepLevMod")->mValue.getInteger(); int rank = ref->mBase->getFactionRank(); data->mNpcStats.setReputation(iAutoRepFacMod * (rank+1) + iAutoRepLevMod * (data->mNpcStats.getLevel()-1)); @@ -528,7 +528,7 @@ namespace MWClass const MWBase::World *world = MWBase::Environment::get().getWorld(); const MWWorld::Store &store = world->getStore().get(); - return store.find("sWerewolfPopup")->getString(); + return store.find("sWerewolfPopup")->mValue.getString(); } const MWWorld::LiveCellRef *ref = ptr.get(); @@ -565,10 +565,10 @@ namespace MWClass MWMechanics::applyFatigueLoss(ptr, weapon, attackStrength); - const float fCombatDistance = store.find("fCombatDistance")->getFloat(); + const float fCombatDistance = store.find("fCombatDistance")->mValue.getFloat(); float dist = fCombatDistance * (!weapon.isEmpty() ? weapon.get()->mBase->mData.mReach : - store.find("fHandToHandReach")->getFloat()); + store.find("fHandToHandReach")->mValue.getFloat()); // For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit result. std::vector targetActors; @@ -638,14 +638,14 @@ namespace MWClass && !MWBase::Environment::get().getMechanicsManager()->awarenessCheck(ptr, victim); if(unaware) { - damage *= store.find("fCombatCriticalStrikeMult")->getFloat(); + damage *= store.find("fCombatCriticalStrikeMult")->mValue.getFloat(); MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}"); MWBase::Environment::get().getSoundManager()->playSound3D(victim, "critical damage", 1.0f, 1.0f); } } if (othercls.getCreatureStats(victim).getKnockedDown()) - damage *= store.find("fCombatKODamageMult")->getFloat(); + damage *= store.find("fCombatKODamageMult")->mValue.getFloat(); // Apply "On hit" enchanted weapons MWMechanics::applyOnStrikeEnchantment(ptr, victim, weapon, hitPosition); @@ -737,14 +737,14 @@ namespace MWClass const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); const GMST& gmst = getGmst(); - int chance = store.get().find("iVoiceHitOdds")->getInt(); + int chance = store.get().find("iVoiceHitOdds")->mValue.getInteger(); if (Misc::Rng::roll0to99() < chance) MWBase::Environment::get().getDialogueManager()->say(ptr, "hit"); // Check for knockdown - float agilityTerm = stats.getAttribute(ESM::Attribute::Agility).getModified() * gmst.fKnockDownMult->getFloat(); + float agilityTerm = stats.getAttribute(ESM::Attribute::Agility).getModified() * gmst.fKnockDownMult->mValue.getFloat(); float knockdownTerm = stats.getAttribute(ESM::Attribute::Agility).getModified() - * gmst.iKnockDownOddsMult->getInt() * 0.01f + gmst.iKnockDownOddsBase->getInt(); + * gmst.iKnockDownOddsMult->mValue.getInteger() * 0.01f + gmst.iKnockDownOddsBase->mValue.getInteger(); if (ishealth && agilityTerm <= damage && knockdownTerm <= Misc::Rng::roll0to99()) stats.setKnockedDown(true); else @@ -772,7 +772,7 @@ namespace MWClass float unmitigatedDamage = damage; float x = damage / (damage + getArmorRating(ptr)); - damage *= std::max(gmst.fCombatArmorMinMult->getFloat(), x); + damage *= std::max(gmst.fCombatArmorMinMult->mValue.getFloat(), x); int damageDiff = static_cast(unmitigatedDamage - damage); damage = std::max(1.f, damage); damageDiff = std::max(1, damageDiff); @@ -941,15 +941,15 @@ namespace MWClass bool sneaking = stats.getStance(MWMechanics::CreatureStats::Stance_Sneak); bool running = stats.getStance(MWMechanics::CreatureStats::Stance_Run); - float walkSpeed = gmst.fMinWalkSpeed->getFloat() + 0.01f*npcdata->mNpcStats.getAttribute(ESM::Attribute::Speed).getModified()* - (gmst.fMaxWalkSpeed->getFloat() - gmst.fMinWalkSpeed->getFloat()); - walkSpeed *= 1.0f - gmst.fEncumberedMoveEffect->getFloat()*normalizedEncumbrance; + float walkSpeed = gmst.fMinWalkSpeed->mValue.getFloat() + 0.01f*npcdata->mNpcStats.getAttribute(ESM::Attribute::Speed).getModified()* + (gmst.fMaxWalkSpeed->mValue.getFloat() - gmst.fMinWalkSpeed->mValue.getFloat()); + walkSpeed *= 1.0f - gmst.fEncumberedMoveEffect->mValue.getFloat()*normalizedEncumbrance; walkSpeed = std::max(0.0f, walkSpeed); if(sneaking) - walkSpeed *= gmst.fSneakSpeedMultiplier->getFloat(); + walkSpeed *= gmst.fSneakSpeedMultiplier->mValue.getFloat(); float runSpeed = walkSpeed*(0.01f * npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified() * - gmst.fAthleticsRunBonus->getFloat() + gmst.fBaseRunMultiplier->getFloat()); + gmst.fAthleticsRunBonus->mValue.getFloat() + gmst.fBaseRunMultiplier->mValue.getFloat()); float moveSpeed; if(getEncumbrance(ptr) > getCapacity(ptr)) @@ -959,8 +959,8 @@ namespace MWClass { float flySpeed = 0.01f*(npcdata->mNpcStats.getAttribute(ESM::Attribute::Speed).getModified() + mageffects.get(ESM::MagicEffect::Levitate).getMagnitude()); - flySpeed = gmst.fMinFlySpeed->getFloat() + flySpeed*(gmst.fMaxFlySpeed->getFloat() - gmst.fMinFlySpeed->getFloat()); - flySpeed *= 1.0f - gmst.fEncumberedMoveEffect->getFloat() * normalizedEncumbrance; + flySpeed = gmst.fMinFlySpeed->mValue.getFloat() + flySpeed*(gmst.fMaxFlySpeed->mValue.getFloat() - gmst.fMinFlySpeed->mValue.getFloat()); + flySpeed *= 1.0f - gmst.fEncumberedMoveEffect->mValue.getFloat() * normalizedEncumbrance; flySpeed = std::max(0.0f, flySpeed); moveSpeed = flySpeed; } @@ -970,8 +970,8 @@ namespace MWClass if(running) swimSpeed = runSpeed; swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).getMagnitude(); - swimSpeed *= gmst.fSwimRunBase->getFloat() + 0.01f*npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified()* - gmst.fSwimRunAthleticsMult->getFloat(); + swimSpeed *= gmst.fSwimRunBase->mValue.getFloat() + 0.01f*npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified()* + gmst.fSwimRunAthleticsMult->mValue.getFloat(); moveSpeed = swimSpeed; } else if(running && !sneaking) @@ -982,7 +982,7 @@ namespace MWClass moveSpeed *= 0.75f; if(npcdata->mNpcStats.isWerewolf() && running && npcdata->mNpcStats.getDrawState() == MWMechanics::DrawState_Nothing) - moveSpeed *= gmst.fWereWolfRunMult->getFloat(); + moveSpeed *= gmst.fWereWolfRunMult->mValue.getFloat(); return moveSpeed; } @@ -999,8 +999,8 @@ namespace MWClass const NpcCustomData *npcdata = static_cast(ptr.getRefData().getCustomData()); const GMST& gmst = getGmst(); const MWMechanics::MagicEffects &mageffects = npcdata->mNpcStats.getMagicEffects(); - const float encumbranceTerm = gmst.fJumpEncumbranceBase->getFloat() + - gmst.fJumpEncumbranceMultiplier->getFloat() * + const float encumbranceTerm = gmst.fJumpEncumbranceBase->mValue.getFloat() + + gmst.fJumpEncumbranceMultiplier->mValue.getFloat() * (1.0f - Npc::getNormalizedEncumbrance(ptr)); float a = static_cast(npcdata->mNpcStats.getSkill(ESM::Skill::Acrobatics).getModified()); @@ -1011,14 +1011,14 @@ namespace MWClass a = 50.0f; } - float x = gmst.fJumpAcrobaticsBase->getFloat() + - std::pow(a / 15.0f, gmst.fJumpAcroMultiplier->getFloat()); - x += 3.0f * b * gmst.fJumpAcroMultiplier->getFloat(); + float x = gmst.fJumpAcrobaticsBase->mValue.getFloat() + + std::pow(a / 15.0f, gmst.fJumpAcroMultiplier->mValue.getFloat()); + x += 3.0f * b * gmst.fJumpAcroMultiplier->mValue.getFloat(); x += mageffects.get(ESM::MagicEffect::Jump).getMagnitude() * 64; x *= encumbranceTerm; if(stats.getStance(MWMechanics::CreatureStats::Stance_Run)) - x *= gmst.fJumpRunMultiplier->getFloat(); + x *= gmst.fJumpRunMultiplier->mValue.getFloat(); x *= npcdata->mNpcStats.getFatigueTerm(); x -= -627.2f;/*gravity constant*/ x /= 3.0f; @@ -1083,7 +1083,7 @@ namespace MWClass float Npc::getCapacity (const MWWorld::Ptr& ptr) const { const MWMechanics::CreatureStats& stats = getCreatureStats (ptr); - static const float fEncumbranceStrMult = MWBase::Environment::get().getWorld()->getStore().get().find("fEncumbranceStrMult")->getFloat(); + static const float fEncumbranceStrMult = MWBase::Environment::get().getWorld()->getStore().get().find("fEncumbranceStrMult")->mValue.getFloat(); return stats.getAttribute(ESM::Attribute::Strength).getModified()*fEncumbranceStrMult; } @@ -1126,8 +1126,8 @@ namespace MWClass MWMechanics::NpcStats &stats = getNpcStats(ptr); const MWWorld::InventoryStore &invStore = getInventoryStore(ptr); - float fUnarmoredBase1 = store.find("fUnarmoredBase1")->getFloat(); - float fUnarmoredBase2 = store.find("fUnarmoredBase2")->getFloat(); + float fUnarmoredBase1 = store.find("fUnarmoredBase1")->mValue.getFloat(); + float fUnarmoredBase2 = store.find("fUnarmoredBase2")->mValue.getFloat(); int unarmoredSkill = stats.getSkill(ESM::Skill::Unarmored).getModified(); float ratings[MWWorld::InventoryStore::Slots]; @@ -1367,8 +1367,8 @@ namespace MWClass return; const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); - static const float fCorpseRespawnDelay = gmst.find("fCorpseRespawnDelay")->getFloat(); - static const float fCorpseClearDelay = gmst.find("fCorpseClearDelay")->getFloat(); + static const float fCorpseRespawnDelay = gmst.find("fCorpseRespawnDelay")->mValue.getFloat(); + static const float fCorpseClearDelay = gmst.find("fCorpseClearDelay")->mValue.getFloat(); float delay = ptr.getRefData().getCount() == 0 ? fCorpseClearDelay : std::min(fCorpseRespawnDelay, fCorpseClearDelay); diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index bb1ca09a3..294aebd94 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -287,8 +287,8 @@ namespace MWClass std::string type = mapping[ref->mBase->mData.mType].first; std::string oneOrTwoHanded = mapping[ref->mBase->mData.mType].second; - text += store.get().find(type)->getString() + - ((oneOrTwoHanded != "") ? ", " + store.get().find(oneOrTwoHanded)->getString() : ""); + text += store.get().find(type)->mValue.getString() + + ((oneOrTwoHanded != "") ? ", " + store.get().find(oneOrTwoHanded)->mValue.getString() : ""); // weapon damage if (ref->mBase->mData.mType >= 9) @@ -326,7 +326,7 @@ namespace MWClass if (ref->mBase->mData.mType < 9 && Settings::Manager::getBool("show melee info", "Game")) { // 64 game units = 1 yard = 3 ft, display value in feet - const float combatDistance = store.get().find("fCombatDistance")->getFloat() * ref->mBase->mData.mReach; + const float combatDistance = store.get().find("fCombatDistance")->mValue.getFloat() * ref->mBase->mData.mReach; text += MWGui::ToolTips::getWeightString(combatDistance*3/64, "#{sRange}"); text += " #{sFeet}"; diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index c3e56c0bf..dcc33d1c3 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -261,7 +261,7 @@ namespace MWDialogue const MWWorld::Store& gmsts = MWBase::Environment::get().getWorld()->getStore().get(); - title = gmsts.find (modifiedTopic)->getString(); + title = gmsts.find (modifiedTopic)->mValue.getString(); } else title = topic; @@ -537,7 +537,7 @@ namespace MWDialogue MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor); - callback->addResponse(gmsts.find ("sServiceRefusal")->getString(), Interpreter::fixDefinesDialog(info->mResponse, interpreterContext)); + callback->addResponse(gmsts.find ("sServiceRefusal")->mValue.getString(), Interpreter::fixDefinesDialog(info->mResponse, interpreterContext)); executeScript (info->mResultScript, mActor); return true; diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index aeb6dfc0f..6aceccaff 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -365,15 +365,15 @@ namespace MWGui const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); - const std::string sPersuasion = gmst.find("sPersuasion")->getString(); - const std::string sCompanionShare = gmst.find("sCompanionShare")->getString(); - const std::string sBarter = gmst.find("sBarter")->getString(); - const std::string sSpells = gmst.find("sSpells")->getString(); - const std::string sTravel = gmst.find("sTravel")->getString(); - const std::string sSpellMakingMenuTitle = gmst.find("sSpellMakingMenuTitle")->getString(); - const std::string sEnchanting = gmst.find("sEnchanting")->getString(); - const std::string sServiceTrainingTitle = gmst.find("sServiceTrainingTitle")->getString(); - const std::string sRepair = gmst.find("sRepair")->getString(); + const std::string sPersuasion = gmst.find("sPersuasion")->mValue.getString(); + const std::string sCompanionShare = gmst.find("sCompanionShare")->mValue.getString(); + const std::string sBarter = gmst.find("sBarter")->mValue.getString(); + const std::string sSpells = gmst.find("sSpells")->mValue.getString(); + const std::string sTravel = gmst.find("sTravel")->mValue.getString(); + const std::string sSpellMakingMenuTitle = gmst.find("sSpellMakingMenuTitle")->mValue.getString(); + const std::string sEnchanting = gmst.find("sEnchanting")->mValue.getString(); + const std::string sServiceTrainingTitle = gmst.find("sServiceTrainingTitle")->mValue.getString(); + const std::string sRepair = gmst.find("sRepair")->mValue.getString(); if (topic != sPersuasion && topic != sCompanionShare && topic != sBarter && topic != sSpells && topic != sTravel && topic != sSpellMakingMenuTitle @@ -458,7 +458,7 @@ namespace MWGui void DialogueWindow::restock() { MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(mPtr); - float delay = MWBase::Environment::get().getWorld()->getStore().get().find("fBarterGoldResetDelay")->getFloat(); + float delay = MWBase::Environment::get().getWorld()->getStore().get().find("fBarterGoldResetDelay")->mValue.getFloat(); // Gold is restocked every 24h if (MWBase::Environment::get().getWorld()->getTimeStamp() >= sellerStats.getLastRestockTime() + delay) @@ -503,31 +503,31 @@ namespace MWGui MWBase::Environment::get().getWorld()->getStore().get(); if (mPtr.getTypeName() == typeid(ESM::NPC).name()) - mTopicsList->addItem(gmst.find("sPersuasion")->getString()); + mTopicsList->addItem(gmst.find("sPersuasion")->mValue.getString()); if (services & ESM::NPC::AllItems) - mTopicsList->addItem(gmst.find("sBarter")->getString()); + mTopicsList->addItem(gmst.find("sBarter")->mValue.getString()); if (services & ESM::NPC::Spells) - mTopicsList->addItem(gmst.find("sSpells")->getString()); + mTopicsList->addItem(gmst.find("sSpells")->mValue.getString()); if (travel) - mTopicsList->addItem(gmst.find("sTravel")->getString()); + mTopicsList->addItem(gmst.find("sTravel")->mValue.getString()); if (services & ESM::NPC::Spellmaking) - mTopicsList->addItem(gmst.find("sSpellmakingMenuTitle")->getString()); + mTopicsList->addItem(gmst.find("sSpellmakingMenuTitle")->mValue.getString()); if (services & ESM::NPC::Enchanting) - mTopicsList->addItem(gmst.find("sEnchanting")->getString()); + mTopicsList->addItem(gmst.find("sEnchanting")->mValue.getString()); if (services & ESM::NPC::Training) - mTopicsList->addItem(gmst.find("sServiceTrainingTitle")->getString()); + mTopicsList->addItem(gmst.find("sServiceTrainingTitle")->mValue.getString()); if (services & ESM::NPC::Repair) - mTopicsList->addItem(gmst.find("sRepair")->getString()); + mTopicsList->addItem(gmst.find("sRepair")->mValue.getString()); if (isCompanion()) - mTopicsList->addItem(gmst.find("sCompanionShare")->getString()); + mTopicsList->addItem(gmst.find("sCompanionShare")->mValue.getString()); if (mTopicsList->getItemCount() > 0) mTopicsList->addSeparator(); @@ -592,7 +592,7 @@ namespace MWGui Goodbye* link = new Goodbye(); link->eventActivated += MyGUI::newDelegate(this, &DialogueWindow::onGoodbyeActivated); mLinks.push_back(link); - std::string goodbye = MWBase::Environment::get().getWorld()->getStore().get().find("sGoodbye")->getString(); + std::string goodbye = MWBase::Environment::get().getWorld()->getStore().get().find("sGoodbye")->mValue.getString(); BookTypesetter::Style* questionStyle = typesetter->createHotStyle(body, textColours.answer, textColours.answerOver, textColours.answerPressed, TypesetBook::InteractiveId(link)); diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index f7764e0f1..8fbfa65c6 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -341,7 +341,7 @@ namespace MWGui MWWorld::Ptr item = (i == 0) ? mEnchanting.getOldItem() : mEnchanting.getGem(); if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom(item.getCellRef().getRefId(), mPtr)) { - std::string msg = MWBase::Environment::get().getWorld()->getStore().get().find("sNotifyMessage49")->getString(); + std::string msg = MWBase::Environment::get().getWorld()->getStore().get().find("sNotifyMessage49")->mValue.getString(); if (msg.find("%s") != std::string::npos) msg.replace(msg.find("%s"), 2, item.getClass().getName(item)); MWBase::Environment::get().getWindowManager()->messageBox(msg); diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index 1841303f2..91467d490 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -611,7 +611,7 @@ namespace MWGui // Therefore any value < 1 should show as an empty health bar. We do the same in statswindow :) mEnemyHealth->setProgressPosition(static_cast(stats.getHealth().getCurrent() / stats.getHealth().getModified() * 100)); - static const float fNPCHealthBarFade = MWBase::Environment::get().getWorld()->getStore().get().find("fNPCHealthBarFade")->getFloat(); + static const float fNPCHealthBarFade = MWBase::Environment::get().getWorld()->getStore().get().find("fNPCHealthBarFade")->mValue.getFloat(); if (fNPCHealthBarFade > 0.f) mEnemyHealth->setAlpha(std::max(0.f, std::min(1.f, mEnemyHealthTimer/fNPCHealthBarFade))); @@ -620,7 +620,7 @@ namespace MWGui void HUD::setEnemy(const MWWorld::Ptr &enemy) { mEnemyActorId = enemy.getClass().getCreatureStats(enemy).getActorId(); - mEnemyHealthTimer = MWBase::Environment::get().getWorld()->getStore().get().find("fNPCHealthBarTime")->getFloat(); + mEnemyHealthTimer = MWBase::Environment::get().getWorld()->getStore().get().find("fNPCHealthBarTime")->mValue.getFloat(); if (!mEnemyHealth->getVisible()) mWeaponSpellBox->setPosition(mWeaponSpellBox->getPosition() - MyGUI::IntPoint(0,20)); mEnemyHealth->setVisible(true); diff --git a/apps/openmw/mwgui/jailscreen.cpp b/apps/openmw/mwgui/jailscreen.cpp index 9fa5927ac..1761e1346 100644 --- a/apps/openmw/mwgui/jailscreen.cpp +++ b/apps/openmw/mwgui/jailscreen.cpp @@ -99,9 +99,9 @@ namespace MWGui std::string message; if (mDays == 1) - message = gmst.find("sNotifyMessage42")->getString(); + message = gmst.find("sNotifyMessage42")->mValue.getString(); else - message = gmst.find("sNotifyMessage43")->getString(); + message = gmst.find("sNotifyMessage43")->mValue.getString(); std::stringstream dayStr; dayStr << mDays; @@ -110,12 +110,12 @@ namespace MWGui for (std::set::iterator it = skills.begin(); it != skills.end(); ++it) { - std::string skillName = gmst.find(ESM::Skill::sSkillNameIds[*it])->getString(); + std::string skillName = gmst.find(ESM::Skill::sSkillNameIds[*it])->mValue.getString(); std::stringstream skillValue; skillValue << player.getClass().getNpcStats(player).getSkill(*it).getBase(); - std::string skillMsg = gmst.find("sNotifyMessage44")->getString(); + std::string skillMsg = gmst.find("sNotifyMessage44")->mValue.getString(); if (*it == ESM::Skill::Sneak || *it == ESM::Skill::Security) - skillMsg = gmst.find("sNotifyMessage39")->getString(); + skillMsg = gmst.find("sNotifyMessage39")->mValue.getString(); if (skillMsg.find("%s") != std::string::npos) skillMsg.replace(skillMsg.find("%s"), 2, skillName); diff --git a/apps/openmw/mwgui/merchantrepair.cpp b/apps/openmw/mwgui/merchantrepair.cpp index d3504ebc3..9974c6d16 100644 --- a/apps/openmw/mwgui/merchantrepair.cpp +++ b/apps/openmw/mwgui/merchantrepair.cpp @@ -57,7 +57,7 @@ void MerchantRepair::setPtr(const MWWorld::Ptr &actor) int basePrice = iter->getClass().getValue(*iter); float fRepairMult = MWBase::Environment::get().getWorld()->getStore().get() - .find("fRepairMult")->getFloat(); + .find("fRepairMult")->mValue.getFloat(); float p = static_cast(std::max(1, basePrice)); float r = static_cast(std::max(1, static_cast(maxDurability / p))); @@ -71,7 +71,7 @@ void MerchantRepair::setPtr(const MWWorld::Ptr &actor) std::string name = iter->getClass().getName(*iter) + " - " + MyGUI::utility::toString(price) + MWBase::Environment::get().getWorld()->getStore().get() - .find("sgp")->getString(); + .find("sgp")->mValue.getString(); MyGUI::Button* button = diff --git a/apps/openmw/mwgui/recharge.cpp b/apps/openmw/mwgui/recharge.cpp index 26a364f72..3133dc0cb 100644 --- a/apps/openmw/mwgui/recharge.cpp +++ b/apps/openmw/mwgui/recharge.cpp @@ -181,7 +181,7 @@ void Recharge::onItemClicked(MyGUI::Widget *sender, const MWWorld::Ptr& item) if (gem.getRefData().getCount() == 0) { - std::string message = MWBase::Environment::get().getWorld()->getStore().get().find("sNotifyMessage51")->getString(); + std::string message = MWBase::Environment::get().getWorld()->getStore().get().find("sNotifyMessage51")->mValue.getString(); message = boost::str(boost::format(message) % gem.getClass().getName(gem)); MWBase::Environment::get().getWindowManager()->messageBox(message); diff --git a/apps/openmw/mwgui/spellbuyingwindow.cpp b/apps/openmw/mwgui/spellbuyingwindow.cpp index d9c3a5f16..9876013f1 100644 --- a/apps/openmw/mwgui/spellbuyingwindow.cpp +++ b/apps/openmw/mwgui/spellbuyingwindow.cpp @@ -44,7 +44,7 @@ namespace MWGui const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - int price = static_cast(spell.mData.mCost*store.get().find("fSpellValueMult")->getFloat()); + int price = static_cast(spell.mData.mCost*store.get().find("fSpellValueMult")->mValue.getFloat()); price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true); MWWorld::Ptr player = MWMechanics::getPlayer(); diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index 4aa208d8f..65d66f9e2 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -32,8 +32,8 @@ namespace const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); - return gmst.find(ESM::MagicEffect::effectIdToString (id1))->getString() - < gmst.find(ESM::MagicEffect::effectIdToString (id2))->getString(); + return gmst.find(ESM::MagicEffect::effectIdToString (id1))->mValue.getString() + < gmst.find(ESM::MagicEffect::effectIdToString (id2))->mValue.getString(); } void init(ESM::ENAMstruct& effect) @@ -469,7 +469,7 @@ namespace MWGui mMagickaCost->setCaption(MyGUI::utility::toString(int(y))); float fSpellMakingValueMult = - store.get().find("fSpellMakingValueMult")->getFloat(); + store.get().find("fSpellMakingValueMult")->mValue.getFloat(); int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, static_cast(y * fSpellMakingValueMult),true); @@ -547,7 +547,7 @@ namespace MWGui for (std::vector::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it) { mAvailableEffectsList->addItem(MWBase::Environment::get().getWorld ()->getStore ().get().find( - ESM::MagicEffect::effectIdToString (*it))->getString()); + ESM::MagicEffect::effectIdToString (*it))->mValue.getString()); mButtonMapping[i] = *it; ++i; } @@ -557,7 +557,7 @@ namespace MWGui for (std::vector::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it) { std::string name = MWBase::Environment::get().getWorld ()->getStore ().get().find( - ESM::MagicEffect::effectIdToString (*it))->getString(); + ESM::MagicEffect::effectIdToString (*it))->mValue.getString(); MyGUI::Widget* w = mAvailableEffectsList->getItemWidget(name); ToolTips::createMagicEffectToolTip (w, *it); diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp index 27896381e..c0f56e654 100644 --- a/apps/openmw/mwgui/spellicons.cpp +++ b/apps/openmw/mwgui/spellicons.cpp @@ -75,7 +75,7 @@ namespace MWGui std::string sourcesDescription; - static const float fadeTime = MWBase::Environment::get().getWorld()->getStore().get().find("fMagicStartIconBlink")->getFloat(); + static const float fadeTime = MWBase::Environment::get().getWorld()->getStore().get().find("fMagicStartIconBlink")->mValue.getFloat(); for (std::vector::const_iterator effectIt = it->second.begin(); effectIt != it->second.end(); ++effectIt) diff --git a/apps/openmw/mwgui/statswindow.cpp b/apps/openmw/mwgui/statswindow.cpp index d3d487579..db73351bf 100644 --- a/apps/openmw/mwgui/statswindow.cpp +++ b/apps/openmw/mwgui/statswindow.cpp @@ -61,7 +61,7 @@ namespace MWGui const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); for (int i=0; names[i][0]; ++i) { - setText (names[i][0], store.get().find (names[i][1])->getString()); + setText (names[i][0], store.get().find (names[i][1])->mValue.getString()); } getWidget(mSkillView, "SkillView"); @@ -306,7 +306,7 @@ namespace MWGui MyGUI::Widget* levelWidget; for (int i=0; i<2; ++i) { - int max = MWBase::Environment::get().getWorld()->getStore().get().find("iLevelUpTotal")->getInt(); + int max = MWBase::Environment::get().getWorld()->getStore().get().find("iLevelUpTotal")->mValue.getInteger(); getWidget(levelWidget, i==0 ? "Level_str" : "LevelText"); levelWidget->setUserString("RangePosition_LevelProgress", MyGUI::utility::toString(PCstats.getLevelProgress())); levelWidget->setUserString("Range_LevelProgress", MyGUI::utility::toString(max)); diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index e11147c74..3871baa09 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -313,7 +313,7 @@ namespace MWGui { if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom(it->mBase.getCellRef().getRefId(), mPtr)) { - std::string msg = gmst.find("sNotifyMessage49")->getString(); + std::string msg = gmst.find("sNotifyMessage49")->mValue.getString(); if (msg.find("%s") != std::string::npos) msg.replace(msg.find("%s"), 2, it->mBase.getClass().getName(it->mBase)); MWBase::Environment::get().getWindowManager()->messageBox(msg); @@ -331,8 +331,8 @@ namespace MWGui // apply disposition change if merchant is NPC if ( mPtr.getClass().isNpc() ) { int dispositionDelta = offerAccepted - ? gmst.find("iBarterSuccessDisposition")->getInt() - : gmst.find("iBarterFailDisposition")->getInt(); + ? gmst.find("iBarterSuccessDisposition")->mValue.getInteger() + : gmst.find("iBarterFailDisposition")->mValue.getInteger(); MWBase::Environment::get().getDialogueManager()->applyBarterDispositionChange(dispositionDelta); } diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index 630ba8ce1..b309da27d 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -98,7 +98,7 @@ namespace MWGui for (int i=0; i<3; ++i) { int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer - (mPtr,pcStats.getSkill (skills[i].first).getBase() * gmst.find("iTrainingMod")->getInt (),true); + (mPtr,pcStats.getSkill (skills[i].first).getBase() * gmst.find("iTrainingMod")->mValue.getInteger(),true); MyGUI::Button* button = mTrainingOptions->createWidget(price <= playerGold ? "SandTextButton" : "SandTextButtonDisabled", // can't use setEnabled since that removes tooltip MyGUI::IntCoord(5, 5+i*18, mTrainingOptions->getWidth()-10, 18), MyGUI::Align::Default); @@ -136,7 +136,7 @@ namespace MWGui const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - int price = pcStats.getSkill (skillId).getBase() * store.get().find("iTrainingMod")->getInt (); + int price = pcStats.getSkill (skillId).getBase() * store.get().find("iTrainingMod")->mValue.getInteger(); price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true); if (price > player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId)) diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index cf4fb1b5e..23a5b322f 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -58,13 +58,13 @@ namespace MWGui if (!mPtr.getCell()->isExterior()) { - price = gmst.find("fMagesGuildTravel")->getInt(); + price = gmst.find("fMagesGuildTravel")->mValue.getInteger(); } else { ESM::Position PlayerPos = player.getRefData().getPosition(); float d = sqrt(pow(pos.pos[0] - PlayerPos.pos[0], 2) + pow(pos.pos[1] - PlayerPos.pos[1], 2) + pow(pos.pos[2] - PlayerPos.pos[2], 2)); - price = static_cast(d / gmst.find("fTravelMult")->getFloat()); + price = static_cast(d / gmst.find("fTravelMult")->mValue.getFloat()); } price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true); @@ -176,7 +176,7 @@ namespace MWGui { ESM::Position playerPos = player.getRefData().getPosition(); float d = (osg::Vec3f(pos.pos[0], pos.pos[1], 0) - osg::Vec3f(playerPos.pos[0], playerPos.pos[1], 0)).length(); - int hours = static_cast(d /MWBase::Environment::get().getWorld()->getStore().get().find("fTravelTimeMult")->getFloat()); + int hours = static_cast(d /MWBase::Environment::get().getWorld()->getStore().get().find("fTravelTimeMult")->mValue.getFloat()); for(int i = 0;i < hours;i++) { MWBase::Environment::get().getMechanicsManager ()->rest (true); diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index 52575e25c..c5a06a12c 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -183,10 +183,10 @@ namespace MWGui { // figure out if player will be woken while sleeping int x = Misc::Rng::rollDice(hoursToWait); - float fSleepRandMod = world->getStore().get().find("fSleepRandMod")->getFloat(); + float fSleepRandMod = world->getStore().get().find("fSleepRandMod")->mValue.getFloat(); if (x < fSleepRandMod * hoursToWait) { - float fSleepRestMod = world->getStore().get().find("fSleepRestMod")->getFloat(); + float fSleepRestMod = world->getStore().get().find("fSleepRestMod")->mValue.getFloat(); int interruptAtHoursRemaining = int(fSleepRestMod * hoursToWait); if (interruptAtHoursRemaining != 0) { @@ -252,7 +252,7 @@ namespace MWGui // trigger levelup if possible const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); - if (mSleeping && pcstats.getLevelProgress () >= gmst.find("iLevelUpTotal")->getInt()) + if (mSleeping && pcstats.getLevelProgress () >= gmst.find("iLevelUpTotal")->mValue.getInteger()) { MWBase::Environment::get().getWindowManager()->pushGuiMode (GM_Levelup); } diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index e1bf9627d..45897b88c 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -358,7 +358,7 @@ namespace MWGui mGuiModeStates[GM_Journal].mCloseSound = "book close"; mGuiModeStates[GM_Journal].mOpenSound = "book open"; - mMessageBoxManager = new MessageBoxManager(mStore->get().find("fMessageTimePerChar")->getFloat()); + mMessageBoxManager = new MessageBoxManager(mStore->get().find("fMessageTimePerChar")->mValue.getFloat()); SpellBuyingWindow* spellBuyingWindow = new SpellBuyingWindow(); mWindows.push_back(spellBuyingWindow); diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 65fc0c098..b24c8cc14 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -1192,7 +1192,7 @@ namespace MWInput void InputManager::updateIdleTime(float dt) { static const float vanityDelay = MWBase::Environment::get().getWorld()->getStore().get() - .find("fVanityDelay")->getFloat(); + .find("fVanityDelay")->mValue.getFloat(); if (mTimeIdle >= 0.f) mTimeIdle += dt; if (mTimeIdle > vanityDelay) { diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index ba8f62e2f..0ee49ac45 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -54,22 +54,22 @@ int getBoundItemSlot (const std::string& itemId) static std::map boundItemsMap; if (boundItemsMap.empty()) { - std::string boundId = MWBase::Environment::get().getWorld()->getStore().get().find("sMagicBoundBootsID")->getString(); + std::string boundId = MWBase::Environment::get().getWorld()->getStore().get().find("sMagicBoundBootsID")->mValue.getString(); boundItemsMap[boundId] = MWWorld::InventoryStore::Slot_Boots; - boundId = MWBase::Environment::get().getWorld()->getStore().get().find("sMagicBoundCuirassID")->getString(); + boundId = MWBase::Environment::get().getWorld()->getStore().get().find("sMagicBoundCuirassID")->mValue.getString(); boundItemsMap[boundId] = MWWorld::InventoryStore::Slot_Cuirass; - boundId = MWBase::Environment::get().getWorld()->getStore().get().find("sMagicBoundLeftGauntletID")->getString(); + boundId = MWBase::Environment::get().getWorld()->getStore().get().find("sMagicBoundLeftGauntletID")->mValue.getString(); boundItemsMap[boundId] = MWWorld::InventoryStore::Slot_LeftGauntlet; - boundId = MWBase::Environment::get().getWorld()->getStore().get().find("sMagicBoundRightGauntletID")->getString(); + boundId = MWBase::Environment::get().getWorld()->getStore().get().find("sMagicBoundRightGauntletID")->mValue.getString(); boundItemsMap[boundId] = MWWorld::InventoryStore::Slot_RightGauntlet; - boundId = MWBase::Environment::get().getWorld()->getStore().get().find("sMagicBoundHelmID")->getString(); + boundId = MWBase::Environment::get().getWorld()->getStore().get().find("sMagicBoundHelmID")->mValue.getString(); boundItemsMap[boundId] = MWWorld::InventoryStore::Slot_Helmet; - boundId = MWBase::Environment::get().getWorld()->getStore().get().find("sMagicBoundShieldID")->getString(); + boundId = MWBase::Environment::get().getWorld()->getStore().get().find("sMagicBoundShieldID")->mValue.getString(); boundItemsMap[boundId] = MWWorld::InventoryStore::Slot_CarriedLeft; } @@ -138,7 +138,7 @@ void getRestorationPerHourOfSleep (const MWWorld::Ptr& ptr, float& health, float magicka = 0; if (!stunted) { - float fRestMagicMult = settings.find("fRestMagicMult")->getFloat (); + float fRestMagicMult = settings.find("fRestMagicMult")->mValue.getFloat (); magicka = fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified(); } } @@ -179,7 +179,7 @@ namespace MWMechanics if (caster.isEmpty() || !caster.getClass().isActor()) return; - static const float fSoulgemMult = world->getStore().get().find("fSoulgemMult")->getFloat(); + static const float fSoulgemMult = world->getStore().get().find("fSoulgemMult")->mValue.getFloat(); int creatureSoulValue = mCreature.get()->mBase->mData.mSoul; if (creatureSoulValue == 0) @@ -313,9 +313,9 @@ namespace MWMechanics MWWorld::Ptr& headTrackTarget, float& sqrHeadTrackDistance) { static const float fMaxHeadTrackDistance = MWBase::Environment::get().getWorld()->getStore().get() - .find("fMaxHeadTrackDistance")->getFloat(); + .find("fMaxHeadTrackDistance")->mValue.getFloat(); static const float fInteriorHeadTrackMult = MWBase::Environment::get().getWorld()->getStore().get() - .find("fInteriorHeadTrackMult")->getFloat(); + .find("fInteriorHeadTrackMult")->mValue.getFloat(); float maxDistance = fMaxHeadTrackDistance; const ESM::Cell* currentCell = actor.getCell()->getCell(); if (!currentCell->isExterior() && !(currentCell->mData.mFlags & ESM::Cell::QuasiEx)) @@ -470,7 +470,7 @@ namespace MWMechanics if (actor1.getClass().isClass(actor1, "Guard") && !actor2.getClass().isNpc()) { // Check if the creature is too far - static const float fAlarmRadius = MWBase::Environment::get().getWorld()->getStore().get().find("fAlarmRadius")->getFloat(); + static const float fAlarmRadius = MWBase::Environment::get().getWorld()->getStore().get().find("fAlarmRadius")->mValue.getFloat(); if (sqrDist > fAlarmRadius * fAlarmRadius) return; @@ -534,9 +534,9 @@ namespace MWMechanics float base = 1.f; if (ptr == getPlayer()) - base = MWBase::Environment::get().getWorld()->getStore().get().find("fPCbaseMagickaMult")->getFloat(); + base = MWBase::Environment::get().getWorld()->getStore().get().find("fPCbaseMagickaMult")->mValue.getFloat(); else - base = MWBase::Environment::get().getWorld()->getStore().get().find("fNPCbaseMagickaMult")->getFloat(); + base = MWBase::Environment::get().getWorld()->getStore().get().find("fNPCbaseMagickaMult")->mValue.getFloat(); double magickaFactor = base + creatureStats.getMagicEffects().get (EffectKey (ESM::MagicEffect::FortifyMaximumMagicka)).getMagnitude() * 0.1; @@ -584,9 +584,9 @@ namespace MWMechanics return; // Restore fatigue - float fFatigueReturnBase = settings.find("fFatigueReturnBase")->getFloat (); - float fFatigueReturnMult = settings.find("fFatigueReturnMult")->getFloat (); - float fEndFatigueMult = settings.find("fEndFatigueMult")->getFloat (); + float fFatigueReturnBase = settings.find("fFatigueReturnBase")->mValue.getFloat (); + float fFatigueReturnMult = settings.find("fFatigueReturnMult")->mValue.getFloat (); + float fEndFatigueMult = settings.find("fEndFatigueMult")->mValue.getFloat (); float x = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance); x *= fEndFatigueMult * endurance; @@ -611,8 +611,8 @@ namespace MWMechanics // Restore fatigue int endurance = stats.getAttribute(ESM::Attribute::Endurance).getModified(); const MWWorld::Store& settings = MWBase::Environment::get().getWorld()->getStore().get(); - static const float fFatigueReturnBase = settings.find("fFatigueReturnBase")->getFloat (); - static const float fFatigueReturnMult = settings.find("fFatigueReturnMult")->getFloat (); + static const float fFatigueReturnBase = settings.find("fFatigueReturnBase")->mValue.getFloat (); + static const float fFatigueReturnMult = settings.find("fFatigueReturnMult")->mValue.getFloat (); float x = fFatigueReturnBase + fFatigueReturnMult * endurance; @@ -853,14 +853,14 @@ namespace MWMechanics std::string itemGmst = it->second; std::string item = MWBase::Environment::get().getWorld()->getStore().get().find( - itemGmst)->getString(); + itemGmst)->mValue.getString(); magnitude > 0 ? addBoundItem(item, ptr) : removeBoundItem(item, ptr); if (it->first == ESM::MagicEffect::BoundGloves) { item = MWBase::Environment::get().getWorld()->getStore().get().find( - "sMagicBoundRightGauntletID")->getString(); + "sMagicBoundRightGauntletID")->mValue.getString(); magnitude > 0 ? addBoundItem(item, ptr) : removeBoundItem(item, ptr); } } @@ -936,7 +936,7 @@ namespace MWMechanics NpcStats &stats = ptr.getClass().getNpcStats(ptr); // When npc stats are just initialized, mTimeToStartDrowning == -1 and we should get value from GMST - static const float fHoldBreathTime = MWBase::Environment::get().getWorld()->getStore().get().find("fHoldBreathTime")->getFloat(); + static const float fHoldBreathTime = MWBase::Environment::get().getWorld()->getStore().get().find("fHoldBreathTime")->mValue.getFloat(); if (stats.getTimeToStartDrowning() == -1.f) stats.setTimeToStartDrowning(fHoldBreathTime); @@ -970,7 +970,7 @@ namespace MWMechanics if(timeLeft == 0.0f && !godmode) { // If drowning, apply 3 points of damage per second - static const float fSuffocationDamage = world->getStore().get().find("fSuffocationDamage")->getFloat(); + static const float fSuffocationDamage = world->getStore().get().find("fSuffocationDamage")->mValue.getFloat(); DynamicStat health = stats.getHealth(); health.setCurrent(health.getCurrent() - fSuffocationDamage*duration); stats.setHealth(health); @@ -1096,7 +1096,7 @@ namespace MWMechanics && creatureStats.getMagicEffects().get(ESM::MagicEffect::CalmHumanoid).getMagnitude() == 0) { const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); - static const int cutoff = esmStore.get().find("iCrimeThreshold")->getInt(); + static const int cutoff = esmStore.get().find("iCrimeThreshold")->mValue.getInteger(); // Force dialogue on sight if bounty is greater than the cutoff // In vanilla morrowind, the greeting dialogue is scripted to either arrest the player (< 5000 bounty) or attack (>= 5000 bounty) if ( player.getClass().getNpcStats(player).getBounty() >= cutoff @@ -1104,7 +1104,7 @@ namespace MWMechanics && MWBase::Environment::get().getWorld()->getLOS(ptr, player) && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr)) { - static const int iCrimeThresholdMultiplier = esmStore.get().find("iCrimeThresholdMultiplier")->getInt(); + static const int iCrimeThresholdMultiplier = esmStore.get().find("iCrimeThresholdMultiplier")->mValue.getInteger(); if (player.getClass().getNpcStats(player).getBounty() >= cutoff * iCrimeThresholdMultiplier) { MWBase::Environment::get().getMechanicsManager()->startCombat(ptr, player); @@ -1487,9 +1487,9 @@ namespace MWMechanics static float sneakSkillTimer = 0.f; // times sneak skill progress from "avoid notice" const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); - const int radius = esmStore.get().find("fSneakUseDist")->getInt(); + const int radius = esmStore.get().find("fSneakUseDist")->mValue.getInteger(); - static float fSneakUseDelay = esmStore.get().find("fSneakUseDelay")->getFloat(); + static float fSneakUseDelay = esmStore.get().find("fSneakUseDelay")->mValue.getFloat(); if (sneakTimer >= fSneakUseDelay) sneakTimer = 0.f; diff --git a/apps/openmw/mwmechanics/aibreathe.cpp b/apps/openmw/mwmechanics/aibreathe.cpp index 4e0076824..36acc75d5 100644 --- a/apps/openmw/mwmechanics/aibreathe.cpp +++ b/apps/openmw/mwmechanics/aibreathe.cpp @@ -19,7 +19,7 @@ MWMechanics::AiBreathe::AiBreathe() bool MWMechanics::AiBreathe::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) { - static const float fHoldBreathTime = MWBase::Environment::get().getWorld()->getStore().get().find("fHoldBreathTime")->getFloat(); + static const float fHoldBreathTime = MWBase::Environment::get().getWorld()->getStore().get().find("fHoldBreathTime")->mValue.getFloat(); const MWWorld::Class& actorClass = actor.getClass(); if (actorClass.isNpc()) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 438f4f7c6..9824347e3 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -351,7 +351,7 @@ namespace MWMechanics case AiCombatStorage::FleeState_RunToDestination: { - static const float fFleeDistance = MWBase::Environment::get().getWorld()->getStore().get().find("fFleeDistance")->getFloat(); + static const float fFleeDistance = MWBase::Environment::get().getWorld()->getStore().get().find("fFleeDistance")->mValue.getFloat(); float dist = (actor.getRefData().getPosition().asVec3() - target.getRefData().getPosition().asVec3()).length(); if ((dist > fFleeDistance && !storage.mLOS) @@ -520,13 +520,13 @@ namespace MWMechanics const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - float baseDelay = store.get().find("fCombatDelayCreature")->getFloat(); + float baseDelay = store.get().find("fCombatDelayCreature")->mValue.getFloat(); if (actor.getClass().isNpc()) { - baseDelay = store.get().find("fCombatDelayNPC")->getFloat(); + baseDelay = store.get().find("fCombatDelayNPC")->mValue.getFloat(); //say a provoking combat phrase - int chance = store.get().find("iVoiceAttackOdds")->getInt(); + int chance = store.get().find("iVoiceAttackOdds")->mValue.getInteger(); if (Misc::Rng::roll0to99() < chance) { MWBase::Environment::get().getDialogueManager()->say(actor, "attack"); @@ -616,21 +616,21 @@ osg::Vec3f AimDirToMovingTarget(const MWWorld::Ptr& actor, const MWWorld::Ptr& t // get projectile speed (depending on weapon type) if (weapType == ESM::Weapon::MarksmanThrown) { - static float fThrownWeaponMinSpeed = gmst.find("fThrownWeaponMinSpeed")->getFloat(); - static float fThrownWeaponMaxSpeed = gmst.find("fThrownWeaponMaxSpeed")->getFloat(); + static float fThrownWeaponMinSpeed = gmst.find("fThrownWeaponMinSpeed")->mValue.getFloat(); + static float fThrownWeaponMaxSpeed = gmst.find("fThrownWeaponMaxSpeed")->mValue.getFloat(); projSpeed = fThrownWeaponMinSpeed + (fThrownWeaponMaxSpeed - fThrownWeaponMinSpeed) * strength; } else if (weapType != 0) { - static float fProjectileMinSpeed = gmst.find("fProjectileMinSpeed")->getFloat(); - static float fProjectileMaxSpeed = gmst.find("fProjectileMaxSpeed")->getFloat(); + static float fProjectileMinSpeed = gmst.find("fProjectileMinSpeed")->mValue.getFloat(); + static float fProjectileMaxSpeed = gmst.find("fProjectileMaxSpeed")->mValue.getFloat(); projSpeed = fProjectileMinSpeed + (fProjectileMaxSpeed - fProjectileMinSpeed) * strength; } else // weapType is 0 ==> it's a target spell projectile { - projSpeed = gmst.find("fTargetSpellMaxSpeed")->getFloat(); + projSpeed = gmst.find("fTargetSpellMaxSpeed")->mValue.getFloat(); } // idea: perpendicular to dir to target speed components of target move vector and projectile vector should be the same diff --git a/apps/openmw/mwmechanics/aicombataction.cpp b/apps/openmw/mwmechanics/aicombataction.cpp index 2685e0e0c..52da1417e 100644 --- a/apps/openmw/mwmechanics/aicombataction.cpp +++ b/apps/openmw/mwmechanics/aicombataction.cpp @@ -23,8 +23,8 @@ namespace MWMechanics { float suggestCombatRange(int rangeTypes) { - static const float fCombatDistance = MWBase::Environment::get().getWorld()->getStore().get().find("fCombatDistance")->getFloat(); - static float fHandToHandReach = MWBase::Environment::get().getWorld()->getStore().get().find("fHandToHandReach")->getFloat(); + static const float fCombatDistance = MWBase::Environment::get().getWorld()->getStore().get().find("fCombatDistance")->mValue.getFloat(); + static float fHandToHandReach = MWBase::Environment::get().getWorld()->getStore().get().find("fHandToHandReach")->mValue.getFloat(); // This distance is a possible distance of melee attack static float distance = fCombatDistance * std::max(2.f, fHandToHandReach); @@ -114,13 +114,13 @@ namespace MWMechanics { isRanged = false; - static const float fCombatDistance = MWBase::Environment::get().getWorld()->getStore().get().find("fCombatDistance")->getFloat(); - static const float fProjectileMaxSpeed = MWBase::Environment::get().getWorld()->getStore().get().find("fProjectileMaxSpeed")->getFloat(); + static const float fCombatDistance = MWBase::Environment::get().getWorld()->getStore().get().find("fCombatDistance")->mValue.getFloat(); + static const float fProjectileMaxSpeed = MWBase::Environment::get().getWorld()->getStore().get().find("fProjectileMaxSpeed")->mValue.getFloat(); if (mWeapon.isEmpty()) { static float fHandToHandReach = - MWBase::Environment::get().getWorld()->getStore().get().find("fHandToHandReach")->getFloat(); + MWBase::Environment::get().getWorld()->getStore().get().find("fHandToHandReach")->mValue.getFloat(); return fHandToHandReach * fCombatDistance; } @@ -336,7 +336,7 @@ namespace MWMechanics float dist = 1.0f; if (activeWeapon.isEmpty() && !selectedSpellId.empty() && !selectedEnchItem.isEmpty()) { - static const float fHandToHandReach = gmst.find("fHandToHandReach")->getFloat(); + static const float fHandToHandReach = gmst.find("fHandToHandReach")->mValue.getFloat(); dist = fHandToHandReach; } else if (stats.getDrawState() == MWMechanics::DrawState_Spell) @@ -375,7 +375,7 @@ namespace MWMechanics } } - static const float fTargetSpellMaxSpeed = gmst.find("fTargetSpellMaxSpeed")->getFloat(); + static const float fTargetSpellMaxSpeed = gmst.find("fTargetSpellMaxSpeed")->mValue.getFloat(); dist *= std::max(1000.0f, fTargetSpellMaxSpeed); } else if (!activeWeapon.isEmpty()) @@ -383,7 +383,7 @@ namespace MWMechanics const ESM::Weapon* esmWeap = activeWeapon.get()->mBase; if (esmWeap->mData.mType >= ESM::Weapon::MarksmanBow) { - static const float fTargetSpellMaxSpeed = gmst.find("fProjectileMaxSpeed")->getFloat(); + static const float fTargetSpellMaxSpeed = gmst.find("fProjectileMaxSpeed")->mValue.getFloat(); dist = fTargetSpellMaxSpeed; if (!activeAmmo.isEmpty()) { @@ -399,8 +399,8 @@ namespace MWMechanics dist = (dist > 0.f) ? dist : 1.0f; - static const float fCombatDistance = gmst.find("fCombatDistance")->getFloat(); - static const float fCombatDistanceWerewolfMod = gmst.find("fCombatDistanceWerewolfMod")->getFloat(); + static const float fCombatDistance = gmst.find("fCombatDistance")->mValue.getFloat(); + static const float fCombatDistanceWerewolfMod = gmst.find("fCombatDistanceWerewolfMod")->mValue.getFloat(); float combatDistance = fCombatDistance; if (actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()) @@ -485,20 +485,20 @@ namespace MWMechanics if (flee >= 100) return flee; - static const float fAIFleeHealthMult = gmst.find("fAIFleeHealthMult")->getFloat(); - static const float fAIFleeFleeMult = gmst.find("fAIFleeFleeMult")->getFloat(); + static const float fAIFleeHealthMult = gmst.find("fAIFleeHealthMult")->mValue.getFloat(); + static const float fAIFleeFleeMult = gmst.find("fAIFleeFleeMult")->mValue.getFloat(); float healthPercentage = (stats.getHealth().getModified() == 0.0f) ? 1.0f : stats.getHealth().getCurrent() / stats.getHealth().getModified(); float rating = (1.0f - healthPercentage) * fAIFleeHealthMult + flee * fAIFleeFleeMult; - static const int iWereWolfLevelToAttack = gmst.find("iWereWolfLevelToAttack")->getInt(); + static const int iWereWolfLevelToAttack = gmst.find("iWereWolfLevelToAttack")->mValue.getInteger(); if (actor.getClass().isNpc() && enemy.getClass().isNpc()) { if (enemy.getClass().getNpcStats(enemy).isWerewolf() && stats.getLevel() < iWereWolfLevelToAttack) { - static const int iWereWolfFleeMod = gmst.find("iWereWolfFleeMod")->getInt(); + static const int iWereWolfFleeMod = gmst.find("iWereWolfFleeMod")->mValue.getInteger(); rating = iWereWolfFleeMod; } } diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 67468453a..d36c5930f 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -495,7 +495,7 @@ namespace MWMechanics MWWorld::Ptr player = getPlayer(); static float fVoiceIdleOdds = MWBase::Environment::get().getWorld()->getStore() - .get().find("fVoiceIdleOdds")->getFloat(); + .get().find("fVoiceIdleOdds")->mValue.getFloat(); float roll = Misc::Rng::rollProbability() * 10000.0f; @@ -522,7 +522,7 @@ namespace MWMechanics int hello = actor.getClass().getCreatureStats(actor).getAiSetting(CreatureStats::AI_Hello).getModified(); float helloDistance = static_cast(hello); static int iGreetDistanceMultiplier = MWBase::Environment::get().getWorld()->getStore() - .get().find("iGreetDistanceMultiplier")->getInt(); + .get().find("iGreetDistanceMultiplier")->mValue.getInteger(); helloDistance *= iGreetDistanceMultiplier; @@ -700,7 +700,7 @@ namespace MWMechanics for(unsigned int counter = 0; counter < mIdle.size(); counter++) { static float fIdleChanceMultiplier = MWBase::Environment::get().getWorld()->getStore() - .get().find("fIdleChanceMultiplier")->getFloat(); + .get().find("fIdleChanceMultiplier")->mValue.getFloat(); unsigned short idleChance = static_cast(fIdleChanceMultiplier * mIdle[counter]); unsigned short randSelect = (int)(Misc::Rng::rollProbability() * int(100 / fIdleChanceMultiplier)); diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index 48705dc72..b8f820307 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -140,11 +140,11 @@ void MWMechanics::Alchemy::updateEffects() float x = getAlchemyFactor(); x *= mTools[ESM::Apparatus::MortarPestle].get()->mBase->mData.mQuality; - x *= MWBase::Environment::get().getWorld()->getStore().get().find ("fPotionStrengthMult")->getFloat(); + x *= MWBase::Environment::get().getWorld()->getStore().get().find ("fPotionStrengthMult")->mValue.getFloat(); // value mValue = static_cast ( - x * MWBase::Environment::get().getWorld()->getStore().get().find ("iAlchemyMod")->getFloat()); + x * MWBase::Environment::get().getWorld()->getStore().get().find ("iAlchemyMod")->mValue.getFloat()); // build quantified effect list for (std::set::const_iterator iter (effects.begin()); iter!=effects.end(); ++iter) @@ -160,13 +160,13 @@ void MWMechanics::Alchemy::updateEffects() } float fPotionT1MagMul = - MWBase::Environment::get().getWorld()->getStore().get().find ("fPotionT1MagMult")->getFloat(); + MWBase::Environment::get().getWorld()->getStore().get().find ("fPotionT1MagMult")->mValue.getFloat(); if (fPotionT1MagMul<=0) throw std::runtime_error ("invalid gmst: fPotionT1MagMul"); float fPotionT1DurMult = - MWBase::Environment::get().getWorld()->getStore().get().find ("fPotionT1DurMult")->getFloat(); + MWBase::Environment::get().getWorld()->getStore().get().find ("fPotionT1DurMult")->mValue.getFloat(); if (fPotionT1DurMult<=0) throw std::runtime_error ("invalid gmst: fPotionT1DurMult"); @@ -449,7 +449,7 @@ bool MWMechanics::Alchemy::knownEffect(unsigned int potionEffectIndex, const MWW MWMechanics::NpcStats& npcStats = npc.getClass().getNpcStats(npc); int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase(); static const float fWortChanceValue = - MWBase::Environment::get().getWorld()->getStore().get().find("fWortChanceValue")->getFloat(); + MWBase::Environment::get().getWorld()->getStore().get().find("fWortChanceValue")->mValue.getFloat(); return (potionEffectIndex <= 1 && alchemySkill >= fWortChanceValue) || (potionEffectIndex <= 3 && alchemySkill >= fWortChanceValue*2) || (potionEffectIndex <= 5 && alchemySkill >= fWortChanceValue*3) @@ -503,5 +503,5 @@ std::string MWMechanics::Alchemy::suggestPotionName() int effectId = effects.begin()->mId; return MWBase::Environment::get().getWorld()->getStore().get().find( - ESM::MagicEffect::effectIdToString(effectId))->getString(); + ESM::MagicEffect::effectIdToString(effectId))->mValue.getString(); } diff --git a/apps/openmw/mwmechanics/autocalcspell.cpp b/apps/openmw/mwmechanics/autocalcspell.cpp index f655a68b4..a52fcc059 100644 --- a/apps/openmw/mwmechanics/autocalcspell.cpp +++ b/apps/openmw/mwmechanics/autocalcspell.cpp @@ -25,7 +25,7 @@ namespace MWMechanics std::vector autoCalcNpcSpells(const int *actorSkills, const int *actorAttributes, const ESM::Race* race) { const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); - static const float fNPCbaseMagickaMult = gmst.find("fNPCbaseMagickaMult")->getFloat(); + static const float fNPCbaseMagickaMult = gmst.find("fNPCbaseMagickaMult")->mValue.getFloat(); float baseMagicka = fNPCbaseMagickaMult * actorAttributes[ESM::Attribute::Intelligence]; static const std::string schools[] = { @@ -38,7 +38,7 @@ namespace MWMechanics for (int i=0; i<6; ++i) { const std::string& gmstName = "iAutoSpell" + schools[i] + "Max"; - iAutoSpellSchoolMax[i] = gmst.find(gmstName)->getInt(); + iAutoSpellSchoolMax[i] = gmst.find(gmstName)->mValue.getInteger(); } init = true; } @@ -70,7 +70,7 @@ namespace MWMechanics continue; if (!(spell->mData.mFlags & ESM::Spell::F_Autocalc)) continue; - static const int iAutoSpellTimesCanCast = gmst.find("iAutoSpellTimesCanCast")->getInt(); + static const int iAutoSpellTimesCanCast = gmst.find("iAutoSpellTimesCanCast")->mValue.getInteger(); if (baseMagicka < iAutoSpellTimesCanCast * spell->mData.mCost) continue; @@ -89,7 +89,7 @@ namespace MWMechanics if (cap.mReachedLimit && spell->mData.mCost <= cap.mMinCost) continue; - static const float fAutoSpellChance = gmst.find("fAutoSpellChance")->getFloat(); + static const float fAutoSpellChance = gmst.find("fAutoSpellChance")->mValue.getFloat(); if (calcAutoCastChance(spell, actorSkills, actorAttributes, school) < fAutoSpellChance) continue; @@ -146,7 +146,7 @@ namespace MWMechanics { const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); - static const float fPCbaseMagickaMult = esmStore.get().find("fPCbaseMagickaMult")->getFloat(); + static const float fPCbaseMagickaMult = esmStore.get().find("fPCbaseMagickaMult")->mValue.getFloat(); float baseMagicka = fPCbaseMagickaMult * actorAttributes[ESM::Attribute::Intelligence]; bool reachedLimit = false; @@ -173,7 +173,7 @@ namespace MWMechanics if (baseMagicka < spell->mData.mCost) continue; - static const float fAutoPCSpellChance = esmStore.get().find("fAutoPCSpellChance")->getFloat(); + static const float fAutoPCSpellChance = esmStore.get().find("fAutoPCSpellChance")->mValue.getFloat(); if (calcAutoCastChance(spell, actorSkills, actorAttributes, -1) < fAutoPCSpellChance) continue; @@ -206,7 +206,7 @@ namespace MWMechanics weakestSpell = spell; minCost = weakestSpell->mData.mCost; } - static const unsigned int iAutoPCSpellMax = esmStore.get().find("iAutoPCSpellMax")->getInt(); + static const unsigned int iAutoPCSpellMax = esmStore.get().find("iAutoPCSpellMax")->mValue.getInteger(); if (selectedSpells.size() == iAutoPCSpellMax) reachedLimit = true; } @@ -221,7 +221,7 @@ namespace MWMechanics for (std::vector::const_iterator effectIt = effects.begin(); effectIt != effects.end(); ++effectIt) { const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find(effectIt->mEffectID); - static const int iAutoSpellAttSkillMin = MWBase::Environment::get().getWorld()->getStore().get().find("iAutoSpellAttSkillMin")->getInt(); + static const int iAutoSpellAttSkillMin = MWBase::Environment::get().getWorld()->getStore().get().find("iAutoSpellAttSkillMin")->mValue.getInteger(); if ((magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill)) { @@ -278,7 +278,7 @@ namespace MWMechanics duration = effect.mDuration; static const float fEffectCostMult = MWBase::Environment::get().getWorld()->getStore() - .get().find("fEffectCostMult")->getFloat(); + .get().find("fEffectCostMult")->mValue.getFloat(); float x = 0.5 * (std::max(1, minMagn) + std::max(1, maxMagn)); x *= 0.1 * magicEffect->mData.mBaseCost; diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index aca3dde7f..9d3d6a80e 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -123,16 +123,16 @@ float getFallDamage(const MWWorld::Ptr& ptr, float fallHeight) MWBase::World *world = MWBase::Environment::get().getWorld(); const MWWorld::Store &store = world->getStore().get(); - const float fallDistanceMin = store.find("fFallDamageDistanceMin")->getFloat(); + const float fallDistanceMin = store.find("fFallDamageDistanceMin")->mValue.getFloat(); if (fallHeight >= fallDistanceMin) { const float acrobaticsSkill = static_cast(ptr.getClass().getSkill(ptr, ESM::Skill::Acrobatics)); const float jumpSpellBonus = ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Jump).getMagnitude(); - const float fallAcroBase = store.find("fFallAcroBase")->getFloat(); - const float fallAcroMult = store.find("fFallAcroMult")->getFloat(); - const float fallDistanceBase = store.find("fFallDistanceBase")->getFloat(); - const float fallDistanceMult = store.find("fFallDistanceMult")->getFloat(); + const float fallAcroBase = store.find("fFallAcroBase")->mValue.getFloat(); + const float fallAcroMult = store.find("fFallAcroMult")->mValue.getFloat(); + const float fallDistanceBase = store.find("fFallDistanceBase")->mValue.getFloat(); + const float fallDistanceMult = store.find("fFallDistanceMult")->mValue.getFloat(); float x = fallHeight - fallDistanceMin; x -= (1.5f * acrobaticsSkill) + jumpSpellBonus; @@ -1907,14 +1907,14 @@ void CharacterController::update(float duration) // reduce fatigue const MWWorld::Store &gmst = world->getStore().get(); float fatigueLoss = 0; - static const float fFatigueRunBase = gmst.find("fFatigueRunBase")->getFloat(); - static const float fFatigueRunMult = gmst.find("fFatigueRunMult")->getFloat(); - static const float fFatigueSwimWalkBase = gmst.find("fFatigueSwimWalkBase")->getFloat(); - static const float fFatigueSwimRunBase = gmst.find("fFatigueSwimRunBase")->getFloat(); - static const float fFatigueSwimWalkMult = gmst.find("fFatigueSwimWalkMult")->getFloat(); - static const float fFatigueSwimRunMult = gmst.find("fFatigueSwimRunMult")->getFloat(); - static const float fFatigueSneakBase = gmst.find("fFatigueSneakBase")->getFloat(); - static const float fFatigueSneakMult = gmst.find("fFatigueSneakMult")->getFloat(); + static const float fFatigueRunBase = gmst.find("fFatigueRunBase")->mValue.getFloat(); + static const float fFatigueRunMult = gmst.find("fFatigueRunMult")->mValue.getFloat(); + static const float fFatigueSwimWalkBase = gmst.find("fFatigueSwimWalkBase")->mValue.getFloat(); + static const float fFatigueSwimRunBase = gmst.find("fFatigueSwimRunBase")->mValue.getFloat(); + static const float fFatigueSwimWalkMult = gmst.find("fFatigueSwimWalkMult")->mValue.getFloat(); + static const float fFatigueSwimRunMult = gmst.find("fFatigueSwimRunMult")->mValue.getFloat(); + static const float fFatigueSneakBase = gmst.find("fFatigueSneakBase")->mValue.getFloat(); + static const float fFatigueSneakMult = gmst.find("fFatigueSneakMult")->mValue.getFloat(); if (cls.getEncumbrance(mPtr) <= cls.getCapacity(mPtr)) { @@ -1954,8 +1954,8 @@ void CharacterController::update(float duration) forcestateupdate = (mJumpState != JumpState_InAir); jumpstate = JumpState_InAir; - static const float fJumpMoveBase = gmst.find("fJumpMoveBase")->getFloat(); - static const float fJumpMoveMult = gmst.find("fJumpMoveMult")->getFloat(); + static const float fJumpMoveBase = gmst.find("fJumpMoveBase")->mValue.getFloat(); + static const float fJumpMoveMult = gmst.find("fJumpMoveMult")->mValue.getFloat(); float factor = fJumpMoveBase + fJumpMoveMult * mPtr.getClass().getSkill(mPtr, ESM::Skill::Acrobatics)/100.f; factor = std::min(1.f, factor); vec.x() *= factor; @@ -1982,8 +1982,8 @@ void CharacterController::update(float duration) cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 0); // decrease fatigue - const float fatigueJumpBase = gmst.find("fFatigueJumpBase")->getFloat(); - const float fatigueJumpMult = gmst.find("fFatigueJumpMult")->getFloat(); + const float fatigueJumpBase = gmst.find("fFatigueJumpBase")->mValue.getFloat(); + const float fatigueJumpMult = gmst.find("fFatigueJumpMult")->mValue.getFloat(); float normalizedEncumbrance = mPtr.getClass().getNormalizedEncumbrance(mPtr); if (normalizedEncumbrance > 1) normalizedEncumbrance = 1; diff --git a/apps/openmw/mwmechanics/combat.cpp b/apps/openmw/mwmechanics/combat.cpp index 06ed99f5a..be55b681f 100644 --- a/apps/openmw/mwmechanics/combat.cpp +++ b/apps/openmw/mwmechanics/combat.cpp @@ -82,9 +82,9 @@ namespace MWMechanics osg::Vec3f(0,0,1))); const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); - if (angleDegrees < gmst.find("fCombatBlockLeftAngle")->getFloat()) + if (angleDegrees < gmst.find("fCombatBlockLeftAngle")->mValue.getFloat()) return false; - if (angleDegrees > gmst.find("fCombatBlockRightAngle")->getFloat()) + if (angleDegrees > gmst.find("fCombatBlockRightAngle")->mValue.getFloat()) return false; MWMechanics::CreatureStats& attackerStats = attacker.getClass().getCreatureStats(attacker); @@ -92,11 +92,11 @@ namespace MWMechanics float blockTerm = blocker.getClass().getSkill(blocker, ESM::Skill::Block) + 0.2f * blockerStats.getAttribute(ESM::Attribute::Agility).getModified() + 0.1f * blockerStats.getAttribute(ESM::Attribute::Luck).getModified(); float enemySwing = attackStrength; - float swingTerm = enemySwing * gmst.find("fSwingBlockMult")->getFloat() + gmst.find("fSwingBlockBase")->getFloat(); + float swingTerm = enemySwing * gmst.find("fSwingBlockMult")->mValue.getFloat() + gmst.find("fSwingBlockBase")->mValue.getFloat(); float blockerTerm = blockTerm * swingTerm; if (blocker.getClass().getMovementSettings(blocker).mPosition[1] <= 0) - blockerTerm *= gmst.find("fBlockStillBonus")->getFloat(); + blockerTerm *= gmst.find("fBlockStillBonus")->mValue.getFloat(); blockerTerm *= blockerStats.getFatigueTerm(); int attackerSkill = 0; @@ -109,8 +109,8 @@ namespace MWMechanics attackerTerm *= attackerStats.getFatigueTerm(); int x = int(blockerTerm - attackerTerm); - int iBlockMaxChance = gmst.find("iBlockMaxChance")->getInt(); - int iBlockMinChance = gmst.find("iBlockMinChance")->getInt(); + int iBlockMaxChance = gmst.find("iBlockMaxChance")->mValue.getInteger(); + int iBlockMinChance = gmst.find("iBlockMinChance")->mValue.getInteger(); x = std::min(iBlockMaxChance, std::max(iBlockMinChance, x)); if (Misc::Rng::roll0to99() < x) @@ -126,9 +126,9 @@ namespace MWMechanics inv.unequipItem(*shield, blocker); } // Reduce blocker fatigue - const float fFatigueBlockBase = gmst.find("fFatigueBlockBase")->getFloat(); - const float fFatigueBlockMult = gmst.find("fFatigueBlockMult")->getFloat(); - const float fWeaponFatigueBlockMult = gmst.find("fWeaponFatigueBlockMult")->getFloat(); + const float fFatigueBlockBase = gmst.find("fFatigueBlockBase")->mValue.getFloat(); + const float fFatigueBlockMult = gmst.find("fFatigueBlockMult")->mValue.getFloat(); + const float fWeaponFatigueBlockMult = gmst.find("fWeaponFatigueBlockMult")->mValue.getFloat(); MWMechanics::DynamicStat fatigue = blockerStats.getFatigue(); float normalizedEncumbrance = blocker.getClass().getNormalizedEncumbrance(blocker); normalizedEncumbrance = std::min(1.f, normalizedEncumbrance); @@ -166,7 +166,7 @@ namespace MWMechanics if ((weapon.get()->mBase->mData.mFlags & ESM::Weapon::Silver) && actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()) - damage *= MWBase::Environment::get().getWorld()->getStore().get().find("fWereWolfSilverWeaponDamageMult")->getFloat(); + damage *= MWBase::Environment::get().getWorld()->getStore().get().find("fWereWolfSilverWeaponDamageMult")->mValue.getFloat(); if (damage == 0 && attacker == getPlayer()) MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicTargetResistsWeapons}"); @@ -219,14 +219,14 @@ namespace MWMechanics if (unaware) { - damage *= gmst.find("fCombatCriticalStrikeMult")->getFloat(); + damage *= gmst.find("fCombatCriticalStrikeMult")->mValue.getFloat(); MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}"); MWBase::Environment::get().getSoundManager()->playSound3D(victim, "critical damage", 1.0f, 1.0f); } } if (victim.getClass().getCreatureStats(victim).getKnockedDown()) - damage *= gmst.find("fCombatKODamageMult")->getFloat(); + damage *= gmst.find("fCombatKODamageMult")->mValue.getFloat(); } reduceWeaponCondition(damage, validVictim, weapon, attacker); @@ -241,7 +241,7 @@ namespace MWMechanics // Non-enchanted arrows shot at enemies have a chance to turn up in their inventory if (victim != getPlayer() && !appliedEnchantment) { - float fProjectileThrownStoreChance = gmst.find("fProjectileThrownStoreChance")->getFloat(); + float fProjectileThrownStoreChance = gmst.find("fProjectileThrownStoreChance")->mValue.getFloat(); if (Misc::Rng::rollProbability() < fProjectileThrownStoreChance / 100.f) victim.getClass().getContainerStore(victim).add(projectile, 1, victim); } @@ -273,10 +273,10 @@ namespace MWMechanics defenseTerm = victimStats.getEvasion(); } defenseTerm += std::min(100.f, - gmst.find("fCombatInvisoMult")->getFloat() * + gmst.find("fCombatInvisoMult")->mValue.getFloat() * victimStats.getMagicEffects().get(ESM::MagicEffect::Chameleon).getMagnitude()); defenseTerm += std::min(100.f, - gmst.find("fCombatInvisoMult")->getFloat() * + gmst.find("fCombatInvisoMult")->mValue.getFloat() * victimStats.getMagicEffects().get(ESM::MagicEffect::Invisibility).getMagnitude()); } float attackTerm = skillValue + @@ -322,7 +322,7 @@ namespace MWMechanics x = std::min(100.f, x + elementResistance); - static const float fElementalShieldMult = MWBase::Environment::get().getWorld()->getStore().get().find("fElementalShieldMult")->getFloat(); + static const float fElementalShieldMult = MWBase::Environment::get().getWorld()->getStore().get().find("fElementalShieldMult")->mValue.getFloat(); x = fElementalShieldMult * magnitude * (1.f - 0.01f * x); // Note swapped victim and attacker, since the attacker takes the damage here. @@ -352,7 +352,7 @@ namespace MWMechanics // weapon condition does not degrade when godmode is on if (!godmode) { - const float fWeaponDamageMult = MWBase::Environment::get().getWorld()->getStore().get().find("fWeaponDamageMult")->getFloat(); + const float fWeaponDamageMult = MWBase::Environment::get().getWorld()->getStore().get().find("fWeaponDamageMult")->mValue.getFloat(); float x = std::max(1.f, fWeaponDamageMult * damage); weaphealth -= std::min(int(x), weaphealth); @@ -379,9 +379,9 @@ namespace MWMechanics } static const float fDamageStrengthBase = MWBase::Environment::get().getWorld()->getStore().get() - .find("fDamageStrengthBase")->getFloat(); + .find("fDamageStrengthBase")->mValue.getFloat(); static const float fDamageStrengthMult = MWBase::Environment::get().getWorld()->getStore().get() - .find("fDamageStrengthMult")->getFloat(); + .find("fDamageStrengthMult")->mValue.getFloat(); damage *= fDamageStrengthBase + (attacker.getClass().getCreatureStats(attacker).getAttribute(ESM::Attribute::Strength).getModified() * fDamageStrengthMult * 0.1f); } @@ -389,8 +389,8 @@ namespace MWMechanics void getHandToHandDamage(const MWWorld::Ptr &attacker, const MWWorld::Ptr &victim, float &damage, bool &healthdmg, float attackStrength) { const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - float minstrike = store.get().find("fMinHandToHandMult")->getFloat(); - float maxstrike = store.get().find("fMaxHandToHandMult")->getFloat(); + float minstrike = store.get().find("fMinHandToHandMult")->mValue.getFloat(); + float maxstrike = store.get().find("fMaxHandToHandMult")->mValue.getFloat(); damage = static_cast(attacker.getClass().getSkill(attacker, ESM::Skill::HandToHand)); damage *= minstrike + ((maxstrike-minstrike)*attackStrength); @@ -415,7 +415,7 @@ namespace MWMechanics damage *= MWBase::Environment::get().getWorld()->getGlobalFloat("werewolfclawmult"); } if(healthdmg) - damage *= store.get().find("fHandtoHandHealthPer")->getFloat(); + damage *= store.get().find("fHandtoHandHealthPer")->mValue.getFloat(); MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); if(isWerewolf) @@ -432,9 +432,9 @@ namespace MWMechanics { // somewhat of a guess, but using the weapon weight makes sense const MWWorld::Store& store = MWBase::Environment::get().getWorld()->getStore().get(); - const float fFatigueAttackBase = store.find("fFatigueAttackBase")->getFloat(); - const float fFatigueAttackMult = store.find("fFatigueAttackMult")->getFloat(); - const float fWeaponFatigueMult = store.find("fWeaponFatigueMult")->getFloat(); + const float fFatigueAttackBase = store.find("fFatigueAttackBase")->mValue.getFloat(); + const float fFatigueAttackMult = store.find("fFatigueAttackMult")->mValue.getFloat(); + const float fWeaponFatigueMult = store.find("fWeaponFatigueMult")->mValue.getFloat(); CreatureStats& stats = attacker.getClass().getCreatureStats(attacker); MWMechanics::DynamicStat fatigue = stats.getFatigue(); const float normalizedEncumbrance = attacker.getClass().getNormalizedEncumbrance(attacker); @@ -459,9 +459,9 @@ namespace MWMechanics float d = (pos1 - pos2).length(); static const int iFightDistanceBase = MWBase::Environment::get().getWorld()->getStore().get().find( - "iFightDistanceBase")->getInt(); + "iFightDistanceBase")->mValue.getInteger(); static const float fFightDistanceMultiplier = MWBase::Environment::get().getWorld()->getStore().get().find( - "fFightDistanceMultiplier")->getFloat(); + "fFightDistanceMultiplier")->mValue.getFloat(); return (iFightDistanceBase - fFightDistanceMultiplier * d); } diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index d1128860c..2994eac28 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -48,8 +48,8 @@ namespace MWMechanics const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); - static const float fFatigueBase = gmst.find("fFatigueBase")->getFloat(); - static const float fFatigueMult = gmst.find("fFatigueMult")->getFloat(); + static const float fFatigueBase = gmst.find("fFatigueBase")->mValue.getFloat(); + static const float fFatigueMult = gmst.find("fFatigueMult")->mValue.getFloat(); return fFatigueBase - fFatigueMult * (1-normalised); } diff --git a/apps/openmw/mwmechanics/difficultyscaling.cpp b/apps/openmw/mwmechanics/difficultyscaling.cpp index 53cf47dea..237698974 100644 --- a/apps/openmw/mwmechanics/difficultyscaling.cpp +++ b/apps/openmw/mwmechanics/difficultyscaling.cpp @@ -17,7 +17,7 @@ float scaleDamage(float damage, const MWWorld::Ptr& attacker, const MWWorld::Ptr difficultySetting = std::min(difficultySetting, 500); difficultySetting = std::max(difficultySetting, -500); - static const float fDifficultyMult = MWBase::Environment::get().getWorld()->getStore().get().find("fDifficultyMult")->getFloat(); + static const float fDifficultyMult = MWBase::Environment::get().getWorld()->getStore().get().find("fDifficultyMult")->mValue.getFloat(); float difficultyTerm = 0.01f * difficultySetting; diff --git a/apps/openmw/mwmechanics/disease.hpp b/apps/openmw/mwmechanics/disease.hpp index 5746af2a2..fec3bdd37 100644 --- a/apps/openmw/mwmechanics/disease.hpp +++ b/apps/openmw/mwmechanics/disease.hpp @@ -28,7 +28,7 @@ namespace MWMechanics float fDiseaseXferChance = MWBase::Environment::get().getWorld()->getStore().get().find( - "fDiseaseXferChance")->getFloat(); + "fDiseaseXferChance")->mValue.getFloat(); MagicEffects& actorEffects = actor.getClass().getCreatureStats(actor).getMagicEffects(); @@ -59,7 +59,7 @@ namespace MWMechanics actor.getClass().getCreatureStats(actor).getSpells().add(it->first); std::string msg = "sMagicContractDisease"; - msg = MWBase::Environment::get().getWorld()->getStore().get().find(msg)->getString(); + msg = MWBase::Environment::get().getWorld()->getStore().get().find(msg)->mValue.getString(); if (msg.find("%s") != std::string::npos) msg.replace(msg.find("%s"), 2, spell->mName); MWBase::Environment::get().getWindowManager()->messageBox(msg); diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index 08f30aba1..c0bffc4cb 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -107,7 +107,7 @@ namespace MWMechanics } const bool powerfulSoul = getGemCharge() >= \ - MWBase::Environment::get().getWorld()->getStore().get().find ("iSoulAmountForConstantEffect")->getInt(); + MWBase::Environment::get().getWorld()->getStore().get().find ("iSoulAmountForConstantEffect")->mValue.getInteger(); if ((mObjectType == typeid(ESM::Armor).name()) || (mObjectType == typeid(ESM::Clothing).name())) { // Armor or Clothing switch(mCastStyle) @@ -184,7 +184,7 @@ namespace MWMechanics float magnitudeCost = (magMin + magMax) * baseCost * 0.05f; if (mCastStyle == ESM::Enchantment::ConstantEffect) { - magnitudeCost *= store.get().find("fEnchantmentConstantDurationMult")->getFloat(); + magnitudeCost *= store.get().find("fEnchantmentConstantDurationMult")->mValue.getFloat(); } else { @@ -193,7 +193,7 @@ namespace MWMechanics float areaCost = area * 0.05f * baseCost; - const float fEffectCostMult = store.get().find("fEffectCostMult")->getFloat(); + const float fEffectCostMult = store.get().find("fEffectCostMult")->mValue.getFloat(); cost += (magnitudeCost + areaCost) * fEffectCostMult; @@ -230,7 +230,7 @@ namespace MWMechanics if(mEnchanter.isEmpty()) return 0; - float priceMultipler = MWBase::Environment::get().getWorld()->getStore().get().find ("fEnchantmentValueMult")->getFloat(); + float priceMultipler = MWBase::Environment::get().getWorld()->getStore().get().find ("fEnchantmentValueMult")->mValue.getFloat(); int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mEnchanter, static_cast(getEnchantPoints() * priceMultipler), true); return price; } @@ -256,7 +256,7 @@ namespace MWMechanics const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - return static_cast(mOldItemPtr.getClass().getEnchantmentPoints(mOldItemPtr) * store.get().find("fEnchantmentMult")->getFloat()); + return static_cast(mOldItemPtr.getClass().getEnchantmentPoints(mOldItemPtr) * store.get().find("fEnchantmentMult")->mValue.getFloat()); } bool Enchanting::soulEmpty() const { @@ -288,8 +288,8 @@ namespace MWMechanics const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); - float chance2 = 7.5f / (gmst.find("fEnchantmentChanceMult")->getFloat() * ((mCastStyle == ESM::Enchantment::ConstantEffect) ? - gmst.find("fEnchantmentConstantChanceMult")->getFloat() : 1.0f )) + float chance2 = 7.5f / (gmst.find("fEnchantmentChanceMult")->mValue.getFloat() * ((mCastStyle == ESM::Enchantment::ConstantEffect) ? + gmst.find("fEnchantmentConstantChanceMult")->mValue.getFloat() : 1.0f )) * getEnchantPoints(); return (chance1-chance2); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index e7343e23a..859b2e522 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -36,7 +36,7 @@ namespace float getFightDispositionBias(float disposition) { static const float fFightDispMult = MWBase::Environment::get().getWorld()->getStore().get().find( - "fFightDispMult")->getFloat(); + "fFightDispMult")->mValue.getFloat(); return ((50.f - disposition) * fFightDispMult); } @@ -45,11 +45,11 @@ namespace const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); - float persTerm = stats.getAttribute(ESM::Attribute::Personality).getModified() / gmst.find("fPersonalityMod")->getFloat(); - float luckTerm = stats.getAttribute(ESM::Attribute::Luck).getModified() / gmst.find("fLuckMod")->getFloat(); - float repTerm = stats.getReputation() * gmst.find("fReputationMod")->getFloat(); + float persTerm = stats.getAttribute(ESM::Attribute::Personality).getModified() / gmst.find("fPersonalityMod")->mValue.getFloat(); + float luckTerm = stats.getAttribute(ESM::Attribute::Luck).getModified() / gmst.find("fLuckMod")->mValue.getFloat(); + float repTerm = stats.getReputation() * gmst.find("fReputationMod")->mValue.getFloat(); float fatigueTerm = stats.getFatigueTerm(); - float levelTerm = stats.getLevel() * gmst.find("fLevelMod")->getFloat(); + float levelTerm = stats.getLevel() * gmst.find("fLevelMod")->mValue.getFloat(); rating1 = (repTerm + luckTerm + persTerm + stats.getSkill(ESM::Skill::Speechcraft).getModified()) * fatigueTerm; @@ -342,7 +342,7 @@ namespace MWMechanics if(timeToDrown != mWatchedTimeToStartDrowning) { static const float fHoldBreathTime = MWBase::Environment::get().getWorld()->getStore().get() - .find("fHoldBreathTime")->getFloat(); + .find("fHoldBreathTime")->mValue.getFloat(); mWatchedTimeToStartDrowning = timeToDrown; @@ -543,12 +543,12 @@ namespace MWMechanics const MWMechanics::NpcStats &playerStats = playerPtr.getClass().getNpcStats(playerPtr); const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); - static const float fDispRaceMod = gmst.find("fDispRaceMod")->getFloat(); + static const float fDispRaceMod = gmst.find("fDispRaceMod")->mValue.getFloat(); if (Misc::StringUtils::ciEqual(npc->mBase->mRace, player->mBase->mRace)) x += fDispRaceMod; - static const float fDispPersonalityMult = gmst.find("fDispPersonalityMult")->getFloat(); - static const float fDispPersonalityBase = gmst.find("fDispPersonalityBase")->getFloat(); + static const float fDispPersonalityMult = gmst.find("fDispPersonalityMult")->mValue.getFloat(); + static const float fDispPersonalityBase = gmst.find("fDispPersonalityBase")->mValue.getFloat(); x += fDispPersonalityMult * (playerStats.getAttribute(ESM::Attribute::Personality).getModified() - fDispPersonalityBase); float reaction = 0; @@ -592,20 +592,20 @@ namespace MWMechanics rank = 0; } - static const float fDispFactionRankMult = gmst.find("fDispFactionRankMult")->getFloat(); - static const float fDispFactionRankBase = gmst.find("fDispFactionRankBase")->getFloat(); - static const float fDispFactionMod = gmst.find("fDispFactionMod")->getFloat(); + static const float fDispFactionRankMult = gmst.find("fDispFactionRankMult")->mValue.getFloat(); + static const float fDispFactionRankBase = gmst.find("fDispFactionRankBase")->mValue.getFloat(); + static const float fDispFactionMod = gmst.find("fDispFactionMod")->mValue.getFloat(); x += (fDispFactionRankMult * rank + fDispFactionRankBase) * fDispFactionMod * reaction; - static const float fDispCrimeMod = gmst.find("fDispCrimeMod")->getFloat(); - static const float fDispDiseaseMod = gmst.find("fDispDiseaseMod")->getFloat(); + static const float fDispCrimeMod = gmst.find("fDispCrimeMod")->mValue.getFloat(); + static const float fDispDiseaseMod = gmst.find("fDispDiseaseMod")->mValue.getFloat(); x -= fDispCrimeMod * playerStats.getBounty(); if (playerStats.hasCommonDisease() || playerStats.hasBlightDisease()) x += fDispDiseaseMod; - static const float fDispWeaponDrawn = gmst.find("fDispWeaponDrawn")->getFloat(); + static const float fDispWeaponDrawn = gmst.find("fDispWeaponDrawn")->mValue.getFloat(); if (playerStats.getDrawState() == MWMechanics::DrawState_Weapon) x += fDispWeaponDrawn; @@ -673,16 +673,16 @@ namespace MWMechanics float target2 = d * (playerRating2 - npcRating2 + 50); float bribeMod; - if (type == PT_Bribe10) bribeMod = gmst.find("fBribe10Mod")->getFloat(); - else if (type == PT_Bribe100) bribeMod = gmst.find("fBribe100Mod")->getFloat(); - else bribeMod = gmst.find("fBribe1000Mod")->getFloat(); + if (type == PT_Bribe10) bribeMod = gmst.find("fBribe10Mod")->mValue.getFloat(); + else if (type == PT_Bribe100) bribeMod = gmst.find("fBribe100Mod")->mValue.getFloat(); + else bribeMod = gmst.find("fBribe1000Mod")->mValue.getFloat(); float target3 = d * (playerRating3 - npcRating3 + 50) + bribeMod; - float iPerMinChance = floor(gmst.find("iPerMinChance")->getFloat()); - float iPerMinChange = floor(gmst.find("iPerMinChange")->getFloat()); - float fPerDieRollMult = gmst.find("fPerDieRollMult")->getFloat(); - float fPerTempMult = gmst.find("fPerTempMult")->getFloat(); + float iPerMinChance = floor(gmst.find("iPerMinChance")->mValue.getFloat()); + float iPerMinChange = floor(gmst.find("iPerMinChange")->mValue.getFloat()); + float fPerDieRollMult = gmst.find("fPerDieRollMult")->mValue.getFloat(); + float fPerTempMult = gmst.find("fPerTempMult")->mValue.getFloat(); float x = 0; float y = 0; @@ -867,7 +867,7 @@ namespace MWMechanics continue; // All sMagicBound* GMST's should be of type string - std::string currentGMSTValue = currentSetting.getString(); + std::string currentGMSTValue = currentSetting.mValue.getString(); Misc::StringUtils::lowerCaseInPlace(currentGMSTValue); boundItemIDCache.insert(currentGMSTValue); @@ -1163,7 +1163,7 @@ namespace MWMechanics osg::Vec3f from (player.getRefData().getPosition().asVec3()); const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); - float radius = esmStore.get().find("fAlarmRadius")->getFloat(); + float radius = esmStore.get().find("fAlarmRadius")->mValue.getFloat(); mActors.getObjectsInRange(from, radius, neighbors); @@ -1261,29 +1261,29 @@ namespace MWMechanics float disp = 0.f, dispVictim = 0.f; if (type == OT_Trespassing || type == OT_SleepingInOwnedBed) { - arg = store.find("iCrimeTresspass")->getInt(); - disp = dispVictim = store.find("iDispTresspass")->getFloat(); + arg = store.find("iCrimeTresspass")->mValue.getInteger(); + disp = dispVictim = store.find("iDispTresspass")->mValue.getFloat(); } else if (type == OT_Pickpocket) { - arg = store.find("iCrimePickPocket")->getInt(); - disp = dispVictim = store.find("fDispPickPocketMod")->getFloat(); + arg = store.find("iCrimePickPocket")->mValue.getInteger(); + disp = dispVictim = store.find("fDispPickPocketMod")->mValue.getFloat(); } else if (type == OT_Assault) { - arg = store.find("iCrimeAttack")->getInt(); - disp = store.find("iDispAttackMod")->getFloat(); - dispVictim = store.find("fDispAttacking")->getFloat(); + arg = store.find("iCrimeAttack")->mValue.getInteger(); + disp = store.find("iDispAttackMod")->mValue.getFloat(); + dispVictim = store.find("fDispAttacking")->mValue.getFloat(); } else if (type == OT_Murder) { - arg = store.find("iCrimeKilling")->getInt(); - disp = dispVictim = store.find("iDispKilling")->getFloat(); + arg = store.find("iCrimeKilling")->mValue.getInteger(); + disp = dispVictim = store.find("iDispKilling")->mValue.getFloat(); } else if (type == OT_Theft) { - disp = dispVictim = store.find("fDispStealing")->getFloat() * arg; - arg = static_cast(arg * store.find("fCrimeStealing")->getFloat()); + disp = dispVictim = store.find("fDispStealing")->mValue.getFloat() * arg; + arg = static_cast(arg * store.find("fCrimeStealing")->mValue.getFloat()); arg = std::max(1, arg); // Minimum bounty of 1, in case items with zero value are stolen } @@ -1293,7 +1293,7 @@ namespace MWMechanics const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); osg::Vec3f from (player.getRefData().getPosition().asVec3()); - float radius = esmStore.get().find("fAlarmRadius")->getFloat(); + float radius = esmStore.get().find("fAlarmRadius")->mValue.getFloat(); mActors.getObjectsInRange(from, radius, neighbors); @@ -1307,21 +1307,21 @@ namespace MWMechanics // Controls whether witnesses will engage combat with the criminal. int fight = 0, fightVictim = 0; if (type == OT_Trespassing || type == OT_SleepingInOwnedBed) - fight = fightVictim = esmStore.get().find("iFightTrespass")->getInt(); + fight = fightVictim = esmStore.get().find("iFightTrespass")->mValue.getInteger(); else if (type == OT_Pickpocket) { - fight = esmStore.get().find("iFightPickpocket")->getInt(); - fightVictim = esmStore.get().find("iFightPickpocket")->getInt() * 4; // *4 according to research wiki + fight = esmStore.get().find("iFightPickpocket")->mValue.getInteger(); + fightVictim = esmStore.get().find("iFightPickpocket")->mValue.getInteger() * 4; // *4 according to research wiki } else if (type == OT_Assault) { - fight = esmStore.get().find("iFightAttacking")->getInt(); - fightVictim = esmStore.get().find("iFightAttack")->getInt(); + fight = esmStore.get().find("iFightAttacking")->mValue.getInteger(); + fightVictim = esmStore.get().find("iFightAttack")->mValue.getInteger(); } else if (type == OT_Murder) - fight = fightVictim = esmStore.get().find("iFightKilling")->getInt(); + fight = fightVictim = esmStore.get().find("iFightKilling")->mValue.getInteger(); else if (type == OT_Theft) - fight = fightVictim = esmStore.get().find("fFightStealing")->getInt(); + fight = fightVictim = esmStore.get().find("fFightStealing")->mValue.getInteger(); bool reported = false; @@ -1552,8 +1552,8 @@ namespace MWMechanics && !MWBase::Environment::get().getWorld()->isSwimming(ptr) && MWBase::Environment::get().getWorld()->isOnGround(ptr)) { - static float fSneakSkillMult = store.find("fSneakSkillMult")->getFloat(); - static float fSneakBootMult = store.find("fSneakBootMult")->getFloat(); + static float fSneakSkillMult = store.find("fSneakSkillMult")->mValue.getFloat(); + static float fSneakBootMult = store.find("fSneakBootMult")->mValue.getFloat(); float sneak = static_cast(ptr.getClass().getSkill(ptr, ESM::Skill::Sneak)); int agility = stats.getAttribute(ESM::Attribute::Agility).getModified(); int luck = stats.getAttribute(ESM::Attribute::Luck).getModified(); @@ -1568,8 +1568,8 @@ namespace MWMechanics sneakTerm = fSneakSkillMult * sneak + 0.2f * agility + 0.1f * luck + bootWeight * fSneakBootMult; } - static float fSneakDistBase = store.find("fSneakDistanceBase")->getFloat(); - static float fSneakDistMult = store.find("fSneakDistanceMultiplier")->getFloat(); + static float fSneakDistBase = store.find("fSneakDistanceBase")->mValue.getFloat(); + static float fSneakDistMult = store.find("fSneakDistanceMultiplier")->mValue.getFloat(); osg::Vec3f pos1 (ptr.getRefData().getPosition().asVec3()); osg::Vec3f pos2 (observer.getRefData().getPosition().asVec3()); @@ -1587,8 +1587,8 @@ namespace MWMechanics float obsTerm = obsSneak + 0.2f * obsAgility + 0.1f * obsLuck - obsBlind; // is ptr behind the observer? - static float fSneakNoViewMult = store.find("fSneakNoViewMult")->getFloat(); - static float fSneakViewMult = store.find("fSneakViewMult")->getFloat(); + static float fSneakNoViewMult = store.find("fSneakNoViewMult")->mValue.getFloat(); + static float fSneakViewMult = store.find("fSneakViewMult")->mValue.getFloat(); float y = 0; osg::Vec3f vec = pos1 - pos2; if (observer.getRefData().getBaseNode()) @@ -1748,7 +1748,7 @@ namespace MWMechanics MWBase::Environment::get().getWorld()->getGlobalInt("pcknownwerewolf"))) { const ESM::GameSetting * iWerewolfFightMod = MWBase::Environment::get().getWorld()->getStore().get().find("iWerewolfFightMod"); - fight += iWerewolfFightMod->getInt(); + fight += iWerewolfFightMod->mValue.getInteger(); } } @@ -1841,7 +1841,7 @@ namespace MWMechanics // Witnesses of the player's transformation will make them a globally known werewolf std::vector closeActors; const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); - getActorsInRange(actor.getRefData().getPosition().asVec3(), gmst.find("fAlarmRadius")->getFloat(), closeActors); + getActorsInRange(actor.getRefData().getPosition().asVec3(), gmst.find("fAlarmRadius")->mValue.getFloat(), closeActors); bool detected = false, reported = false; for (std::vector::const_iterator it = closeActors.begin(); it != closeActors.end(); ++it) @@ -1866,7 +1866,7 @@ namespace MWMechanics if (reported) { npcStats.setBounty(npcStats.getBounty()+ - gmst.find("iWereWolfBounty")->getInt()); + gmst.find("iWereWolfBounty")->mValue.getInteger()); windowManager->messageBox("#{sCrimeMessage}"); } } @@ -1878,7 +1878,7 @@ namespace MWMechanics const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); MWMechanics::NpcStats &stats = actor.getClass().getNpcStats(actor); - stats.getSkill(ESM::Skill::Acrobatics).setBase(gmst.find("fWerewolfAcrobatics")->getInt()); + stats.getSkill(ESM::Skill::Acrobatics).setBase(gmst.find("fWerewolfAcrobatics")->mValue.getInteger()); } void MechanicsManager::cleanupSummonedCreature(const MWWorld::Ptr &caster, int creatureActorId) diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index f15152759..cb9ef5477 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -149,12 +149,12 @@ float MWMechanics::NpcStats::getSkillProgressRequirement (int skillIndex, const const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); - float typeFactor = gmst.find ("fMiscSkillBonus")->getFloat(); + float typeFactor = gmst.find ("fMiscSkillBonus")->mValue.getFloat(); for (int i=0; i<5; ++i) if (class_.mData.mSkills[i][0]==skillIndex) { - typeFactor = gmst.find ("fMinorSkillBonus")->getFloat(); + typeFactor = gmst.find ("fMinorSkillBonus")->mValue.getFloat(); break; } @@ -162,7 +162,7 @@ float MWMechanics::NpcStats::getSkillProgressRequirement (int skillIndex, const for (int i=0; i<5; ++i) if (class_.mData.mSkills[i][1]==skillIndex) { - typeFactor = gmst.find ("fMajorSkillBonus")->getFloat(); + typeFactor = gmst.find ("fMajorSkillBonus")->mValue.getFloat(); break; } @@ -178,7 +178,7 @@ float MWMechanics::NpcStats::getSkillProgressRequirement (int skillIndex, const MWBase::Environment::get().getWorld()->getStore().get().find (skillIndex); if (skill->mData.mSpecialization==class_.mData.mSpecialization) { - specialisationFactor = gmst.find ("fSpecialSkillBonus")->getFloat(); + specialisationFactor = gmst.find ("fSpecialSkillBonus")->mValue.getFloat(); if (specialisationFactor<=0) throw std::runtime_error ("invalid skill specialisation factor"); @@ -227,21 +227,21 @@ void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &clas MWBase::Environment::get().getWorld()->getStore().get(); // is this a minor or major skill? - int increase = gmst.find("iLevelupMiscMultAttriubte")->getInt(); // Note: GMST has a typo + int increase = gmst.find("iLevelupMiscMultAttriubte")->mValue.getInteger(); // Note: GMST has a typo for (int k=0; k<5; ++k) { if (class_.mData.mSkills[k][0] == skillIndex) { - mLevelProgress += gmst.find("iLevelUpMinorMult")->getInt(); - increase = gmst.find("iLevelUpMajorMultAttribute")->getInt(); + mLevelProgress += gmst.find("iLevelUpMinorMult")->mValue.getInteger(); + increase = gmst.find("iLevelUpMajorMultAttribute")->mValue.getInteger(); } } for (int k=0; k<5; ++k) { if (class_.mData.mSkills[k][1] == skillIndex) { - mLevelProgress += gmst.find("iLevelUpMajorMult")->getInt(); - increase = gmst.find("iLevelUpMinorMultAttribute")->getInt(); + mLevelProgress += gmst.find("iLevelUpMajorMult")->mValue.getInteger(); + increase = gmst.find("iLevelUpMinorMultAttribute")->mValue.getInteger(); } } @@ -249,7 +249,7 @@ void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &clas MWBase::Environment::get().getWorld ()->getStore ().get().find(skillIndex); mSkillIncreases[skill->mData.mAttribute] += increase; - mSpecIncreases[skill->mData.mSpecialization] += gmst.find("iLevelupSpecialization")->getInt(); + mSpecIncreases[skill->mData.mSpecialization] += gmst.find("iLevelupSpecialization")->mValue.getInteger(); // Play sound & skill progress notification /// \todo check if character is the player, if levelling is ever implemented for NPCs @@ -266,7 +266,7 @@ void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &clas MWBase::Environment::get().getWindowManager ()->messageBox(message.str(), MWGui::ShowInDialogueMode_Never); - if (mLevelProgress >= gmst.find("iLevelUpTotal")->getInt()) + if (mLevelProgress >= gmst.find("iLevelUpTotal")->mValue.getInteger()) { // levelup is possible now MWBase::Environment::get().getWindowManager ()->messageBox ("#{sLevelUpMsg}", MWGui::ShowInDialogueMode_Never); @@ -287,7 +287,7 @@ void MWMechanics::NpcStats::levelUp() const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); - mLevelProgress -= gmst.find("iLevelUpTotal")->getInt(); + mLevelProgress -= gmst.find("iLevelUpTotal")->mValue.getInteger(); mLevelProgress = std::max(0, mLevelProgress); // might be necessary when levelup was invoked via console for (int i=0; igetFloat()); + setHealth(getHealth().getBase() + endurance * gmst.find("fLevelUpHealthEndMult")->mValue.getFloat()); setLevel(getLevel()+1); } @@ -324,7 +324,7 @@ int MWMechanics::NpcStats::getLevelupAttributeMultiplier(int attribute) const std::stringstream gmst; gmst << "iLevelUp" << std::setfill('0') << std::setw(2) << num << "Mult"; - return MWBase::Environment::get().getWorld()->getStore().get().find(gmst.str())->getInt(); + return MWBase::Environment::get().getWorld()->getStore().get().find(gmst.str())->mValue.getInteger(); } int MWMechanics::NpcStats::getSkillIncreasesForSpecialization(int spec) const diff --git a/apps/openmw/mwmechanics/pickpocket.cpp b/apps/openmw/mwmechanics/pickpocket.cpp index eca24606e..ed6469106 100644 --- a/apps/openmw/mwmechanics/pickpocket.cpp +++ b/apps/openmw/mwmechanics/pickpocket.cpp @@ -37,9 +37,9 @@ namespace MWMechanics float pcSneak = static_cast(mThief.getClass().getSkill(mThief, ESM::Skill::Sneak)); int iPickMinChance = MWBase::Environment::get().getWorld()->getStore().get() - .find("iPickMinChance")->getInt(); + .find("iPickMinChance")->mValue.getInteger(); int iPickMaxChance = MWBase::Environment::get().getWorld()->getStore().get() - .find("iPickMaxChance")->getInt(); + .find("iPickMaxChance")->mValue.getInteger(); int roll = Misc::Rng::roll0to99(); if (t < pcSneak / iPickMinChance) @@ -57,7 +57,7 @@ namespace MWMechanics { float stackValue = static_cast(item.getClass().getValue(item) * count); float fPickPocketMod = MWBase::Environment::get().getWorld()->getStore().get() - .find("fPickPocketMod")->getFloat(); + .find("fPickPocketMod")->mValue.getFloat(); float valueTerm = 10 * fPickPocketMod * stackValue; return getDetected(valueTerm); diff --git a/apps/openmw/mwmechanics/repair.cpp b/apps/openmw/mwmechanics/repair.cpp index 5c6123e82..3ebef36bf 100644 --- a/apps/openmw/mwmechanics/repair.cpp +++ b/apps/openmw/mwmechanics/repair.cpp @@ -42,7 +42,7 @@ void Repair::repair(const MWWorld::Ptr &itemToRepair) int armorerSkill = npcStats.getSkill(ESM::Skill::Armorer).getModified(); float fRepairAmountMult = MWBase::Environment::get().getWorld()->getStore().get() - .find("fRepairAmountMult")->getFloat(); + .find("fRepairAmountMult")->mValue.getFloat(); float toolQuality = ref->mBase->mData.mQuality; @@ -87,7 +87,7 @@ void Repair::repair(const MWWorld::Ptr &itemToRepair) store.remove(mTool, 1, player); std::string message = MWBase::Environment::get().getWorld()->getStore().get() - .find("sNotifyMessage51")->getString(); + .find("sNotifyMessage51")->mValue.getString(); MWBase::Environment::get().getWindowManager()->messageBox((boost::format(message) % mTool.getClass().getName(mTool)).str()); diff --git a/apps/openmw/mwmechanics/security.cpp b/apps/openmw/mwmechanics/security.cpp index 3e38bc521..c8a4dd770 100644 --- a/apps/openmw/mwmechanics/security.cpp +++ b/apps/openmw/mwmechanics/security.cpp @@ -40,7 +40,7 @@ namespace MWMechanics float pickQuality = lockpick.get()->mBase->mData.mQuality; - float fPickLockMult = MWBase::Environment::get().getWorld()->getStore().get().find("fPickLockMult")->getFloat(); + float fPickLockMult = MWBase::Environment::get().getWorld()->getStore().get().find("fPickLockMult")->mValue.getFloat(); float x = 0.2f * mAgility + 0.1f * mLuck + mSecuritySkill; x *= pickQuality * mFatigueTerm; @@ -81,7 +81,7 @@ namespace MWMechanics const ESM::Spell* trapSpell = MWBase::Environment::get().getWorld()->getStore().get().find(trap.getCellRef().getTrap()); int trapSpellPoints = trapSpell->mData.mCost; - float fTrapCostMult = MWBase::Environment::get().getWorld()->getStore().get().find("fTrapCostMult")->getFloat(); + float fTrapCostMult = MWBase::Environment::get().getWorld()->getStore().get().find("fTrapCostMult")->mValue.getFloat(); float x = 0.2f * mAgility + 0.1f * mLuck + mSecuritySkill; x += fTrapCostMult * trapSpellPoints; diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 76140013d..9e163f132 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -62,7 +62,7 @@ namespace MWMechanics duration = effect.mDuration; static const float fEffectCostMult = MWBase::Environment::get().getWorld()->getStore() - .get().find("fEffectCostMult")->getFloat(); + .get().find("fEffectCostMult")->mValue.getFloat(); float x = 0.5 * (std::max(1, minMagn) + std::max(1, maxMagn)); x *= 0.1 * magicEffect->mData.mBaseCost; @@ -93,7 +93,7 @@ namespace MWMechanics if (it->mRange == ESM::RT_Target) x *= 1.5f; static const float fEffectCostMult = MWBase::Environment::get().getWorld()->getStore().get().find( - "fEffectCostMult")->getFloat(); + "fEffectCostMult")->mValue.getFloat(); x *= fEffectCostMult; float s = 2.0f * actor.getClass().getSkill(actor, spellSchoolToSkill(magicEffect->mData.mSchool)); @@ -883,8 +883,8 @@ namespace MWMechanics if (!godmode) { // Reduce fatigue (note that in the vanilla game, both GMSTs are 0, and there's no fatigue loss) - static const float fFatigueSpellBase = store.get().find("fFatigueSpellBase")->getFloat(); - static const float fFatigueSpellMult = store.get().find("fFatigueSpellMult")->getFloat(); + static const float fFatigueSpellBase = store.get().find("fFatigueSpellBase")->mValue.getFloat(); + static const float fFatigueSpellMult = store.get().find("fFatigueSpellMult")->mValue.getFloat(); DynamicStat fatigue = stats.getFatigue(); const float normalizedEncumbrance = mCaster.getClass().getNormalizedEncumbrance(mCaster); @@ -968,7 +968,7 @@ namespace MWMechanics if (roll > x) { // "X has no effect on you" - std::string message = MWBase::Environment::get().getWorld()->getStore().get().find("sNotifyMessage50")->getString(); + std::string message = MWBase::Environment::get().getWorld()->getStore().get().find("sNotifyMessage50")->mValue.getString(); message = boost::str(boost::format(message) % ingredient->mName); MWBase::Environment::get().getWindowManager()->messageBox(message); return false; @@ -1251,7 +1251,7 @@ namespace MWMechanics float damageScale = 1.f - timeDiff / 7.f; // When cloudy, the sun damage effect is halved static float fMagicSunBlockedMult = MWBase::Environment::get().getWorld()->getStore().get().find( - "fMagicSunBlockedMult")->getFloat(); + "fMagicSunBlockedMult")->mValue.getFloat(); int weather = MWBase::Environment::get().getWorld()->getCurrentWeather(); if (weather > 1) @@ -1348,7 +1348,7 @@ namespace MWMechanics if (it == summonMap.end()) return std::string(); else - return MWBase::Environment::get().getWorld()->getStore().get().find(it->second)->getString(); + return MWBase::Environment::get().getWorld()->getStore().get().find(it->second)->mValue.getString(); } void ApplyLoopingParticlesVisitor::visit (MWMechanics::EffectKey key, diff --git a/apps/openmw/mwmechanics/spellpriority.cpp b/apps/openmw/mwmechanics/spellpriority.cpp index 7bedb1e37..9a366a916 100644 --- a/apps/openmw/mwmechanics/spellpriority.cpp +++ b/apps/openmw/mwmechanics/spellpriority.cpp @@ -593,8 +593,8 @@ namespace MWMechanics { const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); - static const float fAIMagicSpellMult = gmst.find("fAIMagicSpellMult")->getFloat(); - static const float fAIRangeMagicSpellMult = gmst.find("fAIRangeMagicSpellMult")->getFloat(); + static const float fAIMagicSpellMult = gmst.find("fAIMagicSpellMult")->mValue.getFloat(); + static const float fAIRangeMagicSpellMult = gmst.find("fAIRangeMagicSpellMult")->mValue.getFloat(); float mult = fAIMagicSpellMult; diff --git a/apps/openmw/mwmechanics/trading.cpp b/apps/openmw/mwmechanics/trading.cpp index eee5e6449..b824d7c45 100644 --- a/apps/openmw/mwmechanics/trading.cpp +++ b/apps/openmw/mwmechanics/trading.cpp @@ -50,11 +50,11 @@ namespace MWMechanics float e1 = 0.1f * merchantStats.getAttribute(ESM::Attribute::Luck).getModified(); float f1 = 0.2f * merchantStats.getAttribute(ESM::Attribute::Personality).getModified(); - float dispositionTerm = gmst.find("fDispositionMod")->getFloat() * (clampedDisposition - 50); + float dispositionTerm = gmst.find("fDispositionMod")->mValue.getFloat() * (clampedDisposition - 50); float pcTerm = (dispositionTerm + a1 + b1 + c1) * playerStats.getFatigueTerm(); float npcTerm = (d1 + e1 + f1) * merchantStats.getFatigueTerm(); - float x = gmst.find("fBargainOfferMulti")->getFloat() * d - + gmst.find("fBargainOfferBase")->getFloat() + float x = gmst.find("fBargainOfferMulti")->mValue.getFloat() * d + + gmst.find("fBargainOfferBase")->mValue.getFloat() + int(pcTerm - npcTerm); int roll = Misc::Rng::rollDice(100) + 1; diff --git a/apps/openmw/mwmechanics/weaponpriority.cpp b/apps/openmw/mwmechanics/weaponpriority.cpp index 9030d6254..7e33784c1 100644 --- a/apps/openmw/mwmechanics/weaponpriority.cpp +++ b/apps/openmw/mwmechanics/weaponpriority.cpp @@ -157,9 +157,9 @@ namespace MWMechanics { const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); - static const float fAIMeleeWeaponMult = gmst.find("fAIMeleeWeaponMult")->getFloat(); - static const float fAIMeleeArmorMult = gmst.find("fAIMeleeArmorMult")->getFloat(); - static const float fAIRangeMeleeWeaponMult = gmst.find("fAIRangeMeleeWeaponMult")->getFloat(); + static const float fAIMeleeWeaponMult = gmst.find("fAIMeleeWeaponMult")->mValue.getFloat(); + static const float fAIMeleeArmorMult = gmst.find("fAIMeleeArmorMult")->mValue.getFloat(); + static const float fAIRangeMeleeWeaponMult = gmst.find("fAIRangeMeleeWeaponMult")->mValue.getFloat(); if (weapon.isEmpty()) return 0.f; diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 2a7b65cac..90668914f 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -303,7 +303,7 @@ namespace MWPhysics position.z() += halfExtents.z(); static const float fSwimHeightScale = MWBase::Environment::get().getWorld()->getStore().get() - .find("fSwimHeightScale")->getFloat(); + .find("fSwimHeightScale")->mValue.getFloat(); float swimlevel = waterlevel + halfExtents.z() - (physicActor->getRenderingHalfExtents().z() * 2 * fSwimHeightScale); ActorTracer tracer; @@ -339,7 +339,7 @@ namespace MWPhysics osg::Vec3f stormDirection = MWBase::Environment::get().getWorld()->getStormDirection(); float angleDegrees = osg::RadiansToDegrees(std::acos(stormDirection * velocity / (stormDirection.length() * velocity.length()))); static const float fStromWalkMult = MWBase::Environment::get().getWorld()->getStore().get() - .find("fStromWalkMult")->getFloat(); + .find("fStromWalkMult")->mValue.getFloat(); velocity *= 1.f-(fStromWalkMult * (angleDegrees/180.f)); } @@ -860,8 +860,8 @@ namespace MWPhysics // Use cone shape as fallback const MWWorld::Store &store = MWBase::Environment::get().getWorld()->getStore().get(); - btConeShape shape (osg::DegreesToRadians(store.find("fCombatAngleXY")->getFloat()/2.0f), queryDistance); - shape.setLocalScaling(btVector3(1, 1, osg::DegreesToRadians(store.find("fCombatAngleZ")->getFloat()/2.0f) / + btConeShape shape (osg::DegreesToRadians(store.find("fCombatAngleXY")->mValue.getFloat()/2.0f), queryDistance); + shape.setLocalScaling(btVector3(1, 1, osg::DegreesToRadians(store.find("fCombatAngleZ")->mValue.getFloat()/2.0f) / shape.getRadius())); // The shape origin is its center, so we have to move it forward by half the length. The diff --git a/apps/openmw/mwrender/weaponanimation.cpp b/apps/openmw/mwrender/weaponanimation.cpp index 054ce1b1d..32990482a 100644 --- a/apps/openmw/mwrender/weaponanimation.cpp +++ b/apps/openmw/mwrender/weaponanimation.cpp @@ -119,8 +119,8 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor, float attackStrength) return; osg::Vec3f launchPos = osg::computeLocalToWorld(nodepaths[0]).getTrans(); - float fThrownWeaponMinSpeed = gmst.find("fThrownWeaponMinSpeed")->getFloat(); - float fThrownWeaponMaxSpeed = gmst.find("fThrownWeaponMaxSpeed")->getFloat(); + float fThrownWeaponMinSpeed = gmst.find("fThrownWeaponMinSpeed")->mValue.getFloat(); + float fThrownWeaponMaxSpeed = gmst.find("fThrownWeaponMaxSpeed")->mValue.getFloat(); float speed = fThrownWeaponMinSpeed + (fThrownWeaponMaxSpeed - fThrownWeaponMinSpeed) * attackStrength; MWWorld::Ptr weaponPtr = *weapon; @@ -146,8 +146,8 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor, float attackStrength) return; osg::Vec3f launchPos = osg::computeLocalToWorld(nodepaths[0]).getTrans(); - float fProjectileMinSpeed = gmst.find("fProjectileMinSpeed")->getFloat(); - float fProjectileMaxSpeed = gmst.find("fProjectileMaxSpeed")->getFloat(); + float fProjectileMinSpeed = gmst.find("fProjectileMinSpeed")->mValue.getFloat(); + float fProjectileMaxSpeed = gmst.find("fProjectileMaxSpeed")->mValue.getFloat(); float speed = fProjectileMinSpeed + (fProjectileMaxSpeed - fProjectileMinSpeed) * attackStrength; MWWorld::Ptr weaponPtr = *weapon; diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index d6dc2ba99..9c12584d7 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -139,10 +139,10 @@ namespace MWSound Sound_Buffer *SoundManager::insertSound(const std::string &soundId, const ESM::Sound *sound) { MWBase::World* world = MWBase::Environment::get().getWorld(); - static const float fAudioDefaultMinDistance = world->getStore().get().find("fAudioDefaultMinDistance")->getFloat(); - static const float fAudioDefaultMaxDistance = world->getStore().get().find("fAudioDefaultMaxDistance")->getFloat(); - static const float fAudioMinDistanceMult = world->getStore().get().find("fAudioMinDistanceMult")->getFloat(); - static const float fAudioMaxDistanceMult = world->getStore().get().find("fAudioMaxDistanceMult")->getFloat(); + static const float fAudioDefaultMinDistance = world->getStore().get().find("fAudioDefaultMinDistance")->mValue.getFloat(); + static const float fAudioDefaultMaxDistance = world->getStore().get().find("fAudioDefaultMaxDistance")->mValue.getFloat(); + static const float fAudioMinDistanceMult = world->getStore().get().find("fAudioMinDistanceMult")->mValue.getFloat(); + static const float fAudioMaxDistanceMult = world->getStore().get().find("fAudioMaxDistanceMult")->mValue.getFloat(); float volume, min, max; volume = static_cast(pow(10.0, (sound->mData.mVolume / 255.0*3348.0 - 3348.0) / 2000.0)); @@ -296,10 +296,10 @@ namespace MWSound Stream *SoundManager::playVoice(DecoderPtr decoder, const osg::Vec3f &pos, bool playlocal) { MWBase::World* world = MWBase::Environment::get().getWorld(); - static const float fAudioMinDistanceMult = world->getStore().get().find("fAudioMinDistanceMult")->getFloat(); - static const float fAudioMaxDistanceMult = world->getStore().get().find("fAudioMaxDistanceMult")->getFloat(); - static const float fAudioVoiceDefaultMinDistance = world->getStore().get().find("fAudioVoiceDefaultMinDistance")->getFloat(); - static const float fAudioVoiceDefaultMaxDistance = world->getStore().get().find("fAudioVoiceDefaultMaxDistance")->getFloat(); + static const float fAudioMinDistanceMult = world->getStore().get().find("fAudioMinDistanceMult")->mValue.getFloat(); + static const float fAudioMaxDistanceMult = world->getStore().get().find("fAudioMaxDistanceMult")->mValue.getFloat(); + static const float fAudioVoiceDefaultMinDistance = world->getStore().get().find("fAudioVoiceDefaultMinDistance")->mValue.getFloat(); + static const float fAudioVoiceDefaultMaxDistance = world->getStore().get().find("fAudioVoiceDefaultMaxDistance")->mValue.getFloat(); static float minDistance = std::max(fAudioVoiceDefaultMinDistance * fAudioMinDistanceMult, 1.0f); static float maxDistance = std::max(fAudioVoiceDefaultMaxDistance * fAudioMaxDistanceMult, minDistance); diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index 40e904ec2..05ff1e326 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -944,7 +944,7 @@ namespace MWWorld void clearCorpse(const MWWorld::Ptr& ptr) { const MWMechanics::CreatureStats& creatureStats = ptr.getClass().getCreatureStats(ptr); - static const float fCorpseClearDelay = MWBase::Environment::get().getWorld()->getStore().get().find("fCorpseClearDelay")->getFloat(); + static const float fCorpseClearDelay = MWBase::Environment::get().getWorld()->getStore().get().find("fCorpseClearDelay")->mValue.getFloat(); if (creatureStats.isDead() && creatureStats.isDeathAnimationFinished() && !ptr.getClass().isPersistent(ptr) && @@ -958,7 +958,7 @@ namespace MWWorld { if (mState == State_Loaded) { - static const int iMonthsToRespawn = MWBase::Environment::get().getWorld()->getStore().get().find("iMonthsToRespawn")->getInt(); + static const int iMonthsToRespawn = MWBase::Environment::get().getWorld()->getStore().get().find("iMonthsToRespawn")->mValue.getInteger(); if (MWBase::Environment::get().getWorld()->getTimeStamp() - mLastRespawn > 24*30*iMonthsToRespawn) { mLastRespawn = MWBase::Environment::get().getWorld()->getTimeStamp(); diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 6cfffcde6..7f3018c55 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -252,8 +252,8 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) const MWWorld::Store &store = world->getStore().get(); MWMechanics::NpcStats& stats = actor.getClass().getNpcStats(actor); - static float fUnarmoredBase1 = store.find("fUnarmoredBase1")->getFloat(); - static float fUnarmoredBase2 = store.find("fUnarmoredBase2")->getFloat(); + static float fUnarmoredBase1 = store.find("fUnarmoredBase1")->mValue.getFloat(); + static float fUnarmoredBase2 = store.find("fUnarmoredBase2")->mValue.getFloat(); int unarmoredSkill = stats.getSkill(ESM::Skill::Unarmored).getModified(); float unarmoredRating = (fUnarmoredBase1 * unarmoredSkill) * (fUnarmoredBase2 * unarmoredSkill); @@ -921,7 +921,7 @@ void MWWorld::InventoryStore::rechargeItems(float duration) continue; static float fMagicItemRechargePerSecond = MWBase::Environment::get().getWorld()->getStore().get().find( - "fMagicItemRechargePerSecond")->getFloat(); + "fMagicItemRechargePerSecond")->mValue.getFloat(); if (it->first->getCellRef().getEnchantmentCharge() <= it->second) { diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 44b78336d..389f59983 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -64,7 +64,7 @@ namespace MWWorld MWMechanics::CreatureStats& creatureStats = getPlayer().getClass().getCreatureStats(getPlayer()); MWMechanics::NpcStats& npcStats = getPlayer().getClass().getNpcStats(getPlayer()); MWMechanics::DynamicStat health = creatureStats.getDynamic(0); - creatureStats.setHealth(int(health.getBase() / gmst.find("fWereWolfHealth")->getFloat())); + creatureStats.setHealth(int(health.getBase() / gmst.find("fWereWolfHealth")->mValue.getFloat())); for (int i=0; i health = creatureStats.getDynamic(0); - creatureStats.setHealth(int(health.getBase() * gmst.find("fWereWolfHealth")->getFloat())); + creatureStats.setHealth(int(health.getBase() * gmst.find("fWereWolfHealth")->mValue.getFloat())); for(size_t i = 0;i < ESM::Attribute::Length;++i) { // Oh, Bethesda. It's "Intelligence". @@ -85,7 +85,7 @@ namespace MWWorld ESM::Attribute::sAttributeNames[i]); MWMechanics::AttributeValue value = npcStats.getAttribute(i); - value.setBase(int(gmst.find(name)->getFloat())); + value.setBase(int(gmst.find(name)->mValue.getFloat())); npcStats.setAttribute(i, value); } @@ -100,7 +100,7 @@ namespace MWWorld ESM::Skill::sSkillNames[i]); MWMechanics::SkillValue value = npcStats.getSkill(i); - value.setBase(int(gmst.find(name)->getFloat())); + value.setBase(int(gmst.find(name)->mValue.getFloat())); npcStats.setSkill(i, value); } } diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index f150ff0ba..21218fab0 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -385,7 +385,7 @@ namespace MWWorld { osg::Quat orient = it->mNode->getAttitude(); static float fTargetSpellMaxSpeed = MWBase::Environment::get().getWorld()->getStore().get() - .find("fTargetSpellMaxSpeed")->getFloat(); + .find("fTargetSpellMaxSpeed")->mValue.getFloat(); float speed = fTargetSpellMaxSpeed * it->mSpeed; osg::Vec3f direction = orient * osg::Vec3f(0,1,0); direction.normalize(); diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index d12e633be..2a9e8d7cc 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -911,7 +911,7 @@ inline void WeatherManager::addWeather(const std::string& name, float dlFactor, float dlOffset, const std::string& particleEffect) { - static const float fStromWindSpeed = mStore.get().find("fStromWindSpeed")->getFloat(); + static const float fStromWindSpeed = mStore.get().find("fStromWindSpeed")->mValue.getFloat(); Weather weather(name, fallback, fStromWindSpeed, mRainSpeed, dlFactor, dlOffset, particleEffect); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 0bc952e89..48cb1dda3 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -190,7 +190,7 @@ namespace MWWorld mStore.setUp(true); mStore.movePlayerRecord(); - mSwimHeightScale = mStore.get().find("fSwimHeightScale")->getFloat(); + mSwimHeightScale = mStore.get().find("fSwimHeightScale")->mValue.getFloat(); mWeatherManager.reset(new MWWorld::WeatherManager(*mRendering, mFallback, mStore)); @@ -1026,7 +1026,7 @@ namespace MWWorld if (mActivationDistanceOverride >= 0) return static_cast(mActivationDistanceOverride); - static const int iMaxActivateDist = getStore().get().find("iMaxActivateDist")->getInt(); + static const int iMaxActivateDist = getStore().get().find("iMaxActivateDist")->mValue.getInteger(); return static_cast(iMaxActivateDist); } @@ -1709,7 +1709,7 @@ namespace MWWorld bool swimming = isSwimming(player); bool flying = isFlying(player); - static const float i1stPersonSneakDelta = getStore().get().find("i1stPersonSneakDelta")->getFloat(); + static const float i1stPersonSneakDelta = getStore().get().find("i1stPersonSneakDelta")->mValue.getFloat(); if (sneaking && !swimming && !flying) mRendering->getCamera()->setSneakOffset(i1stPersonSneakDelta); else @@ -2803,7 +2803,7 @@ namespace MWWorld if (!actor.isEmpty() && actor != MWMechanics::getPlayer() && !manualSpell) stats.getAiSequence().getCombatTargets(targetActors); - const float fCombatDistance = getStore().get().find("fCombatDistance")->getFloat(); + const float fCombatDistance = getStore().get().find("fCombatDistance")->mValue.getFloat(); osg::Vec3f hitPosition = actor.getRefData().getPosition().asVec3(); @@ -3267,8 +3267,8 @@ namespace MWWorld int bounty = player.getClass().getNpcStats(player).getBounty(); int playerGold = player.getClass().getContainerStore(player).count(ContainerStore::sGoldId); - float fCrimeGoldDiscountMult = getStore().get().find("fCrimeGoldDiscountMult")->getFloat(); - float fCrimeGoldTurnInMult = getStore().get().find("fCrimeGoldTurnInMult")->getFloat(); + float fCrimeGoldDiscountMult = getStore().get().find("fCrimeGoldDiscountMult")->mValue.getFloat(); + float fCrimeGoldTurnInMult = getStore().get().find("fCrimeGoldTurnInMult")->mValue.getFloat(); int discount = static_cast(bounty * fCrimeGoldDiscountMult); int turnIn = static_cast(bounty * fCrimeGoldTurnInMult); @@ -3333,7 +3333,7 @@ namespace MWWorld mPlayer->recordCrimeId(); confiscateStolenItems(player); - int iDaysinPrisonMod = getStore().get().find("iDaysinPrisonMod")->getInt(); + int iDaysinPrisonMod = getStore().get().find("iDaysinPrisonMod")->mValue.getInteger(); mDaysInPrison = std::max(1, bounty / iDaysinPrisonMod); return; @@ -3391,7 +3391,7 @@ namespace MWWorld { const ESM::CreatureLevList* list = getStore().get().find(creatureList); - int iNumberCreatures = getStore().get().find("iNumberCreatures")->getInt(); + int iNumberCreatures = getStore().get().find("iNumberCreatures")->mValue.getInteger(); int numCreatures = 1 + Misc::Rng::rollDice(iNumberCreatures); // [1, iNumberCreatures] for (int i=0; i Date: Thu, 30 Aug 2018 23:52:33 +0300 Subject: [PATCH 44/44] Grant Enchant experience even if recharging fails (bug #4622) --- CHANGELOG.md | 1 + apps/openmw/mwgui/recharge.cpp | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5453ffb49..8ae6088de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -110,6 +110,7 @@ Bug #4615: Flicker effects for light sources are handled incorrectly Bug #4617: First person sneaking offset is not applied while the character is in air Bug #4618: Sneaking is possible while the character is flying + Bug #4622: Recharging enchanted items with Soul Gems does not award experience if it fails Feature #1645: Casting effects from objects Feature #2606: Editor: Implemented (optional) case sensitive global search Feature #3083: Play animation when NPC is casting spell via script diff --git a/apps/openmw/mwgui/recharge.cpp b/apps/openmw/mwgui/recharge.cpp index 26a364f72..8bd8e250b 100644 --- a/apps/openmw/mwgui/recharge.cpp +++ b/apps/openmw/mwgui/recharge.cpp @@ -169,14 +169,13 @@ void Recharge::onItemClicked(MyGUI::Widget *sender, const MWWorld::Ptr& item) MWBase::Environment::get().getWindowManager()->playSound("Enchant Success"); player.getClass().getContainerStore(player).restack(item); - - player.getClass().skillUsageSucceeded (player, ESM::Skill::Enchant, 0); } else { MWBase::Environment::get().getWindowManager()->playSound("Enchant Fail"); } + player.getClass().skillUsageSucceeded (player, ESM::Skill::Enchant, 0); gem.getContainerStore()->remove(gem, 1, player); if (gem.getRefData().getCount() == 0)