mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-03 19:49:41 +00:00
Merge branch 'master' of https://github.com/OpenMW/openmw
This commit is contained in:
commit
4680bc6c93
25 changed files with 389 additions and 139 deletions
|
@ -38,13 +38,13 @@ add_openmw_dir (mwgui
|
||||||
itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog
|
itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog
|
||||||
enchantingdialog trainingwindow travelwindow exposedwindow cursor spellicons
|
enchantingdialog trainingwindow travelwindow exposedwindow cursor spellicons
|
||||||
merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks
|
merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks
|
||||||
keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
|
itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
|
||||||
tradeitemmodel companionitemmodel pickpocketitemmodel controllers savegamedialog
|
tradeitemmodel companionitemmodel pickpocketitemmodel controllers savegamedialog
|
||||||
recharge mode videowidget backgroundimage itemwidget screenfader debugwindow
|
recharge mode videowidget backgroundimage itemwidget screenfader debugwindow
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwdialogue
|
add_openmw_dir (mwdialogue
|
||||||
dialoguemanagerimp journalimp journalentry quest topic filter selectwrapper
|
dialoguemanagerimp journalimp journalentry quest topic filter selectwrapper hypertextparser keywordsearch
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwscript
|
add_openmw_dir (mwscript
|
||||||
|
|
|
@ -199,6 +199,10 @@ namespace MWBase
|
||||||
virtual MWWorld::Ptr searchPtrViaActorId (int actorId) = 0;
|
virtual MWWorld::Ptr searchPtrViaActorId (int actorId) = 0;
|
||||||
///< Search is limited to the active cells.
|
///< 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
|
/// \todo enable reference in the OGRE scene
|
||||||
virtual void enable (const MWWorld::Ptr& ptr) = 0;
|
virtual void enable (const MWWorld::Ptr& ptr) = 0;
|
||||||
|
|
||||||
|
|
|
@ -191,8 +191,11 @@ namespace MWClass
|
||||||
|
|
||||||
std::string text;
|
std::string text;
|
||||||
|
|
||||||
|
if (ref->mBase->mData.mWeight != 0)
|
||||||
|
{
|
||||||
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
|
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
|
||||||
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
|
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
|
||||||
|
}
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||||
text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "../mwmechanics/npcstats.hpp"
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
|
|
||||||
#include "filter.hpp"
|
#include "filter.hpp"
|
||||||
|
#include "hypertextparser.hpp"
|
||||||
|
|
||||||
namespace MWDialogue
|
namespace MWDialogue
|
||||||
{
|
{
|
||||||
|
@ -82,42 +83,27 @@ namespace MWDialogue
|
||||||
|
|
||||||
void DialogueManager::parseText (const std::string& text)
|
void DialogueManager::parseText (const std::string& text)
|
||||||
{
|
{
|
||||||
std::vector<HyperTextToken> hypertext = ParseHyperText(text);
|
std::vector<HyperTextParser::Token> hypertext = HyperTextParser::parseHyperText(text);
|
||||||
|
|
||||||
//calculation of standard form fir all hyperlinks
|
for (std::vector<HyperTextParser::Token>::iterator tok = hypertext.begin(); tok != hypertext.end(); ++tok)
|
||||||
for (size_t i = 0; i < hypertext.size(); ++i)
|
|
||||||
{
|
{
|
||||||
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)
|
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)
|
if (tok->isImplicitKeyword() && mTranslationDataStorage.hasTranslation())
|
||||||
{
|
continue;
|
||||||
std::list<std::string>::iterator it;
|
|
||||||
for(it = mActorKnownTopics.begin(); it != mActorKnownTopics.end(); ++it)
|
if (std::find(mActorKnownTopics.begin(), mActorKnownTopics.end(), topicId) != mActorKnownTopics.end())
|
||||||
{
|
mKnownTopics[topicId] = true;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTopics();
|
updateTopics();
|
||||||
|
@ -724,55 +710,4 @@ namespace MWDialogue
|
||||||
mLastTopic, actor.getClass().getName(actor));
|
mLastTopic, actor.getClass().getName(actor));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<HyperTextToken> ParseHyperText(const std::string& text)
|
|
||||||
{
|
|
||||||
std::vector<HyperTextToken> 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,21 +103,6 @@ namespace MWDialogue
|
||||||
/// Removes the last added topic response for the given actor from the journal
|
/// Removes the last added topic response for the given actor from the journal
|
||||||
virtual void clearInfoActor (const MWWorld::Ptr& actor) const;
|
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<HyperTextToken> ParseHyperText(const std::string& text);
|
|
||||||
|
|
||||||
size_t RemovePseudoAsterisks(std::string& phrase);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
89
apps/openmw/mwdialogue/hypertextparser.cpp
Normal file
89
apps/openmw/mwdialogue/hypertextparser.cpp
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
#include <components/esm/loaddial.hpp>
|
||||||
|
|
||||||
|
#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<Token> parseHyperText(const std::string & text)
|
||||||
|
{
|
||||||
|
std::vector<Token> 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<Token> & tokens)
|
||||||
|
{
|
||||||
|
const MWWorld::Store<ESM::Dialogue> & dialogs =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
|
||||||
|
|
||||||
|
std::list<std::string> keywordList;
|
||||||
|
for (MWWorld::Store<ESM::Dialogue>::iterator it = dialogs.begin(); it != dialogs.end(); ++it)
|
||||||
|
keywordList.push_back(Misc::StringUtils::lowerCase(it->mId));
|
||||||
|
keywordList.sort(Misc::StringUtils::ciLess);
|
||||||
|
|
||||||
|
KeywordSearch<std::string, int /*unused*/> keywordSearch;
|
||||||
|
KeywordSearch<std::string, int /*unused*/>::Match match;
|
||||||
|
|
||||||
|
for (std::list<std::string>::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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
apps/openmw/mwdialogue/hypertextparser.hpp
Normal file
36
apps/openmw/mwdialogue/hypertextparser.hpp
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef GAME_MWDIALOGUE_HYPERTEXTPARSER_H
|
||||||
|
#define GAME_MWDIALOGUE_HYPERTEXTPARSER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
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<Token> parseHyperText(const std::string & text);
|
||||||
|
void tokenizeKeywords(const std::string & text, std::vector<Token> & tokens);
|
||||||
|
size_t removePseudoAsterisks(std::string & phrase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef MWGUI_KEYWORDSEARCH_H
|
#ifndef GAME_MWDIALOGUE_KEYWORDSEARCH_H
|
||||||
#define MWGUI_KEYWORDSEARCH_H
|
#define GAME_MWDIALOGUE_KEYWORDSEARCH_H
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
#include <components/misc/stringops.hpp>
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWDialogue
|
||||||
{
|
{
|
||||||
|
|
||||||
template <typename string_t, typename value_t>
|
template <typename string_t, typename value_t>
|
||||||
|
@ -141,7 +141,6 @@ public:
|
||||||
match.mValue = candidate->second.mValue;
|
match.mValue = candidate->second.mValue;
|
||||||
match.mBeg = i;
|
match.mBeg = i;
|
||||||
match.mEnd = k;
|
match.mEnd = k;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#include "bookpage.hpp"
|
#include "bookpage.hpp"
|
||||||
|
|
||||||
#include "keywordsearch.hpp"
|
#include "../mwdialogue/keywordsearch.hpp"
|
||||||
|
|
||||||
namespace Gui
|
namespace Gui
|
||||||
{
|
{
|
||||||
|
@ -76,7 +76,7 @@ namespace MWGui
|
||||||
virtual void activated ();
|
virtual void activated ();
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef KeywordSearch <std::string, intptr_t> KeywordSearchT;
|
typedef MWDialogue::KeywordSearch <std::string, intptr_t> KeywordSearchT;
|
||||||
|
|
||||||
struct DialogueText
|
struct DialogueText
|
||||||
{
|
{
|
||||||
|
|
|
@ -132,6 +132,7 @@ namespace MWGui
|
||||||
virtual int pageSplit();
|
virtual int pageSplit();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual ~GraphicElement() {}
|
||||||
MyGUI::Widget * mParent;
|
MyGUI::Widget * mParent;
|
||||||
Paginator & mPaginator;
|
Paginator & mPaginator;
|
||||||
BlockStyle mBlockStyle;
|
BlockStyle mBlockStyle;
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
#include "../mwbase/journal.hpp"
|
#include "../mwbase/journal.hpp"
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
#include "../mwdialogue/journalentry.hpp"
|
|
||||||
|
|
||||||
#include "keywordsearch.hpp"
|
#include "../mwdialogue/journalentry.hpp"
|
||||||
|
#include "../mwdialogue/keywordsearch.hpp"
|
||||||
|
|
||||||
namespace MWGui {
|
namespace MWGui {
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ struct JournalViewModelImpl;
|
||||||
|
|
||||||
struct JournalViewModelImpl : JournalViewModel
|
struct JournalViewModelImpl : JournalViewModel
|
||||||
{
|
{
|
||||||
typedef KeywordSearch <std::string, intptr_t> KeywordSearchT;
|
typedef MWDialogue::KeywordSearch <std::string, intptr_t> KeywordSearchT;
|
||||||
|
|
||||||
mutable bool mKeywordSearchLoaded;
|
mutable bool mKeywordSearchLoaded;
|
||||||
mutable KeywordSearchT mKeywordSearch;
|
mutable KeywordSearchT mKeywordSearch;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/cellstore.hpp"
|
#include "../mwworld/cellstore.hpp"
|
||||||
|
#include "../mwworld/containerstore.hpp"
|
||||||
|
|
||||||
#include "../mwmechanics/npcstats.hpp"
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
|
|
||||||
|
@ -434,6 +435,16 @@ namespace MWScript
|
||||||
else
|
else
|
||||||
ref2 = MWBase::Environment::get().getWorld()->getPtr(id, false);
|
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);
|
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)
|
// If the objects are in different worldspaces, return a large value (just like vanilla)
|
||||||
|
|
|
@ -454,7 +454,8 @@ namespace MWScript
|
||||||
if (::Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), item))
|
if (::Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), item))
|
||||||
{
|
{
|
||||||
int removed = store.remove(*iter, toRemove, ptr);
|
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;
|
toRemove -= removed;
|
||||||
|
|
||||||
|
|
|
@ -149,6 +149,17 @@ namespace MWWorld
|
||||||
forEachImp (functor, mCreatureLists);
|
forEachImp (functor, mCreatureLists);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class Functor>
|
||||||
|
bool forEachContainer (Functor& functor)
|
||||||
|
{
|
||||||
|
mHasState = true;
|
||||||
|
|
||||||
|
return
|
||||||
|
forEachImp (functor, mContainers) &&
|
||||||
|
forEachImp (functor, mCreatures) &&
|
||||||
|
forEachImp (functor, mNpcs);
|
||||||
|
}
|
||||||
|
|
||||||
bool isExterior() const;
|
bool isExterior() const;
|
||||||
|
|
||||||
Ptr searchInContainer (const std::string& id);
|
Ptr searchInContainer (const std::string& id);
|
||||||
|
|
|
@ -272,7 +272,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr
|
||||||
item.mCell = actorPtr.getCell();
|
item.mCell = actorPtr.getCell();
|
||||||
}
|
}
|
||||||
|
|
||||||
item.mContainerStore = 0;
|
item.mContainerStore = this;
|
||||||
|
|
||||||
MWBase::Environment::get().getWorld()->getLocalScripts().add(script, item);
|
MWBase::Environment::get().getWorld()->getLocalScripts().add(script, item);
|
||||||
|
|
||||||
|
|
|
@ -1187,7 +1187,7 @@ namespace MWWorld
|
||||||
|
|
||||||
mShared.clear();
|
mShared.clear();
|
||||||
mShared.reserve(mStatic.size());
|
mShared.reserve(mStatic.size());
|
||||||
typename std::map<std::string, ESM::Dialogue>::iterator it = mStatic.begin();
|
std::map<std::string, ESM::Dialogue>::iterator it = mStatic.begin();
|
||||||
for (; it != mStatic.end(); ++it) {
|
for (; it != mStatic.end(); ++it) {
|
||||||
mShared.push_back(&(it->second));
|
mShared.push_back(&(it->second));
|
||||||
}
|
}
|
||||||
|
|
|
@ -657,6 +657,47 @@ namespace MWWorld
|
||||||
return mWorldScene->searchPtrViaActorId (actorId);
|
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)
|
void World::addContainerScripts(const Ptr& reference, CellStore * cell)
|
||||||
{
|
{
|
||||||
if( reference.getTypeName()==typeid (ESM::Container).name() ||
|
if( reference.getTypeName()==typeid (ESM::Container).name() ||
|
||||||
|
|
|
@ -260,6 +260,10 @@ namespace MWWorld
|
||||||
virtual Ptr searchPtrViaActorId (int actorId);
|
virtual Ptr searchPtrViaActorId (int actorId);
|
||||||
///< Search is limited to the active cells.
|
///< 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);
|
virtual void adjustPosition (const Ptr& ptr, bool force);
|
||||||
///< Adjust position after load to be on ground. Must be called after model load.
|
///< Adjust position after load to be on ground. Must be called after model load.
|
||||||
/// @param force do this even if the ptr is flying
|
/// @param force do this even if the ptr is flying
|
||||||
|
|
|
@ -382,7 +382,6 @@ endmacro()
|
||||||
ogre_find_component(Paging OgrePaging.h)
|
ogre_find_component(Paging OgrePaging.h)
|
||||||
# look for Overlay component
|
# look for Overlay component
|
||||||
ogre_find_component(Overlay OgreOverlaySystem.h)
|
ogre_find_component(Overlay OgreOverlaySystem.h)
|
||||||
ogre_find_component(Overlay OgreOverlay.h)
|
|
||||||
# look for Terrain component
|
# look for Terrain component
|
||||||
ogre_find_component(Terrain OgreTerrain.h)
|
ogre_find_component(Terrain OgreTerrain.h)
|
||||||
# look for Property component
|
# look for Property component
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "videoplayer.hpp"
|
#include "videoplayer.hpp"
|
||||||
|
|
||||||
|
#include "audiofactory.hpp"
|
||||||
#include "videostate.hpp"
|
#include "videostate.hpp"
|
||||||
|
|
||||||
namespace Video
|
namespace Video
|
||||||
|
|
|
@ -243,7 +243,7 @@ void VideoState::video_refresh()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const float threshold = 0.03;
|
const float threshold = 0.03f;
|
||||||
if (this->pictq[pictq_rindex].pts > this->get_master_clock() + threshold)
|
if (this->pictq[pictq_rindex].pts > this->get_master_clock() + threshold)
|
||||||
return; // not ready yet to show this picture
|
return; // not ready yet to show this picture
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 498 198" name="_Main">
|
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 498 198" name="_Main">
|
||||||
|
|
||||||
<!-- Class name -->
|
<!-- Class name -->
|
||||||
<Widget type="TextBox" skin="NormalText" position="8 8 48 23" name="LabelT" align="Left Top">
|
<Widget type="TextBox" skin="NormalText" position="8 8 52 23" name="LabelT" align="Left Top">
|
||||||
<Property key="Caption" value="#{sName}:"/>
|
<Property key="Caption" value="#{sName}:"/>
|
||||||
<Property key="TextAlign" value="Left VCenter"/>
|
<Property key="TextAlign" value="Left VCenter"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
|
@ -69,33 +69,46 @@
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
<!-- Player level, race and class -->
|
<!-- Player level, race and class -->
|
||||||
<Widget type="Widget" skin="MW_Box" position="8 78 212 62" align="Left Top HStretch">
|
<Widget type="Widget" skin="MW_Box" position="8 78 212 62" align="Top HStretch">
|
||||||
<Widget type="TextBox" skin="NormalText" position="4 4 100 18" name="Level_str" align="Left Top HStretch">
|
<Widget type="HBox" position="4 4 204 18" align="Top HStretch">
|
||||||
|
<Widget type="AutoSizedTextBox" skin="NormalText" position="0 0 200 18" name="Level_str" align="Left Top">
|
||||||
<Property key="Caption" value="#{sLevel}"/>
|
<Property key="Caption" value="#{sLevel}"/>
|
||||||
<UserString key="ToolTipType" value="Layout"/>
|
<UserString key="ToolTipType" value="Layout"/>
|
||||||
<UserString key="ToolTipLayout" value="LevelToolTip"/>
|
<UserString key="ToolTipLayout" value="LevelToolTip"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
<Widget type="TextBox" skin="NormalText" position="4 22 100 18" name="Race_str" align="Left Top HStretch">
|
<Widget type="TextBox" skin="SandTextRight" position="200 0 40 18" name="LevelText" align="Right Top">
|
||||||
|
<Property key="TextAlign" value="Right Top"/>
|
||||||
|
<UserString key="ToolTipType" value="Layout"/>
|
||||||
|
<UserString key="ToolTipLayout" value="LevelToolTip"/>
|
||||||
|
<UserString key="HStretch" value="true"/>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
</Widget>
|
||||||
|
<Widget type="HBox" position="4 24 204 18" align="Top HStretch">
|
||||||
|
<Widget type="AutoSizedTextBox" skin="NormalText" position="0 0 95 18" name="Race_str" align="Left Top">
|
||||||
<Property key="Caption" value="#{sRace}"/>
|
<Property key="Caption" value="#{sRace}"/>
|
||||||
<UserString key="ToolTipType" value="Layout"/>
|
<UserString key="ToolTipType" value="Layout"/>
|
||||||
<UserString key="ToolTipLayout" value="TextWithCenteredCaptionToolTip"/>
|
<UserString key="ToolTipLayout" value="TextWithCenteredCaptionToolTip"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
<Widget type="TextBox" skin="NormalText" position="4 40 100 18" name="Class_str" align="Left Top HStretch">
|
<Widget type="TextBox" skin="SandTextRight" position="104 0 200 18" name="RaceText" align="Left Top">
|
||||||
|
<Property key="TextAlign" value="Right Top"/>
|
||||||
|
<UserString key="ToolTipType" value="Layout"/>
|
||||||
|
<UserString key="ToolTipLayout" value="TextWithCenteredCaptionToolTip"/>
|
||||||
|
<UserString key="HStretch" value="true"/>
|
||||||
|
</Widget>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="HBox" position="4 42 204 18" align="Top HStretch">
|
||||||
|
<Widget type="AutoSizedTextBox" skin="NormalText" position="0 0 95 18" name="Class_str" align="Left Top">
|
||||||
<Property key="Caption" value="#{sClass}"/>
|
<Property key="Caption" value="#{sClass}"/>
|
||||||
<UserString key="ToolTipType" value="Layout"/>
|
<UserString key="ToolTipType" value="Layout"/>
|
||||||
<UserString key="ToolTipLayout" value="ClassToolTip"/>
|
<UserString key="ToolTipLayout" value="ClassToolTip"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
<Widget type="TextBox" skin="SandTextRight" position="104 4 104 18" name="LevelText" align="Right Top">
|
<Widget type="TextBox" skin="SandTextRight" position="104 0 200 18" name="ClassText" align="Left Top">
|
||||||
<UserString key="ToolTipType" value="Layout"/>
|
<Property key="TextAlign" value="Right Top"/>
|
||||||
<UserString key="ToolTipLayout" value="LevelToolTip"/>
|
|
||||||
</Widget>
|
|
||||||
<Widget type="TextBox" skin="SandTextRight" position="104 22 104 18" name="RaceText" align="Right Top">
|
|
||||||
<UserString key="ToolTipType" value="Layout"/>
|
|
||||||
<UserString key="ToolTipLayout" value="TextWithCenteredCaptionToolTip"/>
|
|
||||||
</Widget>
|
|
||||||
<Widget type="TextBox" skin="SandTextRight" position="104 40 104 18" name="ClassText" align="Right Top">
|
|
||||||
<UserString key="ToolTipType" value="Layout"/>
|
<UserString key="ToolTipType" value="Layout"/>
|
||||||
<UserString key="ToolTipLayout" value="ClassToolTip"/>
|
<UserString key="ToolTipLayout" value="ClassToolTip"/>
|
||||||
|
<UserString key="HStretch" value="true"/>
|
||||||
|
</Widget>
|
||||||
</Widget>
|
</Widget>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
|
|
117
readme.txt
117
readme.txt
|
@ -98,6 +98,123 @@ Allowed options:
|
||||||
|
|
||||||
CHANGELOG
|
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
|
0.32.0
|
||||||
|
|
||||||
Bug #1132: Unable to jump when facing a wall
|
Bug #1132: Unable to jump when facing a wall
|
||||||
|
|
Loading…
Reference in a new issue