forked from mirror/openmw-tes3mp
Merge remote-tracking branch 'zini/master' into animation2
This commit is contained in:
commit
0cd3880b20
27 changed files with 345 additions and 86 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -15,3 +15,5 @@ makefile
|
|||
data
|
||||
*.kdev4
|
||||
CMakeLists.txt.user
|
||||
*.swp
|
||||
*.swo
|
||||
|
|
|
@ -67,35 +67,6 @@ endif()
|
|||
# We probably support older versions than this.
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
#
|
||||
# Pre-built binaries being used?
|
||||
#
|
||||
IF(EXISTS "${CMAKE_SOURCE_DIR}/prebuilt/vc100-mt-gd/ogre_1_7_1")
|
||||
set(PREBUILT_DIR "${CMAKE_SOURCE_DIR}/prebuilt/vc100-mt-gd")
|
||||
message (STATUS "OpenMW pre-built binaries found at ${PREBUILT_DIR}.")
|
||||
|
||||
SET(ENV{OGRE_HOME} "${PREBUILT_DIR}/ogre_1_7_1")
|
||||
|
||||
SET(ENV{BOOST_ROOT} "${PREBUILT_DIR}/boost_1_42_0")
|
||||
set(Boost_USE_STATIC_LIBS ON)
|
||||
set(Boost_USE_MULTITHREADED ON)
|
||||
set(ENV{BOOST_INCLUDEDIR} "${BOOST_ROOT}/include")
|
||||
set(ENV{BOOST_LIBRARYDIR} "${BOOST_ROOT}/lib")
|
||||
|
||||
set(ENV{FREETYPE_DIR} "${PREBUILT_DIR}/freetype-2.3.5-1")
|
||||
|
||||
set(USE_MPG123 OFF)
|
||||
set(USE_AUDIERE ON)
|
||||
set(AUDIERE_INCLUDE_DIR "${PREBUILT_DIR}/audiere-1.9.4/include")
|
||||
set(AUDIERE_LIBRARY "${PREBUILT_DIR}/audiere-1.9.4/lib/audiere.lib")
|
||||
|
||||
set(ENV{OPENALDIR} "${PREBUILT_DIR}/OpenAL 1.1 SDK")
|
||||
|
||||
set(BULLET_ROOT "${PREBUILT_DIR}/bullet")
|
||||
ELSE()
|
||||
message (STATUS "OpenMW pre-built binaries not found. Using standard locations.")
|
||||
ENDIF()
|
||||
|
||||
# source directory: libs
|
||||
|
||||
set(LIBDIR ${CMAKE_SOURCE_DIR}/libs)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
|
||||
#include "columnbase.hpp"
|
||||
|
||||
CSMWorld::ColumnBase::ColumnBase (const std::string& title, int flags)
|
||||
: mTitle (title), mFlags (flags)
|
||||
CSMWorld::ColumnBase::ColumnBase (const std::string& title, Display displayType, int flags)
|
||||
: mTitle (title), mDisplayType (displayType), mFlags (flags)
|
||||
{}
|
||||
|
||||
CSMWorld::ColumnBase::~ColumnBase() {}
|
||||
|
|
|
@ -14,7 +14,8 @@ namespace CSMWorld
|
|||
{
|
||||
enum Roles
|
||||
{
|
||||
Role_Flags = Qt::UserRole
|
||||
Role_Flags = Qt::UserRole,
|
||||
Role_Display = Qt::UserRole+1
|
||||
};
|
||||
|
||||
enum Flags
|
||||
|
@ -23,10 +24,18 @@ namespace CSMWorld
|
|||
Flag_Dialogue = 2 // column should be displayed in dialogue view
|
||||
};
|
||||
|
||||
enum Display
|
||||
{
|
||||
Display_String,
|
||||
Display_Integer,
|
||||
Display_Float
|
||||
};
|
||||
|
||||
std::string mTitle;
|
||||
int mFlags;
|
||||
Display mDisplayType;
|
||||
|
||||
ColumnBase (const std::string& title, int flag);
|
||||
ColumnBase (const std::string& title, Display displayType, int flag);
|
||||
|
||||
virtual ~ColumnBase();
|
||||
|
||||
|
@ -34,6 +43,7 @@ namespace CSMWorld
|
|||
|
||||
virtual bool isUserEditable() const;
|
||||
///< Can this column be edited directly by the user?
|
||||
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
|
@ -42,8 +52,8 @@ namespace CSMWorld
|
|||
std::string mTitle;
|
||||
int mFlags;
|
||||
|
||||
Column (const std::string& title, int flags = Flag_Table | Flag_Dialogue)
|
||||
: ColumnBase (title, flags) {}
|
||||
Column (const std::string& title, Display displayType, int flags = Flag_Table | Flag_Dialogue)
|
||||
: ColumnBase (title, displayType, flags) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const = 0;
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace CSMWorld
|
|||
template<typename ESXRecordT>
|
||||
struct FloatValueColumn : public Column<ESXRecordT>
|
||||
{
|
||||
FloatValueColumn() : Column<ESXRecordT> ("Value") {}
|
||||
FloatValueColumn() : Column<ESXRecordT> ("Value", ColumnBase::Display_Float) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ namespace CSMWorld
|
|||
template<typename ESXRecordT>
|
||||
struct StringIdColumn : public Column<ESXRecordT>
|
||||
{
|
||||
StringIdColumn() : Column<ESXRecordT> ("ID") {}
|
||||
StringIdColumn() : Column<ESXRecordT> ("ID", ColumnBase::Display_String) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
|
@ -47,7 +47,7 @@ namespace CSMWorld
|
|||
template<typename ESXRecordT>
|
||||
struct RecordStateColumn : public Column<ESXRecordT>
|
||||
{
|
||||
RecordStateColumn() : Column<ESXRecordT> ("*") {}
|
||||
RecordStateColumn() : Column<ESXRecordT> ("*", ColumnBase::Display_Integer) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
|
@ -78,7 +78,8 @@ namespace CSMWorld
|
|||
{
|
||||
int mType;
|
||||
|
||||
FixedRecordTypeColumn (int type) : Column<ESXRecordT> ("Type", 0), mType (type) {}
|
||||
FixedRecordTypeColumn (int type)
|
||||
: Column<ESXRecordT> ("Type", ColumnBase::Display_Integer, 0), mType (type) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
|
|
|
@ -51,6 +51,9 @@ QVariant CSMWorld::IdTable::headerData (int section, Qt::Orientation orientation
|
|||
if (role==ColumnBase::Role_Flags)
|
||||
return mIdCollection->getColumn (section).mFlags;
|
||||
|
||||
if (role==ColumnBase::Role_Display)
|
||||
return mIdCollection->getColumn (section).mDisplayType;
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,13 @@
|
|||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QAbstractTableModel>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QSpinBox>
|
||||
#include <QLineEdit>
|
||||
#include <QDataWidgetMapper>
|
||||
|
||||
#include "../../model/world/columnbase.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
|
||||
CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
|
||||
bool createAndDelete)
|
||||
|
@ -23,6 +28,9 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM
|
|||
|
||||
int columns = model->columnCount();
|
||||
|
||||
mWidgetMapper = new QDataWidgetMapper (this);
|
||||
mWidgetMapper->setModel (model);
|
||||
|
||||
for (int i=0; i<columns; ++i)
|
||||
{
|
||||
int flags = model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt();
|
||||
|
@ -30,8 +38,54 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM
|
|||
if (flags & CSMWorld::ColumnBase::Flag_Dialogue)
|
||||
{
|
||||
layout->addWidget (new QLabel (model->headerData (i, Qt::Horizontal).toString()), i, 0);
|
||||
|
||||
CSMWorld::ColumnBase::Display display = static_cast<CSMWorld::ColumnBase::Display>
|
||||
(model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
|
||||
|
||||
QWidget *widget = 0;
|
||||
|
||||
if (model->flags (model->index (0, i)) & Qt::ItemIsEditable)
|
||||
{
|
||||
switch (display)
|
||||
{
|
||||
case CSMWorld::ColumnBase::Display_String:
|
||||
|
||||
layout->addWidget (widget = new QLineEdit, i, 1);
|
||||
break;
|
||||
|
||||
case CSMWorld::ColumnBase::Display_Integer:
|
||||
|
||||
/// \todo configure widget properly (range)
|
||||
layout->addWidget (widget = new QSpinBox, i, 1);
|
||||
break;
|
||||
|
||||
case CSMWorld::ColumnBase::Display_Float:
|
||||
|
||||
/// \todo configure widget properly (range, format?)
|
||||
layout->addWidget (widget = new QDoubleSpinBox, i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (display)
|
||||
{
|
||||
case CSMWorld::ColumnBase::Display_String:
|
||||
case CSMWorld::ColumnBase::Display_Integer:
|
||||
case CSMWorld::ColumnBase::Display_Float:
|
||||
|
||||
layout->addWidget (widget = new QLabel, i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (widget)
|
||||
mWidgetMapper->addMapping (widget, i);
|
||||
}
|
||||
}
|
||||
|
||||
mWidgetMapper->setCurrentModelIndex (
|
||||
dynamic_cast<CSMWorld::IdTable&> (*model).getModelIndex (id.getId(), 0));
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::setEditLock (bool locked)
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include "../doc/subview.hpp"
|
||||
|
||||
class QDataWidgetMapper;
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Document;
|
||||
|
@ -12,6 +14,7 @@ namespace CSVWorld
|
|||
{
|
||||
class DialogueSubView : public CSVDoc::SubView
|
||||
{
|
||||
QDataWidgetMapper *mWidgetMapper;
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -21,5 +21,6 @@ void CSVWorld::TableSubView::setEditLock (bool locked)
|
|||
|
||||
void CSVWorld::TableSubView::rowActivated (const QModelIndex& index)
|
||||
{
|
||||
focusId (mTable->getUniversalId (index.row()));
|
||||
/// \todo re-enable, after dialogue sub views have been fixed up
|
||||
// focusId (mTable->getUniversalId (index.row()));
|
||||
}
|
|
@ -46,6 +46,7 @@ namespace MWWorld
|
|||
class LocalScripts;
|
||||
class TimeStamp;
|
||||
class ESMStore;
|
||||
class RefData;
|
||||
}
|
||||
|
||||
namespace MWBase
|
||||
|
@ -139,6 +140,9 @@ namespace MWBase
|
|||
|
||||
virtual std::string getCurrentCellName() const = 0;
|
||||
|
||||
virtual void removeRefScript (MWWorld::RefData *ref) = 0;
|
||||
//< Remove the script attached to ref from mLocalScripts
|
||||
|
||||
virtual MWWorld::Ptr getPtr (const std::string& name, bool activeOnly) = 0;
|
||||
///< Return a pointer to a liveCellRef with the given name.
|
||||
/// \param activeOnly do non search inactive cells.
|
||||
|
|
|
@ -100,14 +100,15 @@ namespace MWClass
|
|||
}
|
||||
else
|
||||
{
|
||||
/// \todo do something with mNpdt12 maybe:p
|
||||
for (int i=0; i<8; ++i)
|
||||
data->mCreatureStats.getAttribute (i).set (10);
|
||||
|
||||
for (int i=0; i<3; ++i)
|
||||
data->mCreatureStats.setDynamic (i, 10);
|
||||
|
||||
data->mCreatureStats.setLevel (1);
|
||||
data->mCreatureStats.setLevel(ref->mBase->mNpdt12.mLevel);
|
||||
data->mNpcStats.setBaseDisposition(ref->mBase->mNpdt12.mDisposition);
|
||||
data->mNpcStats.setReputation(ref->mBase->mNpdt12.mReputation);
|
||||
}
|
||||
|
||||
data->mCreatureStats.setAiSetting (0, ref->mBase->mAiData.mHello);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/journal.hpp"
|
||||
#include "../mwbase/scriptmanager.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
|
@ -138,7 +139,8 @@ namespace MWDialogue
|
|||
{
|
||||
if(it->mType == ESM::Dialogue::Greeting)
|
||||
{
|
||||
if (const ESM::DialInfo *info = filter.search (*it))
|
||||
// Search a response (we do not accept a fallback to "Info refusal" here)
|
||||
if (const ESM::DialInfo *info = filter.search (*it, false))
|
||||
{
|
||||
//initialise the GUI
|
||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Dialogue);
|
||||
|
@ -247,12 +249,12 @@ namespace MWDialogue
|
|||
|
||||
const ESM::Dialogue& dialogue = *dialogues.find (topic);
|
||||
|
||||
if (const ESM::DialInfo *info = filter.search (dialogue))
|
||||
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
|
||||
|
||||
if (const ESM::DialInfo *info = filter.search (dialogue, true))
|
||||
{
|
||||
parseText (info->mResponse);
|
||||
|
||||
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
|
||||
|
||||
if (dialogue.mType==ESM::Dialogue::Persuasion)
|
||||
{
|
||||
std::string modifiedTopic = "s" + topic;
|
||||
|
@ -269,12 +271,20 @@ namespace MWDialogue
|
|||
|
||||
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
|
||||
win->addText (Interpreter::fixDefinesDialog(info->mResponse, interpreterContext));
|
||||
MWBase::Environment::get().getJournal()->addTopic (topic, info->mId);
|
||||
|
||||
executeScript (info->mResultScript);
|
||||
|
||||
mLastTopic = topic;
|
||||
mLastDialogue = *info;
|
||||
}
|
||||
else
|
||||
{
|
||||
// no response found, print a fallback text
|
||||
win->addTitle (topic);
|
||||
win->addText ("…");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void DialogueManager::updateTopics()
|
||||
|
@ -293,7 +303,7 @@ namespace MWDialogue
|
|||
{
|
||||
if (iter->mType == ESM::Dialogue::Topic)
|
||||
{
|
||||
if (filter.search (*iter))
|
||||
if (filter.responseAvailable (*iter))
|
||||
{
|
||||
std::string lower = Misc::StringUtils::lowerCase(iter->mId);
|
||||
mActorKnownTopics.push_back (lower);
|
||||
|
@ -410,7 +420,7 @@ namespace MWDialogue
|
|||
{
|
||||
Filter filter (mActor, mChoice, mTalkedTo);
|
||||
|
||||
if (const ESM::DialInfo *info = filter.search (mDialogueMap[mLastTopic]))
|
||||
if (const ESM::DialInfo *info = filter.search (mDialogueMap[mLastTopic], true))
|
||||
{
|
||||
mChoiceMap.clear();
|
||||
mChoice = -1;
|
||||
|
@ -420,6 +430,7 @@ namespace MWDialogue
|
|||
|
||||
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
|
||||
MWBase::Environment::get().getWindowManager()->getDialogueWindow()->addText (Interpreter::fixDefinesDialog(text, interpreterContext));
|
||||
MWBase::Environment::get().getJournal()->addTopic (mLastTopic, info->mId);
|
||||
executeScript (info->mResultScript);
|
||||
mLastTopic = mLastTopic;
|
||||
mLastDialogue = *info;
|
||||
|
|
|
@ -121,6 +121,18 @@ bool MWDialogue::Filter::testSelectStructs (const ESM::DialInfo& info) const
|
|||
return true;
|
||||
}
|
||||
|
||||
bool MWDialogue::Filter::testDisposition (const ESM::DialInfo& info) const
|
||||
{
|
||||
bool isCreature = (mActor.getTypeName() != typeid (ESM::NPC).name());
|
||||
|
||||
if (isCreature)
|
||||
return true;
|
||||
|
||||
int actorDisposition = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor);
|
||||
|
||||
return actorDisposition >= info.mData.mDisposition;
|
||||
}
|
||||
|
||||
bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const
|
||||
{
|
||||
if (select.isNpcOnly() && mActor.getTypeName()!=typeid (ESM::NPC).name())
|
||||
|
@ -162,7 +174,7 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c
|
|||
int i = 0;
|
||||
|
||||
for (; i<static_cast<int> (script->mVarNames.size()); ++i)
|
||||
if (script->mVarNames[i]==name)
|
||||
if (Misc::StringUtils::lowerCase(script->mVarNames[i]) == name)
|
||||
break;
|
||||
|
||||
if (i>=static_cast<int> (script->mVarNames.size()))
|
||||
|
@ -547,18 +559,50 @@ MWDialogue::Filter::Filter (const MWWorld::Ptr& actor, int choice, bool talkedTo
|
|||
: mActor (actor), mChoice (choice), mTalkedToPlayer (talkedToPlayer)
|
||||
{}
|
||||
|
||||
bool MWDialogue::Filter::operator() (const ESM::DialInfo& info) const
|
||||
const ESM::DialInfo *MWDialogue::Filter::search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const
|
||||
{
|
||||
return testActor (info) && testPlayer (info) && testSelectStructs (info);
|
||||
}
|
||||
bool infoRefusal = false;
|
||||
|
||||
const ESM::DialInfo *MWDialogue::Filter::search (const ESM::Dialogue& dialogue) const
|
||||
{
|
||||
// Iterate over topic responses to find a matching one
|
||||
for (std::vector<ESM::DialInfo>::const_iterator iter = dialogue.mInfo.begin();
|
||||
iter!=dialogue.mInfo.end(); ++iter)
|
||||
if ((*this) (*iter))
|
||||
return &*iter;
|
||||
{
|
||||
if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter))
|
||||
{
|
||||
if (testDisposition (*iter))
|
||||
return &*iter;
|
||||
else
|
||||
infoRefusal = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (infoRefusal && fallbackToInfoRefusal)
|
||||
{
|
||||
// No response is valid because of low NPC disposition,
|
||||
// search a response in the topic "Info Refusal"
|
||||
|
||||
const MWWorld::Store<ESM::Dialogue> &dialogues =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
|
||||
|
||||
const ESM::Dialogue& infoRefusalDialogue = *dialogues.find ("Info Refusal");
|
||||
|
||||
for (std::vector<ESM::DialInfo>::const_iterator iter = infoRefusalDialogue.mInfo.begin();
|
||||
iter!=infoRefusalDialogue.mInfo.end(); ++iter)
|
||||
if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter) && testDisposition(*iter))
|
||||
return &*iter;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool MWDialogue::Filter::responseAvailable (const ESM::Dialogue& dialogue) const
|
||||
{
|
||||
for (std::vector<ESM::DialInfo>::const_iterator iter = dialogue.mInfo.begin();
|
||||
iter!=dialogue.mInfo.end(); ++iter)
|
||||
{
|
||||
if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -18,40 +18,45 @@ namespace MWDialogue
|
|||
MWWorld::Ptr mActor;
|
||||
int mChoice;
|
||||
bool mTalkedToPlayer;
|
||||
|
||||
|
||||
bool testActor (const ESM::DialInfo& info) const;
|
||||
///< Is this the right actor for this \a info?
|
||||
|
||||
|
||||
bool testPlayer (const ESM::DialInfo& info) const;
|
||||
///< Do the player and the cell the player is currently in match \a info?
|
||||
|
||||
|
||||
bool testSelectStructs (const ESM::DialInfo& info) const;
|
||||
///< Are all select structs matching?
|
||||
|
||||
|
||||
bool testDisposition (const ESM::DialInfo& info) const;
|
||||
///< Is the actor disposition toward the player high enough?
|
||||
|
||||
bool testSelectStruct (const SelectWrapper& select) const;
|
||||
|
||||
|
||||
bool testSelectStructNumeric (const SelectWrapper& select) const;
|
||||
|
||||
|
||||
int getSelectStructInteger (const SelectWrapper& select) const;
|
||||
|
||||
|
||||
bool getSelectStructBoolean (const SelectWrapper& select) const;
|
||||
|
||||
|
||||
int getFactionRank (const MWWorld::Ptr& actor, const std::string& factionId) const;
|
||||
|
||||
|
||||
bool hasFactionRankSkillRequirements (const MWWorld::Ptr& actor, const std::string& factionId,
|
||||
int rank) const;
|
||||
|
||||
bool hasFactionRankReputationRequirements (const MWWorld::Ptr& actor, const std::string& factionId,
|
||||
int rank) const;
|
||||
|
||||
public:
|
||||
|
||||
Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer);
|
||||
|
||||
bool operator() (const ESM::DialInfo& info) const;
|
||||
///< \return does the dialogue match?
|
||||
|
||||
const ESM::DialInfo *search (const ESM::Dialogue& dialogue) const;
|
||||
public:
|
||||
|
||||
Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer);
|
||||
|
||||
const ESM::DialInfo *search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const;
|
||||
///< Get a matching response for the requested dialogue.
|
||||
/// Redirect to "Info Refusal" topic if a response fulfills all conditions but disposition.
|
||||
|
||||
bool responseAvailable (const ESM::Dialogue& dialogue) const;
|
||||
///< Does a matching response exist? (disposition is ignored for this check)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -61,8 +61,8 @@ namespace MWDialogue
|
|||
StampedJournalEntry StampedJournalEntry::makeFromQuest (const std::string& topic, int index)
|
||||
{
|
||||
int day = MWBase::Environment::get().getWorld()->getGlobalVariable ("dayspassed").mLong;
|
||||
int month = MWBase::Environment::get().getWorld()->getGlobalVariable ("day").mLong;
|
||||
int dayOfMonth = MWBase::Environment::get().getWorld()->getGlobalVariable ("month").mLong;
|
||||
int month = MWBase::Environment::get().getWorld()->getGlobalVariable ("month").mLong;
|
||||
int dayOfMonth = MWBase::Environment::get().getWorld()->getGlobalVariable ("day").mLong;
|
||||
|
||||
return StampedJournalEntry (topic, idFromIndex (topic, index), day, month, dayOfMonth);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,12 @@ namespace MWDialogue
|
|||
|
||||
void Journal::addEntry (const std::string& id, int index)
|
||||
{
|
||||
// bail out of we already have heard this...
|
||||
std::string infoId = JournalEntry::idFromIndex (id, index);
|
||||
for (TEntryIter i = mJournal.begin (); i != mJournal.end (); ++i)
|
||||
if (i->mTopic == id && i->mInfoId == infoId)
|
||||
return;
|
||||
|
||||
StampedJournalEntry entry = StampedJournalEntry::makeFromQuest (id, index);
|
||||
|
||||
mJournal.push_back (entry);
|
||||
|
|
|
@ -27,17 +27,17 @@ namespace MWDialogue
|
|||
mEntries.push_back (entry.mInfoId);
|
||||
}
|
||||
|
||||
Topic::TEntryIter Topic::begin()
|
||||
Topic::TEntryIter Topic::begin() const
|
||||
{
|
||||
return mEntries.begin();
|
||||
}
|
||||
|
||||
Topic::TEntryIter Topic::end()
|
||||
Topic::TEntryIter Topic::end() const
|
||||
{
|
||||
return mEntries.end();
|
||||
}
|
||||
|
||||
JournalEntry Topic::getEntry (const std::string& infoId)
|
||||
JournalEntry Topic::getEntry (const std::string& infoId) const
|
||||
{
|
||||
return JournalEntry (mTopic, infoId);
|
||||
}
|
||||
|
|
|
@ -34,13 +34,15 @@ namespace MWDialogue
|
|||
///
|
||||
/// \note Redundant entries are ignored.
|
||||
|
||||
TEntryIter begin();
|
||||
std::string const & getName () const { return mTopic; }
|
||||
|
||||
TEntryIter begin() const;
|
||||
///< Iterator pointing to the begin of the journal for this topic.
|
||||
|
||||
TEntryIter end();
|
||||
TEntryIter end() const;
|
||||
///< Iterator pointing past the end of the journal for this topic.
|
||||
|
||||
JournalEntry getEntry (const std::string& infoId);
|
||||
JournalEntry getEntry (const std::string& infoId) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include "manualref.hpp"
|
||||
#include "refdata.hpp"
|
||||
#include "class.hpp"
|
||||
#include "localscripts.hpp"
|
||||
#include "player.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -71,6 +73,31 @@ bool MWWorld::ContainerStore::stacks(const Ptr& ptr1, const Ptr& ptr2)
|
|||
}
|
||||
|
||||
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& ptr)
|
||||
{
|
||||
MWWorld::ContainerStoreIterator it = addImp(ptr);
|
||||
MWWorld::Ptr item = *it;
|
||||
|
||||
std::string script = MWWorld::Class::get(item).getScript(item);
|
||||
if(script != "")
|
||||
{
|
||||
CellStore *cell;
|
||||
|
||||
Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer();
|
||||
// Items in players inventory have cell set to 0, so their scripts will never be removed
|
||||
if(&(MWWorld::Class::get (player).getContainerStore (player)) == this)
|
||||
cell = 0;
|
||||
else
|
||||
cell = player.getCell();
|
||||
|
||||
item.mCell = cell;
|
||||
item.mContainerStore = 0;
|
||||
MWBase::Environment::get().getWorld()->getLocalScripts().add(script, item);
|
||||
}
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr)
|
||||
{
|
||||
int type = getType(ptr);
|
||||
|
||||
|
@ -162,7 +189,7 @@ void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const MWWor
|
|||
}
|
||||
|
||||
ref.getPtr().getRefData().setCount (std::abs(iter->mCount)); /// \todo implement item restocking (indicated by negative count)
|
||||
add (ref.getPtr());
|
||||
addImp (ref.getPtr());
|
||||
}
|
||||
|
||||
flagAsModified();
|
||||
|
|
|
@ -52,6 +52,7 @@ namespace MWWorld
|
|||
int mStateId;
|
||||
mutable float mCachedWeight;
|
||||
mutable bool mWeightUpToDate;
|
||||
ContainerStoreIterator addImp (const Ptr& ptr);
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
#include "esmstore.hpp"
|
||||
#include "cellstore.hpp"
|
||||
|
||||
#include "class.hpp"
|
||||
#include "containerstore.hpp"
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
template<typename T>
|
||||
|
@ -19,6 +23,32 @@ namespace
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adds scripts for items in containers (containers/npcs/creatures)
|
||||
template<typename T>
|
||||
void listCellScriptsCont (MWWorld::LocalScripts& localScripts,
|
||||
MWWorld::CellRefList<T>& cellRefList, MWWorld::Ptr::CellStore *cell)
|
||||
{
|
||||
for (typename MWWorld::CellRefList<T>::List::iterator iter (
|
||||
cellRefList.mList.begin());
|
||||
iter!=cellRefList.mList.end(); ++iter)
|
||||
{
|
||||
|
||||
MWWorld::Ptr containerPtr (&*iter, cell);
|
||||
|
||||
MWWorld::ContainerStore& container = MWWorld::Class::get(containerPtr).getContainerStore(containerPtr);
|
||||
for(MWWorld::ContainerStoreIterator it3 = container.begin(); it3 != container.end(); ++it3)
|
||||
{
|
||||
std::string script = MWWorld::Class::get(*it3).getScript(*it3);
|
||||
if(script != "")
|
||||
{
|
||||
MWWorld::Ptr item = *it3;
|
||||
item.mCell = cell;
|
||||
localScripts.add (script, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MWWorld::LocalScripts::LocalScripts (const MWWorld::ESMStore& store) : mStore (store) {}
|
||||
|
@ -78,13 +108,16 @@ void MWWorld::LocalScripts::addCell (Ptr::CellStore *cell)
|
|||
listCellScripts (*this, cell->mBooks, cell);
|
||||
listCellScripts (*this, cell->mClothes, cell);
|
||||
listCellScripts (*this, cell->mContainers, cell);
|
||||
listCellScriptsCont (*this, cell->mContainers, cell);
|
||||
listCellScripts (*this, cell->mCreatures, cell);
|
||||
listCellScriptsCont (*this, cell->mCreatures, cell);
|
||||
listCellScripts (*this, cell->mDoors, cell);
|
||||
listCellScripts (*this, cell->mIngreds, cell);
|
||||
listCellScripts (*this, cell->mLights, cell);
|
||||
listCellScripts (*this, cell->mLockpicks, cell);
|
||||
listCellScripts (*this, cell->mMiscItems, cell);
|
||||
listCellScripts (*this, cell->mNpcs, cell);
|
||||
listCellScriptsCont (*this, cell->mNpcs, cell);
|
||||
listCellScripts (*this, cell->mProbes, cell);
|
||||
listCellScripts (*this, cell->mRepairs, cell);
|
||||
listCellScripts (*this, cell->mWeapons, cell);
|
||||
|
@ -101,7 +134,7 @@ void MWWorld::LocalScripts::clearCell (Ptr::CellStore *cell)
|
|||
|
||||
while (iter!=mScripts.end())
|
||||
{
|
||||
if (iter->second.getCell()==cell)
|
||||
if (iter->second.mCell==cell)
|
||||
{
|
||||
if (iter==mIter)
|
||||
++mIter;
|
||||
|
@ -113,6 +146,20 @@ void MWWorld::LocalScripts::clearCell (Ptr::CellStore *cell)
|
|||
}
|
||||
}
|
||||
|
||||
void MWWorld::LocalScripts::remove (RefData *ref)
|
||||
{
|
||||
for (std::list<std::pair<std::string, Ptr> >::iterator iter = mScripts.begin();
|
||||
iter!=mScripts.end(); ++iter)
|
||||
if (&(iter->second.getRefData()) == ref)
|
||||
{
|
||||
if (iter==mIter)
|
||||
++mIter;
|
||||
|
||||
mScripts.erase (iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MWWorld::LocalScripts::remove (const Ptr& ptr)
|
||||
{
|
||||
for (std::list<std::pair<std::string, Ptr> >::iterator iter = mScripts.begin();
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace MWWorld
|
|||
{
|
||||
struct ESMStore;
|
||||
class CellStore;
|
||||
class RefData;
|
||||
|
||||
/// \brief List of active local scripts
|
||||
class LocalScripts
|
||||
|
@ -47,6 +48,8 @@ namespace MWWorld
|
|||
|
||||
void clearCell (CellStore *cell);
|
||||
///< Remove all scripts belonging to \a cell.
|
||||
|
||||
void remove (RefData *ref);
|
||||
|
||||
void remove (const Ptr& ptr);
|
||||
///< Remove script for given reference (ignored if reference does not have a scirpt listed).
|
||||
|
|
|
@ -74,7 +74,7 @@ namespace MWWorld
|
|||
|
||||
bool isInCell() const
|
||||
{
|
||||
return (mCell != 0);
|
||||
return (mContainerStore == 0);
|
||||
}
|
||||
|
||||
void setContainerStore (ContainerStore *store);
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
#include "customdata.hpp"
|
||||
#include "cellstore.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
void RefData::copy (const RefData& refData)
|
||||
|
@ -107,6 +110,9 @@ namespace MWWorld
|
|||
|
||||
void RefData::setCount (int count)
|
||||
{
|
||||
if(count == 0)
|
||||
MWBase::Environment::get().getWorld()->removeRefScript(this);
|
||||
|
||||
mCount = count;
|
||||
}
|
||||
|
||||
|
|
|
@ -341,6 +341,11 @@ namespace MWWorld
|
|||
return name;
|
||||
}
|
||||
|
||||
void World::removeRefScript (MWWorld::RefData *ref)
|
||||
{
|
||||
mLocalScripts.remove (ref);
|
||||
}
|
||||
|
||||
Ptr World::getPtr (const std::string& name, bool activeOnly)
|
||||
{
|
||||
// the player is always in an active cell.
|
||||
|
@ -396,23 +401,62 @@ namespace MWWorld
|
|||
return MWWorld::Ptr();
|
||||
}
|
||||
|
||||
void World::addContainerScripts(const Ptr& reference, Ptr::CellStore * cell)
|
||||
{
|
||||
if( reference.getTypeName()==typeid (ESM::Container).name() ||
|
||||
reference.getTypeName()==typeid (ESM::NPC).name() ||
|
||||
reference.getTypeName()==typeid (ESM::Creature).name())
|
||||
{
|
||||
MWWorld::ContainerStore& container = MWWorld::Class::get(reference).getContainerStore(reference);
|
||||
for(MWWorld::ContainerStoreIterator it = container.begin(); it != container.end(); ++it)
|
||||
{
|
||||
std::string script = MWWorld::Class::get(*it).getScript(*it);
|
||||
if(script != "")
|
||||
{
|
||||
MWWorld::Ptr item = *it;
|
||||
item.mCell = cell;
|
||||
mLocalScripts.add (script, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void World::enable (const Ptr& reference)
|
||||
{
|
||||
if (!reference.getRefData().isEnabled())
|
||||
{
|
||||
reference.getRefData().enable();
|
||||
|
||||
|
||||
if(mWorldScene->getActiveCells().find (reference.getCell()) != mWorldScene->getActiveCells().end() && reference.getRefData().getCount())
|
||||
mWorldScene->addObjectToScene (reference);
|
||||
}
|
||||
}
|
||||
|
||||
void World::removeContainerScripts(const Ptr& reference)
|
||||
{
|
||||
if( reference.getTypeName()==typeid (ESM::Container).name() ||
|
||||
reference.getTypeName()==typeid (ESM::NPC).name() ||
|
||||
reference.getTypeName()==typeid (ESM::Creature).name())
|
||||
{
|
||||
MWWorld::ContainerStore& container = MWWorld::Class::get(reference).getContainerStore(reference);
|
||||
for(MWWorld::ContainerStoreIterator it = container.begin(); it != container.end(); ++it)
|
||||
{
|
||||
std::string script = MWWorld::Class::get(*it).getScript(*it);
|
||||
if(script != "")
|
||||
{
|
||||
MWWorld::Ptr item = *it;
|
||||
mLocalScripts.remove (item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void World::disable (const Ptr& reference)
|
||||
{
|
||||
if (reference.getRefData().isEnabled())
|
||||
{
|
||||
reference.getRefData().disable();
|
||||
|
||||
|
||||
if(mWorldScene->getActiveCells().find (reference.getCell())!=mWorldScene->getActiveCells().end() && reference.getRefData().getCount())
|
||||
mWorldScene->removeObjectFromScene (reference);
|
||||
}
|
||||
|
@ -635,6 +679,7 @@ namespace MWWorld
|
|||
{
|
||||
mWorldScene->removeObjectFromScene (ptr);
|
||||
mLocalScripts.remove (ptr);
|
||||
removeContainerScripts (ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -648,6 +693,8 @@ namespace MWWorld
|
|||
CellStore *currCell = ptr.getCell();
|
||||
bool isPlayer = ptr == mPlayer->getPlayer();
|
||||
bool haveToMove = mWorldScene->isCellActive(*currCell) || isPlayer;
|
||||
|
||||
removeContainerScripts(ptr);
|
||||
|
||||
if (*currCell != newCell)
|
||||
{
|
||||
|
@ -675,6 +722,8 @@ namespace MWWorld
|
|||
MWWorld::Ptr copy =
|
||||
MWWorld::Class::get(ptr).copyToCell(ptr, newCell);
|
||||
|
||||
addContainerScripts(copy, &newCell);
|
||||
|
||||
mRendering->moveObjectToCell(copy, vec, currCell);
|
||||
|
||||
if (MWWorld::Class::get(ptr).isActor())
|
||||
|
@ -1272,6 +1321,7 @@ namespace MWWorld
|
|||
if (!script.empty()) {
|
||||
mLocalScripts.add(script, dropped);
|
||||
}
|
||||
addContainerScripts(dropped, &cell);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -106,6 +106,9 @@ namespace MWWorld
|
|||
float getNpcActivationDistance ();
|
||||
float getObjectActivationDistance ();
|
||||
|
||||
void removeContainerScripts(const Ptr& reference);
|
||||
void addContainerScripts(const Ptr& reference, Ptr::CellStore* cell);
|
||||
|
||||
public:
|
||||
|
||||
World (OEngine::Render::OgreRenderer& renderer,
|
||||
|
@ -173,6 +176,9 @@ namespace MWWorld
|
|||
virtual std::vector<std::string> getGlobals () const;
|
||||
|
||||
virtual std::string getCurrentCellName () const;
|
||||
|
||||
virtual void removeRefScript (MWWorld::RefData *ref);
|
||||
//< Remove the script attached to ref from mLocalScripts
|
||||
|
||||
virtual Ptr getPtr (const std::string& name, bool activeOnly);
|
||||
///< Return a pointer to a liveCellRef with the given name.
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<Code range="33 126"/>
|
||||
<Code range="192 382"/> <!-- Central and Eastern European languages glyphs -->
|
||||
<Code range="1025 1105"/>
|
||||
<Code range="2026"/> <!-- Ellipsis -->
|
||||
<Code range="8470"/>
|
||||
<Code range="8211"/> <!-- Minus -->
|
||||
<Code range="8216 8217"/> <!-- Single quotes -->
|
||||
|
|
Loading…
Reference in a new issue