From eef9df504a4f3c9a6254421ec5f2363861d40dc6 Mon Sep 17 00:00:00 2001 From: mckibbenta Date: Thu, 29 Aug 2013 20:25:36 -0400 Subject: [PATCH 01/13] fiddlings --- apps/openmw/mwmechanics/actors.cpp | 2 +- apps/openmw/mwscript/miscextensions.cpp | 3 +-- apps/openmw/mwworld/worldimp.cpp | 9 +++++++-- apps/openmw/mwworld/worldimp.hpp | 2 ++ 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index b8d0a8745..a6db0a909 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -272,7 +272,7 @@ namespace MWMechanics // workaround: always keep player alive for now // \todo remove workaround, once player death can be handled - if(iter->first.getRefData().getHandle()=="player") + if(iter->first.getRefData().getHandle()=="player" && false) { MWMechanics::DynamicStat stat(stats.getHealth()); diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index c53cafa17..a8d8a5f2b 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -726,8 +726,7 @@ namespace MWScript bool enabled = MWBase::Environment::get().getWorld()->toggleGodMode(); - // context.report (enabled ? "God Mode -> On" : "God Mode -> Off"); - context.report("Unimplemented"); + context.report (enabled ? "God Mode -> On" : "God Mode -> Off"); } }; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 5c08af612..a6489fc30 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -170,7 +170,7 @@ namespace MWWorld mSky (true), mCells (mStore, mEsm), mActivationDistanceOverride (mActivationDistanceOverride), mFallback(fallbackMap), mPlayIntro(0), mTeleportEnabled(true), - mFacedDistance(FLT_MAX) + mFacedDistance(FLT_MAX), mGodMode(false) { mPhysics = new PhysicsSystem(renderer); mPhysEngine = mPhysics->getEngine(); @@ -1945,7 +1945,12 @@ namespace MWWorld bool World::toggleGodMode() { - return false; + if (mGodMode) + mGodMode = false; + else + mGodMode = true; + + return mGodMode; } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 30ffcda40..5e6fe50f9 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -68,6 +68,8 @@ namespace MWWorld OEngine::Physic::PhysicEngine* mPhysEngine; + bool mGodMode; + // not implemented World (const World&); World& operator= (const World&); From 89b7d6121d35ca400fc490326adbf278922a1dfe Mon Sep 17 00:00:00 2001 From: mckibbenta Date: Thu, 12 Sep 2013 08:30:00 -0400 Subject: [PATCH 02/13] Initial toggleGodMod/tgm instruction. Currently only affects player health. --- apps/openmw/mwbase/world.hpp | 2 ++ apps/openmw/mwmechanics/actors.cpp | 4 +--- apps/openmw/mwworld/worldimp.cpp | 10 ++++++---- apps/openmw/mwworld/worldimp.hpp | 2 ++ 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 6101358de..f8453afed 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -396,6 +396,8 @@ namespace MWBase /// It only applies to the current form the NPC is in. virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor) = 0; + virtual bool getGodModeState() = 0; + virtual bool toggleGodMode() = 0; }; } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index f5caff359..1e41eb740 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -275,9 +275,7 @@ namespace MWMechanics continue; } - // workaround: always keep player alive for now - // \todo remove workaround, once player death can be handled - if(iter->first.getRefData().getHandle()=="player" && false) + if(iter->first.getRefData().getHandle()=="player" && MWBase::Environment::get().getWorld()->getGodModeState()) { MWMechanics::DynamicStat stat(stats.getHealth()); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 2b4b5d225..d262747b9 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1948,12 +1948,14 @@ namespace MWWorld stats.getSkill(ESM::Skill::Acrobatics).setModified(gmst.find("fWerewolfAcrobatics")->getFloat(), 0); } + bool World::getGodModeState() + { + return mGodMode; + } + bool World::toggleGodMode() { - if (mGodMode) - mGodMode = false; - else - mGodMode = true; + mGodMode ? mGodMode = false : mGodMode = true; return mGodMode; } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 5e6fe50f9..53b01f1ab 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -442,6 +442,8 @@ namespace MWWorld virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor); + virtual bool getGodModeState(); + virtual bool toggleGodMode(); }; } From 644f081c604c91e98e0a81d38c3566c1aca04d76 Mon Sep 17 00:00:00 2001 From: mckibbenta Date: Sun, 15 Sep 2013 15:48:32 -0400 Subject: [PATCH 03/13] minor changes --- apps/openmw/mwworld/worldimp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index d262747b9..f3d4c81b7 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1955,7 +1955,7 @@ namespace MWWorld bool World::toggleGodMode() { - mGodMode ? mGodMode = false : mGodMode = true; + mGodMode = !mGodMode; return mGodMode; } From 6bb6ba6372dc3749bd2aee9f2df74e118d199deb Mon Sep 17 00:00:00 2001 From: mckibbenta Date: Sun, 15 Sep 2013 16:12:59 -0400 Subject: [PATCH 04/13] added god mode comment --- apps/openmw/mwmechanics/actors.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 1e41eb740..ca26e88ce 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -275,6 +275,7 @@ namespace MWMechanics continue; } + // If it's the player and God Mode is turned on, keep it alive if(iter->first.getRefData().getHandle()=="player" && MWBase::Environment::get().getWorld()->getGodModeState()) { MWMechanics::DynamicStat stat(stats.getHealth()); From 78f7f80fc3d7ed744a4c7ec07d78325550041a16 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 19 Sep 2013 08:58:27 +0200 Subject: [PATCH 05/13] configured script highlighting with extensions --- apps/opencs/view/world/scripthighlighter.cpp | 5 +++++ apps/opencs/view/world/scripthighlighter.hpp | 2 ++ 2 files changed, 7 insertions(+) diff --git a/apps/opencs/view/world/scripthighlighter.cpp b/apps/opencs/view/world/scripthighlighter.cpp index 288a3d12a..f06d5542e 100644 --- a/apps/opencs/view/world/scripthighlighter.cpp +++ b/apps/opencs/view/world/scripthighlighter.cpp @@ -4,6 +4,7 @@ #include #include +#include bool CSVWorld::ScriptHighlighter::parseInt (int value, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner) @@ -101,6 +102,10 @@ CSVWorld::ScriptHighlighter::ScriptHighlighter (QTextDocument *parent) format.setForeground (Qt::green); mScheme.insert (std::make_pair (Type_Comment, format)); } + + // configure compiler + Compiler::registerExtensions (mExtensions); + mContext.setExtensions (&mExtensions); } void CSVWorld::ScriptHighlighter::highlightBlock (const QString& text) diff --git a/apps/opencs/view/world/scripthighlighter.hpp b/apps/opencs/view/world/scripthighlighter.hpp index 3ef697809..406935b8d 100644 --- a/apps/opencs/view/world/scripthighlighter.hpp +++ b/apps/opencs/view/world/scripthighlighter.hpp @@ -7,6 +7,7 @@ #include #include +#include #include "../../model/world/scriptcontext.hpp" @@ -29,6 +30,7 @@ namespace CSVWorld private: Compiler::NullErrorHandler mErrorHandler; + Compiler::Extensions mExtensions; CSMWorld::ScriptContext mContext; std::map mScheme; From 3d2281fe808447bfc65ea2bfee13eada450fbf02 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 19 Sep 2013 12:11:27 +0200 Subject: [PATCH 06/13] added signals and functions to Data for handling ID list changes --- apps/opencs/CMakeLists.txt | 4 +- apps/opencs/model/world/collection.hpp | 20 +++++++ apps/opencs/model/world/collectionbase.hpp | 6 +- apps/opencs/model/world/data.cpp | 62 +++++++++++++++++++-- apps/opencs/model/world/data.hpp | 29 +++++++++- apps/opencs/model/world/refidcollection.cpp | 5 ++ apps/opencs/model/world/refidcollection.hpp | 5 ++ apps/opencs/model/world/refiddata.cpp | 22 ++++++++ apps/opencs/model/world/refiddata.hpp | 5 ++ 9 files changed, 147 insertions(+), 11 deletions(-) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index aa6f6ba76..a719750c6 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -18,12 +18,12 @@ opencs_hdrs_noqt (model/doc opencs_units (model/world - idtable idtableproxymodel regionmap + idtable idtableproxymodel regionmap data ) opencs_units_noqt (model/world - universalid data record commands columnbase scriptcontext cell refidcollection + universalid record commands columnbase scriptcontext cell refidcollection refidadapter refiddata refidadapterimp ref collectionbase refcollection columns ) diff --git a/apps/opencs/model/world/collection.hpp b/apps/opencs/model/world/collection.hpp index 6cf31d0a4..a5014e66c 100644 --- a/apps/opencs/model/world/collection.hpp +++ b/apps/opencs/model/world/collection.hpp @@ -107,6 +107,11 @@ namespace CSMWorld virtual int getAppendIndex (UniversalId::Type type = UniversalId::Type_None) const; ///< \param type Will be ignored, unless the collection supports multiple record types + virtual std::vector getIds() const; + ///< Return a sorted collection of all IDs + /// + /// \note Deleted records are not listed. + void addColumn (Column *column); void setRecord (int index, const Record& record); @@ -293,6 +298,21 @@ namespace CSMWorld return static_cast (mRecords.size()); } + template + std::vector Collection::getIds() const + { + std::vector ids; + + for (typename std::map::const_iterator iter = mIndex.begin(); + iter!=mIndex.end(); ++iter) + { + if (!mRecords[iter->second].isDeleted()) + ids.push_back (IdAccessorT().getId (mRecords[iter->second].get())); + } + + return ids; + } + template const Record& Collection::getRecord (const std::string& id) const { diff --git a/apps/opencs/model/world/collectionbase.hpp b/apps/opencs/model/world/collectionbase.hpp index 1700a68ec..16b88e5e1 100644 --- a/apps/opencs/model/world/collectionbase.hpp +++ b/apps/opencs/model/world/collectionbase.hpp @@ -78,8 +78,12 @@ namespace CSMWorld virtual int getAppendIndex (UniversalId::Type type = UniversalId::Type_None) const = 0; ///< \param type Will be ignored, unless the collection supports multiple record types - }; + virtual std::vector getIds() const = 0; + ///< Return a sorted collection of all IDs + /// + /// \note Deleted records are not listed. + }; } #endif \ No newline at end of file diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index fbdbb4413..06fbf61bf 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -2,6 +2,7 @@ #include "data.hpp" #include +#include #include @@ -15,13 +16,30 @@ #include "columns.hpp" void CSMWorld::Data::addModel (QAbstractItemModel *model, UniversalId::Type type1, - UniversalId::Type type2) + UniversalId::Type type2, bool update) { mModels.push_back (model); mModelIndex.insert (std::make_pair (type1, model)); if (type2!=UniversalId::Type_None) mModelIndex.insert (std::make_pair (type2, model)); + + if (update) + { + connect (model, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), + this, SLOT (dataChanged (const QModelIndex&, const QModelIndex&))); + connect (model, SIGNAL (rowsInserted (const QModelIndex&, int, int)), + this, SLOT (rowsChanged (const QModelIndex&, int, int))); + connect (model, SIGNAL (rowsRemoved (const QModelIndex&, int, int)), + this, SLOT (rowsChanged (const QModelIndex&, int, int))); + } +} + +void CSMWorld::Data::appendIds (std::vector& ids, const CollectionBase& collection) +{ + std::vector ids2 = collection.getIds(); + + ids.insert (ids.end(), ids2.begin(), ids2.end()); } CSMWorld::Data::Data() : mRefs (mCells) @@ -155,7 +173,7 @@ CSMWorld::Data::Data() : mRefs (mCells) addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global); addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst); - addModel (new IdTable (&mSkills), UniversalId::Type_Skills, UniversalId::Type_Skill); + addModel (new IdTable (&mSkills), UniversalId::Type_Skills, UniversalId::Type_Skill, false); addModel (new IdTable (&mClasses), UniversalId::Type_Classes, UniversalId::Type_Class); addModel (new IdTable (&mFactions), UniversalId::Type_Factions, UniversalId::Type_Faction); addModel (new IdTable (&mRaces), UniversalId::Type_Races, UniversalId::Type_Race); @@ -167,8 +185,8 @@ CSMWorld::Data::Data() : mRefs (mCells) addModel (new IdTable (&mCells), UniversalId::Type_Cells, UniversalId::Type_Cell); addModel (new IdTable (&mReferenceables), UniversalId::Type_Referenceables, UniversalId::Type_Referenceable); - addModel (new IdTable (&mRefs), UniversalId::Type_References, UniversalId::Type_Reference); - addModel (new IdTable (&mFilters), UniversalId::Type_Filters, UniversalId::Type_Filter); + addModel (new IdTable (&mRefs), UniversalId::Type_References, UniversalId::Type_Reference, false); + addModel (new IdTable (&mFilters), UniversalId::Type_Filters, UniversalId::Type_Filter, false); } CSMWorld::Data::~Data() @@ -341,7 +359,7 @@ QAbstractItemModel *CSMWorld::Data::getTableModel (const UniversalId& id) { RegionMap *table = 0; addModel (table = new RegionMap (*this), UniversalId::Type_RegionMap, - UniversalId::Type_None); + UniversalId::Type_None, false); return table; } throw std::logic_error ("No table model available for " + id.toString()); @@ -440,3 +458,37 @@ bool CSMWorld::Data::hasId (const std::string& id) const getCells().searchId (id)!=-1 || getReferenceables().searchId (id)!=-1; } + +std::vector CSMWorld::Data::getIds() const +{ + std::vector ids; + + appendIds (ids, mGlobals); + appendIds (ids, mGmsts); + appendIds (ids, mClasses); + appendIds (ids, mFactions); + appendIds (ids, mRaces); + appendIds (ids, mSounds); + appendIds (ids, mScripts); + appendIds (ids, mRegions); + appendIds (ids, mBirthsigns); + appendIds (ids, mSpells); + appendIds (ids, mCells); + appendIds (ids, mReferenceables); + + std::sort (ids.begin(), ids.end()); + + return ids; +} + +void CSMWorld::Data::dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) +{ + // Note: The performance of of ID list change updates could be improved only emit the signal, if + // the state of the record is changed. + emit idListChanged(); +} + +void CSMWorld::Data::rowsChanged (const QModelIndex& parent, int start, int end) +{ + emit idListChanged(); +} \ No newline at end of file diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 2f8a2117e..1b024751d 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -6,6 +6,9 @@ #include +#include +#include + #include #include #include @@ -30,8 +33,10 @@ class QAbstractItemModel; namespace CSMWorld { - class Data + class Data : public QObject { + Q_OBJECT + IdCollection mGlobals; IdCollection mGmsts; IdCollection mSkills; @@ -55,13 +60,16 @@ namespace CSMWorld Data& operator= (const Data&); void addModel (QAbstractItemModel *model, UniversalId::Type type1, - UniversalId::Type type2 = UniversalId::Type_None); + UniversalId::Type type2 = UniversalId::Type_None, bool update = true); + + static void appendIds (std::vector& ids, const CollectionBase& collection); + ///< Append all IDs from collection to \a ids. public: Data(); - ~Data(); + virtual ~Data(); const IdCollection& getGlobals() const; @@ -136,6 +144,21 @@ namespace CSMWorld ///< Merging content of a file into base or modified. bool hasId (const std::string& id) const; + + std::vector getIds() const; + ///< Return a sorted collection of all IDs that are not internal to the editor. + /// + /// \note Deleted records are not listed. + + signals: + + void idListChanged(); + + private slots: + + void dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + + void rowsChanged (const QModelIndex& parent, int start, int end); }; } diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 343cbe302..5aadb1be3 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -534,3 +534,8 @@ int CSMWorld::RefIdCollection::getAppendIndex (UniversalId::Type type) const { return mData.getAppendIndex (type); } + +std::vector CSMWorld::RefIdCollection::getIds() const +{ + return mData.getIds(); +} diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index c10d1d2d0..b6c8efdce 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -89,6 +89,11 @@ namespace CSMWorld virtual int getAppendIndex (UniversalId::Type type) const; ///< \param type Will be ignored, unless the collection supports multiple record types + + virtual std::vector getIds() const; + ///< Return a sorted collection of all IDs + /// + /// \note Deleted records are not listed. }; } diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index c95db045f..fca0d8a71 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -196,3 +196,25 @@ int CSMWorld::RefIdData::getSize() const { return mIndex.size(); } + +std::vector CSMWorld::RefIdData::getIds() const +{ + std::vector ids; + + for (std::map::const_iterator iter (mIndex.begin()); iter!=mIndex.end(); + ++iter) + { + if (!getRecord (iter->second).isDeleted()) + { + std::map::const_iterator container = + mRecordContainers.find (iter->second.second); + + if (container==mRecordContainers.end()) + throw std::logic_error ("Invalid referenceable ID type"); + + ids.push_back (container->second->getId (iter->second.first)); + } + } + + return ids; +} diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 475566fb5..bb8c83360 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -182,6 +182,11 @@ namespace CSMWorld void load (const LocalIndex& index, ESM::ESMReader& reader, bool base); int getSize() const; + + std::vector getIds() const; + ///< Return a sorted collection of all IDs + /// + /// \note Deleted records are not listed. }; } From 9c751ae37053346af2f2ded990a956ef5bd15348 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 19 Sep 2013 12:30:42 +0200 Subject: [PATCH 07/13] separate highlight colour for IDs --- apps/opencs/model/world/scriptcontext.cpp | 24 +++++++++++++++++++- apps/opencs/model/world/scriptcontext.hpp | 13 +++++++++++ apps/opencs/view/world/scripthighlighter.cpp | 14 ++++++++---- apps/opencs/view/world/scripthighlighter.hpp | 5 ++-- apps/opencs/view/world/scriptsubview.cpp | 2 +- 5 files changed, 50 insertions(+), 8 deletions(-) diff --git a/apps/opencs/model/world/scriptcontext.cpp b/apps/opencs/model/world/scriptcontext.cpp index 69b72abf2..86689d823 100644 --- a/apps/opencs/model/world/scriptcontext.cpp +++ b/apps/opencs/model/world/scriptcontext.cpp @@ -1,6 +1,14 @@ #include "scriptcontext.hpp" +#include + +#include + +#include "data.hpp" + +CSMWorld::ScriptContext::ScriptContext (const Data& data) : mData (data), mIdsUpdated (false) {} + bool CSMWorld::ScriptContext::canDeclareLocals() const { return false; @@ -18,5 +26,19 @@ char CSMWorld::ScriptContext::getMemberType (const std::string& name, const std: bool CSMWorld::ScriptContext::isId (const std::string& name) const { - return false; + if (!mIdsUpdated) + { + mIds = mData.getIds(); + + std::for_each (mIds.begin(), mIds.end(), &Misc::StringUtils::lowerCase); + + mIdsUpdated = true; + } + + return std::binary_search (mIds.begin(), mIds.end(), Misc::StringUtils::lowerCase (name)); +} + +void CSMWorld::ScriptContext::invalidateIds() +{ + mIdsUpdated = false; } \ No newline at end of file diff --git a/apps/opencs/model/world/scriptcontext.hpp b/apps/opencs/model/world/scriptcontext.hpp index 1231aea64..b839b5a43 100644 --- a/apps/opencs/model/world/scriptcontext.hpp +++ b/apps/opencs/model/world/scriptcontext.hpp @@ -1,14 +1,25 @@ #ifndef CSM_WORLD_SCRIPTCONTEXT_H #define CSM_WORLD_SCRIPTCONTEXT_H +#include +#include + #include namespace CSMWorld { + class Data; + class ScriptContext : public Compiler::Context { + const Data& mData; + mutable std::vector mIds; + mutable bool mIdsUpdated; + public: + ScriptContext (const Data& data); + virtual bool canDeclareLocals() const; ///< Is the compiler allowed to declare local variables? @@ -20,6 +31,8 @@ namespace CSMWorld virtual bool isId (const std::string& name) const; ///< Does \a name match an ID, that can be referenced? + + void invalidateIds(); }; } diff --git a/apps/opencs/view/world/scripthighlighter.cpp b/apps/opencs/view/world/scripthighlighter.cpp index f06d5542e..a16077f8a 100644 --- a/apps/opencs/view/world/scripthighlighter.cpp +++ b/apps/opencs/view/world/scripthighlighter.cpp @@ -23,7 +23,7 @@ bool CSVWorld::ScriptHighlighter::parseFloat (float value, const Compiler::Token bool CSVWorld::ScriptHighlighter::parseName (const std::string& name, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner) { - highlight (loc, Type_Name); + highlight (loc, mContext.isId (name) ? Type_Id : Type_Name); return true; } @@ -63,10 +63,10 @@ void CSVWorld::ScriptHighlighter::highlight (const Compiler::TokenLoc& loc, Type setFormat (index, length, mScheme[type]); } -CSVWorld::ScriptHighlighter::ScriptHighlighter (QTextDocument *parent) -: QSyntaxHighlighter (parent), Compiler::Parser (mErrorHandler, mContext) +CSVWorld::ScriptHighlighter::ScriptHighlighter (const CSMWorld::Data& data, QTextDocument *parent) +: QSyntaxHighlighter (parent), Compiler::Parser (mErrorHandler, mContext), mContext (data) { - /// \ŧodo replace this with user settings + /// \todo replace this with user settings { QTextCharFormat format; format.setForeground (Qt::darkMagenta); @@ -103,6 +103,12 @@ CSVWorld::ScriptHighlighter::ScriptHighlighter (QTextDocument *parent) mScheme.insert (std::make_pair (Type_Comment, format)); } + { + QTextCharFormat format; + format.setForeground (Qt::blue); + mScheme.insert (std::make_pair (Type_Id, format)); + } + // configure compiler Compiler::registerExtensions (mExtensions); mContext.setExtensions (&mExtensions); diff --git a/apps/opencs/view/world/scripthighlighter.hpp b/apps/opencs/view/world/scripthighlighter.hpp index 406935b8d..e29a66490 100644 --- a/apps/opencs/view/world/scripthighlighter.hpp +++ b/apps/opencs/view/world/scripthighlighter.hpp @@ -24,7 +24,8 @@ namespace CSVWorld Type_Name, Type_Keyword, Type_Special, - Type_Comment + Type_Comment, + Type_Id }; private: @@ -73,7 +74,7 @@ namespace CSVWorld public: - ScriptHighlighter (QTextDocument *parent); + ScriptHighlighter (const CSMWorld::Data& data, QTextDocument *parent); virtual void highlightBlock (const QString& text); }; diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index ab1c2d57c..6a7ec752f 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -58,7 +58,7 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: connect (mModel, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), this, SLOT (rowsAboutToBeRemoved (const QModelIndex&, int, int))); - new ScriptHighlighter (mEditor->document()); + new ScriptHighlighter (document.getData(), mEditor->document()); } void CSVWorld::ScriptSubView::setEditLock (bool locked) From ba5e2a0330d203bac77b8d0185c6cca12d9176ed Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 19 Sep 2013 13:42:19 +0200 Subject: [PATCH 08/13] changed ID listing to include deleted records by default --- apps/opencs/model/world/collection.hpp | 8 ++--- apps/opencs/model/world/collectionbase.hpp | 4 +-- apps/opencs/model/world/data.cpp | 36 ++++++++++----------- apps/opencs/model/world/data.hpp | 7 ++-- apps/opencs/model/world/refidcollection.cpp | 4 +-- apps/opencs/model/world/refidcollection.hpp | 4 +-- apps/opencs/model/world/refiddata.cpp | 4 +-- apps/opencs/model/world/refiddata.hpp | 4 +-- 8 files changed, 36 insertions(+), 35 deletions(-) diff --git a/apps/opencs/model/world/collection.hpp b/apps/opencs/model/world/collection.hpp index a5014e66c..84a00cef8 100644 --- a/apps/opencs/model/world/collection.hpp +++ b/apps/opencs/model/world/collection.hpp @@ -107,10 +107,10 @@ namespace CSMWorld virtual int getAppendIndex (UniversalId::Type type = UniversalId::Type_None) const; ///< \param type Will be ignored, unless the collection supports multiple record types - virtual std::vector getIds() const; + virtual std::vector getIds (bool listDeleted = true) const; ///< Return a sorted collection of all IDs /// - /// \note Deleted records are not listed. + /// \param listDeleted include deleted record in the list void addColumn (Column *column); @@ -299,14 +299,14 @@ namespace CSMWorld } template - std::vector Collection::getIds() const + std::vector Collection::getIds (bool listDeleted) const { std::vector ids; for (typename std::map::const_iterator iter = mIndex.begin(); iter!=mIndex.end(); ++iter) { - if (!mRecords[iter->second].isDeleted()) + if (listDeleted || !mRecords[iter->second].isDeleted()) ids.push_back (IdAccessorT().getId (mRecords[iter->second].get())); } diff --git a/apps/opencs/model/world/collectionbase.hpp b/apps/opencs/model/world/collectionbase.hpp index 16b88e5e1..ff6dab247 100644 --- a/apps/opencs/model/world/collectionbase.hpp +++ b/apps/opencs/model/world/collectionbase.hpp @@ -79,10 +79,10 @@ namespace CSMWorld virtual int getAppendIndex (UniversalId::Type type = UniversalId::Type_None) const = 0; ///< \param type Will be ignored, unless the collection supports multiple record types - virtual std::vector getIds() const = 0; + virtual std::vector getIds (bool listDeleted = true) const = 0; ///< Return a sorted collection of all IDs /// - /// \note Deleted records are not listed. + /// \param listDeleted include deleted record in the list }; } diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 06fbf61bf..7eb96a5c3 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -35,9 +35,10 @@ void CSMWorld::Data::addModel (QAbstractItemModel *model, UniversalId::Type type } } -void CSMWorld::Data::appendIds (std::vector& ids, const CollectionBase& collection) +void CSMWorld::Data::appendIds (std::vector& ids, const CollectionBase& collection, + bool listDeleted) { - std::vector ids2 = collection.getIds(); + std::vector ids2 = collection.getIds (listDeleted); ids.insert (ids.end(), ids2.begin(), ids2.end()); } @@ -459,22 +460,22 @@ bool CSMWorld::Data::hasId (const std::string& id) const getReferenceables().searchId (id)!=-1; } -std::vector CSMWorld::Data::getIds() const +std::vector CSMWorld::Data::getIds (bool listDeleted) const { std::vector ids; - appendIds (ids, mGlobals); - appendIds (ids, mGmsts); - appendIds (ids, mClasses); - appendIds (ids, mFactions); - appendIds (ids, mRaces); - appendIds (ids, mSounds); - appendIds (ids, mScripts); - appendIds (ids, mRegions); - appendIds (ids, mBirthsigns); - appendIds (ids, mSpells); - appendIds (ids, mCells); - appendIds (ids, mReferenceables); + appendIds (ids, mGlobals, listDeleted); + appendIds (ids, mGmsts, listDeleted); + appendIds (ids, mClasses, listDeleted); + appendIds (ids, mFactions, listDeleted); + appendIds (ids, mRaces, listDeleted); + appendIds (ids, mSounds, listDeleted); + appendIds (ids, mScripts, listDeleted); + appendIds (ids, mRegions, listDeleted); + appendIds (ids, mBirthsigns, listDeleted); + appendIds (ids, mSpells, listDeleted); + appendIds (ids, mCells, listDeleted); + appendIds (ids, mReferenceables, listDeleted); std::sort (ids.begin(), ids.end()); @@ -483,9 +484,8 @@ std::vector CSMWorld::Data::getIds() const void CSMWorld::Data::dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { - // Note: The performance of of ID list change updates could be improved only emit the signal, if - // the state of the record is changed. - emit idListChanged(); + if (topLeft.column()<=0) + emit idListChanged(); } void CSMWorld::Data::rowsChanged (const QModelIndex& parent, int start, int end) diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 1b024751d..e900bb10f 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -62,7 +62,8 @@ namespace CSMWorld void addModel (QAbstractItemModel *model, UniversalId::Type type1, UniversalId::Type type2 = UniversalId::Type_None, bool update = true); - static void appendIds (std::vector& ids, const CollectionBase& collection); + static void appendIds (std::vector& ids, const CollectionBase& collection, + bool listDeleted); ///< Append all IDs from collection to \a ids. public: @@ -145,10 +146,10 @@ namespace CSMWorld bool hasId (const std::string& id) const; - std::vector getIds() const; + std::vector getIds (bool listDeleted = true) const; ///< Return a sorted collection of all IDs that are not internal to the editor. /// - /// \note Deleted records are not listed. + /// \param listDeleted include deleted record in the list signals: diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 5aadb1be3..cda2711cc 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -535,7 +535,7 @@ int CSMWorld::RefIdCollection::getAppendIndex (UniversalId::Type type) const return mData.getAppendIndex (type); } -std::vector CSMWorld::RefIdCollection::getIds() const +std::vector CSMWorld::RefIdCollection::getIds (bool listDeleted) const { - return mData.getIds(); + return mData.getIds (listDeleted); } diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index b6c8efdce..22f83150d 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -90,10 +90,10 @@ namespace CSMWorld virtual int getAppendIndex (UniversalId::Type type) const; ///< \param type Will be ignored, unless the collection supports multiple record types - virtual std::vector getIds() const; + virtual std::vector getIds (bool listDeleted) const; ///< Return a sorted collection of all IDs /// - /// \note Deleted records are not listed. + /// \param listDeleted include deleted record in the list }; } diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index fca0d8a71..9457937f1 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -197,14 +197,14 @@ int CSMWorld::RefIdData::getSize() const return mIndex.size(); } -std::vector CSMWorld::RefIdData::getIds() const +std::vector CSMWorld::RefIdData::getIds (bool listDeleted) const { std::vector ids; for (std::map::const_iterator iter (mIndex.begin()); iter!=mIndex.end(); ++iter) { - if (!getRecord (iter->second).isDeleted()) + if (listDeleted || !getRecord (iter->second).isDeleted()) { std::map::const_iterator container = mRecordContainers.find (iter->second.second); diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index bb8c83360..e221fbc7c 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -183,10 +183,10 @@ namespace CSMWorld int getSize() const; - std::vector getIds() const; + std::vector getIds (bool listDeleted = true) const; ///< Return a sorted collection of all IDs /// - /// \note Deleted records are not listed. + /// \param listDeleted include deleted record in the list }; } From 8d4f4e395fc596fc15e7b3e0156e21608a51e072 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 19 Sep 2013 14:26:09 +0200 Subject: [PATCH 09/13] update syntax highlighting when ID list changes --- apps/opencs/view/world/scripthighlighter.cpp | 4 +++ apps/opencs/view/world/scripthighlighter.hpp | 2 ++ apps/opencs/view/world/scriptsubview.cpp | 31 +++++++++++++++++++- apps/opencs/view/world/scriptsubview.hpp | 14 ++++++++- 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/world/scripthighlighter.cpp b/apps/opencs/view/world/scripthighlighter.cpp index a16077f8a..e06dab372 100644 --- a/apps/opencs/view/world/scripthighlighter.cpp +++ b/apps/opencs/view/world/scripthighlighter.cpp @@ -125,5 +125,9 @@ void CSVWorld::ScriptHighlighter::highlightBlock (const QString& text) scanner.scan (*this); } catch (...) {} // ignore syntax errors +} +void CSVWorld::ScriptHighlighter::invalidateIds() +{ + mContext.invalidateIds(); } \ No newline at end of file diff --git a/apps/opencs/view/world/scripthighlighter.hpp b/apps/opencs/view/world/scripthighlighter.hpp index e29a66490..495c2e6a3 100644 --- a/apps/opencs/view/world/scripthighlighter.hpp +++ b/apps/opencs/view/world/scripthighlighter.hpp @@ -77,6 +77,8 @@ namespace CSVWorld ScriptHighlighter (const CSMWorld::Data& data, QTextDocument *parent); virtual void highlightBlock (const QString& text); + + void invalidateIds(); }; } diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index 6a7ec752f..446c34e5f 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -58,7 +58,13 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: connect (mModel, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), this, SLOT (rowsAboutToBeRemoved (const QModelIndex&, int, int))); - new ScriptHighlighter (document.getData(), mEditor->document()); + connect (&document.getData(), SIGNAL (idListChanged()), this, SLOT (idListChanged())); + + mHighlighter = new ScriptHighlighter (document.getData(), mEditor->document()); + + connect (&mUpdateTimer, SIGNAL (timeout()), this, SLOT (updateHighlighting())); + + mUpdateTimer.setSingleShot (true); } void CSVWorld::ScriptSubView::setEditLock (bool locked) @@ -66,8 +72,19 @@ void CSVWorld::ScriptSubView::setEditLock (bool locked) mEditor->setReadOnly (locked); } +void CSVWorld::ScriptSubView::idListChanged() +{ + mHighlighter->invalidateIds(); + + if (!mUpdateTimer.isActive()) + mUpdateTimer.start (0); +} + void CSVWorld::ScriptSubView::textChanged() { + if (mChangeLocked) + return; + ChangeLock lock (*this); mDocument.getUndoStack().push (new CSMWorld::ModifyCommand (*mModel, @@ -79,6 +96,8 @@ void CSVWorld::ScriptSubView::dataChanged (const QModelIndex& topLeft, const QMo if (mChangeLocked) return; + ChangeLock lock (*this); + QModelIndex index = mModel->getModelIndex (getUniversalId().getId(), mColumn); if (index.row()>=topLeft.row() && index.row()<=bottomRight.row() && @@ -96,4 +115,14 @@ void CSVWorld::ScriptSubView::rowsAboutToBeRemoved (const QModelIndex& parent, i if (!parent.isValid() && index.row()>=start && index.row()<=end) deleteLater(); +} + +void CSVWorld::ScriptSubView::updateHighlighting() +{ + if (mChangeLocked) + return; + + ChangeLock lock (*this); + + mHighlighter->rehighlight(); } \ No newline at end of file diff --git a/apps/opencs/view/world/scriptsubview.hpp b/apps/opencs/view/world/scriptsubview.hpp index 07d87d947..7ceab70ba 100644 --- a/apps/opencs/view/world/scriptsubview.hpp +++ b/apps/opencs/view/world/scriptsubview.hpp @@ -3,6 +3,8 @@ #include "../doc/subview.hpp" +#include + class QTextEdit; class QModelIndex; @@ -18,6 +20,8 @@ namespace CSMWorld namespace CSVWorld { + class ScriptHighlighter; + class ScriptSubView : public CSVDoc::SubView { Q_OBJECT @@ -27,6 +31,8 @@ namespace CSVWorld CSMWorld::IdTable *mModel; int mColumn; int mChangeLocked; + ScriptHighlighter *mHighlighter; + QTimer mUpdateTimer; class ChangeLock { @@ -49,13 +55,19 @@ namespace CSVWorld virtual void setEditLock (bool locked); - private slots: + public slots: + + void idListChanged(); void textChanged(); void dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); void rowsAboutToBeRemoved (const QModelIndex& parent, int start, int end); + + private slots: + + void updateHighlighting(); }; } From 58bb0b8773bfbe0ba832590d12fdf17ebd65e109 Mon Sep 17 00:00:00 2001 From: Xethik Date: Fri, 20 Sep 2013 21:26:12 -0400 Subject: [PATCH 10/13] Bug #907 Added a check to make sure playerview is allowed when attempting to scroll, locking out zooming before character creation. --- apps/openmw/mwinput/inputmanagerimp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 1039a0dce..430a5d843 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -585,7 +585,7 @@ namespace MWInput mPlayer->pitch(-y/scale); } - if (arg.zrel) + if (arg.zrel && mControlSwitch["playerviewswitch"]) //Check to make sure you are allowed to zoomout and there is a change { MWBase::Environment::get().getWorld()->changeVanityModeScale(arg.zrel); MWBase::Environment::get().getWorld()->setCameraDistance(arg.zrel, true, true); From 094e4d93b7ac90ab0a688140a6ad2f4588687a9b Mon Sep 17 00:00:00 2001 From: Xethik Date: Fri, 20 Sep 2013 21:38:10 -0400 Subject: [PATCH 11/13] Generally speaking, you should never compare iterators from two different compilers http://stackoverflow.com/questions/4657513/comparing-iterators-from-different-containers It seems like this was just an overlook that happened to work on most systems. I was not able to thoroughly test this change, but it fixed an issue I was having in VC10. It's possible the prev.end() was a copy paste error that was meant to be new.end() anyways. --- apps/openmw/mwmechanics/magiceffects.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/magiceffects.cpp b/apps/openmw/mwmechanics/magiceffects.cpp index 1a7b34817..32ac1e088 100644 --- a/apps/openmw/mwmechanics/magiceffects.cpp +++ b/apps/openmw/mwmechanics/magiceffects.cpp @@ -151,8 +151,7 @@ namespace MWMechanics for (Collection::const_iterator iter (prev.begin()); iter!=prev.end(); ++iter) { Collection::const_iterator other = now.mCollection.find (iter->first); - - if (other==prev.end()) + if (other==now.end()) { result.add (iter->first, EffectParam() - iter->second); } From 94bb97e766854d6042686ebb2ea773c98f30f13a Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 21 Sep 2013 08:40:00 +0200 Subject: [PATCH 12/13] replacing tabs with spaces --- apps/openmw/mwmechanics/magiceffects.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/magiceffects.cpp b/apps/openmw/mwmechanics/magiceffects.cpp index 32ac1e088..3ed458c3f 100644 --- a/apps/openmw/mwmechanics/magiceffects.cpp +++ b/apps/openmw/mwmechanics/magiceffects.cpp @@ -151,7 +151,7 @@ namespace MWMechanics for (Collection::const_iterator iter (prev.begin()); iter!=prev.end(); ++iter) { Collection::const_iterator other = now.mCollection.find (iter->first); - if (other==now.end()) + if (other==now.end()) { result.add (iter->first, EffectParam() - iter->second); } From 4e5e3bd694d2cd9ca47846f369b05df3735e6f3a Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 21 Sep 2013 10:04:31 +0200 Subject: [PATCH 13/13] updated credits file --- credits.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/credits.txt b/credits.txt index 9a84c5327..c766c34c3 100644 --- a/credits.txt +++ b/credits.txt @@ -47,6 +47,7 @@ Marc Bouvier (CramitDeFrog) Marcin Hulist (Gohan) Mark Siewert (mark76) Mateusz Kołaczek (PL_kolek) +Michael Hogan (Xethik) Michael Mc Donnell Michael Papageorgiou (werdanith) Michał Bień (Glorf)