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..84a00cef8 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 (bool listDeleted = true) const; + ///< Return a sorted collection of all IDs + /// + /// \param listDeleted include deleted record in the list + 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 (bool listDeleted) const + { + std::vector ids; + + for (typename std::map::const_iterator iter = mIndex.begin(); + iter!=mIndex.end(); ++iter) + { + if (listDeleted || !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..ff6dab247 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 (bool listDeleted = true) const = 0; + ///< Return a sorted collection of all IDs + /// + /// \param listDeleted include deleted record in the list + }; } #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..7eb96a5c3 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,31 @@ #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, + bool listDeleted) +{ + std::vector ids2 = collection.getIds (listDeleted); + + ids.insert (ids.end(), ids2.begin(), ids2.end()); } CSMWorld::Data::Data() : mRefs (mCells) @@ -155,7 +174,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 +186,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 +360,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 +459,36 @@ bool CSMWorld::Data::hasId (const std::string& id) const getCells().searchId (id)!=-1 || getReferenceables().searchId (id)!=-1; } + +std::vector CSMWorld::Data::getIds (bool listDeleted) const +{ + std::vector ids; + + 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()); + + return ids; +} + +void CSMWorld::Data::dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) +{ + if (topLeft.column()<=0) + 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..e900bb10f 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,17 @@ 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, + bool listDeleted); + ///< Append all IDs from collection to \a ids. public: Data(); - ~Data(); + virtual ~Data(); const IdCollection& getGlobals() const; @@ -136,6 +145,21 @@ namespace CSMWorld ///< Merging content of a file into base or modified. bool hasId (const std::string& id) const; + + std::vector getIds (bool listDeleted = true) const; + ///< Return a sorted collection of all IDs that are not internal to the editor. + /// + /// \param listDeleted include deleted record in the list + + 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..cda2711cc 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 (bool listDeleted) const +{ + return mData.getIds (listDeleted); +} diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index c10d1d2d0..22f83150d 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 (bool listDeleted) const; + ///< Return a sorted collection of all IDs + /// + /// \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 c95db045f..9457937f1 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 (bool listDeleted) const +{ + std::vector ids; + + for (std::map::const_iterator iter (mIndex.begin()); iter!=mIndex.end(); + ++iter) + { + if (listDeleted || !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..e221fbc7c 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 (bool listDeleted = true) const; + ///< Return a sorted collection of all IDs + /// + /// \param listDeleted include deleted record in the list }; } 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 288a3d12a..e06dab372 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) @@ -22,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; } @@ -62,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); @@ -101,6 +102,16 @@ CSVWorld::ScriptHighlighter::ScriptHighlighter (QTextDocument *parent) format.setForeground (Qt::green); 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); } void CSVWorld::ScriptHighlighter::highlightBlock (const QString& text) @@ -114,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 3ef697809..495c2e6a3 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" @@ -23,12 +24,14 @@ namespace CSVWorld Type_Name, Type_Keyword, Type_Special, - Type_Comment + Type_Comment, + Type_Id }; private: Compiler::NullErrorHandler mErrorHandler; + Compiler::Extensions mExtensions; CSMWorld::ScriptContext mContext; std::map mScheme; @@ -71,9 +74,11 @@ namespace CSVWorld public: - ScriptHighlighter (QTextDocument *parent); + 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 ab1c2d57c..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 (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(); }; } 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/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); diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 566d4bc50..ca26e88ce 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -275,9 +275,8 @@ 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") + // 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()); diff --git a/apps/openmw/mwmechanics/magiceffects.cpp b/apps/openmw/mwmechanics/magiceffects.cpp index 1a7b34817..3ed458c3f 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); } 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 a372e5288..f3d4c81b7 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(); @@ -1948,9 +1948,16 @@ namespace MWWorld stats.getSkill(ESM::Skill::Acrobatics).setModified(gmst.find("fWerewolfAcrobatics")->getFloat(), 0); } + bool World::getGodModeState() + { + return mGodMode; + } + bool World::toggleGodMode() { - return false; + mGodMode = !mGodMode; + + return mGodMode; } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 30ffcda40..53b01f1ab 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&); @@ -440,6 +442,8 @@ namespace MWWorld virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor); + virtual bool getGodModeState(); + virtual bool toggleGodMode(); }; } 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)