diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 7315a81d3..803c74325 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -38,13 +38,13 @@ add_openmw_dir (mwgui itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog enchantingdialog trainingwindow travelwindow exposedwindow cursor spellicons merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks - keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview + itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview tradeitemmodel companionitemmodel pickpocketitemmodel controllers savegamedialog recharge mode videowidget backgroundimage itemwidget screenfader debugwindow ) add_openmw_dir (mwdialogue - dialoguemanagerimp journalimp journalentry quest topic filter selectwrapper + dialoguemanagerimp journalimp journalentry quest topic filter selectwrapper hypertextparser keywordsearch ) add_openmw_dir (mwscript diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 71a45a92c..c1a889913 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -199,6 +199,10 @@ namespace MWBase virtual MWWorld::Ptr searchPtrViaActorId (int actorId) = 0; ///< Search is limited to the active cells. + virtual MWWorld::Ptr findContainer (const MWWorld::Ptr& ptr) = 0; + ///< Return a pointer to a liveCellRef which contains \a ptr. + /// \note Search is limited to the active cells. + /// \todo enable reference in the OGRE scene virtual void enable (const MWWorld::Ptr& ptr) = 0; diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 7b2d7e132..e6d266de2 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -191,8 +191,11 @@ namespace MWClass std::string text; - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); + if (ref->mBase->mData.mWeight != 0) + { + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); + } if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getCellRefString(ptr.getCellRef()); diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 892669678..eff54fbc0 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -42,6 +42,7 @@ #include "../mwmechanics/npcstats.hpp" #include "filter.hpp" +#include "hypertextparser.hpp" namespace MWDialogue { @@ -82,42 +83,27 @@ namespace MWDialogue void DialogueManager::parseText (const std::string& text) { - std::vector hypertext = ParseHyperText(text); + std::vector hypertext = HyperTextParser::parseHyperText(text); - //calculation of standard form fir all hyperlinks - for (size_t i = 0; i < hypertext.size(); ++i) + for (std::vector::iterator tok = hypertext.begin(); tok != hypertext.end(); ++tok) { - if (hypertext[i].mLink) + std::string topicId = Misc::StringUtils::lowerCase(tok->mText); + + if (tok->isExplicitLink()) { - size_t asterisk_count = MWDialogue::RemovePseudoAsterisks(hypertext[i].mText); + // calculation of standard form for all hyperlinks + size_t asterisk_count = HyperTextParser::removePseudoAsterisks(topicId); for(; asterisk_count > 0; --asterisk_count) - hypertext[i].mText.append("*"); + topicId.append("*"); - hypertext[i].mText = mTranslationDataStorage.topicStandardForm(hypertext[i].mText); + topicId = mTranslationDataStorage.topicStandardForm(topicId); } - } - for (size_t i = 0; i < hypertext.size(); ++i) - { - std::list::iterator it; - for(it = mActorKnownTopics.begin(); it != mActorKnownTopics.end(); ++it) - { - if (hypertext[i].mLink) - { - if( hypertext[i].mText == *it ) - { - mKnownTopics[hypertext[i].mText] = true; - } - } - else if( !mTranslationDataStorage.hasTranslation() ) - { - size_t pos = Misc::StringUtils::lowerCase(hypertext[i].mText).find(*it, 0); - if(pos !=std::string::npos) - { - mKnownTopics[*it] = true; - } - } - } + if (tok->isImplicitKeyword() && mTranslationDataStorage.hasTranslation()) + continue; + + if (std::find(mActorKnownTopics.begin(), mActorKnownTopics.end(), topicId) != mActorKnownTopics.end()) + mKnownTopics[topicId] = true; } updateTopics(); @@ -724,55 +710,4 @@ namespace MWDialogue mLastTopic, actor.getClass().getName(actor)); } } - - std::vector ParseHyperText(const std::string& text) - { - std::vector result; - MyGUI::UString utext(text); - size_t pos_end, iteration_pos = 0; - for(;;) - { - size_t pos_begin = utext.find('@', iteration_pos); - if (pos_begin != std::string::npos) - pos_end = utext.find('#', pos_begin); - - if (pos_begin != std::string::npos && pos_end != std::string::npos) - { - result.push_back( HyperTextToken(utext.substr(iteration_pos, pos_begin - iteration_pos), false) ); - - std::string link = utext.substr(pos_begin + 1, pos_end - pos_begin - 1); - result.push_back( HyperTextToken(link, true) ); - - iteration_pos = pos_end + 1; - } - else - { - result.push_back( HyperTextToken(utext.substr(iteration_pos), false) ); - break; - } - } - - return result; - } - - size_t RemovePseudoAsterisks(std::string& phrase) - { - size_t pseudoAsterisksCount = 0; - - if( !phrase.empty() ) - { - std::string::reverse_iterator rit = phrase.rbegin(); - - const char specialPseudoAsteriskCharacter = 127; - while( rit != phrase.rend() && *rit == specialPseudoAsteriskCharacter ) - { - pseudoAsterisksCount++; - ++rit; - } - } - - phrase = phrase.substr(0, phrase.length() - pseudoAsterisksCount); - - return pseudoAsterisksCount; - } } diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp index 6553ddc01..9c3d0d54b 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp @@ -103,21 +103,6 @@ namespace MWDialogue /// Removes the last added topic response for the given actor from the journal virtual void clearInfoActor (const MWWorld::Ptr& actor) const; }; - - - struct HyperTextToken - { - HyperTextToken(const std::string& text, bool link) : mText(text), mLink(link) {} - - std::string mText; - bool mLink; - }; - - // In translations (at least Russian) the links are marked with @#, so - // it should be a function to parse it - std::vector ParseHyperText(const std::string& text); - - size_t RemovePseudoAsterisks(std::string& phrase); } #endif diff --git a/apps/openmw/mwdialogue/hypertextparser.cpp b/apps/openmw/mwdialogue/hypertextparser.cpp new file mode 100644 index 000000000..776edac94 --- /dev/null +++ b/apps/openmw/mwdialogue/hypertextparser.cpp @@ -0,0 +1,89 @@ +#include + +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" + +#include "../mwworld/store.hpp" +#include "../mwworld/esmstore.hpp" + +#include "keywordsearch.hpp" + +#include "hypertextparser.hpp" + +namespace MWDialogue +{ + namespace HyperTextParser + { + std::vector parseHyperText(const std::string & text) + { + std::vector result; + size_t pos_end, iteration_pos = 0; + for(;;) + { + size_t pos_begin = text.find('@', iteration_pos); + if (pos_begin != std::string::npos) + pos_end = text.find('#', pos_begin); + + if (pos_begin != std::string::npos && pos_end != std::string::npos) + { + if (pos_begin != iteration_pos) + tokenizeKeywords(text.substr(iteration_pos, pos_begin - iteration_pos), result); + + std::string link = text.substr(pos_begin + 1, pos_end - pos_begin - 1); + result.push_back(Token(link, Token::ExplicitLink)); + + iteration_pos = pos_end + 1; + } + else + { + if (iteration_pos != text.size()) + tokenizeKeywords(text.substr(iteration_pos), result); + break; + } + } + + return result; + } + + void tokenizeKeywords(const std::string & text, std::vector & tokens) + { + const MWWorld::Store & dialogs = + MWBase::Environment::get().getWorld()->getStore().get(); + + std::list keywordList; + for (MWWorld::Store::iterator it = dialogs.begin(); it != dialogs.end(); ++it) + keywordList.push_back(Misc::StringUtils::lowerCase(it->mId)); + keywordList.sort(Misc::StringUtils::ciLess); + + KeywordSearch keywordSearch; + KeywordSearch::Match match; + + for (std::list::const_iterator it = keywordList.begin(); it != keywordList.end(); ++it) + keywordSearch.seed(*it, 0 /*unused*/); + + for (std::string::const_iterator it = text.begin(); it != text.end() && keywordSearch.search(it, text.end(), match, text.begin()); it = match.mEnd) + tokens.push_back(Token(std::string(match.mBeg, match.mEnd), Token::ImplicitKeyword)); + } + + size_t removePseudoAsterisks(std::string & phrase) + { + size_t pseudoAsterisksCount = 0; + + if( !phrase.empty() ) + { + std::string::reverse_iterator rit = phrase.rbegin(); + + const char specialPseudoAsteriskCharacter = 127; + while( rit != phrase.rend() && *rit == specialPseudoAsteriskCharacter ) + { + pseudoAsterisksCount++; + ++rit; + } + } + + phrase = phrase.substr(0, phrase.length() - pseudoAsterisksCount); + + return pseudoAsterisksCount; + } + } +} diff --git a/apps/openmw/mwdialogue/hypertextparser.hpp b/apps/openmw/mwdialogue/hypertextparser.hpp new file mode 100644 index 000000000..13e135f3c --- /dev/null +++ b/apps/openmw/mwdialogue/hypertextparser.hpp @@ -0,0 +1,36 @@ +#ifndef GAME_MWDIALOGUE_HYPERTEXTPARSER_H +#define GAME_MWDIALOGUE_HYPERTEXTPARSER_H + +#include +#include + +namespace MWDialogue +{ + namespace HyperTextParser + { + struct Token + { + enum Type + { + ExplicitLink, // enclosed in @# + ImplicitKeyword + }; + + Token(const std::string & text, Type type) : mText(text), mType(type) {} + + bool isExplicitLink() { return mType == ExplicitLink; } + bool isImplicitKeyword() { return mType == ImplicitKeyword; } + + std::string mText; + Type mType; + }; + + // In translations (at least Russian) the links are marked with @#, so + // it should be a function to parse it + std::vector parseHyperText(const std::string & text); + void tokenizeKeywords(const std::string & text, std::vector & tokens); + size_t removePseudoAsterisks(std::string & phrase); + } +} + +#endif diff --git a/apps/openmw/mwgui/keywordsearch.cpp b/apps/openmw/mwdialogue/keywordsearch.cpp similarity index 100% rename from apps/openmw/mwgui/keywordsearch.cpp rename to apps/openmw/mwdialogue/keywordsearch.cpp diff --git a/apps/openmw/mwgui/keywordsearch.hpp b/apps/openmw/mwdialogue/keywordsearch.hpp similarity index 98% rename from apps/openmw/mwgui/keywordsearch.hpp rename to apps/openmw/mwdialogue/keywordsearch.hpp index 4f4459b35..51508890c 100644 --- a/apps/openmw/mwgui/keywordsearch.hpp +++ b/apps/openmw/mwdialogue/keywordsearch.hpp @@ -1,5 +1,5 @@ -#ifndef MWGUI_KEYWORDSEARCH_H -#define MWGUI_KEYWORDSEARCH_H +#ifndef GAME_MWDIALOGUE_KEYWORDSEARCH_H +#define GAME_MWDIALOGUE_KEYWORDSEARCH_H #include #include @@ -9,7 +9,7 @@ #include -namespace MWGui +namespace MWDialogue { template @@ -141,7 +141,6 @@ public: match.mValue = candidate->second.mValue; match.mBeg = i; match.mEnd = k; - return true; } } diff --git a/apps/openmw/mwgui/dialogue.hpp b/apps/openmw/mwgui/dialogue.hpp index 18f1f1555..23709e8fe 100644 --- a/apps/openmw/mwgui/dialogue.hpp +++ b/apps/openmw/mwgui/dialogue.hpp @@ -6,7 +6,7 @@ #include "bookpage.hpp" -#include "keywordsearch.hpp" +#include "../mwdialogue/keywordsearch.hpp" namespace Gui { @@ -76,7 +76,7 @@ namespace MWGui virtual void activated (); }; - typedef KeywordSearch KeywordSearchT; + typedef MWDialogue::KeywordSearch KeywordSearchT; struct DialogueText { diff --git a/apps/openmw/mwgui/formatting.hpp b/apps/openmw/mwgui/formatting.hpp index 3e21b62e2..5b7925057 100644 --- a/apps/openmw/mwgui/formatting.hpp +++ b/apps/openmw/mwgui/formatting.hpp @@ -132,6 +132,7 @@ namespace MWGui virtual int pageSplit(); protected: + virtual ~GraphicElement() {} MyGUI::Widget * mParent; Paginator & mPaginator; BlockStyle mBlockStyle; diff --git a/apps/openmw/mwgui/journalviewmodel.cpp b/apps/openmw/mwgui/journalviewmodel.cpp index 0ab56200d..059af463f 100644 --- a/apps/openmw/mwgui/journalviewmodel.cpp +++ b/apps/openmw/mwgui/journalviewmodel.cpp @@ -12,9 +12,9 @@ #include "../mwbase/journal.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" -#include "../mwdialogue/journalentry.hpp" -#include "keywordsearch.hpp" +#include "../mwdialogue/journalentry.hpp" +#include "../mwdialogue/keywordsearch.hpp" namespace MWGui { @@ -22,7 +22,7 @@ struct JournalViewModelImpl; struct JournalViewModelImpl : JournalViewModel { - typedef KeywordSearch KeywordSearchT; + typedef MWDialogue::KeywordSearch KeywordSearchT; mutable bool mKeywordSearchLoaded; mutable KeywordSearchT mKeywordSearch; diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index cb02a6c97..52021839d 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -21,6 +21,7 @@ #include "../mwworld/class.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/containerstore.hpp" #include "../mwmechanics/npcstats.hpp" @@ -434,6 +435,16 @@ namespace MWScript else ref2 = MWBase::Environment::get().getWorld()->getPtr(id, false); + if (ref2.getContainerStore()) // is the object contained? + { + MWWorld::Ptr container = MWBase::Environment::get().getWorld()->findContainer(ref2); + + if (!container.isEmpty()) + ref2 = container; + else + throw std::runtime_error("failed to find container ptr"); + } + const MWWorld::Ptr ref = MWBase::Environment::get().getWorld()->getPtr(name, false); // If the objects are in different worldspaces, return a large value (just like vanilla) diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 0de8f3b91..c7d221139 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -454,7 +454,8 @@ namespace MWScript if (::Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), item)) { int removed = store.remove(*iter, toRemove, ptr); - MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter, removed); + MWWorld::Ptr dropped = MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter, removed); + dropped.getCellRef().setOwner(""); toRemove -= removed; diff --git a/apps/openmw/mwworld/cellstore.hpp b/apps/openmw/mwworld/cellstore.hpp index ba6fad7ba..e322ef4a4 100644 --- a/apps/openmw/mwworld/cellstore.hpp +++ b/apps/openmw/mwworld/cellstore.hpp @@ -149,6 +149,17 @@ namespace MWWorld forEachImp (functor, mCreatureLists); } + template + bool forEachContainer (Functor& functor) + { + mHasState = true; + + return + forEachImp (functor, mContainers) && + forEachImp (functor, mCreatures) && + forEachImp (functor, mNpcs); + } + bool isExterior() const; Ptr searchInContainer (const std::string& id); diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 085b079d9..45728371b 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -272,7 +272,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr item.mCell = actorPtr.getCell(); } - item.mContainerStore = 0; + item.mContainerStore = this; MWBase::Environment::get().getWorld()->getLocalScripts().add(script, item); diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index 2611bacbd..55c5b8191 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -1187,7 +1187,7 @@ namespace MWWorld mShared.clear(); mShared.reserve(mStatic.size()); - typename std::map::iterator it = mStatic.begin(); + std::map::iterator it = mStatic.begin(); for (; it != mStatic.end(); ++it) { mShared.push_back(&(it->second)); } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index d8e0d52b8..5d07a26a0 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -657,6 +657,47 @@ namespace MWWorld return mWorldScene->searchPtrViaActorId (actorId); } + struct FindContainerFunctor + { + Ptr mContainedPtr; + Ptr mResult; + + FindContainerFunctor(const Ptr& containedPtr) : mContainedPtr(containedPtr) {} + + bool operator() (Ptr ptr) + { + if (mContainedPtr.getContainerStore() == &ptr.getClass().getContainerStore(ptr)) + { + mResult = ptr; + return false; + } + + return true; + } + }; + + Ptr World::findContainer(const Ptr& ptr) + { + if (ptr.isInCell()) + return Ptr(); + + Ptr player = getPlayerPtr(); + if (ptr.getContainerStore() == &player.getClass().getContainerStore(player)) + return player; + + const Scene::CellStoreCollection& collection = mWorldScene->getActiveCells(); + for (Scene::CellStoreCollection::const_iterator cellIt = collection.begin(); cellIt != collection.end(); ++cellIt) + { + FindContainerFunctor functor(ptr); + (*cellIt)->forEachContainer(functor); + + if (!functor.mResult.isEmpty()) + return functor.mResult; + } + + return Ptr(); + } + void World::addContainerScripts(const Ptr& reference, CellStore * cell) { if( reference.getTypeName()==typeid (ESM::Container).name() || diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 334e799f2..fef279705 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -260,6 +260,10 @@ namespace MWWorld virtual Ptr searchPtrViaActorId (int actorId); ///< Search is limited to the active cells. + virtual MWWorld::Ptr findContainer (const MWWorld::Ptr& ptr); + ///< Return a pointer to a liveCellRef which contains \a ptr. + /// \note Search is limited to the active cells. + virtual void adjustPosition (const Ptr& ptr, bool force); ///< Adjust position after load to be on ground. Must be called after model load. /// @param force do this even if the ptr is flying diff --git a/cmake/FindOGRE.cmake b/cmake/FindOGRE.cmake index 51589698f..f2acf9d33 100644 --- a/cmake/FindOGRE.cmake +++ b/cmake/FindOGRE.cmake @@ -382,7 +382,6 @@ endmacro() ogre_find_component(Paging OgrePaging.h) # look for Overlay component ogre_find_component(Overlay OgreOverlaySystem.h) -ogre_find_component(Overlay OgreOverlay.h) # look for Terrain component ogre_find_component(Terrain OgreTerrain.h) # look for Property component diff --git a/extern/ogre-ffmpeg-videoplayer/videoplayer.cpp b/extern/ogre-ffmpeg-videoplayer/videoplayer.cpp index ac759804b..c2daf3579 100644 --- a/extern/ogre-ffmpeg-videoplayer/videoplayer.cpp +++ b/extern/ogre-ffmpeg-videoplayer/videoplayer.cpp @@ -1,5 +1,6 @@ #include "videoplayer.hpp" +#include "audiofactory.hpp" #include "videostate.hpp" namespace Video diff --git a/extern/ogre-ffmpeg-videoplayer/videostate.cpp b/extern/ogre-ffmpeg-videoplayer/videostate.cpp index 9d60cb81c..b36543880 100644 --- a/extern/ogre-ffmpeg-videoplayer/videostate.cpp +++ b/extern/ogre-ffmpeg-videoplayer/videostate.cpp @@ -243,7 +243,7 @@ void VideoState::video_refresh() } else { - const float threshold = 0.03; + const float threshold = 0.03f; if (this->pictq[pictq_rindex].pts > this->get_master_clock() + threshold) return; // not ready yet to show this picture diff --git a/files/mygui/openmw_chargen_create_class.layout b/files/mygui/openmw_chargen_create_class.layout index dee2f4fcf..1d071e621 100644 --- a/files/mygui/openmw_chargen_create_class.layout +++ b/files/mygui/openmw_chargen_create_class.layout @@ -3,7 +3,7 @@ - + diff --git a/files/mygui/openmw_stats_window.layout b/files/mygui/openmw_stats_window.layout index 6cdd4c02a..11119c404 100644 --- a/files/mygui/openmw_stats_window.layout +++ b/files/mygui/openmw_stats_window.layout @@ -69,33 +69,46 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/readme.txt b/readme.txt index 5f96771c7..254e60f7f 100644 --- a/readme.txt +++ b/readme.txt @@ -98,6 +98,123 @@ Allowed options: CHANGELOG +0.33.0 + +Bug #371: If console assigned to ` (probably to any symbolic key), "`" symbol will be added to console every time it closed +Bug #1148: Some books'/scrolls' contents are displayed incorrectly +Bug #1290: Editor: status bar is not updated when record filter is changed +Bug #1292: Editor: Documents are not removed on closing the last view +Bug #1301: Editor: File->Exit only checks the document it was issued from. +Bug #1353: Bluetooth on with no speaker connected results in significantly longer initial load times +Bug #1436: NPCs react from too far distance +Bug #1472: PC is placed on top of following NPC when changing cell +Bug #1487: Tall PC can get stuck in staircases +Bug #1565: Editor: Subviews are deleted on shutdown instead when they are closed +Bug #1623: Door marker on Ghorak Manor's balcony makes PC stuck +Bug #1633: Loaddoor to Sadrith Mora, Telvanni Council House spawns PC in the air +Bug #1655: Use Appropriate Application Icons on Windows +Bug #1679: Tribunal expansion, Meryn Othralas the backstage manager in the theatre group in Mournhold in the great bazaar district is floating a good feet above the ground. +Bug #1705: Rain is broken in third person +Bug #1706: Thunder and lighting still occurs while the game is paused during the rain +Bug #1708: No long jumping +Bug #1710: Editor: ReferenceableID drag to references record filter field creates incorrect filter +Bug #1712: Rest on Water +Bug #1715: "Cancel" button is not always on the same side of menu +Bug #1725: Editor: content file can be opened multiple times from the same dialogue +Bug #1730: [MOD: Less Generic Nerevarine] Compile failure attempting to enter the Corprusarium. +Bug #1733: Unhandled ffmpeg sample formats +Bug #1735: Editor: "Edit Record" context menu button not opening subview for journal infos +Bug #1750: Editor: record edits result in duplicate entries +Bug #1789: Editor: Some characters cannot be used in addon name +Bug #1803: Resizing the map does not keep the pre-resize center at the post-resize center +Bug #1821: Recovering Cloudcleaver quest: attacking Sosia is considered a crime when you side with Hlormar +Bug #1838: Editor: Preferences window appears off screen +Bug #1839: Editor: Record filter title should be moved two pixels to the right +Bug #1849: Subrecord error in MAO_Containers +Bug #1854: Knocked-out actors don't fully act knocked out +Bug #1855: "Soul trapped" sound doesn't play +Bug #1857: Missing sound effect for enchanted items with empty charge +Bug #1859: Missing console command: ResetActors (RA) +Bug #1861: Vendor category "MagicItems" is unhandled +Bug #1862: Launcher doesn't start if a file listed in launcher.cfg has correct name but wrong capitalization +Bug #1864: Editor: Region field for cell record in dialogue subview not working +Bug #1869: Editor: Change label "Musics" to "Music" +Bug #1870: Goblins killed while knocked down remain in knockdown-pose +Bug #1874: CellChanged events should not trigger when crossing exterior cell border +Bug #1877: Spriggans killed instantly if hit while regening +Bug #1878: Magic Menu text not un-highlighting correctly when going from spell to item as active magic +Bug #1881: Stuck in ceiling when entering castle karstaags tower +Bug #1884: Unlit torches still produce a burning sound +Bug #1885: Can type text in price field in barter window +Bug #1887: Equipped items do not emit sounds +Bug #1889: draugr lord aesliip will attack you and remain non-hostile +Bug #1892: Guard asks player to pay bounty of 0 gold +Bug #1895: getdistance should only return max float if ref and target are in different worldspaces +Bug #1896: Crash Report +Bug #1897: Conjured Equipment cant be re-equipped if removed +Bug #1898: Only Gidar Verothan follows you during establish the mine quest +Bug #1900: Black screen when you open the door and breath underwater +Bug #1904: Crash on casting recall spell +Bug #1906: Bound item checks should use the GMSTs +Bug #1907: Bugged door. Mournhold, The Winged Guar +Bug #1908: Crime reported for attacking Drathas Nerus's henchmen while they attack Dilborn +Bug #1909: Weird Quest Flow Infidelities quest +Bug #1910: Follower fighting with gone npc +Bug #1911: Npcs will drown themselves +Bug #1912: World map arrow stays static when inside a building +Bug #1920: Ulyne Henim disappears when game is loaded inside Vas +Bug #1922: alchemy-> potion of paralyze +Bug #1923: "levitation magic cannot be used here" shows outside of tribunal +Bug #1927: AI prefer melee over magic. +Bug #1929: Tamriel Rebuilt: Named cells that lie within the overlap with Morrowind.esm are not shown +Bug #1932: BTB - Spells 14.1 magic effects donĀ“t overwrite the Vanilla ones but are added +Bug #1935: Stacks of items are worth more when sold individually +Bug #1940: Launcher does not list addon files if base game file is renamed to a different case +Bug #1946: Mod "Tel Nechim - moved" breaks savegames +Bug #1947: Buying/Selling price doesn't properly affect the growth of mercantile skill +Bug #1950: followers from east empire company quest will fight each other if combat happens with anything +Bug #1958: Journal can be scrolled indefinitely with a mouse wheel +Bug #1959: Follower not leaving party on quest end +Bug #1960: Key bindings not always saved correctly +Bug #1961: Spell merchants selling racial bonus spells +Bug #1967: segmentation fault on load saves +Bug #1968: Jump sounds are not controlled by footsteps slider, sound weird compared to footsteps +Bug #1970: PC suffers silently when taking damage from lava +Bug #1971: Dwarven Sceptre collision area is not removed after killing one +Bug #1974: Dalin/Daris Norvayne follows player indefinitely +Bug #1975: East Empire Company faction rank breaks during Raven Rock questline +Bug #1979: 0 strength = permanently over encumbered +Bug #1993: Shrine blessing in Maar Gan doesn't work +Bug #2008: Enchanted items do not recharge +Bug #2011: Editor: OpenCS script compiler doesn't handle member variable access properly +Bug #2016: Dagoth Ur already dead in Facility Cavern +Bug #2017: Fighters Guild Quest: The Code Book - dialogue loop when UMP is loaded. +Bug #2019: Animation of 'Correct UV Mudcrabs' broken +Bug #2022: Alchemy window - Removing ingredient doesn't remove the number of ingredients +Bug #2025: Missing mouse-over text for non affordable items +Bug #2028: [MOD: Tamriel Rebuilt] Crashing when trying to enter interior cell "Ruinous Keep, Great Hall" +Bug #2029: Ienith Brothers Thiev's Guild quest journal entry not adding +Feature #471: Editor: Special case implementation for top-level window with single sub-window +Feature #472: Editor: Sub-Window re-use settings +Feature #704: Font colors import from fallback settings +Feature #854: Editor: Add user setting to show status bar +Feature #879: Editor: Open sub-views in a new top-level window +Feature #932: Editor: magic effect table +Feature #937: Editor: Path Grid table +Feature #938: Editor: Sound Gen table +Feature #1117: Death and LevelUp music +Feature #1226: Editor: Request UniversalId editing from table columns +Feature #1310: Editor: Rendering User Settings +Feature #1545: Targeting console on player +Feature #1597: Editor: Render terrain +Feature #1695: Editor: add column for CellRef's global variable +Feature #1696: Editor: use ESM::Cell's RefNum counter +Feature #1697: Redden player's vision when hit +Feature #1856: Spellcasting for non-biped creatures +Feature #1879: Editor: Run OpenMW with the currently edited content list +Task #1851: Move AI temporary state out of AI packages +Task #1865: Replace char type in records + 0.32.0 Bug #1132: Unable to jump when facing a wall