From eef9df504a4f3c9a6254421ec5f2363861d40dc6 Mon Sep 17 00:00:00 2001 From: mckibbenta Date: Thu, 29 Aug 2013 20:25:36 -0400 Subject: [PATCH 01/79] 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/79] 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 9637e1641be22db6b77fb5aff0f8068b51106de6 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 14 Sep 2013 13:33:49 +0200 Subject: [PATCH 03/79] fix for building with system tinyxml --- CMakeLists.txt | 1 + apps/openmw/CMakeLists.txt | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ec306e5a..625239aa0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,6 +167,7 @@ if(USE_SYSTEM_TINYXML) find_library(TINYXML_LIBRARIES tinyxml) find_path(TINYXML_INCLUDE_DIR tinyxml.h) message(STATUS "Found TinyXML: ${TINYXML_LIBRARIES} ${TINYXML_INCLUDE_DIR}") + add_definitions (-DTIXML_USE_STL) if(TINYXML_LIBRARIES AND TINYXML_INCLUDE_DIR) include_directories(${TINYXML_INCLUDE_DIR}) message(STATUS "Using system TinyXML library.") diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index a44fd4b34..b367e2a1e 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -119,6 +119,10 @@ target_link_libraries(openmw components ) +if (USE_SYSTEM_TINYXML) + target_link_libraries(openmw ${TINYXML_LIBRARIES}) +endif() + if (NOT UNIX) target_link_libraries(openmw ${SDL2MAIN_LIBRARY}) endif() From 644f081c604c91e98e0a81d38c3566c1aca04d76 Mon Sep 17 00:00:00 2001 From: mckibbenta Date: Sun, 15 Sep 2013 15:48:32 -0400 Subject: [PATCH 04/79] 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 05/79] 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 d5ef843f5615c309d784794028179eee6d21cd0d Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 16 Sep 2013 19:22:08 +0200 Subject: [PATCH 06/79] Fix a missing model update --- apps/openmw/mwgui/hud.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index f9d31bdcd..edcd49738 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -250,6 +250,7 @@ namespace MWGui // remove object from the container it was coming from mDragAndDrop->mSourceModel->removeItem(mDragAndDrop->mItem, mDragAndDrop->mDraggedCount); mDragAndDrop->finish(); + mDragAndDrop->mSourceModel->update(); } else { From 78f7f80fc3d7ed744a4c7ec07d78325550041a16 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 19 Sep 2013 08:58:27 +0200 Subject: [PATCH 07/79] 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 08/79] 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 09/79] 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 10/79] 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 11/79] 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 12/79] 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 13/79] 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 14/79] 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 15/79] 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) From f2875e234c194705ac969c088727f6e799e97a67 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 22 Sep 2013 10:43:09 +0200 Subject: [PATCH 16/79] added missing position columns to reference table --- apps/opencs/model/world/columnimp.hpp | 68 +++++++++++++++++++++++++++ apps/opencs/model/world/columns.cpp | 12 +++++ apps/opencs/model/world/columns.hpp | 12 +++++ apps/opencs/model/world/data.cpp | 13 +++++ 4 files changed, 105 insertions(+) diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 1a2bf9df1..a13ac9a8a 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -1216,6 +1216,74 @@ namespace CSMWorld return true; } }; + + template + struct PosColumn : public Column + { + ESM::Position ESXRecordT::* mPosition; + int mIndex; + + PosColumn (ESM::Position ESXRecordT::* position, int index, bool door) + : Column ( + (door ? Columns::ColumnId_DoorPositionXPos : Columns::ColumnId_PositionXPos)+index, + ColumnBase::Display_Float), mPosition (position), mIndex (index) {} + + virtual QVariant get (const Record& record) const + { + const ESM::Position& position = record.get().*mPosition; + return position.pos[mIndex]; + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + + ESM::Position& position = record.get().*mPosition; + + position.pos[mIndex] = data.toFloat(); + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; + + template + struct RotColumn : public Column + { + ESM::Position ESXRecordT::* mPosition; + int mIndex; + + RotColumn (ESM::Position ESXRecordT::* position, int index, bool door) + : Column ( + (door ? Columns::ColumnId_DoorPositionXRot : Columns::ColumnId_PositionXRot)+index, + ColumnBase::Display_Float), mPosition (position), mIndex (index) {} + + virtual QVariant get (const Record& record) const + { + const ESM::Position& position = record.get().*mPosition; + return position.rot[mIndex]; + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + + ESM::Position& position = record.get().*mPosition; + + position.rot[mIndex] = data.toFloat(); + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; } #endif diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 5616a4a48..25047807a 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -147,6 +147,18 @@ namespace CSMWorld { ColumnId_Magical, "Magical" }, { ColumnId_Silver, "Silver" }, { ColumnId_Filter, "Filter" }, + { ColumnId_PositionXPos, "Pos X" }, + { ColumnId_PositionYPos, "Pos Y" }, + { ColumnId_PositionZPos, "Pos Z" }, + { ColumnId_PositionXRot, "Rot X" }, + { ColumnId_PositionYRot, "Rot Y" }, + { ColumnId_PositionZRot, "Rot Z" }, + { ColumnId_DoorPositionXPos, "Teleport Pos X" }, + { ColumnId_DoorPositionYPos, "Teleport Pos Y" }, + { ColumnId_DoorPositionZPos, "Teleport Pos Z" }, + { ColumnId_DoorPositionXRot, "Teleport Rot X" }, + { ColumnId_DoorPositionYRot, "Teleport Rot Y" }, + { ColumnId_DoorPositionZRot, "Teleport Rot Z" }, { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 69b20583a..582f5102b 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -140,6 +140,18 @@ namespace CSMWorld ColumnId_Magical = 107, ColumnId_Silver = 108, ColumnId_Filter = 109, + ColumnId_PositionXPos = 110, + ColumnId_PositionYPos = 111, + ColumnId_PositionZPos = 112, + ColumnId_PositionXRot = 113, + ColumnId_PositionYRot = 114, + ColumnId_PositionZRot = 115, + ColumnId_DoorPositionXPos = 116, + ColumnId_DoorPositionYPos = 117, + ColumnId_DoorPositionZPos = 118, + ColumnId_DoorPositionXRot = 119, + ColumnId_DoorPositionYRot = 120, + ColumnId_DoorPositionZRot = 121, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 7eb96a5c3..1e290d45f 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include "idtable.hpp" #include "columnimp.hpp" @@ -153,6 +154,12 @@ CSMWorld::Data::Data() : mRefs (mCells) mRefs.addColumn (new RecordStateColumn); mRefs.addColumn (new CellColumn); mRefs.addColumn (new IdColumn); + mRefs.addColumn (new PosColumn (&CellRef::mPos, 0, false)); + mRefs.addColumn (new PosColumn (&CellRef::mPos, 1, false)); + mRefs.addColumn (new PosColumn (&CellRef::mPos, 2, false)); + mRefs.addColumn (new RotColumn (&CellRef::mPos, 0, false)); + mRefs.addColumn (new RotColumn (&CellRef::mPos, 1, false)); + mRefs.addColumn (new RotColumn (&CellRef::mPos, 2, false)); mRefs.addColumn (new ScaleColumn); mRefs.addColumn (new OwnerColumn); mRefs.addColumn (new SoulColumn); @@ -163,6 +170,12 @@ CSMWorld::Data::Data() : mRefs (mCells) mRefs.addColumn (new GoldValueColumn); mRefs.addColumn (new TeleportColumn); mRefs.addColumn (new TeleportCellColumn); + mRefs.addColumn (new PosColumn (&CellRef::mDoorDest, 0, true)); + mRefs.addColumn (new PosColumn (&CellRef::mDoorDest, 1, true)); + mRefs.addColumn (new PosColumn (&CellRef::mDoorDest, 2, true)); + mRefs.addColumn (new RotColumn (&CellRef::mDoorDest, 0, true)); + mRefs.addColumn (new RotColumn (&CellRef::mDoorDest, 1, true)); + mRefs.addColumn (new RotColumn (&CellRef::mDoorDest, 2, true)); mRefs.addColumn (new LockLevelColumn); mRefs.addColumn (new KeyColumn); mRefs.addColumn (new TrapColumn); From 9f533dbbe485a107c4e045c215dc01541a29728d Mon Sep 17 00:00:00 2001 From: Xethik Date: Sun, 22 Sep 2013 04:57:01 -0400 Subject: [PATCH 17/79] Fixed "most vexing parse" issue. --- components/nif/niffile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index cb7c2feb0..402eadefb 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -425,7 +425,7 @@ void Node::getProperties(const Nif::NiTexturingProperty *&texprop, Ogre::Matrix4 Node::getLocalTransform() const { - Ogre::Matrix4 mat4(Ogre::Matrix4::IDENTITY); + Ogre::Matrix4 mat4 = Ogre::Matrix4(Ogre::Matrix4::IDENTITY); mat4.makeTransform(trafo.pos, Ogre::Vector3(trafo.scale), Ogre::Quaternion(trafo.rotation)); return mat4; } From 1c4a4b4f268a151c9ec5640892f2adb28ab1cd2b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 22 Sep 2013 13:39:44 +0200 Subject: [PATCH 18/79] generalised RefIdTypeDelegate into IdTypeDelegate --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/doc/viewmanager.cpp | 4 +- apps/opencs/view/world/idtypedelegate.cpp | 45 ++++++++++++++ ...fidtypedelegate.hpp => idtypedelegate.hpp} | 20 +++--- apps/opencs/view/world/refidtypedelegate.cpp | 62 ------------------- apps/opencs/view/world/table.cpp | 2 +- 6 files changed, 56 insertions(+), 79 deletions(-) create mode 100755 apps/opencs/view/world/idtypedelegate.cpp rename apps/opencs/view/world/{refidtypedelegate.hpp => idtypedelegate.hpp} (51%) delete mode 100755 apps/opencs/view/world/refidtypedelegate.cpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index a719750c6..00547a2ba 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -64,7 +64,7 @@ opencs_units (view/world opencs_units_noqt (view/world dialoguesubview subviews - enumdelegate vartypedelegate recordstatusdelegate refidtypedelegate datadisplaydelegate + enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate scripthighlighter idvalidator ) diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index a5fe6d356..83cd93e5d 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -14,7 +14,7 @@ #include "../world/enumdelegate.hpp" #include "../world/vartypedelegate.hpp" #include "../world/recordstatusdelegate.hpp" -#include "../world/refidtypedelegate.hpp" +#include "../world/idtypedelegate.hpp" #include "../settings/usersettingsdialog.hpp" #include "view.hpp" @@ -56,7 +56,7 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) new CSVWorld::RecordStatusDelegateFactory()); mDelegateFactories->add (CSMWorld::ColumnBase::Display_RefRecordType, - new CSVWorld::RefIdTypeDelegateFactory()); + new CSVWorld::IdTypeDelegateFactory()); struct Mapping { diff --git a/apps/opencs/view/world/idtypedelegate.cpp b/apps/opencs/view/world/idtypedelegate.cpp new file mode 100755 index 000000000..b0ddcbc42 --- /dev/null +++ b/apps/opencs/view/world/idtypedelegate.cpp @@ -0,0 +1,45 @@ +#include "idtypedelegate.hpp" + +#include "../../model/world/universalid.hpp" + +CSVWorld::IdTypeDelegate::IdTypeDelegate + (const ValueList &values, const IconList &icons, QUndoStack& undoStack, QObject *parent) + : DataDisplayDelegate (values, icons, undoStack, parent) +{} + +bool CSVWorld::IdTypeDelegate::updateEditorSetting (const QString &settingName, const QString &settingValue) +{ + if (settingName == "Referenceable ID Type Display") + { + if (settingValue == "Icon and Text") + mDisplayMode = Mode_IconAndText; + + else if (settingValue == "Icon Only") + mDisplayMode = Mode_IconOnly; + + else if (settingValue == "Text Only") + mDisplayMode = Mode_TextOnly; + + return true; + } + + return false; +} + + +CSVWorld::IdTypeDelegateFactory::IdTypeDelegateFactory() +{ + for (int i=0; i (i)); + + DataDisplayDelegateFactory::add (id.getType(), QString::fromUtf8 (id.getTypeName().c_str()), + QString::fromUtf8 (id.getIcon().c_str())); + } +} + +CSVWorld::CommandDelegate *CSVWorld::IdTypeDelegateFactory::makeDelegate (QUndoStack& undoStack, + QObject *parent) const +{ + return new IdTypeDelegate (mValues, mIcons, undoStack, parent); +} diff --git a/apps/opencs/view/world/refidtypedelegate.hpp b/apps/opencs/view/world/idtypedelegate.hpp similarity index 51% rename from apps/opencs/view/world/refidtypedelegate.hpp rename to apps/opencs/view/world/idtypedelegate.hpp index 384aebb98..ea80fd0d9 100755 --- a/apps/opencs/view/world/refidtypedelegate.hpp +++ b/apps/opencs/view/world/idtypedelegate.hpp @@ -1,5 +1,5 @@ -#ifndef REFIDTYPEDELEGATE_HPP -#define REFIDTYPEDELEGATE_HPP +#ifndef IDTYPEDELEGATE_HPP +#define IDTYPEDELEGATE_HPP #include "enumdelegate.hpp" #include "util.hpp" @@ -8,29 +8,23 @@ namespace CSVWorld { - class RefIdTypeDelegate : public DataDisplayDelegate + class IdTypeDelegate : public DataDisplayDelegate { public: - RefIdTypeDelegate (const ValueList &mValues, const IconList &icons, QUndoStack& undoStack, QObject *parent); + IdTypeDelegate (const ValueList &mValues, const IconList &icons, QUndoStack& undoStack, QObject *parent); virtual bool updateEditorSetting (const QString &settingName, const QString &settingValue); }; - class RefIdTypeDelegateFactory : public DataDisplayDelegateFactory + class IdTypeDelegateFactory : public DataDisplayDelegateFactory { - - typedef std::vector < std::pair > UidTypeList; - public: - RefIdTypeDelegateFactory(); + + IdTypeDelegateFactory(); virtual CommandDelegate *makeDelegate (QUndoStack& undoStack, QObject *parent) const; ///< The ownership of the returned CommandDelegate is transferred to the caller. - - private: - UidTypeList buildUidTypeList () const; - }; } diff --git a/apps/opencs/view/world/refidtypedelegate.cpp b/apps/opencs/view/world/refidtypedelegate.cpp deleted file mode 100755 index 7cffbf3dd..000000000 --- a/apps/opencs/view/world/refidtypedelegate.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "refidtypedelegate.hpp" - -#include "../../model/world/universalid.hpp" - -CSVWorld::RefIdTypeDelegate::RefIdTypeDelegate - (const ValueList &values, const IconList &icons, QUndoStack& undoStack, QObject *parent) - : DataDisplayDelegate (values, icons, undoStack, parent) -{} - -bool CSVWorld::RefIdTypeDelegate::updateEditorSetting (const QString &settingName, const QString &settingValue) -{ - if (settingName == "Referenceable ID Type Display") - { - if (settingValue == "Icon and Text") - mDisplayMode = Mode_IconAndText; - - else if (settingValue == "Icon Only") - mDisplayMode = Mode_IconOnly; - - else if (settingValue == "Text Only") - mDisplayMode = Mode_TextOnly; - - return true; - } - - return false; -} - - -CSVWorld::RefIdTypeDelegateFactory::RefIdTypeDelegateFactory() -{ - UidTypeList uIdList = buildUidTypeList(); - - for (UidTypeList::const_iterator it = uIdList.begin(); it != uIdList.end(); it++) - { - int i = it->first; - DataDisplayDelegateFactory::add (i, QString::fromStdString(CSMWorld::UniversalId(it->first, "").getTypeName()), it->second); - } -} - -CSVWorld::CommandDelegate *CSVWorld::RefIdTypeDelegateFactory::makeDelegate (QUndoStack& undoStack, - QObject *parent) const -{ - return new RefIdTypeDelegate (mValues, mIcons, undoStack, parent); -} - -CSVWorld::RefIdTypeDelegateFactory::UidTypeList CSVWorld::RefIdTypeDelegateFactory::buildUidTypeList() const -{ - UidTypeList list; - - std::vector types = CSMWorld::UniversalId::listReferenceableTypes(); - - for (std::vector::const_iterator iter (types.begin()); - iter!=types.end(); ++iter) - { - CSMWorld::UniversalId id (*iter, ""); - - list.push_back (std::make_pair (id.getType(), id.getIcon().c_str())); - } - - return list; -} diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index 72e78c738..6167c084a 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -12,8 +12,8 @@ #include "../../model/world/idtableproxymodel.hpp" #include "../../model/world/idtable.hpp" #include "../../model/world/record.hpp" + #include "recordstatusdelegate.hpp" -#include "refidtypedelegate.hpp" #include "util.hpp" void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event) From a6ea670255add9306f4d27b9f52b4739a2b5d0ce Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 22 Sep 2013 13:54:01 +0200 Subject: [PATCH 19/79] use IdTypeDelegate in report table --- apps/opencs/view/tools/reportsubview.cpp | 12 ++++++++++++ apps/opencs/view/tools/reportsubview.hpp | 8 ++++++++ apps/opencs/view/world/idtypedelegate.cpp | 1 + 3 files changed, 21 insertions(+) diff --git a/apps/opencs/view/tools/reportsubview.cpp b/apps/opencs/view/tools/reportsubview.cpp index fe1be85d7..182d1cdd6 100644 --- a/apps/opencs/view/tools/reportsubview.cpp +++ b/apps/opencs/view/tools/reportsubview.cpp @@ -6,6 +6,8 @@ #include "../../model/tools/reportmodel.hpp" +#include "../../view/world/idtypedelegate.hpp" + CSVTools::ReportSubView::ReportSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) : CSVDoc::SubView (id), mModel (document.getReport (id)) { @@ -18,6 +20,11 @@ CSVTools::ReportSubView::ReportSubView (const CSMWorld::UniversalId& id, CSMDoc: mTable->setSelectionBehavior (QAbstractItemView::SelectRows); mTable->setSelectionMode (QAbstractItemView::ExtendedSelection); + mIdTypeDelegate = CSVWorld::IdTypeDelegateFactory().makeDelegate ( + document.getUndoStack(), this); + + mTable->setItemDelegateForColumn (0, mIdTypeDelegate); + connect (mTable, SIGNAL (doubleClicked (const QModelIndex&)), this, SLOT (show (const QModelIndex&))); } @@ -26,6 +33,11 @@ void CSVTools::ReportSubView::setEditLock (bool locked) // ignored. We don't change document state anyway. } +void CSVTools::ReportSubView::updateEditorSetting (const QString& key, const QString& value) +{ + mIdTypeDelegate->updateEditorSetting (key, value); +} + void CSVTools::ReportSubView::show (const QModelIndex& index) { focusId (mModel->getUniversalId (index.row())); diff --git a/apps/opencs/view/tools/reportsubview.hpp b/apps/opencs/view/tools/reportsubview.hpp index 626ceb663..6503ebd27 100644 --- a/apps/opencs/view/tools/reportsubview.hpp +++ b/apps/opencs/view/tools/reportsubview.hpp @@ -16,6 +16,11 @@ namespace CSMTools class ReportModel; } +namespace CSVWorld +{ + class CommandDelegate; +} + namespace CSVTools { class Table; @@ -26,6 +31,7 @@ namespace CSVTools CSMTools::ReportModel *mModel; QTableView *mTable; + CSVWorld::CommandDelegate *mIdTypeDelegate; public: @@ -33,6 +39,8 @@ namespace CSVTools virtual void setEditLock (bool locked); + virtual void updateEditorSetting (const QString&, const QString&); + private slots: void show (const QModelIndex& index); diff --git a/apps/opencs/view/world/idtypedelegate.cpp b/apps/opencs/view/world/idtypedelegate.cpp index b0ddcbc42..ce4e8f014 100755 --- a/apps/opencs/view/world/idtypedelegate.cpp +++ b/apps/opencs/view/world/idtypedelegate.cpp @@ -9,6 +9,7 @@ CSVWorld::IdTypeDelegate::IdTypeDelegate bool CSVWorld::IdTypeDelegate::updateEditorSetting (const QString &settingName, const QString &settingValue) { + /// \todo make the setting key a member variable, that is initialised from a constructor argument if (settingName == "Referenceable ID Type Display") { if (settingValue == "Icon and Text") From c423479f20ae71dbb24e2b8f5e14f1ddc0eef5e5 Mon Sep 17 00:00:00 2001 From: Berulacks Date: Mon, 23 Sep 2013 07:31:14 -0400 Subject: [PATCH 20/79] Fixed bug #887 --- apps/openmw/mwgui/mainmenu.cpp | 3 +++ apps/openmw/mwinput/inputmanagerimp.cpp | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index 88227c751..1e967ea93 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -70,7 +70,10 @@ namespace MWGui { MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f); if (sender == mButtons["return"]) + { + MWBase::Environment::get().getSoundManager()->resumeSounds(8); MWBase::Environment::get().getWindowManager ()->removeGuiMode (GM_MainMenu); + } else if (sender == mButtons["options"]) MWBase::Environment::get().getWindowManager ()->pushGuiMode (GM_Settings); else if (sender == mButtons["exitgame"]) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 430a5d843..27977d99c 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -617,9 +617,15 @@ namespace MWInput if (MWBase::Environment::get().getWindowManager()->isGuiMode () && MWBase::Environment::get().getWindowManager()->getMode () == MWGui::GM_Video) MWBase::Environment::get().getWorld ()->stopVideo (); else if (MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu)) + { MWBase::Environment::get().getWindowManager()->popGuiMode(); + MWBase::Environment::get().getSoundManager()->resumeSounds(8); + } else + { MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); + MWBase::Environment::get().getSoundManager()->pauseSounds(8); + } } void InputManager::toggleSpell() From 0c518fb047a966234a23370fb6439cb8ea2e911c Mon Sep 17 00:00:00 2001 From: Berulacks Date: Mon, 23 Sep 2013 07:36:50 -0400 Subject: [PATCH 21/79] Replaced tabs with spaces. --- apps/openmw/mwgui/mainmenu.cpp | 4 ++-- apps/openmw/mwinput/inputmanagerimp.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index 1e967ea93..400dcab96 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -70,10 +70,10 @@ namespace MWGui { MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f); if (sender == mButtons["return"]) - { + { MWBase::Environment::get().getSoundManager()->resumeSounds(8); MWBase::Environment::get().getWindowManager ()->removeGuiMode (GM_MainMenu); - } + } else if (sender == mButtons["options"]) MWBase::Environment::get().getWindowManager ()->pushGuiMode (GM_Settings); else if (sender == mButtons["exitgame"]) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 27977d99c..014045099 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -617,15 +617,15 @@ namespace MWInput if (MWBase::Environment::get().getWindowManager()->isGuiMode () && MWBase::Environment::get().getWindowManager()->getMode () == MWGui::GM_Video) MWBase::Environment::get().getWorld ()->stopVideo (); else if (MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu)) - { + { MWBase::Environment::get().getWindowManager()->popGuiMode(); MWBase::Environment::get().getSoundManager()->resumeSounds(8); - } + } else - { + { MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); MWBase::Environment::get().getSoundManager()->pauseSounds(8); - } + } } void InputManager::toggleSpell() From 91d7291c0c79e6c4283b729aa938e4a5de4e672b Mon Sep 17 00:00:00 2001 From: Berulacks Date: Mon, 23 Sep 2013 08:31:36 -0400 Subject: [PATCH 22/79] Switched to using proper enums as opposed to ints. --- apps/openmw/mwgui/mainmenu.cpp | 2 +- apps/openmw/mwinput/inputmanagerimp.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index 400dcab96..70cd4b592 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -71,7 +71,7 @@ namespace MWGui MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f); if (sender == mButtons["return"]) { - MWBase::Environment::get().getSoundManager()->resumeSounds(8); + MWBase::Environment::get().getSoundManager ()->resumeSounds(MWBase::Environment::get().getSoundManager ()-> Play_TypeSfx); MWBase::Environment::get().getWindowManager ()->removeGuiMode (GM_MainMenu); } else if (sender == mButtons["options"]) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 014045099..958703df3 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -619,12 +619,12 @@ namespace MWInput else if (MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu)) { MWBase::Environment::get().getWindowManager()->popGuiMode(); - MWBase::Environment::get().getSoundManager()->resumeSounds(8); + MWBase::Environment::get().getSoundManager()->resumeSounds(MWBase::Environment::get().getSoundManager()->Play_TypeSfx); } else { MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); - MWBase::Environment::get().getSoundManager()->pauseSounds(8); + MWBase::Environment::get().getSoundManager()->pauseSounds(MWBase::Environment::get().getSoundManager()->Play_TypeSfx); } } From 0f1c4cb00e6adfd5a8a20555fa8e57cbba8319cd Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 23 Sep 2013 15:34:52 +0200 Subject: [PATCH 23/79] cleanup --- apps/openmw/mwgui/mainmenu.cpp | 2 +- apps/openmw/mwinput/inputmanagerimp.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index 70cd4b592..1db6e9ecd 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -71,7 +71,7 @@ namespace MWGui MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f); if (sender == mButtons["return"]) { - MWBase::Environment::get().getSoundManager ()->resumeSounds(MWBase::Environment::get().getSoundManager ()-> Play_TypeSfx); + MWBase::Environment::get().getSoundManager ()->resumeSounds (MWBase::SoundManager::Play_TypeSfx); MWBase::Environment::get().getWindowManager ()->removeGuiMode (GM_MainMenu); } else if (sender == mButtons["options"]) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 958703df3..43f2bcc15 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -577,8 +577,8 @@ namespace MWInput rot[0] = -y; rot[1] = 0.0f; rot[2] = x; - - // Only actually turn player when we're not in vanity mode + + // Only actually turn player when we're not in vanity mode if(!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot)) { mPlayer->yaw(x/scale); @@ -619,12 +619,12 @@ namespace MWInput else if (MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu)) { MWBase::Environment::get().getWindowManager()->popGuiMode(); - MWBase::Environment::get().getSoundManager()->resumeSounds(MWBase::Environment::get().getSoundManager()->Play_TypeSfx); + MWBase::Environment::get().getSoundManager()->resumeSounds (MWBase::SoundManager::Play_TypeSfx); } else { MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); - MWBase::Environment::get().getSoundManager()->pauseSounds(MWBase::Environment::get().getSoundManager()->Play_TypeSfx); + MWBase::Environment::get().getSoundManager()->pauseSounds (MWBase::SoundManager::Play_TypeSfx); } } From ea637a24b99d875804c3d324d48efb7e7696364a Mon Sep 17 00:00:00 2001 From: sirherrbatka Date: Mon, 23 Sep 2013 19:48:18 +0200 Subject: [PATCH 24/79] Issue 912, making branch --- issue912 | 1 + 1 file changed, 1 insertion(+) create mode 100644 issue912 diff --git a/issue912 b/issue912 new file mode 100644 index 000000000..604cc392c --- /dev/null +++ b/issue912 @@ -0,0 +1 @@ +branch for issue912 From ae5e8b95ffba3bd45d277acee9eec4c78447138f Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 23 Sep 2013 20:12:04 +0200 Subject: [PATCH 25/79] Solving Issue912 --- apps/opencs/model/world/universalid.cpp | 26 ++++---- files/opencs/GMST.png | Bin 0 -> 820 bytes files/opencs/Info.png | Bin 0 -> 1234 bytes files/opencs/LandTexture.png | Bin 0 -> 2662 bytes files/opencs/PathGrid.png | Bin 0 -> 1297 bytes files/opencs/activator.png | Bin 2297 -> 1913 bytes files/opencs/added.png | Bin 862 -> 615 bytes files/opencs/apparatus.png | Bin files/opencs/armor.png | Bin files/opencs/attribute.png | Bin 0 -> 1788 bytes files/opencs/birthsign.png | Bin 0 -> 2454 bytes files/opencs/body-part.png | Bin 0 -> 1248 bytes files/opencs/book.png | Bin 1336 -> 1599 bytes files/opencs/cell.png | Bin 0 -> 1403 bytes files/opencs/class.png | Bin 0 -> 2283 bytes files/opencs/clothing.png | Bin files/opencs/container.png | Bin files/opencs/creature.png | Bin files/opencs/dialogoue-info.png | Bin 0 -> 1851 bytes files/opencs/dialogoue-journal.png | Bin 0 -> 1991 bytes files/opencs/dialogoue-regular.png | Bin 0 -> 1486 bytes files/opencs/dialogue-greeting.png | Bin 0 -> 1948 bytes files/opencs/dialogue-persuasion.png | Bin 0 -> 1987 bytes files/opencs/dialogue-speech.png | Bin 0 -> 1987 bytes files/opencs/door.png | Bin files/opencs/enchantment.png | Bin 0 -> 1812 bytes files/opencs/faction.png | Bin 0 -> 1858 bytes files/opencs/filter.png | Bin 0 -> 1375 bytes files/opencs/globvar.png | Bin 0 -> 2394 bytes files/opencs/ingredient.png | Bin 1444 -> 1384 bytes files/opencs/land.png | Bin 0 -> 1220 bytes files/opencs/landpaint.png | Bin 0 -> 1361 bytes files/opencs/leveled-creature.png | Bin files/opencs/light.png | Bin 747 -> 1199 bytes files/opencs/lockpick.png | Bin files/opencs/magic-effect.png | Bin 0 -> 1702 bytes files/opencs/magicrabbit.png | Bin 0 -> 1820 bytes files/opencs/map.png | Bin 0 -> 1477 bytes files/opencs/miscellaneous.png | Bin files/opencs/modified.png | Bin 2149 -> 1320 bytes files/opencs/npc.png | Bin files/opencs/potion.png | Bin files/opencs/probe.png | Bin files/opencs/race.png | Bin 0 -> 1834 bytes files/opencs/random-item.png | Bin 0 -> 1698 bytes files/opencs/random.png | Bin 0 -> 1892 bytes files/opencs/removed.png | Bin 1772 -> 1251 bytes files/opencs/repair.png | Bin files/opencs/resources.qrc | 77 +++++++++++++++++------- files/opencs/script.png | Bin 0 -> 952 bytes files/opencs/skill.png | Bin 0 -> 1676 bytes files/opencs/sound.png | Bin 0 -> 1144 bytes files/opencs/soundgen.png | Bin 0 -> 2149 bytes files/opencs/spell.png | Bin 0 -> 2071 bytes files/opencs/static.png | Bin 1518 -> 1297 bytes files/opencs/weapon.png | Bin 56 files changed, 67 insertions(+), 36 deletions(-) create mode 100644 files/opencs/GMST.png create mode 100644 files/opencs/Info.png create mode 100644 files/opencs/LandTexture.png create mode 100644 files/opencs/PathGrid.png mode change 100755 => 100644 files/opencs/activator.png mode change 100755 => 100644 files/opencs/apparatus.png mode change 100755 => 100644 files/opencs/armor.png create mode 100644 files/opencs/attribute.png create mode 100644 files/opencs/birthsign.png create mode 100644 files/opencs/body-part.png mode change 100755 => 100644 files/opencs/book.png create mode 100644 files/opencs/cell.png create mode 100644 files/opencs/class.png mode change 100755 => 100644 files/opencs/clothing.png mode change 100755 => 100644 files/opencs/container.png mode change 100755 => 100644 files/opencs/creature.png create mode 100644 files/opencs/dialogoue-info.png create mode 100644 files/opencs/dialogoue-journal.png create mode 100644 files/opencs/dialogoue-regular.png create mode 100644 files/opencs/dialogue-greeting.png create mode 100644 files/opencs/dialogue-persuasion.png create mode 100644 files/opencs/dialogue-speech.png mode change 100755 => 100644 files/opencs/door.png create mode 100644 files/opencs/enchantment.png create mode 100644 files/opencs/faction.png create mode 100644 files/opencs/filter.png create mode 100644 files/opencs/globvar.png mode change 100755 => 100644 files/opencs/ingredient.png create mode 100644 files/opencs/land.png create mode 100644 files/opencs/landpaint.png mode change 100755 => 100644 files/opencs/leveled-creature.png mode change 100755 => 100644 files/opencs/light.png mode change 100755 => 100644 files/opencs/lockpick.png create mode 100644 files/opencs/magic-effect.png create mode 100644 files/opencs/magicrabbit.png create mode 100644 files/opencs/map.png mode change 100755 => 100644 files/opencs/miscellaneous.png mode change 100755 => 100644 files/opencs/npc.png mode change 100755 => 100644 files/opencs/potion.png mode change 100755 => 100644 files/opencs/probe.png create mode 100644 files/opencs/race.png create mode 100644 files/opencs/random-item.png create mode 100644 files/opencs/random.png mode change 100755 => 100644 files/opencs/repair.png create mode 100644 files/opencs/script.png create mode 100644 files/opencs/skill.png create mode 100644 files/opencs/sound.png create mode 100644 files/opencs/soundgen.png create mode 100644 files/opencs/spell.png mode change 100755 => 100644 files/opencs/static.png mode change 100755 => 100644 files/opencs/weapon.png diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index d360fde8f..60a8485f8 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -43,18 +43,18 @@ namespace static const TypeData sIdArg[] = { - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable", 0 }, - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting", 0 }, - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Skill, "Skill", 0 }, - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Class, "Class", 0 }, - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Faction, "Faction", 0 }, - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Race, "Race", 0 }, - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Sound, "Sound", 0 }, - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Script, "Script", 0 }, - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Region, "Region", 0 }, - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Birthsign, "Birthsign", 0 }, - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Spell, "Spell", 0 }, - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell", 0 }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable", ":./globvar.png" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting", ":./GMST.png" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Skill, "Skill", ":./skill.png" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Class, "Class", ":./class.png" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Faction, "Faction", ":./faction.png" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Race, "Race", ":./race.png" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Sound, "Sound", ":./sound.png" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Script, "Script", ":./script.png" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Region, "Region", ":./land.png" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Birthsign, "Birthsign", ":./birthsign.png" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Spell, "Spell", ":./spell.png" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell", ":./cell.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Referenceable, "Referenceables", 0 }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Activator, "Activator", ":./activator.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Potion, "Potion", ":./potion.png" }, @@ -80,7 +80,7 @@ namespace { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Static, "Static", ":./static.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Weapon, "Weapon", ":./weapon.png" }, { CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Reference, "Reference", 0 }, - { CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Filter, "Filter", 0 }, + { CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Filter, "Filter", ":./filter.png" }, { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker }; diff --git a/files/opencs/GMST.png b/files/opencs/GMST.png new file mode 100644 index 0000000000000000000000000000000000000000..f246202882eae9203e9a718ee5117031b8e76aa0 GIT binary patch literal 820 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 U5S+aqrvLx|07*qoM6N<$f?VGlaR2}S literal 0 HcmV?d00001 diff --git a/files/opencs/PathGrid.png b/files/opencs/PathGrid.png new file mode 100644 index 0000000000000000000000000000000000000000..23b6b84d74867d65d7eb4542c5bc2864c94ea0ef GIT binary patch literal 1297 zcmV+s1@8KZP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv000DlNkl&1h@qpg`~OoL(;U&%JFjqc8IC%f0>1{m%J)=R3diePsZcO~ic( zJjC(Gh?oS(wt-le0Qr`hOXD2F2L^nKfvLq|#8cZZOV1^rOl*(9UIq$g;Pd09KiG~P z{aLDztS^?&5~S=GUMc&-QeJ+kKoLt9;b2+W*WVsG1a3sFLUAY8Nh6Mt{W_vX#Qx5a zBXjrm?}sxoSyCrSf>*&B0_Bno_62$TE;_hfQUZ<79wnV;ebZ7UPfVlz8$>O>XWE0o z10$vid2$}--b8ylWMH*3I0(=+zS3BVzfx;OejrUi|etDWcK!r(4 zA-NVSLON2n_j>n9!Aa*NwN9msj_a&%1UvNsL%JF5+Nn63P#x3bsB&mST z{5%4*azW=LwcKwgfRtSz;6nnJk$^^;z~h3gm{u;O^J0B~>>AvH*9&jKKf4bU>jQlE zle*0OA1@@dE!}qe%ez_m53giai)HlP-rj^>uTL~KG^ltIMF_l)MM%{ycG!>uvJ=Gi z`3pS2Y7goh4NYOm;uwbWWe3`F(hb{=RP?^x5r@OeWL8mzS3z91g>Gw{AgK zXFWD3Cc${U&o3EU*(cFx6xP<(!0-3NmEmDHYqxEDh)@muNY0E#<0ux(lQRxS3JIld<5tk5%-|l62TVre zZy7QYC4lqiXr8d=UauF>cS>DX$6?@gtwuAty@2~W1ZW`5ytz4Gx7jw0t*vRM!pbSQ z%jF{GF(adEevEUipeG*I7Wu5+M1eh&B>F{a7xDw zUAze69*0kGo_#A}wOT(Ya34r#Aj;Q)C_>aHE`9vcUs_Fd zDjF?$fWPT(ARzDWdn{HGx4c=;UA_7m{cWc!f9ChO@0))EwEBWcff-P}00000NkvXX Hu0mjfN03_( literal 0 HcmV?d00001 diff --git a/files/opencs/activator.png b/files/opencs/activator.png old mode 100755 new mode 100644 index 0446af22cf7d4238e06d7682ab5ec86127b103c8..32cc6f8a3c428c2d6b6bd726c182dc246f6151d9 GIT binary patch delta 1898 zcmV-w2bK8w5%~^~B!3BTNLh0L01FcU01FcV0GgZ_0000PbVXQnQ*UN;cVTj606}DL zVr3vnZDD6+Qe|Oed2z{QJOBU(21!IgRCwB)S6fU|cNqVG(n6tJv_PS-0*N?9K#*$y z5g!B*HNym*VJ3Ui7mW{7W2O&2sEL`Hxn#~I`e3~6!HF}1BYzp=rrbdUMV&xnpaseu zilqqqekVQTP-zvKob+7&=l|V)-}n0+m-+d5TFEabC+B5IaIg~Z_x1Ie|1K+Azmk1i zKewQupddCkC+DvHeHj1Y*fHJVBS&-^KDU3Ky=BYY?YX(JD|R3O$B!Qg=PAj_`J&_QGTEWcSy^yIo|2NXIW#Qn zup>Jz&M?4rHe9%HL1Q!;X<%T0e!F_r6doR~$jHo8g@1;IQb0fe_4M=*9C`o#JvBBo zOz^+u*zx0PA0Hoj_wF6tym`}DSy>tE$cD^WecavMkCvC0-$_hNB!7Q@`sw0DwU?I{ zSu7Tsnwk=vf^oTAPO-7E#OqXit@8HvrZ;ciP<>q;$=uwIIsHUv(NP*69u_vOZ)l+5p&?RucnDaSo}MN@Utih~6GK|9mfYOj$ZR%K zS67#randU_n4X?~+R)ecb60ow=%Nw;aHx6l!-qyh4&zFtvgGW!b6!|eU0qEjj~|ng zGr(manM_6^2Jnxp=(!xz49tv-3Cq(|^sZ*YKe(TmPYHe+$O`A3e(ZQh9_##KxfzHlOidwst z;^N|jdk-EwFefD?DKj%O$;HKmZd|`^;cO=VTT#&_v!(iEU|^tpaBz@DMn+IeLfY{% zjDG`!X=!Oo8kC;n-<2KwdfhtWG*b)Ti{Y{yIB-B25)vZp)7#ri-YS*CU@)9y)B6@m zfIdg7eY=0ZFH(me5MEqd{KdxY@4bHgnliZ@fm{w;k1&R+s;b6ZU0ttMR#lz&qzwT? z2GLuf9f14g$`y)Xbbl`Gj+_H7cuWId!hiLj_wSo{-!&otKWRfe_^zl(fmQ?B0l1}% zqfDKzUiGu{tq6ca*ccHJ5yYTfw3Z_!H$M9N`)T#+)uavxP&76*jXInIm~dPI6+B0) z0qsi}Z*FR;X?^}YL;7xPOiVQcFC9)uv*5pKl~4*sKb%l)jEl?XcONY{AZ0a8Cf&w*WJI3o$Xb0dN+UIA^Is={c z-`lq)2B%O09(rb(RLOu+na%zJv0%0XjIOryiJJiJ032#AHNGJ_x>~2x1=$-%cE#=h zfK5X~-?z23J#t9LdkYK44<0(CdiwM!)joShI_?DfXfUpM?)RhSWNX7eIBY`l1U^NhnvuWq7<|gJAP&BTYVX3gNP#vPx>bcbC7nJ}45*iLN z3g81_fX}f>V`C%rGl_8jE`Q7T#KZ(K!BJ#nKknT#gOot20lX2W89@0t<4F4ek6zI@-eD}6yLev&hm7`gcUxFb zoLvM$s8f!3QES))3apfu3duoG#U)_thQE|?LOQg5G3|!M}O3)InwTH>moKj z$rkc>y_VNs;$fs=Dz0p9Zq8cd0KftD$^vphk}(ZuDin%R@HxWEE&vWrA@UikHMgaurApkB753?|(a{A-CX+HD|DBO`1!NSI48(-VWD+(7tASXg z(Mt~za7edWtyXerwSUq**_kt6tcs!GAfupUASTMn%1oeCuo@!8YzJ0U0W5+B2 z9BRJo4-=cQtSwntu@I2l0VnLg4W+Cm{ngdipGb(04@avp+S{C!*=41l=RD0`s#Gea k$Z8FZjVt;*|6hOs0QX!jM!rPcX8-^I07*qoM6N<$g1YF3VE_OC delta 2285 zcmV004R> z004l5008;`004mK004C`008P>0026e000+ooVrmw00006VoOIv00000008+zyMF)x z010qNS#tmY4f_B94f_ELcQu;;00+rQL_t(o!|hdRaFx{=et*9G`|iHq3rT<*66ykh zu#8&cuqvgt(spF1;}{D{ROqOs4(QbJ2V)&OPU|0L>;`pMgpiaVkOn~ziy_d0M8L2o zKrq|A3HN^6-Ol;G{=m!7$|w`;Kc8P`&b;q=p7WmPeGl**zQg|sYu^29^{vFQ-xlFZ zD_@#WJg;T<&VTLW?x;Li6fuAPe9!Xb&sW|okH1~wWy_Yya~_(#tzulo+)33{PaZhX zx`Sbu>53%Fp-`Zv_Nm(Q^XC5G(^xDrcJ$ct880k*@#7ownQ!Cvo9Z|2nOHq>j-eaS z4PAA)oF3b@K}Z3brYD?EN7%A~bEnVT`_!Um4&Ru|-G2`8_Lld*9}0x8UbxuFPo7-; zBZdVmN+nfQkxr*TEec7IoeaZ5*L16?vFX)$^B!{7F0QTGxxKmjwkoi(e#6!Y6DIsv zO{Y(bqHs4a3QTwRWvF@@xm*^65ZJa2p5x&0_z{gnF*rCxB}uecmczjV2WP#$>Wxo^ z?SWiAJAY(R%K82N@dc8{g{}+GbQOlKBa_L36bi5zK;U^~^Eu>lIh2)^aV*1fnyOJ> zFyOtdCwRYU`}XRoRh1>BrB!|Xy-206LQ^%UstPr&B9%(ng?yeNgu=FMSQbIR7X&5L zYHK@G^P82geso&`c76Ddnt(sJN|HpWKhY0O*MFdC8WQ~p>tAh0U)!`{%j{?@GTq@+ z;tb0`5O{DL50}f$h_ZZs)~uOEOLI%#usrbLN4s}~!{Hy=u-RNLi>^x-Ff=%X!NDP% z>NtJyy><2X7h@Ma^F$#MjqpC72cb|HW8)P7!yuQ<<*ha%!l9~AC_GueWjemrFrkR0Z7?#uJU`tEOAPk5Y;#f#>4ulY}EC)#v zF{&&Mp679*{p4r

{MD4u9)E4{ZXz{EYtir*{^N7&)RulH?~X%YtF*=pX2VVd%)1 zCbIcFC?x;@!!$57B%`#nM52_!@At9CkDuth6z zC=QP0c5G|f-qqIHW)v%by?+fAhulRe%^QY+Y&HwiG@8Qa|4+z9}` zTJik;Xf!h2>2$#Dabr~3XfR-H!!VP*Jw0oeEPnQ709d#2Z>yXx*Q_^Iy*cCP(WB(+ z<_sT;MSLS;BO{_D34|0tCbwfigmjk618wmL) z-8tdTlhuIm~A%rY(I-Eh4Wx;VAL`gt(^~6V1O`pectiTH#B!5waAP7(-2Uw0pPfyQ| z4I4Hbx)rjUq4*gwM~?lw)93S!A(UWXpdX3B0qD90)5u(_hDE_~ECf-2Ad0AnSAyqx z5K3{j<80ltbxZ#;905E4ELgBWRurWyl}f3)q4x)afl5LN2qj<`27<(Y+1G%;i6|*4 z1H&*#CX(G=pMS5^<#9!ZTLBILIyySYnE2?!3x2ln=}A>pe-A~%KlixZ9$9uk5JX6# z2$$0hzb}YrGzOMs(f;YNm5XbaJnC_JH^02%m8RhexIPC~{CedF#kC|!A%KCVY5fkx zK_ZbDLZL7$N{0;7)OcP%AQ-9ufYqy4pBXOse+ek!@PCmbg?zq1x-WHanK$R*m|>c; zDWSHS);@lC?)>1MJ$vrSWK3OgD7WPDVPWZuOC7~^eZzY-yZ5z_OppnF*7YNGc7YQR536*Fg7|hF)J`K zIxsM}cUt8D000?uMObuGZ)S9NVRB^vcXxL#X>MzCV_|S*E^l&Yo9;Xs00000NkvXX Hu0mjf&!0hG diff --git a/files/opencs/added.png b/files/opencs/added.png index aff7e25d460be771eb1c93bf556bedce44a06f0f..ddd9c2108e92610ec92b88676e5e4c172e19944d 100644 GIT binary patch delta 566 zcmV-60?GZ}2ImAJiBL{Q4GJ0x0000DNk~Le0000W0000W2nGNE0CReJ^pPPN3kf;^ z00}w)@MMxokwzzf0pv+UK~z|U?U%7?+fWpSzvEtNr#OTNLNFAP&7A^yflL{@BtxKm zjTVw6Q>I82O3-A=;PCxvkaM)NN;B0yDDL{i{HRhQDq?M5KvE7oMDp$-6$s*mSC0l~hlfQYmb+yDRo07*qoM6N<$ Ef`*;_F#rGn delta 815 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 KMNUMnLSTYa`Bd8g literal 0 HcmV?d00001 diff --git a/files/opencs/book.png b/files/opencs/book.png old mode 100755 new mode 100644 index 3afa9e8aae15c8d494e6e6e338890baffde4cec7..9d7669bd7ece44b51116176d9f15151a02fc234f GIT binary patch delta 1567 zcmV+)2H^R)3cn1HBnkm@Qb$4nuFf3kks%X*32;bRa{vGf5&!@T5&_cPe*6Fc02*{f zSaefwW^{L9a%BKeVQFr3E>1;MAa*k@H7+qQF!XYv000H9NklNEpH#62TzIBtw{opb-H^PlCjLdhmK88JGc${hl=nv| zR%!CiBz7+Y@+y_v$X*zPN=q&lm9O>2#5%+J7L8DIlBny@x6TO=&m_r{OSE^Jh?jw>f3p~ z8e(tvWk#X&VQ0pBOol(WIf{aR{4`8m>RRo&v2g0!cD54Ue*0KPP6SMkb{k!Gs-6b8 zcjF?Ct5Y#K(y^&s8_T{n^A+FL=5k1U-B~6q!ke8k5M*WAR|byud@cOWwIOJ7RTv*` zUpFhpz^QLbQyCG!Cj!DH?8YF*z;DhD;%H7X#)eu~kEpTmTXTar-&hKNv5y_JmaAw*&-K<>p3 z^)>6)>sA9tdrr$vGpF!>nb8j9q{U;fr+IbB7z>{r??io70TJNBGQn~YJJ@r^Wcc(* z8?sVkaiP0Ozu`=QU%u3iy2|4adQkx~5j)V;sNd~|j+&v&DSTq61(~WC^mjIx44=B# ziqqxCAP^A&fifZ6-%)Qed~EO>(vuIPucK~ty{;@7Lp`TurKn%C@;#ve$W2}(3@!^yhxKl z?`#~2iNL9XEHsj1L#=^KZ)I^VlHv}+&Xxzhs}oX>MB&tlEL4}|qw1uZyw8IsCj~K) z3cX-WUJBO2zwNF^Dfzu#fHcU1r8g5T`}9aV)MUMe5wM1T?D;cfSu|CjSO>2snb(zT zP+N8kiLpvjg+r(*&0hzvD9S@cQ7+00b5M372kA*M2=o(^nTbYMOC<(6YEe>mMu{d1naQyT_Lu0}DfHmO+0|~D*~90)_YgS2 zN6Lp#>`Xoq+#v9Fgu9m=L;())le<6|Vh1j5hKKJSxC(4x?`jPfzAfDM+r!1p4*Y$8d*S4?8(f~*dxpEyLbunQtKIF) z(e2@LwA6SGmh(J&%Xw?N?Ta?#xzl$0DA(Ge(~4)&w9Cmdof`SD+`rar>@Cu%advKN z+F@nh$+g}#YQ@_&&#^XN=Q RU;qFL002ovPDHLkV1f;u@GAfS delta 1317 zcmV+=1={+*47duAB!2{FK}|sb0I`n?{9y$E0004VQb$4nuFf3k0000WV@Og>004R> z004l5008;`004mK004C`008P>0026e000+ooVrmw00006VoOIv00000008+zyMF)x z010qNS#tmY4f_B94f_ELcQu;;00an0L_t(o!|hgWOj}hLet&N7rKLcjv_M+j_^44n zG6xKXGjUK*V$fI%V=arr#F)&nOfvtNX(E}Lz>>u*j;Oe}O|y`U#F#82^UwY*Qxk)Y zVpJFmjmQ97TxqGLrRVj>y=`wl2QFz$-23OA^PH3Syzlco=iUq4kN-mS8d1n6C()a1KDad+<&cN{PQbV zS#aUtt1sfh>2rVru)bi0a^9$GrZs6um)7ahq7?zfn;JE%B3JVIVPP{Yl z*1z_^@i$%{I`-PJ+4V|mGG{45ex+U zpM3mj-GAuC(Wxyl&}Hi?u-R-cGa?WOL|8pKF@Pw-2+44Y!$E|-t$RBx7R$~}7jU%y=+jTO zw;doz4hJHghM$bYYZsk|*AsC~exAzO{oF{hvw!$_z-%_F_uKY;QC3=39PTXIQEbO@ z95RMj!ajmduiLII)Xsi=4j-!Tc($WoPFt!ZEHY;?v@=TX3AuNQiu8JOyZLN_1UqVK z-pk3&QOaqHUO~u`rN%|3l6!*5x}kV~I%6ZSQ`n@5n1}3RzhS@yf9z^u{KM z^++s3iQbVLR>TAa*XZ-EU*H=W8iXT#hktLFOeRfKd&rCwy;?|uQyd=uvWhSeCx^CB zTR3-XZc!*HG469ZS2PpfPC&8|q)$2ksTgS%=|nPHWX!@>4dQ;1#!@0NhnO8im|yr~ z)#Gu076=Bl!m20GQe9OIgTa7IMV7b^rhXC3HntbYx+4WjbwdWNBu305UK! zGc7PREiyJ#F*iCgH##yfD=;!TFfcirw8{Vg02y>eSaefwW^{L9a%BK_cOG{xX>MzC bV_|S*E^l&Yo9;Xs00000NkvXXu0mjf%~V>i diff --git a/files/opencs/cell.png b/files/opencs/cell.png new file mode 100644 index 0000000000000000000000000000000000000000..c4f00c1f073664f0663ec388f129eec4454b629e GIT binary patch literal 1403 zcmV->1%&#EP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv000E)Nkl7ip7{|GL!GmU5b~|71 zeC^K8$L{QOXFp3zmqMYiu=Go@g;L`@FOuHDjH)v=)sFe z4hB6m#xy35AsiGnXkz}(3@&!t?Z=h_G2t+mndfqGJ|?%3PQ$c7~+MY{LSG$>qfDB1nq+aBecO$Ys8j zhcqNXPVhMQWj`iA?ZWYEotXGw3--K{fnMNmc-He7azz`{pdHr0#o5p2i&%6E{!N}u zy_N#sO75^aoAZ*r_f}E-UM4MfMIV4h?^7bvI&0=rj2Y((*eg?5AxECxZ66uQsHQLWsAZ<|uF zX;OjMN|3pf0Xx8gHmET2Dr#y4{ zt9^*INxpJ^nD>+EWD|Cs*8Ohpsl?H2hLMgvj(mxreAZY1SBeCY(Fn{b^DewIh(LP) z0Xu-O7@DbyxF;ZAlGSXNJnO^LqQA$=VdcN%VgPJ{!md-g-*ARbA*qJYF)S{CZ#t#G z=;k5h8E_T_AszzJ*Mru=po}n@pmR$B#V)^Qs{U#2GyjIQ38kx>yaOnuwznd2%b4A!7jVUG`b!}BnZtF zpgipsw~qzsWWW&mSAVi43c_@AQM@^LE{XAvGB|WKjf3yoXfHAt&>lgCf2{5~pWATr zEBD~3aS_Qw0^$dGzj6;QmKd-)eUnk>Y2SglN5bxuD)v^%={u9~$7|=Hh;51D!mH`jKxkASxr_cE#vUXg%mkkQIlj5gkBA6NVdw-j7|fI4xd~a z+>n53usez?Y7234qjJqr^D2+;;UT(U!CD!3RRXF>(JWVq<~XN$NQ5~kK(bj!Y-a23 z@pAu+%l;ECwSa816)Ckk@O?S3Tvd&Hzb^+G0WB8$P{0Fs;2$t|&*3H>@<{*y002ov JPDHLkV1m1kiJ|}i literal 0 HcmV?d00001 diff --git a/files/opencs/class.png b/files/opencs/class.png new file mode 100644 index 0000000000000000000000000000000000000000..316380363ae0a1039bbd8810b2a100099503446c GIT binary patch literal 2283 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv000PDNklh8OL{=Oonk%Cu3ta z&NQ7g9>@*LF1yQKz}^=N?807LdvL3}$gw~WSP)zg1QZkm!sS6~L@-H}ai|c}z{Do8 zwpeY^G#;&!F;#0@J8_(Uzx@(+LX=8OX1X)q%sb!l{Ql4JKF_-p0F?jd^~~^Jy!P6Q zB9Yo7j8l2M>t}W1dkK(96GH`j$%s@Ee_?blQvuot^KXyL$p19q*#G^*DCzI*Nvd!*II?QCivokx=u1&yy>bD`Hs! zydhS|b$9#vCYOX)R`$Z>+K-~5y@+Ou?k+bi%Mu_K#rHMT_oJ!lFbw)^7!BEQIz2wm zv$D1$US)zzmIAxI270{%^hjRca-y&-0YuLKk}2?hn69JFU!Qr7$a@YlOqsa*z6V9y zoP=Wl@f>f~=cBhShg^GqMTHK0+Np;$MglfVhVh=~pq5bQ|Cfj*1sD@vxj1+FdCb1| zQ^;jnBxq7`d$JClwFRgww8LT3W87oHvHBEjvFK1%kdFOTHvG0d2`r`vv4Q{^Up_%@L`t?%ZBn)h}8X<~e1X~Y7q-5hnF9mAx%eR&# zz@n!Xo*Z0>3zMtCu z_BE_RjdLYrvDCuvig+vnMB&XoxI}@;E(CY)?XTe-cM;uw8!U|zfdL_4(-}BctMhq& zuv7wiSQs{L2tY8;?1Kl{#}JS@1d)t}BYP+i3#hYC72veLbmRUU1(LM1MR0b@-@t0R z4yJ1wQR>YI5063=lZ!|i6CojVgbOnfYCW_F9+-I)0cl6Th!tYEl>&|Qr5jHdkoEH~ zt4rvRYLX!#@-9wufmby8HN4>}qUtV#UOk7%%JZO=okK*)48jZFN7&Y1KM}skIE1j6 z1oZEsz!1Osu{v0k0<}`{Sw(p{jvqgcv9U3XjErDlU;qUL1z_`pU~K<*S#Y+l0@2Z2 zu%jZupoM`E5sbL#KnPd?knw3-z8wXh0JT#7kHNt~OiWBHf_HUwp{=bAwQe_Pw8*D= z&gO~8#Eu~iNUkB0PkF8O@p`q!c4M{vAsio>E-81yL*>~t02PEgD4@ z7EJLW5cAf9&s_JJMa5K56miT;UgLZA>_KyLGcn^Eh|`T5?d|Qv{BMH8;Xqzq9_%(7 z(utixkE9WmPk*f7qM}$ttxz#N?T3kzemF7ehcfZU^{Q3ambeOyZa>tP`Jvq5 z2R?f(VxxjCQSwveQ$vk8sCVda=Aaunwlug)^H5S!Lc)u4%}6uoaI~!mJF~?o)N`Oo z(2`BYyU!Q4n$etrI%f*HsxxqMa0k*&DHzyYhU}0HC>KVczqJzCnI??261Giz?8+6w zETK(N@=VgHe}B}Do2TnhQ|ZFo+#K==j~6`8&B?*Nd-sS*=fq@_4rg1m&}sDu(0BUa z81HF&wI&kP%tRDdMs~Ob_=cozL<(U%yxuA!Zk#B^Uyc>x%18mS6Qg0*urSlE z$0r>rB)rcN114XEP09Nf!Pjd#uuf7-G%E$(YqR6}IAP~)C(ie0!z5$ijr17&uFFJv z{!wcJ8m$}%8Jl?IHe6^3N#dxBe>k|AgkK)c#>F=+xX^9(!DpJ3NQ(8xuF6$V#fL&5 zqJu4r0V75TjvxYZWe`eoe*(RnM#ATh5O#*LFxQv42tHXSgMuC4JD~Ukn3e2MIWPSF z$3503!m||Nj}nBh-YLm>0X?1-WN+{BP|#IRL5G`yM%N114KF|y_xc@&LGWlPIN|yI zBwnEJ-_xR5V3aXJwL;qb4tp$yT{5!Zyx|f@ZMr6;`;#FP^Qi_Ak2)sgQD^0GYo??z zYo=nNsk3}Gb&SWN8ockwxM4gwC-hotfe6E;UOOUGnORVC1LwaDUzCDx4+sf6h?lQn zICIrBr|6qpE$4{+-FGCcAYR@#b{2B})N%YQpda$he*taD)yj+Zn<@YR002ovPDHLk FV1mysJKq2R literal 0 HcmV?d00001 diff --git a/files/opencs/clothing.png b/files/opencs/clothing.png old mode 100755 new mode 100644 diff --git a/files/opencs/container.png b/files/opencs/container.png old mode 100755 new mode 100644 diff --git a/files/opencs/creature.png b/files/opencs/creature.png old mode 100755 new mode 100644 diff --git a/files/opencs/dialogoue-info.png b/files/opencs/dialogoue-info.png new file mode 100644 index 0000000000000000000000000000000000000000..f6743d43c9766f95655d64d297f66cab4b054eb3 GIT binary patch literal 1851 zcmV-B2gLY^P)N2bPDNB8 zb~7$DE-^4L^m3s900y^7L_t(oN3B-}P*hhGT|^ym&=?g^x-m-EC{lF5N)W|{B4UA{ zpaw(5#L@7ZqC-1$<-&qJti8AvB z{__4i_nmw0xp#TIVf;u*NomW-Om#9gT6kf%gKe_6w?}nAz^V3-kkbeZ^y~5Q@oI5* zcM(`xu8-AFpY1bo;zWzlqeo8}#?j)pNJ>gd$;ryP+1gk?4G;eXRaFIOZmvXITOHoK zX+(Q_6Ispd@3yvjw6s*CzP=2Vm3iRv@8aaiW4#9Y3;vLnmR>UAK*o z5?;NkMrUU$dV2msS63T(uEWch&+y_!32JJJ@celmS@|r$nwnw~L^=C^U0o>zg2(vj z#{kTkqkWk$GGWL-MvWRJp`@tbeLmz&Z)g159h9~8W>fDiROM$m9wioCoevEYS;d=wNsVgcmkCF1bm{WJ)} zK0!>GJlQ@vIvgDx%>?`{5nIKe;FNYp{{v9wTR|m!E!=~SGTQs!oCD9#PeN|)L*(Q< zKvq@)EH|yIA)5Gz1wqs<{gsPjOIuql-o5K(N*70aRaL$)=ks3mnp4H-E zfoEsmX92{=-@+#|RD)Om)8yp#2}(1V%4vxWmUB*UfnjH$>Yxv;W%Hm&SWy0U39jD> z6XtxNn{(h98GqvO<2ZPFx^|BnH%^7OdGm%?3f$e@F)VN@xWx`;P~X1fzy0*v{UfR%y@9%>FM_f3pXJvBjdp%u2$30(ZWhioZ3Z8jhf7-2aK`N zWecO-(9Q(%Nt>az+X!iC_n6@NgHzf?!PC-Wk&<#3dV2FCdFO)t-%^8VYN{Br&S|M_ zJ!XfQc7}*ayva)KP{0u=hOC6b#Z_?gKR9ggB}L)HaSxEDr^6dFW{mua^0gUZwT#}3>yccqpy(`D;Th`WM(EnjrjgD z$2DT>JSpimRK764lu$Ehn&}}S;T9{k{x^U4FcKu~FUO7@Db)hr{Jbe>!A>_7ACf<#nw5cUEM+-Q%Fh59yWrhjXC1tt~0fBv{P{RBL})kGcx&4 zMj#oQgnOmI3D2B6QP4o3y|!v#O~x%LJ_d}g~8b8MDC z(?pkjCJKJ&kaIU_eAZ%Tg1vj}Dr#$sSt>;P`C#5Yl-jA_sN%O+S=5u8FCBC$vbVP> zudXg)<5Y2R>VRseEmd5d4*f~Um zU%>BILlGJp06$+Z>~pezv)Fi19O-iIq{e3r8<^WDD=Tx9dV51dIa51V=Web}P2{_Q z+P?#g6rpoA>E-$p$jD8WF?pU#mV$(Y#HbO2ioQS&RVDNMJ33}l2B_Mp$dnWnPrui} zBY9a}ZT6+)ndd^~PFmioJaKJoW75?{(-%U#4TT zudi1Z)j&kVMasbNl{``~ar;SsaK3aYh*#1*9np&) pa`VSTfaEJ%73~!t@?7q$e*k>p?a4!+b>RR2002ovPDHLkV1mjZY+(QZ literal 0 HcmV?d00001 diff --git a/files/opencs/dialogoue-journal.png b/files/opencs/dialogoue-journal.png new file mode 100644 index 0000000000000000000000000000000000000000..b6a95c53848b787d5e857c1f8c3a38238e2518e6 GIT binary patch literal 1991 zcmV;&2RQhNP)N2bPDNB8 zb~7$DE-^4L^m3s900%=!L_t(oN3B;2P?XmhT~V3EA(pZ)c9-R`AS{ALC4eZ18j25$ zAP+^FSG)0rC=o+cY;hn-#W7)qh^BG0c4BLVNmFZs5{r#d9wIMAP*_lqS3m_M3Kqeh ze)l#%*+mekGV>4YaQ}PGJ>R+C`Bo%)h93(H3lEu08sqQhduYu&Z{{Z_?`TR(`{==e z10UnlPxtii-ksFBZCjinA|fQmP3N+E^5n@YCQO(hd4{b=UNV0CcngJG9{=VWQ8zL( z|A5BEtLW%xKzDa5?%%(I2M_Mj)4~7l?ruY8XA|1mYSGYe1$lX=@ZpC$2YkF=`Mag1 zWx$w;Oqw*wCwg^6b$R)D+`HF=-rg?s_x~FYA9mB{R@}aQ6W@PdjppVm+`4szo(fK| zx%oPgsN?@{ZLNX9a0#FPJ`K~SdmJT2UK*8%nVH!*jjcNQvjd+Dbagf2(W71he#lSQ z-fo~xuc4)-ihwH7)O3}DH#A&EeSJA@-Yi31T?uMyi#f2tP)wvM`BPZ<4OWCMyGd$z zj!1&Q$GcB;`%_-tX_B=a0|Wi|;Rgm>L#L{SkFyrb0#!&{C&hv}wpik+L4>O#!d)E@ z=Hh_)(=`a1t3phK6mvb*sII<ZU)}j zd20}yojgjXMcQwza4g*t(SB-VcxaIBZi}?3w%F^YMygJQ=-EpAZLc}jhDry)D=YJG z_38yq;L4TnkdUy6k(g~lLSk*L&(6+7PfrJdKO(c$n}9RfSLqy~kCG39Cj=<5X{iDm z7b~zKNP%^M3anWu$KqKk1pC==Kmoj>;yf;2K8N!1Z&6x$77^jgo5>SD<0Q!KmhZ-G z=axe1z>Ev7em55%T#Fw9lQI#dahHwd@{T0~aq{RFgs$s#) z%KpU(kez{-l;lDHFDm+mRQN08GT9Chb+zW6o=$$%nA=CX zY7yl0SBZdNI0l~LqC{+{1cwvFc-Ke9!Q-`Z1Zp)V;7oR7@QW97P*89RUS6|Ki1ugf zeZ(5f-MjTqz31VKfYzS7T>#%TMTwZ#B=|f*j7{D$4j$(yqjef?xS_JMlMCSa`Pm3r zzNDBD=>M1u5KG1hxZIrs*9 zDdszBxZ9rwe&NDD;N$IiQnWfMJh!9c7Vg}s=k0YkaMoT|I8(PH0>`mAXT3d?2n0CV;eBT%f_-fe;$y>W zu3u!0;5l-yYb1-ojU<4`)zY`bJ-vP7Q@p#+_MS_a>xgjJXV?P?BqhKEhhq-S6X4$Tb5Wn zo$mjSh7)9G;DI^?b}lu?vY8To&xgv+z_-1>xsSpq@QFku66U}D)h`>Ho3BwnFqnX| zV410Pz&uYCUJsPQ+e3{xIyHAYGaReAr?VP9Q&k*%#uW9i;P1T`+eg6{HR4RLZtdIk zEiKo1DU9=cxKtCG%xG?BhGULjwQ@xpoqYaNry{-njk>0$Dn3qKzh3x6q_X~Q+~J0T z4`;ZHeW{o=^X0Fp=F(9|GRo=VhK362h}HiWIIBA|-09QDk&?U}ety2+Sy@?yj0!9) zm_6I;L~U&eFM+Y_Wo6%j#_>DhVXsy0OpG7M$k>A~zSxhf%tQFgv4c2xFb#WBldv&H ze}A6;oHLYi+vtu@d1hc?p8oxlBI?z1-n2p&?0hZ^i&Kg_WkDqJfvAnEvbvcrse~P+b2{+uy zlYa))arIdCc&@c1rFB$PSc@>l9zFUQ>)8vRYtym5%*N)_)TD=OrpwAY%oKQbCyy0u zr1g{!u}6;V!`ZW6F#>TfYTq&Kqf#k%rKkVyKhvhU9~;w)FLLqE$$<2gt&wHLi`-Y( Z>%YE4D0;;cY#smr002ovPDHLkV1jGJ%=rKS literal 0 HcmV?d00001 diff --git a/files/opencs/dialogoue-regular.png b/files/opencs/dialogoue-regular.png new file mode 100644 index 0000000000000000000000000000000000000000..f9b8d252d368f16aad97beabd89aee50a53a6760 GIT binary patch literal 1486 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 Vb_lquM&tkh002ovPDHLkV1n32&YS=M literal 0 HcmV?d00001 diff --git a/files/opencs/dialogue-speech.png b/files/opencs/dialogue-speech.png new file mode 100644 index 0000000000000000000000000000000000000000..11eb9f1ca8163670aab67bb916490c145ccf9340 GIT binary patch literal 1987 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 literal 0 HcmV?d00001 diff --git a/files/opencs/globvar.png b/files/opencs/globvar.png new file mode 100644 index 0000000000000000000000000000000000000000..646145f0f44a1f5c5f3546f19697773543c102a7 GIT binary patch literal 2394 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 Tq^~E300000NkvXXu0mjf43Bmj literal 0 HcmV?d00001 diff --git a/files/opencs/leveled-creature.png b/files/opencs/leveled-creature.png old mode 100755 new mode 100644 diff --git a/files/opencs/light.png b/files/opencs/light.png old mode 100755 new mode 100644 index c606fcd98737296fdd6d642e343e95f50108ca58..2765ef1d33d8507c67d64e913e19fcc629c12325 GIT binary patch delta 1174 zcmV;H1Zn&01+NK^85ITq0047(dh`GQ00DDSM?wIu&K&8HArpTIa7bBm000XT000XT z0n*)m`~Uy|8gxZibW?9;ba!ELWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900bUML_t(o zN4=L{OjB1J#~b3Si@qTEL0q@z$uZTVCFSP)TRQ^y7b7&0LI8Q|zp z7?4|{Y+?{m1R;Mi0Yy-dKSRNV4laX%OASUt7T>-*w~2k&mXI~ec{mR@x#xU7-}5`? zo^yEsc-FSqSo=Y)S=*oMXEi)pZZEB=+55J-eD7O%guT>S39ALPN&Adj8#XX4*dQTh zpOLCSy3W?EwsH@)XLxu$!b4;Jdq|eqx>+M()eNX&?eu@YKHi0mdLA~<^Dy7G3yP2J z^wb1oVf&f&ejBW3^YBv6!*Zz&!X^6|Y6590TeqVjcCRk_?Z)?RyAkJQx0NWRSb}#+ z`3?>`u33}(T_3B~fL5bKdviTn^wntowh}E3RnRD-$(aBBn_`s!2j4a=;nnZYU}ER6 zX`DuVMKOOp0Yg(AOe?cknHk2?mZpcz$vOCgzN`53L>fH- zeRU}o9}ijJ!#A%WJ0pdjz=g`MF#mACoScK-?J|Ghluk=epsu_KGo!aH@cyf<$VyA3 zCs6Zs0VYZPx#S%D)|Dn4Pl=}|P+5|P@qsQ2{JP;gq-)jm1S*PhasPIwIXMUKY`K7A zi7I*mWd-MOucyNT@3{00Qsb5M1kUH3!C+UrIXMS6=qr(|R?rhD&dnk9Z?nK#>&uWB zNAZ6+E36ulY9Cr9sfL!$+*uPB5%Mn+HIOLFvHYi%$m=iqgv zc~HqC{~rNGl(;A|RK##CB1FW52aA}nAR!ZaM972$3Yp*lCq@-5B_AFcQZymZ9t}c* z@(4l$-68dLWc+;ujK8;l@$(Wez7hfB(#ygm4g*C9T6<`@0_#QevVEH%OP#h)9+ z*j_Kh>(zX0E$8B;@htxMB?lV|C$aW46RUGNEYGB3X(|cNAH|b$v7>-S>3n1L=K{R>tppp3YOKwxurjM8uo!XO84T7sBO(TG^BTEr&C3EB8qA*)t6u`0PEtBi7F6*5OQIzqrk oh4WciD4!+CjUMg}|N0007YG|xzM3qDoB#j-07*qoM6N<$g38At`Tzg` literal 747 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyacIC_6YK2V5m}KU}$JzVE6?TYIwoGP-?)y@G60U!Dss^Zy@@{=eG)|JtPgpN{?i`||&{Q~#eY{CBJ7|LwZ} zua^D)aqs`vz5gHd{(n~T_io|;`xE~Ec<}%0zW)z8{y#4Gdq4mGz3%^iU;O`e`v1e; z|Bnj(-pl)czyJULSO0%J`Tuy{zh||7AJzVUwBY}3^IumT9v^aeeWC8n#imCG?S5aj zJ-x>0?+w?#H{Ji<^!Rfp`tQS{zt8*sKgj$0v}xZ${T;K-ch0f=ddcJ5M%%L+tpD7O z{QDs9&y(iA4@>_(p8)hudYNSnkg_TX@(X5QU>38oW6=uPxhYsKaPr4D-TE2({{G#q zmwxo$-y_ogoBsaYz^qpD`*#)d^vi$$UXJ(@7Z*6~)^k4TvPuR!pec+=-tI089jvk* zKn`btM`STDW`2V(BX_y!Y@pyAPZ!4!i_>pUxk@z!NVGoW){sbOU}Rg+#K;!wwfVoP zWx#mQ{&{c%6UuqIPNT3vuaa; z;exzbyO?Ev2v^uYXk_^5D8XiTNaSeYmAHKYp$6@oi!yY9?o=&tjVMV;EJ?LWE=mPb z3`Pcq#<~Wkx<+OphUQjAKxCwCU}R-ra6eKu9z{cLeoAIqC2kGtSe8BpYLEok5S*V@ pQl40p%1~Zju9umYU7Va)kgAtols@~NjTBH3gQu&X%Q~loCIGkaSGE8E diff --git a/files/opencs/lockpick.png b/files/opencs/lockpick.png old mode 100755 new mode 100644 diff --git a/files/opencs/magic-effect.png b/files/opencs/magic-effect.png new file mode 100644 index 0000000000000000000000000000000000000000..e672ffccb3bc9f8203a7a0ebf8954ab17b5ffbf9 GIT binary patch literal 1702 zcmZ8ic~}x=7^gXPNw_VK%L#WbBqAs(P&9!&^DO>AYJX|*W~@1<#L z&C!-tT$8_xnA+-}^pa&Itqzq@<|?002O6 z4_7}~)cwo8P>^|CN{Uz(w&DC>&HzUL-g#N_c{J1;3INm>0;S>dvV8klk6;`C0NnYP zZ5x_Om&y(`@oqu*lZjDyVt5h;a3UO=fQKO5{B;TD5KG7rQ&VwL6#$^126u(}2f^r+ z^IoGE)kmAP^id}&=oA~>b`29zLpAX+1@~fN3?~9nha>9=?rK*{OC1feS^k z>%wO7xm8{um)@%p7!&E&UAX~ z6wx=K=m0aeeahppLkp-kVlUA$h69Um8H{830-1$9vdoKIrpXPOj)YI*wEC$wn zU?NfTU78@f%i!uOa&Ti-1SXFPh; zw0vfNpv%ac_L93+s5RV+&#+HJu?yi$4L$Ae4VLUNyB&`tg>`gZ$WsW3`NhG;F5B zP42M8pw+p!rD5i<{yifvXrWSI<}jJEuAoA2$g>bqB74r|+x(kC>~we&MeK^OXy3 z4^$JYEpTLOEmpQ?%Ww8{A^0|{kzK3v0ohH3hB|n>kBXy8vALiIj(8*lFS5oF zJj;ZkFFji}YRrX(xM_#Y44Li_&6uhjE6cjM6-`=}0jG~J{zIIl>5Ns$J{-&W=XL1% zZ0m9pe?#M=P8ANvhzc~y)4rs@=eZ>mvp0Jfc6o`t!ErgOt#W4tKV49##hknt;z$g0 z_3zIZzdi-oXnb}PB<$O7?q%J6hO-3o>mK*p94%Mw==@Iy881ZLgB6f77yrxG`Y??*QTg)Z(?NnJu8v%-VzlgAlqUcgbz| zbP=^>VVt(?<^1W0@KQHkzi$AzSCi~k%BhUtJNir8$z)>uu=+~p;E5eYDiy)Jkg)s9 zxogjW{2fz?tjTd&G0E4RKa_DG7ts;#8?7W0ZqBXe!i4;}R%JMaPI4J7weD^E|P&)ZsYZ6Hhl6ffGOrUfNQB)-05It;n!pw>5RJ_)UXo$rH}LqmmXCKcE?uZoI2I4`JOu6(@gi5lW~7P0-&JNe&M0`}?MzXb>{;=| oB_i_=g4g@-x5<4v2-u?2mQo5pLDlek**5}!yCGZ|&SBsE3EgiyE&u=k literal 0 HcmV?d00001 diff --git a/files/opencs/magicrabbit.png b/files/opencs/magicrabbit.png new file mode 100644 index 0000000000000000000000000000000000000000..d1d7c8270b2fec8dd98806f591bf5bf4aa70331d GIT binary patch literal 1820 zcmV+%2jlpOP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv000JyNklC^@s{=4Ko|d>FYoIl8d~R<2l~J9zLQu3x_n zoleIDl<%zqywTZ)2D$(h<>koJYFox`p0jFIOWCenc=6%|Dk>`YQIo1`(nGvi(UvX7 zVFFtU3;Fk`ch{|3XJi6KqmkS6#{KaKnM{Di*VosFlP6DN*Up`9WLQ;Ig=0sL;?}KO zNK&bOdhZork*&ze>Suv%-n<$4Yt}TX)oOiaW~N@F(KMD*Ypz_rjD-03zy3?4?_2@i zfPCO~XJ;pRdV28c)hiK$gM%0t7(iE77al%*h>ucJZv+FOs183dRAv= zXAiu7{TgLuWvH*O7lM2K{5k5*oDpq#_Usw*^YdT2xw=-nxw&ci-HFJ&L4d#%GMP+A z(c&$a_k;uoBPuEi2?+_PIduw$Xw=vf8fYp`pFWM++FJ3O*Y@w<4;ErbNC6_xn3x!ly`sOrA2b01kT%6< z#l^y$_&2X@Sic@kO-+bcv+1`-TrSACy0{EFIXOLba&%liV#O>NnU_~v zRAeMbPy#rPz{11B5fl^zsZPefvlRGhXJ;qY_-b!&4+jSa zy#-}pWblZHh!Jq^A-^*rN6nHQR&(p&Lvu4c_;M1p1hoz+@ z3Tgh?Y%2HcK{-tVS0yhm4?DJR$F{9oap1rK(3v1IWMB@?lnJ=IyN?2&GiMGQ?CrZO zNa=~B*gqMRGv_P!J}fLu2#9;g!n=3x9`^0qhpHn-(A(Q9=AK)@m3Z{%k+{Ei?_N|^ zRth&HqY`E3_qp%ItP>6ZwapTBRtN#&mbTp{40@#k* zAQ6J=q^#>GMtQ-wPMEoD?a-mhI;5#`5EGG%(4c4p_yuEuGK};=Gfkr6V6E_Yxw^Q+ zTe<);PbGY$!3dB?BSevcbGpj?6V*?CT&Q6xeq_;jA%I4fx08VqxP$((0%b6 zPV8<&b!jWU-u3`r7LhhK-p1~NX6)27VMq22lw|&b!eu{WL+TZ1BYJ-?a_u1Pq94};di+k-~h!DHO-gK=9xf;8}W1_g#7A}k(DA~O&hxg6@0 z?I>RTJqojHu|ZvfwV&vazw}#ZQ%*qj!6qtqDgu4t2{;rITSxG?kq!)Iw}1{MgG!}> zzrVk5MIK2O8hg42_1#|)jzA^p!Z(t7zmP>X;&iNbHW~(J|FE^OF`odP4~BSB{=dQb zfZ?-&3Gi&Q_;|kAY=&)iEcoo%vteUxZ9V~VNJDIF>`3Ns3(jsz_G>-?@&v=;#fwGR z-vxZej2Ub|<`eKF0{kKJuHe(AO=A}{pMZzEyKxbnfN#@tE<0z=;8Ukg^HL7Y3%_;y|tB9;zVD>eE)AGZZSMjInD?G0000< KMNUMnLSTXwuTk3o literal 0 HcmV?d00001 diff --git a/files/opencs/map.png b/files/opencs/map.png new file mode 100644 index 0000000000000000000000000000000000000000..3653797cca076d1ef7a1983d109e67e2fc4ab52c GIT binary patch literal 1477 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 delta 2113 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 literal 0 HcmV?d00001 diff --git a/files/opencs/random-item.png b/files/opencs/random-item.png new file mode 100644 index 0000000000000000000000000000000000000000..7b8e68e60543867519ed7518d0061c8a21be3b60 GIT binary patch literal 1698 zcmV;T23`4yP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv000INNklc2^rkbttJT4A zbfl385<)_Ngb+x=5)#8=2_T>#P(VZ~;BJvBt;L0cD6$q2M5z=gRZyxFMX0qbiW&mQ zCKgaD;B=mz@64PGArO)aF21XioZs_q&wIX)0DNT0`FzzXfvdny8mJamM@RaklK*Og zB-Y^}vL=6}s5LmyeMIibYcThn7QsV{={T_f#EO%59A?&w#>9(7Yl7!Zgy6xwjAT;axBOn;FII^b<^vHsa0LJ-mC}jaRxF1gJzhDoY=) zh=8qr!sdtf&f(wJ&3HS06aNfV((viAHX5EsWk%)eqBa*!erHh$NMs6c=V4v%MNABo zVq9B{(dUI2?km7h?*;fPg*r>%77Jh+E;3B^zOMSP9^Tu27Nr-G5bW>t$BGM}val+^ z=hF{IldTXD%=zFevzrSEu%C_9dj-Koi?iZuA={O9-cq?5q+KK@TC0=dhTb_ z@W*$*!=pPVabR!Ydxeajznln@0s_@;`FrBG&P)u{P_y1a&3y}oo)j+&?`%GShc`2E z;$R2_j_ejwB9;^&7IIoH<|I%NH{s3rBfRRbr|Nv3hPO3k;c$950@ZTxcs!_;o=A-K z$F1v!z`!3gW}vO%7|QeFp^)=CmU72M1$asM4XwAn$J8isxelt%)p~egUNYR>h2Zn~ zG@Q%jg2Um!-rgQgd@fFBMuCC1)*Zp!8;4MGE)F~nYh*DIMgpjsS2zBAoQk@gh7b3Z z8AQGm+|JGpwzjr#p>K+k1NzPz_6oXq*1+GD6JNel7niC}q4sBLPWq zDlM_sf$k!c4#&)SX>Ovv=1kfNoNe<3DyZ3C3VxL;!8V0JYb0QItWrz7-ITq~H<{v` zc!QcV@WLOWO~Na4b|J`j5dn!YO6};g+9kbxp~DrPjnmhhz@x+DxKXrcS$M^nC@4I* z#wCahl?@K{RxP?%7Q%_i6lBNH-A>@^*RMxTW`tSr^6VW5@a7wrfcntreDT*MYNh5G zY_-MU#AJT0NJW632wt8}Q2Dr^=F)C@&dI3FZ#YtOl6Dd~ftQ_%gqst))u;z#636ta z;;-?%vp~O6mx416mwR#t5_kIGY{qu8;U`kmM1X!x>&K9IbkuhF^wS5q^gcHSzHZ$* ztX;bnR#sNXKB8GR@{+7@sHEKK`TM}Yiv7F=`K7rD%fgAnk;obNnl)<>9qK`w44L!A z(oW#t?o~m+Vg0n^E+7xYuJ*dhf;~nnb>U(mX(y2r`0CZGk+pxDNqFATVDPqB8{Hd> z)-g$sL}=fcc|c>dQWttVNjr&rIXH=2$g?q8#U?K%B4@h@xrE!7nxI1QnHZDazEs-t zzX?G?mk07*qoM6N<$f?F6ad;kCd literal 0 HcmV?d00001 diff --git a/files/opencs/random.png b/files/opencs/random.png new file mode 100644 index 0000000000000000000000000000000000000000..2667630f5c27ba416a3810aab36cbf9d8e872b3c GIT binary patch literal 1892 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 delta 1733 zcmV;$20HoU3G59aiBL{Q4GJ0x0000DNk~Le0000m0000m2nGNE09OL}hmj!~3k}x* z01ejxLMWSfkwzzf25Ct|K~!jg<(f@wR8!|6pi2eqMl@0o z48(PJC28wMfHXoc6l7_fB75 z-+S}kOj{P-q-i>xIrslN_q==0J!cFd1Yw6^7zThS=ffU<_R6(og#Dah7!jaK{S<&{ zA;ff9lS@ZbD_c`QAuLEJ0K+h<025dSM1ef;Ct!tzP>!er9#Ow@z+K>87+Zk>l=xbp z0Z0K)0hfUvfa}0y(214!81MwptZZh0pMY^77Z^eaQSt}5#4%tk@D6YX5WpY6TS`O> zhy<_|0qT{119kzwD_g$-dz5qPgV+*6lm<}Zqre(qA8-#4anlrP;vBG7K}7u~R^lI0 zB6k53fT*jfvD?}m1|q2E*8p#8@vW(pxZTquT9Qfo#JkkQt}9{ld`gL&0K{_*4dUjZ zLt;Zylik)H<&b(*n1=>%gv~y?_{qLLA^Q8pL~pNu6Joc5odx0L`E`ke_~-CpA^Q78 z?#K~0h>|Pe`ViY5*aYwzZ~&-nO{Msvy&bcp$Zs74?&jGNBZ&c#>D;AAU;8^KqnA;zOj*!&Q4$PJ`nFASK>O5*ARvf zLLV$T=C>2V^CciG^|Bd8ybnYgIEh?|ybwZvMAUmDz*6Ml@@Bc>0pg~~*^Ulcl1Y%^ zXugn4h87PHU9yBzJ9e<4sR`s6qtA$?$Q%j{ptsD`!1B0hGThb{TD%)XOESqwM@MM! zc8Jf~+Ni6k0a&3l)&UVirLh=>u>^PwcosMYtY}FlIor`eyv&I~hLZ*=cif$vflN2v04@Tzgb)S20{;Sk0hfRyK>k7|!=}N(qKI-v+%zi|zwy{HEj|Z)2#hMN zQ=mdf<=}bXCU6EgG+z*vivRxFH7$NW@D*|wvV`r32S9C0Iph<568XgE9t6aMWzjlY zd>RM@|^8YjR#+ZVuP7-gv}Zv?6~_yVXTFAh8oYyi4{0CPT0 zX+2zWr!L?{WW~Z%8o~oON*|k%+gWTr#p~gKh#@zPEy(P+)(^tY#Vt&bC6$vzq6J_+wd?} zp-_?d3z-a+rX5zHK-=)J{`@WAXJnak%3hV2Mqbk{14jXCWOS5mLqnl|AzaETW#>*- zp}@AGAx1_=QKCNrepFfuFmt7xR+EhZp94MRK)4jPjshQ3Mi%QL{sUxTYaCS*0{7Bl z9dgfo9a&O0D=aNe11}-Zlt8J7i+Ej?y8&cfON$POD6&4fJqUzHaaZ4AtB~8XF7En5 zczFH<9u;c8@_L|^a1q~sjqMJLOpEK8eY(3sxQKrr_!1Y-7e|Q(M;v$t84i>9H#oA$ zGh|MyiJ1mRGqOCG1w>0SDJFV*h3M}WlYM=nHI>q~^2lDC?$UU-tpc=|;=t3$uqZ+} zT1;7BC$hHc*J9ETd(~=*mSj@g?&)!g--qnz b*VcbxKi86U^taRu00000NkvXXu0mjfXUG~7 diff --git a/files/opencs/repair.png b/files/opencs/repair.png old mode 100755 new mode 100644 diff --git a/files/opencs/resources.qrc b/files/opencs/resources.qrc index 56e25b2c1..eadcf9697 100644 --- a/files/opencs/resources.qrc +++ b/files/opencs/resources.qrc @@ -1,30 +1,61 @@ opencs.png - added.png - modified.png - removed.png - base.png activator.png - apparatus.png - armor.png - book.png - clothing.png - container.png - creature.png - door.png - ingredient.png - leveled-creature.png - leveled-item.png - light.png - lockpick.png - miscellaneous.png - npc.png - potion.png - probe.png - repair.png - static.png - weapon.png + added.png + apparatus.png + armor.png + attribute.png + base.png + birthsign.png + body-part.png + book.png + cell.png + class.png + clothing.png + container.png + creature.png + dialogoue-info.png + dialogoue-journal.png + dialogoue-regular.png + dialogue-greeting.png + dialogue-persuasion.png + dialogue-speech.png + door.png + enchantment.png + faction.png + filter.png + globvar.png + GMST.png + Info.png + ingredient.png + landpaint.png + land.png + LandTexture.png + leveled-creature.png + light.png + lockpick.png + magic-effect.png + magicrabbit.png + map.png + miscellaneous.png + modified.png + npc.png + PathGrid.png + potion.png + probe.png + race.png + random-item.png + random.png + removed.png + repair.png + script.png + skill.png + soundgen.png + sound.png + spell.png + static.png + weapon.png raster/startup/big/create-addon.png raster/startup/big/new-game.png raster/startup/big/edit-content.png diff --git a/files/opencs/script.png b/files/opencs/script.png new file mode 100644 index 0000000000000000000000000000000000000000..297da40210490e4345d2ef8adda136cc8a404db4 GIT binary patch literal 952 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 KMNUMnLSTXe=@Tgc literal 0 HcmV?d00001 diff --git a/files/opencs/soundgen.png b/files/opencs/soundgen.png new file mode 100644 index 0000000000000000000000000000000000000000..222fc4c7fe4b18f2a8db0b175c7fb173bc090d6f GIT binary patch literal 2149 zcmV-r2%7haP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv000NnNklb`O^YcG(-tW!XEhTz1ig<+7k$BL!K)eMF5~Dz3 z0>&6H700F~LzSr1+KHw!CDSoazwdOHE=W?0)BN$xIfprWe$V^9&-;EK8~~i3YANLM zEPsZX;BvX=UCf^hE*6XHDTj zJB~Xa_u<~Br}6j60bJ?di+G*t_QILN2@DMEkBo?zmWah;VG>E5%P0$9Of`C68{D}P z4)gD@zp((lZTTp*d1AC<1(ebt6c!e;@ae04Ed0xlj^fXkkKoq(hcP*H5TBF#1G_3= zOVVv}|2Bs>bs{S(3l$X=a5x+=8Vs~$W<(;<7%@{75hSq2#@u{!&o)p27~)`b&k77S zk^5l|CJ()Y>OvFN*^_Yj)b2&$pIzLK@eBL#$>3fXV-(-b6F}=Jm&vw^f`Vp925yr3 zC&WZZOiYB?Y=%;yfJv`KhRurXq*w8HWEmcRxD0pSTMk_3V6bB)1`coe-pJkISKety zyk154{~iBq8xj$x-CBhX38_#h{8S;8Jd8K$5FHf>;%bmGK^7*0IK&T185fTymtnAb zB?{7||1)w5Kend|nX8RZikQ4P6FP^8eSwf>vobEuY$e7z$PmiTCx)iQ)|y`DHZN_L#OrW3h$m7;mIN!{Mp zS&x5y@d3WRaTbq0dmDcpKZWi_8%B?73ODSj}p*)~=`Rhb`q9NKl4C&i97c$Fq^$4V`m(l`HjbS*THpga6jJrHp*c zfUd?0eDY2w>-Mf4R^+dd%)v+dcVkce2H33zWUVnFldP147&KI`V{2}=>TslEBl%7Y zqDTgIs>M+Ga!TJto#?Ke$j<@6Oo>uI5qX3(VGf|jrMQN@L1zE`` zFGxj}Ee?*}ayZl1<0Vrria^45#Mjk0^R^vocG*TnOSa^=jh*qt1F72+!-3{kTJB4cn-m^M^ck;Y8TuLc4 z4FC3x;xwF1(V{moimkaVMh=}KWJz$E_AnpMuOs-L+UGu$(jRCUe(~mL>9<4avGWX9 zL)wlS?)xI&stQCL<1;Ju@f@RRf96EAl;~aWXoUP?9m9W6N*w(|HK%Sbm-|B}+gQ}(=w b7mD~dG%8@IxwiGh00000NkvXXu0mjfleqwj literal 0 HcmV?d00001 diff --git a/files/opencs/spell.png b/files/opencs/spell.png new file mode 100644 index 0000000000000000000000000000000000000000..69c8971805c431bdf29c4db04ab9feffdd358e2b GIT binary patch literal 2071 zcmV+y2Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv000MuNkljp1N8(PCpQM{Oxot<gHDtkis{dz%jzz zNFkcfY z4}?|#wc?dX@iM$aZyfE-3|Go^fltWN8$@4F5DD1RB0k%lZb<>hXjbCE?$j1SD*(B# z-i)eH2U0Feu7>bq4yw)nM$}JX@-GZE#KG)enMC-ox|D^wka;n4w1LnHAk)j>F6t@B zBlKpZUM#uPhb6z=_8KrqmJbu%(?A69*>|(T4T@CxO9{~Zd-QeE&}jIOHAlD|jE@(H5viM}S+-qMAe!LA_6pl-P=ED6B3 zHLABVH<^=hnK|3N4acA)w|_(-FHRpL*MFul{*h>kXhd@)JdV+{s+PdDkT!K^sq1Db zEqeqTEY|)I&tuL>+}NEX4aAfHpoeJSf056U&uJn$8+{Zwn~ditl?*jNuAlxWeGEh! zp9QfjK!E+~W>vNh9M&0sqpBp4b&@5YYtCF%t&ew#4ba#5b6|-4ev3lbRu*uPd_ScD zh<0VR5dhu`14uTLma3*;ZL#*DdH}VPvyNlqkd-^`y5*v8Qv&LBZ4u*Of*YrFpe!RT zO3#Ut6p8}%`bi!A_)-8eH|8)Z$hrILtJB(%xeD)@`2)M!F&}mmKUgN<``<+2<6n9p z(aBhop>rfd#~2{S2;-29EKvu`9ziap)!~Nu3n+eEzGd#+E4>Q6F(tRAn7)Ig!s+ycnIh>_Pko-)5c ztw*`eo4Ay+5|h7YAk3YG$vq6jxG=k)8({y=Z6{0wD<{1xW-q+|sq4>K@X$$&CS7tt=vaIFCn!@O-ILboq#cE!!!|EwAFch2KP zo-b}^kg2E8WMMzo2wz#o;;WTD>a^35)8;2A3xt@h1)9ix(E>c^JBNn@9hmDoi+}eV!_;R75$f@V24WxCxSD}vD^pz1v0pGh%&>sO z&=eme{{lEl?kQ&=g=aXC=x%7UEWn=3&>;+dfJb*P<39r*V(#`?47OJyD^`e8RS6jF zD8q2O0wrO#Xq3LLK8ndI1{7R2Qq~zG)yxFx95x0O1dv2dzpjNlv&KaZnn(1L`ZXC! zL{AMRsx(77G~d^R_v>>pbMpuu^c=#!x@+;x<$d^5MLgnyd3g8Wc8p(Epra-d*?w<8 zPFj*SQsomBXjBuX2N}=kQIxy!&BqTRAD0d8JV)!XXy45bgsvMpv!pK5jk|*<1RU$6 zg|}jPddSdh?{Ub}f)~u`v`=2&kAHMkV&ZB!>Iy?qm>@)NOE&Ib+Kv9RxkwALpU?C) z>rUNjdR^>l-W4fyDkssIKHk{h!&c7Qyzb!_r}B^!CBSLLHjKQ#2h}?SvpfgOPdPRg z>bEDVBuz5Zdrpqi2a?p0FE*zm|E{AH1Lt?5HZK?jao(uO5#dT*Jp8zJGY7JR?Loe6a-mEoo@X^MQw*ML$)X5;XMfl`3_? zJ(>2$k^evQ4Xidk!nN;LNa3Krepj9r$=SL!Ot04-1JsyFY6i=iDJK{@D%v3$dRE#Oo8Nmk2VX0*7R>+Nl8mO^BHU?`q3;i| z3+Cw(4h|;spe)*|Hs2TLf-p~;2|pL>F21AXQ{6$uOSX(%X~;rVwgk;(F}T%QpgwbL z%==F!s?F)h8}fz72yuqY-vQ@Je32652oHP9sjbe|e-=1dEmZyD)}+!Sy%S0G^5_co z-{R=L&EK^#CeW=nBZ5D^H^pzE;1);Tbtn>tvV_PCbw!5M1?35(CgQn>^R*uh;@WhJ zJT@#jf*0Cwxk*KX#fx0)d_6V|7slNs80GnkN7N002ovPDHLkV1lGv B*sA~l literal 0 HcmV?d00001 diff --git a/files/opencs/static.png b/files/opencs/static.png old mode 100755 new mode 100644 index b53be12d9a8abad9272fdd7c6a75b1d3a6a494ba..aedf2d30eeed220acb1c5eb82b457f29354ed124 GIT binary patch delta 1262 zcmV1;MAa*k@H7+qQF!XYv000DlNkloADTs|mAvH#$F&d3VqcIwd(fBWXFzH`^ z;9=qk&)c<-lblRuK8S(L!^(tj_-5_B*FJ0SqeMit6Ky4D;%Xt2d9jhp>2+W!mD;_V z&F(zu>e7#aH-WWGMy~?P>GU4nNTu{pELMMn&xb@ZsUIW~`aWkF}% zo+mmx^<7{t8r{R}KFX2EUy9^^o;@pne*n+ZY1!`Wm0wSvmS2FMPo0vVfFE-?`5~K? z?}6{Sy5tr7{Y@q#Ujtv^oiBkeQYrZy_$--}Pk{=aeVjG5nSj`MZ(Ge*rwrW;Mxwe*?CV z!TSiHRpumT<_w@!<|Jq4WB9FBnUnk-V3Gk;lF9lVRA3GP5VcE}WESP0LFuP~3P`6e zT-Yl+iHW&$=j3HPzrBwM1a%AFv+T^Axnw2DK_D5_Mbig^L$u3VIsNN1eYCBm+sce+h_2P z^Drp-yOXyU5zs-JGYDpXzT)@GGSKJs?kY|-r@^v{s8?_@4jL?tCeuuFR>zRP?(@m8 z->(%%s?%UuK?#>(#Rm02c`}%hwR$D$0EnXPgab z>us`r==I72;GV}LgI=#z++xfkah!UyzW(8~(&rea?h4zoxcrr|1F%@KgDIm>Ryr%s%Z9ut6l zTlqgjrCGy`VgDNip{==1K8XMd9UWSYgu^d*SDT4MG;bDGfp%P72+nGjrK~1%lmvg*WB)19yNA58}2&5vNLm%pLe3o>!~g&Q delta 1500 zcmV<21ta>A3hoP#B!2{FK}|sb0I`n?{9y$E0004VQb$4nuFf3k0000WV@Og>004R> z004l5008;`004mK004C`008P>0026e000+ooVrmw00006VoOIv00000008+zyMF)x z010qNS#tmY4f_B94f_ELcQu;;00h2CL_t(o!|hhjZ_`K={(ojXaoadfaZ%b7wWv@v zqC!Z(1%W8)ffK##UxW6-Wp68S=dyPWfH-nN2&o*P2o(VmAP`hE6$?qzpRwb_es2$n zCyo<`?s<2l(TvB>&+pCq=9^Fav9!d@3_6^L8=p6tMGZ=t$9)BCI2lgNU&6 z@}&+gX`>tmnL>egU%wVYqhwYq#z(70y9He7KCXE ze|wuX1`a=bkehe!c0tnaBFb=NdKwc~u5kIm1Cg)+06_r2jKYl@yz}Z68b5yY)Et0} zaAKc5i%hXdmB){D=~Ym#BdFI?w_3R_!d8nz*A@CS3@8t^S_nN4q35Og3Oo<8(Lm5> zXg?B(T7Mq3c1Hmn2F*K1GFn&JQVF?INq-z|X_Tc|EJE3~u;%BHdY%DfY#Z6RImodw zy-tbX#%5<>7K<32nbB+F=Hem)T_SOomQerl1#Y?AmsK>MSY8GP0aaI5We-usY}EKT z@)s^p<;fEnB^CD*1*Z<)zwg<`?3pt-`1nx=Fn<7e7@3(t7=}3b{J94cacrn#$1r;O zH0m20=|>qcA{s;($$7l?$yyG=Mo-o$7*oo&dyIr>!pP-d(D?aN+o9tt z;)hJ303(+Z&ZSFj-eHFLeR(;Ivs(WAdEr+o?3T+tY)7%VRVoPzLq7QQDQ+XElO6$3 z`8-BvXR-U{O^*WVTy$E6scH-m48X|ev9rD|ysfSDZO&vsLBKmNUL<)$15k~RV}HW3 zXm5R84)CGvWFLueKN1E3?nsyzLRL|eN4e#Gh32&OD>=ph#Gkirg^fxD+#wL5ln9$m ztyqkF9xMd>TCJTq5nvdCnGv>H-CE}J%wdS;-k#9JlgWsn+2lAm38mog?R8bLyRjj+ z9zH|_9>iW|ipcX2cwX24pxdr*jH#x73%EW^ zBo&c8KTo;&`EK?x)dRGNXw-3FpE^Z-;ESDxF~>nTH^-)Bi9x|JfZWNG$bS?H+}zxx zNOg(7?%er}V-%?!N6*ZVrYT#E1|d$%vG)KV45KaQiF$+UFkWm&G!YFuLI1b^PWuNL z>S^MF3P{KR001R)MObuXVRU6WV{&C-bY%cCFflVNFf%PPF;p=yIxsdmH90FVGCD9Y z`o*k10000bbVXQnWMOn=I#q3NWNBu305UK!Gc7PPEi*AxF)%tXHaayqD=;!TFffal z6oLQ%02y>eSaefwW^{L9a%BK_cXuvnZfkR6VQ^(GZ*pgw?mQX*0000 Date: Tue, 24 Sep 2013 09:40:35 +0200 Subject: [PATCH 26/79] updated credits file --- credits.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/credits.txt b/credits.txt index c766c34c3..6e8e36612 100644 --- a/credits.txt +++ b/credits.txt @@ -62,6 +62,7 @@ Roman Proskuryakov (humbug) Sandy Carter (bwrsandman) Sebastian Wick (swick) Sergey Shambir +sir_herrbatka Sylvain Thesnieres (Garvek) Tom Mason (wheybags) Torben Leif Carrington (TorbenC) From 1363e868281a94f9e967a81cb94fbc249e0f6b7d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 27 Sep 2013 10:08:09 +0200 Subject: [PATCH 27/79] made verifier ignore deleted records --- apps/opencs/model/tools/birthsigncheck.cpp | 7 ++++++- apps/opencs/model/tools/classcheck.cpp | 7 ++++++- apps/opencs/model/tools/factioncheck.cpp | 7 ++++++- apps/opencs/model/tools/racecheck.cpp | 7 ++++++- apps/opencs/model/tools/regioncheck.cpp | 7 ++++++- apps/opencs/model/tools/skillcheck.cpp | 7 ++++++- apps/opencs/model/tools/soundcheck.cpp | 7 ++++++- apps/opencs/model/tools/spellcheck.cpp | 7 ++++++- 8 files changed, 48 insertions(+), 8 deletions(-) diff --git a/apps/opencs/model/tools/birthsigncheck.cpp b/apps/opencs/model/tools/birthsigncheck.cpp index b673c93de..59c65086e 100644 --- a/apps/opencs/model/tools/birthsigncheck.cpp +++ b/apps/opencs/model/tools/birthsigncheck.cpp @@ -19,7 +19,12 @@ int CSMTools::BirthsignCheckStage::setup() void CSMTools::BirthsignCheckStage::perform (int stage, std::vector& messages) { - const ESM::BirthSign& birthsign = mBirthsigns.getRecord (stage).get(); + const CSMWorld::Record& record = mBirthsigns.getRecord (stage); + + if (record.isDeleted()) + return; + + const ESM::BirthSign& birthsign = record.get(); CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Birthsign, birthsign.mId); diff --git a/apps/opencs/model/tools/classcheck.cpp b/apps/opencs/model/tools/classcheck.cpp index da2e9f19a..6923b3153 100644 --- a/apps/opencs/model/tools/classcheck.cpp +++ b/apps/opencs/model/tools/classcheck.cpp @@ -20,7 +20,12 @@ int CSMTools::ClassCheckStage::setup() void CSMTools::ClassCheckStage::perform (int stage, std::vector& messages) { - const ESM::Class& class_= mClasses.getRecord (stage).get(); + const CSMWorld::Record& record = mClasses.getRecord (stage); + + if (record.isDeleted()) + return; + + const ESM::Class& class_ = record.get(); CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Class, class_.mId); diff --git a/apps/opencs/model/tools/factioncheck.cpp b/apps/opencs/model/tools/factioncheck.cpp index af26904ef..c219e5610 100644 --- a/apps/opencs/model/tools/factioncheck.cpp +++ b/apps/opencs/model/tools/factioncheck.cpp @@ -20,7 +20,12 @@ int CSMTools::FactionCheckStage::setup() void CSMTools::FactionCheckStage::perform (int stage, std::vector& messages) { - const ESM::Faction& faction = mFactions.getRecord (stage).get(); + const CSMWorld::Record& record = mFactions.getRecord (stage); + + if (record.isDeleted()) + return; + + const ESM::Faction& faction = record.get(); CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Faction, faction.mId); diff --git a/apps/opencs/model/tools/racecheck.cpp b/apps/opencs/model/tools/racecheck.cpp index 1e7a4cab4..413de5ef0 100644 --- a/apps/opencs/model/tools/racecheck.cpp +++ b/apps/opencs/model/tools/racecheck.cpp @@ -9,7 +9,12 @@ void CSMTools::RaceCheckStage::performPerRecord (int stage, std::vector& messages) { - const ESM::Race& race = mRaces.getRecord (stage).get(); + const CSMWorld::Record& record = mRaces.getRecord (stage); + + if (record.isDeleted()) + return; + + const ESM::Race& race = record.get(); CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Race, race.mId); diff --git a/apps/opencs/model/tools/regioncheck.cpp b/apps/opencs/model/tools/regioncheck.cpp index ac64ac027..4398e00ef 100644 --- a/apps/opencs/model/tools/regioncheck.cpp +++ b/apps/opencs/model/tools/regioncheck.cpp @@ -19,7 +19,12 @@ int CSMTools::RegionCheckStage::setup() void CSMTools::RegionCheckStage::perform (int stage, std::vector& messages) { - const ESM::Region& region = mRegions.getRecord (stage).get(); + const CSMWorld::Record& record = mRegions.getRecord (stage); + + if (record.isDeleted()) + return; + + const ESM::Region& region = record.get(); CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Region, region.mId); diff --git a/apps/opencs/model/tools/skillcheck.cpp b/apps/opencs/model/tools/skillcheck.cpp index 897aeab47..28fc24fd3 100644 --- a/apps/opencs/model/tools/skillcheck.cpp +++ b/apps/opencs/model/tools/skillcheck.cpp @@ -18,7 +18,12 @@ int CSMTools::SkillCheckStage::setup() void CSMTools::SkillCheckStage::perform (int stage, std::vector& messages) { - const ESM::Skill& skill = mSkills.getRecord (stage).get(); + const CSMWorld::Record& record = mSkills.getRecord (stage); + + if (record.isDeleted()) + return; + + const ESM::Skill& skill = record.get(); CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Skill, skill.mId); diff --git a/apps/opencs/model/tools/soundcheck.cpp b/apps/opencs/model/tools/soundcheck.cpp index 52834e659..dce2d2b6f 100644 --- a/apps/opencs/model/tools/soundcheck.cpp +++ b/apps/opencs/model/tools/soundcheck.cpp @@ -18,7 +18,12 @@ int CSMTools::SoundCheckStage::setup() void CSMTools::SoundCheckStage::perform (int stage, std::vector& messages) { - const ESM::Sound& sound = mSounds.getRecord (stage).get(); + const CSMWorld::Record& record = mSounds.getRecord (stage); + + if (record.isDeleted()) + return; + + const ESM::Sound& sound = record.get(); CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Sound, sound.mId); diff --git a/apps/opencs/model/tools/spellcheck.cpp b/apps/opencs/model/tools/spellcheck.cpp index 3adee0a4e..a2cc7c8d2 100644 --- a/apps/opencs/model/tools/spellcheck.cpp +++ b/apps/opencs/model/tools/spellcheck.cpp @@ -19,7 +19,12 @@ int CSMTools::SpellCheckStage::setup() void CSMTools::SpellCheckStage::perform (int stage, std::vector& messages) { - const ESM::Spell& spell = mSpells.getRecord (stage).get(); + const CSMWorld::Record& record = mSpells.getRecord (stage); + + if (record.isDeleted()) + return; + + const ESM::Spell& spell = record.get(); CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Spell, spell.mId); From 9ea092927fca60c1b92b8d4fbc7305eda672c8db Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 28 Sep 2013 09:25:54 +0200 Subject: [PATCH 28/79] added basic scene subview (no functionality yet) --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/world/universalid.cpp | 1 + apps/opencs/model/world/universalid.hpp | 5 +- apps/opencs/view/doc/view.cpp | 9 ++++ apps/opencs/view/doc/view.hpp | 2 + apps/opencs/view/world/scenesubview.cpp | 72 +++++++++++++++++++++++++ apps/opencs/view/world/scenesubview.hpp | 37 +++++++++++++ apps/opencs/view/world/scenetoolbar.cpp | 8 +++ apps/opencs/view/world/scenetoolbar.hpp | 20 +++++++ apps/opencs/view/world/subviews.cpp | 2 + 10 files changed, 155 insertions(+), 3 deletions(-) create mode 100644 apps/opencs/view/world/scenesubview.cpp create mode 100644 apps/opencs/view/world/scenesubview.hpp create mode 100644 apps/opencs/view/world/scenetoolbar.cpp create mode 100644 apps/opencs/view/world/scenetoolbar.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 00547a2ba..2fbceac96 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -59,7 +59,7 @@ opencs_hdrs_noqt (view/doc opencs_units (view/world table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator - cellcreator referenceablecreator referencecreator + cellcreator referenceablecreator referencecreator scenesubview scenetoolbar ) opencs_units_noqt (view/world diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index 60a8485f8..c9edd0c16 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -87,6 +87,7 @@ namespace static const TypeData sIndexArg[] = { { CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, "Verification Results", 0 }, + { CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", 0 }, { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker }; diff --git a/apps/opencs/model/world/universalid.hpp b/apps/opencs/model/world/universalid.hpp index aa0cdacc0..246640733 100644 --- a/apps/opencs/model/world/universalid.hpp +++ b/apps/opencs/model/world/universalid.hpp @@ -86,10 +86,11 @@ namespace CSMWorld Type_Reference, Type_RegionMap, Type_Filter, - Type_Filters + Type_Filters, + Type_Scene }; - enum { NumberOfTypes = Type_Filters+1 }; + enum { NumberOfTypes = Type_Scene+1 }; private: diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 7183753e1..b29250d20 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -115,6 +115,10 @@ void CSVDoc::View::setupWorldMenu() world->addSeparator(); // items that don't represent single record lists follow here + QAction *scene = new QAction (tr ("Scene"), this); + connect (scene, SIGNAL (triggered()), this, SLOT (addSceneSubView())); + world->addAction (scene); + QAction *regionMap = new QAction (tr ("Region Map"), this); connect (regionMap, SIGNAL (triggered()), this, SLOT (addRegionMapSubView())); world->addAction (regionMap); @@ -403,6 +407,11 @@ void CSVDoc::View::addFiltersSubView() addSubView (CSMWorld::UniversalId::Type_Filters); } +void CSVDoc::View::addSceneSubView() +{ + addSubView (CSMWorld::UniversalId::Type_Scene); +} + void CSVDoc::View::abortOperation (int type) { mDocument->abortOperation (type); diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index 29a1d52f7..6f3c38daa 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -164,6 +164,8 @@ namespace CSVDoc void addFiltersSubView(); + void addSceneSubView(); + void toggleShowStatusBar (bool show); }; } diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp new file mode 100644 index 000000000..bb77fec2e --- /dev/null +++ b/apps/opencs/view/world/scenesubview.cpp @@ -0,0 +1,72 @@ + +#include "scenesubview.hpp" + +#include +#include +#include + +#include "../../model/doc/document.hpp" + +#include "../filter/filterbox.hpp" + +#include "tablebottombox.hpp" +#include "creator.hpp" +#include "scenetoolbar.hpp" + +CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) +: SubView (id) +{ + QVBoxLayout *layout = new QVBoxLayout; + + layout->setContentsMargins (QMargins (0, 0, 0, 0)); + + layout->addWidget (mBottom = + new TableBottomBox (NullCreatorFactory(), document.getData(), document.getUndoStack(), id, + this), 0); + + QHBoxLayout *layout2 = new QHBoxLayout; + + layout2->setContentsMargins (QMargins (0, 0, 0, 0)); + + SceneToolbar *toolbar = new SceneToolbar (this); + layout2->addWidget (toolbar, 0); + + /// \todo replace with rendering widget + QPalette palette2 (palette()); + palette2.setColor (QPalette::Background, Qt::white); + QLabel *placeholder = new QLabel ("Here goes the 3D scene", this); + placeholder->setAutoFillBackground (true); + placeholder->setPalette (palette2); + placeholder->setAlignment (Qt::AlignHCenter); + + layout2->addWidget (placeholder, 1); + + layout->insertLayout (0, layout2, 1); + + CSVFilter::FilterBox *filterBox = new CSVFilter::FilterBox (document.getData(), this); + + layout->insertWidget (0, filterBox); + + QWidget *widget = new QWidget; + + widget->setLayout (layout); + + setWidget (widget); +} + +void CSVWorld::SceneSubView::setEditLock (bool locked) +{ + + +} + +void CSVWorld::SceneSubView::updateEditorSetting(const QString &settingName, const QString &settingValue) +{ + + +} + +void CSVWorld::SceneSubView::setStatusBar (bool show) +{ + mBottom->setStatusBar (show); +} \ No newline at end of file diff --git a/apps/opencs/view/world/scenesubview.hpp b/apps/opencs/view/world/scenesubview.hpp new file mode 100644 index 000000000..a0fed908d --- /dev/null +++ b/apps/opencs/view/world/scenesubview.hpp @@ -0,0 +1,37 @@ +#ifndef CSV_WORLD_SCENESUBVIEW_H +#define CSV_WORLD_SCENESUBVIEW_H + +#include "../doc/subview.hpp" + +class QModelIndex; + +namespace CSMDoc +{ + class Document; +} + +namespace CSVWorld +{ + class Table; + class TableBottomBox; + class CreatorFactoryBase; + + class SceneSubView : public CSVDoc::SubView + { + Q_OBJECT + + TableBottomBox *mBottom; + + public: + + SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); + + virtual void setEditLock (bool locked); + + virtual void updateEditorSetting (const QString& key, const QString& value); + + virtual void setStatusBar (bool show); + }; +} + +#endif diff --git a/apps/opencs/view/world/scenetoolbar.cpp b/apps/opencs/view/world/scenetoolbar.cpp new file mode 100644 index 000000000..6ced03a9f --- /dev/null +++ b/apps/opencs/view/world/scenetoolbar.cpp @@ -0,0 +1,8 @@ + +#include "scenetoolbar.hpp" + +CSVWorld::SceneToolbar::SceneToolbar (QWidget *parent) : QWidget (parent) +{ + setFixedWidth (52); + +} diff --git a/apps/opencs/view/world/scenetoolbar.hpp b/apps/opencs/view/world/scenetoolbar.hpp new file mode 100644 index 000000000..2fb288100 --- /dev/null +++ b/apps/opencs/view/world/scenetoolbar.hpp @@ -0,0 +1,20 @@ +#ifndef CSV_WORLD_SCENETOOLBAR_H +#define CSV_WORLD_SCENETOOLBAR_H + +#include + +namespace CSVWorld +{ + class SceneToolbar : public QWidget + { + Q_OBJECT + + public: + + SceneToolbar (QWidget *parent); + + + }; +} + +#endif diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index d22e07d89..0e3465b38 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -13,6 +13,7 @@ #include "cellcreator.hpp" #include "referenceablecreator.hpp" #include "referencecreator.hpp" +#include "scenesubview.hpp" void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) { @@ -62,4 +63,5 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) new CSVDoc::SubViewFactoryWithCreator >); + manager.add (CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory); } \ No newline at end of file From 84cadc10f4a32a752426f106d75db9078f160c10 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 28 Sep 2013 11:06:56 +0200 Subject: [PATCH 29/79] added scene toolbar buttons (still not doing anything) --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/world/scenesubview.cpp | 5 +++++ apps/opencs/view/world/scenetool.cpp | 9 +++++++++ apps/opencs/view/world/scenetool.hpp | 19 +++++++++++++++++++ apps/opencs/view/world/scenetoolbar.cpp | 17 ++++++++++++++++- apps/opencs/view/world/scenetoolbar.hpp | 8 +++++++- 6 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 apps/opencs/view/world/scenetool.cpp create mode 100644 apps/opencs/view/world/scenetool.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 2fbceac96..2bb31be9f 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -59,7 +59,7 @@ opencs_hdrs_noqt (view/doc opencs_units (view/world table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator - cellcreator referenceablecreator referencecreator scenesubview scenetoolbar + cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool ) opencs_units_noqt (view/world diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index bb77fec2e..3b15326ab 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -12,6 +12,7 @@ #include "tablebottombox.hpp" #include "creator.hpp" #include "scenetoolbar.hpp" +#include "scenetool.hpp" CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) : SubView (id) @@ -29,6 +30,10 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D layout2->setContentsMargins (QMargins (0, 0, 0, 0)); SceneToolbar *toolbar = new SceneToolbar (this); +toolbar->addTool (new SceneTool (this)); // test +toolbar->addTool (new SceneTool (this)); +toolbar->addTool (new SceneTool (this)); +toolbar->addTool (new SceneTool (this)); layout2->addWidget (toolbar, 0); /// \todo replace with rendering widget diff --git a/apps/opencs/view/world/scenetool.cpp b/apps/opencs/view/world/scenetool.cpp new file mode 100644 index 000000000..12743c52c --- /dev/null +++ b/apps/opencs/view/world/scenetool.cpp @@ -0,0 +1,9 @@ + +#include "scenetool.hpp" + +CSVWorld::SceneTool::SceneTool (QWidget *parent) : QPushButton (parent) +{ + setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); + setFixedSize (48, 48); + +} \ No newline at end of file diff --git a/apps/opencs/view/world/scenetool.hpp b/apps/opencs/view/world/scenetool.hpp new file mode 100644 index 000000000..ae440b579 --- /dev/null +++ b/apps/opencs/view/world/scenetool.hpp @@ -0,0 +1,19 @@ +#ifndef CSV_WORLD_SCENETOOL_H +#define CSV_WORLD_SCENETOOL_H + +#include + +namespace CSVWorld +{ + class SceneTool : public QPushButton + { + Q_OBJECT + + public: + + SceneTool (QWidget *parent = 0); + + }; +} + +#endif diff --git a/apps/opencs/view/world/scenetoolbar.cpp b/apps/opencs/view/world/scenetoolbar.cpp index 6ced03a9f..7c716b5fc 100644 --- a/apps/opencs/view/world/scenetoolbar.cpp +++ b/apps/opencs/view/world/scenetoolbar.cpp @@ -1,8 +1,23 @@ #include "scenetoolbar.hpp" +#include + +#include "scenetool.hpp" + CSVWorld::SceneToolbar::SceneToolbar (QWidget *parent) : QWidget (parent) { - setFixedWidth (52); + setFixedWidth (48); + + mLayout = new QVBoxLayout (this); + mLayout->setAlignment (Qt::AlignTop); + mLayout->setContentsMargins (QMargins (0, 0, 0, 0)); + + setLayout (mLayout); } + +void CSVWorld::SceneToolbar::addTool (SceneTool *tool) +{ + mLayout->addWidget (tool, 0, Qt::AlignTop); +} \ No newline at end of file diff --git a/apps/opencs/view/world/scenetoolbar.hpp b/apps/opencs/view/world/scenetoolbar.hpp index 2fb288100..00631c360 100644 --- a/apps/opencs/view/world/scenetoolbar.hpp +++ b/apps/opencs/view/world/scenetoolbar.hpp @@ -3,17 +3,23 @@ #include +class QVBoxLayout; + namespace CSVWorld { + class SceneTool; + class SceneToolbar : public QWidget { Q_OBJECT + QVBoxLayout *mLayout; + public: SceneToolbar (QWidget *parent); - + void addTool (SceneTool *tool); }; } From 0c5f07a65addf90c4fd033b2d4e4e03424f26e24 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 28 Sep 2013 11:27:24 +0200 Subject: [PATCH 30/79] added SceneToolMode class --- apps/opencs/CMakeLists.txt | 1 + apps/opencs/view/world/scenesubview.cpp | 10 +++++----- apps/opencs/view/world/scenetool.cpp | 1 - apps/opencs/view/world/scenetool.hpp | 1 + apps/opencs/view/world/scenetoolmode.cpp | 6 ++++++ apps/opencs/view/world/scenetoolmode.hpp | 19 +++++++++++++++++++ 6 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 apps/opencs/view/world/scenetoolmode.cpp create mode 100644 apps/opencs/view/world/scenetoolmode.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 2bb31be9f..f918cfebf 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -60,6 +60,7 @@ opencs_hdrs_noqt (view/doc opencs_units (view/world table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool + scenetoolmode ) opencs_units_noqt (view/world diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 3b15326ab..8f3ecab21 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -12,7 +12,7 @@ #include "tablebottombox.hpp" #include "creator.hpp" #include "scenetoolbar.hpp" -#include "scenetool.hpp" +#include "scenetoolmode.hpp" CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) : SubView (id) @@ -30,10 +30,10 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D layout2->setContentsMargins (QMargins (0, 0, 0, 0)); SceneToolbar *toolbar = new SceneToolbar (this); -toolbar->addTool (new SceneTool (this)); // test -toolbar->addTool (new SceneTool (this)); -toolbar->addTool (new SceneTool (this)); -toolbar->addTool (new SceneTool (this)); +toolbar->addTool (new SceneToolMode (this)); // test +toolbar->addTool (new SceneToolMode (this)); +toolbar->addTool (new SceneToolMode (this)); +toolbar->addTool (new SceneToolMode (this)); layout2->addWidget (toolbar, 0); /// \todo replace with rendering widget diff --git a/apps/opencs/view/world/scenetool.cpp b/apps/opencs/view/world/scenetool.cpp index 12743c52c..f67e4fa45 100644 --- a/apps/opencs/view/world/scenetool.cpp +++ b/apps/opencs/view/world/scenetool.cpp @@ -5,5 +5,4 @@ CSVWorld::SceneTool::SceneTool (QWidget *parent) : QPushButton (parent) { setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); setFixedSize (48, 48); - } \ No newline at end of file diff --git a/apps/opencs/view/world/scenetool.hpp b/apps/opencs/view/world/scenetool.hpp index ae440b579..c3e9e3b4b 100644 --- a/apps/opencs/view/world/scenetool.hpp +++ b/apps/opencs/view/world/scenetool.hpp @@ -5,6 +5,7 @@ namespace CSVWorld { + ///< \brief Tool base class class SceneTool : public QPushButton { Q_OBJECT diff --git a/apps/opencs/view/world/scenetoolmode.cpp b/apps/opencs/view/world/scenetoolmode.cpp new file mode 100644 index 000000000..a6b9b5a28 --- /dev/null +++ b/apps/opencs/view/world/scenetoolmode.cpp @@ -0,0 +1,6 @@ + +#include "scenetoolmode.hpp" + +CSVWorld::SceneToolMode::SceneToolMode (QWidget *parent) +: SceneTool (parent) +{} \ No newline at end of file diff --git a/apps/opencs/view/world/scenetoolmode.hpp b/apps/opencs/view/world/scenetoolmode.hpp new file mode 100644 index 000000000..d54ec76b2 --- /dev/null +++ b/apps/opencs/view/world/scenetoolmode.hpp @@ -0,0 +1,19 @@ +#ifndef CSV_WORLD_SCENETOOL_MODE_H +#define CSV_WORLD_SCENETOOL_MODE_H + +#include "scenetool.hpp" + +namespace CSVWorld +{ + ///< \brief Mode selector tool + class SceneToolMode : public SceneTool + { + Q_OBJECT + + public: + + SceneToolMode (QWidget *parent = 0); + }; +} + +#endif From 7be1f1afc2a9e5ce7f6e0d95d22483fc544d90ac Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 28 Sep 2013 13:10:42 +0200 Subject: [PATCH 31/79] implemented SceneToolMode as a horizontal panel with radiobutton-type buttons --- apps/opencs/view/world/scenesubview.cpp | 7 +++- apps/opencs/view/world/scenetool.cpp | 14 ++++++- apps/opencs/view/world/scenetool.hpp | 9 +++++ apps/opencs/view/world/scenetoolmode.cpp | 47 +++++++++++++++++++++++- apps/opencs/view/world/scenetoolmode.hpp | 20 ++++++++++ 5 files changed, 94 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 8f3ecab21..36ace68f0 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -30,7 +30,12 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D layout2->setContentsMargins (QMargins (0, 0, 0, 0)); SceneToolbar *toolbar = new SceneToolbar (this); -toolbar->addTool (new SceneToolMode (this)); // test +// test +SceneToolMode *tool = new SceneToolMode (this); +tool->addButton (":door.png", "a"); +tool->addButton (":GMST.png", "b"); +tool->addButton (":Info.png", "c"); +toolbar->addTool (tool); toolbar->addTool (new SceneToolMode (this)); toolbar->addTool (new SceneToolMode (this)); toolbar->addTool (new SceneToolMode (this)); diff --git a/apps/opencs/view/world/scenetool.cpp b/apps/opencs/view/world/scenetool.cpp index f67e4fa45..d7d37c98f 100644 --- a/apps/opencs/view/world/scenetool.cpp +++ b/apps/opencs/view/world/scenetool.cpp @@ -5,4 +5,16 @@ CSVWorld::SceneTool::SceneTool (QWidget *parent) : QPushButton (parent) { setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); setFixedSize (48, 48); -} \ No newline at end of file + + connect (this, SIGNAL (clicked()), this, SLOT (openRequest())); +} + +void CSVWorld::SceneTool::updateIcon (const QIcon& icon) +{ + setIcon (icon); +} + +void CSVWorld::SceneTool::openRequest() +{ + showPanel (parentWidget()->mapToGlobal (pos())); +} diff --git a/apps/opencs/view/world/scenetool.hpp b/apps/opencs/view/world/scenetool.hpp index c3e9e3b4b..d5c9dd5d2 100644 --- a/apps/opencs/view/world/scenetool.hpp +++ b/apps/opencs/view/world/scenetool.hpp @@ -14,6 +14,15 @@ namespace CSVWorld SceneTool (QWidget *parent = 0); + virtual void showPanel (const QPoint& position) = 0; + + protected slots: + + void updateIcon (const QIcon& icon); + + private slots: + + void openRequest(); }; } diff --git a/apps/opencs/view/world/scenetoolmode.cpp b/apps/opencs/view/world/scenetoolmode.cpp index a6b9b5a28..b4277bcbe 100644 --- a/apps/opencs/view/world/scenetoolmode.cpp +++ b/apps/opencs/view/world/scenetoolmode.cpp @@ -1,6 +1,51 @@ #include "scenetoolmode.hpp" +#include +#include +#include + CSVWorld::SceneToolMode::SceneToolMode (QWidget *parent) : SceneTool (parent) -{} \ No newline at end of file +{ + mPanel = new QFrame (this, Qt::Popup); + + mLayout = new QHBoxLayout (mPanel); + + mLayout->setContentsMargins (QMargins (0, 0, 0, 0)); + + mPanel->setLayout (mLayout); +} + +void CSVWorld::SceneToolMode::showPanel (const QPoint& position) +{ + mPanel->move (position); + mPanel->show(); +} + +void CSVWorld::SceneToolMode::addButton (const std::string& icon, const std::string& id) +{ + QPushButton *button = new QPushButton (QIcon (QPixmap (icon.c_str())), "", mPanel); + button->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); + button->setFixedSize (48, 48); + + mLayout->addWidget (button); + + mButtons.insert (std::make_pair (button, id)); + + connect (button, SIGNAL (clicked()), this, SLOT (selected())); +} + +void CSVWorld::SceneToolMode::selected() +{ + std::map::const_iterator iter = + mButtons.find (dynamic_cast (sender())); + + if (iter!=mButtons.end()) + { + mPanel->hide(); + + emit updateIcon (iter->first->icon()); + emit modeChanged (iter->second); + } +} \ No newline at end of file diff --git a/apps/opencs/view/world/scenetoolmode.hpp b/apps/opencs/view/world/scenetoolmode.hpp index d54ec76b2..feee78376 100644 --- a/apps/opencs/view/world/scenetoolmode.hpp +++ b/apps/opencs/view/world/scenetoolmode.hpp @@ -3,6 +3,10 @@ #include "scenetool.hpp" +#include + +class QHBoxLayout; + namespace CSVWorld { ///< \brief Mode selector tool @@ -10,9 +14,25 @@ namespace CSVWorld { Q_OBJECT + QWidget *mPanel; + QHBoxLayout *mLayout; + std::map mButtons; // widget, id + public: SceneToolMode (QWidget *parent = 0); + + virtual void showPanel (const QPoint& position); + + void addButton (const std::string& icon, const std::string& id); + + signals: + + void modeChanged (const std::string& id); + + private slots: + + void selected(); }; } From fd169c2399ba2ccc103361696b61c662d88b901b Mon Sep 17 00:00:00 2001 From: Tom Mason Date: Sun, 29 Sep 2013 15:49:47 +0100 Subject: [PATCH 32/79] fixed issue with cds where subfolders of Data Files were contained outside the Data Files folder --- apps/launcher/unshieldthread.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/apps/launcher/unshieldthread.cpp b/apps/launcher/unshieldthread.cpp index 6ddad7a21..33bdf44f4 100644 --- a/apps/launcher/unshieldthread.cpp +++ b/apps/launcher/unshieldthread.cpp @@ -268,6 +268,27 @@ namespace strptime(time, "%d %B %Y", &tms); return mktime(&tms); } + + // Some cds have cab files which have the Data Files subfolders outside the Data Files folder + void install_dfiles_outside(const bfs::path& from, const bfs::path& dFiles) + { + bfs::path fonts = findFile(from, "fonts", false); + if(fonts.string() != "") + installToPath(fonts, dFiles / "Fonts"); + + bfs::path music = findFile(from, "music", false); + if(music.string() != "") + installToPath(music, dFiles / "Music"); + + bfs::path sound = findFile(from, "sound", false); + if(sound.string() != "") + installToPath(sound, dFiles / "Sound"); + + bfs::path splash = findFile(from, "splash", false); + if(splash.string() != "") + installToPath(splash, dFiles / "Splash"); + } + } bool UnshieldThread::SetMorrowindPath(const std::string& path) @@ -365,6 +386,8 @@ bool UnshieldThread::extract() installToPath(dFilesDir, outputDataFilesDir); + install_dfiles_outside(mwExtractPath, outputDataFilesDir); + // Videos are often kept uncompressed on the cd bfs::path videosPath = findFile(mMorrowindPath.parent_path(), "video", false); if(videosPath.string() != "") @@ -399,6 +422,8 @@ bool UnshieldThread::extract() installToPath(dFilesDir, outputDataFilesDir); + install_dfiles_outside(tbExtractPath, outputDataFilesDir); + // Mt GOTY CD has Sounds in a seperate folder from the rest of the data files bfs::path soundsPath = findFile(tbExtractPath, "sounds", false); if(soundsPath.string() != "") @@ -426,6 +451,8 @@ bool UnshieldThread::extract() bfs::path dFilesDir = findFile(bmExtractPath, "bloodmoon.esm").parent_path(); installToPath(dFilesDir, outputDataFilesDir); + + install_dfiles_outside(bmExtractPath, outputDataFilesDir); // My GOTY CD contains a folder within cab files called Tribunal patch, // which contains Tribunal.esm From dd0a41624970b657a4159cffdb7b2a120636a023 Mon Sep 17 00:00:00 2001 From: Tom Mason Date: Sun, 29 Sep 2013 16:59:52 +0100 Subject: [PATCH 33/79] cleaned up bloodmoon_fix_ini --- apps/launcher/unshieldthread.cpp | 143 ++++++++++++++++--------------- 1 file changed, 72 insertions(+), 71 deletions(-) diff --git a/apps/launcher/unshieldthread.cpp b/apps/launcher/unshieldthread.cpp index 33bdf44f4..69b241365 100644 --- a/apps/launcher/unshieldthread.cpp +++ b/apps/launcher/unshieldthread.cpp @@ -77,6 +77,8 @@ namespace ini.insert(loc, setting + "=" + val + "\r\n"); } + #define FIX(setting) add_setting(category, setting, get_setting(category, setting, inx), ini) + void bloodmoon_fix_ini(std::string& ini, const bfs::path inxPath) { std::string inx = read_to_string(inxPath); @@ -88,95 +90,94 @@ namespace ini.erase(start, end-start); std::string category; - std::string setting; category = "General"; { - setting = "Werewolf FOV"; add_setting(category, setting, get_setting(category, setting, inx), ini); + FIX("Werewolf FOV"); } category = "Moons"; { - setting = "Script Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + FIX("Script Color"); } category = "Weather"; { - setting = "Snow Ripples"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Ripple Radius"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Ripples Per Flake"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Ripple Scale"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Ripple Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Gravity Scale"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow High Kill"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Low Kill"; add_setting(category, setting, get_setting(category, setting, inx), ini); + FIX("Snow Ripples"); + FIX("Snow Ripple Radius"); + FIX("Snow Ripples Per Flake"); + FIX("Snow Ripple Scale"); + FIX("Snow Ripple Speed"); + FIX("Snow Gravity Scale"); + FIX("Snow High Kill"); + FIX("Snow Low Kill"); } category = "Weather Blight"; { - setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini); + FIX("Ambient Loop Sound ID"); } category = "Weather Snow"; { - setting = "Sky Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sky Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sky Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sky Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Disc Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Transition Delta"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Land Fog Day Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Land Fog Night Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Clouds Maximum Percent"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Wind Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Cloud Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Glare View"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Cloud Texture"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Threshold"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Diameter"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Height Min"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Height Max"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Entrance Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Max Snowflakes"; add_setting(category, setting, get_setting(category, setting, inx), ini); + FIX("Sky Sunrise Color"); + FIX("Sky Day Color"); + FIX("Sky Sunset Color"); + FIX("Sky Night Color"); + FIX("Fog Sunrise Color"); + FIX("Fog Day Color"); + FIX("Fog Sunset Color"); + FIX("Fog Night Color"); + FIX("Ambient Sunrise Color"); + FIX("Ambient Day Color"); + FIX("Ambient Sunset Color"); + FIX("Ambient Night Color"); + FIX("Sun Sunrise Color"); + FIX("Sun Day Color"); + FIX("Sun Sunset Color"); + FIX("Sun Night Color"); + FIX("Sun Disc Sunset Color"); + FIX("Transition Delta"); + FIX("Land Fog Day Depth"); + FIX("Land Fog Night Depth"); + FIX("Clouds Maximum Percent"); + FIX("Wind Speed"); + FIX("Cloud Speed"); + FIX("Glare View"); + FIX("Cloud Texture"); + FIX("Ambient Loop Sound ID"); + FIX("Snow Threshold"); + FIX("Snow Diameter"); + FIX("Snow Height Min"); + FIX("Snow Height Max"); + FIX("Snow Entrance Speed"); + FIX("Max Snowflakes"); } category = "Weather Blizzard"; { - setting = "Sky Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sky Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sky Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sky Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Disc Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Transition Delta"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Land Fog Day Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Land Fog Night Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Clouds Maximum Percent"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Wind Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Cloud Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Glare View"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Cloud Texture"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Storm Threshold"; add_setting(category, setting, get_setting(category, setting, inx), ini); + FIX("Sky Sunrise Color"); + FIX("Sky Day Color"); + FIX("Sky Sunset Color"); + FIX("Sky Night Color"); + FIX("Fog Sunrise Color"); + FIX("Fog Day Color"); + FIX("Fog Sunset Color"); + FIX("Fog Night Color"); + FIX("Ambient Sunrise Color"); + FIX("Ambient Day Color"); + FIX("Ambient Sunset Color"); + FIX("Ambient Night Color"); + FIX("Sun Sunrise Color"); + FIX("Sun Day Color"); + FIX("Sun Sunset Color"); + FIX("Sun Night Color"); + FIX("Sun Disc Sunset Color"); + FIX("Transition Delta"); + FIX("Land Fog Day Depth"); + FIX("Land Fog Night Depth"); + FIX("Clouds Maximum Percent"); + FIX("Wind Speed"); + FIX("Cloud Speed"); + FIX("Glare View"); + FIX("Cloud Texture"); + FIX("Ambient Loop Sound ID"); + FIX("Storm Threshold"); } } From bffbfff41c791c18a182e49d1f11710b6c46a3b2 Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Mon, 30 Sep 2013 00:32:06 -0400 Subject: [PATCH 34/79] My own fix to make it hackily compile --- apps/launcher/main.cpp | 16 ++++++++++++++++ apps/opencs/view/doc/adjusterwidget.cpp | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index f67f5edcf..a5cda7647 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -62,3 +62,19 @@ int main(int argc, char *argv[]) return returnValue; } + +#include +#include + +#ifdef __GNUC__ +#define _stdcall __attribute__((stdcall)) +#endif + +int _stdcall +WinMain (struct HINSTANCE__ *hInstance, + struct HINSTANCE__ *hPrevInstance, + char *lpszCmdLine, + int nCmdShow) +{ + return main (__argc, __argv); +} \ No newline at end of file diff --git a/apps/opencs/view/doc/adjusterwidget.cpp b/apps/opencs/view/doc/adjusterwidget.cpp index 910819700..c97f06672 100644 --- a/apps/opencs/view/doc/adjusterwidget.cpp +++ b/apps/opencs/view/doc/adjusterwidget.cpp @@ -61,7 +61,7 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) if (path.parent_path().string()==mLocalData.string()) { // path already points to the local data directory - message = QString::fromUtf8 (("Will be saved as: " + path.native()).c_str()); + message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str()); mResultPath = path; mValid = true; } @@ -70,7 +70,7 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) // path points somewhere else or is a leaf name. path = mLocalData / path.filename(); - message = QString::fromUtf8 (("Will be saved as: " + path.native()).c_str()); + message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str()); mResultPath = path; mValid = true; From 4cdb57e3883051b9dc4dcc6ca16668aa4961ee28 Mon Sep 17 00:00:00 2001 From: greye Date: Mon, 30 Sep 2013 10:30:40 +0400 Subject: [PATCH 35/79] workaround segfault on --new-game switch --- apps/openmw/engine.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index a2eccbaf9..e1fd3a0af 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -399,8 +399,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) mExtensions, mFpsLevel, mOgre, mCfgMgr.getLogPath().string() + std::string("/"), mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage, mEncoding); mEnvironment.setWindowManager (window); - if (mNewGame) - mEnvironment.getWindowManager()->setNewGame(true); // Create the world mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mMaster, mPlugins, @@ -410,6 +408,10 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) input->setPlayer(&mEnvironment.getWorld()->getPlayer()); window->initUI(); + if (mNewGame) + // still redundant work here: recreate CharacterCreation(), + // double update visibility etc. + window->setNewGame(true); window->renderWorldMap(); //Load translation data From 00a776a1a8585c2205c86f958bbe2dc7ba9e64c6 Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Mon, 30 Sep 2013 02:54:20 -0400 Subject: [PATCH 36/79] Fixed compilation failure on my machine Fixed shared records not being populated before the player record is moved. --- 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 f3d4c81b7..8e8f68f70 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -225,8 +225,8 @@ namespace MWWorld if (mEsm[0].getFormat() == 0) ensureNeededRecords(); - mStore.movePlayerRecord(); mStore.setUp(); + mStore.movePlayerRecord(); mGlobalVariables = new Globals (mStore); From eae02ea00dc9823fed63366709ef9c857f4e1956 Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Mon, 30 Sep 2013 03:33:31 -0400 Subject: [PATCH 37/79] Cleaned up my hackish code for WinMain --- apps/launcher/main.cpp | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index a5cda7647..73bdb95da 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -62,19 +62,14 @@ int main(int argc, char *argv[]) return returnValue; } - -#include -#include - -#ifdef __GNUC__ -#define _stdcall __attribute__((stdcall)) -#endif - -int _stdcall -WinMain (struct HINSTANCE__ *hInstance, - struct HINSTANCE__ *hPrevInstance, - char *lpszCmdLine, - int nCmdShow) +#ifdef _WINDOWS +// If the system compiles for main(), then main will be used. +// If it wants WinMain, this will call main anyways. +int _stdcall WinMain(struct HINSTANCE__ *hInstance, + struct HINSTANCE__ *hPrevInstance, + char *lpszCmdLine, + int nCmdShow) { - return main (__argc, __argv); -} \ No newline at end of file + return main(__argc, __argv); +} +#endif From 4496244b1428cb43d9d5d41d191360b7b98e2cb0 Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Tue, 1 Oct 2013 05:36:13 -0400 Subject: [PATCH 38/79] Tabs to spaces My own code uses only tabs - I forgot to change the setting on my IDE, sorry! --- apps/launcher/main.cpp | 2 +- apps/opencs/view/doc/adjusterwidget.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index 73bdb95da..df7aa11d4 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -72,4 +72,4 @@ int _stdcall WinMain(struct HINSTANCE__ *hInstance, { return main(__argc, __argv); } -#endif +#endif \ No newline at end of file diff --git a/apps/opencs/view/doc/adjusterwidget.cpp b/apps/opencs/view/doc/adjusterwidget.cpp index c97f06672..9e01f685c 100644 --- a/apps/opencs/view/doc/adjusterwidget.cpp +++ b/apps/opencs/view/doc/adjusterwidget.cpp @@ -61,7 +61,7 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) if (path.parent_path().string()==mLocalData.string()) { // path already points to the local data directory - message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str()); + message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str()); mResultPath = path; mValid = true; } @@ -70,7 +70,7 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) // path points somewhere else or is a leaf name. path = mLocalData / path.filename(); - message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str()); + message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str()); mResultPath = path; mValid = true; From 296abfd48faec66aa77490f58d6f0e868bb4f17f Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Tue, 1 Oct 2013 10:48:34 -0400 Subject: [PATCH 39/79] Bug #840, First Person Sneaking Camera Height Also, added comments to existing code in the area. --- apps/openmw/mwrender/npcanimation.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 13b5971e2..7b5a105c0 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -443,11 +443,31 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed) Ogre::Vector3 ret = Animation::runAnimation(timepassed); Ogre::SkeletonInstance *baseinst = mSkelBase->getSkeleton(); + + // We have to make a few adjustments to the first person animation, since the armature + // is partly driven by code. if(mViewMode == VM_FirstPerson && mCamera) { + // Bend his neck and shoulders so his eyes don't go into his torso. float pitch = mCamera->getPitch(); Ogre::Node *node = baseinst->getBone("Bip01 Neck"); node->pitch(Ogre::Radian(pitch*0.75f), Ogre::Node::TS_WORLD); + + // If NPC is sneaking, his head and shoulders must lower to adjust his camera. + const MWWorld::Class *npcClass = &MWWorld::Class::get(mPtr); + const MWBase::World *world = MWBase::Environment::get().getWorld(); + + bool isSneaking = npcClass->getStance(mPtr, MWWorld::Class::Sneak); + bool isInAir = !world->isOnGround(mPtr); + bool isSwimming = world->isSwimming(mPtr); + + if(isSneaking && !(isSwimming || isInAir)) + { + Ogre::Node *headNode = baseinst->getBone("Bip01 Neck"); + Ogre::Vector3 position = headNode->getPosition(); + position.x -= 9.5f; + headNode->setPosition(position); + } } for(size_t i = 0;i < ESM::PRT_Count;i++) From 0ddb5097fc48f5e4f87ac08121fa6c02b3f25c16 Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Tue, 1 Oct 2013 11:44:45 -0400 Subject: [PATCH 40/79] Revert "Bug #840, First Person Sneaking Camera Height" This reverts commit 296abfd48faec66aa77490f58d6f0e868bb4f17f. --- apps/openmw/mwrender/npcanimation.cpp | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 7b5a105c0..13b5971e2 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -443,31 +443,11 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed) Ogre::Vector3 ret = Animation::runAnimation(timepassed); Ogre::SkeletonInstance *baseinst = mSkelBase->getSkeleton(); - - // We have to make a few adjustments to the first person animation, since the armature - // is partly driven by code. if(mViewMode == VM_FirstPerson && mCamera) { - // Bend his neck and shoulders so his eyes don't go into his torso. float pitch = mCamera->getPitch(); Ogre::Node *node = baseinst->getBone("Bip01 Neck"); node->pitch(Ogre::Radian(pitch*0.75f), Ogre::Node::TS_WORLD); - - // If NPC is sneaking, his head and shoulders must lower to adjust his camera. - const MWWorld::Class *npcClass = &MWWorld::Class::get(mPtr); - const MWBase::World *world = MWBase::Environment::get().getWorld(); - - bool isSneaking = npcClass->getStance(mPtr, MWWorld::Class::Sneak); - bool isInAir = !world->isOnGround(mPtr); - bool isSwimming = world->isSwimming(mPtr); - - if(isSneaking && !(isSwimming || isInAir)) - { - Ogre::Node *headNode = baseinst->getBone("Bip01 Neck"); - Ogre::Vector3 position = headNode->getPosition(); - position.x -= 9.5f; - headNode->setPosition(position); - } } for(size_t i = 0;i < ESM::PRT_Count;i++) From b8c60dabb3cc1d2e6c377d9807d5b1c654d6918b Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Tue, 1 Oct 2013 23:35:34 +0200 Subject: [PATCH 41/79] Reintroduce Acrobatics changes made by Glorf Advance Acrobatics skill on jump and on landing, apply fall damage on landing. --- apps/openmw/mwclass/npc.cpp | 28 ++++++++++++++++ apps/openmw/mwclass/npc.hpp | 3 ++ apps/openmw/mwmechanics/character.cpp | 47 ++++++++++++++++++++++++++- apps/openmw/mwmechanics/character.hpp | 3 ++ apps/openmw/mwworld/class.cpp | 5 +++ apps/openmw/mwworld/class.hpp | 3 ++ 6 files changed, 88 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 073d1b1b9..505c902db 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -769,6 +769,34 @@ namespace MWClass return x; } + float Npc::getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const + { + const float fallDistanceMin = MWBase::Environment::get().getWorld()->getStore().get().find("fFallDamageDistanceMin")->getFloat(); + + if (fallHeight>=fallDistanceMin) + { + const float acrobaticsSkill = MWWorld::Class::get(ptr).getNpcStats (ptr).getSkill(ESM::Skill::Acrobatics).getModified(); + const CustomData *npcdata = static_cast(ptr.getRefData().getCustomData()); + const float jumpSpellBonus = npcdata->mNpcStats.getMagicEffects().get(MWMechanics::EffectKey(9/*jump*/)).mMagnitude; + const float fallAcroBase = MWBase::Environment::get().getWorld()->getStore().get().find("fFallAcroBase")->getFloat(); + const float fallAcroMult = MWBase::Environment::get().getWorld()->getStore().get().find("fFallAcroMult")->getFloat(); + const float fallDistanceBase = MWBase::Environment::get().getWorld()->getStore().get().find("fFallDistanceBase")->getFloat(); + const float fallDistanceMult = MWBase::Environment::get().getWorld()->getStore().get().find("fFallDistanceMult")->getFloat(); + + float x = fallHeight - fallDistanceMin; + x -= (1.5 * acrobaticsSkill) + jumpSpellBonus; + x = std::max(0.0f, x); + + float a = fallAcroBase + fallAcroMult * (100 - acrobaticsSkill); + x = fallDistanceBase + fallDistanceMult * x; + x *= a; + + return x; + } + + return 0; + } + MWMechanics::Movement& Npc::getMovementSettings (const MWWorld::Ptr& ptr) const { ensureCustomData (ptr); diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index 3591d7c68..c39ca42ef 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -97,6 +97,9 @@ namespace MWClass virtual float getJump(const MWWorld::Ptr &ptr) const; ///< Return jump velocity (not accounting for movement) + virtual float getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const; + ///< Return amount of health points lost when falling + virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const; ///< Return desired movement. diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index ec2bb1b59..2753b09c2 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -767,10 +767,17 @@ void CharacterController::update(float duration) } if(sneak || inwater || flying) + { vec.z = 0.0f; + mFallHeight = 0.0f; + } if(!onground && !flying && !inwater) { + // The player is in the air (either getting up —ascending part of jump— or falling). + + mFallHeight = std::max(mFallHeight, mPtr.getRefData().getPosition().pos[2]); + const MWWorld::Store &gmst = world->getStore().get(); forcestateupdate = (mJumpState != JumpState_Falling); @@ -794,6 +801,8 @@ void CharacterController::update(float duration) } else if(vec.z > 0.0f && mJumpState == JumpState_None) { + // The player has started a jump. + float z = cls.getJump(mPtr); if(vec.x == 0 && vec.y == 0) vec = Ogre::Vector3(0.0f, 0.0f, z); @@ -803,13 +812,49 @@ void CharacterController::update(float duration) vec = Ogre::Vector3(lat.x, lat.y, 1.0f) * z * 0.707f; } - //decrease fatigue by fFatigueJumpBase + (1 - normalizedEncumbrance) * fFatigueJumpMult; + // advance acrobatics + MWWorld::Class::get(mPtr).skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 0); + + // decrease fatigue + const float fatigueJumpBase = MWBase::Environment::get().getWorld()->getStore().get().find("fFatigueJumpBase")->getFloat(); + const float fatigueJumpMult = MWBase::Environment::get().getWorld()->getStore().get().find("fFatigueJumpMult")->getFloat(); + const float normalizedEncumbrance = cls.getEncumbrance(mPtr) / cls.getCapacity(mPtr); + const int fatigueDecrease = fatigueJumpBase + (1 - normalizedEncumbrance) * fatigueJumpMult; + DynamicStat fatigue = cls.getCreatureStats(mPtr).getDynamic(2); + fatigue.setModified(fatigue.getModified() - fatigueDecrease, 0); + fatigue.setCurrent(fatigue.getCurrent() - fatigueDecrease); + cls.getCreatureStats(mPtr).setDynamic(2, fatigue); } else if(mJumpState == JumpState_Falling) { + // The player is landing. + forcestateupdate = true; mJumpState = JumpState_Landing; vec.z = 0.0f; + + float healthLost = cls.getFallDamage(mPtr, mFallHeight - mPtr.getRefData().getPosition().pos[2]); + if (healthLost > 0.0f) + { + // inflict fall damages + DynamicStat health = cls.getCreatureStats(mPtr).getHealth(); + int current = health.getCurrent(); + int realHealthLost = healthLost * (1.0f - 0.25 * 1.25f /* * fatigueTerm */); + health.setModified(health.getModified() - realHealthLost, 0); + health.setCurrent(current - realHealthLost); + cls.getCreatureStats(mPtr).setHealth(health); + + // report acrobatics progression + cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1); + + const float acrobaticsSkill = cls.getNpcStats(mPtr).getSkill(ESM::Skill::Acrobatics).getModified(); + if (healthLost > (acrobaticsSkill * 1.25f /* * fatigueTerm */)) + { + //TODO: actor falls over + } + } + + mFallHeight = 0; } else { diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index c943b9597..7b9dda49a 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -154,6 +154,9 @@ class CharacterController float mSecondsOfSwimming; float mSecondsOfRunning; + // used for acrobatics progress and fall damages + float mFallHeight; + std::string mAttackType; // slash, chop or thrust void refreshCurrentAnims(CharacterState idle, CharacterState movement, bool force=false); diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index c739ea831..de5093547 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -167,6 +167,11 @@ namespace MWWorld throw std::runtime_error ("class does not support enchanting"); } + float Class::getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const + { + return 0; + } + MWMechanics::Movement& Class::getMovementSettings (const Ptr& ptr) const { throw std::runtime_error ("movement settings not supported by class"); diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 28e37cbf3..1db09647e 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -175,6 +175,9 @@ namespace MWWorld virtual float getJump(const MWWorld::Ptr &ptr) const; ///< Return jump velocity (not accounting for movement) + virtual float getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const; + ///< Return amount of health points lost when falling + virtual MWMechanics::Movement& getMovementSettings (const Ptr& ptr) const; ///< Return desired movement. From ed0c31b4854cc19d474402127d434ea379c374c1 Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Wed, 2 Oct 2013 05:16:52 -0400 Subject: [PATCH 42/79] Refactored, moved logic out of NpcAnimation The logic is now handled by RenderingManager, and Camera sets its animation's first person offset height. Due to how NpcAnimation seems to be updated, it has to be the one to actually set its own nodes, in the case of the hands. Otherwise, the hands would not move without a messier hack. --- apps/openmw/mwrender/camera.cpp | 6 ++++++ apps/openmw/mwrender/camera.hpp | 6 ++++++ apps/openmw/mwrender/npcanimation.cpp | 13 ++++++++++++- apps/openmw/mwrender/npcanimation.hpp | 7 +++++++ apps/openmw/mwrender/renderingmanager.cpp | 9 +++++++++ 5 files changed, 40 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index 36f53c0fe..232b95c69 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -187,6 +187,12 @@ namespace MWRender rotateCamera(Ogre::Vector3(getPitch(), 0.f, getYaw()), false); } + void Camera::setSneakOffset() + { + if(mAnimation) + mAnimation->addFirstPersonOffset(Ogre::Vector3(-9.8f, 0.f, 0.f)); + } + float Camera::getYaw() { if(mVanity.enabled || mPreviewMode) diff --git a/apps/openmw/mwrender/camera.hpp b/apps/openmw/mwrender/camera.hpp index dc552371e..baf2f3685 100644 --- a/apps/openmw/mwrender/camera.hpp +++ b/apps/openmw/mwrender/camera.hpp @@ -79,6 +79,12 @@ namespace MWRender void togglePreviewMode(bool enable); + /// \brief Lowers the camera for sneak. + /// As animation is tied to the camera, this needs + /// to be set each frame after the animation is + /// applied. + void setSneakOffset(); + bool isFirstPerson() const { return !(mVanity.enabled || mPreviewMode || !mFirstPersonView); } diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 13b5971e2..84e89773c 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -84,7 +84,8 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor mWeapon(inv.end()), mShield(inv.end()), mViewMode(viewMode), - mShowWeapons(false) + mShowWeapons(false), + mFirstPersonOffset(0.f, 0.f, 0.f) { mNpc = mPtr.get()->mBase; @@ -392,6 +393,11 @@ void NpcAnimation::updateParts(bool forceupdate) } } +void NpcAnimation::addFirstPersonOffset(const Ogre::Vector3 &offset) +{ + mFirstPersonOffset += offset; +} + class SetObjectGroup { int mGroup; @@ -448,7 +454,12 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed) float pitch = mCamera->getPitch(); Ogre::Node *node = baseinst->getBone("Bip01 Neck"); node->pitch(Ogre::Radian(pitch*0.75f), Ogre::Node::TS_WORLD); + + // This has to be done before this function ends; + // updateSkeletonInstance, below, touches the hands. + node->translate(mFirstPersonOffset); } + mFirstPersonOffset = 0.f; // reset the X, Y, Z offset for the next frame. for(size_t i = 0;i < ESM::PRT_Count;i++) { diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index 24205acaf..b1abf97af 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -64,6 +64,8 @@ private: int mPartslots[ESM::PRT_Count]; //Each part slot is taken by clothing, armor, or is empty int mPartPriorities[ESM::PRT_Count]; + Ogre::Vector3 mFirstPersonOffset; + void updateNpcBase(); NifOgre::ObjectList insertBoundedPart(const std::string &model, int group, const std::string &bonename); @@ -89,6 +91,11 @@ public: void updateParts(bool forceupdate = false); + /// \brief Applies a translation to the arms and hands. + /// This may be called multiple times before the animation + /// is updated to add additional offsets. + void addFirstPersonOffset(const Ogre::Vector3 &offset); + /// Rebuilds the NPC, updating their root model, animation sources, and equipment. void rebuild(); }; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index e03b2ccfc..261fd45c8 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -354,6 +354,15 @@ void RenderingManager::update (float duration, bool paused) mCamera->setCameraDistance(test.second * orig.distance(dest), false, false); } + // Sink the camera while sneaking + bool isSneaking = MWWorld::Class::get(player).getStance(player, MWWorld::Class::Sneak); + bool isInAir = !world->isOnGround(player); + bool isSwimming = world->isSwimming(player); + + if(isSneaking && !(isSwimming || isInAir)) + mCamera->setSneakOffset(); + + mOcclusionQuery->update(duration); mVideoPlayer->update (); From f1b4c2e400743dfb207f8b9bbad19e50af6b95ed Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Wed, 2 Oct 2013 07:03:39 -0400 Subject: [PATCH 43/79] Fixed first person offset to use world transform It slipped my mind that some necks might not be perfectly vertical. --- apps/openmw/mwrender/camera.cpp | 2 +- apps/openmw/mwrender/npcanimation.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index 232b95c69..9af3987a8 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -190,7 +190,7 @@ namespace MWRender void Camera::setSneakOffset() { if(mAnimation) - mAnimation->addFirstPersonOffset(Ogre::Vector3(-9.8f, 0.f, 0.f)); + mAnimation->addFirstPersonOffset(Ogre::Vector3(0.f, 0.f, -9.8f)); } float Camera::getYaw() diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 84e89773c..9ffe53eab 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -457,7 +457,7 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed) // This has to be done before this function ends; // updateSkeletonInstance, below, touches the hands. - node->translate(mFirstPersonOffset); + node->translate(mFirstPersonOffset, Ogre::Node::TS_WORLD); } mFirstPersonOffset = 0.f; // reset the X, Y, Z offset for the next frame. From 496f786c2a6e5c202027429b5cc14af0f089c2a0 Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Wed, 2 Oct 2013 15:12:41 +0200 Subject: [PATCH 44/79] Implement Disable/EnableLevitation script functions Totally copied on Disable/EnableTeleporting implementation. Thanks KittyCat! --- apps/openmw/mwbase/world.hpp | 6 ++++++ apps/openmw/mwscript/docs/vmformat.txt | 4 +++- apps/openmw/mwscript/miscextensions.cpp | 15 ++++++++++++++- apps/openmw/mwworld/worldimp.cpp | 10 ++++++++++ apps/openmw/mwworld/worldimp.hpp | 7 +++++++ components/compiler/extensions0.cpp | 2 ++ components/compiler/opcodes.hpp | 2 ++ 7 files changed, 44 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index f8453afed..d7b013a84 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -389,6 +389,12 @@ namespace MWBase /// Returns true if teleport spell effects are allowed. virtual bool isTeleportingEnabled() const = 0; + /// Enables or disables use of levitation spell effect. + virtual void enableLevitation(bool enable) = 0; + + /// Returns true if levitation spell effect is allowed. + virtual bool isLevitationEnabled() const = 0; + /// Turn actor into werewolf or normal form. virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf) = 0; diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index ff3b60ca6..7bbb33699 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -352,5 +352,7 @@ op 0x200021c: SetWerewolfAcrobaticsExplicit op 0x200021d: ShowVars op 0x200021e: ShowVarsExplicit op 0x200021f: ToggleGodMode +op 0x2000220: DisableLevitation +op 0x2000221: EnableLevitation -opcodes 0x2000220-0x3ffffff unused +opcodes 0x2000222-0x3ffffff unused diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index a8d8a5f2b..4ae1136e2 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -635,7 +635,18 @@ namespace MWScript world->enableTeleporting(Enable); } }; - + + template + class OpEnableLevitation : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWBase::World *world = MWBase::Environment::get().getWorld(); + world->enableLevitation(Enable); + } + }; template class OpShowVars : public Interpreter::Opcode0 @@ -789,6 +800,8 @@ namespace MWScript interpreter.installSegment5 (Compiler::Misc::opcodeShowVars, new OpShowVars); interpreter.installSegment5 (Compiler::Misc::opcodeShowVarsExplicit, new OpShowVars); interpreter.installSegment5 (Compiler::Misc::opcodeToggleGodMode, new OpToggleGodMode); + interpreter.installSegment5 (Compiler::Misc::opcodeDisableLevitation, new OpEnableLevitation); + interpreter.installSegment5 (Compiler::Misc::opcodeEnableLevitation, new OpEnableLevitation); } } } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index f3d4c81b7..1ba209663 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1877,6 +1877,16 @@ namespace MWWorld return mTeleportEnabled; } + void World::enableLevitation(bool enable) + { + mLevitationEnabled = enable; + } + + bool World::isLevitationEnabled() const + { + return mLevitationEnabled; + } + void World::setWerewolf(const MWWorld::Ptr& actor, bool werewolf) { MWMechanics::NpcStats& npcStats = Class::get(actor).getNpcStats(actor); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 53b01f1ab..8f80d90d6 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -116,6 +116,7 @@ namespace MWWorld int mPlayIntro; bool mTeleportEnabled; + bool mLevitationEnabled; public: @@ -438,6 +439,12 @@ namespace MWWorld /// Returns true if teleport spell effects are allowed. virtual bool isTeleportingEnabled() const; + /// Enables or disables use of levitation spell effect. + virtual void enableLevitation(bool enable); + + /// Returns true if levitation spell effect is allowed. + virtual bool isLevitationEnabled() const; + virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf); virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor); diff --git a/components/compiler/extensions0.cpp b/components/compiler/extensions0.cpp index 415f8d168..65f6e112a 100644 --- a/components/compiler/extensions0.cpp +++ b/components/compiler/extensions0.cpp @@ -260,6 +260,8 @@ namespace Compiler extensions.registerInstruction ("sv", "", opcodeShowVars, opcodeShowVarsExplicit); extensions.registerInstruction("tgm", "", opcodeToggleGodMode); extensions.registerInstruction("togglegodmode", "", opcodeToggleGodMode); + extensions.registerInstruction ("disablelevitation", "", opcodeDisableLevitation); + extensions.registerInstruction ("enablelevitation", "", opcodeEnableLevitation); } } diff --git a/components/compiler/opcodes.hpp b/components/compiler/opcodes.hpp index 5eb54208a..aca24e0d3 100644 --- a/components/compiler/opcodes.hpp +++ b/components/compiler/opcodes.hpp @@ -222,6 +222,8 @@ namespace Compiler const int opcodeShowVars = 0x200021d; const int opcodeShowVarsExplicit = 0x200021e; const int opcodeToggleGodMode = 0x200021f; + const int opcodeDisableLevitation = 0x2000220; + const int opcodeEnableLevitation = 0x2000221; } namespace Sky From 073f64c8bb4abf7cc8653f3fa0b70a6d69f241e7 Mon Sep 17 00:00:00 2001 From: mckibbenta Date: Wed, 2 Oct 2013 13:46:33 -0400 Subject: [PATCH 45/79] stop weapon condition degredation (for the player) with tgm on --- apps/openmw/mwclass/npc.cpp | 7 ++++--- apps/openmw/mwmechanics/actors.cpp | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 073d1b1b9..3d8bdf16f 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -396,9 +396,10 @@ namespace MWClass MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}"); MWBase::Environment::get().getSoundManager()->playSound3D(victim, "critical damage", 1.0f, 1.0f); } - weapon.getCellRef().mCharge -= std::min(std::max(1, - (int)(damage * gmst.find("fWeaponDamageMult")->getFloat())), - weapon.getCellRef().mCharge); + + if (!MWBase::Environment::get().getWorld()->getGodModeState()) + weapon.getCellRef().mCharge -= std::min(std::max(1, + (int)(damage * gmst.find("fWeaponDamageMult")->getFloat())), weapon.getCellRef().mCharge); } healthdmg = true; } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index ca26e88ce..f9b5b695a 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -276,7 +276,8 @@ namespace MWMechanics } // 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()) + if(iter->first.getRefData().getHandle()=="player" && + MWBase::Environment::get().getWorld()->getGodModeState()) { MWMechanics::DynamicStat stat(stats.getHealth()); From 486051486599e80bc0731252a7191095226b1eaf Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Wed, 2 Oct 2013 12:58:34 +0200 Subject: [PATCH 46/79] Acrobatics: cosmetic changes --- apps/openmw/mwclass/npc.cpp | 18 +++++++++++------- apps/openmw/mwmechanics/character.cpp | 14 +++++++------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 505c902db..0110bef88 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -7,6 +7,7 @@ #include +#include #include #include "../mwbase/environment.hpp" @@ -771,17 +772,20 @@ namespace MWClass float Npc::getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const { - const float fallDistanceMin = MWBase::Environment::get().getWorld()->getStore().get().find("fFallDamageDistanceMin")->getFloat(); + MWBase::World *world = MWBase::Environment::get().getWorld(); + const MWWorld::Store &gmst = world->getStore().get(); + + const float fallDistanceMin = gmst.find("fFallDamageDistanceMin")->getFloat(); - if (fallHeight>=fallDistanceMin) + if (fallHeight >= fallDistanceMin) { const float acrobaticsSkill = MWWorld::Class::get(ptr).getNpcStats (ptr).getSkill(ESM::Skill::Acrobatics).getModified(); const CustomData *npcdata = static_cast(ptr.getRefData().getCustomData()); - const float jumpSpellBonus = npcdata->mNpcStats.getMagicEffects().get(MWMechanics::EffectKey(9/*jump*/)).mMagnitude; - const float fallAcroBase = MWBase::Environment::get().getWorld()->getStore().get().find("fFallAcroBase")->getFloat(); - const float fallAcroMult = MWBase::Environment::get().getWorld()->getStore().get().find("fFallAcroMult")->getFloat(); - const float fallDistanceBase = MWBase::Environment::get().getWorld()->getStore().get().find("fFallDistanceBase")->getFloat(); - const float fallDistanceMult = MWBase::Environment::get().getWorld()->getStore().get().find("fFallDistanceMult")->getFloat(); + const float jumpSpellBonus = npcdata->mNpcStats.getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::Jump)).mMagnitude; + const float fallAcroBase = gmst.find("fFallAcroBase")->getFloat(); + const float fallAcroMult = gmst.find("fFallAcroMult")->getFloat(); + const float fallDistanceBase = gmst.find("fFallDistanceBase")->getFloat(); + const float fallDistanceMult = gmst.find("fFallDistanceMult")->getFloat(); float x = fallHeight - fallDistanceMin; x -= (1.5 * acrobaticsSkill) + jumpSpellBonus; diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 2753b09c2..efd3b94cc 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -813,17 +813,18 @@ void CharacterController::update(float duration) } // advance acrobatics - MWWorld::Class::get(mPtr).skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 0); + cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 0); // decrease fatigue - const float fatigueJumpBase = MWBase::Environment::get().getWorld()->getStore().get().find("fFatigueJumpBase")->getFloat(); - const float fatigueJumpMult = MWBase::Environment::get().getWorld()->getStore().get().find("fFatigueJumpMult")->getFloat(); + const MWWorld::Store &gmst = world->getStore().get(); + const float fatigueJumpBase = gmst.find("fFatigueJumpBase")->getFloat(); + const float fatigueJumpMult = gmst.find("fFatigueJumpMult")->getFloat(); const float normalizedEncumbrance = cls.getEncumbrance(mPtr) / cls.getCapacity(mPtr); const int fatigueDecrease = fatigueJumpBase + (1 - normalizedEncumbrance) * fatigueJumpMult; - DynamicStat fatigue = cls.getCreatureStats(mPtr).getDynamic(2); + DynamicStat fatigue = cls.getCreatureStats(mPtr).getFatigue(); fatigue.setModified(fatigue.getModified() - fatigueDecrease, 0); fatigue.setCurrent(fatigue.getCurrent() - fatigueDecrease); - cls.getCreatureStats(mPtr).setDynamic(2, fatigue); + cls.getCreatureStats(mPtr).setFatigue(fatigue); } else if(mJumpState == JumpState_Falling) { @@ -838,10 +839,9 @@ void CharacterController::update(float duration) { // inflict fall damages DynamicStat health = cls.getCreatureStats(mPtr).getHealth(); - int current = health.getCurrent(); int realHealthLost = healthLost * (1.0f - 0.25 * 1.25f /* * fatigueTerm */); health.setModified(health.getModified() - realHealthLost, 0); - health.setCurrent(current - realHealthLost); + health.setCurrent(health.getCurrent() - realHealthLost); cls.getCreatureStats(mPtr).setHealth(health); // report acrobatics progression From 4c151e59a26caed2d77d1f74e446472b3e78863c Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Wed, 2 Oct 2013 13:00:47 +0200 Subject: [PATCH 47/79] Acrobatics: do not touch modified stats --- apps/openmw/mwmechanics/character.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index efd3b94cc..14eed2641 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -822,7 +822,6 @@ void CharacterController::update(float duration) const float normalizedEncumbrance = cls.getEncumbrance(mPtr) / cls.getCapacity(mPtr); const int fatigueDecrease = fatigueJumpBase + (1 - normalizedEncumbrance) * fatigueJumpMult; DynamicStat fatigue = cls.getCreatureStats(mPtr).getFatigue(); - fatigue.setModified(fatigue.getModified() - fatigueDecrease, 0); fatigue.setCurrent(fatigue.getCurrent() - fatigueDecrease); cls.getCreatureStats(mPtr).setFatigue(fatigue); } @@ -840,7 +839,6 @@ void CharacterController::update(float duration) // inflict fall damages DynamicStat health = cls.getCreatureStats(mPtr).getHealth(); int realHealthLost = healthLost * (1.0f - 0.25 * 1.25f /* * fatigueTerm */); - health.setModified(health.getModified() - realHealthLost, 0); health.setCurrent(health.getCurrent() - realHealthLost); cls.getCreatureStats(mPtr).setHealth(health); From 2b992ef3b5e8dd27c5b4edee3e98323be230079e Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Wed, 2 Oct 2013 13:02:14 +0200 Subject: [PATCH 48/79] Acrobatics: use calculated fatigueTerm --- apps/openmw/mwmechanics/character.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 14eed2641..5b4d316e5 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -836,9 +836,11 @@ void CharacterController::update(float duration) float healthLost = cls.getFallDamage(mPtr, mFallHeight - mPtr.getRefData().getPosition().pos[2]); if (healthLost > 0.0f) { + const float fatigueTerm = cls.getCreatureStats(mPtr).getFatigueTerm(); + // inflict fall damages DynamicStat health = cls.getCreatureStats(mPtr).getHealth(); - int realHealthLost = healthLost * (1.0f - 0.25 * 1.25f /* * fatigueTerm */); + int realHealthLost = healthLost * (1.0f - 0.25 * fatigueTerm); health.setCurrent(health.getCurrent() - realHealthLost); cls.getCreatureStats(mPtr).setHealth(health); @@ -846,7 +848,7 @@ void CharacterController::update(float duration) cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1); const float acrobaticsSkill = cls.getNpcStats(mPtr).getSkill(ESM::Skill::Acrobatics).getModified(); - if (healthLost > (acrobaticsSkill * 1.25f /* * fatigueTerm */)) + if (healthLost > (acrobaticsSkill * fatigueTerm)) { //TODO: actor falls over } From 6e09a5fb4af2ac97330020f92172c5a712b84356 Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Wed, 2 Oct 2013 22:36:28 +0200 Subject: [PATCH 49/79] Acrobatics: reinit fall height at current height rather than zero To prevent problems. --- apps/openmw/mwmechanics/character.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 5b4d316e5..0924e36b9 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -769,7 +769,7 @@ void CharacterController::update(float duration) if(sneak || inwater || flying) { vec.z = 0.0f; - mFallHeight = 0.0f; + mFallHeight = mPtr.getRefData().getPosition().pos[2]; } if(!onground && !flying && !inwater) @@ -854,7 +854,7 @@ void CharacterController::update(float duration) } } - mFallHeight = 0; + mFallHeight = mPtr.getRefData().getPosition().pos[2]; } else { From 4265dddc40923d1fbcdbb848a0e06a5df4e66308 Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Wed, 2 Oct 2013 22:53:29 +0200 Subject: [PATCH 50/79] Add MWWorld::isSlowFalling(Ptr) --- apps/openmw/mwbase/world.hpp | 1 + apps/openmw/mwworld/worldimp.cpp | 13 +++++++++++++ apps/openmw/mwworld/worldimp.hpp | 1 + 3 files changed, 15 insertions(+) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index f8453afed..db03cb7bf 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -324,6 +324,7 @@ namespace MWBase virtual void processChangedSettings (const Settings::CategorySettingVector& settings) = 0; virtual bool isFlying(const MWWorld::Ptr &ptr) const = 0; + virtual bool isSlowFalling(const MWWorld::Ptr &ptr) const = 0; virtual bool isSwimming(const MWWorld::Ptr &object) const = 0; ///Is the head of the creature underwater? virtual bool isSubmerged(const MWWorld::Ptr &object) const = 0; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index f3d4c81b7..34ac01102 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1582,6 +1582,19 @@ namespace MWWorld return false; } + bool + World::isSlowFalling(const MWWorld::Ptr &ptr) const + { + if(!ptr.getClass().isActor()) + return false; + + const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr); + if(stats.getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::SlowFall)).mMagnitude > 0) + return true; + + return false; + } + bool World::isSubmerged(const MWWorld::Ptr &object) const { float *fpos = object.getRefData().getPosition().pos; diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 53b01f1ab..333beb831 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -355,6 +355,7 @@ namespace MWWorld virtual void processChangedSettings(const Settings::CategorySettingVector& settings); virtual bool isFlying(const MWWorld::Ptr &ptr) const; + virtual bool isSlowFalling(const MWWorld::Ptr &ptr) const; ///Is the head of the creature underwater? virtual bool isSubmerged(const MWWorld::Ptr &object) const; virtual bool isSwimming(const MWWorld::Ptr &object) const; From 2abe5c1c9a304bae549d4591f0c11ccd84286c9b Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Wed, 2 Oct 2013 22:54:36 +0200 Subject: [PATCH 51/79] Acrobatics: do not apply fall damages when slowfalling spell effect is active If spell effect ends up in mid-air, calculate fall height from then. --- apps/openmw/mwmechanics/character.cpp | 10 +++++++++- apps/openmw/mwmechanics/character.hpp | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 0924e36b9..c4260d907 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -776,7 +776,15 @@ void CharacterController::update(float duration) { // The player is in the air (either getting up —ascending part of jump— or falling). - mFallHeight = std::max(mFallHeight, mPtr.getRefData().getPosition().pos[2]); + if (world->isSlowFalling(mPtr)) + { + // SlowFalling spell effect is active, do not keep previous fall height + mFallHeight = mPtr.getRefData().getPosition().pos[2]; + } + else + { + mFallHeight = std::max(mFallHeight, mPtr.getRefData().getPosition().pos[2]); + } const MWWorld::Store &gmst = world->getStore().get(); diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 7b9dda49a..8670b385e 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -3,6 +3,8 @@ #include +#include + #include "../mwworld/ptr.hpp" namespace MWWorld From 75991fedfdc17eacaf0e08c5032ecee550434d16 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 4 Oct 2013 12:33:55 +0200 Subject: [PATCH 52/79] removed some garbage --- issue912 | 1 - 1 file changed, 1 deletion(-) delete mode 100644 issue912 diff --git a/issue912 b/issue912 deleted file mode 100644 index 604cc392c..000000000 --- a/issue912 +++ /dev/null @@ -1 +0,0 @@ -branch for issue912 From 6983a55a16db58c882c654766006ac98a83bc7b3 Mon Sep 17 00:00:00 2001 From: Jordan Ayers Date: Sun, 6 Oct 2013 19:32:40 -0500 Subject: [PATCH 53/79] Magic effect display improvement. Related to Bug #794. Show the "x INT" notation for Fortify Max. Magicka. Show "%" notation for weakness / resistance effects. --- apps/openmw/mwgui/spellicons.cpp | 25 ++++++++++++++++++++----- apps/openmw/mwgui/widgets.cpp | 29 ++++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp index 9812c0f8a..e7a1f32a4 100644 --- a/apps/openmw/mwgui/spellicons.cpp +++ b/apps/openmw/mwgui/spellicons.cpp @@ -171,11 +171,26 @@ namespace MWGui if (!(effect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) { - std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", ""); - std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", ""); - - sourcesDescription += ": " + boost::lexical_cast(effectIt->mMagnitude); - sourcesDescription += " " + ((effectIt->mMagnitude > 1) ? pts : pt); + if (it->first == 84) // special handling for fortify maximum magicka + { + std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", ""); + sourcesDescription += " " + boost::lexical_cast(effectIt->mMagnitude / 10.0f) + timesInt; + } + else + { + std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", ""); + std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", ""); + std::string pct = MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", ""); + const bool usePct = ( + (it->first >= 28 && it->first <= 36) || // Weakness effects + (it->first >= 90 && it->first <= 99) ); // Resistance effects + + sourcesDescription += ": " + boost::lexical_cast(effectIt->mMagnitude) + " "; + if ( usePct ) + sourcesDescription += pct; + else + sourcesDescription += ((effectIt->mMagnitude > 1) ? pts : pt); + } } } diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index dea64ae8c..d435dd6f9 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -405,6 +405,7 @@ namespace MWGui std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", ""); std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", ""); + std::string pct = MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", ""); std::string to = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sTo", "") + " "; std::string sec = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("ssecond", ""); std::string secs = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sseconds", ""); @@ -423,11 +424,33 @@ namespace MWGui if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) { - if (mEffectParams.mMagnMin == mEffectParams.mMagnMax) - spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + " " + ((mEffectParams.mMagnMin == 1) ? pt : pts); + // Fortify Maximum Magicka display rules: + if ( mEffectParams.mEffectID == 84 ) + { + std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", ""); + std::string times = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimes", ""); + if (mEffectParams.mMagnMin == mEffectParams.mMagnMax) + spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin / 10.0f) + timesInt; + else + { + spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin / 10.0f) + times + " " + to + boost::lexical_cast(mEffectParams.mMagnMax / 10.0f) + timesInt; + } + } else { - spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + to + boost::lexical_cast(mEffectParams.mMagnMax) + " " + pts; + const bool usePct = ( + (mEffectParams.mEffectID >= 28 && mEffectParams.mEffectID <= 36) || // Weakness effects + (mEffectParams.mEffectID >= 90 && mEffectParams.mEffectID <= 99) ); // Resistance effects + if (mEffectParams.mMagnMin == mEffectParams.mMagnMax) + spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + " "; + else + { + spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + to + boost::lexical_cast(mEffectParams.mMagnMax) + " "; + } + if ( usePct ) + spellLine += pct; + else + spellLine += ((mEffectParams.mMagnMin == 1 && mEffectParams.mMagnMax == 1) ? pt : pts ); } } From 707f45aa8e758ef34da14cffc83dbf6c992f4008 Mon Sep 17 00:00:00 2001 From: Jordan Ayers Date: Sun, 6 Oct 2013 19:46:04 -0500 Subject: [PATCH 54/79] Magic Effect Display improvement. Related to Bug #794. Always show one decimal point precision for Fortify Max. Magicka effect. --- apps/openmw/mwgui/spellicons.cpp | 7 ++++++- apps/openmw/mwgui/widgets.cpp | 17 +++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp index e7a1f32a4..93727ed7f 100644 --- a/apps/openmw/mwgui/spellicons.cpp +++ b/apps/openmw/mwgui/spellicons.cpp @@ -2,6 +2,9 @@ #include +#include +#include + #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" @@ -174,7 +177,9 @@ namespace MWGui if (it->first == 84) // special handling for fortify maximum magicka { std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", ""); - sourcesDescription += " " + boost::lexical_cast(effectIt->mMagnitude / 10.0f) + timesInt; + std::stringstream formatter; + formatter << std::fixed << std::setprecision(1) << " " << (effectIt->mMagnitude / 10.0f) << timesInt; + sourcesDescription += formatter.str(); } else { diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index d435dd6f9..e46838a64 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -2,6 +2,9 @@ #include +#include +#include + #include #include #include @@ -429,12 +432,14 @@ namespace MWGui { std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", ""); std::string times = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimes", ""); - if (mEffectParams.mMagnMin == mEffectParams.mMagnMax) - spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin / 10.0f) + timesInt; - else - { - spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin / 10.0f) + times + " " + to + boost::lexical_cast(mEffectParams.mMagnMax / 10.0f) + timesInt; - } + std::stringstream formatter; + + formatter << std::fixed << std::setprecision(1) << " " << (mEffectParams.mMagnMin / 10.0f); + if (mEffectParams.mMagnMin != mEffectParams.mMagnMax) + formatter << times << " " << to << " " << (mEffectParams.mMagnMax / 10.0f); + formatter << timesInt; + + spellLine += formatter.str(); } else { From 6303e56ce4521fda92bc25dc6bc32b8ad4bdfcbb Mon Sep 17 00:00:00 2001 From: Jordan Ayers Date: Sun, 6 Oct 2013 20:35:59 -0500 Subject: [PATCH 55/79] Magic Effect Display cleanup: Don't put spaces in percentages. --- apps/openmw/mwgui/spellicons.cpp | 4 ++-- apps/openmw/mwgui/widgets.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp index 93727ed7f..3b3057248 100644 --- a/apps/openmw/mwgui/spellicons.cpp +++ b/apps/openmw/mwgui/spellicons.cpp @@ -190,11 +190,11 @@ namespace MWGui (it->first >= 28 && it->first <= 36) || // Weakness effects (it->first >= 90 && it->first <= 99) ); // Resistance effects - sourcesDescription += ": " + boost::lexical_cast(effectIt->mMagnitude) + " "; + sourcesDescription += ": " + boost::lexical_cast(effectIt->mMagnitude); if ( usePct ) sourcesDescription += pct; else - sourcesDescription += ((effectIt->mMagnitude > 1) ? pts : pt); + sourcesDescription += " " + ((effectIt->mMagnitude > 1) ? pts : pt); } } } diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index e46838a64..e942aa703 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -447,15 +447,15 @@ namespace MWGui (mEffectParams.mEffectID >= 28 && mEffectParams.mEffectID <= 36) || // Weakness effects (mEffectParams.mEffectID >= 90 && mEffectParams.mEffectID <= 99) ); // Resistance effects if (mEffectParams.mMagnMin == mEffectParams.mMagnMax) - spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + " "; + spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin); else { - spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + to + boost::lexical_cast(mEffectParams.mMagnMax) + " "; + spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + to + boost::lexical_cast(mEffectParams.mMagnMax); } if ( usePct ) spellLine += pct; else - spellLine += ((mEffectParams.mMagnMin == 1 && mEffectParams.mMagnMax == 1) ? pt : pts ); + spellLine += " " + ((mEffectParams.mMagnMin == 1 && mEffectParams.mMagnMax == 1) ? pt : pts ); } } From 4d6c3cdf09faf49cd36f9d0607c657f17c8e10b1 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 7 Oct 2013 08:55:04 +0200 Subject: [PATCH 56/79] removed more garbage --- apps/opencs/ocspropertywidget.cpp | 6 ------ apps/opencs/ocspropertywidget.hpp | 18 ------------------ 2 files changed, 24 deletions(-) delete mode 100644 apps/opencs/ocspropertywidget.cpp delete mode 100644 apps/opencs/ocspropertywidget.hpp diff --git a/apps/opencs/ocspropertywidget.cpp b/apps/opencs/ocspropertywidget.cpp deleted file mode 100644 index 68315201a..000000000 --- a/apps/opencs/ocspropertywidget.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "ocspropertywidget.hpp" - -OcsPropertyWidget::OcsPropertyWidget(QObject *parent) : - QObject(parent) -{ -} diff --git a/apps/opencs/ocspropertywidget.hpp b/apps/opencs/ocspropertywidget.hpp deleted file mode 100644 index fc64a0a69..000000000 --- a/apps/opencs/ocspropertywidget.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef OCSPROPERTYWIDGET_HPP -#define OCSPROPERTYWIDGET_HPP - -#include - -class OcsPropertyWidget : public QObject -{ - Q_OBJECT -public: - explicit OcsPropertyWidget(QObject *parent = 0); - -signals: - -public slots: - -}; - -#endif // OCSPROPERTYWIDGET_HPP From 74cee662731d0004adbfdaa657eed3bdc8c45986 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 7 Oct 2013 11:14:11 +0200 Subject: [PATCH 57/79] consolidated magic numbers for button size --- apps/opencs/view/world/scenesubview.cpp | 10 +++++----- apps/opencs/view/world/scenetool.cpp | 6 ++++-- apps/opencs/view/world/scenetool.hpp | 4 +++- apps/opencs/view/world/scenetoolbar.cpp | 10 ++++++++-- apps/opencs/view/world/scenetoolbar.hpp | 5 ++++- apps/opencs/view/world/scenetoolmode.cpp | 8 +++++--- apps/opencs/view/world/scenetoolmode.hpp | 5 ++++- 7 files changed, 33 insertions(+), 15 deletions(-) diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 36ace68f0..e3618c549 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -29,16 +29,16 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D layout2->setContentsMargins (QMargins (0, 0, 0, 0)); - SceneToolbar *toolbar = new SceneToolbar (this); + SceneToolbar *toolbar = new SceneToolbar (48, this); // test -SceneToolMode *tool = new SceneToolMode (this); +SceneToolMode *tool = new SceneToolMode (toolbar); tool->addButton (":door.png", "a"); tool->addButton (":GMST.png", "b"); tool->addButton (":Info.png", "c"); toolbar->addTool (tool); -toolbar->addTool (new SceneToolMode (this)); -toolbar->addTool (new SceneToolMode (this)); -toolbar->addTool (new SceneToolMode (this)); +toolbar->addTool (new SceneToolMode (toolbar)); +toolbar->addTool (new SceneToolMode (toolbar)); +toolbar->addTool (new SceneToolMode (toolbar)); layout2->addWidget (toolbar, 0); /// \todo replace with rendering widget diff --git a/apps/opencs/view/world/scenetool.cpp b/apps/opencs/view/world/scenetool.cpp index d7d37c98f..2140cd1e0 100644 --- a/apps/opencs/view/world/scenetool.cpp +++ b/apps/opencs/view/world/scenetool.cpp @@ -1,10 +1,12 @@ #include "scenetool.hpp" -CSVWorld::SceneTool::SceneTool (QWidget *parent) : QPushButton (parent) +#include "scenetoolbar.hpp" + +CSVWorld::SceneTool::SceneTool (SceneToolbar *parent) : QPushButton (parent) { setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); - setFixedSize (48, 48); + setFixedSize (parent->getButtonSize(), parent->getButtonSize()); connect (this, SIGNAL (clicked()), this, SLOT (openRequest())); } diff --git a/apps/opencs/view/world/scenetool.hpp b/apps/opencs/view/world/scenetool.hpp index d5c9dd5d2..2e83b0c6d 100644 --- a/apps/opencs/view/world/scenetool.hpp +++ b/apps/opencs/view/world/scenetool.hpp @@ -5,6 +5,8 @@ namespace CSVWorld { + class SceneToolbar; + ///< \brief Tool base class class SceneTool : public QPushButton { @@ -12,7 +14,7 @@ namespace CSVWorld public: - SceneTool (QWidget *parent = 0); + SceneTool (SceneToolbar *parent); virtual void showPanel (const QPoint& position) = 0; diff --git a/apps/opencs/view/world/scenetoolbar.cpp b/apps/opencs/view/world/scenetoolbar.cpp index 7c716b5fc..2972c5391 100644 --- a/apps/opencs/view/world/scenetoolbar.cpp +++ b/apps/opencs/view/world/scenetoolbar.cpp @@ -5,9 +5,10 @@ #include "scenetool.hpp" -CSVWorld::SceneToolbar::SceneToolbar (QWidget *parent) : QWidget (parent) +CSVWorld::SceneToolbar::SceneToolbar (int buttonSize, QWidget *parent) +: QWidget (parent), mButtonSize (buttonSize) { - setFixedWidth (48); + setFixedWidth (mButtonSize); mLayout = new QVBoxLayout (this); mLayout->setAlignment (Qt::AlignTop); @@ -20,4 +21,9 @@ CSVWorld::SceneToolbar::SceneToolbar (QWidget *parent) : QWidget (parent) void CSVWorld::SceneToolbar::addTool (SceneTool *tool) { mLayout->addWidget (tool, 0, Qt::AlignTop); +} + +int CSVWorld::SceneToolbar::getButtonSize() const +{ + return mButtonSize; } \ No newline at end of file diff --git a/apps/opencs/view/world/scenetoolbar.hpp b/apps/opencs/view/world/scenetoolbar.hpp index 00631c360..f713ca3df 100644 --- a/apps/opencs/view/world/scenetoolbar.hpp +++ b/apps/opencs/view/world/scenetoolbar.hpp @@ -14,12 +14,15 @@ namespace CSVWorld Q_OBJECT QVBoxLayout *mLayout; + int mButtonSize; public: - SceneToolbar (QWidget *parent); + SceneToolbar (int buttonSize, QWidget *parent = 0); void addTool (SceneTool *tool); + + int getButtonSize() const; }; } diff --git a/apps/opencs/view/world/scenetoolmode.cpp b/apps/opencs/view/world/scenetoolmode.cpp index b4277bcbe..2435a8e35 100644 --- a/apps/opencs/view/world/scenetoolmode.cpp +++ b/apps/opencs/view/world/scenetoolmode.cpp @@ -5,8 +5,10 @@ #include #include -CSVWorld::SceneToolMode::SceneToolMode (QWidget *parent) -: SceneTool (parent) +#include "scenetoolbar.hpp" + +CSVWorld::SceneToolMode::SceneToolMode (SceneToolbar *parent) +: SceneTool (parent), mButtonSize (parent->getButtonSize()) { mPanel = new QFrame (this, Qt::Popup); @@ -27,7 +29,7 @@ void CSVWorld::SceneToolMode::addButton (const std::string& icon, const std::str { QPushButton *button = new QPushButton (QIcon (QPixmap (icon.c_str())), "", mPanel); button->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); - button->setFixedSize (48, 48); + button->setFixedSize (mButtonSize, mButtonSize); mLayout->addWidget (button); diff --git a/apps/opencs/view/world/scenetoolmode.hpp b/apps/opencs/view/world/scenetoolmode.hpp index feee78376..a8fe2b5a6 100644 --- a/apps/opencs/view/world/scenetoolmode.hpp +++ b/apps/opencs/view/world/scenetoolmode.hpp @@ -9,6 +9,8 @@ class QHBoxLayout; namespace CSVWorld { + class SceneToolbar; + ///< \brief Mode selector tool class SceneToolMode : public SceneTool { @@ -17,10 +19,11 @@ namespace CSVWorld QWidget *mPanel; QHBoxLayout *mLayout; std::map mButtons; // widget, id + int mButtonSize; public: - SceneToolMode (QWidget *parent = 0); + SceneToolMode (SceneToolbar *parent); virtual void showPanel (const QPoint& position); From 065f435225c66bb9b51dd4eb0660d8f081b1b6a4 Mon Sep 17 00:00:00 2001 From: Jordan Ayers Date: Mon, 7 Oct 2013 20:02:20 -0500 Subject: [PATCH 58/79] Format fix: remove extra spaces from ranged TimesINT formatting. --- apps/openmw/mwgui/widgets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index e942aa703..9278c1a56 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -436,7 +436,7 @@ namespace MWGui formatter << std::fixed << std::setprecision(1) << " " << (mEffectParams.mMagnMin / 10.0f); if (mEffectParams.mMagnMin != mEffectParams.mMagnMax) - formatter << times << " " << to << " " << (mEffectParams.mMagnMax / 10.0f); + formatter << times << to << (mEffectParams.mMagnMax / 10.0f); formatter << timesInt; spellLine += formatter.str(); From 6ab7002908b66098afc260d6ef3a8f235f58ce17 Mon Sep 17 00:00:00 2001 From: Jordan Ayers Date: Mon, 7 Oct 2013 22:28:55 -0500 Subject: [PATCH 59/79] MagicEffect: Put magnitude type into ESM::MagicEffect helper. --- apps/openmw/mwgui/spellicons.cpp | 41 ++++++++++++++------------------ apps/openmw/mwgui/widgets.cpp | 28 ++++++++-------------- components/esm/loadmgef.cpp | 11 +++++++++ components/esm/loadmgef.hpp | 8 +++++++ 4 files changed, 47 insertions(+), 41 deletions(-) diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp index 3b3057248..0e59230c7 100644 --- a/apps/openmw/mwgui/spellicons.cpp +++ b/apps/openmw/mwgui/spellicons.cpp @@ -172,30 +172,25 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->getGameSettingString( ESM::Attribute::sGmstAttributeIds[effectIt->mKey.mArg], "") + ")"; - if (!(effect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) + int displayType = effect->getMagnitudeDisplayType(); + if (displayType == ESM::MagicEffect::MDT_TimesInt) { - if (it->first == 84) // special handling for fortify maximum magicka - { - std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", ""); - std::stringstream formatter; - formatter << std::fixed << std::setprecision(1) << " " << (effectIt->mMagnitude / 10.0f) << timesInt; - sourcesDescription += formatter.str(); - } - else - { - std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", ""); - std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", ""); - std::string pct = MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", ""); - const bool usePct = ( - (it->first >= 28 && it->first <= 36) || // Weakness effects - (it->first >= 90 && it->first <= 99) ); // Resistance effects - - sourcesDescription += ": " + boost::lexical_cast(effectIt->mMagnitude); - if ( usePct ) - sourcesDescription += pct; - else - sourcesDescription += " " + ((effectIt->mMagnitude > 1) ? pts : pt); - } + std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", ""); + std::stringstream formatter; + formatter << std::fixed << std::setprecision(1) << " " << (effectIt->mMagnitude / 10.0f) << timesInt; + sourcesDescription += formatter.str(); + } + else if ( displayType != ESM::MagicEffect::MDT_None ) + { + std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", ""); + std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", ""); + std::string pct = MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", ""); + + sourcesDescription += ": " + boost::lexical_cast(effectIt->mMagnitude); + if ( displayType == ESM::MagicEffect::MDT_Percentage ) + sourcesDescription += pct; + else // ESM::MagicEffect::MDT_Points + sourcesDescription += " " + ((effectIt->mMagnitude > 1) ? pts : pt); } } diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index 9278c1a56..f3eda4b22 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -425,11 +425,9 @@ namespace MWGui spellLine += " " + MWBase::Environment::get().getWindowManager()->getGameSettingString(ESM::Attribute::sGmstAttributeIds[mEffectParams.mAttribute], ""); } - if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) - { - // Fortify Maximum Magicka display rules: - if ( mEffectParams.mEffectID == 84 ) - { + if (mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) { + int displayType = magicEffect->getMagnitudeDisplayType(); + if ( displayType == ESM::MagicEffect::MDT_TimesInt ) { std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", ""); std::string times = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimes", ""); std::stringstream formatter; @@ -441,20 +439,14 @@ namespace MWGui spellLine += formatter.str(); } - else - { - const bool usePct = ( - (mEffectParams.mEffectID >= 28 && mEffectParams.mEffectID <= 36) || // Weakness effects - (mEffectParams.mEffectID >= 90 && mEffectParams.mEffectID <= 99) ); // Resistance effects - if (mEffectParams.mMagnMin == mEffectParams.mMagnMax) - spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin); - else - { - spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + to + boost::lexical_cast(mEffectParams.mMagnMax); - } - if ( usePct ) + else if ( displayType != ESM::MagicEffect::MDT_None ) { + spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin); + if (mEffectParams.mMagnMin != mEffectParams.mMagnMax) + spellLine += to + boost::lexical_cast(mEffectParams.mMagnMax); + + if ( displayType == ESM::MagicEffect::MDT_Percentage ) spellLine += pct; - else + else // ESM::MagicEffect::MDT_Points spellLine += " " + ((mEffectParams.mMagnMin == 1 && mEffectParams.mMagnMax == 1) ? pt : pts ); } } diff --git a/components/esm/loadmgef.cpp b/components/esm/loadmgef.cpp index 060645b5f..0dfc2be9c 100644 --- a/components/esm/loadmgef.cpp +++ b/components/esm/loadmgef.cpp @@ -274,5 +274,16 @@ short MagicEffect::effectStringToId(const std::string &effect) return name->first; } +MagicEffect::MagnitudeDisplayType MagicEffect::getMagnitudeDisplayType() const { + if ( mData.mFlags & NoMagnitude ) + return MDT_None; + if ( mIndex == 84 ) + return MDT_TimesInt; + if ( ( mIndex >= 28 && mIndex <= 36 ) + || ( mIndex >= 90 && mIndex <= 99 ) ) + return MDT_Percentage; + + return MDT_Points; +} } diff --git a/components/esm/loadmgef.hpp b/components/esm/loadmgef.hpp index b74efb466..c3af56e3a 100644 --- a/components/esm/loadmgef.hpp +++ b/components/esm/loadmgef.hpp @@ -32,6 +32,13 @@ struct MagicEffect Negative = 0x0800 // A harmful effect. Will determine whether // eg. NPCs regard this spell as an attack. (same as 0x10?) }; + enum MagnitudeDisplayType + { + MDT_None, + MDT_Points, + MDT_Percentage, + MDT_TimesInt + }; struct MEDTstruct { @@ -47,6 +54,7 @@ struct MagicEffect static const std::string &effectIdToString(short effectID); static short effectStringToId(const std::string &effect); + MagnitudeDisplayType getMagnitudeDisplayType() const; MEDTstruct mData; From 296b2ab87025c0d26d5010dd38a8b3cb01e2ecda Mon Sep 17 00:00:00 2001 From: Jordan Ayers Date: Tue, 8 Oct 2013 23:55:14 -0500 Subject: [PATCH 60/79] Magic Effect: Recognize other display types. Fill out the list of effects which use percentage formatting. Add in types which use Feet and level labels. --- components/esm/loadmgef.cpp | 9 ++++++++- components/esm/loadmgef.hpp | 4 +++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/components/esm/loadmgef.cpp b/components/esm/loadmgef.cpp index 0dfc2be9c..19d535600 100644 --- a/components/esm/loadmgef.cpp +++ b/components/esm/loadmgef.cpp @@ -279,8 +279,15 @@ MagicEffect::MagnitudeDisplayType MagicEffect::getMagnitudeDisplayType() const { return MDT_None; if ( mIndex == 84 ) return MDT_TimesInt; + if ( mIndex == 59 || + ( mIndex >= 64 && mIndex <= 66) ) + return MDT_Feet; + if ( mIndex == 118 || mIndex == 119 ) + return MDT_Level; if ( ( mIndex >= 28 && mIndex <= 36 ) - || ( mIndex >= 90 && mIndex <= 99 ) ) + || ( mIndex >= 90 && mIndex <= 99 ) + || mIndex == 40 || mIndex == 47 + || mIndex == 57 || mIndex == 68 ) return MDT_Percentage; return MDT_Points; diff --git a/components/esm/loadmgef.hpp b/components/esm/loadmgef.hpp index c3af56e3a..f139fa32c 100644 --- a/components/esm/loadmgef.hpp +++ b/components/esm/loadmgef.hpp @@ -35,8 +35,10 @@ struct MagicEffect enum MagnitudeDisplayType { MDT_None, - MDT_Points, + MDT_Feet, + MDT_Level, MDT_Percentage, + MDT_Points, MDT_TimesInt }; From 6e4978643c7e209e0b2a82af0fdf04aa44c50bf4 Mon Sep 17 00:00:00 2001 From: Jordan Ayers Date: Wed, 9 Oct 2013 00:08:11 -0500 Subject: [PATCH 61/79] Magic Effect descriptions: support feet / level modes. Show proper suffixes for all magnitudes. Drop extra 'times' symbol in 'timesInt format (not consistent with other magnitude displays). --- apps/openmw/mwgui/spellicons.cpp | 23 ++++++++++++++++------- apps/openmw/mwgui/widgets.cpp | 12 +++++++++--- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp index 0e59230c7..0c303485a 100644 --- a/apps/openmw/mwgui/spellicons.cpp +++ b/apps/openmw/mwgui/spellicons.cpp @@ -172,7 +172,7 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->getGameSettingString( ESM::Attribute::sGmstAttributeIds[effectIt->mKey.mArg], "") + ")"; - int displayType = effect->getMagnitudeDisplayType(); + ESM::MagicEffect::MagnitudeDisplayType displayType = effect->getMagnitudeDisplayType(); if (displayType == ESM::MagicEffect::MDT_TimesInt) { std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", ""); @@ -182,15 +182,24 @@ namespace MWGui } else if ( displayType != ESM::MagicEffect::MDT_None ) { - std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", ""); - std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", ""); - std::string pct = MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", ""); - sourcesDescription += ": " + boost::lexical_cast(effectIt->mMagnitude); + if ( displayType == ESM::MagicEffect::MDT_Percentage ) - sourcesDescription += pct; + sourcesDescription += MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", ""); + else if ( displayType == ESM::MagicEffect::MDT_Feet ) + sourcesDescription += " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sfeet", ""); + else if ( displayType == ESM::MagicEffect::MDT_Level ) + { + sourcesDescription += " " + ((effectIt->mMagnitude > 1) ? + MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevels", "") : + MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevel", "") ); + } else // ESM::MagicEffect::MDT_Points - sourcesDescription += " " + ((effectIt->mMagnitude > 1) ? pts : pt); + { + sourcesDescription += " " + ((effectIt->mMagnitude > 1) ? + MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", "") : + MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", "") ); + } } } diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index f3eda4b22..3fc3187e8 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -409,6 +409,9 @@ namespace MWGui std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", ""); std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", ""); std::string pct = MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", ""); + std::string ft = MWBase::Environment::get().getWindowManager()->getGameSettingString("sfeet", ""); + std::string lvl = MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevel", ""); + std::string lvls = MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevels", ""); std::string to = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sTo", "") + " "; std::string sec = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("ssecond", ""); std::string secs = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sseconds", ""); @@ -426,15 +429,14 @@ namespace MWGui } if (mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) { - int displayType = magicEffect->getMagnitudeDisplayType(); + ESM::MagicEffect::MagnitudeDisplayType displayType = magicEffect->getMagnitudeDisplayType(); if ( displayType == ESM::MagicEffect::MDT_TimesInt ) { std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", ""); - std::string times = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimes", ""); std::stringstream formatter; formatter << std::fixed << std::setprecision(1) << " " << (mEffectParams.mMagnMin / 10.0f); if (mEffectParams.mMagnMin != mEffectParams.mMagnMax) - formatter << times << to << (mEffectParams.mMagnMax / 10.0f); + formatter << to << (mEffectParams.mMagnMax / 10.0f); formatter << timesInt; spellLine += formatter.str(); @@ -446,6 +448,10 @@ namespace MWGui if ( displayType == ESM::MagicEffect::MDT_Percentage ) spellLine += pct; + else if ( displayType == ESM::MagicEffect::MDT_Feet ) + spellLine += " " + ft; + else if ( displayType == ESM::MagicEffect::MDT_Level ) + spellLine += " " + ((mEffectParams.mMagnMin == 1 && mEffectParams.mMagnMax == 1) ? lvl : lvls ); else // ESM::MagicEffect::MDT_Points spellLine += " " + ((mEffectParams.mMagnMin == 1 && mEffectParams.mMagnMax == 1) ? pt : pts ); } From 5ce1f50fab6456afcd5adc781a0e141ea13e6e5b Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Thu, 10 Oct 2013 23:06:37 +0200 Subject: [PATCH 62/79] Cleanup in MWGui::WindowManager constructor initialzation list. Corrected order of initialization list, and added missing member field initializations - without this openmw crashes when installer is interrupted and there are no valid data path in openmw.cfg, as reported by BrotherBrick in: https://forum.openmw.org/viewtopic.php?f=20&p=19501#p19499 Signed-off-by: Lukasz Gromanowski --- apps/openmw/mwgui/windowmanagerimp.cpp | 33 ++++++++++++++++---------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index bf8b664da..4b4d2dfd1 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -61,20 +61,23 @@ namespace MWGui const Compiler::Extensions& extensions, int fpsLevel, OEngine::Render::OgreRenderer *ogre, const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, ToUTF8::FromType encoding) - : mGuiManager(NULL) - , mConsoleOnlyScripts(consoleOnlyScripts) + : mConsoleOnlyScripts(consoleOnlyScripts) + , mGuiManager(NULL) , mRendering(ogre) , mHud(NULL) , mMap(NULL) , mMenu(NULL) - , mStatsWindow(NULL) , mToolTips(NULL) + , mStatsWindow(NULL) , mMessageBoxManager(NULL) , mConsole(NULL) , mJournal(NULL) , mDialogueWindow(NULL) - , mBookWindow(NULL) + , mContainerWindow(NULL) + , mDragAndDrop(NULL) + , mInventoryWindow(NULL) , mScrollWindow(NULL) + , mBookWindow(NULL) , mCountDialog(NULL) , mTradeWindow(NULL) , mSpellBuyingWindow(NULL) @@ -83,27 +86,37 @@ namespace MWGui , mConfirmationDialog(NULL) , mAlchemyWindow(NULL) , mSpellWindow(NULL) + , mQuickKeysMenu(NULL) , mLoadingScreen(NULL) - , mCharGen(NULL) , mLevelupDialog(NULL) , mWaitDialog(NULL) , mSpellCreationDialog(NULL) , mEnchantingDialog(NULL) , mTrainingWindow(NULL) , mMerchantRepair(NULL) - , mRepair(NULL) , mSoulgemDialog(NULL) + , mRepair(NULL) , mCompanionWindow(NULL) + , mTranslationDataStorage (translationDataStorage) + , mSoftwareCursor(NULL) + , mCharGen(NULL) + , mInputBlocker(NULL) + , mCrosshairEnabled(Settings::Manager::getBool ("crosshair", "HUD")) + , mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI")) + , mHudEnabled(true) + , mCursorVisible(true) , mPlayerName() , mPlayerRaceId() , mPlayerAttributes() - , mPlayerMajorSkills() , mPlayerMinorSkills() + , mPlayerMajorSkills() , mPlayerSkillValues() , mPlayerHealth() , mPlayerMagicka() , mPlayerFatigue() , mGui(NULL) + , mGuiModes() + , mCursorManager(NULL) , mGarbageDialogs() , mShown(GW_ALL) , mForceHidden(GW_None) @@ -113,13 +126,7 @@ namespace MWGui , mFPS(0.0f) , mTriangleCount(0) , mBatchCount(0) - , mCrosshairEnabled(Settings::Manager::getBool ("crosshair", "HUD")) - , mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI")) - , mHudEnabled(true) - , mTranslationDataStorage (translationDataStorage) - , mCursorManager(NULL) , mUseHardwareCursors(Settings::Manager::getBool("hardware cursors", "GUI")) - , mCursorVisible(true) { // Set up the GUI system mGuiManager = new OEngine::GUI::MyGUIManager(mRendering->getWindow(), mRendering->getScene(), false, logpath); From a77044cda43e368789bfd036978eb2aa78bb8e66 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 12 Oct 2013 16:15:47 +0200 Subject: [PATCH 63/79] fixed column numbering --- apps/opencs/model/world/columns.cpp | 2 +- apps/opencs/model/world/columns.hpp | 214 ++++++++++++++-------------- 2 files changed, 108 insertions(+), 108 deletions(-) diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 25047807a..ca37840ad 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -51,7 +51,7 @@ namespace CSMWorld { ColumnId_FactionIndex, "Faction Index" }, { ColumnId_Charges, "Charges" }, { ColumnId_Enchantment, "Enchantment" }, - { ColumnId_Value, "Coin Value" }, + { ColumnId_CoinValue, "Coin Value" }, { ColumnId_Teleport, "Teleport" }, { ColumnId_TeleportCell, "Teleport Cell" }, { ColumnId_LockLevel, "Lock Level" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 582f5102b..9b26cac4c 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -45,113 +45,113 @@ namespace CSMWorld ColumnId_Charges = 32, ColumnId_Enchantment = 33, ColumnId_CoinValue = 34, - ColumnId_Teleport = 25, - ColumnId_TeleportCell = 26, - ColumnId_LockLevel = 27, - ColumnId_Key = 28, - ColumnId_Trap = 29, - ColumnId_BeastRace = 30, - ColumnId_AutoCalc = 31, - ColumnId_StarterSpell = 32, - ColumnId_AlwaysSucceeds = 33, - ColumnId_SleepForbidden = 34, - ColumnId_InteriorWater = 35, - ColumnId_InteriorSky = 36, - ColumnId_Model = 37, - ColumnId_Script = 38, - ColumnId_Icon = 39, - ColumnId_Weight = 40, - ColumnId_EnchantmentPoints = 31, - ColumnId_Quality = 32, - ColumnId_Ai = 33, - ColumnId_AiHello = 34, - ColumnId_AiFlee = 35, - ColumnId_AiFight = 36, - ColumnId_AiAlarm = 37, - ColumnId_BuysWeapons = 38, - ColumnId_BuysArmor = 39, - ColumnId_BuysClothing = 40, - ColumnId_BuysBooks = 41, - ColumnId_BuysIngredients = 42, - ColumnId_BuysLockpicks = 43, - ColumnId_BuysProbes = 44, - ColumnId_BuysLights = 45, - ColumnId_BuysApparati = 46, - ColumnId_BuysRepairItems = 47, - ColumnId_BuysMiscItems = 48, - ColumnId_BuysPotions = 49, - ColumnId_BuysMagicItems = 50, - ColumnId_SellsSpells = 51, - ColumnId_Trainer = 52, - ColumnId_Spellmaking = 53, - ColumnId_EnchantingService = 54, - ColumnId_RepairService = 55, - ColumnId_ApparatusType = 56, - ColumnId_ArmorType = 57, - ColumnId_Health = 58, - ColumnId_ArmorValue = 59, - ColumnId_Scroll = 60, - ColumnId_ClothingType = 61, - ColumnId_WeightCapacity = 62, - ColumnId_OrganicContainer = 63, - ColumnId_Respawn = 64, - ColumnId_CreatureType = 65, - ColumnId_SoulPoints = 66, - ColumnId_OriginalCreature = 67, - ColumnId_Biped = 68, - ColumnId_HasWeapon = 69, - ColumnId_NoMovement = 70, - ColumnId_Swims = 71, - ColumnId_Flies = 72, - ColumnId_Walks = 73, - ColumnId_Essential = 74, - ColumnId_SkeletonBlood = 75, - ColumnId_MetalBlood = 76, - ColumnId_OpenSound = 77, - ColumnId_CloseSound = 78, - ColumnId_Duration = 79, - ColumnId_Radius = 80, - ColumnId_Colour = 81, - ColumnId_Sound = 82, - ColumnId_Dynamic = 83, - ColumnId_Portable = 84, - ColumnId_NegativeLight = 85, - ColumnId_Flickering = 86, - ColumnId_SlowFlickering = 87, - ColumnId_Pulsing = 88, - ColumnId_SlowPulsing = 89, - ColumnId_Fire = 90, - ColumnId_OffByDefault = 91, - ColumnId_IsKey = 92, - ColumnId_Race = 93, - ColumnId_Class = 94, - Columnid_Hair = 95, - ColumnId_Head = 96, - ColumnId_Female = 97, - ColumnId_WeaponType = 98, - ColumnId_WeaponSpeed = 99, - ColumnId_WeaponReach = 100, - ColumnId_MinChop = 101, - ColumnId_MaxChip = 102, - Columnid_MinSlash = 103, - ColumnId_MaxSlash = 104, - ColumnId_MinThrust = 105, - ColumnId_MaxThrust = 106, - ColumnId_Magical = 107, - ColumnId_Silver = 108, - ColumnId_Filter = 109, - ColumnId_PositionXPos = 110, - ColumnId_PositionYPos = 111, - ColumnId_PositionZPos = 112, - ColumnId_PositionXRot = 113, - ColumnId_PositionYRot = 114, - ColumnId_PositionZRot = 115, - ColumnId_DoorPositionXPos = 116, - ColumnId_DoorPositionYPos = 117, - ColumnId_DoorPositionZPos = 118, - ColumnId_DoorPositionXRot = 119, - ColumnId_DoorPositionYRot = 120, - ColumnId_DoorPositionZRot = 121, + ColumnId_Teleport = 35, + ColumnId_TeleportCell = 36, + ColumnId_LockLevel = 37, + ColumnId_Key = 38, + ColumnId_Trap = 39, + ColumnId_BeastRace = 40, + ColumnId_AutoCalc = 41, + ColumnId_StarterSpell = 42, + ColumnId_AlwaysSucceeds = 43, + ColumnId_SleepForbidden = 44, + ColumnId_InteriorWater = 45, + ColumnId_InteriorSky = 46, + ColumnId_Model = 47, + ColumnId_Script = 48, + ColumnId_Icon = 49, + ColumnId_Weight = 50, + ColumnId_EnchantmentPoints = 51, + ColumnId_Quality = 52, + ColumnId_Ai = 53, + ColumnId_AiHello = 54, + ColumnId_AiFlee = 55, + ColumnId_AiFight = 56, + ColumnId_AiAlarm = 57, + ColumnId_BuysWeapons = 58, + ColumnId_BuysArmor = 59, + ColumnId_BuysClothing = 60, + ColumnId_BuysBooks = 61, + ColumnId_BuysIngredients = 62, + ColumnId_BuysLockpicks = 63, + ColumnId_BuysProbes = 64, + ColumnId_BuysLights = 65, + ColumnId_BuysApparati = 66, + ColumnId_BuysRepairItems = 67, + ColumnId_BuysMiscItems = 68, + ColumnId_BuysPotions = 69, + ColumnId_BuysMagicItems = 70, + ColumnId_SellsSpells = 71, + ColumnId_Trainer = 72, + ColumnId_Spellmaking = 73, + ColumnId_EnchantingService = 74, + ColumnId_RepairService = 75, + ColumnId_ApparatusType = 76, + ColumnId_ArmorType = 77, + ColumnId_Health = 78, + ColumnId_ArmorValue = 79, + ColumnId_Scroll = 80, + ColumnId_ClothingType = 81, + ColumnId_WeightCapacity = 82, + ColumnId_OrganicContainer = 83, + ColumnId_Respawn = 84, + ColumnId_CreatureType = 85, + ColumnId_SoulPoints = 86, + ColumnId_OriginalCreature = 87, + ColumnId_Biped = 88, + ColumnId_HasWeapon = 89, + ColumnId_NoMovement = 90, + ColumnId_Swims = 91, + ColumnId_Flies = 92, + ColumnId_Walks = 93, + ColumnId_Essential = 94, + ColumnId_SkeletonBlood = 95, + ColumnId_MetalBlood = 96, + ColumnId_OpenSound = 97, + ColumnId_CloseSound = 98, + ColumnId_Duration = 99, + ColumnId_Radius = 100, + ColumnId_Colour = 101, + ColumnId_Sound = 102, + ColumnId_Dynamic = 103, + ColumnId_Portable = 104, + ColumnId_NegativeLight = 105, + ColumnId_Flickering = 106, + ColumnId_SlowFlickering = 107, + ColumnId_Pulsing = 108, + ColumnId_SlowPulsing = 109, + ColumnId_Fire = 110, + ColumnId_OffByDefault = 111, + ColumnId_IsKey = 112, + ColumnId_Race = 113, + ColumnId_Class = 114, + Columnid_Hair = 115, + ColumnId_Head = 116, + ColumnId_Female = 117, + ColumnId_WeaponType = 118, + ColumnId_WeaponSpeed = 119, + ColumnId_WeaponReach = 120, + ColumnId_MinChop = 121, + ColumnId_MaxChip = 122, + Columnid_MinSlash = 123, + ColumnId_MaxSlash = 124, + ColumnId_MinThrust = 125, + ColumnId_MaxThrust = 126, + ColumnId_Magical = 127, + ColumnId_Silver = 128, + ColumnId_Filter = 129, + ColumnId_PositionXPos = 130, + ColumnId_PositionYPos = 131, + ColumnId_PositionZPos = 132, + ColumnId_PositionXRot = 133, + ColumnId_PositionYRot = 134, + ColumnId_PositionZRot = 135, + ColumnId_DoorPositionXPos = 136, + ColumnId_DoorPositionYPos = 137, + ColumnId_DoorPositionZPos = 138, + ColumnId_DoorPositionXRot = 139, + ColumnId_DoorPositionYRot = 140, + ColumnId_DoorPositionZRot = 141, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. From a29b8667efc3485e33e83d63ccf680d300ddc6a6 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 12 Oct 2013 16:29:36 +0200 Subject: [PATCH 64/79] fixed string filter on boolean columns when testing against the value false --- apps/opencs/model/filter/textnode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/filter/textnode.cpp b/apps/opencs/model/filter/textnode.cpp index f3d98ce53..133208b31 100644 --- a/apps/opencs/model/filter/textnode.cpp +++ b/apps/opencs/model/filter/textnode.cpp @@ -47,7 +47,7 @@ bool CSMFilter::TextNode::test (const CSMWorld::IdTable& table, int row, } else if (data.type()==QVariant::Bool) { - string = data.toBool() ? "true" : " false"; + string = data.toBool() ? "true" : "false"; } else return false; From b5d620a8dcb9ea6a9cdcacab70784ebfce78d3f8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 12 Oct 2013 16:35:59 +0200 Subject: [PATCH 65/79] fixed string filter on enum column when column is empty --- apps/opencs/model/filter/textnode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/filter/textnode.cpp b/apps/opencs/model/filter/textnode.cpp index 133208b31..e335f7ea7 100644 --- a/apps/opencs/model/filter/textnode.cpp +++ b/apps/opencs/model/filter/textnode.cpp @@ -34,7 +34,7 @@ bool CSMFilter::TextNode::test (const CSMWorld::IdTable& table, int row, { string = data.toString(); } - else if (data.type()==QVariant::Int || data.type()==QVariant::UInt || + else if ((data.type()==QVariant::Int || data.type()==QVariant::UInt) && CSMWorld::Columns::hasEnums (static_cast (mColumnId))) { int value = data.toInt(); From cfc30933202a7804be0c5ff5a5de23f908175218 Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Sat, 12 Oct 2013 10:46:44 -0400 Subject: [PATCH 66/79] Reverted conditional compiling --- apps/launcher/main.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index df7aa11d4..f67f5edcf 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -62,14 +62,3 @@ int main(int argc, char *argv[]) return returnValue; } -#ifdef _WINDOWS -// If the system compiles for main(), then main will be used. -// If it wants WinMain, this will call main anyways. -int _stdcall WinMain(struct HINSTANCE__ *hInstance, - struct HINSTANCE__ *hPrevInstance, - char *lpszCmdLine, - int nCmdShow) -{ - return main(__argc, __argv); -} -#endif \ No newline at end of file From 141382b8c0b879803bffa0e41f54556b2f9f3d6c Mon Sep 17 00:00:00 2001 From: Jordan Ayers Date: Sat, 12 Oct 2013 14:48:37 -0500 Subject: [PATCH 67/79] COC Command: Exterior cell selection fix. Return the northernmost cell of the easternmost matching column for Ext. cells. --- apps/openmw/mwworld/store.hpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index 2ee23dbd6..90452f661 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -656,26 +656,38 @@ namespace MWWorld return iterator(mSharedExt.end()); } - /// \todo implement appropriate index + // Return the northernmost cell in the easternmost column. const ESM::Cell *searchExtByName(const std::string &id) const { + ESM::Cell *cell = 0; std::vector::const_iterator it = mSharedExt.begin(); for (; it != mSharedExt.end(); ++it) { if (Misc::StringUtils::ciEqual((*it)->mName, id)) { - return *it; + if ( cell == 0 || + ( (*it)->mData.mX > cell->mData.mX ) || + ( (*it)->mData.mX == cell->mData.mX && (*it)->mData.mY > cell->mData.mY ) ) + { + cell = *it; + } } } - return 0; + return cell; } - /// \todo implement appropriate index + // Return the northernmost cell in the easternmost column. const ESM::Cell *searchExtByRegion(const std::string &id) const { + ESM::Cell *cell = 0; std::vector::const_iterator it = mSharedExt.begin(); for (; it != mSharedExt.end(); ++it) { if (Misc::StringUtils::ciEqual((*it)->mRegion, id)) { - return *it; + if ( cell == 0 || + ( (*it)->mData.mX > cell->mData.mX ) || + ( (*it)->mData.mX == cell->mData.mX && (*it)->mData.mY > cell->mData.mY ) ) + { + cell = *it; + } } } - return 0; + return cell; } size_t getSize() const { From dcfff7946064b47610b9c88b4133b4cce2cc524f Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Sun, 13 Oct 2013 00:32:28 +0200 Subject: [PATCH 68/79] Regenerate fatigue over time --- apps/openmw/mwmechanics/actors.cpp | 52 +++++++++++++++++------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index f9b5b695a..70b820f8c 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -31,11 +31,14 @@ namespace MWMechanics calculateDynamicStats (ptr); calculateCreatureStatModifiers (ptr); - // AI if(!MWBase::Environment::get().getWindowManager()->isGuiMode()) { + // AI CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr); creatureStats.getAiSequence().execute (ptr); + + // fatigue restoration + calculateRestoration(ptr, duration); } } @@ -93,39 +96,29 @@ namespace MWMechanics void Actors::calculateRestoration (const MWWorld::Ptr& ptr, float duration) { CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr); + const MWWorld::Store& settings = MWBase::Environment::get().getWorld()->getStore().get(); + + int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified (); + + float capacity = MWWorld::Class::get(ptr).getCapacity(ptr); + float encumbrance = MWWorld::Class::get(ptr).getEncumbrance(ptr); + float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity); + if (normalizedEncumbrance > 1) + normalizedEncumbrance = 1; if (duration == 3600) { - bool stunted = stats.getMagicEffects ().get(MWMechanics::EffectKey(ESM::MagicEffect::StuntedMagicka)).mMagnitude > 0; + // the actor is sleeping, restore health and magicka - int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified (); + bool stunted = stats.getMagicEffects ().get(MWMechanics::EffectKey(ESM::MagicEffect::StuntedMagicka)).mMagnitude > 0; DynamicStat health = stats.getHealth(); health.setCurrent (health.getCurrent() + 0.1 * endurance); stats.setHealth (health); - const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - - float fFatigueReturnBase = store.get().find("fFatigueReturnBase")->getFloat (); - float fFatigueReturnMult = store.get().find("fFatigueReturnMult")->getFloat (); - float fEndFatigueMult = store.get().find("fEndFatigueMult")->getFloat (); - - float capacity = MWWorld::Class::get(ptr).getCapacity(ptr); - float encumbrance = MWWorld::Class::get(ptr).getEncumbrance(ptr); - float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity); - if (normalizedEncumbrance > 1) - normalizedEncumbrance = 1; - - float x = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance); - x *= fEndFatigueMult * endurance; - - DynamicStat fatigue = stats.getFatigue(); - fatigue.setCurrent (fatigue.getCurrent() + 3600 * x); - stats.setFatigue (fatigue); - if (!stunted) { - float fRestMagicMult = store.get().find("fRestMagicMult")->getFloat (); + float fRestMagicMult = settings.find("fRestMagicMult")->getFloat (); DynamicStat magicka = stats.getMagicka(); magicka.setCurrent (magicka.getCurrent() @@ -133,6 +126,19 @@ namespace MWMechanics stats.setMagicka (magicka); } } + + // restore fatigue + + float fFatigueReturnBase = settings.find("fFatigueReturnBase")->getFloat (); + float fFatigueReturnMult = settings.find("fFatigueReturnMult")->getFloat (); + float fEndFatigueMult = settings.find("fEndFatigueMult")->getFloat (); + + float x = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance); + x *= fEndFatigueMult * endurance; + + DynamicStat fatigue = stats.getFatigue(); + fatigue.setCurrent (fatigue.getCurrent() + duration * x); + stats.setFatigue (fatigue); } void Actors::calculateCreatureStatModifiers (const MWWorld::Ptr& ptr) From c8d0fb8c4e6a5a1230261c661b3c7b1fda47537b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 13 Oct 2013 14:43:59 +0200 Subject: [PATCH 69/79] updated credits file --- credits.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/credits.txt b/credits.txt index 6e8e36612..bd0c6ca74 100644 --- a/credits.txt +++ b/credits.txt @@ -12,6 +12,7 @@ Marc Zinnschlag (Zini) - Lead Programmer/Project Manager Adam Hogan (aurix) Aleksandar Jovanov +Alex Haddad (rainChu) Alex McKibben (WeirdSexy) Alexander Nadeau (wareya) Alexander Olofsson (Ace) From 4624bed899568f8465399048502b1e0ef9aa073c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 13 Oct 2013 15:41:48 +0200 Subject: [PATCH 70/79] changed handling of scene toolbar button icons --- apps/opencs/view/world/scenetool.cpp | 5 ----- apps/opencs/view/world/scenetool.hpp | 4 ---- apps/opencs/view/world/scenetoolmode.cpp | 5 ++++- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/apps/opencs/view/world/scenetool.cpp b/apps/opencs/view/world/scenetool.cpp index 2140cd1e0..320deb1ba 100644 --- a/apps/opencs/view/world/scenetool.cpp +++ b/apps/opencs/view/world/scenetool.cpp @@ -11,11 +11,6 @@ CSVWorld::SceneTool::SceneTool (SceneToolbar *parent) : QPushButton (parent) connect (this, SIGNAL (clicked()), this, SLOT (openRequest())); } -void CSVWorld::SceneTool::updateIcon (const QIcon& icon) -{ - setIcon (icon); -} - void CSVWorld::SceneTool::openRequest() { showPanel (parentWidget()->mapToGlobal (pos())); diff --git a/apps/opencs/view/world/scenetool.hpp b/apps/opencs/view/world/scenetool.hpp index 2e83b0c6d..07e8b58d7 100644 --- a/apps/opencs/view/world/scenetool.hpp +++ b/apps/opencs/view/world/scenetool.hpp @@ -18,10 +18,6 @@ namespace CSVWorld virtual void showPanel (const QPoint& position) = 0; - protected slots: - - void updateIcon (const QIcon& icon); - private slots: void openRequest(); diff --git a/apps/opencs/view/world/scenetoolmode.cpp b/apps/opencs/view/world/scenetoolmode.cpp index 2435a8e35..281d703b6 100644 --- a/apps/opencs/view/world/scenetoolmode.cpp +++ b/apps/opencs/view/world/scenetoolmode.cpp @@ -36,6 +36,9 @@ void CSVWorld::SceneToolMode::addButton (const std::string& icon, const std::str mButtons.insert (std::make_pair (button, id)); connect (button, SIGNAL (clicked()), this, SLOT (selected())); + + if (mButtons.size()==1) + setIcon (button->icon()); } void CSVWorld::SceneToolMode::selected() @@ -47,7 +50,7 @@ void CSVWorld::SceneToolMode::selected() { mPanel->hide(); - emit updateIcon (iter->first->icon()); + setIcon (iter->first->icon()); emit modeChanged (iter->second); } } \ No newline at end of file From f504ab42feb40382228390b4b3a62874303b3de0 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 13 Oct 2013 17:52:14 +0200 Subject: [PATCH 71/79] Turn off vsync while in the loading screen --- apps/openmw/mwgui/loadingscreen.cpp | 22 +++++++++++++++++++++- apps/openmw/mwgui/loadingscreen.hpp | 2 ++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index 9b63dfa76..d2ebcd109 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -23,6 +23,7 @@ namespace MWGui , mLastWallpaperChangeTime(0.f) , mFirstLoad(true) , mProgress(0) + , mVSyncWasEnabled(false) { getWidget(mLoadingText, "LoadingText"); getWidget(mProgressBar, "ProgressBar"); @@ -67,6 +68,14 @@ namespace MWGui void LoadingScreen::loadingOn() { + // Temporarily turn off VSync, we want to do actual loading rather than waiting for the screen to sync. + // Threaded loading would be even better, of course - especially because some drivers force VSync to on and we can't change it. + // In Ogre 1.8, the swapBuffers argument is useless and setVSyncEnabled is bugged with GLX, nothing we can do :/ + mVSyncWasEnabled = mWindow->isVSyncEnabled(); + #if OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) + mWindow->setVSyncEnabled(false); + #endif + setVisible(true); if (mFirstLoad) @@ -83,6 +92,12 @@ namespace MWGui void LoadingScreen::loadingOff() { + // Re-enable vsync now. + // In Ogre 1.8, the swapBuffers argument is useless and setVSyncEnabled is bugged with GLX, nothing we can do :/ + #if OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) + mWindow->setVSyncEnabled(mVSyncWasEnabled); + #endif + setVisible(false); MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Loading); @@ -212,7 +227,12 @@ namespace MWGui // caused a sync / flush and would be expensive). // We're doing this so we can do some actual loading while the GPU is busy with the render. // This means the render is lagging a frame behind, but this is hardly noticable. - mWindow->swapBuffers(false); // never Vsync, makes no sense here +#if OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) + mWindow->swapBuffers(); +#else + // In Ogre 1.8, the swapBuffers argument is useless and setVSyncEnabled is bugged when using GLX. Not much we can do :/ + mWindow->swapBuffers(false); +#endif mWindow->update(false); if (!hasCompositor) diff --git a/apps/openmw/mwgui/loadingscreen.hpp b/apps/openmw/mwgui/loadingscreen.hpp index dde8ff63a..2d1d7431f 100644 --- a/apps/openmw/mwgui/loadingscreen.hpp +++ b/apps/openmw/mwgui/loadingscreen.hpp @@ -57,6 +57,8 @@ namespace MWGui Ogre::StringVector mResources; + bool mVSyncWasEnabled; + void changeWallpaper(); void draw(); From fa264935ff2ff9d05a7da8334e8836fa53a088ea Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 13 Oct 2013 17:56:26 +0200 Subject: [PATCH 72/79] We can apply vsync at runtime now that the Ogre bug is fixed. --- apps/openmw/mwgui/settingswindow.cpp | 4 ++++ apps/openmw/mwrender/renderingmanager.cpp | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index 3dfa17bad..923b9d01d 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -363,8 +363,12 @@ namespace MWGui else if (_sender == mVSyncButton) { Settings::Manager::setBool("vsync", "Video", newState); + // Ogre::Window::setVSyncEnabled is bugged in 1.8 +#if OGRE_VERSION < (1 << 16 | 9 << 8 | 0) MWBase::Environment::get().getWindowManager()-> messageBox("VSync will be applied after a restart", std::vector()); +#endif + apply(); } else { diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index e03b2ccfc..8396e70d7 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -760,6 +760,13 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec || it->second == "resolution y" || it->second == "fullscreen")) changeRes = true; + else if (it->first == "Video" && it->second == "vsync") + { + // setVSyncEnabled is bugged in 1.8 +#if OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) + mRendering.getWindow()->setVSyncEnabled(Settings::Manager::getBool("vsync", "Video")); +#endif + } else if (it->second == "field of view" && it->first == "General") mRendering.setFov(Settings::Manager::getFloat("field of view", "General")); else if ((it->second == "texture filtering" && it->first == "General") From 2fb059e2fa067f34efc88b8cfb23aafe3f138e55 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 13 Oct 2013 18:20:55 +0200 Subject: [PATCH 73/79] Don't destroy the SDL window twice --- extern/sdl4ogre/sdlinputwrapper.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index 931d6aca3..df74bba3b 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -30,9 +30,6 @@ namespace SFO InputWrapper::~InputWrapper() { - if(mSDLWindow != NULL) - SDL_DestroyWindow(mSDLWindow); - mSDLWindow = NULL; } void InputWrapper::capture(bool windowEventsOnly) From 683ad40e219f30650440ddee577cec14cf30e4fe Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 13 Oct 2013 18:28:22 +0200 Subject: [PATCH 74/79] No need for this ifdef since there is a default argument. --- apps/openmw/mwgui/loadingscreen.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index d2ebcd109..4bd383c2f 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -227,12 +227,8 @@ namespace MWGui // caused a sync / flush and would be expensive). // We're doing this so we can do some actual loading while the GPU is busy with the render. // This means the render is lagging a frame behind, but this is hardly noticable. -#if OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) mWindow->swapBuffers(); -#else - // In Ogre 1.8, the swapBuffers argument is useless and setVSyncEnabled is bugged when using GLX. Not much we can do :/ - mWindow->swapBuffers(false); -#endif + mWindow->update(false); if (!hasCompositor) From 4905f1c8ab0291be80f5546177318cba266e1633 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 13 Oct 2013 21:54:36 +0200 Subject: [PATCH 75/79] make testing empty cells against an empty string yield true --- apps/opencs/model/filter/textnode.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/opencs/model/filter/textnode.cpp b/apps/opencs/model/filter/textnode.cpp index e335f7ea7..7d1a4845f 100644 --- a/apps/opencs/model/filter/textnode.cpp +++ b/apps/opencs/model/filter/textnode.cpp @@ -49,6 +49,8 @@ bool CSMFilter::TextNode::test (const CSMWorld::IdTable& table, int row, { string = data.toBool() ? "true" : "false"; } + else if (mText.empty() && !data.isValid()) + return true; else return false; From 9b0766b6789434e8134b1c0551972223e79e7890 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 14 Oct 2013 10:58:11 +0200 Subject: [PATCH 76/79] minor fix in ValueNode::toString --- apps/opencs/model/filter/valuenode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/filter/valuenode.cpp b/apps/opencs/model/filter/valuenode.cpp index 7eeb6beab..464fc8ec4 100644 --- a/apps/opencs/model/filter/valuenode.cpp +++ b/apps/opencs/model/filter/valuenode.cpp @@ -68,7 +68,7 @@ std::string CSMFilter::ValueNode::toString (bool numericColumns) const << CSMWorld::Columns::getName (static_cast (mColumnId)) << "\""; - stream << ", \""; + stream << ", "; if (mLower==mUpper && mLowerType!=Type_Infinite && mUpperType!=Type_Infinite) stream << mLower; From 679754b305070ac17a81250f7e6d59aa2d54e374 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 14 Oct 2013 11:06:59 +0200 Subject: [PATCH 77/79] corrected an error message --- apps/opencs/model/filter/valuenode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/filter/valuenode.cpp b/apps/opencs/model/filter/valuenode.cpp index 464fc8ec4..66f76efcb 100644 --- a/apps/opencs/model/filter/valuenode.cpp +++ b/apps/opencs/model/filter/valuenode.cpp @@ -17,7 +17,7 @@ bool CSMFilter::ValueNode::test (const CSMWorld::IdTable& table, int row, const std::map::const_iterator iter = columns.find (mColumnId); if (iter==columns.end()) - throw std::logic_error ("invalid column in test value test"); + throw std::logic_error ("invalid column in value node test"); if (iter->second==-1) return true; From db7ea30483f126047c014dfdce807994c0ceb4e7 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 14 Oct 2013 11:15:36 +0200 Subject: [PATCH 78/79] allow float values in cell for value tests --- apps/opencs/model/filter/valuenode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/filter/valuenode.cpp b/apps/opencs/model/filter/valuenode.cpp index 66f76efcb..fdcce00ab 100644 --- a/apps/opencs/model/filter/valuenode.cpp +++ b/apps/opencs/model/filter/valuenode.cpp @@ -27,7 +27,7 @@ bool CSMFilter::ValueNode::test (const CSMWorld::IdTable& table, int row, QVariant data = table.data (index); if (data.type()!=QVariant::Double && data.type()!=QVariant::Bool && data.type()!=QVariant::Int && - data.type()!=QVariant::UInt) + data.type()!=QVariant::UInt && data.type()!=static_cast (QMetaType::Float)) return false; double value = data.toDouble(); From ba4b8a37e2301f1ecb0633c361b3cb5c73bd1cdc Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Mon, 14 Oct 2013 11:15:23 +0200 Subject: [PATCH 79/79] Remember pressed message box button longer Remember which button was pressed until a new interactive message box is displayed or until the pressed button number is read. Before that, it was not possible to get the pressed button after the message box was hidden/destroyed. --- apps/openmw/mwgui/messagebox.cpp | 15 +++++++-------- apps/openmw/mwgui/messagebox.hpp | 1 + 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwgui/messagebox.cpp b/apps/openmw/mwgui/messagebox.cpp index 45da1bf17..48d7ec171 100644 --- a/apps/openmw/mwgui/messagebox.cpp +++ b/apps/openmw/mwgui/messagebox.cpp @@ -14,6 +14,7 @@ namespace MWGui mMessageBoxSpeed = 0.1; mInterMessageBoxe = NULL; mStaticMessageBox = NULL; + mLastButtonPressed = -1; } void MessageBoxManager::onFrame (float frameDuration) @@ -62,6 +63,7 @@ namespace MWGui } if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) { + mLastButtonPressed = mInterMessageBoxe->readPressedButton(); delete mInterMessageBoxe; mInterMessageBoxe = NULL; MWBase::Environment::get().getInputManager()->changeInputMode( @@ -107,6 +109,7 @@ namespace MWGui } mInterMessageBoxe = new InteractiveMessageBox(*this, message, buttons); + mLastButtonPressed = -1; return true; } @@ -154,11 +157,9 @@ namespace MWGui int MessageBoxManager::readPressedButton () { - if(mInterMessageBoxe != NULL) - { - return mInterMessageBoxe->readPressedButton(); - } - return -1; + int pressed = mLastButtonPressed; + mLastButtonPressed = -1; + return pressed; } @@ -421,9 +422,7 @@ namespace MWGui int InteractiveMessageBox::readPressedButton () { - int pressed = mButtonPressed; - mButtonPressed = -1; - return pressed; + return mButtonPressed; } } diff --git a/apps/openmw/mwgui/messagebox.hpp b/apps/openmw/mwgui/messagebox.hpp index 4ef645f5e..63840cfe2 100644 --- a/apps/openmw/mwgui/messagebox.hpp +++ b/apps/openmw/mwgui/messagebox.hpp @@ -56,6 +56,7 @@ namespace MWGui MessageBox* mStaticMessageBox; std::vector mTimers; float mMessageBoxSpeed; + int mLastButtonPressed; }; class MessageBox : public OEngine::GUI::Layout