From c7275965b8c8e419eec920db231f59270bdf1059 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 25 Mar 2013 13:22:06 +0100 Subject: [PATCH 01/26] added basic class record table --- apps/opencs/model/world/data.cpp | 7 +++++++ apps/opencs/model/world/data.hpp | 2 ++ apps/opencs/model/world/universalid.cpp | 2 ++ apps/opencs/model/world/universalid.hpp | 4 +++- apps/opencs/view/doc/view.cpp | 9 +++++++++ apps/opencs/view/doc/view.hpp | 2 ++ apps/opencs/view/world/subviews.cpp | 7 +++++-- components/esm/loadclas.cpp | 14 ++++++++++++++ components/esm/loadclas.hpp | 4 ++++ 9 files changed, 48 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 4b10a6683..2b635d9ab 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -44,9 +44,15 @@ CSMWorld::Data::Data() mSkills.addColumn (new UseValueColumn (i)); mSkills.addColumn (new DescriptionColumn); + mClasses.addColumn (new StringIdColumn); + mClasses.addColumn (new RecordStateColumn); + mClasses.addColumn (new SpecialisationColumn); + mClasses.addColumn (new DescriptionColumn); + 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 (&mClasses), UniversalId::Type_Classes, UniversalId::Type_Class); } CSMWorld::Data::~Data() @@ -122,6 +128,7 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base) case ESM::REC_GLOB: mGlobals.load (reader, base); break; case ESM::REC_GMST: mGmsts.load (reader, base); break; case ESM::REC_SKIL: mSkills.load (reader, base); break; + case ESM::REC_CLAS: mClasses.load (reader, base); break; default: diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index ac953dbec..7baf03259 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include "idcollection.hpp" #include "universalid.hpp" @@ -22,6 +23,7 @@ namespace CSMWorld IdCollection mGlobals; IdCollection mGmsts; IdCollection mSkills; + IdCollection mClasses; std::vector mModels; std::map mModelIndex; diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index 57c276a6d..a85b30c2a 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -20,6 +20,7 @@ namespace { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Globals, "Global Variables" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Gmsts, "Game Settings" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Skills, "Skills" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Classes, "Classes" }, { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker }; @@ -29,6 +30,7 @@ namespace { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Skill, "Skill" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Class, "Class" }, { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker }; diff --git a/apps/opencs/model/world/universalid.hpp b/apps/opencs/model/world/universalid.hpp index a412cb6b1..4c4d95654 100644 --- a/apps/opencs/model/world/universalid.hpp +++ b/apps/opencs/model/world/universalid.hpp @@ -39,7 +39,9 @@ namespace CSMWorld Type_Gmsts, Type_Gmst, Type_Skills, - Type_Skill + Type_Skill, + Type_Classes, + Type_Class }; private: diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 267ddf26c..2ef66593f 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -90,6 +90,10 @@ void CSVDoc::View::setupWorldMenu() connect (skills, SIGNAL (triggered()), this, SLOT (addSkillsSubView())); world->addAction (skills); + QAction *classes = new QAction (tr ("Classes"), this); + connect (classes, SIGNAL (triggered()), this, SLOT (addClassesSubView())); + world->addAction (classes); + mVerify = new QAction (tr ("&Verify"), this); connect (mVerify, SIGNAL (triggered()), this, SLOT (verify())); world->addAction (mVerify); @@ -253,6 +257,11 @@ void CSVDoc::View::addSkillsSubView() addSubView (CSMWorld::UniversalId::Type_Skills); } +void CSVDoc::View::addClassesSubView() +{ + addSubView (CSMWorld::UniversalId::Type_Classes); +} + 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 4c5aa4078..bc8e8fc26 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -117,6 +117,8 @@ namespace CSVDoc void addGmstsSubView(); void addSkillsSubView(); + + void addClassesSubView(); }; } diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index bdff0017b..5d715ea21 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -17,6 +17,9 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) manager.add (CSMWorld::UniversalId::Type_Skills, new CSVDoc::SubViewFactoryWithCreateFlag (false)); - manager.add (CSMWorld::UniversalId::Type_Global, - new CSVDoc::SubViewFactoryWithCreateFlag (true)); + manager.add (CSMWorld::UniversalId::Type_Classes, + new CSVDoc::SubViewFactoryWithCreateFlag (true)); + +// manager.add (CSMWorld::UniversalId::Type_Global, +// new CSVDoc::SubViewFactoryWithCreateFlag (true)); } \ No newline at end of file diff --git a/components/esm/loadclas.cpp b/components/esm/loadclas.cpp index a62668950..d9f367fd6 100644 --- a/components/esm/loadclas.cpp +++ b/components/esm/loadclas.cpp @@ -35,4 +35,18 @@ void Class::save(ESMWriter &esm) esm.writeHNOString("DESC", mDescription); } + void Class::blank() + { + mName.clear(); + mDescription.clear(); + + mData.mAttribute[0] = mData.mAttribute[1] = 0; + mData.mSpecialization = 0; + mData.mIsPlayable = 0; + mData.mCalc = 0; + + for (int i=0; i<5; ++i) + for (int i2=0; i2<2; ++i2) + mData.mSkills[i][i2] = 0; + } } diff --git a/components/esm/loadclas.hpp b/components/esm/loadclas.hpp index 264e342e6..ac596af32 100644 --- a/components/esm/loadclas.hpp +++ b/components/esm/loadclas.hpp @@ -65,6 +65,10 @@ struct Class void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID/index). + }; } #endif From 65cda580db62ccba881a6518d880c5027c38824a Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 25 Mar 2013 14:31:46 +0100 Subject: [PATCH 02/26] added attributes to class table --- apps/opencs/model/world/columns.hpp | 53 +++++++++++++++++++++++++++++ apps/opencs/model/world/data.cpp | 3 ++ 2 files changed, 56 insertions(+) diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 7764f5870..b41e98f40 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -285,6 +285,59 @@ namespace CSMWorld } }; + template + struct NameColumn : public Column + { + NameColumn() : Column ("Name", ColumnBase::Display_String) {} + + virtual QVariant get (const Record& record) const + { + return QString::fromUtf8 (record.get().mName.c_str()); + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + + record2.mName = data.toString().toUtf8().constData(); + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; + + template + struct AttributesColumn : public Column + { + int mIndex; + + AttributesColumn (int index) + : Column ("Attribute #" + boost::lexical_cast (index), + ColumnBase::Display_Attribute), mIndex (index) {} + + virtual QVariant get (const Record& record) const + { + return record.get().mData.mAttribute[mIndex]; + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + + record2.mData.mAttribute[mIndex] = data.toInt(); + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; } #endif \ No newline at end of file diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 2b635d9ab..b0a8b95a6 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -46,6 +46,9 @@ CSMWorld::Data::Data() mClasses.addColumn (new StringIdColumn); mClasses.addColumn (new RecordStateColumn); + mClasses.addColumn (new NameColumn); + mClasses.addColumn (new AttributesColumn (0)); + mClasses.addColumn (new AttributesColumn (1)); mClasses.addColumn (new SpecialisationColumn); mClasses.addColumn (new DescriptionColumn); From ea3b14f2d25d3174ad57d7fa7d4d7acc23e7d0ef Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 26 Mar 2013 09:43:13 +0100 Subject: [PATCH 03/26] added skill columns to class --- apps/opencs/model/doc/document.cpp | 2 +- apps/opencs/model/world/columns.hpp | 46 +++++++++++++++++++++++++++++ apps/opencs/model/world/data.cpp | 4 +++ components/esm/loadskil.cpp | 7 +++-- components/esm/loadskil.hpp | 2 +- 5 files changed, 57 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index d1462d6a3..acca877f0 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -207,7 +207,7 @@ void CSMDoc::Document::createBase() { ESM::Skill record; record.mIndex = i; - record.mId = ESM::Skill::getIndexToId (record.mIndex); + record.mId = ESM::Skill::indexToId (record.mIndex); record.blank(); getData().getSkills().add (record); diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index b41e98f40..902d7d86f 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -1,6 +1,8 @@ #ifndef CSM_WOLRD_COLUMNS_H #define CSM_WOLRD_COLUMNS_H +#include + #include #include "columnbase.hpp" @@ -338,6 +340,50 @@ namespace CSMWorld return true; } }; + + template + struct SkillsColumn : public Column + { + int mIndex; + bool mMajor; + + SkillsColumn (int index, bool major) + : Column ((major ? "Major Skill #" : "Minor Skill #")+ + boost::lexical_cast (index), ColumnBase::Display_String), + mIndex (index), mMajor (major) + {} + + virtual QVariant get (const Record& record) const + { + int skill = record.get().mData.mSkills[mIndex][mMajor ? 1 : 0]; + + return QString::fromUtf8 (ESM::Skill::indexToId (skill).c_str()); + } + + virtual void set (Record& record, const QVariant& data) + { + std::istringstream stream (data.toString().toUtf8().constData()); + + int index = -1; + char c; + + stream >> c >> index; + + if (index!=-1) + { + ESXRecordT record2 = record.get(); + + record2.mData.mSkills[mIndex][mMajor ? 1 : 0] = index; + + record.setModified (record2); + } + } + + virtual bool isEditable() const + { + return true; + } + }; } #endif \ No newline at end of file diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index b0a8b95a6..917be2632 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -50,6 +50,10 @@ CSMWorld::Data::Data() mClasses.addColumn (new AttributesColumn (0)); mClasses.addColumn (new AttributesColumn (1)); mClasses.addColumn (new SpecialisationColumn); + for (int i=0; i<5; ++i) + mClasses.addColumn (new SkillsColumn (i, true)); + for (int i=0; i<5; ++i) + mClasses.addColumn (new SkillsColumn (i, false)); mClasses.addColumn (new DescriptionColumn); addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global); diff --git a/components/esm/loadskil.cpp b/components/esm/loadskil.cpp index b9d588eef..b7259db94 100644 --- a/components/esm/loadskil.cpp +++ b/components/esm/loadskil.cpp @@ -2,6 +2,8 @@ #include +#include + #include "esmreader.hpp" #include "esmwriter.hpp" @@ -103,8 +105,9 @@ void Skill::load(ESMReader &esm) // create an ID from the index and the name (only used in the editor and likely to change in the // future) - mId = getIndexToId (mIndex); + mId = indexToId (mIndex); } + void Skill::save(ESMWriter &esm) { esm.writeHNT("INDX", mIndex); @@ -120,7 +123,7 @@ void Skill::save(ESMWriter &esm) mDescription.clear(); } - std::string Skill::getIndexToId (int index) + std::string Skill::indexToId (int index) { std::ostringstream stream; diff --git a/components/esm/loadskil.hpp b/components/esm/loadskil.hpp index 83a4d8bfd..43f4fc45e 100644 --- a/components/esm/loadskil.hpp +++ b/components/esm/loadskil.hpp @@ -79,7 +79,7 @@ struct Skill void blank(); ///< Set record to default state (does not touch the ID/index). - static std::string getIndexToId (int index); + static std::string indexToId (int index); }; } #endif From 82f1cee116a740e853be87a732cfbf52dac3ec1c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 26 Mar 2013 09:51:39 +0100 Subject: [PATCH 04/26] added is-playable column to class --- apps/opencs/model/world/columnbase.hpp | 3 ++- apps/opencs/model/world/columns.hpp | 25 +++++++++++++++++++++++++ apps/opencs/model/world/data.cpp | 1 + 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index b5863f8e4..5c2ce8a67 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -33,7 +33,8 @@ namespace CSMWorld Display_GmstVarType, Display_GlobalVarType, Display_Specialisation, - Display_Attribute + Display_Attribute, + Display_Boolean }; std::string mTitle; diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 902d7d86f..cbcddd972 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -384,6 +384,31 @@ namespace CSMWorld return true; } }; + + template + struct PlayableColumn : public Column + { + PlayableColumn() : Column ("Playable", ColumnBase::Display_Boolean) {} + + virtual QVariant get (const Record& record) const + { + return record.get().mData.mIsPlayable!=0; + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + + record2.mData.mIsPlayable = data.toInt(); + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; } #endif \ No newline at end of file diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 917be2632..7b3e66771 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -54,6 +54,7 @@ CSMWorld::Data::Data() mClasses.addColumn (new SkillsColumn (i, true)); for (int i=0; i<5; ++i) mClasses.addColumn (new SkillsColumn (i, false)); + mClasses.addColumn (new PlayableColumn); mClasses.addColumn (new DescriptionColumn); addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global); From 04673b2f14f2572e9b2a6d5d98c066f3b778d3b5 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 30 Mar 2013 12:54:20 +0100 Subject: [PATCH 05/26] Don't enchant if the enchantment value is too high for the item --- apps/openmw/mwgui/enchantingdialog.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index 6114bd464..536dafc01 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -158,7 +158,7 @@ namespace MWGui if(mEnchanting.getGemCharge()==0) { - mWindowManager.messageBox ("#{sNotifyMessage32}", std::vector()); + mWindowManager.messageBox ("#{sNotifyMessage32}"); return; } @@ -222,31 +222,37 @@ namespace MWGui { if (mEffects.size() <= 0) { - mWindowManager.messageBox ("#{sNotifyMessage30}", std::vector()); + mWindowManager.messageBox ("#{sNotifyMessage30}"); return; } if (mName->getCaption ().empty()) { - mWindowManager.messageBox ("#{sNotifyMessage10}", std::vector()); + mWindowManager.messageBox ("#{sNotifyMessage10}"); return; } if (boost::lexical_cast(mPrice->getCaption()) > mWindowManager.getInventoryWindow()->getPlayerGold()) { - mWindowManager.messageBox ("#{sNotifyMessage18}", std::vector()); + mWindowManager.messageBox ("#{sNotifyMessage18}"); return; } if (mEnchanting.soulEmpty()) { - mWindowManager.messageBox ("#{sNotifyMessage52}", std::vector()); + mWindowManager.messageBox ("#{sNotifyMessage52}"); return; } if (mEnchanting.itemEmpty()) { - mWindowManager.messageBox ("#{sNotifyMessage11}", std::vector()); + mWindowManager.messageBox ("#{sNotifyMessage11}"); + return; + } + + if (mEnchanting.getEnchantCost() > mEnchanting.getMaxEnchantValue()) + { + mWindowManager.messageBox ("#{sNotifyMessage29}"); return; } @@ -254,7 +260,7 @@ namespace MWGui mEnchanting.setEffect(mEffectList); mEnchanting.create(); - mWindowManager.messageBox ("#{sEnchantmentMenu12}", std::vector()); + mWindowManager.messageBox ("#{sEnchantmentMenu12}"); mWindowManager.removeGuiMode (GM_Enchanting); } } From e7af718b55a8a436ddc950bd47a0ebfb4a7a0e9d Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 30 Mar 2013 12:56:37 +0100 Subject: [PATCH 06/26] Remove unnecessary WindowManager::messageBox arguments --- apps/openmw/mwclass/container.cpp | 2 +- apps/openmw/mwclass/door.cpp | 2 +- apps/openmw/mwgui/alchemywindow.cpp | 12 ++++++------ apps/openmw/mwgui/container.cpp | 6 +++--- apps/openmw/mwgui/levelupdialog.cpp | 2 +- apps/openmw/mwgui/quickkeysmenu.cpp | 4 ++-- apps/openmw/mwgui/settingswindow.cpp | 4 ++-- apps/openmw/mwgui/spellcreationdialog.cpp | 12 ++++++------ apps/openmw/mwgui/spellwindow.cpp | 2 +- apps/openmw/mwgui/text_input.cpp | 4 ++-- apps/openmw/mwgui/tradewindow.cpp | 10 +++++----- apps/openmw/mwgui/trainingwindow.cpp | 2 +- apps/openmw/mwgui/waitdialog.cpp | 2 +- apps/openmw/mwmechanics/actors.cpp | 2 +- apps/openmw/mwmechanics/npcstats.cpp | 4 ++-- apps/openmw/mwscript/containerextensions.cpp | 4 ++-- apps/openmw/mwworld/actionequip.cpp | 6 +++--- apps/openmw/mwworld/failedaction.cpp | 2 +- 18 files changed, 41 insertions(+), 41 deletions(-) diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index a2d75131e..4ee95b96e 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -115,7 +115,7 @@ namespace MWClass if (needKey && hasKey) { - MWBase::Environment::get().getWindowManager ()->messageBox (keyName + " #{sKeyUsed}", std::vector()); + MWBase::Environment::get().getWindowManager ()->messageBox (keyName + " #{sKeyUsed}"); ptr.getCellRef().mLockLevel = 0; // using a key disarms the trap ptr.getCellRef().mTrap = ""; diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index fb6329939..163cf0277 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -98,7 +98,7 @@ namespace MWClass if (needKey && hasKey) { - MWBase::Environment::get().getWindowManager ()->messageBox (keyName + " #{sKeyUsed}", std::vector()); + MWBase::Environment::get().getWindowManager ()->messageBox (keyName + " #{sKeyUsed}"); ptr.getCellRef().mLockLevel = 0; // using a key disarms the trap ptr.getCellRef().mTrap = ""; diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index fce612600..ca7f1b913 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -77,40 +77,40 @@ namespace MWGui if (result == MWMechanics::Alchemy::Result_NoName) { - mWindowManager.messageBox("#{sNotifyMessage37}", std::vector()); + mWindowManager.messageBox("#{sNotifyMessage37}"); return; } // check if mortar & pestle is available (always needed) if (result == MWMechanics::Alchemy::Result_NoMortarAndPestle) { - mWindowManager.messageBox("#{sNotifyMessage45}", std::vector()); + mWindowManager.messageBox("#{sNotifyMessage45}"); return; } // make sure 2 or more ingredients were selected if (result == MWMechanics::Alchemy::Result_LessThanTwoIngredients) { - mWindowManager.messageBox("#{sNotifyMessage6a}", std::vector()); + mWindowManager.messageBox("#{sNotifyMessage6a}"); return; } if (result == MWMechanics::Alchemy::Result_NoEffects) { - mWindowManager.messageBox("#{sNotifyMessage8}", std::vector()); + mWindowManager.messageBox("#{sNotifyMessage8}"); MWBase::Environment::get().getSoundManager()->playSound("potion fail", 1.f, 1.f); return; } if (result == MWMechanics::Alchemy::Result_Success) { - mWindowManager.messageBox("#{sPotionSuccess}", std::vector()); + mWindowManager.messageBox("#{sPotionSuccess}"); MWBase::Environment::get().getSoundManager()->playSound("potion success", 1.f, 1.f); } else if (result == MWMechanics::Alchemy::Result_RandomFailure) { // potion failed - mWindowManager.messageBox("#{sNotifyMessage8}", std::vector()); + mWindowManager.messageBox("#{sNotifyMessage8}"); MWBase::Environment::get().getSoundManager()->playSound("potion fail", 1.f, 1.f); } diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index 0a674ba82..98d818638 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -150,7 +150,7 @@ void ContainerBase::onSelectedItem(MyGUI::Widget* _sender) { // user notification "i don't buy this item" MWBase::Environment::get().getWindowManager()-> - messageBox("#{sBarterDialog4}", std::vector()); + messageBox("#{sBarterDialog4}"); return; } } @@ -294,7 +294,7 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender) { // user notification MWBase::Environment::get().getWindowManager()-> - messageBox("#{sContentsMessage2}", std::vector()); + messageBox("#{sContentsMessage2}"); return; } @@ -318,7 +318,7 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender) object.getRefData().setCount(origCount); // user notification MWBase::Environment::get().getWindowManager()-> - messageBox("#{sContentsMessage3}", std::vector()); + messageBox("#{sContentsMessage3}"); return; } diff --git a/apps/openmw/mwgui/levelupdialog.cpp b/apps/openmw/mwgui/levelupdialog.cpp index f0a385808..67620d49d 100644 --- a/apps/openmw/mwgui/levelupdialog.cpp +++ b/apps/openmw/mwgui/levelupdialog.cpp @@ -162,7 +162,7 @@ namespace MWGui MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player); if (mSpentAttributes.size() < 3) - MWBase::Environment::get().getWindowManager ()->messageBox("#{sNotifyMessage36}", std::vector()); + MWBase::Environment::get().getWindowManager ()->messageBox("#{sNotifyMessage36}"); else { // increase attributes diff --git a/apps/openmw/mwgui/quickkeysmenu.cpp b/apps/openmw/mwgui/quickkeysmenu.cpp index 6d51420f0..5ea13fb0d 100644 --- a/apps/openmw/mwgui/quickkeysmenu.cpp +++ b/apps/openmw/mwgui/quickkeysmenu.cpp @@ -291,7 +291,7 @@ namespace MWGui if (item.getRefData ().getCount() == 0) { MWBase::Environment::get().getWindowManager ()->messageBox ( - "#{sQuickMenu5} " + MWWorld::Class::get(item).getName(item), std::vector()); + "#{sQuickMenu5} " + MWWorld::Class::get(item).getName(item)); return; } @@ -317,7 +317,7 @@ namespace MWGui if (item.getRefData ().getCount() == 0) { MWBase::Environment::get().getWindowManager ()->messageBox ( - "#{sQuickMenu5} " + MWWorld::Class::get(item).getName(item), std::vector()); + "#{sQuickMenu5} " + MWWorld::Class::get(item).getName(item)); return; } diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index 04856c3ed..58754472d 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -362,7 +362,7 @@ namespace MWGui { std::string msg = "This resolution is not supported in Fullscreen mode. Please select a resolution from the list."; MWBase::Environment::get().getWindowManager()-> - messageBox(msg, std::vector()); + messageBox(msg); _sender->castType()->setCaption(off); } else @@ -593,7 +593,7 @@ namespace MWGui static_cast(_sender)->setCaptionWithReplacing("#{sNone}"); - MWBase::Environment::get().getWindowManager ()->messageBox ("#{sControlsMenu3}", std::vector()); + MWBase::Environment::get().getWindowManager ()->messageBox ("#{sControlsMenu3}"); MWBase::Environment::get().getWindowManager ()->disallowMouse(); MWBase::Environment::get().getInputManager ()->enableDetectingBindingMode (actionId); diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index ea91ac278..592063a76 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -310,25 +310,25 @@ namespace MWGui { if (mEffects.size() <= 0) { - mWindowManager.messageBox ("#{sNotifyMessage30}", std::vector()); + mWindowManager.messageBox ("#{sNotifyMessage30}"); return; } if (mNameEdit->getCaption () == "") { - mWindowManager.messageBox ("#{sNotifyMessage10}", std::vector()); + mWindowManager.messageBox ("#{sNotifyMessage10}"); return; } if (mMagickaCost->getCaption() == "0") { - mWindowManager.messageBox ("#{sEnchantmentMenu8}", std::vector()); + mWindowManager.messageBox ("#{sEnchantmentMenu8}"); return; } if (boost::lexical_cast(mPriceLabel->getCaption()) > mWindowManager.getInventoryWindow()->getPlayerGold()) { - mWindowManager.messageBox ("#{sNotifyMessage18}", std::vector()); + mWindowManager.messageBox ("#{sNotifyMessage18}"); return; } @@ -517,7 +517,7 @@ namespace MWGui { if (mEffects.size() >= 8) { - MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage28}", std::vector()); + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage28}"); return; } @@ -528,7 +528,7 @@ namespace MWGui { if (it->mEffectID == effectId) { - MWBase::Environment::get().getWindowManager()->messageBox ("#{sOnetypeEffectMessage}", std::vector()); + MWBase::Environment::get().getWindowManager()->messageBox ("#{sOnetypeEffectMessage}"); return; } } diff --git a/apps/openmw/mwgui/spellwindow.cpp b/apps/openmw/mwgui/spellwindow.cpp index 50691d554..d7fb0e1bc 100644 --- a/apps/openmw/mwgui/spellwindow.cpp +++ b/apps/openmw/mwgui/spellwindow.cpp @@ -404,7 +404,7 @@ namespace MWGui if (spell->mData.mFlags & ESM::Spell::F_Always || spell->mData.mType == ESM::Spell::ST_Power) { - mWindowManager.messageBox("#{sDeleteSpellError}", std::vector()); + mWindowManager.messageBox("#{sDeleteSpellError}"); } else { diff --git a/apps/openmw/mwgui/text_input.cpp b/apps/openmw/mwgui/text_input.cpp index 9265cadf9..ee9144be6 100644 --- a/apps/openmw/mwgui/text_input.cpp +++ b/apps/openmw/mwgui/text_input.cpp @@ -50,7 +50,7 @@ void TextInputDialog::onOkClicked(MyGUI::Widget* _sender) { if (mTextEdit->getCaption() == "") { - mWindowManager.messageBox ("#{sNotifyMessage37}", std::vector()); + mWindowManager.messageBox ("#{sNotifyMessage37}"); MyGUI::InputManager::getInstance ().setKeyFocusWidget (mTextEdit); } else @@ -61,7 +61,7 @@ void TextInputDialog::onTextAccepted(MyGUI::Edit* _sender) { if (mTextEdit->getCaption() == "") { - mWindowManager.messageBox ("#{sNotifyMessage37}", std::vector()); + mWindowManager.messageBox ("#{sNotifyMessage37}"); MyGUI::InputManager::getInstance ().setKeyFocusWidget (mTextEdit); } else diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index f84a0abc8..307533d91 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -181,7 +181,7 @@ namespace MWGui { // user notification MWBase::Environment::get().getWindowManager()-> - messageBox("#{sBarterDialog11}", std::vector()); + messageBox("#{sBarterDialog11}"); return; } @@ -190,7 +190,7 @@ namespace MWGui { // user notification MWBase::Environment::get().getWindowManager()-> - messageBox("#{sBarterDialog1}", std::vector()); + messageBox("#{sBarterDialog1}"); return; } @@ -199,7 +199,7 @@ namespace MWGui { // user notification MWBase::Environment::get().getWindowManager()-> - messageBox("#{sBarterDialog2}", std::vector()); + messageBox("#{sBarterDialog2}"); return; } @@ -209,7 +209,7 @@ namespace MWGui if (mPtr.getTypeName() != typeid(ESM::NPC).name()) { MWBase::Environment::get().getWindowManager()-> - messageBox("#{sNotifyMessage9}", std::vector()); + messageBox("#{sNotifyMessage9}"); return; } @@ -245,7 +245,7 @@ namespace MWGui if(roll > x) //trade refused { MWBase::Environment::get().getWindowManager()-> - messageBox("#{sNotifyMessage9}", std::vector()); + messageBox("#{sNotifyMessage9}"); int iBarterFailDisposition = gmst.find("iBarterFailDisposition")->getInt(); MWBase::Environment::get().getDialogueManager()->applyTemporaryDispositionChange(iBarterFailDisposition); diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index ba39ee601..601b44d6c 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -129,7 +129,7 @@ namespace MWGui MWMechanics::NpcStats& npcStats = MWWorld::Class::get(mPtr).getNpcStats (mPtr); if (npcStats.getSkill (skillId).getBase () <= pcStats.getSkill (skillId).getBase ()) { - mWindowManager.messageBox ("#{sServiceTrainingWords}", std::vector()); + mWindowManager.messageBox ("#{sServiceTrainingWords}"); return; } diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index df8a52456..09eb5c914 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -83,7 +83,7 @@ namespace MWGui if (canRest == 2) { // resting underwater or mid-air not allowed - mWindowManager.messageBox ("#{sNotifyMessage1}", std::vector()); + mWindowManager.messageBox ("#{sNotifyMessage1}"); mWindowManager.popGuiMode (); } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 1480b3182..c8d87b425 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -256,7 +256,7 @@ namespace MWMechanics if(MWWorld::Class::get(iter->first).isEssential(iter->first)) MWBase::Environment::get().getWindowManager()->messageBox( - "#{sKilledEssential}", std::vector()); + "#{sKilledEssential}"); } } diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index 26c4c8e9a..51e23d16e 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -221,12 +221,12 @@ void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &clas message << boost::format(MWBase::Environment::get().getWindowManager ()->getGameSettingString ("sNotifyMessage39", "")) % std::string("#{" + ESM::Skill::sSkillNameIds[skillIndex] + "}") % static_cast (base); - MWBase::Environment::get().getWindowManager ()->messageBox(message.str(), std::vector()); + MWBase::Environment::get().getWindowManager ()->messageBox(message.str()); if (mLevelProgress >= 10) { // levelup is possible now - MWBase::Environment::get().getWindowManager ()->messageBox ("#{sLevelUpMsg}", std::vector()); + MWBase::Environment::get().getWindowManager ()->messageBox ("#{sLevelUpMsg}"); } getSkill (skillIndex).setBase (base); diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index 81639b5be..1154b06c6 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -83,7 +83,7 @@ namespace MWScript msgBox = boost::str(boost::format(msgBox) % count % itemName); } - MWBase::Environment::get().getWindowManager()->messageBox(msgBox, std::vector()); + MWBase::Environment::get().getWindowManager()->messageBox(msgBox); } } }; @@ -179,7 +179,7 @@ namespace MWScript } if (numRemoved > 0) - MWBase::Environment::get().getWindowManager()->messageBox(msgBox, std::vector()); + MWBase::Environment::get().getWindowManager()->messageBox(msgBox); } } }; diff --git a/apps/openmw/mwworld/actionequip.cpp b/apps/openmw/mwworld/actionequip.cpp index eb2ae9dca..afbb505f2 100644 --- a/apps/openmw/mwworld/actionequip.cpp +++ b/apps/openmw/mwworld/actionequip.cpp @@ -62,7 +62,7 @@ namespace MWWorld if((*itr).mPart == ESM::PRT_Head) { if(actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() ) - MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage13}", std::vector()); + MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage13}"); allow = false; break; @@ -90,12 +90,12 @@ namespace MWWorld if(actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() ) { if(it.getType() == MWWorld::ContainerStore::Type_Clothing){ // It's shoes - MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage15}", std::vector()); + MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage15}"); } else // It's boots { - MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage14}", std::vector()); + MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage14}"); } } break; diff --git a/apps/openmw/mwworld/failedaction.cpp b/apps/openmw/mwworld/failedaction.cpp index ec763dba0..1db00ad06 100644 --- a/apps/openmw/mwworld/failedaction.cpp +++ b/apps/openmw/mwworld/failedaction.cpp @@ -15,7 +15,7 @@ namespace MWWorld { if ( actor.getRefData().getHandle()=="player" && !(message.empty())) { - MWBase::Environment::get().getWindowManager() ->messageBox(message, std::vector()); + MWBase::Environment::get().getWindowManager() ->messageBox(message); } } } From 51204f098e77b7fc7767956045e1625eef7dbd84 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 30 Mar 2013 15:51:07 +0100 Subject: [PATCH 07/26] Added soulgem dialog; made interactive message boxes not close the previous UI --- apps/openmw/CMakeLists.txt | 4 +-- apps/openmw/mwbase/windowmanager.hpp | 3 +++ apps/openmw/mwclass/misc.cpp | 10 ++++++++ apps/openmw/mwclass/misc.hpp | 4 +++ apps/openmw/mwgui/enchantingdialog.cpp | 5 ++++ apps/openmw/mwgui/enchantingdialog.hpp | 1 + apps/openmw/mwgui/messagebox.cpp | 21 ++++++++------- apps/openmw/mwgui/messagebox.hpp | 9 ++++++- apps/openmw/mwgui/mode.hpp | 4 +-- apps/openmw/mwgui/soulgemdialog.cpp | 34 +++++++++++++++++++++++++ apps/openmw/mwgui/soulgemdialog.hpp | 28 ++++++++++++++++++++ apps/openmw/mwgui/windowmanagerimp.cpp | 29 +++++++++++++-------- apps/openmw/mwgui/windowmanagerimp.hpp | 7 +++++ apps/openmw/mwinput/inputmanagerimp.cpp | 8 +++--- apps/openmw/mwworld/actionsoulgem.cpp | 21 +++++++++++++++ apps/openmw/mwworld/actionsoulgem.hpp | 19 ++++++++++++++ 16 files changed, 177 insertions(+), 30 deletions(-) create mode 100644 apps/openmw/mwgui/soulgemdialog.cpp create mode 100644 apps/openmw/mwgui/soulgemdialog.hpp create mode 100644 apps/openmw/mwworld/actionsoulgem.cpp create mode 100644 apps/openmw/mwworld/actionsoulgem.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 9b1e5a02f..41f56f993 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -31,7 +31,7 @@ add_openmw_dir (mwgui confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons - merchantrepair repair + merchantrepair repair soulgemdialog ) add_openmw_dir (mwdialogue @@ -54,7 +54,7 @@ add_openmw_dir (mwworld containerstore actiontalk actiontake manualref player cellfunctors failedaction cells localscripts customdata weather inventorystore ptr actionopen actionread actionequip timestamp actionalchemy cellstore actionapply actioneat - esmstore store recordcmp fallback actionrepair + esmstore store recordcmp fallback actionrepair actionsoulgem ) add_openmw_dir (mwclass diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 6760c89d0..58897dc74 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -237,10 +237,13 @@ namespace MWBase virtual void startSpellMaking(MWWorld::Ptr actor) = 0; virtual void startEnchanting(MWWorld::Ptr actor) = 0; + virtual void startSelfEnchanting(MWWorld::Ptr soulgem) = 0; virtual void startTraining(MWWorld::Ptr actor) = 0; virtual void startRepair(MWWorld::Ptr actor) = 0; virtual void startRepairItem(MWWorld::Ptr item) = 0; + virtual void showSoulgemDialog (MWWorld::Ptr item) = 0; + virtual void changePointer (const std::string& name) = 0; virtual const Translation::Storage& getTranslationDataStorage() const = 0; diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index b971fa6f3..b8a928bec 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -15,6 +15,7 @@ #include "../mwworld/physicssystem.hpp" #include "../mwworld/manualref.hpp" #include "../mwworld/nullaction.hpp" +#include "../mwworld/actionsoulgem.hpp" #include "../mwgui/tooltips.hpp" @@ -233,4 +234,13 @@ namespace MWClass } return newPtr; } + + boost::shared_ptr Miscellaneous::use (const MWWorld::Ptr& ptr) const + { + if (ptr.getCellRef().mSoul == "") + return boost::shared_ptr(new MWWorld::NullAction()); + else + return boost::shared_ptr(new MWWorld::ActionSoulgem(ptr)); + } + } diff --git a/apps/openmw/mwclass/misc.hpp b/apps/openmw/mwclass/misc.hpp index a5a79a8f6..12a50af19 100644 --- a/apps/openmw/mwclass/misc.hpp +++ b/apps/openmw/mwclass/misc.hpp @@ -49,6 +49,10 @@ namespace MWClass ///< Return name of inventory icon. virtual std::string getModel(const MWWorld::Ptr &ptr) const; + + virtual boost::shared_ptr use (const MWWorld::Ptr& ptr) + const; + ///< Generate action for using via inventory menu }; } diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index 536dafc01..ef124bb43 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -92,6 +92,11 @@ namespace MWGui startEditing (); } + void EnchantingDialog::startSelfEnchanting(MWWorld::Ptr soulgem) + { + /// \todo + } + void EnchantingDialog::onReferenceUnavailable () { mWindowManager.removeGuiMode (GM_Dialogue); diff --git a/apps/openmw/mwgui/enchantingdialog.hpp b/apps/openmw/mwgui/enchantingdialog.hpp index 60445a8dc..347b37e90 100644 --- a/apps/openmw/mwgui/enchantingdialog.hpp +++ b/apps/openmw/mwgui/enchantingdialog.hpp @@ -22,6 +22,7 @@ namespace MWGui virtual void open(); void startEnchanting(MWWorld::Ptr actor); + void startSelfEnchanting(MWWorld::Ptr soulgem); protected: virtual void onReferenceUnavailable(); diff --git a/apps/openmw/mwgui/messagebox.cpp b/apps/openmw/mwgui/messagebox.cpp index b8a34c457..46663b67a 100644 --- a/apps/openmw/mwgui/messagebox.cpp +++ b/apps/openmw/mwgui/messagebox.cpp @@ -3,6 +3,7 @@ #include "messagebox.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/soundmanager.hpp" +#include "../mwbase/inputmanager.hpp" using namespace MWGui; @@ -62,7 +63,8 @@ void MessageBoxManager::onFrame (float frameDuration) if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) { delete mInterMessageBoxe; mInterMessageBoxe = NULL; - mWindowManager->removeGuiMode(GM_InterMessageBox); + MWBase::Environment::get().getInputManager()->changeInputMode( + MWBase::Environment::get().getWindowManager()->isGuiMode()); } } @@ -90,11 +92,8 @@ void MessageBoxManager::createMessageBox (const std::string& message) bool MessageBoxManager::createInteractiveMessageBox (const std::string& message, const std::vector& buttons) { - /// \todo Don't write this kind of error message to cout. Either discard the old message box - /// silently or throw an exception. if(mInterMessageBoxe != NULL) { - std::cout << "there is a MessageBox already" << std::endl; - return false; + throw std::runtime_error("There is a message box already"); } mInterMessageBoxe = new InteractiveMessageBox(*this, message, buttons); @@ -139,7 +138,8 @@ void MessageBoxManager::setMessageBoxSpeed (int speed) void MessageBoxManager::enterPressed () { - mInterMessageBoxe->enterPressed(); + if(mInterMessageBoxe != NULL) + mInterMessageBoxe->enterPressed(); } int MessageBoxManager::readPressedButton () @@ -213,10 +213,12 @@ int MessageBox::getHeight () InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector& buttons) - : Layout("openmw_interactive_messagebox.layout") + : WindowModal("openmw_interactive_messagebox.layout", *MWBase::Environment::get().getWindowManager()) , mMessageBoxManager(parMessageBoxManager) , mButtonPressed(-1) { + WindowModal::open(); + int fixedWidth = 500; int textPadding = 10; // padding between text-widget and main-widget int textButtonPadding = 20; // padding between the text-widget und the button-widget @@ -232,7 +234,7 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan getWidget(mButtonsWidget, "buttons"); mMessageWidget->setOverflowToTheLeft(true); - mMessageWidget->addText(message); + mMessageWidget->setCaptionWithReplacing(message); MyGUI::IntSize textSize = mMessageWidget->getTextSize(); @@ -252,7 +254,7 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan std::string("MW_Button"), dummyCoord, MyGUI::Align::Default); - button->setCaption(*it); + button->setCaptionWithReplacing(*it); button->eventMouseButtonClick += MyGUI::newDelegate(this, &InteractiveMessageBox::mousePressed); @@ -399,6 +401,7 @@ void InteractiveMessageBox::buttonActivated (MyGUI::Widget* pressed) if(*button == pressed) { mButtonPressed = index; + mMessageBoxManager.onButtonPressed(mButtonPressed); return; } index++; diff --git a/apps/openmw/mwgui/messagebox.hpp b/apps/openmw/mwgui/messagebox.hpp index 149aa7e7f..859e1806a 100644 --- a/apps/openmw/mwgui/messagebox.hpp +++ b/apps/openmw/mwgui/messagebox.hpp @@ -44,6 +44,13 @@ namespace MWGui void enterPressed(); int readPressedButton (); + typedef MyGUI::delegates::CMultiDelegate1 EventHandle_Int; + + // Note: this delegate unassigns itself after it was fired, i.e. works once. + EventHandle_Int eventButtonPressed; + + void onButtonPressed(int button) { eventButtonPressed(button); eventButtonPressed.clear(); } + MWBase::WindowManager *mWindowManager; private: @@ -73,7 +80,7 @@ namespace MWGui int mNextBoxPadding; }; - class InteractiveMessageBox : public OEngine::GUI::Layout + class InteractiveMessageBox : public WindowModal { public: InteractiveMessageBox (MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector& buttons); diff --git a/apps/openmw/mwgui/mode.hpp b/apps/openmw/mwgui/mode.hpp index 4091f47ac..e9b01395f 100644 --- a/apps/openmw/mwgui/mode.hpp +++ b/apps/openmw/mwgui/mode.hpp @@ -5,6 +5,7 @@ namespace MWGui { enum GuiMode { + GM_None, GM_Settings, // Settings window GM_Inventory, // Inventory mode GM_Container, @@ -41,9 +42,6 @@ namespace MWGui GM_ClassCreate, GM_Review, - // interactive MessageBox - GM_InterMessageBox, - GM_Loading, GM_LoadingWallpaper, diff --git a/apps/openmw/mwgui/soulgemdialog.cpp b/apps/openmw/mwgui/soulgemdialog.cpp new file mode 100644 index 000000000..4530a13d0 --- /dev/null +++ b/apps/openmw/mwgui/soulgemdialog.cpp @@ -0,0 +1,34 @@ +#include "soulgemdialog.hpp" + +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/environment.hpp" + +#include "messagebox.hpp" + +namespace MWGui +{ + + void SoulgemDialog::show(const MWWorld::Ptr &soulgem) + { + mSoulgem = soulgem; + std::vector buttons; + buttons.push_back("#{sRechargeEnchantment}"); + buttons.push_back("#{sMake Enchantment}"); + mManager->createInteractiveMessageBox("#{sDoYouWantTo}", buttons); + mManager->eventButtonPressed += MyGUI::newDelegate(this, &SoulgemDialog::onButtonPressed); + } + + void SoulgemDialog::onButtonPressed(int button) + { + if (button == 0) + { + /// \todo show recharge enchanted item dialog here + } + else + { + MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Enchanting); + MWBase::Environment::get().getWindowManager()->startSelfEnchanting(mSoulgem); + } + } + +} diff --git a/apps/openmw/mwgui/soulgemdialog.hpp b/apps/openmw/mwgui/soulgemdialog.hpp new file mode 100644 index 000000000..9aea1f339 --- /dev/null +++ b/apps/openmw/mwgui/soulgemdialog.hpp @@ -0,0 +1,28 @@ +#ifndef OPENMW_MWGUI_SOULGEMDIALOG_H +#define OPENMW_MWGUI_SOULGEMDIALOG_H + +#include "../mwworld/ptr.hpp" + +namespace MWGui +{ + + class MessageBoxManager; + + class SoulgemDialog + { + public: + SoulgemDialog (MessageBoxManager* manager) + : mManager(manager) {} + + void show (const MWWorld::Ptr& soulgem); + + void onButtonPressed(int button); + + private: + MessageBoxManager* mManager; + MWWorld::Ptr mSoulgem; + }; + +} + +#endif diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 718bb7106..eadd65787 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -57,6 +57,7 @@ #include "spellicons.hpp" #include "merchantrepair.hpp" #include "repair.hpp" +#include "soulgemdialog.hpp" using namespace MWGui; @@ -94,6 +95,7 @@ WindowManager::WindowManager( , mTrainingWindow(NULL) , mMerchantRepair(NULL) , mRepair(NULL) + , mSoulgemDialog(NULL) , mPlayerName() , mPlayerRaceId() , mPlayerAttributes() @@ -186,6 +188,7 @@ WindowManager::WindowManager( mTrainingWindow = new TrainingWindow(*this); mMerchantRepair = new MerchantRepair(*this); mRepair = new Repair(*this); + mSoulgemDialog = new SoulgemDialog(mMessageBoxManager); mLoadingScreen = new LoadingScreen(mRendering->getScene (), mRendering->getWindow (), *this); mLoadingScreen->onResChange (w,h); @@ -253,6 +256,7 @@ WindowManager::~WindowManager() delete mQuickKeysMenu; delete mMerchantRepair; delete mRepair; + delete mSoulgemDialog; delete mCursor; cleanupGarbage(); @@ -316,9 +320,6 @@ void WindowManager::updateVisible() mHud->setVisible(mHudEnabled); - // Mouse is visible whenever we're not in game mode - mCursor->setVisible(isGuiMode()); - bool gameMode = !isGuiMode(); mInputBlocker->setVisible (gameMode); @@ -444,8 +445,6 @@ void WindowManager::updateVisible() case GM_Repair: mRepair->setVisible(true); break; - case GM_InterMessageBox: - break; case GM_Journal: mJournal->setVisible(true); break; @@ -609,7 +608,7 @@ void WindowManager::messageBox (const std::string& message, const std::vectorcreateInteractiveMessageBox(message, buttons); - pushGuiMode(GM_InterMessageBox); + MWBase::Environment::get().getInputManager()->changeInputMode(isGuiMode()); } } @@ -648,6 +647,7 @@ void WindowManager::onDialogueWindowBye() void WindowManager::onFrame (float frameDuration) { mMessageBoxManager->onFrame(frameDuration); + mToolTips->onFrame(frameDuration); if (mDragAndDrop->mIsOnDragAndDrop) @@ -1033,12 +1033,12 @@ void WindowManager::toggleVisible (GuiWindow wnd) bool WindowManager::isGuiMode() const { - return !mGuiModes.empty(); + return !mGuiModes.empty() || mMessageBoxManager->isInteractiveMessageBox(); } bool WindowManager::isConsoleMode() const { - if (mGuiModes.back()==GM_Console) + if (!mGuiModes.empty() && mGuiModes.back()==GM_Console) return true; return false; } @@ -1046,8 +1046,7 @@ bool WindowManager::isConsoleMode() const MWGui::GuiMode WindowManager::getMode() const { if (mGuiModes.empty()) - throw std::runtime_error ("getMode() called, but there is no active mode"); - + return GM_None; return mGuiModes.back(); } @@ -1143,6 +1142,11 @@ void WindowManager::startEnchanting (MWWorld::Ptr actor) mEnchantingDialog->startEnchanting (actor); } +void WindowManager::startSelfEnchanting(MWWorld::Ptr soulgem) +{ + mEnchantingDialog->startSelfEnchanting(soulgem); +} + void WindowManager::startTraining(MWWorld::Ptr actor) { mTrainingWindow->startTraining(actor); @@ -1167,3 +1171,8 @@ void WindowManager::changePointer(const std::string &name) { mCursor->onCursorChange(name); } + +void WindowManager::showSoulgemDialog(MWWorld::Ptr item) +{ + mSoulgemDialog->show(item); +} diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 216ab9a6f..5cf7bae02 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -76,6 +76,7 @@ namespace MWGui class SpellIcons; class MerchantRepair; class Repair; + class SoulgemDialog; class WindowManager : public MWBase::WindowManager { @@ -230,14 +231,19 @@ namespace MWGui virtual void startSpellMaking(MWWorld::Ptr actor); virtual void startEnchanting(MWWorld::Ptr actor); + virtual void startSelfEnchanting(MWWorld::Ptr soulgem); virtual void startTraining(MWWorld::Ptr actor); virtual void startRepair(MWWorld::Ptr actor); virtual void startRepairItem(MWWorld::Ptr item); + virtual void showSoulgemDialog (MWWorld::Ptr item); + virtual void changePointer (const std::string& name); virtual const Translation::Storage& getTranslationDataStorage() const; + void onSoulgemDialogButtonPressed (int button); + private: OEngine::GUI::MyGUIManager *mGuiManager; OEngine::Render::OgreRenderer *mRendering; @@ -271,6 +277,7 @@ namespace MWGui EnchantingDialog* mEnchantingDialog; TrainingWindow* mTrainingWindow; MerchantRepair* mMerchantRepair; + SoulgemDialog* mSoulgemDialog; Repair* mRepair; Translation::Storage& mTranslationDataStorage; diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index f49422747..bd5367dad 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -181,8 +181,7 @@ namespace MWInput break; case A_Activate: resetIdleTime(); - if( MWBase::Environment::get().getWindowManager()->isGuiMode() - && MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_InterMessageBox ) { + if( MWBase::Environment::get().getWindowManager()->isGuiMode()) { // Pressing the activation key when a messagebox is prompting for "ok" will activate the ok button MWBase::Environment::get().getWindowManager()->enterPressed(); } @@ -378,7 +377,7 @@ namespace MWInput void InputManager::changeInputMode(bool guiMode) { - // Are we in GUI mode now? + MWBase::Environment::get().getWindowManager()->setMouseVisible(guiMode); if(guiMode) { // Disable mouse look @@ -462,8 +461,7 @@ namespace MWInput bool InputManager::keyPressed( const OIS::KeyEvent &arg ) { if(arg.key == OIS::KC_RETURN - && MWBase::Environment::get().getWindowManager()->isGuiMode() - && MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_InterMessageBox ) + && MWBase::Environment::get().getWindowManager()->isGuiMode()) { // Pressing enter when a messagebox is prompting for "ok" will activate the ok button MWBase::Environment::get().getWindowManager()->enterPressed(); diff --git a/apps/openmw/mwworld/actionsoulgem.cpp b/apps/openmw/mwworld/actionsoulgem.cpp new file mode 100644 index 000000000..6746f692f --- /dev/null +++ b/apps/openmw/mwworld/actionsoulgem.cpp @@ -0,0 +1,21 @@ +#include "actionsoulgem.hpp" + +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/environment.hpp" + +namespace MWWorld +{ + +ActionSoulgem::ActionSoulgem(const Ptr &object) + : Action(false, object) +{ + +} + +void ActionSoulgem::executeImp(const Ptr &actor) +{ + MWBase::Environment::get().getWindowManager()->showSoulgemDialog(getTarget()); +} + + +} diff --git a/apps/openmw/mwworld/actionsoulgem.hpp b/apps/openmw/mwworld/actionsoulgem.hpp new file mode 100644 index 000000000..0dd526657 --- /dev/null +++ b/apps/openmw/mwworld/actionsoulgem.hpp @@ -0,0 +1,19 @@ +#ifndef GAME_MWWORLD_ACTIONSOULGEM_H +#define GAME_MWWORLD_ACTIONSOULGEM_H + +#include "action.hpp" +#include "ptr.hpp" + +namespace MWWorld +{ + class ActionSoulgem : public Action + { + virtual void executeImp (const MWWorld::Ptr& actor); + + public: + /// @param soulgem to use + ActionSoulgem (const Ptr& object); + }; +} + +#endif From a031c7761943afc38df5e0ea2a595a3cdcc4d90f Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 30 Mar 2013 15:56:14 +0100 Subject: [PATCH 08/26] Improved enchanting layout --- files/mygui/openmw_enchanting_dialog.layout | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/files/mygui/openmw_enchanting_dialog.layout b/files/mygui/openmw_enchanting_dialog.layout index 2549fd26f..41b8ffa93 100644 --- a/files/mygui/openmw_enchanting_dialog.layout +++ b/files/mygui/openmw_enchanting_dialog.layout @@ -70,18 +70,18 @@ - + - + - + - - + + From c8606d2f63d63c8db1cca9838d2f03466587907f Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 30 Mar 2013 13:20:51 -0700 Subject: [PATCH 09/26] Implement IsWerewolf script function --- apps/openmw/mwscript/docs/vmformat.txt | 4 +++- apps/openmw/mwscript/statsextensions.cpp | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 0f07b4d2e..7e9827062 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -316,5 +316,7 @@ op 0x20001f9: Drop, explicit reference op 0x20001fa: DropSoulGem op 0x20001fb: DropSoulGem, explicit reference op 0x20001fc: OnDeath +op 0x20001fd: IsWerewolf +op 0x20001fe: IsWerewolf, explicit reference -opcodes 0x20001fd-0x3ffffff unused +opcodes 0x20001ff-0x3ffffff unused diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index c5fc9436b..1d321fbbb 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -1046,6 +1046,18 @@ namespace MWScript } }; + template + class OpIsWerewolf : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + runtime.push(MWWorld::Class::get(ptr).getNpcStats(ptr).isWerewolf()); + } + }; + const int numberOfAttributes = 8; const int opcodeGetAttribute = 0x2000027; @@ -1137,6 +1149,9 @@ namespace MWScript const int opcodeOnDeath = 0x20001fc; + const int opcodeIsWerewolf = 0x20001fd; + const int opcodeIsWerewolfExplicit = 0x20001fe; + void registerExtensions (Compiler::Extensions& extensions) { static const char *attributes[numberOfAttributes] = @@ -1252,6 +1267,8 @@ namespace MWScript extensions.registerInstruction ("lowerrank", "", opcodeLowerRank, opcodeLowerRankExplicit); extensions.registerFunction ("ondeath", 'l', "", opcodeOnDeath); + + extensions.registerFunction ("iswerewolf", 'l', "", opcodeIsWerewolf, opcodeIsWerewolfExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -1368,6 +1385,9 @@ namespace MWScript interpreter.installSegment5 (opcodeLowerRankExplicit, new OpLowerRank); interpreter.installSegment5 (opcodeOnDeath, new OpOnDeath); + + interpreter.installSegment5 (opcodeIsWerewolf, new OpIsWerewolf); + interpreter.installSegment5 (opcodeIsWerewolfExplicit, new OpIsWerewolf); } } } From 63af72c31577454322524c30982f964e4b6cfaa3 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 30 Mar 2013 17:31:16 -0700 Subject: [PATCH 10/26] Avoid converting to and from quaternions --- apps/openmw/mwrender/renderingmanager.cpp | 34 +++++++++-------------- apps/openmw/mwworld/worldimp.cpp | 4 ++- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 1bab676c3..7c442c686 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -262,37 +262,29 @@ void RenderingManager::scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3 ptr.getRefData().getBaseNode()->setScale(scale); } -bool RenderingManager::rotateObject( const MWWorld::Ptr &ptr, Ogre::Vector3 &rot, bool adjust) +bool RenderingManager::rotateObject(const MWWorld::Ptr &ptr, Ogre::Vector3 &rot, bool adjust) { bool isActive = ptr.getRefData().getBaseNode() != 0; bool isPlayer = isActive && ptr.getRefData().getHandle() == "player"; bool force = true; - + if (isPlayer) force = mPlayer->rotate(rot, adjust); - - MWWorld::Class::get(ptr).adjustRotation(ptr, rot.x, rot.y, rot.z); + MWWorld::Class::get(ptr).adjustRotation(ptr, rot.x, rot.y, rot.z); if (!isPlayer && isActive) { - Ogre::Quaternion xr(Ogre::Radian(-rot.x), Ogre::Vector3::UNIT_X); - Ogre::Quaternion yr(Ogre::Radian(-rot.y), Ogre::Vector3::UNIT_Y); - Ogre::Quaternion zr(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Z); - - Ogre::Quaternion xref(Ogre::Radian(-ptr.getRefData().getPosition().rot[0]), Ogre::Vector3::UNIT_X); - Ogre::Quaternion yref(Ogre::Radian(-ptr.getRefData().getPosition().rot[1]), Ogre::Vector3::UNIT_Y); - Ogre::Quaternion zref(Ogre::Radian(-ptr.getRefData().getPosition().rot[2]), Ogre::Vector3::UNIT_Z); - - Ogre::Quaternion newo = adjust ? (xr * yr * zr) * (xref*yref*zref) : xr * yr * zr; - - Ogre::Matrix3 mat; - newo.ToRotationMatrix(mat); - Ogre::Radian ax,ay,az; - mat.ToEulerAnglesXYZ(ax,ay,az); - rot.x = -ax.valueRadians(); - rot.y = -ay.valueRadians(); - rot.z = -az.valueRadians(); + if(adjust) + { + const float *objRot = ptr.getRefData().getPosition().rot; + rot.x += objRot[0]; + rot.y += objRot[1]; + rot.z += objRot[2]; + } + Ogre::Quaternion newo = Ogre::Quaternion(Ogre::Radian(-rot.x), Ogre::Vector3::UNIT_X) * + Ogre::Quaternion(Ogre::Radian(-rot.y), Ogre::Vector3::UNIT_Y) * + Ogre::Quaternion(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Z); ptr.getRefData().getBaseNode()->setOrientation(newo); } else if(isPlayer) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 75ff6ec83..209e4c4be 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -816,7 +816,9 @@ namespace MWWorld { // rotate physically iff renderer confirm so float *objRot = ptr.getRefData().getPosition().rot; - objRot[0] = rot.x, objRot[1] = rot.y, objRot[2] = rot.z; + objRot[0] = rot.x; + objRot[1] = rot.y; + objRot[2] = rot.z; if (ptr.getRefData().getBaseNode() != 0) { mPhysics->rotateObject(ptr); From af65ecd8415b3504c26b8d9fdb8d713bfef2fa89 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 30 Mar 2013 18:37:40 -0700 Subject: [PATCH 11/26] Pass the movement vector in as a parameter to CharacterController::update --- apps/openmw/mwmechanics/activators.cpp | 5 ++++- apps/openmw/mwmechanics/actors.cpp | 3 ++- apps/openmw/mwmechanics/character.cpp | 6 +----- apps/openmw/mwmechanics/character.hpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwmechanics/activators.cpp b/apps/openmw/mwmechanics/activators.cpp index b67fcb216..51fa55f4e 100644 --- a/apps/openmw/mwmechanics/activators.cpp +++ b/apps/openmw/mwmechanics/activators.cpp @@ -56,7 +56,10 @@ void Activators::update(float duration, bool paused) if(!paused) { for(PtrControllerMap::iterator iter(mActivators.begin());iter != mActivators.end();++iter) - iter->second.update(duration); + { + Ogre::Vector3 movement(0.0f); + iter->second.update(duration, movement); + } } } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 1480b3182..a7615311b 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -266,7 +266,8 @@ namespace MWMechanics for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter) { - Ogre::Vector3 movement = iter->second.update(duration); + Ogre::Vector3 movement(0.0f); + iter->second.update(duration, movement); mMovement.push_back(std::make_pair(iter->first, movement)); } MWBase::Environment::get().getWorld()->doPhysics(mMovement, duration); diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 62958db8d..5e112d54e 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -168,10 +168,8 @@ void CharacterController::markerEvent(float time, const std::string &evt) } -Ogre::Vector3 CharacterController::update(float duration) +void CharacterController::update(float duration, Ogre::Vector3 &movement) { - Ogre::Vector3 movement(0.0f); - float speed = 0.0f; if(!(getState() >= CharState_Death1)) { @@ -240,8 +238,6 @@ Ogre::Vector3 CharacterController::update(float duration) movement += mAnimation->runAnimation(duration); } mSkipAnim = false; - - return movement; } diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 46f0690e7..8cba49b5f 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -87,7 +87,7 @@ public: void updatePtr(const MWWorld::Ptr &ptr); - Ogre::Vector3 update(float duration); + void update(float duration, Ogre::Vector3 &movement); void playGroup(const std::string &groupname, int mode, int count); void skipAnim(); From 0ce188b7cc02ef6e1cd49ceb8fd1b5e24cc1d48c Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 30 Mar 2013 19:00:46 -0700 Subject: [PATCH 12/26] Store the position and rotation in MWMechanics::Movement --- apps/openmw/mwclass/npc.cpp | 9 ++------- apps/openmw/mwmechanics/character.cpp | 2 +- apps/openmw/mwmechanics/movement.hpp | 11 +++++++---- apps/openmw/mwworld/player.cpp | 8 ++++---- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index a5319ada0..61d081b4b 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -368,7 +368,7 @@ namespace MWClass moveSpeed = runSpeed; else moveSpeed = walkSpeed; - if(getMovementSettings(ptr).mLeftRight != 0 && getMovementSettings(ptr).mForwardBackward == 0) + if(getMovementSettings(ptr).mPosition[0] != 0 && getMovementSettings(ptr).mPosition[1] == 0) moveSpeed *= 0.75f; return moveSpeed; @@ -414,12 +414,7 @@ namespace MWClass Ogre::Vector3 Npc::getMovementVector (const MWWorld::Ptr& ptr) const { - Ogre::Vector3 vector; - vector.x = getMovementSettings(ptr).mLeftRight; - vector.y = getMovementSettings(ptr).mForwardBackward; - vector.z = getMovementSettings(ptr).mUpDown; - - return vector; + return Ogre::Vector3(getMovementSettings(ptr).mPosition); } bool Npc::isEssential (const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 5e112d54e..ea9ff7e10 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -175,12 +175,12 @@ void CharacterController::update(float duration, Ogre::Vector3 &movement) { const MWBase::World *world = MWBase::Environment::get().getWorld(); const MWWorld::Class &cls = MWWorld::Class::get(mPtr); - const Ogre::Vector3 &vec = cls.getMovementVector(mPtr); bool onground = world->isOnGround(mPtr); bool inwater = world->isSwimming(mPtr); bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run); bool sneak = cls.getStance(mPtr, MWWorld::Class::Sneak); + const Ogre::Vector3 &vec = cls.getMovementVector(mPtr); speed = cls.getSpeed(mPtr); /* FIXME: The state should be set to Jump, and X/Y movement should be disallowed except diff --git a/apps/openmw/mwmechanics/movement.hpp b/apps/openmw/mwmechanics/movement.hpp index 11eb83151..6c9a4b758 100644 --- a/apps/openmw/mwmechanics/movement.hpp +++ b/apps/openmw/mwmechanics/movement.hpp @@ -6,11 +6,14 @@ namespace MWMechanics /// Desired movement for an actor struct Movement { - signed char mLeftRight; // 1: wants to move left, -1: wants to move right - signed char mForwardBackward; // 1:wants to move forward, -1: wants to move backward - signed char mUpDown; + float mPosition[3]; + float mRotation[3]; - Movement() : mLeftRight (0), mForwardBackward (0), mUpDown(0) {} + Movement() + { + mPosition[0] = mPosition[1] = mPosition[2] = 0.0f; + mRotation[0] = mRotation[1] = mRotation[2] = 0.0f; + } }; } diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 0dc8b37ef..b01b929c4 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -42,14 +42,14 @@ namespace MWWorld if (mAutoMove) value = 1; - MWWorld::Class::get (ptr).getMovementSettings (ptr).mForwardBackward = value; + MWWorld::Class::get (ptr).getMovementSettings (ptr).mPosition[1] = value; } void Player::setLeftRight (int value) { MWWorld::Ptr ptr = getPlayer(); - MWWorld::Class::get (ptr).getMovementSettings (ptr).mLeftRight = value; + MWWorld::Class::get (ptr).getMovementSettings (ptr).mPosition[0] = value; } void Player::setForwardBackward (int value) @@ -61,14 +61,14 @@ namespace MWWorld if (mAutoMove) value = 1; - MWWorld::Class::get (ptr).getMovementSettings (ptr).mForwardBackward = value; + MWWorld::Class::get (ptr).getMovementSettings (ptr).mPosition[1] = value; } void Player::setUpDown(int value) { MWWorld::Ptr ptr = getPlayer(); - MWWorld::Class::get (ptr).getMovementSettings (ptr).mUpDown = value; + MWWorld::Class::get (ptr).getMovementSettings (ptr).mPosition[2] = value; } void Player::setRunState(bool run) From 466c0086b84eaca4da61b8d3a64e9ba675ebe24a Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 31 Mar 2013 00:13:56 -0700 Subject: [PATCH 13/26] Use a full Movement to hand off to the world physics update --- apps/openmw/mwbase/world.hpp | 7 ++++++- apps/openmw/mwmechanics/activators.cpp | 4 +++- apps/openmw/mwmechanics/actors.cpp | 3 ++- apps/openmw/mwmechanics/actors.hpp | 1 + apps/openmw/mwmechanics/character.cpp | 17 +++++++++++------ apps/openmw/mwmechanics/character.hpp | 4 +++- apps/openmw/mwworld/worldimp.cpp | 5 +++-- 7 files changed, 29 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 67d7dda6a..8eea383eb 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -44,6 +44,11 @@ namespace MWRender class Animation; } +namespace MWMechanics +{ + class Movement; +} + namespace MWWorld { class Fallback; @@ -54,7 +59,7 @@ namespace MWWorld class ESMStore; class RefData; - typedef std::vector > PtrMovementList; + typedef std::vector > PtrMovementList; } namespace MWBase diff --git a/apps/openmw/mwmechanics/activators.cpp b/apps/openmw/mwmechanics/activators.cpp index 51fa55f4e..cbc380299 100644 --- a/apps/openmw/mwmechanics/activators.cpp +++ b/apps/openmw/mwmechanics/activators.cpp @@ -2,6 +2,8 @@ #include +#include "movement.hpp" + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -57,7 +59,7 @@ void Activators::update(float duration, bool paused) { for(PtrControllerMap::iterator iter(mActivators.begin());iter != mActivators.end();++iter) { - Ogre::Vector3 movement(0.0f); + Movement movement; iter->second.update(duration, movement); } } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index a7615311b..6aae85087 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -17,6 +17,7 @@ #include "../mwbase/windowmanager.hpp" #include "creaturestats.hpp" +#include "movement.hpp" namespace MWMechanics { @@ -266,7 +267,7 @@ namespace MWMechanics for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter) { - Ogre::Vector3 movement(0.0f); + Movement movement; iter->second.update(duration, movement); mMovement.push_back(std::make_pair(iter->first, movement)); } diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index fc4af8dd6..aabd86dc7 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -7,6 +7,7 @@ #include #include "character.hpp" +#include "movement.hpp" #include "../mwbase/world.hpp" namespace Ogre diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index ea9ff7e10..3bba065ff 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -21,6 +21,8 @@ #include +#include "movement.hpp" + #include "../mwrender/animation.hpp" #include "../mwbase/environment.hpp" @@ -168,7 +170,7 @@ void CharacterController::markerEvent(float time, const std::string &evt) } -void CharacterController::update(float duration, Ogre::Vector3 &movement) +void CharacterController::update(float duration, Movement &movement) { float speed = 0.0f; if(!(getState() >= CharState_Death1)) @@ -190,14 +192,14 @@ void CharacterController::update(float duration, Ogre::Vector3 &movement) float x = cls.getJump(mPtr); if(vec.x == 0 && vec.y == 0) - movement.z += x*duration; + movement.mPosition[2] += x*duration; else { /* FIXME: this would be more correct if we were going into a jumping state, * rather than normal walking/idle states. */ //Ogre::Vector3 lat = Ogre::Vector3(vec.x, vec.y, 0.0f).normalisedCopy(); //movement += Ogre::Vector3(lat.x, lat.y, 1.0f) * x * 0.707f * duration; - movement.z += x * 0.707f * duration; + movement.mPosition[2] += x * 0.707f * duration; } //decrease fatigue by fFatigueJumpBase + (1 - normalizedEncumbrance) * fFatigueJumpMult; @@ -214,7 +216,7 @@ void CharacterController::update(float duration, Ogre::Vector3 &movement) : (sneak ? CharState_SneakLeft : (isrunning ? CharState_RunLeft : CharState_WalkLeft)), true); // Apply any forward/backward movement manually - movement.y += vec.y * (speed*duration); + movement.mPosition[1] += vec.y * (speed*duration); } else if(vec.y != 0.0f && speed > 0.0f) { @@ -226,7 +228,7 @@ void CharacterController::update(float duration, Ogre::Vector3 &movement) setState(inwater ? (isrunning ? CharState_SwimRunBack : CharState_SwimWalkBack) : (sneak ? CharState_SneakBack : (isrunning ? CharState_RunBack : CharState_WalkBack)), true); // Apply any sideways movement manually - movement.x += vec.x * (speed*duration); + movement.mPosition[0] += vec.x * (speed*duration); } else if(mAnimQueue.size() == 0) setState((inwater ? CharState_IdleSwim : (sneak ? CharState_IdleSneak : CharState_Idle)), true); @@ -235,7 +237,10 @@ void CharacterController::update(float duration, Ogre::Vector3 &movement) if(mAnimation && !mSkipAnim) { mAnimation->setSpeed(speed); - movement += mAnimation->runAnimation(duration); + Ogre::Vector3 moved = mAnimation->runAnimation(duration); + movement.mPosition[0] += moved.x; + movement.mPosition[1] += moved.y; + movement.mPosition[2] += moved.z; } mSkipAnim = false; } diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 8cba49b5f..61efd0be0 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -13,6 +13,8 @@ namespace MWRender namespace MWMechanics { +class Movement; + enum CharacterState { CharState_SpecialIdle, CharState_Idle, @@ -87,7 +89,7 @@ public: void updatePtr(const MWWorld::Ptr &ptr); - void update(float duration, Ogre::Vector3 &movement); + void update(float duration, Movement &movement); void playGroup(const std::string &groupname, int mode, int count); void skipAnim(); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 209e4c4be..37fa73279 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -13,6 +13,7 @@ #include "../mwbase/scriptmanager.hpp" #include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/movement.hpp" #include "../mwrender/sky.hpp" #include "../mwrender/player.hpp" @@ -875,13 +876,13 @@ namespace MWWorld player = iter; continue; } - Ogre::Vector3 vec = mPhysics->move(iter->first, iter->second, duration, + Ogre::Vector3 vec = mPhysics->move(iter->first, Ogre::Vector3(iter->second.mPosition), duration, !isSwimming(iter->first) && !isFlying(iter->first)); moveObjectImp(iter->first, vec.x, vec.y, vec.z); } if(player != actors.end()) { - Ogre::Vector3 vec = mPhysics->move(player->first, player->second, duration, + Ogre::Vector3 vec = mPhysics->move(player->first, Ogre::Vector3(player->second.mPosition), duration, !isSwimming(player->first) && !isFlying(player->first)); moveObjectImp(player->first, vec.x, vec.y, vec.z); } From 13be61812a101d2278234044cf72a4bc5fd27440 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 31 Mar 2013 10:16:02 +0200 Subject: [PATCH 14/26] Made the "Unknown class key" exception slightly more helpful --- apps/openmw/mwworld/class.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 876328641..1eb2f35bd 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -184,10 +184,13 @@ namespace MWWorld const Class& Class::get (const std::string& key) { + if (key.empty()) + throw std::logic_error ("Class::get(): attempting to get an empty key"); + std::map >::const_iterator iter = sClasses.find (key); if (iter==sClasses.end()) - throw std::logic_error ("unknown class key: " + key); + throw std::logic_error ("Class::get(): unknown class key: " + key); return *iter->second; } From 7b02ec411bcb04fb667eda5c509a9b6b33bbe806 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 31 Mar 2013 01:29:24 -0700 Subject: [PATCH 15/26] Apply the rotation when updating the character controller --- apps/openmw/mwclass/npc.cpp | 7 ++++++- apps/openmw/mwclass/npc.hpp | 3 +++ apps/openmw/mwmechanics/character.cpp | 5 +++++ apps/openmw/mwworld/class.cpp | 5 +++++ apps/openmw/mwworld/class.hpp | 3 +++ 5 files changed, 22 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 61d081b4b..e3733fe7c 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -416,7 +416,12 @@ namespace MWClass { return Ogre::Vector3(getMovementSettings(ptr).mPosition); } - + + Ogre::Vector3 Npc::getRotationVector (const MWWorld::Ptr& ptr) const + { + return Ogre::Vector3(getMovementSettings(ptr).mRotation); + } + bool Npc::isEssential (const MWWorld::Ptr& ptr) const { MWWorld::LiveCellRef *ref = diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index 0f61fc8c9..1a10bce6c 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -96,6 +96,9 @@ namespace MWClass ///< Return desired movement vector (determined based on movement settings, /// stance and stats). + virtual Ogre::Vector3 getRotationVector (const MWWorld::Ptr& ptr) const; + ///< Return desired rotations, as euler angles. + virtual float getCapacity (const MWWorld::Ptr& ptr) const; ///< Return total weight that fits into the object. Throws an exception, if the object can't /// hold other objects. diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 3bba065ff..56de21d27 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -183,6 +183,7 @@ void CharacterController::update(float duration, Movement &movement) bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run); bool sneak = cls.getStance(mPtr, MWWorld::Class::Sneak); const Ogre::Vector3 &vec = cls.getMovementVector(mPtr); + const Ogre::Vector3 &rot = cls.getRotationVector(mPtr); speed = cls.getSpeed(mPtr); /* FIXME: The state should be set to Jump, and X/Y movement should be disallowed except @@ -232,6 +233,10 @@ void CharacterController::update(float duration, Movement &movement) } else if(mAnimQueue.size() == 0) setState((inwater ? CharState_IdleSwim : (sneak ? CharState_IdleSneak : CharState_Idle)), true); + + movement.mRotation[0] += rot.x * duration; + movement.mRotation[1] += rot.y * duration; + movement.mRotation[2] += rot.z * duration; } if(mAnimation && !mSkipAnim) diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 876328641..571815d9e 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -142,6 +142,11 @@ namespace MWWorld return Ogre::Vector3 (0, 0, 0); } + Ogre::Vector3 Class::getRotationVector (const Ptr& ptr) const + { + return Ogre::Vector3 (0, 0, 0); + } + std::pair, bool> Class::getEquipmentSlots (const Ptr& ptr) const { return std::make_pair (std::vector(), false); diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 012a03bf6..36d7e97db 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -150,6 +150,9 @@ namespace MWWorld ///< Return desired movement vector (determined based on movement settings, /// stance and stats). + virtual Ogre::Vector3 getRotationVector (const Ptr& ptr) const; + ///< Return desired rotations, as euler angles. + virtual std::pair, bool> getEquipmentSlots (const Ptr& ptr) const; ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? From 38d19d33d8029ecddfcc1b66f8d5a978e9b8d69e Mon Sep 17 00:00:00 2001 From: lazydev Date: Sat, 30 Mar 2013 22:18:34 +0400 Subject: [PATCH 16/26] fix for #634 --- apps/openmw/mwdialogue/filter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index cd9908d3d..f7e952956 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -198,7 +198,7 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c if (imData.mNumLongs) return select.selectCompare (locals.mLongs[i]); - i -= script->mData.mNumShorts; + i -= script->mData.mNumLongs; return select.selectCompare (locals.mFloats.at (i)); } From b6f2b39a2fa0139300009975818a29377b2aaf36 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 31 Mar 2013 01:56:38 -0700 Subject: [PATCH 17/26] Clear the movement and rotation vector when getting them --- apps/openmw/mwclass/npc.cpp | 14 ++++++++++++-- apps/openmw/mwinput/inputmanagerimp.cpp | 6 ------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index e3733fe7c..cd6b0def1 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -414,12 +414,22 @@ namespace MWClass Ogre::Vector3 Npc::getMovementVector (const MWWorld::Ptr& ptr) const { - return Ogre::Vector3(getMovementSettings(ptr).mPosition); + MWMechanics::Movement &movement = getMovementSettings(ptr); + Ogre::Vector3 vec(movement.mPosition); + movement.mPosition[0] = 0.0f; + movement.mPosition[1] = 0.0f; + movement.mPosition[2] = 0.0f; + return vec; } Ogre::Vector3 Npc::getRotationVector (const MWWorld::Ptr& ptr) const { - return Ogre::Vector3(getMovementSettings(ptr).mRotation); + MWMechanics::Movement &movement = getMovementSettings(ptr); + Ogre::Vector3 vec(movement.mRotation); + movement.mRotation[0] = 0.0f; + movement.mRotation[1] = 0.0f; + movement.mRotation[2] = 0.0f; + return vec; } bool Npc::isEssential (const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 013c722c0..1d55ff84d 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -288,8 +288,6 @@ namespace MWInput triedToMove = true; mPlayer.setLeftRight (1); } - else - mPlayer.setLeftRight (0); if (actionIsActive(A_MoveForward)) { @@ -303,8 +301,6 @@ namespace MWInput mPlayer.setAutoMove (false); mPlayer.setForwardBackward (-1); } - else - mPlayer.setForwardBackward (0); mPlayer.setSneak(actionIsActive(A_Sneak)); @@ -313,8 +309,6 @@ namespace MWInput mPlayer.setUpDown (1); triedToMove = true; } - else - mPlayer.setUpDown (0); if (mAlwaysRunActive) mPlayer.setRunState(!actionIsActive(A_Run)); From 18e8ff7198b0b7247c3ba0fae5101ca0f653e106 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 31 Mar 2013 02:24:44 -0700 Subject: [PATCH 18/26] Actually rotate the object when updating physics --- apps/openmw/mwworld/worldimp.cpp | 20 ++++++++++++++------ apps/openmw/mwworld/worldimp.hpp | 2 ++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 37fa73279..ae0e02c8c 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -806,13 +806,8 @@ namespace MWWorld mPhysics->scaleObject(ptr); } - void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust) + void World::rotateObjectImp (const Ptr& ptr, Ogre::Vector3 rot, bool adjust) { - Ogre::Vector3 rot; - rot.x = Ogre::Degree(x).valueRadians(); - rot.y = Ogre::Degree(y).valueRadians(); - rot.z = Ogre::Degree(z).valueRadians(); - if (mRendering->rotateObject(ptr, rot, adjust)) { // rotate physically iff renderer confirm so @@ -827,6 +822,14 @@ namespace MWWorld } } + void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust) + { + rotateObjectImp(ptr, Ogre::Vector3(Ogre::Degree(x).valueRadians(), + Ogre::Degree(y).valueRadians(), + Ogre::Degree(z).valueRadians()), + adjust); + } + void World::safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos) { copyObjectToCell(ptr,Cell,pos); @@ -876,12 +879,17 @@ namespace MWWorld player = iter; continue; } + + rotateObjectImp(iter->first, Ogre::Vector3(iter->second.mRotation), true); + Ogre::Vector3 vec = mPhysics->move(iter->first, Ogre::Vector3(iter->second.mPosition), duration, !isSwimming(iter->first) && !isFlying(iter->first)); moveObjectImp(iter->first, vec.x, vec.y, vec.z); } if(player != actors.end()) { + rotateObjectImp(player->first, Ogre::Vector3(player->second.mRotation), true); + Ogre::Vector3 vec = mPhysics->move(player->first, Ogre::Vector3(player->second.mPosition), duration, !isSwimming(player->first) && !isFlying(player->first)); moveObjectImp(player->first, vec.x, vec.y, vec.z); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 8554d904a..8cff50bd1 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -90,6 +90,8 @@ namespace MWWorld int getDaysPerMonth (int month) const; + void rotateObjectImp (const Ptr& ptr, Ogre::Vector3 rot, bool adjust); + bool moveObjectImp (const Ptr& ptr, float x, float y, float z); ///< @return true if the active cell (cell player is in) changed From 13c098266cbe17e49917ff3b1306765b9f853452 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 31 Mar 2013 02:57:22 -0700 Subject: [PATCH 19/26] Pass player rotation through the movement settings --- apps/openmw/mwinput/inputmanagerimp.cpp | 8 ++++---- apps/openmw/mwworld/player.cpp | 16 ++++++++++++++++ apps/openmw/mwworld/player.hpp | 4 ++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 1d55ff84d..c23efe579 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -538,11 +538,11 @@ namespace MWInput { resetIdleTime(); - float x = arg.state.X.rel * mCameraSensitivity * 0.2; - float y = arg.state.Y.rel * mCameraSensitivity * 0.2 * (mInvertY ? -1 : 1) * mUIYMultiplier; + float x = arg.state.X.rel * mCameraSensitivity * 0.2f; + float y = arg.state.Y.rel * mCameraSensitivity * 0.2f * (mInvertY ? -1 : 1) * mUIYMultiplier; - MWBase::World *world = MWBase::Environment::get().getWorld(); - world->rotateObject(world->getPlayer().getPlayer(), -y, 0.f, x, true); + mPlayer.setYaw(x); + mPlayer.setPitch(-y); if (arg.state.Z.rel) MWBase::Environment::get().getWorld()->changeVanityModeScale(arg.state.Z.rel); diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index b01b929c4..ea8a02dee 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -84,6 +84,22 @@ namespace MWWorld MWWorld::Class::get (ptr).setStance (ptr, MWWorld::Class::Sneak, sneak); } + void Player::setYaw(float yaw) + { + MWWorld::Ptr ptr = getPlayer(); + MWWorld::Class::get(ptr).getMovementSettings(ptr).mRotation[2] = yaw; + } + void Player::setPitch(float pitch) + { + MWWorld::Ptr ptr = getPlayer(); + MWWorld::Class::get(ptr).getMovementSettings(ptr).mRotation[0] = pitch; + } + void Player::setRoll(float roll) + { + MWWorld::Ptr ptr = getPlayer(); + MWWorld::Class::get(ptr).getMovementSettings(ptr).mRotation[1] = roll; + } + MWMechanics::DrawState_ Player::getDrawState() { MWWorld::Ptr ptr = getPlayer(); diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index d82d3fc32..c98551091 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -67,6 +67,10 @@ namespace MWWorld void setRunState(bool run); void setSneak(bool sneak); + + void setYaw(float yaw); + void setPitch(float pitch); + void setRoll(float roll); }; } #endif From 4836ba16f763ceca71cbc7557ebea44561d85184 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 31 Mar 2013 03:50:20 -0700 Subject: [PATCH 20/26] Implement turning states --- apps/openmw/mwmechanics/character.cpp | 10 ++++++++++ apps/openmw/mwmechanics/character.hpp | 3 +++ 2 files changed, 13 insertions(+) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 56de21d27..7aff2e1d0 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -75,6 +75,9 @@ static const struct { { CharState_SneakLeft, "sneakleft" }, { CharState_SneakRight, "sneakright" }, + { CharState_TurnLeft, "turnleft" }, + { CharState_TurnRight, "turnright" }, + { CharState_Jump, "jump" }, { CharState_Death1, "death1" }, @@ -231,6 +234,13 @@ void CharacterController::update(float duration, Movement &movement) // Apply any sideways movement manually movement.mPosition[0] += vec.x * (speed*duration); } + else if(rot.z != 0.0f && !inwater && !sneak) + { + if(rot.z > 0.0f) + setState(CharState_TurnRight, true); + else if(rot.z < 0.0f) + setState(CharState_TurnLeft, true); + } else if(mAnimQueue.size() == 0) setState((inwater ? CharState_IdleSwim : (sneak ? CharState_IdleSneak : CharState_Idle)), true); diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 61efd0be0..5b5a65f79 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -54,6 +54,9 @@ enum CharacterState { CharState_SneakLeft, CharState_SneakRight, + CharState_TurnLeft, + CharState_TurnRight, + CharState_Jump, /* Death states must be last! */ From b0199c703ce0f37fbb2ea0b4a65d9cd77e7a8c38 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 31 Mar 2013 13:13:46 +0200 Subject: [PATCH 21/26] Companion UI --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwbase/dialoguemanager.hpp | 2 ++ apps/openmw/mwbase/windowmanager.hpp | 2 ++ apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 28 ++++++++++++------- apps/openmw/mwdialogue/dialoguemanagerimp.hpp | 2 ++ apps/openmw/mwgui/container.cpp | 3 ++ apps/openmw/mwgui/container.hpp | 4 +++ apps/openmw/mwgui/dialogue.cpp | 19 +++++++++++-- apps/openmw/mwgui/hud.cpp | 3 +- apps/openmw/mwgui/inventorywindow.cpp | 5 +--- apps/openmw/mwgui/inventorywindow.hpp | 4 +-- apps/openmw/mwgui/mode.hpp | 1 + apps/openmw/mwgui/windowmanagerimp.cpp | 14 ++++++++++ apps/openmw/mwgui/windowmanagerimp.hpp | 3 ++ apps/openmw/mwmechanics/npcstats.cpp | 22 +++++++++++++-- apps/openmw/mwmechanics/npcstats.hpp | 5 ++++ apps/openmw/mwscript/locals.cpp | 24 ++++++++++++++++ apps/openmw/mwscript/locals.hpp | 1 + apps/openmw/mwscript/scriptmanagerimp.cpp | 2 +- files/mygui/CMakeLists.txt | 1 + files/mygui/openmw_container_window.layout | 2 +- files/mygui/openmw_inventory_window.layout | 3 +- files/mygui/openmw_text.skin.xml | 5 ++++ 23 files changed, 130 insertions(+), 27 deletions(-) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 41f56f993..da8d47439 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -31,7 +31,7 @@ add_openmw_dir (mwgui confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons - merchantrepair repair soulgemdialog + merchantrepair repair soulgemdialog companionwindow ) add_openmw_dir (mwdialogue diff --git a/apps/openmw/mwbase/dialoguemanager.hpp b/apps/openmw/mwbase/dialoguemanager.hpp index db86385d4..de39b212a 100644 --- a/apps/openmw/mwbase/dialoguemanager.hpp +++ b/apps/openmw/mwbase/dialoguemanager.hpp @@ -25,6 +25,8 @@ namespace MWBase virtual ~DialogueManager() {} + virtual bool isInChoice() const = 0; + virtual void startDialogue (const MWWorld::Ptr& actor) = 0; virtual void addTopic (const std::string& topic) = 0; diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 58897dc74..4d66a7742 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -201,6 +201,7 @@ namespace MWBase ///< Hides dialog and schedules dialog to be deleted. virtual void messageBox (const std::string& message, const std::vector& buttons = std::vector()) = 0; + virtual void enterPressed () = 0; virtual int readPressedButton() = 0; ///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox) @@ -235,6 +236,7 @@ namespace MWBase virtual bool getPlayerSleeping() = 0; virtual void wakeUpPlayer() = 0; + virtual void showCompanionWindow(MWWorld::Ptr actor) = 0; virtual void startSpellMaking(MWWorld::Ptr actor) = 0; virtual void startEnchanting(MWWorld::Ptr actor) = 0; virtual void startSelfEnchanting(MWWorld::Ptr soulgem) = 0; diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index b75c514a2..9380ab76c 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -117,6 +117,8 @@ namespace MWDialogue void DialogueManager::startDialogue (const MWWorld::Ptr& actor) { + mLastTopic = ""; + mChoice = -1; mIsInChoice = false; @@ -127,6 +129,9 @@ namespace MWDialogue mActorKnownTopics.clear(); + MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); + win->startDialogue(actor, MWWorld::Class::get (actor).getName (actor)); + //setup the list of topics known by the actor. Topics who are also on the knownTopics list will be added to the GUI updateTopics(); @@ -145,8 +150,6 @@ namespace MWDialogue { //initialise the GUI MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Dialogue); - MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); - win->startDialogue(actor, MWWorld::Class::get (actor).getName (actor)); creatureStats.talkedToPlayer(); @@ -160,7 +163,7 @@ namespace MWDialogue MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor); win->addText (Interpreter::fixDefinesDialog(info->mResponse, interpreterContext)); executeScript (info->mResultScript); - mLastTopic = it->mId; + mLastTopic = Misc::StringUtils::lowerCase(it->mId); mLastDialogue = *info; break; } @@ -398,6 +401,11 @@ namespace MWDialogue updateTopics(); } + bool DialogueManager::isInChoice() const + { + return mIsInChoice; + } + void DialogueManager::goodbyeSelected() { // Do not close the dialogue window if the player has to answer a question @@ -424,15 +432,13 @@ namespace MWDialogue if (mDialogueMap.find(mLastTopic) != mDialogueMap.end()) { - if (mDialogueMap[mLastTopic].mType == ESM::Dialogue::Topic) - { - Filter filter (mActor, mChoice, mTalkedTo); + Filter filter (mActor, mChoice, mTalkedTo); + if (mDialogueMap[mLastTopic].mType == ESM::Dialogue::Topic + || mDialogueMap[mLastTopic].mType == ESM::Dialogue::Greeting) + { if (const ESM::DialInfo *info = filter.search (mDialogueMap[mLastTopic], true)) { - mChoiceMap.clear(); - mChoice = -1; - mIsInChoice = false; std::string text = info->mResponse; parseText (text); @@ -440,10 +446,12 @@ namespace MWDialogue MWBase::Environment::get().getWindowManager()->getDialogueWindow()->addText (Interpreter::fixDefinesDialog(text, interpreterContext)); MWBase::Environment::get().getJournal()->addTopic (mLastTopic, info->mId); executeScript (info->mResultScript); - mLastTopic = mLastTopic; mLastDialogue = *info; } } + mChoiceMap.clear(); + mChoice = -1; + mIsInChoice = false; } updateTopics(); diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp index 337cf6247..a7bec31a6 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp @@ -54,6 +54,8 @@ namespace MWDialogue DialogueManager (const Compiler::Extensions& extensions, bool scriptVerbose, Translation::Storage& translationDataStorage); + virtual bool isInChoice() const; + virtual void startDialogue (const MWWorld::Ptr& actor); virtual void addTopic (const std::string& topic); diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index 98d818638..837766953 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -340,6 +340,9 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender) drawItems(); mDragAndDrop->mDraggedFrom->drawItems(); + mDragAndDrop->mDraggedFrom->notifyItemDragged(object, -mDragAndDrop->mDraggedCount); + notifyItemDragged(object, mDragAndDrop->mDraggedCount); + MWBase::Environment::get().getWindowManager()->setDragDrop(false); std::string sound = MWWorld::Class::get(object).getDownSoundId(object); diff --git a/apps/openmw/mwgui/container.hpp b/apps/openmw/mwgui/container.hpp index 49e60aa25..03bd519f7 100644 --- a/apps/openmw/mwgui/container.hpp +++ b/apps/openmw/mwgui/container.hpp @@ -82,6 +82,10 @@ namespace MWGui void setFilter(int filter); ///< set category filter void drawItems(); + /// fired when an item was moved by drag&drop. \n + /// if it was removed from this container, count will be negative. + virtual void notifyItemDragged(MWWorld::Ptr item, int count) {} + protected: bool mDisplayEquippedItems; bool mHighlightEquippedItems; diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 6875b2021..b3aa27617 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -228,7 +228,8 @@ void DialogueWindow::onByeClicked(MyGUI::Widget* _sender) void DialogueWindow::onSelectTopic(const std::string& topic, int id) { - if (!mEnabled) return; + if (!mEnabled || MWBase::Environment::get().getDialogueManager()->isInChoice()) + return; int separatorPos = 0; for (unsigned int i=0; igetItemCount(); ++i) @@ -248,6 +249,11 @@ void DialogueWindow::onSelectTopic(const std::string& topic, int id) { mPersuasionDialog.setVisible(true); } + else if (topic == gmst.find("sCompanionShare")->getString()) + { + mWindowManager.pushGuiMode(GM_Companion); + mWindowManager.showCompanionWindow(mPtr); + } else if (!MWBase::Environment::get().getDialogueManager()->checkServiceRefused()) { if (topic == gmst.find("sBarter")->getString()) @@ -306,7 +312,10 @@ void DialogueWindow::setKeywords(std::list keyWords) { mTopicsList->clear(); - bool anyService = mServices > 0; + bool isCompanion = !MWWorld::Class::get(mPtr).getScript(mPtr).empty() + && mPtr.getRefData().getLocals().getIntVar(MWWorld::Class::get(mPtr).getScript(mPtr), "companion"); + + bool anyService = mServices > 0 || isCompanion || mPtr.getTypeName() == typeid(ESM::NPC).name(); const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); @@ -335,9 +344,13 @@ void DialogueWindow::setKeywords(std::list keyWords) if (mServices & Service_Repair) mTopicsList->addItem(gmst.find("sRepair")->getString()); - if (anyService || mPtr.getTypeName() == typeid(ESM::NPC).name()) + if (isCompanion) + mTopicsList->addItem(gmst.find("sCompanionShare")->getString()); + + if (anyService) mTopicsList->addSeparator(); + for(std::list::iterator it = keyWords.begin(); it != keyWords.end(); ++it) { mTopicsList->addItem(*it); diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index 0a31a428b..84526a28d 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -234,7 +234,8 @@ void HUD::onWorldClicked(MyGUI::Widget* _sender) mDragAndDrop->mDraggedWidget = 0; MWBase::Environment::get().getWindowManager()->setDragDrop(false); - MWBase::Environment::get().getWindowManager()->getInventoryWindow()->drawItems(); + mDragAndDrop->mDraggedFrom->drawItems(); + mDragAndDrop->mDraggedFrom->notifyItemDragged(object, -mDragAndDrop->mDraggedCount); } else { diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 578ec3da3..1943ff773 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -43,7 +43,6 @@ namespace MWGui getWidget(mAvatar, "Avatar"); getWidget(mAvatarImage, "AvatarImage"); getWidget(mEncumbranceBar, "EncumbranceBar"); - getWidget(mEncumbranceText, "EncumbranceBarT"); getWidget(mFilterAll, "AllButton"); getWidget(mFilterWeapon, "WeaponButton"); getWidget(mFilterApparel, "ApparelButton"); @@ -240,9 +239,7 @@ namespace MWGui float capacity = MWWorld::Class::get(player).getCapacity(player); float encumbrance = MWWorld::Class::get(player).getEncumbrance(player); - mEncumbranceBar->setProgressRange(capacity); - mEncumbranceBar->setProgressPosition(encumbrance); - mEncumbranceText->setCaption( boost::lexical_cast(int(encumbrance)) + "/" + boost::lexical_cast(int(capacity)) ); + mEncumbranceBar->setValue(encumbrance, capacity); } void InventoryWindow::onFrame() diff --git a/apps/openmw/mwgui/inventorywindow.hpp b/apps/openmw/mwgui/inventorywindow.hpp index 7c59bab50..95657672d 100644 --- a/apps/openmw/mwgui/inventorywindow.hpp +++ b/apps/openmw/mwgui/inventorywindow.hpp @@ -5,6 +5,7 @@ #include "container.hpp" #include "window_pinnable_base.hpp" +#include "widgets.hpp" namespace MWGui { @@ -36,8 +37,7 @@ namespace MWGui MyGUI::Widget* mAvatar; MyGUI::ImageBox* mAvatarImage; MyGUI::TextBox* mArmorRating; - MyGUI::ProgressBar* mEncumbranceBar; - MyGUI::TextBox* mEncumbranceText; + Widgets::MWDynamicStat* mEncumbranceBar; MyGUI::Widget* mLeftPane; MyGUI::Widget* mRightPane; diff --git a/apps/openmw/mwgui/mode.hpp b/apps/openmw/mwgui/mode.hpp index e9b01395f..879fcb483 100644 --- a/apps/openmw/mwgui/mode.hpp +++ b/apps/openmw/mwgui/mode.hpp @@ -9,6 +9,7 @@ namespace MWGui GM_Settings, // Settings window GM_Inventory, // Inventory mode GM_Container, + GM_Companion, GM_MainMenu, // Main menu mode GM_Console, // Console mode diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index eadd65787..cf14c1f51 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -58,6 +58,7 @@ #include "merchantrepair.hpp" #include "repair.hpp" #include "soulgemdialog.hpp" +#include "companionwindow.hpp" using namespace MWGui; @@ -96,6 +97,7 @@ WindowManager::WindowManager( , mMerchantRepair(NULL) , mRepair(NULL) , mSoulgemDialog(NULL) + , mCompanionWindow(NULL) , mPlayerName() , mPlayerRaceId() , mPlayerAttributes() @@ -189,6 +191,7 @@ WindowManager::WindowManager( mMerchantRepair = new MerchantRepair(*this); mRepair = new Repair(*this); mSoulgemDialog = new SoulgemDialog(mMessageBoxManager); + mCompanionWindow = new CompanionWindow(*this, mDragAndDrop, mMessageBoxManager); mLoadingScreen = new LoadingScreen(mRendering->getScene (), mRendering->getWindow (), *this); mLoadingScreen->onResChange (w,h); @@ -317,6 +320,7 @@ void WindowManager::updateVisible() mTrainingWindow->setVisible(false); mMerchantRepair->setVisible(false); mRepair->setVisible(false); + mCompanionWindow->setVisible(false); mHud->setVisible(mHudEnabled); @@ -417,6 +421,10 @@ void WindowManager::updateVisible() mContainerWindow->setVisible(true); mInventoryWindow->setVisible(true); break; + case GM_Companion: + mCompanionWindow->setVisible(true); + mInventoryWindow->setVisible(true); + break; case GM_Dialogue: mDialogueWindow->setVisible(true); break; @@ -676,6 +684,7 @@ void WindowManager::onFrame (float frameDuration) mSpellCreationDialog->checkReferenceAvailable(); mEnchantingDialog->checkReferenceAvailable(); mContainerWindow->checkReferenceAvailable(); + mCompanionWindow->checkReferenceAvailable(); mConsole->checkReferenceAvailable(); } @@ -1167,6 +1176,11 @@ const Translation::Storage& WindowManager::getTranslationDataStorage() const return mTranslationDataStorage; } +void WindowManager::showCompanionWindow(MWWorld::Ptr actor) +{ + mCompanionWindow->open(actor); +} + void WindowManager::changePointer(const std::string &name) { mCursor->onCursorChange(name); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 5cf7bae02..7a7adec27 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -77,6 +77,7 @@ namespace MWGui class MerchantRepair; class Repair; class SoulgemDialog; + class CompanionWindow; class WindowManager : public MWBase::WindowManager { @@ -229,6 +230,7 @@ namespace MWGui virtual bool getPlayerSleeping(); virtual void wakeUpPlayer(); + virtual void showCompanionWindow(MWWorld::Ptr actor); virtual void startSpellMaking(MWWorld::Ptr actor); virtual void startEnchanting(MWWorld::Ptr actor); virtual void startSelfEnchanting(MWWorld::Ptr soulgem); @@ -279,6 +281,7 @@ namespace MWGui MerchantRepair* mMerchantRepair; SoulgemDialog* mSoulgemDialog; Repair* mRepair; + CompanionWindow* mCompanionWindow; Translation::Storage& mTranslationDataStorage; Cursor* mCursor; diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index 51e23d16e..b9aee6abf 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -21,8 +21,16 @@ #include "../mwbase/soundmanager.hpp" MWMechanics::NpcStats::NpcStats() -: mMovementFlags (0), mDrawState (DrawState_Nothing), mBounty (0) -, mLevelProgress(0), mDisposition(0), mVampire (0), mReputation(0), mWerewolf (false), mWerewolfKills (0) +: mMovementFlags (0) +, mDrawState (DrawState_Nothing) +, mBounty (0) +, mLevelProgress(0) +, mDisposition(0) +, mVampire (0) +, mReputation(0) +, mWerewolf (false) +, mWerewolfKills (0) +, mProfit(0) { mSkillIncreases.resize (ESM::Attribute::Length); for (int i=0; igetLocals(script); + int index = locals.getIndex(var); + char type = locals.getType(var); + if(index != -1) + { + switch(type) + { + case 's': + return mShorts.at (index); + + case 'l': + return mLongs.at (index); + + case 'f': + return mFloats.at (index); + default: + return 0; + } + } + return 0; + } bool Locals::setVarByInt(const std::string& script, const std::string& var, int val) { diff --git a/apps/openmw/mwscript/locals.hpp b/apps/openmw/mwscript/locals.hpp index e933c727f..1d9b9c3e4 100644 --- a/apps/openmw/mwscript/locals.hpp +++ b/apps/openmw/mwscript/locals.hpp @@ -17,6 +17,7 @@ namespace MWScript void configure (const ESM::Script& script); bool setVarByInt(const std::string& script, const std::string& var, int val); + int getIntVar (const std::string& script, const std::string& var); ///< if var does not exist, returns 0 }; } diff --git a/apps/openmw/mwscript/scriptmanagerimp.cpp b/apps/openmw/mwscript/scriptmanagerimp.cpp index fed5877c4..933a6e0d3 100644 --- a/apps/openmw/mwscript/scriptmanagerimp.cpp +++ b/apps/openmw/mwscript/scriptmanagerimp.cpp @@ -114,7 +114,7 @@ namespace MWScript } catch (const std::exception& e) { - std::cerr << "exeution of script " << name << " failed." << std::endl; + std::cerr << "execution of script " << name << " failed." << std::endl; if (mVerbose) std::cerr << "(" << e.what() << ")" << std::endl; diff --git a/files/mygui/CMakeLists.txt b/files/mygui/CMakeLists.txt index 7da28f0bf..af695ac6c 100644 --- a/files/mygui/CMakeLists.txt +++ b/files/mygui/CMakeLists.txt @@ -80,6 +80,7 @@ set(MYGUI_FILES openmw_persuasion_dialog.layout openmw_merchantrepair.layout openmw_repair.layout + openmw_companion_window.layout smallbars.png DejaVuLGCSansMono.ttf markers.png diff --git a/files/mygui/openmw_container_window.layout b/files/mygui/openmw_container_window.layout index 452196aae..69961e9be 100644 --- a/files/mygui/openmw_container_window.layout +++ b/files/mygui/openmw_container_window.layout @@ -1,7 +1,7 @@ - + diff --git a/files/mygui/openmw_inventory_window.layout b/files/mygui/openmw_inventory_window.layout index 41bd40f92..09842f108 100644 --- a/files/mygui/openmw_inventory_window.layout +++ b/files/mygui/openmw_inventory_window.layout @@ -6,8 +6,7 @@ - - + diff --git a/files/mygui/openmw_text.skin.xml b/files/mygui/openmw_text.skin.xml index 71e86091c..b2a15b503 100644 --- a/files/mygui/openmw_text.skin.xml +++ b/files/mygui/openmw_text.skin.xml @@ -158,6 +158,11 @@ + + + + + From af6409b9f57880c5f8e796b62d2fd62183ddb589 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 31 Mar 2013 13:50:57 +0200 Subject: [PATCH 22/26] Fix NPC physics scale problem --- libs/openengine/bullet/physic.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 8de931bbf..7b831d32c 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -89,18 +89,19 @@ namespace Physic } void PhysicActor::setScale(float scale){ - Ogre::Vector3 position = getPosition(); - Ogre::Quaternion rotation = getRotation(); //We only need to change the scaled box translation, box rotations remain the same. mBoxScaledTranslation = mBoxScaledTranslation / mBody->getCollisionShape()->getLocalScaling().getX(); mBoxScaledTranslation *= scale; if(mBody){ mEngine->dynamicsWorld->removeRigidBody(mBody); + mEngine->dynamicsWorld->removeRigidBody(mRaycastingBody); delete mBody; + delete mRaycastingBody; } //Create the newly scaled rigid body - mBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, position, rotation); - mEngine->addRigidBody(mBody, false); //Add rigid body to dynamics world, but do not add to object map + mBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, getPosition(), getRotation()); + mRaycastingBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, getPosition(), getRotation(), 0, 0, true); + mEngine->addRigidBody(mBody, false, mRaycastingBody); //Add rigid body to dynamics world, but do not add to object map } Ogre::Vector3 PhysicActor::getHalfExtents() const From bc6e1fd9816f3acb914be559e7e79b4d84edb477 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 31 Mar 2013 14:36:03 +0200 Subject: [PATCH 23/26] Add missing files --- apps/openmw/mwgui/companionwindow.cpp | 107 +++++++++++++++++++++ apps/openmw/mwgui/companionwindow.hpp | 39 ++++++++ files/mygui/openmw_companion_window.layout | 26 +++++ 3 files changed, 172 insertions(+) create mode 100644 apps/openmw/mwgui/companionwindow.cpp create mode 100644 apps/openmw/mwgui/companionwindow.hpp create mode 100644 files/mygui/openmw_companion_window.layout diff --git a/apps/openmw/mwgui/companionwindow.cpp b/apps/openmw/mwgui/companionwindow.cpp new file mode 100644 index 000000000..643cdf4c6 --- /dev/null +++ b/apps/openmw/mwgui/companionwindow.cpp @@ -0,0 +1,107 @@ +#include "companionwindow.hpp" + +#include + +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/environment.hpp" +#include "../mwbase/dialoguemanager.hpp" + +#include "../mwmechanics/npcstats.hpp" + +#include "messagebox.hpp" + +namespace MWGui +{ + +CompanionWindow::CompanionWindow(MWBase::WindowManager &parWindowManager, DragAndDrop *dragAndDrop, MessageBoxManager* manager) + : ContainerBase(dragAndDrop) + , WindowBase("openmw_companion_window.layout", parWindowManager) + , mMessageBoxManager(manager) +{ + MyGUI::ScrollView* itemView; + MyGUI::Widget* containerWidget; + getWidget(containerWidget, "Items"); + getWidget(itemView, "ItemView"); + setWidgets(containerWidget, itemView); + + getWidget(mCloseButton, "CloseButton"); + getWidget(mProfitLabel, "ProfitLabel"); + getWidget(mEncumbranceBar, "EncumbranceBar"); + + mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CompanionWindow::onCloseButtonClicked); + + setCoord(200,0,600,300); +} + +void CompanionWindow::open(MWWorld::Ptr npc) +{ + openContainer(npc); + setTitle(MWWorld::Class::get(npc).getName(npc)); + drawItems(); + updateEncumbranceBar(); +} + +void CompanionWindow::notifyItemDragged(MWWorld::Ptr item, int count) +{ + if (mPtr.getTypeName() == typeid(ESM::NPC).name()) + { + MWMechanics::NpcStats& stats = MWWorld::Class::get(mPtr).getNpcStats(mPtr); + stats.modifyProfit(MWWorld::Class::get(item).getValue(item) * count); + } + updateEncumbranceBar(); +} + +void CompanionWindow::updateEncumbranceBar() +{ + float capacity = MWWorld::Class::get(mPtr).getCapacity(mPtr); + float encumbrance = MWWorld::Class::get(mPtr).getEncumbrance(mPtr); + mEncumbranceBar->setValue(encumbrance, capacity); + + if (mPtr.getTypeName() != typeid(ESM::NPC).name()) + mProfitLabel->setCaption(""); + else + { + MWMechanics::NpcStats& stats = MWWorld::Class::get(mPtr).getNpcStats(mPtr); + mProfitLabel->setCaptionWithReplacing("#{sProfitValue} " + boost::lexical_cast(stats.getProfit())); + } +} + +void CompanionWindow::onWindowResize(MyGUI::Window* window) +{ + drawItems(); +} + +void CompanionWindow::onCloseButtonClicked(MyGUI::Widget* _sender) +{ + if (mPtr.getTypeName() == typeid(ESM::NPC).name() && MWWorld::Class::get(mPtr).getNpcStats(mPtr).getProfit() < 0) + { + std::vector buttons; + buttons.push_back("#{sCompanionWarningButtonOne}"); + buttons.push_back("#{sCompanionWarningButtonTwo}"); + mMessageBoxManager->createInteractiveMessageBox("#{sCompanionWarningMessage}", buttons); + mMessageBoxManager->eventButtonPressed += MyGUI::newDelegate(this, &CompanionWindow::onMessageBoxButtonClicked); + } + else + MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Companion); +} + +void CompanionWindow::onMessageBoxButtonClicked(int button) +{ + if (button == 0) + { + mPtr.getRefData().getLocals().setVarByInt(MWWorld::Class::get(mPtr).getScript(mPtr), + "minimumProfit", MWWorld::Class::get(mPtr).getNpcStats(mPtr).getProfit()); + + MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Companion); + MWBase::Environment::get().getDialogueManager()->startDialogue (mPtr); + } +} + +void CompanionWindow::onReferenceUnavailable() +{ + MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Companion); +} + + + +} diff --git a/apps/openmw/mwgui/companionwindow.hpp b/apps/openmw/mwgui/companionwindow.hpp new file mode 100644 index 000000000..1b64a34d5 --- /dev/null +++ b/apps/openmw/mwgui/companionwindow.hpp @@ -0,0 +1,39 @@ +#ifndef OPENMW_MWGUI_COMPANIONWINDOW_H +#define OPENMW_MWGUI_COMPANIONWINDOW_H + +#include "container.hpp" +#include "widgets.hpp" + +namespace MWGui +{ + class MessageBoxManager; + + class CompanionWindow : public ContainerBase, public WindowBase + { + public: + CompanionWindow(MWBase::WindowManager& parWindowManager,DragAndDrop* dragAndDrop, MessageBoxManager* manager); + virtual ~CompanionWindow() {} + + void open(MWWorld::Ptr npc); + + virtual void notifyItemDragged(MWWorld::Ptr item, int count); + + protected: + MyGUI::Button* mCloseButton; + MyGUI::TextBox* mProfitLabel; + Widgets::MWDynamicStat* mEncumbranceBar; + MessageBoxManager* mMessageBoxManager; + + void onMessageBoxButtonClicked(int button); + + void updateEncumbranceBar(); + + void onWindowResize(MyGUI::Window* window); + void onCloseButtonClicked(MyGUI::Widget* _sender); + + virtual void onReferenceUnavailable(); + }; + +} + +#endif diff --git a/files/mygui/openmw_companion_window.layout b/files/mygui/openmw_companion_window.layout new file mode 100644 index 000000000..6172dd5b1 --- /dev/null +++ b/files/mygui/openmw_companion_window.layout @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + From fd0aa1a4b82c4b94bc99657c1c64272e20b95c05 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 31 Mar 2013 14:46:46 +0200 Subject: [PATCH 24/26] Issue #685: Treat : as a whitespace --- components/compiler/scanner.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/components/compiler/scanner.cpp b/components/compiler/scanner.cpp index 7f43c36a5..420fd8f7f 100644 --- a/components/compiler/scanner.cpp +++ b/components/compiler/scanner.cpp @@ -106,6 +106,12 @@ namespace Compiler mLoc.mLiteral.clear(); return true; } + else if (c==':') + { + // treat : as a whitespace :( + mLoc.mLiteral.clear(); + return true; + } else if (std::isdigit (c)) { bool cont = false; From 857f2b33dbdb14d5a0778929a0de7d12575ffa13 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 31 Mar 2013 14:48:48 +0200 Subject: [PATCH 25/26] Fix companion layout align --- files/mygui/openmw_companion_window.layout | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/mygui/openmw_companion_window.layout b/files/mygui/openmw_companion_window.layout index 6172dd5b1..41a97a1ae 100644 --- a/files/mygui/openmw_companion_window.layout +++ b/files/mygui/openmw_companion_window.layout @@ -11,7 +11,7 @@ - + From 8fd961bbac29bddb7bc838c7ed29e4268ed340c7 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 31 Mar 2013 15:50:48 +0200 Subject: [PATCH 26/26] Fix ReferenceInterface not resetting the Ptr after it was deleted, causing onReferenceUnavailable to be called every frame. Fix inputmanager hiding the cursor when it shouldn't. --- apps/openmw/mwgui/referenceinterface.cpp | 3 +++ apps/openmw/mwinput/inputmanagerimp.cpp | 25 +++++------------------- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/apps/openmw/mwgui/referenceinterface.cpp b/apps/openmw/mwgui/referenceinterface.cpp index b1f7affb6..66e036d92 100644 --- a/apps/openmw/mwgui/referenceinterface.cpp +++ b/apps/openmw/mwgui/referenceinterface.cpp @@ -26,7 +26,10 @@ namespace MWGui // check if player has changed cell, or count of the reference has become 0 if ((playerCell != mCurrentPlayerCell && mCurrentPlayerCell != NULL) || mPtr.getRefData().getCount() == 0) + { + mPtr = MWWorld::Ptr(); onReferenceUnavailable(); + } mCurrentPlayerCell = playerCell; } diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 33ab9b1b4..e514638bb 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -372,26 +372,11 @@ namespace MWInput void InputManager::changeInputMode(bool guiMode) { MWBase::Environment::get().getWindowManager()->setMouseVisible(guiMode); - if(guiMode) - { - // Disable mouse look - mMouseLookEnabled = false; - - mWindows.showCrosshair (false); - - // Enable GUI events - mGuiCursorEnabled = true; - } - else - { - // Enable mouse look - mMouseLookEnabled = true; - - mWindows.showCrosshair (false); - - // Disable GUI events - mGuiCursorEnabled = false; - } + mGuiCursorEnabled = guiMode; + mMouseLookEnabled = !guiMode; + if (guiMode) + mWindows.showCrosshair(false); + // if not in gui mode, the camera decides whether to show crosshair or not. } void InputManager::processChangedSettings(const Settings::CategorySettingVector& changed)